From: Flole998 Date: Mon, 10 Jun 2024 16:52:53 +0000 (+0000) Subject: Reformat all files to follow the coding style guidelines X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=be9b344ff677b5e18b71f086be01b59596f65829;p=thirdparty%2Ftvheadend.git Reformat all files to follow the coding style guidelines --- diff --git a/src/access.c b/src/access.c index 1b0289a35..7b1da1338 100644 --- a/src/access.c +++ b/src/access.c @@ -27,29 +27,30 @@ #include "tcp.h" #include "lang_codes.h" -struct access_entry_queue access_entries; +struct access_entry_queue access_entries; struct access_ticket_queue access_tickets; -struct passwd_entry_queue passwd_entries; +struct passwd_entry_queue passwd_entries; struct ipblock_entry_queue ipblock_entries; -const char *superuser_username; -const char *superuser_password; +const char* superuser_username; +const char* superuser_password; int access_noacl; -static int passwd_verify(access_t *a, const char *username, verify_callback_t verify, void *aux); -static int passwd_verify2(const char *username, verify_callback_t verify, void *aux, - const char *username2, const char *passwd2); -static void access_ticket_destroy(access_ticket_t *at); -static void access_ticket_timeout(void *aux); +static int passwd_verify(access_t* a, const char* username, verify_callback_t verify, void* aux); +static int passwd_verify2(const char* username, + verify_callback_t verify, + void* aux, + const char* username2, + const char* passwd2); +static void access_ticket_destroy(access_ticket_t* at); +static void access_ticket_timeout(void* aux); /** * */ -static void -access_ticket_rearm(void) -{ - access_ticket_t *at; +static void access_ticket_rearm(void) { + access_ticket_t* at; while ((at = TAILQ_FIRST(&access_tickets)) != NULL) { if (at->at_timer.mti_expire > mclk()) { @@ -63,9 +64,7 @@ access_ticket_rearm(void) /** * */ -static void -access_ticket_destroy(access_ticket_t *at) -{ +static void access_ticket_destroy(access_ticket_t* at) { mtimer_disarm(&at->at_timer); free(at->at_id); free(at->at_resource); @@ -77,28 +76,24 @@ access_ticket_destroy(access_ticket_t *at) /** * */ -static access_ticket_t * -access_ticket_find(const char *id) -{ - access_ticket_t *at = NULL; - - if(id != NULL) { +static access_ticket_t* access_ticket_find(const char* id) { + access_ticket_t* at = NULL; + + if (id != NULL) { /* assume that newer tickets are hit more probably */ - TAILQ_FOREACH_REVERSE(at, &access_tickets, access_ticket_queue, at_link) - if(!strcmp(at->at_id, id)) + TAILQ_FOREACH_REVERSE (at, &access_tickets, access_ticket_queue, at_link) + if (!strcmp(at->at_id, id)) return at; } - + return NULL; } /** * */ -static void -access_ticket_timeout(void *aux) -{ - access_ticket_t *at = aux; +static void access_ticket_timeout(void* aux) { + access_ticket_t* at = aux; access_ticket_destroy(at); access_ticket_rearm(); @@ -107,19 +102,17 @@ access_ticket_timeout(void *aux) /** * Create a new ticket for the requested resource and generate a id for it */ -const char * -access_ticket_create(const char *resource, access_t *a) -{ - const int64_t lifetime = sec2mono(MINMAX(config.ticket_expires, 30, 3600)); - uint8_t buf[20]; - char id[41]; - uint_fast32_t i; - access_ticket_t *at; +const char* access_ticket_create(const char* resource, access_t* a) { + const int64_t lifetime = sec2mono(MINMAX(config.ticket_expires, 30, 3600)); + uint8_t buf[20]; + char id[41]; + uint_fast32_t i; + access_ticket_t* at; assert(a); /* try to find an existing ticket */ - TAILQ_FOREACH_REVERSE(at, &access_tickets, access_ticket_queue, at_link) { + TAILQ_FOREACH_REVERSE (at, &access_tickets, access_ticket_queue, at_link) { if (at->at_timer.mti_expire - lifetime + sec2mono(60) < mclk()) break; if (strcmp(resource, at->at_resource)) @@ -133,10 +126,10 @@ access_ticket_create(const char *resource, access_t *a) uuid_random(buf, sizeof(buf)); bin2hex(id, sizeof(id), buf, sizeof(buf)); - at->at_id = strdup(id); + at->at_id = strdup(id); at->at_resource = strdup(resource); - at->at_access = access_copy(a); + at->at_access = access_copy(a); at->at_timer.mti_expire = mclk() + lifetime; i = TAILQ_EMPTY(&access_tickets); @@ -152,12 +145,10 @@ access_ticket_create(const char *resource, access_t *a) /** * */ -int -access_ticket_delete(const char *id) -{ - access_ticket_t *at; +int access_ticket_delete(const char* id) { + access_ticket_t* at; - if((at = access_ticket_find(id)) == NULL) + if ((at = access_ticket_find(id)) == NULL) return -1; access_ticket_destroy(at); @@ -169,13 +160,11 @@ access_ticket_delete(const char *id) /** * */ -access_t * -access_ticket_verify2(const char *id, const char *resource) -{ - access_ticket_t *at; - char buf[256], *r; +access_t* access_ticket_verify2(const char* id, const char* resource) { + access_ticket_t* at; + char buf[256], *r; - if((at = access_ticket_find(id)) == NULL) + if ((at = access_ticket_find(id)) == NULL) return NULL; if (tvheadend_webroot) { @@ -185,7 +174,7 @@ access_ticket_verify2(const char *id, const char *resource) r = at->at_resource; } - if(strcmp(r, resource)) + if (strcmp(r, resource)) return NULL; return access_copy(at->at_access); @@ -194,16 +183,16 @@ access_ticket_verify2(const char *id, const char *resource) /** * */ -static int -passwd_auth_exists(const char *id) -{ - passwd_entry_t *pw; +static int passwd_auth_exists(const char* id) { + passwd_entry_t* pw; if (id == NULL) return 0; - TAILQ_FOREACH(pw, &passwd_entries, pw_link) { - if (strempty(pw->pw_auth)) continue; - if (strcmp(id, pw->pw_auth) == 0) return 1; + TAILQ_FOREACH (pw, &passwd_entries, pw_link) { + if (strempty(pw->pw_auth)) + continue; + if (strcmp(id, pw->pw_auth) == 0) + return 1; } return 0; } @@ -211,18 +200,20 @@ passwd_auth_exists(const char *id) /** * */ -static passwd_entry_t * -passwd_auth_find(const char *id) -{ - passwd_entry_t *pw; +static passwd_entry_t* passwd_auth_find(const char* id) { + passwd_entry_t* pw; if (id == NULL) return NULL; - TAILQ_FOREACH(pw, &passwd_entries, pw_link) { - if (!pw->pw_enabled) continue; - if (!pw->pw_auth_enabled) continue; - if (strempty(pw->pw_auth)) continue; - if (strcmp(id, pw->pw_auth) == 0) return pw; + TAILQ_FOREACH (pw, &passwd_entries, pw_link) { + if (!pw->pw_enabled) + continue; + if (!pw->pw_auth_enabled) + continue; + if (strempty(pw->pw_auth)) + continue; + if (strcmp(id, pw->pw_auth) == 0) + return pw; } return NULL; } @@ -230,15 +221,13 @@ passwd_auth_find(const char *id) /** * */ -int -access_verify_list(htsmsg_t *list, const char *item) -{ - htsmsg_field_t *f; +int access_verify_list(htsmsg_t* list, const char* item) { + htsmsg_field_t* f; if (list) { HTSMSG_FOREACH(f, list) - if (!strcmp(htsmsg_field_get_str(f) ?: "", item)) - return 0; + if (!strcmp(htsmsg_field_get_str(f) ?: "", item)) + return 0; return -1; } return 0; @@ -247,9 +236,7 @@ access_verify_list(htsmsg_t *list, const char *item) /** * */ -int -access_compare(access_t *a, access_t *b) -{ +int access_compare(access_t* a, access_t* b) { int r = strcmp(a->aa_username ?: "", b->aa_username ?: ""); if (!r) r = strcmp(a->aa_representative ?: "", b->aa_representative ?: ""); @@ -259,11 +246,9 @@ access_compare(access_t *a, access_t *b) /** * */ -access_t * -access_copy(access_t *src) -{ - access_t *dst = malloc(sizeof(*dst)); - *dst = *src; +access_t* access_copy(access_t* src) { + access_t* dst = malloc(sizeof(*dst)); + *dst = *src; if (src->aa_username) dst->aa_username = strdup(src->aa_username); if (src->aa_representative) @@ -279,7 +264,7 @@ access_copy(access_t *src) if (src->aa_dvrcfgs) dst->aa_dvrcfgs = htsmsg_copy(src->aa_dvrcfgs); if (src->aa_chrange) { - size_t l = src->aa_chrange_count * sizeof(uint64_t); + size_t l = src->aa_chrange_count * sizeof(uint64_t); dst->aa_chrange = malloc(l); if (dst->aa_chrange == NULL) dst->aa_chrange_count = 0; @@ -293,16 +278,14 @@ access_copy(access_t *src) if (src->aa_auth) dst->aa_auth = strdup(src->aa_auth); dst->aa_xmltv_output_format = src->aa_xmltv_output_format; - dst->aa_htsp_output_format = src->aa_htsp_output_format; + dst->aa_htsp_output_format = src->aa_htsp_output_format; return dst; } /** * */ -char * -access_get_lang(access_t *a, const char *lang) -{ +char* access_get_lang(access_t* a, const char* lang) { if (lang == NULL) { if (a->aa_lang == NULL) return NULL; @@ -315,9 +298,7 @@ access_get_lang(access_t *a, const char *lang) /** * */ -const char * -access_get_theme(access_t *a) -{ +const char* access_get_theme(access_t* a) { if (a == NULL) return "blue"; if (tvh_str_default(a->aa_theme, NULL) == NULL) { @@ -331,9 +312,7 @@ access_get_theme(access_t *a) /** * */ -void -access_destroy(access_t *a) -{ +void access_destroy(access_t* a) { if (a == NULL) return; free(a->aa_username); @@ -353,34 +332,32 @@ access_destroy(access_t *a) /** * */ -static int -netmask_verify(struct access_ipmask_queue *ais, struct sockaddr_storage *src) -{ - access_ipmask_t *ai; - int isv4v6 = 0; - uint32_t v4v6 = 0; - +static int netmask_verify(struct access_ipmask_queue* ais, struct sockaddr_storage* src) { + access_ipmask_t* ai; + int isv4v6 = 0; + uint32_t v4v6 = 0; + if (src->ss_family == AF_INET6) { - struct in6_addr *in6 = &(((struct sockaddr_in6 *)src)->sin6_addr); - uint32_t *a32 = (uint32_t*)in6->s6_addr; + struct in6_addr* in6 = &(((struct sockaddr_in6*)src)->sin6_addr); + uint32_t* a32 = (uint32_t*)in6->s6_addr; if (a32[0] == 0 && a32[1] == 0 && ntohl(a32[2]) == 0x0000FFFFu) { isv4v6 = 1; - v4v6 = ntohl(a32[3]); + v4v6 = ntohl(a32[3]); } } - TAILQ_FOREACH(ai, ais, ai_link) { + TAILQ_FOREACH (ai, ais, ai_link) { if (ai->ai_family == AF_INET && src->ss_family == AF_INET) { - struct sockaddr_in *in4 = (struct sockaddr_in *)src; - uint32_t b = ntohl(in4->sin_addr.s_addr); + struct sockaddr_in* in4 = (struct sockaddr_in*)src; + uint32_t b = ntohl(in4->sin_addr.s_addr); if ((b & ai->ai_netmask) == ai->ai_network) return 1; } else if (ai->ai_family == AF_INET && isv4v6) { - if((v4v6 & ai->ai_netmask) == ai->ai_network) + if ((v4v6 & ai->ai_netmask) == ai->ai_network) return 1; } else if (ai->ai_family == AF_INET6 && isv4v6) { @@ -389,28 +366,27 @@ netmask_verify(struct access_ipmask_queue *ais, struct sockaddr_storage *src) } else if (ai->ai_family == AF_INET6 && src->ss_family == AF_INET6) { - struct in6_addr *in6 = &(((struct sockaddr_in6 *)src)->sin6_addr); - uint8_t *a8 = (uint8_t*)in6->s6_addr; - uint8_t *m8 = (uint8_t*)ai->ai_ip6.s6_addr; - int slen = ai->ai_prefixlen; - uint32_t apos = 0; - uint8_t lastMask = (0xFFu << (8 - (slen % 8))); + struct in6_addr* in6 = &(((struct sockaddr_in6*)src)->sin6_addr); + uint8_t* a8 = (uint8_t*)in6->s6_addr; + uint8_t* m8 = (uint8_t*)ai->ai_ip6.s6_addr; + int slen = ai->ai_prefixlen; + uint32_t apos = 0; + uint8_t lastMask = (0xFFu << (8 - (slen % 8))); - if(slen < 0 || slen > 128) + if (slen < 0 || slen > 128) continue; - while(slen >= 8) - { - if(a8[apos] != m8[apos]) + while (slen >= 8) { + if (a8[apos] != m8[apos]) break; apos += 1; slen -= 8; } - if(slen >= 8) + if (slen >= 8) continue; - if(slen == 0 || (a8[apos] & lastMask) == (m8[apos] & lastMask)) + if (slen == 0 || (a8[apos] & lastMask) == (m8[apos] & lastMask)) return 1; } } @@ -421,12 +397,10 @@ netmask_verify(struct access_ipmask_queue *ais, struct sockaddr_storage *src) /** * */ -static inline int -access_ip_blocked(struct sockaddr_storage *src) -{ - ipblock_entry_t *ib; +static inline int access_ip_blocked(struct sockaddr_storage* src) { + ipblock_entry_t* ib; - TAILQ_FOREACH(ib, &ipblock_entries, ib_link) + TAILQ_FOREACH (ib, &ipblock_entries, ib_link) if (ib->ib_enabled && netmask_verify(&ib->ib_ipmasks, src)) return 1; return 0; @@ -436,15 +410,13 @@ access_ip_blocked(struct sockaddr_storage *src) * */ static void -access_dump_tags - (const char *prefix, char *buf, size_t buflen, size_t *_l, htsmsg_t *tags) -{ +access_dump_tags(const char* prefix, char* buf, size_t buflen, size_t* _l, htsmsg_t* tags) { size_t l = *_l; if (tags) { - int first = 1; - htsmsg_field_t *f; + int first = 1; + htsmsg_field_t* f; HTSMSG_FOREACH(f, tags) { - channel_tag_t *ct = channel_tag_find_by_uuid(htsmsg_field_get_str(f) ?: ""); + channel_tag_t* ct = channel_tag_find_by_uuid(htsmsg_field_get_str(f) ?: ""); if (ct) { if (first) tvh_strlcatf(buf, sizeof(buf), l, ", %s tags=", prefix); @@ -461,44 +433,43 @@ access_dump_tags /* * */ -static void -access_dump_a(access_t *a) -{ - htsmsg_field_t *f; - size_t l = 0; - char buf[1024]; - int first; - - tvh_strlcatf(buf, sizeof(buf), l, - "%s:%s [%c%c%c%c%c%c%c%c%c%c%c], conn=%u:s%u:r%u:l%u%s", - a->aa_representative ?: "", - a->aa_username ?: "", - a->aa_rights & ACCESS_STREAMING ? 'S' : ' ', - a->aa_rights & ACCESS_ADVANCED_STREAMING ? 'A' : ' ', - a->aa_rights & ACCESS_HTSP_STREAMING ? 'T' : ' ', - a->aa_rights & ACCESS_WEB_INTERFACE ? 'W' : ' ', - a->aa_rights & ACCESS_RECORDER ? 'R' : ' ', - a->aa_rights & ACCESS_HTSP_RECORDER ? 'E' : ' ', - a->aa_rights & ACCESS_ALL_RECORDER ? 'L' : ' ', - a->aa_rights & ACCESS_ALL_RW_RECORDER ? 'D' : ' ', - a->aa_rights & ACCESS_FAILED_RECORDER ? 'F' : ' ', - a->aa_rights & ACCESS_HTSP_ANONYMIZE ? 'H' : ' ', - a->aa_rights & ACCESS_ADMIN ? '*' : ' ', - a->aa_conn_limit, - a->aa_conn_limit_streaming, - a->aa_conn_limit_dvr, - a->aa_uilevel, - a->aa_match ? ", matched" : ""); +static void access_dump_a(access_t* a) { + htsmsg_field_t* f; + size_t l = 0; + char buf[1024]; + int first; + + tvh_strlcatf(buf, + sizeof(buf), + l, + "%s:%s [%c%c%c%c%c%c%c%c%c%c%c], conn=%u:s%u:r%u:l%u%s", + a->aa_representative ?: "", + a->aa_username ?: "", + a->aa_rights & ACCESS_STREAMING ? 'S' : ' ', + a->aa_rights & ACCESS_ADVANCED_STREAMING ? 'A' : ' ', + a->aa_rights & ACCESS_HTSP_STREAMING ? 'T' : ' ', + a->aa_rights & ACCESS_WEB_INTERFACE ? 'W' : ' ', + a->aa_rights & ACCESS_RECORDER ? 'R' : ' ', + a->aa_rights & ACCESS_HTSP_RECORDER ? 'E' : ' ', + a->aa_rights & ACCESS_ALL_RECORDER ? 'L' : ' ', + a->aa_rights & ACCESS_ALL_RW_RECORDER ? 'D' : ' ', + a->aa_rights & ACCESS_FAILED_RECORDER ? 'F' : ' ', + a->aa_rights & ACCESS_HTSP_ANONYMIZE ? 'H' : ' ', + a->aa_rights & ACCESS_ADMIN ? '*' : ' ', + a->aa_conn_limit, + a->aa_conn_limit_streaming, + a->aa_conn_limit_dvr, + a->aa_uilevel, + a->aa_match ? ", matched" : ""); if (a->aa_profiles) { first = 1; HTSMSG_FOREACH(f, a->aa_profiles) { - profile_t *pro = profile_find_by_uuid(htsmsg_field_get_str(f) ?: ""); + profile_t* pro = profile_find_by_uuid(htsmsg_field_get_str(f) ?: ""); if (pro) { if (first) tvh_strlcatf(buf, sizeof(buf), l, ", profile="); - tvh_strlcatf(buf, sizeof(buf), l, "%s'%s'", - first ? "" : ",", profile_get_name(pro)); + tvh_strlcatf(buf, sizeof(buf), l, "%s'%s'", first ? "" : ",", profile_get_name(pro)); first = 0; } } @@ -509,12 +480,11 @@ access_dump_a(access_t *a) if (a->aa_dvrcfgs) { first = 1; HTSMSG_FOREACH(f, a->aa_dvrcfgs) { - dvr_config_t *cfg = dvr_config_find_by_uuid(htsmsg_field_get_str(f) ?: ""); + dvr_config_t* cfg = dvr_config_find_by_uuid(htsmsg_field_get_str(f) ?: ""); if (cfg) { if (first) tvh_strlcatf(buf, sizeof(buf), l, ", dvr="); - tvh_strlcatf(buf, sizeof(buf), l, "%s'%s'", - first ? "" : ",", cfg->dvr_config_name ?: ""); + tvh_strlcatf(buf, sizeof(buf), l, "%s'%s'", first ? "" : ",", cfg->dvr_config_name ?: ""); first = 0; } } @@ -524,12 +494,14 @@ access_dump_a(access_t *a) if (a->aa_chrange) { for (first = 0; first < a->aa_chrange_count; first += 2) - tvh_strlcatf(buf, sizeof(buf), l, ", [chmin=%llu, chmax=%llu]", - (long long)a->aa_chrange[first], - (long long)a->aa_chrange[first+1]); + tvh_strlcatf(buf, + sizeof(buf), + l, + ", [chmin=%llu, chmax=%llu]", + (long long)a->aa_chrange[first], + (long long)a->aa_chrange[first + 1]); } - access_dump_tags("exclude ", buf, sizeof(buf), &l, a->aa_chtags_exclude); access_dump_tags("", buf, sizeof(buf), &l, a->aa_chtags); @@ -539,10 +511,9 @@ access_dump_a(access_t *a) /* * */ -static access_t *access_alloc(void) -{ - access_t *a = calloc(1, sizeof(access_t)); - a->aa_uilevel = -1; +static access_t* access_alloc(void) { + access_t* a = calloc(1, sizeof(access_t)); + a->aa_uilevel = -1; a->aa_uilevel_nochange = -1; return a; } @@ -550,10 +521,9 @@ static access_t *access_alloc(void) /* * */ -static access_t *access_full(access_t *a) -{ - a->aa_rights = ACCESS_FULL; - a->aa_uilevel = UILEVEL_EXPERT; +static access_t* access_full(access_t* a) { + a->aa_rights = ACCESS_FULL; + a->aa_uilevel = UILEVEL_EXPERT; a->aa_uilevel_nochange = config.uilevel_nochange; return a; } @@ -561,39 +531,37 @@ static access_t *access_full(access_t *a) /* * */ -static void -access_update(access_t *a, access_entry_t *ae) -{ - idnode_list_mapping_t *ilm; - const char *s; - char ubuf[UUID_HEX_SIZE]; +static void access_update(access_t* a, access_entry_t* ae) { + idnode_list_mapping_t* ilm; + const char* s; + char ubuf[UUID_HEX_SIZE]; if (ae->ae_change_conn_limit) { switch (ae->ae_conn_limit_type) { - case ACCESS_CONN_LIMIT_TYPE_ALL: - a->aa_conn_limit = ae->ae_conn_limit; - break; - case ACCESS_CONN_LIMIT_TYPE_STREAMING: - a->aa_conn_limit_streaming = ae->ae_conn_limit; - break; - case ACCESS_CONN_LIMIT_TYPE_DVR: - a->aa_conn_limit_dvr = ae->ae_conn_limit; - break; + case ACCESS_CONN_LIMIT_TYPE_ALL: + a->aa_conn_limit = ae->ae_conn_limit; + break; + case ACCESS_CONN_LIMIT_TYPE_STREAMING: + a->aa_conn_limit_streaming = ae->ae_conn_limit; + break; + case ACCESS_CONN_LIMIT_TYPE_DVR: + a->aa_conn_limit_dvr = ae->ae_conn_limit; + break; } } if (ae->ae_change_uilevel) { - a->aa_uilevel = ae->ae_uilevel; + a->aa_uilevel = ae->ae_uilevel; a->aa_uilevel_nochange = ae->ae_uilevel_nochange; } if (ae->ae_change_chrange) { if (ae->ae_chmin || ae->ae_chmax) { - uint64_t *p = realloc(a->aa_chrange, (a->aa_chrange_count + 2) * sizeof(uint64_t)); + uint64_t* p = realloc(a->aa_chrange, (a->aa_chrange_count + 2) * sizeof(uint64_t)); if (p) { p[a->aa_chrange_count++] = ae->ae_chmin; p[a->aa_chrange_count++] = ae->ae_chmax; - a->aa_chrange = p; + a->aa_chrange = p; } } else { free(a->aa_chrange); @@ -605,9 +573,9 @@ access_update(access_t *a, access_entry_t *ae) if (LIST_EMPTY(&ae->ae_profiles)) { idnode_list_destroy(&ae->ae_profiles, ae); } else { - LIST_FOREACH(ilm, &ae->ae_profiles, ilm_in1_link) { - profile_t *pro = (profile_t *)ilm->ilm_in2; - if(pro && pro->pro_name && pro->pro_name[0] != '\0') { + LIST_FOREACH (ilm, &ae->ae_profiles, ilm_in1_link) { + profile_t* pro = (profile_t*)ilm->ilm_in2; + if (pro && pro->pro_name && pro->pro_name[0] != '\0') { if (a->aa_profiles == NULL) a->aa_profiles = htsmsg_create_list(); htsmsg_add_str_exclusive(a->aa_profiles, idnode_uuid_as_str(&pro->pro_id, ubuf)); @@ -620,13 +588,13 @@ access_update(access_t *a, access_entry_t *ae) if (LIST_EMPTY(&ae->ae_dvr_configs)) { idnode_list_destroy(&ae->ae_dvr_configs, ae); } else { - LIST_FOREACH(ilm, &ae->ae_dvr_configs, ilm_in1_link) { - dvr_config_t *dvr = (dvr_config_t *)ilm->ilm_in2; - if(dvr && dvr->dvr_config_name[0] != '\0') { + LIST_FOREACH (ilm, &ae->ae_dvr_configs, ilm_in1_link) { + dvr_config_t* dvr = (dvr_config_t*)ilm->ilm_in2; + if (dvr && dvr->dvr_config_name[0] != '\0') { if (a->aa_dvrcfgs == NULL) a->aa_dvrcfgs = htsmsg_create_list(); htsmsg_add_str_exclusive(a->aa_dvrcfgs, idnode_uuid_as_str(&dvr->dvr_id, ubuf)); - } + } } } } @@ -636,15 +604,15 @@ access_update(access_t *a, access_entry_t *ae) idnode_list_destroy(&ae->ae_chtags, ae); } else { htsmsg_t **lst, *lst2; - LIST_FOREACH(ilm, &ae->ae_chtags, ilm_in1_link) { - channel_tag_t *ct = (channel_tag_t *)ilm->ilm_in2; - if(ct && ct->ct_name[0] != '\0') { - const char *ct_uuid = idnode_uuid_as_str(&ct->ct_id, ubuf); + LIST_FOREACH (ilm, &ae->ae_chtags, ilm_in1_link) { + channel_tag_t* ct = (channel_tag_t*)ilm->ilm_in2; + if (ct && ct->ct_name[0] != '\0') { + const char* ct_uuid = idnode_uuid_as_str(&ct->ct_id, ubuf); if (ae->ae_chtags_exclude) { - lst = &a->aa_chtags_exclude; + lst = &a->aa_chtags_exclude; lst2 = a->aa_chtags; } else { - lst = &a->aa_chtags; + lst = &a->aa_chtags; lst2 = a->aa_chtags_exclude; } /* remove the tag from the accepted or exclude list */ @@ -699,10 +667,8 @@ access_update(access_t *a, access_entry_t *ae) /** */ -static void -access_set_lang_ui(access_t *a) -{ - const char *s; +static void access_set_lang_ui(access_t* a) { + const char* s; if (!a->aa_lang_ui) { if ((s = config_get_language_ui()) != NULL) a->aa_lang_ui = lang_code_user(s); @@ -718,29 +684,28 @@ access_set_lang_ui(access_t *a) /** * */ -access_t * -access_get(struct sockaddr_storage *src, const char *username, verify_callback_t verify, void *aux) -{ - access_t *a = access_alloc(); - access_entry_t *ae; - int nouser = tvh_str_default(username, NULL) == NULL; - char *s; +access_t* access_get(struct sockaddr_storage* src, + const char* username, + verify_callback_t verify, + void* aux) { + access_t* a = access_alloc(); + access_entry_t* ae; + int nouser = tvh_str_default(username, NULL) == NULL; + char* s; if (!access_noacl && access_ip_blocked(src)) return a; if (!passwd_verify(a, username, verify, aux)) { - a->aa_username = strdup(username); + a->aa_username = strdup(username); a->aa_representative = strdup(username); - if(!passwd_verify2(username, verify, aux, - superuser_username, superuser_password)) + if (!passwd_verify2(username, verify, aux, superuser_username, superuser_password)) return access_full(a); } else { s = alloca(50); tcp_get_str_from_ip(src, s, 50); a->aa_representative = strdup(s); - if(!passwd_verify2(username, verify, aux, - superuser_username, superuser_password)) + if (!passwd_verify2(username, verify, aux, superuser_username, superuser_password)) return access_full(a); username = NULL; } @@ -748,21 +713,21 @@ access_get(struct sockaddr_storage *src, const char *username, verify_callback_t if (access_noacl) return access_full(a); - TAILQ_FOREACH(ae, &access_entries, ae_link) { + TAILQ_FOREACH (ae, &access_entries, ae_link) { - if(!ae->ae_enabled) + if (!ae->ae_enabled) continue; - if(ae->ae_username[0] != '*') { + if (ae->ae_username[0] != '*') { /* acl entry requires username to match */ - if(username == NULL || strcmp(username, ae->ae_username)) + if (username == NULL || strcmp(username, ae->ae_username)) continue; /* Didn't get one */ } - if(!netmask_verify(&ae->ae_ipmasks, src)) + if (!netmask_verify(&ae->ae_ipmasks, src)) continue; /* IP based access mismatches */ - if(ae->ae_username[0] != '*') + if (ae->ae_username[0] != '*') a->aa_match = 1; access_update(a, ae); @@ -786,27 +751,25 @@ access_get(struct sockaddr_storage *src, const char *username, verify_callback_t /** * */ -access_t * -access_get_by_username(const char *username) -{ - access_t *a = access_alloc(); - access_entry_t *ae; +access_t* access_get_by_username(const char* username) { + access_t* a = access_alloc(); + access_entry_t* ae; - a->aa_username = strdup(username); + a->aa_username = strdup(username); a->aa_representative = strdup(username); - if(access_noacl) + if (access_noacl) return access_full(a); if (username[0] == '\0') return a; - TAILQ_FOREACH(ae, &access_entries, ae_link) { + TAILQ_FOREACH (ae, &access_entries, ae_link) { - if(!ae->ae_enabled) + if (!ae->ae_enabled) continue; - if(ae->ae_username[0] == '*' || strcmp(ae->ae_username, username)) + if (ae->ae_username[0] == '*' || strcmp(ae->ae_username, username)) continue; access_update(a, ae); @@ -820,31 +783,29 @@ access_get_by_username(const char *username) /** * */ -access_t * -access_get_by_addr(struct sockaddr_storage *src) -{ - access_t *a = access_alloc(); - access_entry_t *ae; - char buf[50]; +access_t* access_get_by_addr(struct sockaddr_storage* src) { + access_t* a = access_alloc(); + access_entry_t* ae; + char buf[50]; tcp_get_str_from_ip(src, buf, sizeof(buf)); a->aa_representative = strdup(buf); - if(access_noacl) + if (access_noacl) return access_full(a); if (access_ip_blocked(src)) return a; - TAILQ_FOREACH(ae, &access_entries, ae_link) { + TAILQ_FOREACH (ae, &access_entries, ae_link) { - if(!ae->ae_enabled) + if (!ae->ae_enabled) continue; - if(ae->ae_username[0] != '*') + if (ae->ae_username[0] != '*') continue; - if(!netmask_verify(&ae->ae_ipmasks, src)) + if (!netmask_verify(&ae->ae_ipmasks, src)) continue; /* IP based access mismatches */ access_update(a, ae); @@ -858,9 +819,7 @@ access_get_by_addr(struct sockaddr_storage *src) /** * */ -static int -access_get_by_auth_verify(void *aux, const char *passwd) -{ +static int access_get_by_auth_verify(void* aux, const char* passwd) { if (passwd == superuser_password) return 0; return 1; @@ -869,15 +828,13 @@ access_get_by_auth_verify(void *aux, const char *passwd) /** * */ -access_t * -access_get_by_auth(struct sockaddr_storage *src, const char *id) -{ - access_t *a; - passwd_entry_t *pw = passwd_auth_find(id); +access_t* access_get_by_auth(struct sockaddr_storage* src, const char* id) { + access_t* a; + passwd_entry_t* pw = passwd_auth_find(id); if (!pw) return NULL; a = access_get(src, pw->pw_username, access_get_by_auth_verify, NULL); - a->aa_rights &= ACCESS_ADVANCED_STREAMING|ACCESS_STREAMING; + a->aa_rights &= ACCESS_ADVANCED_STREAMING | ACCESS_STREAMING; tvh_str_set(&a->aa_auth, id); return a; } @@ -885,16 +842,14 @@ access_get_by_auth(struct sockaddr_storage *src, const char *id) /** * */ -static void -access_set_prefix_default(struct access_ipmask_queue *ais) -{ - access_ipmask_t *ai; +static void access_set_prefix_default(struct access_ipmask_queue* ais) { + access_ipmask_t* ai; - ai = calloc(1, sizeof(access_ipmask_t)); + ai = calloc(1, sizeof(access_ipmask_t)); ai->ai_family = AF_INET6; TAILQ_INSERT_HEAD(ais, ai, ai_link); - ai = calloc(1, sizeof(access_ipmask_t)); + ai = calloc(1, sizeof(access_ipmask_t)); ai->ai_family = AF_INET; TAILQ_INSERT_HEAD(ais, ai, ai_link); } @@ -902,8 +857,7 @@ access_set_prefix_default(struct access_ipmask_queue *ais) /** * */ -static int access_addr4_empty(const char *s) -{ +static int access_addr4_empty(const char* s) { int empty = 1; while (*s) { if (*s == '0') { @@ -923,8 +877,7 @@ static int access_addr4_empty(const char *s) /** * */ -static int access_addr6_empty(const char *s) -{ +static int access_addr6_empty(const char* s) { int empty = 1; while (*s) { if (*s == '0') { @@ -944,18 +897,16 @@ static int access_addr6_empty(const char *s) /** * */ -static void -access_set_prefix(struct access_ipmask_queue *ais, const char *prefix, int dflt) -{ - static const char *delim = ",;| "; - char buf[100]; - char tokbuf[4096]; - int prefixlen; - char *p, *tok, *saveptr; - in_addr_t s_addr; - access_ipmask_t *ai = NULL; - - while((ai = TAILQ_FIRST(ais)) != NULL) { +static void access_set_prefix(struct access_ipmask_queue* ais, const char* prefix, int dflt) { + static const char* delim = ",;| "; + char buf[100]; + char tokbuf[4096]; + int prefixlen; + char * p, *tok, *saveptr; + in_addr_t s_addr; + access_ipmask_t* ai = NULL; + + while ((ai = TAILQ_FIRST(ais)) != NULL) { TAILQ_REMOVE(ais, ai, ai_link); free(ai); } @@ -979,7 +930,7 @@ access_set_prefix(struct access_ipmask_queue *ais, const char *prefix, int dflt) if (ai->ai_family == AF_INET6) { if ((p = strchr(buf, '/')) != NULL) { - *p++ = 0; + *p++ = 0; prefixlen = atoi(p); if (prefixlen < 0 || prefixlen > 128) goto fnext; @@ -994,7 +945,7 @@ access_set_prefix(struct access_ipmask_queue *ais, const char *prefix, int dflt) ai->ai_network = 0x00000000; } else { if ((p = strchr(buf, '/')) != NULL) { - *p++ = 0; + *p++ = 0; prefixlen = atoi(p); if (prefixlen < 0 || prefixlen > 32) goto fnext; @@ -1002,11 +953,11 @@ access_set_prefix(struct access_ipmask_queue *ais, const char *prefix, int dflt) prefixlen = !access_addr4_empty(buf) ? 32 : 0; } - s_addr = inet_addr(buf); + s_addr = inet_addr(buf); ai->ai_prefixlen = prefixlen; - ai->ai_netmask = prefixlen ? 0xffffffff << (32 - prefixlen) : 0; - ai->ai_network = ntohl(s_addr) & ai->ai_netmask; + ai->ai_netmask = prefixlen ? 0xffffffff << (32 - prefixlen) : 0; + ai->ai_network = ntohl(s_addr) & ai->ai_netmask; } TAILQ_INSERT_TAIL(ais, ai, ai_link); @@ -1015,7 +966,7 @@ access_set_prefix(struct access_ipmask_queue *ais, const char *prefix, int dflt) tok = strtok_r(NULL, delim, &saveptr); continue; -fnext: + fnext: tok = strtok_r(NULL, delim, &saveptr); if (tok == NULL) { free(ai); @@ -1030,18 +981,17 @@ fnext: /** * */ -static const char *access_get_prefix(struct access_ipmask_queue *ais) -{ - char addrbuf[50]; - access_ipmask_t *ai; - size_t pos = 0; - uint32_t s_addr; +static const char* access_get_prefix(struct access_ipmask_queue* ais) { + char addrbuf[50]; + access_ipmask_t* ai; + size_t pos = 0; + uint32_t s_addr; prop_sbuf[0] = prop_sbuf[1] = '\0'; - TAILQ_FOREACH(ai, ais, ai_link) { - if(PROP_SBUF_LEN-pos <= 0) + TAILQ_FOREACH (ai, ais, ai_link) { + if (PROP_SBUF_LEN - pos <= 0) break; - if(ai->ai_family == AF_INET6) { + if (ai->ai_family == AF_INET6) { inet_ntop(AF_INET6, &ai->ai_ip6, addrbuf, sizeof(addrbuf)); } else { s_addr = htonl(ai->ai_network); @@ -1055,9 +1005,7 @@ static const char *access_get_prefix(struct access_ipmask_queue *ais) /** * */ -static void -access_entry_update_rights(access_entry_t *ae) -{ +static void access_entry_update_rights(access_entry_t* ae) { uint32_t r = 0; if (ae->ae_streaming) @@ -1091,9 +1039,7 @@ access_entry_update_rights(access_entry_t *ae) static void access_entry_reindex(void); -access_entry_t * -access_entry_create(const char *uuid, htsmsg_t *conf) -{ +access_entry_t* access_entry_create(const char* uuid, htsmsg_t* conf) { access_entry_t *ae, *ae2; lock_assert(&global_lock); @@ -1109,30 +1055,30 @@ access_entry_create(const char *uuid, htsmsg_t *conf) TAILQ_INIT(&ae->ae_ipmasks); - ae->ae_uilevel = UILEVEL_DEFAULT; + ae->ae_uilevel = UILEVEL_DEFAULT; ae->ae_uilevel_nochange = -1; if (conf) { /* defaults */ - ae->ae_change_lang = 1; - ae->ae_change_lang_ui = 1; - ae->ae_change_theme = 1; - ae->ae_change_uilevel = 1; - ae->ae_change_profiles = 1; - ae->ae_change_conn_limit = 1; - ae->ae_change_dvr_configs = 1; - ae->ae_change_chrange = 1; - ae->ae_change_chtags = 1; - ae->ae_change_rights = 1; + ae->ae_change_lang = 1; + ae->ae_change_lang_ui = 1; + ae->ae_change_theme = 1; + ae->ae_change_uilevel = 1; + ae->ae_change_profiles = 1; + ae->ae_change_conn_limit = 1; + ae->ae_change_dvr_configs = 1; + ae->ae_change_chrange = 1; + ae->ae_change_chtags = 1; + ae->ae_change_rights = 1; ae->ae_change_xmltv_output_format = 1; - ae->ae_change_htsp_output_format = 1; - ae->ae_htsp_streaming = 1; - ae->ae_htsp_dvr = 1; - ae->ae_all_dvr = 1; - ae->ae_failed_dvr = 1; + ae->ae_change_htsp_output_format = 1; + ae->ae_htsp_streaming = 1; + ae->ae_htsp_dvr = 1; + ae->ae_all_dvr = 1; + ae->ae_failed_dvr = 1; idnode_load(&ae->ae_id, conf); access_entry_update_rights(ae); - TAILQ_FOREACH(ae2, &access_entries, ae_link) + TAILQ_FOREACH (ae2, &access_entries, ae_link) if (ae->ae_index < ae2->ae_index) break; if (ae2) @@ -1157,11 +1103,9 @@ access_entry_create(const char *uuid, htsmsg_t *conf) /** * */ -void -access_entry_destroy(access_entry_t *ae, int delconf) -{ - access_ipmask_t *ai; - char ubuf[UUID_HEX_SIZE]; +void access_entry_destroy(access_entry_t* ae, int delconf) { + access_ipmask_t* ai; + char ubuf[UUID_HEX_SIZE]; idnode_save_check(&ae->ae_id, delconf); @@ -1175,8 +1119,7 @@ access_entry_destroy(access_entry_t *ae, int delconf) idnode_list_destroy(&ae->ae_dvr_configs, ae); idnode_list_destroy(&ae->ae_chtags, ae); - while((ai = TAILQ_FIRST(&ae->ae_ipmasks)) != NULL) - { + while ((ai = TAILQ_FIRST(&ae->ae_ipmasks)) != NULL) { TAILQ_REMOVE(&ae->ae_ipmasks, ai, ai_link); free(ai); } @@ -1192,40 +1135,32 @@ access_entry_destroy(access_entry_t *ae, int delconf) /* * */ -void -access_destroy_by_profile(profile_t *pro, int delconf) -{ +void access_destroy_by_profile(profile_t* pro, int delconf) { idnode_list_destroy(&pro->pro_accesses, delconf ? pro : NULL); } /* * */ -void -access_destroy_by_dvr_config(dvr_config_t *cfg, int delconf) -{ +void access_destroy_by_dvr_config(dvr_config_t* cfg, int delconf) { idnode_list_destroy(&cfg->dvr_accesses, delconf ? cfg : NULL); } /* * */ -void -access_destroy_by_channel_tag(channel_tag_t *ct, int delconf) -{ +void access_destroy_by_channel_tag(channel_tag_t* ct, int delconf) { idnode_list_destroy(&ct->ct_accesses, delconf ? ct : NULL); } /** * */ -static void -access_entry_reindex(void) -{ - access_entry_t *ae; - int i = 1; +static void access_entry_reindex(void) { + access_entry_t* ae; + int i = 1; - TAILQ_FOREACH(ae, &access_entries, ae_link) { + TAILQ_FOREACH (ae, &access_entries, ae_link) { if (ae->ae_index != i) { ae->ae_index = i; idnode_changed(&ae->ae_id); @@ -1238,31 +1173,25 @@ access_entry_reindex(void) * Class definition * **************************************************************************/ -static htsmsg_t * -access_entry_class_save(idnode_t *self, char *filename, size_t fsize) -{ - access_entry_t *ae = (access_entry_t *)self; - char ubuf[UUID_HEX_SIZE]; - htsmsg_t *c = htsmsg_create_map(); - access_entry_update_rights((access_entry_t *)self); +static htsmsg_t* access_entry_class_save(idnode_t* self, char* filename, size_t fsize) { + access_entry_t* ae = (access_entry_t*)self; + char ubuf[UUID_HEX_SIZE]; + htsmsg_t* c = htsmsg_create_map(); + access_entry_update_rights((access_entry_t*)self); idnode_save(&ae->ae_id, c); if (filename) snprintf(filename, fsize, "accesscontrol/%s", idnode_uuid_as_str(&ae->ae_id, ubuf)); return c; } -static void -access_entry_class_delete(idnode_t *self) -{ - access_entry_t *ae = (access_entry_t *)self; +static void access_entry_class_delete(idnode_t* self) { + access_entry_t* ae = (access_entry_t*)self; access_entry_destroy(ae, 1); } -static void -access_entry_class_moveup(idnode_t *self) -{ - access_entry_t *ae = (access_entry_t *)self; - access_entry_t *prev = TAILQ_PREV(ae, access_entry_queue, ae_link); +static void access_entry_class_moveup(idnode_t* self) { + access_entry_t* ae = (access_entry_t*)self; + access_entry_t* prev = TAILQ_PREV(ae, access_entry_queue, ae_link); if (prev) { TAILQ_REMOVE(&access_entries, ae, ae_link); TAILQ_INSERT_BEFORE(prev, ae, ae_link); @@ -1270,11 +1199,9 @@ access_entry_class_moveup(idnode_t *self) } } -static void -access_entry_class_movedown(idnode_t *self) -{ - access_entry_t *ae = (access_entry_t *)self; - access_entry_t *next = TAILQ_NEXT(ae, ae_link); +static void access_entry_class_movedown(idnode_t* self) { + access_entry_t* ae = (access_entry_t*)self; + access_entry_t* next = TAILQ_NEXT(ae, ae_link); if (next) { TAILQ_REMOVE(&access_entries, ae, ae_link); TAILQ_INSERT_AFTER(&access_entries, next, ae, ae_link); @@ -1283,10 +1210,8 @@ access_entry_class_movedown(idnode_t *self) } static void -access_entry_class_get_title - (idnode_t *self, const char *lang, char *buf, size_t dstsize) -{ - access_entry_t *ae = (access_entry_t *)self; +access_entry_class_get_title(idnode_t* self, const char* lang, char* buf, size_t dstsize) { + access_entry_t* ae = (access_entry_t*)self; if (ae->ae_comment && ae->ae_comment[0] != '\0') { if (ae->ae_username && ae->ae_username[0]) { @@ -1303,392 +1228,320 @@ access_entry_class_get_title buf[0] = '\0'; } -static int -access_entry_class_prefix_set(void *o, const void *v) -{ - access_set_prefix(&((access_entry_t *)o)->ae_ipmasks, (const char *)v, 1); +static int access_entry_class_prefix_set(void* o, const void* v) { + access_set_prefix(&((access_entry_t*)o)->ae_ipmasks, (const char*)v, 1); return 1; } -static const void * -access_entry_class_prefix_get(void *o) -{ - prop_ptr = access_get_prefix(&((access_entry_t *)o)->ae_ipmasks); +static const void* access_entry_class_prefix_get(void* o) { + prop_ptr = access_get_prefix(&((access_entry_t*)o)->ae_ipmasks); return &prop_ptr; } -static int -access_entry_chtag_set_cb ( idnode_t *in1, idnode_t *in2, void *origin ) -{ - access_entry_t *ae = (access_entry_t *)in1; - idnode_list_mapping_t *ilm; - channel_tag_t *ct = (channel_tag_t *)in2; +static int access_entry_chtag_set_cb(idnode_t* in1, idnode_t* in2, void* origin) { + access_entry_t* ae = (access_entry_t*)in1; + idnode_list_mapping_t* ilm; + channel_tag_t* ct = (channel_tag_t*)in2; ilm = idnode_list_link(in1, &ae->ae_chtags, in2, &ct->ct_accesses, origin, 1); return ilm ? 1 : 0; } -static int -access_entry_chtag_set(void *o, const void *v) -{ - access_entry_t *ae = (access_entry_t *)o; - return idnode_list_set1(&ae->ae_id, &ae->ae_chtags, - &channel_tag_class, (htsmsg_t *)v, - access_entry_chtag_set_cb); +static int access_entry_chtag_set(void* o, const void* v) { + access_entry_t* ae = (access_entry_t*)o; + return idnode_list_set1(&ae->ae_id, + &ae->ae_chtags, + &channel_tag_class, + (htsmsg_t*)v, + access_entry_chtag_set_cb); } -static const void * -access_entry_chtag_get(void *o) -{ - return idnode_list_get1(&((access_entry_t *)o)->ae_chtags); +static const void* access_entry_chtag_get(void* o) { + return idnode_list_get1(&((access_entry_t*)o)->ae_chtags); } -static char * -access_entry_chtag_rend (void *o, const char *lang) -{ - return idnode_list_get_csv1(&((access_entry_t *)o)->ae_chtags, lang); +static char* access_entry_chtag_rend(void* o, const char* lang) { + return idnode_list_get_csv1(&((access_entry_t*)o)->ae_chtags, lang); } -static int -access_entry_dvr_config_set_cb ( idnode_t *in1, idnode_t *in2, void *origin ) -{ - access_entry_t *ae = (access_entry_t *)in1; - idnode_list_mapping_t *ilm; - dvr_config_t *dvr = (dvr_config_t *)in2; +static int access_entry_dvr_config_set_cb(idnode_t* in1, idnode_t* in2, void* origin) { + access_entry_t* ae = (access_entry_t*)in1; + idnode_list_mapping_t* ilm; + dvr_config_t* dvr = (dvr_config_t*)in2; ilm = idnode_list_link(in1, &ae->ae_dvr_configs, in2, &dvr->dvr_accesses, origin, 1); return ilm ? 1 : 0; } -static int -access_entry_dvr_config_set(void *o, const void *v) -{ - access_entry_t *ae = (access_entry_t *)o; - return idnode_list_set1(&ae->ae_id, &ae->ae_dvr_configs, - &dvr_config_class, (htsmsg_t *)v, - access_entry_dvr_config_set_cb); +static int access_entry_dvr_config_set(void* o, const void* v) { + access_entry_t* ae = (access_entry_t*)o; + return idnode_list_set1(&ae->ae_id, + &ae->ae_dvr_configs, + &dvr_config_class, + (htsmsg_t*)v, + access_entry_dvr_config_set_cb); } -static const void * -access_entry_dvr_config_get(void *o) -{ - return idnode_list_get1(&((access_entry_t *)o)->ae_dvr_configs); +static const void* access_entry_dvr_config_get(void* o) { + return idnode_list_get1(&((access_entry_t*)o)->ae_dvr_configs); } -static char * -access_entry_dvr_config_rend (void *o, const char *lang) -{ - return idnode_list_get_csv1(&((access_entry_t *)o)->ae_dvr_configs, lang); +static char* access_entry_dvr_config_rend(void* o, const char* lang) { + return idnode_list_get_csv1(&((access_entry_t*)o)->ae_dvr_configs, lang); } -static int -access_entry_profile_set_cb ( idnode_t *in1, idnode_t *in2, void *origin ) -{ - access_entry_t *ae = (access_entry_t *)in1; - idnode_list_mapping_t *ilm; - profile_t *pro = (profile_t *)in2; +static int access_entry_profile_set_cb(idnode_t* in1, idnode_t* in2, void* origin) { + access_entry_t* ae = (access_entry_t*)in1; + idnode_list_mapping_t* ilm; + profile_t* pro = (profile_t*)in2; ilm = idnode_list_link(in1, &ae->ae_profiles, in2, &pro->pro_accesses, origin, 1); return ilm ? 1 : 0; } -static int -access_entry_profile_set(void *o, const void *v) -{ - access_entry_t *ae = (access_entry_t *)o; - return idnode_list_set1(&ae->ae_id, &ae->ae_profiles, - &profile_class, (htsmsg_t *)v, - access_entry_profile_set_cb); +static int access_entry_profile_set(void* o, const void* v) { + access_entry_t* ae = (access_entry_t*)o; + return idnode_list_set1(&ae->ae_id, + &ae->ae_profiles, + &profile_class, + (htsmsg_t*)v, + access_entry_profile_set_cb); } -static const void * -access_entry_profile_get(void *o) -{ - return idnode_list_get1(&((access_entry_t *)o)->ae_profiles); +static const void* access_entry_profile_get(void* o) { + return idnode_list_get1(&((access_entry_t*)o)->ae_profiles); } -static char * -access_entry_profile_rend (void *o, const char *lang) -{ - return idnode_list_get_csv1(&((access_entry_t *)o)->ae_profiles, lang); +static char* access_entry_profile_rend(void* o, const char* lang) { + return idnode_list_get_csv1(&((access_entry_t*)o)->ae_profiles, lang); } -static htsmsg_t * -access_entry_conn_limit_type_enum ( void *p, const char *lang ) -{ - static struct strtab - conn_limit_type_tab[] = { - { N_("All (Streaming plus DVR)"), ACCESS_CONN_LIMIT_TYPE_ALL }, - { N_("Streaming"), ACCESS_CONN_LIMIT_TYPE_STREAMING }, - { N_("DVR"), ACCESS_CONN_LIMIT_TYPE_DVR }, +static htsmsg_t* access_entry_conn_limit_type_enum(void* p, const char* lang) { + static struct strtab conn_limit_type_tab[] = { + {N_("All (Streaming plus DVR)"), ACCESS_CONN_LIMIT_TYPE_ALL}, + {N_("Streaming"), ACCESS_CONN_LIMIT_TYPE_STREAMING}, + {N_("DVR"), ACCESS_CONN_LIMIT_TYPE_DVR}, }; return strtab2htsmsg(conn_limit_type_tab, 1, lang); } -static htsmsg_t * -access_entry_xmltv_output_format_enum ( void *p, const char *lang ) -{ - static struct strtab - xmltv_output_format_tab[] = { - { N_("All"), ACCESS_XMLTV_OUTPUT_FORMAT_ALL }, - { N_("Basic"), ACCESS_XMLTV_OUTPUT_FORMAT_BASIC }, - { N_("Basic Alternative (No Hash)"), ACCESS_XMLTV_OUTPUT_FORMAT_BASIC_NO_HASH }, +static htsmsg_t* access_entry_xmltv_output_format_enum(void* p, const char* lang) { + static struct strtab xmltv_output_format_tab[] = { + {N_("All"), ACCESS_XMLTV_OUTPUT_FORMAT_ALL}, + {N_("Basic"), ACCESS_XMLTV_OUTPUT_FORMAT_BASIC}, + {N_("Basic Alternative (No Hash)"), ACCESS_XMLTV_OUTPUT_FORMAT_BASIC_NO_HASH}, }; return strtab2htsmsg(xmltv_output_format_tab, 1, lang); } -static htsmsg_t * -access_entry_htsp_output_format_enum ( void *p, const char *lang ) -{ - static struct strtab - htsp_output_format_tab[] = { - { N_("All"), ACCESS_HTSP_OUTPUT_FORMAT_ALL }, - { N_("Basic"), ACCESS_HTSP_OUTPUT_FORMAT_BASIC }, +static htsmsg_t* access_entry_htsp_output_format_enum(void* p, const char* lang) { + static struct strtab htsp_output_format_tab[] = { + {N_("All"), ACCESS_HTSP_OUTPUT_FORMAT_ALL}, + {N_("Basic"), ACCESS_HTSP_OUTPUT_FORMAT_BASIC}, }; return strtab2htsmsg(htsp_output_format_tab, 1, lang); } -htsmsg_t * -language_get_list ( void *obj, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "language/locale"); +htsmsg_t* language_get_list(void* obj, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "language/locale"); return m; } -htsmsg_t * -language_get_ui_list ( void *obj, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "language/ui_locale"); +htsmsg_t* language_get_ui_list(void* obj, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "language/ui_locale"); return m; } -htsmsg_t * -user_get_userlist ( void *obj, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "access/entry/userlist"); +htsmsg_t* user_get_userlist(void* obj, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "access/entry/userlist"); htsmsg_add_str(m, "event", "access"); return m; } -static htsmsg_t * -uilevel_get_list ( void *o, const char *lang ) -{ +static htsmsg_t* uilevel_get_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Default"), UILEVEL_DEFAULT }, - { N_("Basic"), UILEVEL_BASIC }, - { N_("Advanced"), UILEVEL_ADVANCED }, - { N_("Expert"), UILEVEL_EXPERT }, + {N_("Default"), UILEVEL_DEFAULT}, + {N_("Basic"), UILEVEL_BASIC}, + {N_("Advanced"), UILEVEL_ADVANCED}, + {N_("Expert"), UILEVEL_EXPERT}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -uilevel_nochange_get_list ( void *o, const char *lang ) -{ +static htsmsg_t* uilevel_nochange_get_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Default"), -1 }, - { N_("No"), 0 }, - { N_("Yes"), 1 }, + {N_("Default"), -1}, + {N_("No"), 0}, + {N_("Yes"), 1}, }; return strtab2htsmsg(tab, 1, lang); } -htsmsg_t * -theme_get_ui_list ( void *p, const char *lang ) -{ +htsmsg_t* theme_get_ui_list(void* p, const char* lang) { static struct strtab_str tab[] = { - { N_("Blue"), "blue" }, - { N_("Gray"), "gray" }, - { N_("Access"), "access" }, + {N_("Blue"), "blue"}, + {N_("Gray"), "gray"}, + {N_("Access"), "access"}, }; return strtab2htsmsg_str(tab, 1, lang); } static idnode_slist_t access_entry_class_change_slist[] = { - { - .id = "change_rights", - .name = N_("Rights"), - .off = offsetof(access_entry_t, ae_change_rights), - }, - { - .id = "change_chrange", - .name = N_("Channel number range"), - .off = offsetof(access_entry_t, ae_change_chrange), - }, - { - .id = "change_chtags", - .name = N_("Channel tags"), - .off = offsetof(access_entry_t, ae_change_chtags), - }, - { - .id = "change_dvr_configs", - .name = N_("DVR configurations"), - .off = offsetof(access_entry_t, ae_change_dvr_configs), - }, - { - .id = "change_profiles", - .name = N_("Streaming profiles"), - .off = offsetof(access_entry_t, ae_change_profiles), - }, - { - .id = "change_conn_limit", - .name = N_("Connection limits"), - .off = offsetof(access_entry_t, ae_change_conn_limit), - }, - { - .id = "change_lang", - .name = N_("Language"), - .off = offsetof(access_entry_t, ae_change_lang), - }, - { - .id = "change_lang_ui", - .name = N_("Web interface language"), - .off = offsetof(access_entry_t, ae_change_lang_ui), - }, - { - .id = "change_theme", - .name = N_("Theme"), - .off = offsetof(access_entry_t, ae_change_theme), - }, - { - .id = "change_uilevel", - .name = N_("User interface level"), - .off = offsetof(access_entry_t, ae_change_uilevel), - }, - { - .id = "change_xmltv_output", - .name = N_("XMLTV output format"), - .off = offsetof(access_entry_t, ae_change_xmltv_output_format), - }, - { - .id = "change_htsp_output", - .name = N_("HTSP output format"), - .off = offsetof(access_entry_t, ae_change_htsp_output_format), - }, - {} -}; - -static htsmsg_t * -access_entry_class_change_enum ( void *obj, const char *lang ) -{ + { + .id = "change_rights", + .name = N_("Rights"), + .off = offsetof(access_entry_t, ae_change_rights), + }, + { + .id = "change_chrange", + .name = N_("Channel number range"), + .off = offsetof(access_entry_t, ae_change_chrange), + }, + { + .id = "change_chtags", + .name = N_("Channel tags"), + .off = offsetof(access_entry_t, ae_change_chtags), + }, + { + .id = "change_dvr_configs", + .name = N_("DVR configurations"), + .off = offsetof(access_entry_t, ae_change_dvr_configs), + }, + { + .id = "change_profiles", + .name = N_("Streaming profiles"), + .off = offsetof(access_entry_t, ae_change_profiles), + }, + { + .id = "change_conn_limit", + .name = N_("Connection limits"), + .off = offsetof(access_entry_t, ae_change_conn_limit), + }, + { + .id = "change_lang", + .name = N_("Language"), + .off = offsetof(access_entry_t, ae_change_lang), + }, + { + .id = "change_lang_ui", + .name = N_("Web interface language"), + .off = offsetof(access_entry_t, ae_change_lang_ui), + }, + { + .id = "change_theme", + .name = N_("Theme"), + .off = offsetof(access_entry_t, ae_change_theme), + }, + { + .id = "change_uilevel", + .name = N_("User interface level"), + .off = offsetof(access_entry_t, ae_change_uilevel), + }, + { + .id = "change_xmltv_output", + .name = N_("XMLTV output format"), + .off = offsetof(access_entry_t, ae_change_xmltv_output_format), + }, + { + .id = "change_htsp_output", + .name = N_("HTSP output format"), + .off = offsetof(access_entry_t, ae_change_htsp_output_format), + }, + {}}; + +static htsmsg_t* access_entry_class_change_enum(void* obj, const char* lang) { return idnode_slist_enum(obj, access_entry_class_change_slist, lang); } -static const void * -access_entry_class_change_get ( void *obj ) -{ +static const void* access_entry_class_change_get(void* obj) { return idnode_slist_get(obj, access_entry_class_change_slist); } -static char * -access_entry_class_change_rend ( void *obj, const char *lang ) -{ +static char* access_entry_class_change_rend(void* obj, const char* lang) { return idnode_slist_rend(obj, access_entry_class_change_slist, lang); } -static int -access_entry_class_change_set ( void *obj, const void *p ) -{ +static int access_entry_class_change_set(void* obj, const void* p) { return idnode_slist_set(obj, access_entry_class_change_slist, p); } - static idnode_slist_t access_entry_class_streaming_slist[] = { - { - .id = "basic", - .name = N_("Basic"), - .off = offsetof(access_entry_t, ae_streaming), - }, - { - .id = "advanced", - .name = N_("Advanced"), - .off = offsetof(access_entry_t, ae_adv_streaming), - }, - { - .id = "htsp", - .name = N_("HTSP"), - .off = offsetof(access_entry_t, ae_htsp_streaming), - }, - {} -}; - -static htsmsg_t * -access_entry_class_streaming_enum ( void *obj, const char *lang ) -{ + { + .id = "basic", + .name = N_("Basic"), + .off = offsetof(access_entry_t, ae_streaming), + }, + { + .id = "advanced", + .name = N_("Advanced"), + .off = offsetof(access_entry_t, ae_adv_streaming), + }, + { + .id = "htsp", + .name = N_("HTSP"), + .off = offsetof(access_entry_t, ae_htsp_streaming), + }, + {}}; + +static htsmsg_t* access_entry_class_streaming_enum(void* obj, const char* lang) { return idnode_slist_enum(obj, access_entry_class_streaming_slist, lang); } -static const void * -access_entry_class_streaming_get ( void *obj ) -{ +static const void* access_entry_class_streaming_get(void* obj) { return idnode_slist_get(obj, access_entry_class_streaming_slist); } -static char * -access_entry_class_streaming_rend ( void *obj, const char *lang ) -{ +static char* access_entry_class_streaming_rend(void* obj, const char* lang) { return idnode_slist_rend(obj, access_entry_class_streaming_slist, lang); } -static int -access_entry_class_streaming_set ( void *obj, const void *p ) -{ +static int access_entry_class_streaming_set(void* obj, const void* p) { return idnode_slist_set(obj, access_entry_class_streaming_slist, p); } -static idnode_slist_t access_entry_class_dvr_slist[] = { - { - .id = "basic", - .name = N_("Basic"), - .off = offsetof(access_entry_t, ae_dvr), - }, - { - .id = "htsp", - .name = N_("HTSP"), - .off = offsetof(access_entry_t, ae_htsp_dvr), - }, - { - .id = "all", - .name = N_("View all"), - .off = offsetof(access_entry_t, ae_all_dvr), - }, - { - .id = "all_rw", - .name = N_("Manage all"), - .off = offsetof(access_entry_t, ae_all_rw_dvr), - }, - { - .id = "failed", - .name = N_("Failed view"), - .off = offsetof(access_entry_t, ae_failed_dvr), - }, - {} -}; - -static htsmsg_t * -access_entry_class_dvr_enum ( void *obj, const char *lang ) -{ +static idnode_slist_t access_entry_class_dvr_slist[] = {{ + .id = "basic", + .name = N_("Basic"), + .off = offsetof(access_entry_t, ae_dvr), + }, + { + .id = "htsp", + .name = N_("HTSP"), + .off = offsetof(access_entry_t, ae_htsp_dvr), + }, + { + .id = "all", + .name = N_("View all"), + .off = offsetof(access_entry_t, ae_all_dvr), + }, + { + .id = "all_rw", + .name = N_("Manage all"), + .off = offsetof(access_entry_t, ae_all_rw_dvr), + }, + { + .id = "failed", + .name = N_("Failed view"), + .off = offsetof(access_entry_t, ae_failed_dvr), + }, + {}}; + +static htsmsg_t* access_entry_class_dvr_enum(void* obj, const char* lang) { return idnode_slist_enum(obj, access_entry_class_dvr_slist, lang); } -static const void * -access_entry_class_dvr_get ( void *obj ) -{ +static const void* access_entry_class_dvr_get(void* obj) { return idnode_slist_get(obj, access_entry_class_dvr_slist); } -static char * -access_entry_class_dvr_rend ( void *obj, const char *lang ) -{ +static char* access_entry_class_dvr_rend(void* obj, const char* lang) { return idnode_slist_rend(obj, access_entry_class_dvr_slist, lang); } -static int -access_entry_class_dvr_set ( void *obj, const void *p ) -{ +static int access_entry_class_dvr_set(void* obj, const void* p) { return idnode_slist_set(obj, access_entry_class_dvr_slist, p); } @@ -1702,303 +1555,292 @@ PROP_DOC(change_parameters) PROP_DOC(xmltv_output_format) PROP_DOC(htsp_output_format) -const idclass_t access_entry_class = { - .ic_class = "access", - .ic_caption = N_("Users - Access Entries"), - .ic_event = "access", - .ic_perm_def = ACCESS_ADMIN, - .ic_doc = tvh_doc_access_entry_class, - .ic_save = access_entry_class_save, - .ic_get_title = access_entry_class_get_title, - .ic_delete = access_entry_class_delete, - .ic_moveup = access_entry_class_moveup, - .ic_movedown = access_entry_class_movedown, - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "index", - .name = N_("Index"), - .off = offsetof(access_entry_t, ae_index), - .opts = PO_RDONLY | PO_HIDDEN | PO_NOUI, - }, - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/Disable the entry."), - .def.i = 1, - .off = offsetof(access_entry_t, ae_enabled), - }, - { - .type = PT_STR, - .id = "username", - .name = N_("Username"), - .desc = N_("Username for the entry (login username)."), - .off = offsetof(access_entry_t, ae_username), - }, - { - .type = PT_STR, - .id = "prefix", - .name = N_("Allowed networks"), - .desc = N_("List of allowed IPv4 or IPv6 hosts or networks (comma-separated)."), - .set = access_entry_class_prefix_set, - .get = access_entry_class_prefix_get, - .opts = PO_ADVANCED - }, - { - .type = PT_INT, - .islist = 1, - .id = "change", - .name = N_("Change parameters"), - .desc = N_("Specify the parameters to be changed. See Help for details."), - .doc = prop_doc_change_parameters, - .list = access_entry_class_change_enum, - .get = access_entry_class_change_get, - .set = access_entry_class_change_set, - .rend = access_entry_class_change_rend, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_INT, - .id = "uilevel", - .name = N_("User interface level"), - .desc = N_("Default user interface level."), - .doc = prop_doc_viewlevel_access_entries, - .off = offsetof(access_entry_t, ae_uilevel), - .list = uilevel_get_list, - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_INT, - .id = "uilevel_nochange", - .name = N_("Persistent user interface level"), - .desc = N_("Prevent the user from overriding the default user " - "interface level setting and removes the view level " - "drop-dowm from the interface."), - .doc = prop_doc_persistent_viewlevel, - .off = offsetof(access_entry_t, ae_uilevel_nochange), - .list = uilevel_nochange_get_list, - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "lang", - .name = N_("Language"), - .desc = N_("Default language."), - .list = language_get_list, - .off = offsetof(access_entry_t, ae_lang), - .opts = PO_ADVANCED, - }, - { - .type = PT_STR, - .id = "langui", - .name = N_("Web interface language"), - .desc = N_("Web interface language."), - .list = language_get_ui_list, - .off = offsetof(access_entry_t, ae_lang_ui), - .opts = PO_ADVANCED, - }, - { - .type = PT_STR, - .id = "themeui", - .name = N_("Web theme"), - .desc = N_("Web interface theme."), - .doc = prop_doc_themes, - .list = theme_get_ui_list, - .off = offsetof(access_entry_t, ae_theme), - .opts = PO_DOC_NLIST | PO_ADVANCED, - }, - { - .type = PT_INT, - .islist = 1, - .id = "streaming", - .name = N_("Streaming"), - .desc = N_("Streaming flags, allow/disallow HTTP streaming, " - "advanced HTTP streaming (e.g, direct service or mux links), " - "HTSP protocol streaming (e.g, Kodi (via pvr.hts) or Movian."), - .list = access_entry_class_streaming_enum, - .get = access_entry_class_streaming_get, - .set = access_entry_class_streaming_set, - .rend = access_entry_class_streaming_rend, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .islist = 1, - .id = "profile", - .name = N_("Streaming profiles"), - .desc = N_("The streaming profile to use/used. If not set, " - "the default will be used."), - .doc = prop_doc_streaming_profile, - .set = access_entry_profile_set, - .get = access_entry_profile_get, - .list = profile_class_get_list, - .rend = access_entry_profile_rend, - .opts = PO_ADVANCED, - }, - { - .type = PT_INT, - .islist = 1, - .id = "dvr", - .name = N_("Video recorder"), - .desc = N_("Video recorder flags, allow/disallow access to video recorder " - "functionality (including Autorecs), allow/disallow users to " - "view other DVR entries, allow/disallow users to work with " - "DVR entries of other users (remove, edit) etc."), - .list = access_entry_class_dvr_enum, - .get = access_entry_class_dvr_get, - .set = access_entry_class_dvr_set, - .rend = access_entry_class_dvr_rend, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_BOOL, - .id = "htsp_anonymize", - .name = N_("Anonymize HTSP access"), - .desc = N_("Do not send any stream specific information to " - "the HTSP client like signal strength, input source " - "etc."), - .off = offsetof(access_entry_t, ae_htsp_anonymize), - .opts = PO_EXPERT | PO_HIDDEN, - }, - { - .type = PT_STR, - .islist = 1, - .id = "dvr_config", - .name = N_("DVR configuration profiles"), - .desc = N_("Allowed DVR profiles. This limits the profiles " - "the user has access to."), - .set = access_entry_dvr_config_set, - .get = access_entry_dvr_config_get, - .list = dvr_entry_class_config_name_list, - .rend = access_entry_dvr_config_rend, - .opts = PO_ADVANCED, - }, - { - .type = PT_BOOL, - .id = "webui", - .name = N_("Web interface"), - .desc = N_("Allow/Disallow web interface access (this " - " includes access to the EPG)."), - .off = offsetof(access_entry_t, ae_webui), - }, - { - .type = PT_BOOL, - .id = "admin", - .name = N_("Admin"), - .desc = N_("Allow/Disallow access to the 'Configuration' tab."), - .off = offsetof(access_entry_t, ae_admin), - }, - { - .type = PT_INT, - .id = "conn_limit_type", - .name = N_("Connection limit type"), - .desc = N_("Restrict connections to this type."), - .doc = prop_doc_connection_limit, - .off = offsetof(access_entry_t, ae_conn_limit_type), - .list = access_entry_conn_limit_type_enum, - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "conn_limit", - .name = N_("Limit connections"), - .desc = N_("The number of allowed connections this user can " - "make to the server."), - .off = offsetof(access_entry_t, ae_conn_limit), - .opts = PO_EXPERT - }, - { - .type = PT_S64, - .intextra = CHANNEL_SPLIT, - .id = "channel_min", - .name = N_("Minimal channel number"), - .desc = N_("Lowest channel number the user can access."), - .off = offsetof(access_entry_t, ae_chmin), - .opts = PO_ADVANCED, - }, - { - .type = PT_S64, - .intextra = CHANNEL_SPLIT, - .id = "channel_max", - .name = N_("Maximal channel number"), - .desc = N_("Highest channel number the user can access."), - .off = offsetof(access_entry_t, ae_chmax), - .opts = PO_ADVANCED, - }, - { - .type = PT_BOOL, - .id = "channel_tag_exclude", - .name = N_("Exclude channel tags"), - .desc = N_("Enable exclusion of user-config defined channel " - "tags. This will prevent the user from accessing " - "channels associated with the tags selected (below)."), - .off = offsetof(access_entry_t, ae_chtags_exclude), - .opts = PO_ADVANCED, - }, - { - .type = PT_STR, - .islist = 1, - .id = "channel_tag", - .name = N_("Channel tags"), - .desc = N_("Channel tags the user is allowed access to/excluded from."), - .set = access_entry_chtag_set, - .get = access_entry_chtag_get, - .list = channel_tag_class_get_list, - .rend = access_entry_chtag_rend, - .opts = PO_ADVANCED, - }, - { - .type = PT_INT, - .id = "xmltv_output_format", - .name = N_("Format for xmltv output"), - .desc = N_("Specify format for xmltv output."), - .doc = prop_doc_xmltv_output_format, - .off = offsetof(access_entry_t, ae_xmltv_output_format), - .list = access_entry_xmltv_output_format_enum, - .opts = PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_INT, - .id = "htsp_output_format", - .name = N_("Format for htsp output"), - .desc = N_("Specify format for htsp output."), - .doc = prop_doc_htsp_output_format, - .off = offsetof(access_entry_t, ae_htsp_output_format), - .list = access_entry_htsp_output_format_enum, - .opts = PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-form text field, enter whatever you like here."), - .off = offsetof(access_entry_t, ae_comment), - }, - { - .type = PT_BOOL, - .id = "wizard", - .name = N_("Wizard"), - .off = offsetof(access_entry_t, ae_wizard), - .opts = PO_NOUI - }, - {} - } -}; +const idclass_t access_entry_class = {.ic_class = "access", + .ic_caption = N_("Users - Access Entries"), + .ic_event = "access", + .ic_perm_def = ACCESS_ADMIN, + .ic_doc = tvh_doc_access_entry_class, + .ic_save = access_entry_class_save, + .ic_get_title = access_entry_class_get_title, + .ic_delete = access_entry_class_delete, + .ic_moveup = access_entry_class_moveup, + .ic_movedown = access_entry_class_movedown, + .ic_properties = (const property_t[]){{ + .type = PT_INT, + .id = "index", + .name = N_("Index"), + .off = offsetof(access_entry_t, ae_index), + .opts = PO_RDONLY | PO_HIDDEN | PO_NOUI, + }, + { + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/Disable the entry."), + .def.i = 1, + .off = offsetof(access_entry_t, ae_enabled), + }, + { + .type = PT_STR, + .id = "username", + .name = N_("Username"), + .desc = N_("Username for the entry (login username)."), + .off = offsetof(access_entry_t, ae_username), + }, + {.type = PT_STR, + .id = "prefix", + .name = N_("Allowed networks"), + .desc = N_("List of allowed IPv4 or IPv6 hosts or networks (comma-separated)."), + .set = access_entry_class_prefix_set, + .get = access_entry_class_prefix_get, + .opts = PO_ADVANCED}, + { + .type = PT_INT, + .islist = 1, + .id = "change", + .name = N_("Change parameters"), + .desc = N_("Specify the parameters to be changed. See Help for details."), + .doc = prop_doc_change_parameters, + .list = access_entry_class_change_enum, + .get = access_entry_class_change_get, + .set = access_entry_class_change_set, + .rend = access_entry_class_change_rend, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_INT, + .id = "uilevel", + .name = N_("User interface level"), + .desc = N_("Default user interface level."), + .doc = prop_doc_viewlevel_access_entries, + .off = offsetof(access_entry_t, ae_uilevel), + .list = uilevel_get_list, + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_INT, + .id = "uilevel_nochange", + .name = N_("Persistent user interface level"), + .desc = N_("Prevent the user from overriding the default user " + "interface level setting and removes the view level " + "drop-dowm from the interface."), + .doc = prop_doc_persistent_viewlevel, + .off = offsetof(access_entry_t, ae_uilevel_nochange), + .list = uilevel_nochange_get_list, + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "lang", + .name = N_("Language"), + .desc = N_("Default language."), + .list = language_get_list, + .off = offsetof(access_entry_t, ae_lang), + .opts = PO_ADVANCED, + }, + { + .type = PT_STR, + .id = "langui", + .name = N_("Web interface language"), + .desc = N_("Web interface language."), + .list = language_get_ui_list, + .off = offsetof(access_entry_t, ae_lang_ui), + .opts = PO_ADVANCED, + }, + { + .type = PT_STR, + .id = "themeui", + .name = N_("Web theme"), + .desc = N_("Web interface theme."), + .doc = prop_doc_themes, + .list = theme_get_ui_list, + .off = offsetof(access_entry_t, ae_theme), + .opts = PO_DOC_NLIST | PO_ADVANCED, + }, + { + .type = PT_INT, + .islist = 1, + .id = "streaming", + .name = N_("Streaming"), + .desc = N_("Streaming flags, allow/disallow HTTP streaming, " + "advanced HTTP streaming (e.g, direct service or mux links), " + "HTSP protocol streaming (e.g, Kodi (via pvr.hts) or Movian."), + .list = access_entry_class_streaming_enum, + .get = access_entry_class_streaming_get, + .set = access_entry_class_streaming_set, + .rend = access_entry_class_streaming_rend, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .islist = 1, + .id = "profile", + .name = N_("Streaming profiles"), + .desc = N_("The streaming profile to use/used. If not set, " + "the default will be used."), + .doc = prop_doc_streaming_profile, + .set = access_entry_profile_set, + .get = access_entry_profile_get, + .list = profile_class_get_list, + .rend = access_entry_profile_rend, + .opts = PO_ADVANCED, + }, + { + .type = PT_INT, + .islist = 1, + .id = "dvr", + .name = N_("Video recorder"), + .desc = N_("Video recorder flags, allow/disallow access to video recorder " + "functionality (including Autorecs), allow/disallow users to " + "view other DVR entries, allow/disallow users to work with " + "DVR entries of other users (remove, edit) etc."), + .list = access_entry_class_dvr_enum, + .get = access_entry_class_dvr_get, + .set = access_entry_class_dvr_set, + .rend = access_entry_class_dvr_rend, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_BOOL, + .id = "htsp_anonymize", + .name = N_("Anonymize HTSP access"), + .desc = N_("Do not send any stream specific information to " + "the HTSP client like signal strength, input source " + "etc."), + .off = offsetof(access_entry_t, ae_htsp_anonymize), + .opts = PO_EXPERT | PO_HIDDEN, + }, + { + .type = PT_STR, + .islist = 1, + .id = "dvr_config", + .name = N_("DVR configuration profiles"), + .desc = N_("Allowed DVR profiles. This limits the profiles " + "the user has access to."), + .set = access_entry_dvr_config_set, + .get = access_entry_dvr_config_get, + .list = dvr_entry_class_config_name_list, + .rend = access_entry_dvr_config_rend, + .opts = PO_ADVANCED, + }, + { + .type = PT_BOOL, + .id = "webui", + .name = N_("Web interface"), + .desc = N_("Allow/Disallow web interface access (this " + " includes access to the EPG)."), + .off = offsetof(access_entry_t, ae_webui), + }, + { + .type = PT_BOOL, + .id = "admin", + .name = N_("Admin"), + .desc = N_("Allow/Disallow access to the 'Configuration' tab."), + .off = offsetof(access_entry_t, ae_admin), + }, + { + .type = PT_INT, + .id = "conn_limit_type", + .name = N_("Connection limit type"), + .desc = N_("Restrict connections to this type."), + .doc = prop_doc_connection_limit, + .off = offsetof(access_entry_t, ae_conn_limit_type), + .list = access_entry_conn_limit_type_enum, + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + {.type = PT_U32, + .id = "conn_limit", + .name = N_("Limit connections"), + .desc = N_("The number of allowed connections this user can " + "make to the server."), + .off = offsetof(access_entry_t, ae_conn_limit), + .opts = PO_EXPERT}, + { + .type = PT_S64, + .intextra = CHANNEL_SPLIT, + .id = "channel_min", + .name = N_("Minimal channel number"), + .desc = N_("Lowest channel number the user can access."), + .off = offsetof(access_entry_t, ae_chmin), + .opts = PO_ADVANCED, + }, + { + .type = PT_S64, + .intextra = CHANNEL_SPLIT, + .id = "channel_max", + .name = N_("Maximal channel number"), + .desc = N_("Highest channel number the user can access."), + .off = offsetof(access_entry_t, ae_chmax), + .opts = PO_ADVANCED, + }, + { + .type = PT_BOOL, + .id = "channel_tag_exclude", + .name = N_("Exclude channel tags"), + .desc = N_("Enable exclusion of user-config defined channel " + "tags. This will prevent the user from accessing " + "channels associated with the tags selected (below)."), + .off = offsetof(access_entry_t, ae_chtags_exclude), + .opts = PO_ADVANCED, + }, + { + .type = PT_STR, + .islist = 1, + .id = "channel_tag", + .name = N_("Channel tags"), + .desc = N_("Channel tags the user is allowed access to/excluded from."), + .set = access_entry_chtag_set, + .get = access_entry_chtag_get, + .list = channel_tag_class_get_list, + .rend = access_entry_chtag_rend, + .opts = PO_ADVANCED, + }, + { + .type = PT_INT, + .id = "xmltv_output_format", + .name = N_("Format for xmltv output"), + .desc = N_("Specify format for xmltv output."), + .doc = prop_doc_xmltv_output_format, + .off = offsetof(access_entry_t, ae_xmltv_output_format), + .list = access_entry_xmltv_output_format_enum, + .opts = PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_INT, + .id = "htsp_output_format", + .name = N_("Format for htsp output"), + .desc = N_("Specify format for htsp output."), + .doc = prop_doc_htsp_output_format, + .off = offsetof(access_entry_t, ae_htsp_output_format), + .list = access_entry_htsp_output_format_enum, + .opts = PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-form text field, enter whatever you like here."), + .off = offsetof(access_entry_t, ae_comment), + }, + {.type = PT_BOOL, + .id = "wizard", + .name = N_("Wizard"), + .off = offsetof(access_entry_t, ae_wizard), + .opts = PO_NOUI}, + {}}}; /* * Password table */ -static int passwd_entry_class_password_set(void *o, const void *v); +static int passwd_entry_class_password_set(void* o, const void* v); -static int -passwd_verify2 - (const char *username, verify_callback_t verify, void *aux, - const char *username2, const char *passwd2) -{ - if (username == NULL || username[0] == '\0' || - username2 == NULL || username2[0] == '\0' || +static int passwd_verify2(const char* username, + verify_callback_t verify, + void* aux, + const char* username2, + const char* passwd2) { + if (username == NULL || username[0] == '\0' || username2 == NULL || username2[0] == '\0' || passwd2 == NULL) return -1; @@ -2008,16 +1850,12 @@ passwd_verify2 return verify(aux, passwd2) ? 0 : -1; } -static int -passwd_verify - (access_t *a, const char *username, verify_callback_t verify, void *aux) -{ - passwd_entry_t *pw; +static int passwd_verify(access_t* a, const char* username, verify_callback_t verify, void* aux) { + passwd_entry_t* pw; - TAILQ_FOREACH(pw, &passwd_entries, pw_link) + TAILQ_FOREACH (pw, &passwd_entries, pw_link) if (pw->pw_enabled && - !passwd_verify2(username, verify, aux, - pw->pw_username, pw->pw_password)) { + !passwd_verify2(username, verify, aux, pw->pw_username, pw->pw_password)) { if (pw->pw_auth_enabled) tvh_str_set(&a->aa_auth, pw->pw_auth); return 0; @@ -2025,24 +1863,21 @@ passwd_verify return -1; } -static void -passwd_entry_new_auth(passwd_entry_t *pw) -{ - static const char table[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-."; - uint8_t buf[20], *in; - char id[42], *dst; - unsigned int bits; - int len, shift; +static void passwd_entry_new_auth(passwd_entry_t* pw) { + static const char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-."; + uint8_t buf[20], *in; + char id[42], *dst; + unsigned int bits; + int len, shift; do { id[0] = 'P'; uuid_random(in = buf, sizeof(buf)); /* convert random bits to URL safe characters, modified base64 encoding */ - bits = 0; + bits = 0; shift = 0; - in = buf; - dst = id + 1; + in = buf; + dst = id + 1; for (len = sizeof(buf); len > 0; len--) { bits = (bits << 8) + *in++; shift += 8; @@ -2056,11 +1891,9 @@ passwd_entry_new_auth(passwd_entry_t *pw) tvh_str_set(&pw->pw_auth, id); } -passwd_entry_t * -passwd_entry_create(const char *uuid, htsmsg_t *conf) -{ - passwd_entry_t *pw; - const char *s; +passwd_entry_t* passwd_entry_create(const char* uuid, htsmsg_t* conf) { + passwd_entry_t* pw; + const char* s; lock_assert(&global_lock); @@ -2086,9 +1919,7 @@ passwd_entry_create(const char *uuid, htsmsg_t *conf) return pw; } -void -passwd_entry_destroy(passwd_entry_t *pw, int delconf) -{ +void passwd_entry_destroy(passwd_entry_t* pw, int delconf) { char ubuf[UUID_HEX_SIZE]; if (pw == NULL) @@ -2108,30 +1939,24 @@ passwd_entry_destroy(passwd_entry_t *pw, int delconf) free(pw); } -static htsmsg_t * -passwd_entry_class_save(idnode_t *self, char *filename, size_t fsize) -{ - passwd_entry_t *pw = (passwd_entry_t *)self; - char ubuf[UUID_HEX_SIZE]; - htsmsg_t *c = htsmsg_create_map(); +static htsmsg_t* passwd_entry_class_save(idnode_t* self, char* filename, size_t fsize) { + passwd_entry_t* pw = (passwd_entry_t*)self; + char ubuf[UUID_HEX_SIZE]; + htsmsg_t* c = htsmsg_create_map(); idnode_save(&pw->pw_id, c); if (filename) snprintf(filename, fsize, "passwd/%s", idnode_uuid_as_str(&pw->pw_id, ubuf)); return c; } -static void -passwd_entry_class_delete(idnode_t *self) -{ - passwd_entry_t *pw = (passwd_entry_t *)self; +static void passwd_entry_class_delete(idnode_t* self) { + passwd_entry_t* pw = (passwd_entry_t*)self; passwd_entry_destroy(pw, 1); } static void -passwd_entry_class_get_title - (idnode_t *self, const char *lang, char *dst, size_t dstsize) -{ - passwd_entry_t *pw = (passwd_entry_t *)self; +passwd_entry_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + passwd_entry_t* pw = (passwd_entry_t*)self; if (pw->pw_comment && pw->pw_comment[0] != '\0') { snprintf(dst, dstsize, "%s", pw->pw_comment); @@ -2140,108 +1965,91 @@ passwd_entry_class_get_title } } -static int -passwd_entry_class_password_set(void *o, const void *v) -{ - passwd_entry_t *pw = (passwd_entry_t *)o; - char buf[256], result[300]; +static int passwd_entry_class_password_set(void* o, const void* v) { + passwd_entry_t* pw = (passwd_entry_t*)o; + char buf[256], result[300]; if (strcmp(v ?: "", pw->pw_password ?: "")) { - snprintf(buf, sizeof(buf), "TVHeadend-Hide-%s", (const char *)v ?: ""); - base64_encode(result, sizeof(result), (uint8_t *)buf, strlen(buf)); + snprintf(buf, sizeof(buf), "TVHeadend-Hide-%s", (const char*)v ?: ""); + base64_encode(result, sizeof(result), (uint8_t*)buf, strlen(buf)); free(pw->pw_password2); pw->pw_password2 = strdup(result); free(pw->pw_password); - pw->pw_password = strdup((const char *)v ?: ""); + pw->pw_password = strdup((const char*)v ?: ""); return 1; } return 0; } -static int -passwd_entry_class_password2_set(void *o, const void *v) -{ - passwd_entry_t *pw = (passwd_entry_t *)o; - char result[300]; - int l; +static int passwd_entry_class_password2_set(void* o, const void* v) { + passwd_entry_t* pw = (passwd_entry_t*)o; + char result[300]; + int l; if (strcmp(v ?: "", pw->pw_password2 ?: "")) { - if (v && ((const char *)v)[0] != '\0') { - l = base64_decode((uint8_t *)result, v, sizeof(result)-1); + if (v && ((const char*)v)[0] != '\0') { + l = base64_decode((uint8_t*)result, v, sizeof(result) - 1); if (l < 0) l = 0; result[l] = '\0'; free(pw->pw_password); pw->pw_password = strdup(result + 15); free(pw->pw_password2); - pw->pw_password2 = strdup((const char *)v); + pw->pw_password2 = strdup((const char*)v); return 1; } } return 0; } -static int -passwd_entry_class_auth_enabled_set ( void *obj, idnode_slist_t *entry, int val ) -{ - passwd_entry_t *pw = (passwd_entry_t *)obj; - val = !!val; +static int passwd_entry_class_auth_enabled_set(void* obj, idnode_slist_t* entry, int val) { + passwd_entry_t* pw = (passwd_entry_t*)obj; + val = !!val; if (pw->pw_auth_enabled != val) { pw->pw_auth_enabled = val; if (val && strempty(pw->pw_auth)) - passwd_entry_new_auth((passwd_entry_t *)obj); + passwd_entry_new_auth((passwd_entry_t*)obj); return 1; } return 0; } -static int -passwd_entry_class_auth_reset_set ( void *obj, idnode_slist_t *entry, int val ) -{ +static int passwd_entry_class_auth_reset_set(void* obj, idnode_slist_t* entry, int val) { if (val) { - passwd_entry_new_auth((passwd_entry_t *)obj); + passwd_entry_new_auth((passwd_entry_t*)obj); return 1; } return 0; } static idnode_slist_t passwd_entry_class_auth_slist[] = { - { - .id = "enable", - .name = N_("Enable"), - .off = offsetof(passwd_entry_t, pw_auth_enabled), - .set = passwd_entry_class_auth_enabled_set, - }, - { - .id = "reset", - .name = N_("Reset"), - .off = 0, - .set = passwd_entry_class_auth_reset_set, - }, - {} -}; - -static htsmsg_t * -passwd_entry_class_auth_enum ( void *obj, const char *lang ) -{ + { + .id = "enable", + .name = N_("Enable"), + .off = offsetof(passwd_entry_t, pw_auth_enabled), + .set = passwd_entry_class_auth_enabled_set, + }, + { + .id = "reset", + .name = N_("Reset"), + .off = 0, + .set = passwd_entry_class_auth_reset_set, + }, + {}}; + +static htsmsg_t* passwd_entry_class_auth_enum(void* obj, const char* lang) { return idnode_slist_enum(obj, passwd_entry_class_auth_slist, lang); } -static const void * -passwd_entry_class_auth_get ( void *obj ) -{ +static const void* passwd_entry_class_auth_get(void* obj) { return idnode_slist_get(obj, passwd_entry_class_auth_slist); } -static char * -passwd_entry_class_auth_rend ( void *obj, const char *lang ) -{ +static char* passwd_entry_class_auth_rend(void* obj, const char* lang) { return idnode_slist_rend(obj, passwd_entry_class_auth_slist, lang); } -static int -passwd_entry_class_auth_set ( void *obj, const void *p ) -{ +static int passwd_entry_class_auth_set(void* obj, const void* p) { return idnode_slist_set(obj, passwd_entry_class_auth_slist, p); } @@ -2249,97 +2057,89 @@ CLASS_DOC(passwd) PROP_DOC(auth) PROP_DOC(authcode) -const idclass_t passwd_entry_class = { - .ic_class = "passwd", - .ic_caption = N_("Users - Passwords"), - .ic_event = "passwd", - .ic_perm_def = ACCESS_ADMIN, - .ic_doc = tvh_doc_passwd_class, - .ic_save = passwd_entry_class_save, - .ic_get_title = passwd_entry_class_get_title, - .ic_delete = passwd_entry_class_delete, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable the entry."), - .def.i = 1, - .off = offsetof(passwd_entry_t, pw_enabled), - }, - { - .type = PT_STR, - .id = "username", - .name = N_("Username"), - .desc = N_("Username of the entry (this should match a " - "username from within the \"Access Entries\" tab)."), - .off = offsetof(passwd_entry_t, pw_username), - }, - { - .type = PT_STR, - .id = "password", - .name = N_("Password"), - .desc = N_("Password for the entry."), - .off = offsetof(passwd_entry_t, pw_password), - .opts = PO_PASSWORD | PO_NOSAVE, - .set = passwd_entry_class_password_set, - }, - { - .type = PT_STR, - .id = "password2", - .name = N_("Password2"), - .off = offsetof(passwd_entry_t, pw_password2), - .opts = PO_PASSWORD | PO_HIDDEN | PO_EXPERT | PO_WRONCE | PO_NOUI, - .set = passwd_entry_class_password2_set, - }, - { - .type = PT_INT, - .islist = 1, - .id = "auth", - .name = N_("Persistent authentication"), - .desc = N_("Manage persistent authentication for HTTP streaming."), - .doc = prop_doc_auth, - .list = passwd_entry_class_auth_enum, - .get = passwd_entry_class_auth_get, - .set = passwd_entry_class_auth_set, - .rend = passwd_entry_class_auth_rend, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "authcode", - .name = N_("Persistent authentication code"), - .desc = N_("The code which may be used for HTTP streaming."), - .doc = prop_doc_authcode, - .off = offsetof(passwd_entry_t, pw_auth), - .opts = PO_RDONLY, - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-form text field, enter whatever you like here."), - .off = offsetof(passwd_entry_t, pw_comment), - }, - { - .type = PT_BOOL, - .id = "wizard", - .name = N_("Wizard"), - .off = offsetof(passwd_entry_t, pw_wizard), - .opts = PO_NOUI - }, - {} - } -}; +const idclass_t passwd_entry_class = {.ic_class = "passwd", + .ic_caption = N_("Users - Passwords"), + .ic_event = "passwd", + .ic_perm_def = ACCESS_ADMIN, + .ic_doc = tvh_doc_passwd_class, + .ic_save = passwd_entry_class_save, + .ic_get_title = passwd_entry_class_get_title, + .ic_delete = passwd_entry_class_delete, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable the entry."), + .def.i = 1, + .off = offsetof(passwd_entry_t, pw_enabled), + }, + { + .type = PT_STR, + .id = "username", + .name = N_("Username"), + .desc = N_("Username of the entry (this should match a " + "username from within the \"Access Entries\" tab)."), + .off = offsetof(passwd_entry_t, pw_username), + }, + { + .type = PT_STR, + .id = "password", + .name = N_("Password"), + .desc = N_("Password for the entry."), + .off = offsetof(passwd_entry_t, pw_password), + .opts = PO_PASSWORD | PO_NOSAVE, + .set = passwd_entry_class_password_set, + }, + { + .type = PT_STR, + .id = "password2", + .name = N_("Password2"), + .off = offsetof(passwd_entry_t, pw_password2), + .opts = PO_PASSWORD | PO_HIDDEN | PO_EXPERT | PO_WRONCE | PO_NOUI, + .set = passwd_entry_class_password2_set, + }, + { + .type = PT_INT, + .islist = 1, + .id = "auth", + .name = N_("Persistent authentication"), + .desc = N_("Manage persistent authentication for HTTP streaming."), + .doc = prop_doc_auth, + .list = passwd_entry_class_auth_enum, + .get = passwd_entry_class_auth_get, + .set = passwd_entry_class_auth_set, + .rend = passwd_entry_class_auth_rend, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "authcode", + .name = N_("Persistent authentication code"), + .desc = N_("The code which may be used for HTTP streaming."), + .doc = prop_doc_authcode, + .off = offsetof(passwd_entry_t, pw_auth), + .opts = PO_RDONLY, + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-form text field, enter whatever you like here."), + .off = offsetof(passwd_entry_t, pw_comment), + }, + {.type = PT_BOOL, + .id = "wizard", + .name = N_("Wizard"), + .off = offsetof(passwd_entry_t, pw_wizard), + .opts = PO_NOUI}, + {}}}; /** * IP block list */ -ipblock_entry_t * -ipblock_entry_create(const char *uuid, htsmsg_t *conf) -{ - ipblock_entry_t *ib; +ipblock_entry_t* ipblock_entry_create(const char* uuid, htsmsg_t* conf) { + ipblock_entry_t* ib; lock_assert(&global_lock); @@ -2364,9 +2164,7 @@ ipblock_entry_create(const char *uuid, htsmsg_t *conf) return ib; } -static void -ipblock_entry_destroy(ipblock_entry_t *ib, int delconf) -{ +static void ipblock_entry_destroy(ipblock_entry_t* ib, int delconf) { if (ib == NULL) return; idnode_save_check(&ib->ib_id, delconf); @@ -2376,12 +2174,10 @@ ipblock_entry_destroy(ipblock_entry_t *ib, int delconf) free(ib); } -static htsmsg_t * -ipblock_entry_class_save(idnode_t *self, char *filename, size_t fsize) -{ - ipblock_entry_t *ib = (ipblock_entry_t *)self; - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* ipblock_entry_class_save(idnode_t* self, char* filename, size_t fsize) { + ipblock_entry_t* ib = (ipblock_entry_t*)self; + htsmsg_t* c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(&ib->ib_id, c); if (filename) snprintf(filename, fsize, "ipblock/%s", idnode_uuid_as_str(&ib->ib_id, ubuf)); @@ -2389,10 +2185,8 @@ ipblock_entry_class_save(idnode_t *self, char *filename, size_t fsize) } static void -ipblock_entry_class_get_title - (idnode_t *self, const char *lang, char *dst, size_t dstsize) -{ - ipblock_entry_t *ib = (ipblock_entry_t *)self; +ipblock_entry_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + ipblock_entry_t* ib = (ipblock_entry_t*)self; if (ib->ib_comment && ib->ib_comment[0] != '\0') snprintf(dst, dstsize, "%s", ib->ib_comment); @@ -2400,79 +2194,67 @@ ipblock_entry_class_get_title snprintf(dst, dstsize, "%s", tvh_gettext_lang(lang, N_("IP blocking"))); } -static void -ipblock_entry_class_delete(idnode_t *self) -{ - ipblock_entry_t *ib = (ipblock_entry_t *)self; - char ubuf[UUID_HEX_SIZE]; +static void ipblock_entry_class_delete(idnode_t* self) { + ipblock_entry_t* ib = (ipblock_entry_t*)self; + char ubuf[UUID_HEX_SIZE]; hts_settings_remove("ipblock/%s", idnode_uuid_as_str(&ib->ib_id, ubuf)); ipblock_entry_destroy(ib, 1); } -static int -ipblock_entry_class_prefix_set(void *o, const void *v) -{ - access_set_prefix(&((ipblock_entry_t *)o)->ib_ipmasks, (const char *)v, 0); +static int ipblock_entry_class_prefix_set(void* o, const void* v) { + access_set_prefix(&((ipblock_entry_t*)o)->ib_ipmasks, (const char*)v, 0); return 1; } -static const void * -ipblock_entry_class_prefix_get(void *o) -{ - prop_ptr = access_get_prefix(&((ipblock_entry_t *)o)->ib_ipmasks); +static const void* ipblock_entry_class_prefix_get(void* o) { + prop_ptr = access_get_prefix(&((ipblock_entry_t*)o)->ib_ipmasks); return &prop_ptr; } CLASS_DOC(ipblocking) -const idclass_t ipblock_entry_class = { - .ic_class = "ipblocking", - .ic_caption = N_("Users - IP Blocking"), - .ic_event = "ipblocking", - .ic_perm_def = ACCESS_ADMIN, - .ic_doc = tvh_doc_ipblocking_class, - .ic_save = ipblock_entry_class_save, - .ic_get_title = ipblock_entry_class_get_title, - .ic_delete = ipblock_entry_class_delete, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable the entry."), - .off = offsetof(ipblock_entry_t, ib_enabled), - }, - { - .type = PT_STR, - .id = "prefix", - .name = N_("Network prefix"), - .desc = N_("The network prefix(es) to block, " - "e.g.192.168.2.0/24 (comma-separated list)."), - .set = ipblock_entry_class_prefix_set, - .get = ipblock_entry_class_prefix_get, - }, - { - .type = PT_STR, - .id = "comment", - .desc = N_("Free-form text field, enter whatever you like here."), - .name = N_("Comment"), - .off = offsetof(ipblock_entry_t, ib_comment), - }, - {} - } -}; +const idclass_t ipblock_entry_class = {.ic_class = "ipblocking", + .ic_caption = N_("Users - IP Blocking"), + .ic_event = "ipblocking", + .ic_perm_def = ACCESS_ADMIN, + .ic_doc = tvh_doc_ipblocking_class, + .ic_save = ipblock_entry_class_save, + .ic_get_title = ipblock_entry_class_get_title, + .ic_delete = ipblock_entry_class_delete, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable the entry."), + .off = offsetof(ipblock_entry_t, ib_enabled), + }, + { + .type = PT_STR, + .id = "prefix", + .name = N_("Network prefix"), + .desc = N_("The network prefix(es) to block, " + "e.g.192.168.2.0/24 (comma-separated list)."), + .set = ipblock_entry_class_prefix_set, + .get = ipblock_entry_class_prefix_get, + }, + { + .type = PT_STR, + .id = "comment", + .desc = N_("Free-form text field, enter whatever you like here."), + .name = N_("Comment"), + .off = offsetof(ipblock_entry_t, ib_comment), + }, + {}}}; /** * */ -void -access_init(int createdefault, int noacl) -{ - htsmsg_t *c, *m; - htsmsg_field_t *f; - access_entry_t *ae; - const char *s; +void access_init(int createdefault, int noacl) { + htsmsg_t * c, *m; + htsmsg_field_t* f; + access_entry_t* ae; + const char* s; access_noacl = noacl; if (noacl) @@ -2490,7 +2272,8 @@ access_init(int createdefault, int noacl) /* Load ipblock entries */ if ((c = hts_settings_load("ipblock")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(m = htsmsg_field_get_map(f))) continue; + if (!(m = htsmsg_field_get_map(f))) + continue; (void)ipblock_entry_create(htsmsg_field_name(f), m); } htsmsg_destroy(c); @@ -2499,7 +2282,8 @@ access_init(int createdefault, int noacl) /* Load passwd entries */ if ((c = hts_settings_load("passwd")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(m = htsmsg_field_get_map(f))) continue; + if (!(m = htsmsg_field_get_map(f))) + continue; (void)passwd_entry_create(htsmsg_field_name(f), m); } htsmsg_destroy(c); @@ -2508,14 +2292,15 @@ access_init(int createdefault, int noacl) /* Load ACL entries */ if ((c = hts_settings_load("accesscontrol")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(m = htsmsg_field_get_map(f))) continue; + if (!(m = htsmsg_field_get_map(f))) + continue; (void)access_entry_create(htsmsg_field_name(f), m); } htsmsg_destroy(c); access_entry_reindex(); } - if(createdefault && TAILQ_FIRST(&access_entries) == NULL) { + if (createdefault && TAILQ_FIRST(&access_entries) == NULL) { /* No records available */ ae = access_entry_create(NULL, NULL); @@ -2541,27 +2326,25 @@ access_init(int createdefault, int noacl) tvhwarn(LS_ACCESS, "Created default wide open access controle entry"); } - if(!TAILQ_FIRST(&access_entries) && !noacl) + if (!TAILQ_FIRST(&access_entries) && !noacl) tvherror(LS_ACCESS, "No access entries loaded"); /* Load superuser account */ - if((m = hts_settings_load("superuser")) != NULL) { - s = htsmsg_get_str(m, "username"); + if ((m = hts_settings_load("superuser")) != NULL) { + s = htsmsg_get_str(m, "username"); superuser_username = s ? strdup(s) : NULL; - s = htsmsg_get_str(m, "password"); + s = htsmsg_get_str(m, "password"); superuser_password = s ? strdup(s) : NULL; htsmsg_destroy(m); } } -void -access_done(void) -{ - access_entry_t *ae; - access_ticket_t *at; - passwd_entry_t *pw; - ipblock_entry_t *ib; +void access_done(void) { + access_entry_t* ae; + access_ticket_t* at; + passwd_entry_t* pw; + ipblock_entry_t* ib; tvh_mutex_lock(&global_lock); while ((ae = TAILQ_FIRST(&access_entries)) != NULL) @@ -2572,9 +2355,9 @@ access_done(void) passwd_entry_destroy(pw, 0); while ((ib = TAILQ_FIRST(&ipblock_entries)) != NULL) ipblock_entry_destroy(ib, 0); - free((void *)superuser_username); + free((void*)superuser_username); superuser_username = NULL; - free((void *)superuser_password); + free((void*)superuser_password); superuser_password = NULL; tvh_mutex_unlock(&global_lock); } diff --git a/src/access.h b/src/access.h index 4035d2584..613112a8d 100644 --- a/src/access.h +++ b/src/access.h @@ -23,7 +23,7 @@ #include "htsmsg.h" #define ACCESS_DEFAULT_COMMENT "Default access entry" -#define ACCESS_WIZARD_COMMENT "Wizard access entry" +#define ACCESS_WIZARD_COMMENT "Wizard access entry" struct profile; struct dvr_config; @@ -40,9 +40,9 @@ typedef struct ipblock_entry { TAILQ_ENTRY(ipblock_entry) ib_link; - int ib_enabled; + int ib_enabled; struct access_ipmask_queue ib_ipmasks; - char *ib_comment; + char* ib_comment; } ipblock_entry_t; extern const idclass_t ipblock_entry_class; @@ -56,17 +56,17 @@ typedef struct passwd_entry { TAILQ_ENTRY(passwd_entry) pw_link; - char *pw_username; - char *pw_password; - char *pw_password2; + char* pw_username; + char* pw_password; + char* pw_password2; - char *pw_auth; + char* pw_auth; - int pw_enabled; - int pw_auth_enabled; - int pw_wizard; + int pw_enabled; + int pw_auth_enabled; + int pw_wizard; - char *pw_comment; + char* pw_comment; } passwd_entry_t; extern const idclass_t passwd_entry_class; @@ -109,14 +109,14 @@ typedef struct access_entry { idnode_t ae_id; TAILQ_ENTRY(access_entry) ae_link; - char *ae_username; - char *ae_comment; - char *ae_lang; - int ae_change_lang; - char *ae_lang_ui; - int ae_change_lang_ui; - char *ae_theme; - int ae_change_theme; + char* ae_username; + char* ae_comment; + char* ae_lang; + int ae_change_lang; + char* ae_lang_ui; + int ae_change_lang_ui; + char* ae_theme; + int ae_change_theme; int ae_index; int ae_wizard; @@ -130,11 +130,11 @@ typedef struct access_entry { int ae_htsp_streaming; idnode_list_head_t ae_profiles; - int ae_change_profiles; + int ae_change_profiles; - int ae_conn_limit_type; + int ae_conn_limit_type; uint32_t ae_conn_limit; - int ae_change_conn_limit; + int ae_change_conn_limit; int ae_xmltv_output_format; int ae_change_xmltv_output_format; @@ -151,20 +151,20 @@ typedef struct access_entry { int ae_htsp_anonymize; idnode_list_head_t ae_dvr_configs; - int ae_change_dvr_configs; + int ae_change_dvr_configs; int ae_webui; int ae_admin; uint64_t ae_chmin; uint64_t ae_chmax; - int ae_change_chrange; + int ae_change_chrange; - int ae_chtags_exclude; + int ae_chtags_exclude; idnode_list_head_t ae_chtags; - int ae_change_chtags; + int ae_change_chtags; - int ae_change_rights; + int ae_change_rights; uint32_t ae_rights; struct access_ipmask_queue ae_ipmasks; @@ -175,17 +175,17 @@ LIST_HEAD(access_entry_list, access_entry); extern const idclass_t access_entry_class; typedef struct access { - char *aa_username; - char *aa_representative; - char *aa_lang; - char *aa_lang_ui; + char* aa_username; + char* aa_representative; + char* aa_lang; + char* aa_lang_ui; uint32_t aa_rights; - htsmsg_t *aa_profiles; - htsmsg_t *aa_dvrcfgs; - uint64_t *aa_chrange; + htsmsg_t* aa_profiles; + htsmsg_t* aa_dvrcfgs; + uint64_t* aa_chrange; int aa_chrange_count; - htsmsg_t *aa_chtags_exclude; - htsmsg_t *aa_chtags; + htsmsg_t* aa_chtags_exclude; + htsmsg_t* aa_chtags; int aa_match; uint32_t aa_conn_limit; uint32_t aa_conn_limit_streaming; @@ -196,8 +196,8 @@ typedef struct access { uint32_t aa_htsp_output_format; int aa_uilevel; int aa_uilevel_nochange; - char *aa_theme; - char *aa_auth; + char* aa_theme; + char* aa_auth; } access_t; TAILQ_HEAD(access_ticket_queue, access_ticket); @@ -205,79 +205,74 @@ TAILQ_HEAD(access_ticket_queue, access_ticket); extern struct access_ticket_queue access_tickets; typedef struct access_ticket { - char *at_id; + char* at_id; TAILQ_ENTRY(access_ticket) at_link; - mtimer_t at_timer; - char *at_resource; - access_t *at_access; + mtimer_t at_timer; + char* at_resource; + access_t* at_access; } access_ticket_t; #define ACCESS_ANONYMOUS 0 -#define ACCESS_STREAMING (1<<0) -#define ACCESS_ADVANCED_STREAMING (1<<1) -#define ACCESS_HTSP_STREAMING (1<<2) -#define ACCESS_WEB_INTERFACE (1<<3) -#define ACCESS_HTSP_INTERFACE (1<<4) -#define ACCESS_RECORDER (1<<5) -#define ACCESS_HTSP_RECORDER (1<<6) -#define ACCESS_ALL_RECORDER (1<<7) -#define ACCESS_ALL_RW_RECORDER (1<<8) -#define ACCESS_FAILED_RECORDER (1<<9) -#define ACCESS_HTSP_ANONYMIZE (1<<10) -#define ACCESS_ADMIN (1<<11) -#define ACCESS_NO_EMPTY_ARGS (1<<29) -#define ACCESS_OR (1<<30) - -#define ACCESS_FULL \ - (ACCESS_STREAMING | ACCESS_ADVANCED_STREAMING | \ - ACCESS_HTSP_STREAMING | ACCESS_WEB_INTERFACE | \ - ACCESS_RECORDER | ACCESS_HTSP_RECORDER | \ - ACCESS_ALL_RECORDER | ACCESS_ALL_RW_RECORDER | \ - ACCESS_FAILED_RECORDER | ACCESS_ADMIN) - -#define ACCESS_INTERNAL \ - (ACCESS_NO_EMPTY_ARGS) +#define ACCESS_STREAMING (1 << 0) +#define ACCESS_ADVANCED_STREAMING (1 << 1) +#define ACCESS_HTSP_STREAMING (1 << 2) +#define ACCESS_WEB_INTERFACE (1 << 3) +#define ACCESS_HTSP_INTERFACE (1 << 4) +#define ACCESS_RECORDER (1 << 5) +#define ACCESS_HTSP_RECORDER (1 << 6) +#define ACCESS_ALL_RECORDER (1 << 7) +#define ACCESS_ALL_RW_RECORDER (1 << 8) +#define ACCESS_FAILED_RECORDER (1 << 9) +#define ACCESS_HTSP_ANONYMIZE (1 << 10) +#define ACCESS_ADMIN (1 << 11) +#define ACCESS_NO_EMPTY_ARGS (1 << 29) +#define ACCESS_OR (1 << 30) + +#define ACCESS_FULL \ + (ACCESS_STREAMING | ACCESS_ADVANCED_STREAMING | ACCESS_HTSP_STREAMING | ACCESS_WEB_INTERFACE | \ + ACCESS_RECORDER | ACCESS_HTSP_RECORDER | ACCESS_ALL_RECORDER | ACCESS_ALL_RW_RECORDER | \ + ACCESS_FAILED_RECORDER | ACCESS_ADMIN) + +#define ACCESS_INTERNAL (ACCESS_NO_EMPTY_ARGS) /** * Create a new ticket for the requested resource and generate a id for it */ -const char* access_ticket_create(const char *resource, access_t *a); +const char* access_ticket_create(const char* resource, access_t* a); /** * Verifies that a given ticket id matches a resource */ -access_t *access_ticket_verify2(const char *id, const char *resource); +access_t* access_ticket_verify2(const char* id, const char* resource); -int access_ticket_delete(const char *ticket_id); +int access_ticket_delete(const char* ticket_id); /** * Free the access structure */ -void access_destroy(access_t *a); +void access_destroy(access_t* a); /** * Copy the access structure */ -access_t *access_copy(access_t *src); +access_t* access_copy(access_t* src); /** * Compare the access structures */ -int access_compare(access_t *a, access_t *b); +int access_compare(access_t* a, access_t* b); /** * */ -char * -access_get_lang(access_t *a, const char *lang); +char* access_get_lang(access_t* a, const char* lang); /** * */ -const char * -access_get_theme(access_t *a); +const char* access_get_theme(access_t* a); /** * Verifies that the given user in combination with the source ip @@ -285,74 +280,64 @@ access_get_theme(access_t *a); * * Return 0 if access is granted, -1 otherwise */ -static inline int access_verify2(const access_t *a, uint32_t mask) - { return a ? ((mask & ACCESS_OR) ? - ((a->aa_rights & mask) ? 0 : -1) : - ((a->aa_rights & mask) == mask ? 0 : -1)) : -1; } +static inline int access_verify2(const access_t* a, uint32_t mask) { + return a ? ((mask & ACCESS_OR) ? ((a->aa_rights & mask) ? 0 : -1) + : ((a->aa_rights & mask) == mask ? 0 : -1)) + : -1; +} -int access_verify_list(htsmsg_t *list, const char *item); +int access_verify_list(htsmsg_t* list, const char* item); /** * Get the access structure */ -typedef int (*verify_callback_t)(void *aux, const char *passwd); +typedef int (*verify_callback_t)(void* aux, const char* passwd); -access_t *access_get(struct sockaddr_storage *src, const char *username, - verify_callback_t verify, void *aux); +access_t* +access_get(struct sockaddr_storage* src, const char* username, verify_callback_t verify, void* aux); /** * */ -access_t * -access_get_by_username(const char *username); +access_t* access_get_by_username(const char* username); /** * */ -access_t * -access_get_by_addr(struct sockaddr_storage *src); +access_t* access_get_by_addr(struct sockaddr_storage* src); /** * */ -access_t * -access_get_by_auth(struct sockaddr_storage *src, const char *id); +access_t* access_get_by_auth(struct sockaddr_storage* src, const char* id); /** * */ -access_entry_t * -access_entry_create(const char *uuid, htsmsg_t *conf); +access_entry_t* access_entry_create(const char* uuid, htsmsg_t* conf); /** * */ -void -access_entry_destroy(access_entry_t *ae, int delconf); +void access_entry_destroy(access_entry_t* ae, int delconf); /** * */ -void -access_destroy_by_profile(struct profile *pro, int delconf); -void -access_destroy_by_dvr_config(struct dvr_config *cfg, int delconf); -void -access_destroy_by_channel_tag(struct channel_tag *ct, int delconf); +void access_destroy_by_profile(struct profile* pro, int delconf); +void access_destroy_by_dvr_config(struct dvr_config* cfg, int delconf); +void access_destroy_by_channel_tag(struct channel_tag* ct, int delconf); /** * */ -passwd_entry_t * -passwd_entry_create(const char *uuid, htsmsg_t *conf); -void -passwd_entry_destroy(passwd_entry_t *ae, int delconf); +passwd_entry_t* passwd_entry_create(const char* uuid, htsmsg_t* conf); +void passwd_entry_destroy(passwd_entry_t* ae, int delconf); /** * */ -ipblock_entry_t * -ipblock_entry_create(const char *uuid, htsmsg_t *conf); +ipblock_entry_t* ipblock_entry_create(const char* uuid, htsmsg_t* conf); /** * @@ -363,9 +348,9 @@ void access_done(void); /** * */ -htsmsg_t *language_get_list ( void *obj, const char *lang ); -htsmsg_t *language_get_ui_list ( void *obj, const char *lang ); -htsmsg_t *theme_get_ui_list ( void *obj, const char *lang ); -htsmsg_t *user_get_userlist ( void *obj, const char *lang ); +htsmsg_t* language_get_list(void* obj, const char* lang); +htsmsg_t* language_get_ui_list(void* obj, const char* lang); +htsmsg_t* theme_get_ui_list(void* obj, const char* lang); +htsmsg_t* user_get_userlist(void* obj, const char* lang); #endif /* ACCESS_H_ */ diff --git a/src/api.c b/src/api.c index 7e853aa95..753a6f428 100644 --- a/src/api.c +++ b/src/api.c @@ -24,26 +24,22 @@ #include typedef struct api_link { - const api_hook_t *hook; - RB_ENTRY(api_link) link; + const api_hook_t* hook; + RB_ENTRY(api_link) link; } api_link_t; -RB_HEAD(,api_link) api_hook_tree; +RB_HEAD(, api_link) api_hook_tree; SKEL_DECLARE(api_skel, api_link_t); -static int ah_cmp - ( api_link_t *a, api_link_t *b ) -{ +static int ah_cmp(api_link_t* a, api_link_t* b) { return strcmp(a->hook->ah_subsystem, b->hook->ah_subsystem); } -void -api_register ( const api_hook_t *hook ) -{ - api_link_t *t; +void api_register(const api_hook_t* hook) { + api_link_t* t; SKEL_ALLOC(api_skel); api_skel->hook = hook; - t = RB_INSERT_SORTED(&api_hook_tree, api_skel, link, ah_cmp); + t = RB_INSERT_SORTED(&api_hook_tree, api_skel, link, ah_cmp); if (t) { tvherror(LS_API, "trying to re-register subsystem"); } else { @@ -51,23 +47,18 @@ api_register ( const api_hook_t *hook ) } } -void -api_register_all ( const api_hook_t *hooks ) -{ +void api_register_all(const api_hook_t* hooks) { while (hooks->ah_subsystem) { api_register(hooks); hooks++; } } -int -api_exec ( access_t *perm, const char *subsystem, - htsmsg_t *args, htsmsg_t **resp ) -{ - api_hook_t h; +int api_exec(access_t* perm, const char* subsystem, htsmsg_t* args, htsmsg_t** resp) { + api_hook_t h; api_link_t *ah, skel; - const char *op; - uint32_t access; + const char* op; + uint32_t access; /* Args and response must be set */ if (!args || !resp || !subsystem) @@ -78,7 +69,7 @@ api_exec ( access_t *perm, const char *subsystem, // need updating) h.ah_subsystem = subsystem; skel.hook = &h; - ah = RB_FIND(&api_hook_tree, &skel, link, ah_cmp); + ah = RB_FIND(&api_hook_tree, &skel, link, ah_cmp); if (!ah) { tvhwarn(LS_API, "failed to find subsystem [%s]", subsystem); @@ -103,38 +94,31 @@ api_exec ( access_t *perm, const char *subsystem, } static int -api_serverinfo - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +api_serverinfo(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { *resp = htsmsg_create_map(); - htsmsg_add_str(*resp, "sw_version", tvheadend_version); - htsmsg_add_u32(*resp, "api_version", TVH_API_VERSION); - htsmsg_add_str(*resp, "name", "Tvheadend"); + htsmsg_add_str(*resp, "sw_version", tvheadend_version); + htsmsg_add_u32(*resp, "api_version", TVH_API_VERSION); + htsmsg_add_str(*resp, "name", "Tvheadend"); if (tvheadend_webroot) - htsmsg_add_str(*resp, "webroot", tvheadend_webroot); + htsmsg_add_str(*resp, "webroot", tvheadend_webroot); htsmsg_add_msg(*resp, "capabilities", tvheadend_capabilities_list(1)); return 0; } static int -api_pathlist - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - api_link_t *t; +api_pathlist(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + api_link_t* t; *resp = htsmsg_create_list(); - RB_FOREACH(t, &api_hook_tree, link) { + RB_FOREACH (t, &api_hook_tree, link) { htsmsg_add_str(*resp, NULL, t->hook->ah_subsystem); } return 0; } -void api_init ( void ) -{ - static api_hook_t h[] = { - { "serverinfo", ACCESS_ANONYMOUS, api_serverinfo, NULL }, - { "pathlist", ACCESS_ANONYMOUS, api_pathlist, NULL }, - { NULL, 0, NULL, NULL } - }; +void api_init(void) { + static api_hook_t h[] = {{"serverinfo", ACCESS_ANONYMOUS, api_serverinfo, NULL}, + {"pathlist", ACCESS_ANONYMOUS, api_pathlist, NULL}, + {NULL, 0, NULL, NULL}}; api_register_all(h); /* Subsystems */ @@ -164,9 +148,8 @@ void api_init ( void ) api_wizard_init(); } -void api_done ( void ) -{ - api_link_t *t; +void api_done(void) { + api_link_t* t; while ((t = RB_FIRST(&api_hook_tree)) != NULL) { RB_REMOVE(&api_hook_tree, t, link); diff --git a/src/api.h b/src/api.h index 7a815b426..c8e77edfe 100644 --- a/src/api.h +++ b/src/api.h @@ -31,61 +31,58 @@ * Command hook */ -typedef int (*api_callback_t) - ( access_t *perm, void *opaque, const char *op, - htsmsg_t *args, htsmsg_t **resp ); - -typedef struct api_hook -{ - const char *ah_subsystem; - uint32_t ah_access; - api_callback_t ah_callback; - void *ah_opaque; +typedef int ( + *api_callback_t)(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp); + +typedef struct api_hook { + const char* ah_subsystem; + uint32_t ah_access; + api_callback_t ah_callback; + void* ah_opaque; } api_hook_t; /* * Regsiter handler */ -void api_register ( const api_hook_t *hook ); -void api_register_all ( const api_hook_t *hooks ); +void api_register(const api_hook_t* hook); +void api_register_all(const api_hook_t* hooks); /* * Execute */ -int api_exec ( access_t *perm, const char *subsystem, - htsmsg_t *args, htsmsg_t **resp ); +int api_exec(access_t* perm, const char* subsystem, htsmsg_t* args, htsmsg_t** resp); /* * Initialise */ -void api_init ( void ); -void api_done ( void ); -void api_config_init ( void ); -void api_idnode_init ( void ); -void api_idnode_raw_init ( void ); -void api_input_init ( void ); -void api_service_init ( void ); -void api_channel_init ( void ); -void api_bouquet_init ( void ); -void api_ratinglabel_init ( void ); -void api_mpegts_init ( void ); -void api_epg_init ( void ); -void api_epggrab_init ( void ); -void api_status_init ( void ); -void api_imagecache_init ( void ); -void api_esfilter_init ( void ); -void api_intlconv_init ( void ); -void api_access_init ( void ); -void api_dvr_init ( void ); -void api_caclient_init ( void ); -void api_profile_init ( void ); -void api_language_init ( void ); -void api_satip_server_init ( void ); -void api_timeshift_init ( void ); -void api_wizard_init ( void ); +void api_init(void); +void api_done(void); +void api_config_init(void); +void api_idnode_init(void); +void api_idnode_raw_init(void); +void api_input_init(void); +void api_service_init(void); +void api_channel_init(void); +void api_bouquet_init(void); +void api_ratinglabel_init(void); +void api_mpegts_init(void); +void api_epg_init(void); +void api_epggrab_init(void); +void api_status_init(void); +void api_imagecache_init(void); +void api_esfilter_init(void); +void api_intlconv_init(void); +void api_access_init(void); +void api_dvr_init(void); +void api_caclient_init(void); +void api_profile_init(void); +void api_language_init(void); +void api_satip_server_init(void); +void api_timeshift_init(void); +void api_wizard_init(void); #if ENABLE_LIBAV -void api_codec_init ( void ); +void api_codec_init(void); #else static inline void api_codec_init(void) {}; #endif @@ -93,53 +90,60 @@ static inline void api_codec_init(void) {}; /* * IDnode */ -typedef struct api_idnode_grid_conf -{ +typedef struct api_idnode_grid_conf { uint32_t start; uint32_t limit; idnode_filter_t filter; idnode_sort_t sort; } api_idnode_grid_conf_t; -typedef void (*api_idnode_grid_callback_t) - (access_t *perm, idnode_set_t*, api_idnode_grid_conf_t*, htsmsg_t *args); -typedef idnode_set_t *(*api_idnode_tree_callback_t) - (access_t *perm); +typedef void (*api_idnode_grid_callback_t)(access_t* perm, + idnode_set_t*, + api_idnode_grid_conf_t*, + htsmsg_t* args); +typedef idnode_set_t* (*api_idnode_tree_callback_t)(access_t* perm); -htsmsg_t *api_idnode_flist_conf - ( htsmsg_t *args, const char *name ); +htsmsg_t* api_idnode_flist_conf(htsmsg_t* args, const char* name); -int api_idnode_grid - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ); +int api_idnode_grid(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp); -int api_idnode_class - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ); +int api_idnode_class(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp); -int api_idnode_tree - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ); +int api_idnode_tree(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp); -int api_idnode_load_by_class - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ); +int api_idnode_load_by_class(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp); -int api_idnode_handler - ( const idclass_t *idc, access_t *perm, htsmsg_t *args, htsmsg_t **resp, - void (*handler)(access_t *perm, idnode_t *in), const char *op, int destroyed ); +int api_idnode_handler(const idclass_t* idc, + access_t* perm, + htsmsg_t* args, + htsmsg_t** resp, + void (*handler)(access_t* perm, idnode_t* in), + const char* op, + int destroyed); -int api_idnode_load_simple - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ); +int api_idnode_load_simple(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp); -int api_idnode_save_simple - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ); +int api_idnode_save_simple(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp); -void api_idnode_create - ( htsmsg_t **resp, idnode_t *in ); +void api_idnode_create(htsmsg_t** resp, idnode_t* in); -void api_idnode_create_list - ( htsmsg_t **resp, htsmsg_t *list ); +void api_idnode_create_list(htsmsg_t** resp, htsmsg_t* list); /* * Service mapper */ -void api_service_mapper_notify ( void ); +void api_service_mapper_notify(void); #endif /* __TVH_API_H__ */ diff --git a/src/api/api_access.c b/src/api/api_access.c index 24279b97b..7aa1eafca 100644 --- a/src/api/api_access.c +++ b/src/api/api_access.c @@ -25,24 +25,25 @@ * */ -static void -api_passwd_entry_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - passwd_entry_t *pw; +static void api_passwd_entry_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + passwd_entry_t* pw; - TAILQ_FOREACH(pw, &passwd_entries, pw_link) + TAILQ_FOREACH (pw, &passwd_entries, pw_link) idnode_set_add(ins, (idnode_t*)pw, &conf->filter, perm->aa_lang_ui); } -static int -api_passwd_entry_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_t *conf; - passwd_entry_t *pw; +static int api_passwd_entry_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_t* conf; + passwd_entry_t* pw; - if (!(conf = htsmsg_get_map(args, "conf"))) + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; tvh_mutex_lock(&global_lock); @@ -57,24 +58,25 @@ api_passwd_entry_create * */ -static void -api_ipblock_entry_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - ipblock_entry_t *ib; +static void api_ipblock_entry_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + ipblock_entry_t* ib; - TAILQ_FOREACH(ib, &ipblock_entries, ib_link) + TAILQ_FOREACH (ib, &ipblock_entries, ib_link) idnode_set_add(ins, (idnode_t*)ib, &conf->filter, perm->aa_lang_ui); } -static int -api_ipblock_entry_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_t *conf; - ipblock_entry_t *ib; +static int api_ipblock_entry_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_t* conf; + ipblock_entry_t* ib; - if (!(conf = htsmsg_get_map(args, "conf"))) + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; tvh_mutex_lock(&global_lock); @@ -89,15 +91,16 @@ api_ipblock_entry_create * */ -static int -api_access_entry_userlist - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int i; - idnode_set_t *is; - idnode_t *in; - access_entry_t *ae; - htsmsg_t *l; +static int api_access_entry_userlist(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int i; + idnode_set_t* is; + idnode_t* in; + access_entry_t* ae; + htsmsg_t* l; l = htsmsg_create_list(); @@ -111,9 +114,8 @@ api_access_entry_userlist if (idnode_perm(in, perm, NULL)) continue; - ae = (access_entry_t *)in; - if (ae->ae_username != NULL && ae->ae_username[0] != '\0' && - ae->ae_username[0] != '*') + ae = (access_entry_t*)in; + if (ae->ae_username != NULL && ae->ae_username[0] != '\0' && ae->ae_username[0] != '*') htsmsg_add_msg(l, NULL, htsmsg_create_key_val(ae->ae_username, ae->ae_username)); idnode_perm_unset(in); @@ -129,24 +131,25 @@ empty: return 0; } -static void -api_access_entry_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - access_entry_t *ae; +static void api_access_entry_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + access_entry_t* ae; - TAILQ_FOREACH(ae, &access_entries, ae_link) + TAILQ_FOREACH (ae, &access_entries, ae_link) idnode_set_add(ins, (idnode_t*)ae, &conf->filter, perm->aa_lang_ui); } -static int -api_access_entry_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_t *conf; - access_entry_t *ae; +static int api_access_entry_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_t* conf; + access_entry_t* ae; - if (!(conf = htsmsg_get_map(args, "conf"))) + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; tvh_mutex_lock(&global_lock); @@ -157,23 +160,22 @@ api_access_entry_create return 0; } -void api_access_init ( void ) -{ +void api_access_init(void) { static api_hook_t ah[] = { - { "passwd/entry/class", ACCESS_ADMIN, api_idnode_class, (void*)&passwd_entry_class }, - { "passwd/entry/grid", ACCESS_ADMIN, api_idnode_grid, api_passwd_entry_grid }, - { "passwd/entry/create", ACCESS_ADMIN, api_passwd_entry_create, NULL }, + {"passwd/entry/class", ACCESS_ADMIN, api_idnode_class, (void*)&passwd_entry_class}, + {"passwd/entry/grid", ACCESS_ADMIN, api_idnode_grid, api_passwd_entry_grid}, + {"passwd/entry/create", ACCESS_ADMIN, api_passwd_entry_create, NULL}, - { "ipblock/entry/class", ACCESS_ADMIN, api_idnode_class, (void*)&ipblock_entry_class }, - { "ipblock/entry/grid", ACCESS_ADMIN, api_idnode_grid, api_ipblock_entry_grid }, - { "ipblock/entry/create", ACCESS_ADMIN, api_ipblock_entry_create, NULL }, + {"ipblock/entry/class", ACCESS_ADMIN, api_idnode_class, (void*)&ipblock_entry_class}, + {"ipblock/entry/grid", ACCESS_ADMIN, api_idnode_grid, api_ipblock_entry_grid}, + {"ipblock/entry/create", ACCESS_ADMIN, api_ipblock_entry_create, NULL}, - { "access/entry/class", ACCESS_ADMIN, api_idnode_class, (void*)&access_entry_class }, - { "access/entry/userlist", ACCESS_ANONYMOUS, api_access_entry_userlist, NULL }, - { "access/entry/grid", ACCESS_ADMIN, api_idnode_grid, api_access_entry_grid }, - { "access/entry/create", ACCESS_ADMIN, api_access_entry_create, NULL }, + {"access/entry/class", ACCESS_ADMIN, api_idnode_class, (void*)&access_entry_class}, + {"access/entry/userlist", ACCESS_ANONYMOUS, api_access_entry_userlist, NULL}, + {"access/entry/grid", ACCESS_ADMIN, api_idnode_grid, api_access_entry_grid}, + {"access/entry/create", ACCESS_ADMIN, api_access_entry_create, NULL}, - { NULL }, + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_bouquet.c b/src/api/api_bouquet.c index cbf196b73..fb0150ec9 100644 --- a/src/api/api_bouquet.c +++ b/src/api/api_bouquet.c @@ -26,17 +26,17 @@ #include "api.h" static int -api_bouquet_list - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - bouquet_t *bq; - htsmsg_t *l; - char ubuf[UUID_HEX_SIZE]; +api_bouquet_list(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + bouquet_t* bq; + htsmsg_t* l; + char ubuf[UUID_HEX_SIZE]; l = htsmsg_create_list(); tvh_mutex_lock(&global_lock); - RB_FOREACH(bq, &bouquets, bq_link) - htsmsg_add_msg(l, NULL, htsmsg_create_key_val(idnode_uuid_as_str(&bq->bq_id, ubuf), bq->bq_name ?: "")); + RB_FOREACH (bq, &bouquets, bq_link) + htsmsg_add_msg(l, + NULL, + htsmsg_create_key_val(idnode_uuid_as_str(&bq->bq_id, ubuf), bq->bq_name ?: "")); tvh_mutex_unlock(&global_lock); *resp = htsmsg_create_map(); htsmsg_add_msg(*resp, "entries", l); @@ -44,23 +44,18 @@ api_bouquet_list return 0; } -static void -api_bouquet_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf ) -{ - bouquet_t *bq; +static void api_bouquet_grid(access_t* perm, idnode_set_t* ins, api_idnode_grid_conf_t* conf) { + bouquet_t* bq; - RB_FOREACH(bq, &bouquets, bq_link) + RB_FOREACH (bq, &bouquets, bq_link) idnode_set_add(ins, (idnode_t*)bq, &conf->filter, perm->aa_lang_ui); } static int -api_bouquet_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_t *conf; - bouquet_t *bq; - const char *s; +api_bouquet_create(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + htsmsg_t* conf; + bouquet_t* bq; + const char* s; if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; @@ -77,21 +72,23 @@ api_bouquet_create return 0; } -static int -bouquet_cb - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp, - int (*cb)(const char *uuid) ) -{ - htsmsg_field_t *f; - htsmsg_t *uuids; - const char *uuid; - int r = 0; +static int bouquet_cb(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp, + int (*cb)(const char* uuid)) { + htsmsg_field_t* f; + htsmsg_t* uuids; + const char* uuid; + int r = 0; if (!(f = htsmsg_field_find(args, "uuid"))) return EINVAL; if ((uuids = htsmsg_field_get_list(f))) { HTSMSG_FOREACH(f, uuids) { - if (!(uuid = htsmsg_field_get_str(f))) continue; + if (!(uuid = htsmsg_field_get_str(f))) + continue; tvh_mutex_lock(&global_lock); cb(uuid); tvh_mutex_unlock(&global_lock); @@ -107,9 +104,8 @@ bouquet_cb return r; } -static int bouquet_cb_scan(const char *uuid) -{ - bouquet_t *bq = bouquet_find_by_uuid(uuid); +static int bouquet_cb_scan(const char* uuid) { + bouquet_t* bq = bouquet_find_by_uuid(uuid); if (bq) { bouquet_scan(bq); return 0; @@ -118,15 +114,12 @@ static int bouquet_cb_scan(const char *uuid) } static int -api_bouquet_scan - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +api_bouquet_scan(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { return bouquet_cb(perm, opaque, op, args, resp, bouquet_cb_scan); } -static int bouquet_cb_detach(const char *uuid) -{ - channel_t *ch = channel_find_by_uuid(uuid); +static int bouquet_cb_detach(const char* uuid) { + channel_t* ch = channel_find_by_uuid(uuid); if (ch) { bouquet_detach(ch); return 0; @@ -135,23 +128,20 @@ static int bouquet_cb_detach(const char *uuid) } static int -api_bouquet_detach - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +api_bouquet_detach(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { return bouquet_cb(perm, opaque, op, args, resp, bouquet_cb_detach); } -void api_bouquet_init ( void ) -{ +void api_bouquet_init(void) { static api_hook_t ah[] = { - { "bouquet/list", ACCESS_ADMIN, api_bouquet_list, NULL }, - { "bouquet/class", ACCESS_ADMIN, api_idnode_class, (void*)&bouquet_class }, - { "bouquet/grid", ACCESS_ADMIN, api_idnode_grid, api_bouquet_grid }, - { "bouquet/create", ACCESS_ADMIN, api_bouquet_create, NULL }, - { "bouquet/scan", ACCESS_ADMIN, api_bouquet_scan, NULL }, - { "bouquet/detach", ACCESS_ADMIN, api_bouquet_detach, NULL }, - - { NULL }, + {"bouquet/list", ACCESS_ADMIN, api_bouquet_list, NULL}, + {"bouquet/class", ACCESS_ADMIN, api_idnode_class, (void*)&bouquet_class}, + {"bouquet/grid", ACCESS_ADMIN, api_idnode_grid, api_bouquet_grid}, + {"bouquet/create", ACCESS_ADMIN, api_bouquet_create, NULL}, + {"bouquet/scan", ACCESS_ADMIN, api_bouquet_scan, NULL}, + {"bouquet/detach", ACCESS_ADMIN, api_bouquet_detach, NULL}, + + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_caclient.c b/src/api/api_caclient.c index ad24820d8..07096284b 100644 --- a/src/api/api_caclient.c +++ b/src/api/api_caclient.c @@ -27,16 +27,14 @@ * */ static int -api_caclient_list - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - caclient_t *cac; - htsmsg_t *l, *e; - char buf[384]; +api_caclient_list(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + caclient_t* cac; + htsmsg_t * l, *e; + char buf[384]; l = htsmsg_create_list(); tvh_mutex_lock(&global_lock); - TAILQ_FOREACH(cac, &caclients, cac_link) { + TAILQ_FOREACH (cac, &caclients, cac_link) { e = htsmsg_create_map(); htsmsg_add_uuid(e, "uuid", &cac->cac_id.in_uuid); htsmsg_add_str(e, "title", idnode_get_title(&cac->cac_id, perm->aa_lang_ui, buf, sizeof(buf))); @@ -49,12 +47,13 @@ api_caclient_list return 0; } -static int -api_caclient_builders - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - const idclass_t **r; - htsmsg_t *l, *e; +static int api_caclient_builders(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + const idclass_t** r; + htsmsg_t * l, *e; /* List of available builder classes */ l = htsmsg_create_list(); @@ -70,17 +69,15 @@ api_caclient_builders } static int -api_caclient_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err = 0; - const char *clazz; - htsmsg_t *conf; - caclient_t *cac; +api_caclient_create(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + int err = 0; + const char* clazz; + htsmsg_t* conf; + caclient_t* cac; if (!(clazz = htsmsg_get_str(args, "class"))) return EINVAL; - if (!(conf = htsmsg_get_map(args, "conf"))) + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; htsmsg_set_str(conf, "class", clazz); @@ -98,15 +95,13 @@ api_caclient_create /* * Init */ -void -api_caclient_init ( void ) -{ +void api_caclient_init(void) { static api_hook_t ah[] = { - { "caclient/list", ACCESS_ADMIN, api_caclient_list, NULL }, - { "caclient/class", ACCESS_ADMIN, api_idnode_class, (void*)&caclient_class }, - { "caclient/builders", ACCESS_ADMIN, api_caclient_builders, NULL }, - { "caclient/create", ACCESS_ADMIN, api_caclient_create, NULL }, - { NULL }, + {"caclient/list", ACCESS_ADMIN, api_caclient_list, NULL}, + {"caclient/class", ACCESS_ADMIN, api_idnode_class, (void*)&caclient_class}, + {"caclient/builders", ACCESS_ADMIN, api_caclient_builders, NULL}, + {"caclient/create", ACCESS_ADMIN, api_caclient_create, NULL}, + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_channel.c b/src/api/api_channel.c index b67051da4..f17a4ff3a 100644 --- a/src/api/api_channel.c +++ b/src/api/api_channel.c @@ -26,40 +26,35 @@ #include "api.h" #include "string_list.h" -static int -api_channel_is_all(access_t *perm, htsmsg_t *args) -{ - return htsmsg_get_bool_or_default(args, "all", 0) && - !access_verify2(perm, ACCESS_ADMIN); +static int api_channel_is_all(access_t* perm, htsmsg_t* args) { + return htsmsg_get_bool_or_default(args, "all", 0) && !access_verify2(perm, ACCESS_ADMIN); } static int -api_channel_list - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - channel_t *ch, **chlist; - htsmsg_t *l; - const int cfg = api_channel_is_all(perm, args); - const int numbers = htsmsg_get_s32_or_default(args, "numbers", 0); - const int sources = htsmsg_get_s32_or_default(args, "sources", 0); - const int flags = (numbers ? CHANNEL_ENAME_NUMBERS : 0) | - (sources ? CHANNEL_ENAME_SOURCES : 0); - char buf[128], buf1[128], ubuf[UUID_HEX_SIZE]; +api_channel_list(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + channel_t * ch, **chlist; + htsmsg_t* l; + const int cfg = api_channel_is_all(perm, args); + const int numbers = htsmsg_get_s32_or_default(args, "numbers", 0); + const int sources = htsmsg_get_s32_or_default(args, "sources", 0); + const int flags = (numbers ? CHANNEL_ENAME_NUMBERS : 0) | (sources ? CHANNEL_ENAME_SOURCES : 0); + char buf[128], buf1[128], ubuf[UUID_HEX_SIZE]; const char *name, *blank, *sort = htsmsg_get_str(args, "sort"); - int i, count; + int i, count; sort = htsmsg_get_str(args, "sort"); - if (numbers && !sort) sort = "numname"; + if (numbers && !sort) + sort = "numname"; blank = tvh_gettext_lang(perm->aa_lang_ui, channel_blank_name); - l = htsmsg_create_list(); + l = htsmsg_create_list(); tvh_mutex_lock(&global_lock); chlist = channel_get_sorted_list(sort, cfg, &count); for (i = 0; i < count; i++) { ch = chlist[i]; - if (!cfg && !channel_access(ch, perm, 0)) continue; + if (!cfg && !channel_access(ch, perm, 0)) + continue; if (!ch->ch_enabled) { - snprintf(buf, sizeof(buf), "{%s}", - channel_get_ename(ch, buf1, sizeof(buf1), blank, flags)); + snprintf(buf, sizeof(buf), "{%s}", channel_get_ename(ch, buf1, sizeof(buf1), blank, flags)); name = buf; } else { name = channel_get_ename(ch, buf1, sizeof(buf1), blank, flags); @@ -70,30 +65,26 @@ api_channel_list free(chlist); *resp = htsmsg_create_map(); htsmsg_add_msg(*resp, "entries", l); - + return 0; } static void -api_channel_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - channel_t *ch; - int cfg = api_channel_is_all(perm, args); +api_channel_grid(access_t* perm, idnode_set_t* ins, api_idnode_grid_conf_t* conf, htsmsg_t* args) { + channel_t* ch; + int cfg = api_channel_is_all(perm, args); CHANNEL_FOREACH(ch) - if (cfg || channel_access(ch, perm, 0)) - idnode_set_add(ins, (idnode_t*)ch, &conf->filter, perm->aa_lang_ui); + if (cfg || channel_access(ch, perm, 0)) + idnode_set_add(ins, (idnode_t*)ch, &conf->filter, perm->aa_lang_ui); } static int -api_channel_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_t *conf; - channel_t *ch; +api_channel_create(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + htsmsg_t* conf; + channel_t* ch; - if (!(conf = htsmsg_get_map(args, "conf"))) + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; tvh_mutex_lock(&global_lock); @@ -106,9 +97,7 @@ api_channel_create } static int -api_channel_rename - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +api_channel_rename(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { const char *from, *to; if (!(from = htsmsg_get_str(args, "from"))) return EINVAL; @@ -122,18 +111,19 @@ api_channel_rename return num_match > 0 ? 0 : ENOENT; } -static int -api_channel_tag_list - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - channel_tag_t *ct; - htsmsg_t *l; - int cfg = api_channel_is_all(perm, args); - char buf[128], ubuf[UUID_HEX_SIZE], *name; +static int api_channel_tag_list(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + channel_tag_t* ct; + htsmsg_t* l; + int cfg = api_channel_is_all(perm, args); + char buf[128], ubuf[UUID_HEX_SIZE], *name; l = htsmsg_create_list(); tvh_mutex_lock(&global_lock); - TAILQ_FOREACH(ct, &channel_tags, ct_link) + TAILQ_FOREACH (ct, &channel_tags, ct_link) if (cfg || channel_tag_access(ct, perm, 0)) { if (ct->ct_enabled) { name = ct->ct_name; @@ -149,26 +139,27 @@ api_channel_tag_list return 0; } -static void -api_channel_tag_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - channel_tag_t *ct; - int cfg = api_channel_is_all(perm, args); +static void api_channel_tag_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + channel_tag_t* ct; + int cfg = api_channel_is_all(perm, args); - TAILQ_FOREACH(ct, &channel_tags, ct_link) + TAILQ_FOREACH (ct, &channel_tags, ct_link) if (cfg || channel_tag_access(ct, perm, 0)) idnode_set_add(ins, (idnode_t*)ct, &conf->filter, perm->aa_lang_ui); } -static int -api_channel_tag_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_t *conf; - channel_tag_t *ct; +static int api_channel_tag_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_t* conf; + channel_tag_t* ct; - if (!(conf = htsmsg_get_map(args, "conf"))) + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; tvh_mutex_lock(&global_lock); @@ -180,29 +171,32 @@ api_channel_tag_create return 0; } -static int -api_channel_cat_list - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - channel_t *ch; - int cfg = api_channel_is_all(perm, args); +static int api_channel_cat_list(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + channel_t* ch; + int cfg = api_channel_is_all(perm, args); - htsmsg_t *l = htsmsg_create_list(); - string_list_t *sl = string_list_create(); - const string_list_item_t *item; + htsmsg_t* l = htsmsg_create_list(); + string_list_t* sl = string_list_create(); + const string_list_item_t* item; tvh_mutex_lock(&global_lock); /* Build string_list of all categories the user is allowed * to see. */ CHANNEL_FOREACH(ch) { - if (!cfg && !channel_access(ch, perm, 0)) continue; - if (!ch->ch_enabled) continue; - epg_broadcast_t *e; - RB_FOREACH(e, &ch->ch_epg_schedule, sched_link) { + if (!cfg && !channel_access(ch, perm, 0)) + continue; + if (!ch->ch_enabled) + continue; + epg_broadcast_t* e; + RB_FOREACH (e, &ch->ch_epg_schedule, sched_link) { if (e->category) { - RB_FOREACH(item, e->category, h_link) { - const char *id = item->id; + RB_FOREACH (item, e->category, h_link) { + const char* id = item->id; /* Get rid of duplicates */ string_list_insert(sl, id); } @@ -212,8 +206,8 @@ api_channel_cat_list tvh_mutex_unlock(&global_lock); /* Now we have the unique list, convert it for GUI. */ - RB_FOREACH(item, sl, h_link) { - const char *id = item->id; + RB_FOREACH (item, sl, h_link) { + const char* id = item->id; htsmsg_add_msg(l, NULL, htsmsg_create_key_val(id, id)); } @@ -224,27 +218,24 @@ api_channel_cat_list return 0; } - -void api_channel_init ( void ) -{ +void api_channel_init(void) { static api_hook_t ah[] = { - { "channel/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&channel_class }, - { "channel/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_channel_grid }, - { "channel/list", ACCESS_ANONYMOUS, api_channel_list, NULL }, - { "channel/create", ACCESS_ADMIN, api_channel_create, NULL }, - { "channel/rename", ACCESS_ADMIN, api_channel_rename, NULL }, /* User convenience function */ - - { "channeltag/class",ACCESS_ANONYMOUS, api_idnode_class, (void*)&channel_tag_class }, - { "channeltag/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_channel_tag_grid }, - { "channeltag/list", ACCESS_ANONYMOUS, api_channel_tag_list, NULL }, - { "channeltag/create", ACCESS_ADMIN, api_channel_tag_create, NULL }, - - { "channelcategory/list", ACCESS_ANONYMOUS, api_channel_cat_list, NULL }, - { NULL }, + {"channel/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&channel_class}, + {"channel/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_channel_grid}, + {"channel/list", ACCESS_ANONYMOUS, api_channel_list, NULL}, + {"channel/create", ACCESS_ADMIN, api_channel_create, NULL}, + {"channel/rename", ACCESS_ADMIN, api_channel_rename, NULL}, /* User convenience function */ + + {"channeltag/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&channel_tag_class}, + {"channeltag/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_channel_tag_grid}, + {"channeltag/list", ACCESS_ANONYMOUS, api_channel_tag_list, NULL}, + {"channeltag/create", ACCESS_ADMIN, api_channel_tag_create, NULL}, + + {"channelcategory/list", ACCESS_ANONYMOUS, api_channel_cat_list, NULL}, + {NULL}, }; api_register_all(ah); } - #endif /* __TVH_API_CHANNEL_H__ */ diff --git a/src/api/api_codec.c b/src/api/api_codec.c index 23cfbd476..86a748f26 100644 --- a/src/api/api_codec.c +++ b/src/api/api_codec.c @@ -17,122 +17,107 @@ * along with this program. If not, see . */ - #include "tvheadend.h" #include "access.h" #include "api.h" #include "transcoding/codec.h" - static int -api_codec_list(access_t *perm, void *opaque, const char *op, - htsmsg_t *args, htsmsg_t **resp) -{ - htsmsg_t *list = NULL, *map = NULL; - TVHCodec *tvh_codec = NULL; - int err = ENOMEM; +api_codec_list(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + htsmsg_t *list = NULL, *map = NULL; + TVHCodec* tvh_codec = NULL; + int err = ENOMEM; - if ((list = htsmsg_create_list())) { - tvh_mutex_lock(&global_lock); - SLIST_FOREACH(tvh_codec, &tvh_codecs, link) { - if (!(map = idclass_serialize(tvh_codec_get_class(tvh_codec), - perm->aa_lang_ui))) { - htsmsg_destroy(list); - list = NULL; - break; - } - htsmsg_add_str(map, "name", tvh_codec_get_name(tvh_codec)); - htsmsg_add_str(map, "title", tvh_codec_get_title(tvh_codec)); - htsmsg_add_msg(list, NULL, map); - } - tvh_mutex_unlock(&global_lock); - if (list) { - if ((*resp = htsmsg_create_map())) { - htsmsg_add_msg(*resp, "entries", list); - err = 0; - } - else { - htsmsg_destroy(list); - list = NULL; - } - } + if ((list = htsmsg_create_list())) { + tvh_mutex_lock(&global_lock); + SLIST_FOREACH (tvh_codec, &tvh_codecs, link) { + if (!(map = idclass_serialize(tvh_codec_get_class(tvh_codec), perm->aa_lang_ui))) { + htsmsg_destroy(list); + list = NULL; + break; + } + htsmsg_add_str(map, "name", tvh_codec_get_name(tvh_codec)); + htsmsg_add_str(map, "title", tvh_codec_get_title(tvh_codec)); + htsmsg_add_msg(list, NULL, map); + } + tvh_mutex_unlock(&global_lock); + if (list) { + if ((*resp = htsmsg_create_map())) { + htsmsg_add_msg(*resp, "entries", list); + err = 0; + } else { + htsmsg_destroy(list); + list = NULL; + } } - return err; + } + return err; } +static int api_codec_profile_list(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_t * list = NULL, *map = NULL; + TVHCodecProfile* tvh_profile = NULL; + char buf[UUID_HEX_SIZE]; + int err = ENOMEM; -static int -api_codec_profile_list(access_t *perm, void *opaque, const char *op, - htsmsg_t *args, htsmsg_t **resp) -{ - htsmsg_t *list = NULL, *map = NULL; - TVHCodecProfile *tvh_profile = NULL; - char buf[UUID_HEX_SIZE]; - int err = ENOMEM; - - if ((list = htsmsg_create_list())) { - tvh_mutex_lock(&global_lock); - LIST_FOREACH(tvh_profile, &tvh_codec_profiles, link) { - if (!(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - break; - } - htsmsg_add_str(map, "uuid", - idnode_uuid_as_str((idnode_t *)tvh_profile, buf)); - htsmsg_add_str(map, "title", - tvh_codec_profile_get_title(tvh_profile)); - htsmsg_add_str(map, "status", - tvh_codec_profile_get_status(tvh_profile)); - htsmsg_add_msg(list, NULL, map); - } - tvh_mutex_unlock(&global_lock); - if (list) { - if ((*resp = htsmsg_create_map())) { - htsmsg_add_msg(*resp, "entries", list); - err = 0; - } - else { - htsmsg_destroy(list); - list = NULL; - } - } + if ((list = htsmsg_create_list())) { + tvh_mutex_lock(&global_lock); + LIST_FOREACH (tvh_profile, &tvh_codec_profiles, link) { + if (!(map = htsmsg_create_map())) { + htsmsg_destroy(list); + list = NULL; + break; + } + htsmsg_add_str(map, "uuid", idnode_uuid_as_str((idnode_t*)tvh_profile, buf)); + htsmsg_add_str(map, "title", tvh_codec_profile_get_title(tvh_profile)); + htsmsg_add_str(map, "status", tvh_codec_profile_get_status(tvh_profile)); + htsmsg_add_msg(list, NULL, map); } - return err; + tvh_mutex_unlock(&global_lock); + if (list) { + if ((*resp = htsmsg_create_map())) { + htsmsg_add_msg(*resp, "entries", list); + err = 0; + } else { + htsmsg_destroy(list); + list = NULL; + } + } + } + return err; } +static int api_codec_profile_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + const char* codec_name = NULL; + htsmsg_t* conf = NULL; + int err = EINVAL; -static int -api_codec_profile_create(access_t *perm, void *opaque, const char *op, - htsmsg_t *args, htsmsg_t **resp) -{ - const char *codec_name = NULL; - htsmsg_t *conf = NULL; - int err = EINVAL; - - if ((codec_name = htsmsg_get_str(args, "class")) && - (conf = htsmsg_get_map(args, "conf"))) { - htsmsg_set_str(conf, "codec_name", codec_name); - tvh_mutex_lock(&global_lock); - err = (err = tvh_codec_profile_create(conf, NULL, 1)) ? -err : 0; - tvh_mutex_unlock(&global_lock); - } - return err; + if ((codec_name = htsmsg_get_str(args, "class")) && (conf = htsmsg_get_map(args, "conf"))) { + htsmsg_set_str(conf, "codec_name", codec_name); + tvh_mutex_lock(&global_lock); + err = (err = tvh_codec_profile_create(conf, NULL, 1)) ? -err : 0; + tvh_mutex_unlock(&global_lock); + } + return err; } +void api_codec_init(void) { + static api_hook_t ah[] = { + {"codec/list", ACCESS_ADMIN, api_codec_list, NULL}, + {"codec_profile/list", ACCESS_ANONYMOUS, api_codec_profile_list, NULL}, + {"codec_profile/create", ACCESS_ADMIN, api_codec_profile_create, NULL}, + {"codec_profile/class", ACCESS_ADMIN, api_idnode_class, (void*)&codec_profile_class}, + {NULL}, + }; -void -api_codec_init(void) -{ - static api_hook_t ah[] = { - {"codec/list", ACCESS_ADMIN, api_codec_list, NULL}, - {"codec_profile/list", ACCESS_ANONYMOUS, api_codec_profile_list, NULL}, - {"codec_profile/create", ACCESS_ADMIN, api_codec_profile_create, NULL}, - {"codec_profile/class", ACCESS_ADMIN, api_idnode_class, - (void*)&codec_profile_class}, - {NULL}, - }; - - api_register_all(ah); + api_register_all(ah); } diff --git a/src/api/api_config.c b/src/api/api_config.c index 7887eada4..4c99910b3 100644 --- a/src/api/api_config.c +++ b/src/api/api_config.c @@ -24,75 +24,67 @@ #include "api.h" #include "config.h" -//Needed to get the current trace/debug states for each subsystem. -//Look in tvhlog.c for more details. +// Needed to get the current trace/debug states for each subsystem. +// Look in tvhlog.c for more details. #include "bitops.h" -extern bitops_ulong_t tvhlog_debug[TVHLOG_BITARRAY]; //TVHLOG_BITARRAY is defined in bitops.h -extern bitops_ulong_t tvhlog_trace[TVHLOG_BITARRAY]; - -static int -api_config_capabilities(access_t *perm, void *opaque, const char *op, - htsmsg_t *args, htsmsg_t **resp) -{ - *resp = tvheadend_capabilities_list(0); - return 0; +extern bitops_ulong_t tvhlog_debug[TVHLOG_BITARRAY]; // TVHLOG_BITARRAY is defined in bitops.h +extern bitops_ulong_t tvhlog_trace[TVHLOG_BITARRAY]; + +static int api_config_capabilities(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + *resp = tvheadend_capabilities_list(0); + return 0; } -static void -api_memoryinfo_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - memoryinfo_t *my; +static void api_memoryinfo_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + memoryinfo_t* my; - LIST_FOREACH(my, &memoryinfo_entries, my_link) { + LIST_FOREACH (my, &memoryinfo_entries, my_link) { if (my->my_update) my->my_update(my); idnode_set_add(ins, (idnode_t*)my, &conf->filter, perm->aa_lang_ui); } } -//Return a list of trace/debug subsystems and their description. +// Return a list of trace/debug subsystems and their description. static int -api_subsystems_grid - (access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp) -{ +api_subsystems_grid(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { - int i; - int counter = 0; - int trace_count = 0; - int debug_count = 0; + int i; + int counter = 0; + int trace_count = 0; + int debug_count = 0; - htsmsg_t *api_response; - htsmsg_t *api_item; + htsmsg_t* api_response; + htsmsg_t* api_item; api_response = htsmsg_create_list(); - tvhlog_subsys_t *ts = tvhlog_subsystems; + tvhlog_subsys_t* ts = tvhlog_subsystems; - for (i = 1, ts++; i < LS_LAST; i++, ts++) - { + for (i = 1, ts++; i < LS_LAST; i++, ts++) { api_item = htsmsg_create_map(); htsmsg_add_u32(api_item, "id", i); htsmsg_add_str(api_item, "subsystem", ts->name); htsmsg_add_str(api_item, "description", _(ts->desc)); - if(test_bit(i, tvhlog_trace)) - { + if (test_bit(i, tvhlog_trace)) { trace_count++; htsmsg_add_bool(api_item, "trace", 1); - } - else - { + } else { htsmsg_add_bool(api_item, "trace", 0); } - if(test_bit(i, tvhlog_debug)) - { + if (test_bit(i, tvhlog_debug)) { debug_count++; htsmsg_add_bool(api_item, "debug", 1); - } - else - { + } else { htsmsg_add_bool(api_item, "debug", 0); } @@ -111,19 +103,20 @@ api_subsystems_grid return 0; } -void -api_config_init ( void ) -{ +void api_config_init(void) { static api_hook_t ah[] = { - { "config/capabilities", ACCESS_OR|ACCESS_WEB_INTERFACE|ACCESS_HTSP_INTERFACE, api_config_capabilities, NULL }, - { "config/load", ACCESS_ADMIN, api_idnode_load_simple, &config }, - { "config/save", ACCESS_ADMIN, api_idnode_save_simple, &config }, - { "tvhlog/config/load", ACCESS_ADMIN, api_idnode_load_simple, &tvhlog_conf }, - { "tvhlog/config/save", ACCESS_ADMIN, api_idnode_save_simple, &tvhlog_conf }, - { "tvhlog/subsystem/grid", ACCESS_ADMIN, api_subsystems_grid, NULL }, - { "memoryinfo/class", ACCESS_ADMIN, api_idnode_class, (void *)&memoryinfo_class }, - { "memoryinfo/grid", ACCESS_ADMIN, api_idnode_grid, api_memoryinfo_grid }, - { NULL }, + {"config/capabilities", + ACCESS_OR | ACCESS_WEB_INTERFACE | ACCESS_HTSP_INTERFACE, + api_config_capabilities, + NULL}, + {"config/load", ACCESS_ADMIN, api_idnode_load_simple, &config}, + {"config/save", ACCESS_ADMIN, api_idnode_save_simple, &config}, + {"tvhlog/config/load", ACCESS_ADMIN, api_idnode_load_simple, &tvhlog_conf}, + {"tvhlog/config/save", ACCESS_ADMIN, api_idnode_save_simple, &tvhlog_conf}, + {"tvhlog/subsystem/grid", ACCESS_ADMIN, api_subsystems_grid, NULL}, + {"memoryinfo/class", ACCESS_ADMIN, api_idnode_class, (void*)&memoryinfo_class}, + {"memoryinfo/grid", ACCESS_ADMIN, api_idnode_grid, api_memoryinfo_grid}, + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_dvr.c b/src/api/api_dvr.c index a39009258..6e689f959 100644 --- a/src/api/api_dvr.c +++ b/src/api/api_dvr.c @@ -27,26 +27,27 @@ * */ -static void -api_dvr_config_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - dvr_config_t *cfg; - - LIST_FOREACH(cfg, &dvrconfigs, config_link) - if (!idnode_perm((idnode_t *)cfg, perm, NULL)) { +static void api_dvr_config_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + dvr_config_t* cfg; + + LIST_FOREACH (cfg, &dvrconfigs, config_link) + if (!idnode_perm((idnode_t*)cfg, perm, NULL)) { idnode_set_add(ins, (idnode_t*)cfg, &conf->filter, perm->aa_lang_ui); - idnode_perm_unset((idnode_t *)cfg); + idnode_perm_unset((idnode_t*)cfg); } } -static int -api_dvr_config_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - dvr_config_t *cfg; - htsmsg_t *conf; - const char *s; +static int api_dvr_config_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + dvr_config_t* cfg; + htsmsg_t* conf; + const char* s; if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; @@ -65,83 +66,84 @@ api_dvr_config_create return 0; } -static void -api_dvr_entry_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - dvr_entry_t *de; +static void api_dvr_entry_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + dvr_entry_t* de; - LIST_FOREACH(de, &dvrentries, de_global_link) + LIST_FOREACH (de, &dvrentries, de_global_link) idnode_set_add(ins, (idnode_t*)de, &conf->filter, perm->aa_lang_ui); } -static void -api_dvr_entry_grid_upcoming - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - dvr_entry_t *de; - int duplicates = htsmsg_get_s32_or_default(args, "duplicates", 1); +static void api_dvr_entry_grid_upcoming(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + dvr_entry_t* de; + int duplicates = htsmsg_get_s32_or_default(args, "duplicates", 1); if (duplicates) { - LIST_FOREACH(de, &dvrentries, de_global_link) + LIST_FOREACH (de, &dvrentries, de_global_link) if (dvr_entry_is_upcoming(de)) idnode_set_add(ins, (idnode_t*)de, &conf->filter, perm->aa_lang_ui); } else { - LIST_FOREACH(de, &dvrentries, de_global_link) + LIST_FOREACH (de, &dvrentries, de_global_link) if (dvr_entry_is_upcoming_nodup(de)) idnode_set_add(ins, (idnode_t*)de, &conf->filter, perm->aa_lang_ui); } } -static void -api_dvr_entry_grid_finished - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - dvr_entry_t *de; +static void api_dvr_entry_grid_finished(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + dvr_entry_t* de; - LIST_FOREACH(de, &dvrentries, de_global_link) + LIST_FOREACH (de, &dvrentries, de_global_link) if (dvr_entry_is_finished(de, DVR_FINISHED_SUCCESS)) idnode_set_add(ins, (idnode_t*)de, &conf->filter, perm->aa_lang_ui); } -static void -api_dvr_entry_grid_failed - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - dvr_entry_t *de; +static void api_dvr_entry_grid_failed(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + dvr_entry_t* de; - LIST_FOREACH(de, &dvrentries, de_global_link) + LIST_FOREACH (de, &dvrentries, de_global_link) if (dvr_entry_is_finished(de, DVR_FINISHED_FAILED)) idnode_set_add(ins, (idnode_t*)de, &conf->filter, perm->aa_lang_ui); } -static void -api_dvr_entry_grid_removed - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - dvr_entry_t *de; +static void api_dvr_entry_grid_removed(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + dvr_entry_t* de; - LIST_FOREACH(de, &dvrentries, de_global_link) + LIST_FOREACH (de, &dvrentries, de_global_link) if (dvr_entry_is_finished(de, DVR_FINISHED_REMOVED_SUCCESS | DVR_FINISHED_REMOVED_FAILED)) idnode_set_add(ins, (idnode_t*)de, &conf->filter, perm->aa_lang_ui); } -static int -api_dvr_entry_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - dvr_entry_t *de; - dvr_config_t *cfg; - htsmsg_t *conf, *m; - char *s, *lang; - const char *s1; - int res = EPERM; +static int api_dvr_entry_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + dvr_entry_t* de; + dvr_config_t* cfg; + htsmsg_t * conf, *m; + char * s, *lang; + const char* s1; + int res = EPERM; if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; tvh_mutex_lock(&global_lock); - s1 = htsmsg_get_str(conf, "config_name"); + s1 = htsmsg_get_str(conf, "config_name"); cfg = dvr_config_find_by_list(perm->aa_dvrcfgs, s1); if (cfg) { htsmsg_set_uuid(conf, "config_name", &cfg->dvr_id.in_uuid); @@ -150,7 +152,8 @@ api_dvr_entry_create lang = access_get_lang(perm, htsmsg_get_str(conf, "lang")); if (lang) { - for (s = (char *)lang; *s && *s != ','; s++); + for (s = (char*)lang; *s && *s != ','; s++) + ; *s = '\0'; } else { lang = strdup(lang_code_preferred()); @@ -182,19 +185,17 @@ api_dvr_entry_create return res; } -static htsmsg_t * -api_dvr_entry_create_from_single(htsmsg_t *args) -{ - htsmsg_t *entries, *m; +static htsmsg_t* api_dvr_entry_create_from_single(htsmsg_t* args) { + htsmsg_t * entries, *m; const char *s1, *s2, *s3; if (!(s1 = htsmsg_get_str(args, "config_uuid"))) return NULL; if (!(s2 = htsmsg_get_str(args, "event_id"))) return NULL; - s3 = htsmsg_get_str(args, "comment"); + s3 = htsmsg_get_str(args, "comment"); entries = htsmsg_create_list(); - m = htsmsg_create_map(); + m = htsmsg_create_map(); htsmsg_add_str(m, "config_uuid", s1); htsmsg_add_str(m, "event_id", s2); if (s3) @@ -203,16 +204,17 @@ api_dvr_entry_create_from_single(htsmsg_t *args) return entries; } -static int -api_dvr_entry_create_by_event - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - dvr_entry_t *de; - epg_broadcast_t *e; - htsmsg_t *entries, *entries2 = NULL, *m, *l = NULL, *conf; - htsmsg_field_t *f; - const char *s, *config_uuid; - int count = 0; +static int api_dvr_entry_create_by_event(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + dvr_entry_t* de; + epg_broadcast_t* e; + htsmsg_t * entries, *entries2 = NULL, *m, *l = NULL, *conf; + htsmsg_field_t* f; + const char * s, *config_uuid; + int count = 0; if (!(entries = htsmsg_get_list(args, "entries"))) { entries = entries2 = api_dvr_entry_create_from_single(args); @@ -221,7 +223,8 @@ api_dvr_entry_create_by_event } HTSMSG_FOREACH(f, entries) { - if (!(m = htsmsg_get_map_by_field(f))) continue; + if (!(m = htsmsg_get_map_by_field(f))) + continue; if (!(s = htsmsg_get_str(m, "event_id"))) continue; @@ -232,11 +235,11 @@ api_dvr_entry_create_by_event htsmsg_add_str2(conf, "owner", perm->aa_username); htsmsg_add_str2(conf, "creator", perm->aa_representative); config_uuid = htsmsg_get_str(m, "config_uuid"); - de = NULL; + de = NULL; tvh_mutex_lock(&global_lock); if ((e = epg_broadcast_find_by_id(strtoll(s, NULL, 10)))) { - dvr_config_t *cfg = dvr_config_find_by_list(perm->aa_dvrcfgs, config_uuid); + dvr_config_t* cfg = dvr_config_find_by_list(perm->aa_dvrcfgs, config_uuid); if (cfg) { htsmsg_add_uuid(conf, "config_name", &cfg->dvr_id.in_uuid); de = dvr_entry_create_from_htsmsg(conf, e); @@ -264,171 +267,200 @@ api_dvr_entry_create_by_event return !count ? EINVAL : 0; } -static void -api_dvr_rerecord_toggle(access_t *perm, idnode_t *self) -{ - dvr_entry_set_rerecord((dvr_entry_t *)self, -1); +static void api_dvr_rerecord_toggle(access_t* perm, idnode_t* self) { + dvr_entry_set_rerecord((dvr_entry_t*)self, -1); } -static int -api_dvr_entry_rerecord_toggle - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - return api_idnode_handler(&dvr_entry_class, perm, args, resp, api_dvr_rerecord_toggle, "rerecord", 0); +static int api_dvr_entry_rerecord_toggle(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + return api_idnode_handler(&dvr_entry_class, + perm, + args, + resp, + api_dvr_rerecord_toggle, + "rerecord", + 0); } -static void -api_dvr_rerecord_deny(access_t *perm, idnode_t *self) -{ - dvr_entry_set_rerecord((dvr_entry_t *)self, 0); +static void api_dvr_rerecord_deny(access_t* perm, idnode_t* self) { + dvr_entry_set_rerecord((dvr_entry_t*)self, 0); } -static int -api_dvr_entry_rerecord_deny - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - return api_idnode_handler(&dvr_entry_class, perm, args, resp, api_dvr_rerecord_deny, "rerecord", 0); +static int api_dvr_entry_rerecord_deny(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + return api_idnode_handler(&dvr_entry_class, + perm, + args, + resp, + api_dvr_rerecord_deny, + "rerecord", + 0); } -static void -api_dvr_rerecord_allow(access_t *perm, idnode_t *self) -{ - dvr_entry_set_rerecord((dvr_entry_t *)self, 1); +static void api_dvr_rerecord_allow(access_t* perm, idnode_t* self) { + dvr_entry_set_rerecord((dvr_entry_t*)self, 1); } -static int -api_dvr_entry_rerecord_allow - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - return api_idnode_handler(&dvr_entry_class, perm, args, resp, api_dvr_rerecord_allow, "rerecord", 0); +static int api_dvr_entry_rerecord_allow(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + return api_idnode_handler(&dvr_entry_class, + perm, + args, + resp, + api_dvr_rerecord_allow, + "rerecord", + 0); } -static void -api_dvr_stop(access_t *perm, idnode_t *self) -{ - dvr_entry_stop((dvr_entry_t *)self); +static void api_dvr_stop(access_t* perm, idnode_t* self) { + dvr_entry_stop((dvr_entry_t*)self); } static int -api_dvr_entry_stop - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +api_dvr_entry_stop(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { return api_idnode_handler(&dvr_entry_class, perm, args, resp, api_dvr_stop, "stop", 0); } -static void -api_dvr_cancel(access_t *perm, idnode_t *self) -{ - dvr_entry_cancel((dvr_entry_t *)self, 0); +static void api_dvr_cancel(access_t* perm, idnode_t* self) { + dvr_entry_cancel((dvr_entry_t*)self, 0); } -static int -api_dvr_entry_cancel - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_dvr_entry_cancel(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { return api_idnode_handler(&dvr_entry_class, perm, args, resp, api_dvr_cancel, "cancel", 0); } -static void -api_dvr_remove(access_t *perm, idnode_t *self) -{ - dvr_entry_t *de = (dvr_entry_t *)self; +static void api_dvr_remove(access_t* perm, idnode_t* self) { + dvr_entry_t* de = (dvr_entry_t*)self; if (de->de_sched_state != DVR_SCHEDULED && de->de_sched_state != DVR_NOSTATE) dvr_entry_cancel_remove(de, 0); } -static int -api_dvr_entry_remove - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_dvr_entry_remove(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { return api_idnode_handler(&dvr_entry_class, perm, args, resp, api_dvr_remove, "remove", 0); } -static void -api_dvr_prevrec_toggle(access_t *perm, idnode_t *self) -{ - dvr_entry_set_prevrec((dvr_entry_t *)self, -1); +static void api_dvr_prevrec_toggle(access_t* perm, idnode_t* self) { + dvr_entry_set_prevrec((dvr_entry_t*)self, -1); } -static int -api_dvr_entry_prevrec_toggle - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - return api_idnode_handler(&dvr_entry_class, perm, args, resp, api_dvr_prevrec_toggle, "prevrec", 0); +static int api_dvr_entry_prevrec_toggle(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + return api_idnode_handler(&dvr_entry_class, + perm, + args, + resp, + api_dvr_prevrec_toggle, + "prevrec", + 0); } -static void -api_dvr_prevrec_unset(access_t *perm, idnode_t *self) -{ - dvr_entry_set_prevrec((dvr_entry_t *)self, 0); +static void api_dvr_prevrec_unset(access_t* perm, idnode_t* self) { + dvr_entry_set_prevrec((dvr_entry_t*)self, 0); } -static int -api_dvr_entry_prevrec_unset - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - return api_idnode_handler(&dvr_entry_class, perm, args, resp, api_dvr_prevrec_unset, "prevrec", 0); +static int api_dvr_entry_prevrec_unset(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + return api_idnode_handler(&dvr_entry_class, + perm, + args, + resp, + api_dvr_prevrec_unset, + "prevrec", + 0); } -static void -api_dvr_prevrec_set(access_t *perm, idnode_t *self) -{ - dvr_entry_set_prevrec((dvr_entry_t *)self, 1); +static void api_dvr_prevrec_set(access_t* perm, idnode_t* self) { + dvr_entry_set_prevrec((dvr_entry_t*)self, 1); } -static int -api_dvr_entry_prevrec_set - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_dvr_entry_prevrec_set(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { return api_idnode_handler(&dvr_entry_class, perm, args, resp, api_dvr_prevrec_set, "prevrec", 0); } -static void -api_dvr_move_finished(access_t *perm, idnode_t *self) -{ - dvr_entry_move((dvr_entry_t *)self, 0); +static void api_dvr_move_finished(access_t* perm, idnode_t* self) { + dvr_entry_move((dvr_entry_t*)self, 0); } -static int -api_dvr_entry_move_finished - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - return api_idnode_handler(&dvr_entry_class, perm, args, resp, api_dvr_move_finished, "move finished", 0); +static int api_dvr_entry_move_finished(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + return api_idnode_handler(&dvr_entry_class, + perm, + args, + resp, + api_dvr_move_finished, + "move finished", + 0); } -static void -api_dvr_move_failed(access_t *perm, idnode_t *self) -{ - dvr_entry_move((dvr_entry_t *)self, 1); +static void api_dvr_move_failed(access_t* perm, idnode_t* self) { + dvr_entry_move((dvr_entry_t*)self, 1); } -static int -api_dvr_entry_move_failed - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - return api_idnode_handler(&dvr_entry_class, perm, args, resp, api_dvr_move_failed, "move failed", 0); +static int api_dvr_entry_move_failed(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + return api_idnode_handler(&dvr_entry_class, + perm, + args, + resp, + api_dvr_move_failed, + "move failed", + 0); } -static void -api_dvr_autorec_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - dvr_autorec_entry_t *dae; +static void api_dvr_autorec_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + dvr_autorec_entry_t* dae; - TAILQ_FOREACH(dae, &autorec_entries, dae_link) + TAILQ_FOREACH (dae, &autorec_entries, dae_link) idnode_set_add(ins, (idnode_t*)dae, &conf->filter, perm->aa_lang_ui); } -static int -api_dvr_autorec_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_t *conf; - dvr_config_t *cfg; - dvr_autorec_entry_t *dae; - const char *s1; - - if (!(conf = htsmsg_get_map(args, "conf"))) +static int api_dvr_autorec_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_t* conf; + dvr_config_t* cfg; + dvr_autorec_entry_t* dae; + const char* s1; + + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; htsmsg_set_str2(conf, "owner", perm->aa_username); @@ -454,19 +486,20 @@ api_dvr_autorec_create return 0; } -static int -api_dvr_autorec_create_by_series - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - dvr_autorec_entry_t *dae; - epg_broadcast_t *e; - htsmsg_t *entries, *entries2 = NULL, *m, *l = NULL; - htsmsg_field_t *f; - const char *config_uuid, *s, *title; - int count = 0; - char ubuf[UUID_HEX_SIZE]; - const char * msg = " - Created from EPG query"; - char *comment; +static int api_dvr_autorec_create_by_series(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + dvr_autorec_entry_t* dae; + epg_broadcast_t* e; + htsmsg_t * entries, *entries2 = NULL, *m, *l = NULL; + htsmsg_field_t* f; + const char * config_uuid, *s, *title; + int count = 0; + char ubuf[UUID_HEX_SIZE]; + const char* msg = " - Created from EPG query"; + char* comment; if (!(entries = htsmsg_get_list(args, "entries"))) { entries = entries2 = api_dvr_entry_create_from_single(args); @@ -475,7 +508,8 @@ api_dvr_autorec_create_by_series } HTSMSG_FOREACH(f, entries) { - if (!(m = htsmsg_get_map_by_field(f))) continue; + if (!(m = htsmsg_get_map_by_field(f))) + continue; if (!(s = htsmsg_get_str(m, "event_id"))) continue; @@ -484,16 +518,16 @@ api_dvr_autorec_create_by_series tvh_mutex_lock(&global_lock); if ((e = epg_broadcast_find_by_id(strtoll(s, NULL, 10)))) { - dvr_config_t *cfg = dvr_config_find_by_list(perm->aa_dvrcfgs, config_uuid); + dvr_config_t* cfg = dvr_config_find_by_list(perm->aa_dvrcfgs, config_uuid); if (cfg) { - title = epg_broadcast_get_title(e, NULL); + title = epg_broadcast_get_title(e, NULL); comment = alloca(strlen(title) + strlen(msg) + 1); sprintf(comment, "%s%s", title, msg); dae = dvr_autorec_add_series_link(idnode_uuid_as_str(&cfg->dvr_id, ubuf), - e, - perm->aa_username, - perm->aa_representative, - comment); + e, + perm->aa_username, + perm->aa_representative, + comment); if (dae) { if (l == NULL) l = htsmsg_create_list(); @@ -513,24 +547,25 @@ api_dvr_autorec_create_by_series return !count ? EINVAL : 0; } -static void -api_dvr_timerec_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - dvr_timerec_entry_t *dte; +static void api_dvr_timerec_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + dvr_timerec_entry_t* dte; - TAILQ_FOREACH(dte, &timerec_entries, dte_link) + TAILQ_FOREACH (dte, &timerec_entries, dte_link) idnode_set_add(ins, (idnode_t*)dte, &conf->filter, perm->aa_lang_ui); } -static int -api_dvr_timerec_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_t *conf; - dvr_timerec_entry_t *dte; +static int api_dvr_timerec_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_t* conf; + dvr_timerec_entry_t* dte; - if (!(conf = htsmsg_get_map(args, "conf"))) + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; htsmsg_set_str2(conf, "owner", perm->aa_username); @@ -547,10 +582,11 @@ api_dvr_timerec_create return 0; } -static int -api_dvr_entry_file_moved - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_dvr_entry_file_moved(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { const char *src, *dst; if (!(src = htsmsg_get_str(args, "src"))) return EINVAL; @@ -561,47 +597,58 @@ api_dvr_entry_file_moved return 0; } - -void api_dvr_init ( void ) -{ +void api_dvr_init(void) { static api_hook_t ah[] = { - { "dvr/config/class", ACCESS_OR|ACCESS_ADMIN|ACCESS_RECORDER, - api_idnode_class, (void*)&dvr_config_class }, - { "dvr/config/grid", ACCESS_OR|ACCESS_ADMIN|ACCESS_RECORDER, - api_idnode_grid, api_dvr_config_grid }, - { "dvr/config/create", ACCESS_ADMIN, api_dvr_config_create, NULL }, - - { "dvr/entry/class", ACCESS_RECORDER, api_idnode_class, (void*)&dvr_entry_class }, - { "dvr/entry/grid", ACCESS_RECORDER, api_idnode_grid, api_dvr_entry_grid }, - { "dvr/entry/grid_upcoming", ACCESS_RECORDER, api_idnode_grid, api_dvr_entry_grid_upcoming }, - { "dvr/entry/grid_finished", ACCESS_RECORDER, api_idnode_grid, api_dvr_entry_grid_finished }, - { "dvr/entry/grid_failed", ACCESS_RECORDER, api_idnode_grid, api_dvr_entry_grid_failed }, - { "dvr/entry/grid_removed", ACCESS_RECORDER, api_idnode_grid, api_dvr_entry_grid_removed }, - { "dvr/entry/create", ACCESS_RECORDER, api_dvr_entry_create, NULL }, - { "dvr/entry/create_by_event", ACCESS_RECORDER, api_dvr_entry_create_by_event, NULL }, - { "dvr/entry/rerecord/toggle", ACCESS_RECORDER, api_dvr_entry_rerecord_toggle, NULL }, - { "dvr/entry/rerecord/deny", ACCESS_RECORDER, api_dvr_entry_rerecord_deny, NULL }, - { "dvr/entry/rerecord/allow", ACCESS_RECORDER, api_dvr_entry_rerecord_allow, NULL }, - { "dvr/entry/stop", ACCESS_RECORDER, api_dvr_entry_stop, NULL }, /* Stop active recording gracefully */ - { "dvr/entry/cancel", ACCESS_RECORDER, api_dvr_entry_cancel, NULL }, /* Cancel scheduled or active recording */ - { "dvr/entry/prevrec/toggle", ACCESS_RECORDER, api_dvr_entry_prevrec_toggle, NULL }, - { "dvr/entry/prevrec/set", ACCESS_RECORDER, api_dvr_entry_prevrec_set, NULL }, - { "dvr/entry/prevrec/unset", ACCESS_RECORDER, api_dvr_entry_prevrec_unset, NULL }, - { "dvr/entry/remove", ACCESS_RECORDER, api_dvr_entry_remove, NULL }, /* Remove recorded files from storage */ - { "dvr/entry/filemoved", ACCESS_ADMIN, api_dvr_entry_file_moved, NULL }, - { "dvr/entry/move/finished", ACCESS_RECORDER, api_dvr_entry_move_finished, NULL }, - { "dvr/entry/move/failed", ACCESS_RECORDER, api_dvr_entry_move_failed, NULL }, - - { "dvr/autorec/class", ACCESS_RECORDER, api_idnode_class, (void*)&dvr_autorec_entry_class }, - { "dvr/autorec/grid", ACCESS_RECORDER, api_idnode_grid, api_dvr_autorec_grid }, - { "dvr/autorec/create", ACCESS_RECORDER, api_dvr_autorec_create, NULL }, - { "dvr/autorec/create_by_series", ACCESS_RECORDER, api_dvr_autorec_create_by_series, NULL }, - - { "dvr/timerec/class", ACCESS_RECORDER, api_idnode_class, (void*)&dvr_timerec_entry_class }, - { "dvr/timerec/grid", ACCESS_RECORDER, api_idnode_grid, api_dvr_timerec_grid }, - { "dvr/timerec/create", ACCESS_RECORDER, api_dvr_timerec_create, NULL }, - - { NULL }, + {"dvr/config/class", + ACCESS_OR | ACCESS_ADMIN | ACCESS_RECORDER, + api_idnode_class, + (void*)&dvr_config_class}, + {"dvr/config/grid", + ACCESS_OR | ACCESS_ADMIN | ACCESS_RECORDER, + api_idnode_grid, + api_dvr_config_grid}, + {"dvr/config/create", ACCESS_ADMIN, api_dvr_config_create, NULL}, + + {"dvr/entry/class", ACCESS_RECORDER, api_idnode_class, (void*)&dvr_entry_class}, + {"dvr/entry/grid", ACCESS_RECORDER, api_idnode_grid, api_dvr_entry_grid}, + {"dvr/entry/grid_upcoming", ACCESS_RECORDER, api_idnode_grid, api_dvr_entry_grid_upcoming}, + {"dvr/entry/grid_finished", ACCESS_RECORDER, api_idnode_grid, api_dvr_entry_grid_finished}, + {"dvr/entry/grid_failed", ACCESS_RECORDER, api_idnode_grid, api_dvr_entry_grid_failed}, + {"dvr/entry/grid_removed", ACCESS_RECORDER, api_idnode_grid, api_dvr_entry_grid_removed}, + {"dvr/entry/create", ACCESS_RECORDER, api_dvr_entry_create, NULL}, + {"dvr/entry/create_by_event", ACCESS_RECORDER, api_dvr_entry_create_by_event, NULL}, + {"dvr/entry/rerecord/toggle", ACCESS_RECORDER, api_dvr_entry_rerecord_toggle, NULL}, + {"dvr/entry/rerecord/deny", ACCESS_RECORDER, api_dvr_entry_rerecord_deny, NULL}, + {"dvr/entry/rerecord/allow", ACCESS_RECORDER, api_dvr_entry_rerecord_allow, NULL}, + {"dvr/entry/stop", + ACCESS_RECORDER, + api_dvr_entry_stop, + NULL}, /* Stop active recording gracefully */ + {"dvr/entry/cancel", + ACCESS_RECORDER, + api_dvr_entry_cancel, + NULL}, /* Cancel scheduled or active recording */ + {"dvr/entry/prevrec/toggle", ACCESS_RECORDER, api_dvr_entry_prevrec_toggle, NULL}, + {"dvr/entry/prevrec/set", ACCESS_RECORDER, api_dvr_entry_prevrec_set, NULL}, + {"dvr/entry/prevrec/unset", ACCESS_RECORDER, api_dvr_entry_prevrec_unset, NULL}, + {"dvr/entry/remove", + ACCESS_RECORDER, + api_dvr_entry_remove, + NULL}, /* Remove recorded files from storage */ + {"dvr/entry/filemoved", ACCESS_ADMIN, api_dvr_entry_file_moved, NULL}, + {"dvr/entry/move/finished", ACCESS_RECORDER, api_dvr_entry_move_finished, NULL}, + {"dvr/entry/move/failed", ACCESS_RECORDER, api_dvr_entry_move_failed, NULL}, + + {"dvr/autorec/class", ACCESS_RECORDER, api_idnode_class, (void*)&dvr_autorec_entry_class}, + {"dvr/autorec/grid", ACCESS_RECORDER, api_idnode_grid, api_dvr_autorec_grid}, + {"dvr/autorec/create", ACCESS_RECORDER, api_dvr_autorec_create, NULL}, + {"dvr/autorec/create_by_series", ACCESS_RECORDER, api_dvr_autorec_create_by_series, NULL}, + + {"dvr/timerec/class", ACCESS_RECORDER, api_idnode_class, (void*)&dvr_timerec_entry_class}, + {"dvr/timerec/grid", ACCESS_RECORDER, api_idnode_grid, api_dvr_timerec_grid}, + {"dvr/timerec/create", ACCESS_RECORDER, api_dvr_timerec_create, NULL}, + + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_epg.c b/src/api/api_epg.c index 35718cc27..22a30e866 100644 --- a/src/api/api_epg.c +++ b/src/api/api_epg.c @@ -26,16 +26,14 @@ #include "dvr/dvr.h" #include "lang_codes.h" #include "string_list.h" -#include "epggrab.h" //Needed to be able to test for epggrab_conf.epgdb_processparentallabels +#include "epggrab.h" //Needed to be able to test for epggrab_conf.epgdb_processparentallabels -static htsmsg_t * -api_epg_get_list ( const char *s ) -{ - htsmsg_t *m = NULL; - char *r, *saveptr = NULL; +static htsmsg_t* api_epg_get_list(const char* s) { + htsmsg_t* m = NULL; + char * r, *saveptr = NULL; if (s && s[0] != '\0') { s = r = strdup(s); - r = strtok_r(r, ";", &saveptr); + r = strtok_r(r, ";", &saveptr); while (r) { while (*r != '\0' && *r <= ' ') r++; @@ -46,17 +44,15 @@ api_epg_get_list ( const char *s ) } r = strtok_r(NULL, ";", &saveptr); } - free((char *)s); + free((char*)s); } return m; } -static void -api_epg_add_channel ( htsmsg_t *m, channel_t *ch, const char *blank ) -{ - int64_t chnum; - char buf[128]; - const char *s; +static void api_epg_add_channel(htsmsg_t* m, channel_t* ch, const char* blank) { + int64_t chnum; + char buf[128]; + const char* s; htsmsg_add_str(m, "channelName", channel_get_name(ch, blank)); htsmsg_add_uuid(m, "channelUuid", &ch->ch_id.in_uuid); if ((chnum = channel_get_number(ch)) >= 0) { @@ -76,19 +72,19 @@ api_epg_add_channel ( htsmsg_t *m, channel_t *ch, const char *blank ) } } -static htsmsg_t * -api_epg_entry ( epg_broadcast_t *eb, const char *lang, const access_t *perm, const char **blank ) -{ - const char *s, *blank2 = NULL; - char buf[128]; - channel_t *ch = eb->channel; - htsmsg_t *m, *m2; +static htsmsg_t* +api_epg_entry(epg_broadcast_t* eb, const char* lang, const access_t* perm, const char** blank) { + const char * s, *blank2 = NULL; + char buf[128]; + channel_t* ch = eb->channel; + htsmsg_t * m, *m2; epg_episode_num_t epnum; - epg_genre_t *eg; - dvr_entry_t *de; - char ubuf[UUID_HEX_SIZE]; + epg_genre_t* eg; + dvr_entry_t* de; + char ubuf[UUID_HEX_SIZE]; - if (!ch) return NULL; + if (!ch) + return NULL; if (blank == NULL) blank = &blank2; @@ -170,8 +166,7 @@ api_epg_entry ( epg_broadcast_t *eb, const char *lang, const access_t *perm, con } if (epnum.text) htsmsg_add_str(m, "episodeOnscreen", epnum.text); - else if (epg_broadcast_epnumber_format(eb, buf, sizeof(buf), NULL, - "s%02d", ".", "e%02d", "")) + else if (epg_broadcast_epnumber_format(eb, buf, sizeof(buf), NULL, "s%02d", ".", "e%02d", "")) htsmsg_add_str(m, "episodeOnscreen", buf); /* Image */ @@ -188,23 +183,21 @@ api_epg_entry ( epg_broadcast_t *eb, const char *lang, const access_t *perm, con if (eb->age_rating) htsmsg_add_u32(m, "ageRating", eb->age_rating); - if(epggrab_conf.epgdb_processparentallabels) - { - if (eb->rating_label) - { - if(eb->rating_label->rl_display_label){ - htsmsg_add_str(m, "ratingLabel", eb->rating_label->rl_display_label); - } - if(eb->rating_label->rl_icon){ - s = eb->rating_label->rl_icon; - if (!strempty(s)) { - s = imagecache_get_propstr(s, buf, sizeof(buf)); - if (s) - htsmsg_add_str(m, "ratingLabelIcon", s); - }//END we got an imagecache - }//END rating label icon is not null - }//END rating label is not null - }//END parental labels enabled. + if (epggrab_conf.epgdb_processparentallabels) { + if (eb->rating_label) { + if (eb->rating_label->rl_display_label) { + htsmsg_add_str(m, "ratingLabel", eb->rating_label->rl_display_label); + } + if (eb->rating_label->rl_icon) { + s = eb->rating_label->rl_icon; + if (!strempty(s)) { + s = imagecache_get_propstr(s, buf, sizeof(buf)); + if (s) + htsmsg_add_str(m, "ratingLabelIcon", s); + } // END we got an imagecache + } // END rating label icon is not null + } // END rating label is not null + } // END parental labels enabled. if (eb->first_aired) htsmsg_add_s64(m, "first_aired", eb->first_aired); @@ -213,7 +206,7 @@ api_epg_entry ( epg_broadcast_t *eb, const char *lang, const access_t *perm, con /* Content Type */ m2 = NULL; - LIST_FOREACH(eg, &eb->genre, link) { + LIST_FOREACH (eg, &eb->genre, link) { if (m2 == NULL) m2 = htsmsg_create_list(); htsmsg_add_u32(m2, NULL, eg->code); @@ -224,11 +217,10 @@ api_epg_entry ( epg_broadcast_t *eb, const char *lang, const access_t *perm, con /* Recording */ if (eb->channel && !access_verify2(perm, ACCESS_RECORDER)) { /* Note: only first hit is matched */ - LIST_FOREACH(de, &eb->channel->ch_dvrs, de_channel_link) { + LIST_FOREACH (de, &eb->channel->ch_dvrs, de_channel_link) { if (de->de_bcast != eb) continue; - if (access_verify_list(perm->aa_dvrcfgs, - idnode_uuid_as_str(&de->de_config->dvr_id, ubuf))) + if (access_verify_list(perm->aa_dvrcfgs, idnode_uuid_as_str(&de->de_config->dvr_id, ubuf))) continue; htsmsg_add_uuid(m, "dvrUuid", &de->de_id.in_uuid); htsmsg_add_str(m, "dvrState", dvr_entry_schedstatus(de)); @@ -243,18 +235,12 @@ api_epg_entry ( epg_broadcast_t *eb, const char *lang, const access_t *perm, con return m; } -static void -api_epg_filter_set_str - ( epg_filter_str_t *f, const char *str, int comp ) -{ - f->str = strdup(str); +static void api_epg_filter_set_str(epg_filter_str_t* f, const char* str, int comp) { + f->str = strdup(str); f->comp = comp; } -static void -api_epg_filter_add_str - ( epg_query_t *eq, const char *k, const char *v, int comp ) -{ +static void api_epg_filter_add_str(epg_query_t* eq, const char* k, const char* v, int comp) { if (!strcmp(k, "channelName")) api_epg_filter_set_str(&eq->channel_name, v, comp); else if (!strcmp(k, "title")) @@ -269,10 +255,7 @@ api_epg_filter_add_str api_epg_filter_set_str(&eq->extratext, v, comp); } -static void -api_epg_filter_set_num - ( epg_filter_num_t *f, int64_t v1, int64_t v2, int comp ) -{ +static void api_epg_filter_set_num(epg_filter_num_t* f, int64_t v1, int64_t v2, int comp) { /* Range? */ if (f->comp == EC_LT && comp == EC_GT) { f->val2 = f->val1; @@ -291,9 +274,7 @@ api_epg_filter_set_num } static void -api_epg_filter_add_num - ( epg_query_t *eq, const char *k, int64_t v1, int64_t v2, int comp ) -{ +api_epg_filter_add_num(epg_query_t* eq, const char* k, int64_t v1, int64_t v2, int comp) { if (!strcmp(k, "start")) api_epg_filter_set_num(&eq->start, v1, v2, comp); else if (!strcmp(k, "stop")) @@ -308,53 +289,45 @@ api_epg_filter_add_num api_epg_filter_set_num(&eq->age, v1, v2, comp); } -static struct strtab sortcmptab[] = { - { "start", ESK_START }, - { "stop", ESK_STOP }, - { "duration", ESK_DURATION }, - { "title", ESK_TITLE }, - { "subtitle", ESK_SUBTITLE }, - { "summary", ESK_SUMMARY }, - { "description", ESK_DESCRIPTION }, - { "extratext", ESK_EXTRATEXT }, - { "channelName", ESK_CHANNEL }, - { "channelNumber", ESK_CHANNEL_NUM }, - { "starRating", ESK_STARS }, - { "ageRating", ESK_AGE }, - { "genre", ESK_GENRE } -}; - -static struct strtab filtcmptab[] = { - { "gt", EC_GT }, - { "lt", EC_LT }, - { "eq", EC_EQ }, - { "regex", EC_RE }, - { "range", EC_RG } -}; - -static int64_t -api_epg_decode_channel_num ( const char *s ) -{ - int64_t v = atol(s); - const char *s1 = strchr(s, '.'); - if (s1) - v += atol(s1 + 1) % CHANNEL_SPLIT; - return v; +static struct strtab sortcmptab[] = {{"start", ESK_START}, + {"stop", ESK_STOP}, + {"duration", ESK_DURATION}, + {"title", ESK_TITLE}, + {"subtitle", ESK_SUBTITLE}, + {"summary", ESK_SUMMARY}, + {"description", ESK_DESCRIPTION}, + {"extratext", ESK_EXTRATEXT}, + {"channelName", ESK_CHANNEL}, + {"channelNumber", ESK_CHANNEL_NUM}, + {"starRating", ESK_STARS}, + {"ageRating", ESK_AGE}, + {"genre", ESK_GENRE}}; + +static struct strtab filtcmptab[] = {{"gt", EC_GT}, + {"lt", EC_LT}, + {"eq", EC_EQ}, + {"regex", EC_RE}, + {"range", EC_RG}}; + +static int64_t api_epg_decode_channel_num(const char* s) { + int64_t v = atol(s); + const char* s1 = strchr(s, '.'); + if (s1) + v += atol(s1 + 1) % CHANNEL_SPLIT; + return v; } static int -api_epg_grid - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int i; - epg_query_t eq; - const char *str, *blank = NULL; - char *lang; - uint32_t start, limit, end, genre; - int64_t duration_min, duration_max; +api_epg_grid(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + int i; + epg_query_t eq; + const char * str, *blank = NULL; + char* lang; + uint32_t start, limit, end, genre; + int64_t duration_min, duration_max; htsmsg_field_t *f, *f2; - htsmsg_t *l = NULL, *e, *filter; - const char* mode; + htsmsg_t * l = NULL, *e, *filter; + const char* mode; memset(&eq, 0, sizeof(eq)); @@ -362,12 +335,12 @@ api_epg_grid if (lang) eq.lang = strdup(lang); mode = htsmsg_get_str(args, "mode"); - str = htsmsg_get_str(args, "title"); + str = htsmsg_get_str(args, "title"); if (str) eq.stitle = strdup(str); eq.fulltext = htsmsg_get_bool_or_default(args, "fulltext", 0); eq.new_only = htsmsg_get_bool_or_default(args, "new", 0); - str = htsmsg_get_str(args, "channel"); + str = htsmsg_get_str(args, "channel"); if (str) eq.channel = strdup(str); str = htsmsg_get_str(args, "channelTag"); @@ -384,11 +357,11 @@ api_epg_grid eq.cat3 = strdup(str); if (mode != NULL) { - if (!strcmp(mode, "now")) { - eq.start.comp = EC_LT; - eq.stop.comp = EC_GT; - eq.start.val1 = eq.stop.val1 = gclk(); - } + if (!strcmp(mode, "now")) { + eq.start.comp = EC_LT; + eq.stop.comp = EC_GT; + eq.start.val1 = eq.stop.val1 = gclk(); + } } duration_min = -1; @@ -402,8 +375,8 @@ api_epg_grid } if (!htsmsg_get_u32(args, "contentType", &genre)) { - eq.genre = eq.genre_static; - eq.genre[0] = genre; + eq.genre = eq.genre_static; + eq.genre[0] = genre; eq.genre_count = 1; } @@ -411,20 +384,24 @@ api_epg_grid if ((filter = htsmsg_get_list(args, "filter"))) { HTSMSG_FOREACH(f, filter) { const char *k, *t, *v; - int comp; - if (!(e = htsmsg_get_map_by_field(f))) continue; - if (!(k = htsmsg_get_str(e, "field"))) continue; - if (!(t = htsmsg_get_str(e, "type"))) continue; + int comp; + if (!(e = htsmsg_get_map_by_field(f))) + continue; + if (!(k = htsmsg_get_str(e, "field"))) + continue; + if (!(t = htsmsg_get_str(e, "type"))) + continue; comp = str2val(htsmsg_get_str(e, "comparison") ?: "", filtcmptab); - if (comp == -1) comp = EC_EQ; + if (comp == -1) + comp = EC_EQ; if (!strcmp(k, "channelNumber")) { if (!strcmp(t, "numeric")) { f2 = htsmsg_field_find(e, "value"); if (f2) { int64_t v1, v2 = 0; if (f2->hmf_type == HMF_STR) { - const char *s = htsmsg_field_get_str(f2); - const char *z = s ? strchr(s, ';') : NULL; + const char* s = htsmsg_field_get_str(f2); + const char* z = s ? strchr(s, ';') : NULL; if (s) { v1 = api_epg_decode_channel_num(s); if (z) @@ -446,26 +423,26 @@ api_epg_grid if (f2) { int64_t v; if (f2->hmf_type == HMF_STR) { - htsmsg_t *z = api_epg_get_list(htsmsg_field_get_str(f2)); + htsmsg_t* z = api_epg_get_list(htsmsg_field_get_str(f2)); if (z) { - htsmsg_field_t *f3; - uint32_t count = 0; + htsmsg_field_t* f3; + uint32_t count = 0; HTSMSG_FOREACH(f3, z) - count++; + count++; if (ARRAY_SIZE(eq.genre_static) > count) eq.genre = malloc(sizeof(eq.genre[0]) * count); else eq.genre = eq.genre_static; HTSMSG_FOREACH(f3, z) - if (!htsmsg_field_get_s64(f3, &v)) - eq.genre[eq.genre_count++] = v; + if (!htsmsg_field_get_s64(f3, &v)) + eq.genre[eq.genre_count++] = v; htsmsg_destroy(z); } } else { if (!htsmsg_field_get_s64(f2, &v)) { eq.genre_count = 1; - eq.genre = eq.genre_static; - eq.genre[0] = v; + eq.genre = eq.genre_static; + eq.genre[0] = v; } } } @@ -478,9 +455,9 @@ api_epg_grid if (f2) { int64_t v1 = 0, v2 = 0; if (f2->hmf_type == HMF_STR) { - const char *z = htsmsg_field_get_str(f2); + const char* z = htsmsg_field_get_str(f2); if (z) { - const char *z2 = strchr(z, ';'); + const char* z2 = strchr(z, ';'); if (z2) v2 = strtoll(z2 + 1, NULL, 0); v1 = strtoll(z, NULL, 0); @@ -520,7 +497,8 @@ api_epg_grid end = MIN(eq.entries, start + limit); l = htsmsg_create_list(); for (i = start; i < end; i++) { - if (!(e = api_epg_entry(eq.result[i], lang, perm, &blank))) continue; + if (!(e = api_epg_entry(eq.result[i], lang, perm, &blank))) + continue; htsmsg_add_msg(l, NULL, e); } tvh_mutex_unlock(&global_lock); @@ -536,39 +514,35 @@ api_epg_grid return 0; } -static int -api_epg_sort_by_time_t(const void *a, const void *b, void *arg) -{ - const time_t *at= (const time_t*)a; - const time_t *bt= (const time_t*)b; +static int api_epg_sort_by_time_t(const void* a, const void* b, void* arg) { + const time_t* at = (const time_t*)a; + const time_t* bt = (const time_t*)b; return *at - *bt; } /// Generate a sorted list of episodes that /// do NOT match ebc_skip in to message l. /// @return number of entries allocated. -static uint32_t -api_epg_episode_sorted(const struct epg_set *set, - const access_t *perm, - htsmsg_t *l, - const char *lang, - const epg_broadcast_t *ebc_skip) -{ +static uint32_t api_epg_episode_sorted(const struct epg_set* set, + const access_t* perm, + htsmsg_t* l, + const char* lang, + const epg_broadcast_t* ebc_skip) { typedef struct { - time_t start; - htsmsg_t *m; + time_t start; + htsmsg_t* m; } bcast_entry_t; - epg_broadcast_t *ebc; - htsmsg_t *m; - bcast_entry_t *bcast_entries = NULL; - const epg_set_item_t *item; - bcast_entry_t new_bcast_entry; - size_t num_allocated = 0; - size_t num_entries = 0; - size_t i; + epg_broadcast_t* ebc; + htsmsg_t* m; + bcast_entry_t* bcast_entries = NULL; + const epg_set_item_t* item; + bcast_entry_t new_bcast_entry; + size_t num_allocated = 0; + size_t num_entries = 0; + size_t i; - LIST_FOREACH(item, &set->broadcasts, item_link) { + LIST_FOREACH (item, &set->broadcasts, item_link) { ebc = item->broadcast; if (ebc != ebc_skip) { m = api_epg_entry(ebc, lang, perm, NULL); @@ -578,17 +552,17 @@ api_epg_episode_sorted(const struct epg_set *set, bcast_entries = realloc(bcast_entries, num_allocated * sizeof(bcast_entry_t)); } - new_bcast_entry.start = htsmsg_get_u32_or_default(m, "start", 0); - new_bcast_entry.m = m; + new_bcast_entry.start = htsmsg_get_u32_or_default(m, "start", 0); + new_bcast_entry.m = m; bcast_entries[num_entries++] = new_bcast_entry; } } - if(bcast_entries != NULL) + if (bcast_entries != NULL) tvh_qsort_r(bcast_entries, num_entries, sizeof(bcast_entry_t), api_epg_sort_by_time_t, 0); - for (i=0; iepisodelink; +static void api_epg_episode_broadcasts(access_t* perm, + htsmsg_t* l, + const char* lang, + epg_broadcast_t* ep, + uint32_t* entries, + epg_broadcast_t* ebc_skip) { + epg_set_t* episodelink = ep->episodelink; if (episodelink == NULL) return; @@ -614,13 +588,11 @@ api_epg_episode_broadcasts } static int -api_epg_alternative - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - uint32_t id, entries = 0; - htsmsg_t *l; - epg_broadcast_t *e; - char *lang; +api_epg_alternative(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + uint32_t id, entries = 0; + htsmsg_t* l; + epg_broadcast_t* e; + char* lang; if (htsmsg_get_u32(args, "eventId", &id)) return EINVAL; @@ -645,15 +617,13 @@ api_epg_alternative } static int -api_epg_related - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - uint32_t id, entries = 0; - htsmsg_t *l; - epg_broadcast_t *e; - char *lang, *title_esc, *title_anchor; - epg_set_t *serieslink = NULL; - const char *title = NULL; +api_epg_related(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + uint32_t id, entries = 0; + htsmsg_t* l; + epg_broadcast_t* e; + char * lang, *title_esc, *title_anchor; + epg_set_t* serieslink = NULL; + const char* title = NULL; if (htsmsg_get_u32(args, "eventId", &id)) return EINVAL; @@ -678,7 +648,7 @@ api_epg_related /* Need to escape/anchor the search, otherwise the film "elf" * matches titles containing "self". */ - title_esc = regexp_escape(title); + title_esc = regexp_escape(title); title_anchor = alloca(strlen(title_esc) + 3); sprintf(title_anchor, "^%s$", title_esc); htsmsg_add_str(args, "title", title_anchor); @@ -706,15 +676,13 @@ api_epg_related } static int -api_epg_load - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - uint32_t id = 0, entries = 0; - htsmsg_t *l, *ids = NULL, *m; - htsmsg_field_t *f; - epg_broadcast_t *e; - const char *blank = NULL; - char *lang; +api_epg_load(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + uint32_t id = 0, entries = 0; + htsmsg_t * l, *ids = NULL, *m; + htsmsg_field_t* f; + epg_broadcast_t* e; + const char* blank = NULL; + char* lang; if (!(f = htsmsg_field_find(args, "eventId"))) return EINVAL; @@ -729,10 +697,13 @@ api_epg_load lang = access_get_lang(perm, htsmsg_get_str(args, "lang")); if (ids) { HTSMSG_FOREACH(f, ids) { - if (htsmsg_field_get_u32(f, &id)) continue; + if (htsmsg_field_get_u32(f, &id)) + continue; e = epg_broadcast_find_by_id(id); - if (e == NULL) continue; - if ((m = api_epg_entry(e, lang, perm, &blank)) == NULL) continue; + if (e == NULL) + continue; + if ((m = api_epg_entry(e, lang, perm, &blank)) == NULL) + continue; htsmsg_add_msg(l, NULL, m); entries++; } @@ -754,12 +725,13 @@ api_epg_load return 0; } -static int -api_epg_content_type_list(access_t *perm, void *opaque, const char *op, - htsmsg_t *args, htsmsg_t **resp) -{ - htsmsg_t *array; - int full = 0; +static int api_epg_content_type_list(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_t* array; + int full = 0; htsmsg_get_bool(args, "full", &full); @@ -769,16 +741,15 @@ api_epg_content_type_list(access_t *perm, void *opaque, const char *op, return 0; } -void api_epg_init ( void ) -{ +void api_epg_init(void) { static api_hook_t ah[] = { - { "epg/events/grid", ACCESS_ANONYMOUS, api_epg_grid, NULL }, - { "epg/events/alternative", ACCESS_ANONYMOUS, api_epg_alternative, NULL }, - { "epg/events/related", ACCESS_ANONYMOUS, api_epg_related, NULL }, - { "epg/events/load", ACCESS_ANONYMOUS, api_epg_load, NULL }, - { "epg/content_type/list", ACCESS_ANONYMOUS, api_epg_content_type_list, NULL }, + {"epg/events/grid", ACCESS_ANONYMOUS, api_epg_grid, NULL}, + {"epg/events/alternative", ACCESS_ANONYMOUS, api_epg_alternative, NULL}, + {"epg/events/related", ACCESS_ANONYMOUS, api_epg_related, NULL}, + {"epg/events/load", ACCESS_ANONYMOUS, api_epg_load, NULL}, + {"epg/content_type/list", ACCESS_ANONYMOUS, api_epg_content_type_list, NULL}, - { NULL }, + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_epggrab.c b/src/api/api_epggrab.c index 656c3bfc7..5e6653d57 100644 --- a/src/api/api_epggrab.c +++ b/src/api/api_epggrab.c @@ -22,25 +22,26 @@ #include "api.h" #include "epggrab.h" -static void -api_epggrab_channel_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - epggrab_channel_t *ec; +static void api_epggrab_channel_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + epggrab_channel_t* ec; - TAILQ_FOREACH(ec, &epggrab_channel_entries, all_link) + TAILQ_FOREACH (ec, &epggrab_channel_entries, all_link) idnode_set_add(ins, (idnode_t*)ec, &conf->filter, perm->aa_lang_ui); } -static int -api_epggrab_module_list - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_t *l = htsmsg_create_list(), *m; - epggrab_module_t *mod; - char buf[384]; +static int api_epggrab_module_list(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_t * l = htsmsg_create_list(), *m; + epggrab_module_t* mod; + char buf[384]; tvh_mutex_lock(&global_lock); - LIST_FOREACH(mod, &epggrab_modules, link) { + LIST_FOREACH (mod, &epggrab_modules, link) { m = htsmsg_create_map(); htsmsg_add_uuid(m, "uuid", &mod->idnode.in_uuid); htsmsg_add_str(m, "status", epggrab_module_get_status(mod)); @@ -53,10 +54,11 @@ api_epggrab_module_list return 0; } -static int -api_epggrab_ota_trigger - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_epggrab_ota_trigger(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { int32_t s32; if (htsmsg_get_s32(args, "trigger", &s32)) return EINVAL; @@ -68,10 +70,11 @@ api_epggrab_ota_trigger return 0; } -static int -api_epggrab_rerun_internal - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_epggrab_rerun_internal(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { int32_t s32; if (htsmsg_get_s32(args, "rerun", &s32)) return EINVAL; @@ -83,19 +86,21 @@ api_epggrab_rerun_internal return 0; } -void api_epggrab_init ( void ) -{ +void api_epggrab_init(void) { static api_hook_t ah[] = { - { "epggrab/channel/list", ACCESS_ANONYMOUS, api_idnode_load_by_class, (void*)&epggrab_channel_class }, - { "epggrab/channel/class", ACCESS_ADMIN, api_idnode_class, (void*)&epggrab_channel_class }, - { "epggrab/channel/grid", ACCESS_ADMIN, api_idnode_grid, api_epggrab_channel_grid }, + {"epggrab/channel/list", + ACCESS_ANONYMOUS, + api_idnode_load_by_class, + (void*)&epggrab_channel_class}, + {"epggrab/channel/class", ACCESS_ADMIN, api_idnode_class, (void*)&epggrab_channel_class}, + {"epggrab/channel/grid", ACCESS_ADMIN, api_idnode_grid, api_epggrab_channel_grid}, - { "epggrab/module/list", ACCESS_ADMIN, api_epggrab_module_list, NULL }, - { "epggrab/config/load", ACCESS_ADMIN, api_idnode_load_simple, &epggrab_conf.idnode }, - { "epggrab/config/save", ACCESS_ADMIN, api_idnode_save_simple, &epggrab_conf.idnode }, - { "epggrab/ota/trigger", ACCESS_ADMIN, api_epggrab_ota_trigger, NULL }, - { "epggrab/internal/rerun", ACCESS_ADMIN, api_epggrab_rerun_internal, NULL }, - { NULL }, + {"epggrab/module/list", ACCESS_ADMIN, api_epggrab_module_list, NULL}, + {"epggrab/config/load", ACCESS_ADMIN, api_idnode_load_simple, &epggrab_conf.idnode}, + {"epggrab/config/save", ACCESS_ADMIN, api_idnode_save_simple, &epggrab_conf.idnode}, + {"epggrab/ota/trigger", ACCESS_ADMIN, api_epggrab_ota_trigger, NULL}, + {"epggrab/internal/rerun", ACCESS_ADMIN, api_epggrab_rerun_internal, NULL}, + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_esfilter.c b/src/api/api_esfilter.c index d612ec285..10786bfce 100644 --- a/src/api/api_esfilter.c +++ b/src/api/api_esfilter.c @@ -22,26 +22,27 @@ #include "access.h" #include "api.h" -static void -api_esfilter_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args, - esfilter_class_t cls ) -{ - esfilter_t *esf; - - TAILQ_FOREACH(esf, &esfilters[cls], esf_link) +static void api_esfilter_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args, + esfilter_class_t cls) { + esfilter_t* esf; + + TAILQ_FOREACH (esf, &esfilters[cls], esf_link) idnode_set_add(ins, (idnode_t*)esf, &conf->filter, perm->aa_lang_ui); } -static int -api_esfilter_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp, - esfilter_class_t cls ) -{ - htsmsg_t *conf; - esfilter_t *esf; +static int api_esfilter_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp, + esfilter_class_t cls) { + htsmsg_t* conf; + esfilter_t* esf; - if (!(conf = htsmsg_get_map(args, "conf"))) + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; tvh_mutex_lock(&global_lock); @@ -53,13 +54,20 @@ api_esfilter_create return 0; } -#define ESFILTER(func, t) \ -static void api_esfilter_grid_##func \ - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) \ -{ return api_esfilter_grid(perm, ins, conf, args, (t)); } \ -static int api_esfilter_create_##func \ - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) \ -{ return api_esfilter_create(perm, opaque, op, args, resp, (t)); } +#define ESFILTER(func, t) \ + static void api_esfilter_grid_##func(access_t* perm, \ + idnode_set_t* ins, \ + api_idnode_grid_conf_t* conf, \ + htsmsg_t* args) { \ + return api_esfilter_grid(perm, ins, conf, args, (t)); \ + } \ + static int api_esfilter_create_##func(access_t* perm, \ + void* opaque, \ + const char* op, \ + htsmsg_t* args, \ + htsmsg_t** resp) { \ + return api_esfilter_create(perm, opaque, op, args, resp, (t)); \ + } ESFILTER(video, ESF_CLASS_VIDEO); ESFILTER(audio, ESF_CLASS_AUDIO); @@ -68,34 +76,36 @@ ESFILTER(subtit, ESF_CLASS_SUBTIT); ESFILTER(ca, ESF_CLASS_CA); ESFILTER(other, ESF_CLASS_OTHER); -void api_esfilter_init ( void ) -{ +void api_esfilter_init(void) { static api_hook_t ah[] = { - { "esfilter/video/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&esfilter_class_video }, - { "esfilter/video/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_video }, - { "esfilter/video/create", ACCESS_ADMIN, api_esfilter_create_video, NULL }, - - { "esfilter/audio/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&esfilter_class_audio }, - { "esfilter/audio/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_audio }, - { "esfilter/audio/create", ACCESS_ADMIN, api_esfilter_create_audio, NULL }, - - { "esfilter/teletext/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&esfilter_class_teletext }, - { "esfilter/teletext/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_teletext }, - { "esfilter/teletext/create",ACCESS_ADMIN, api_esfilter_create_teletext, NULL }, - - { "esfilter/subtit/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&esfilter_class_subtit }, - { "esfilter/subtit/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_subtit }, - { "esfilter/subtit/create", ACCESS_ADMIN, api_esfilter_create_subtit, NULL }, - - { "esfilter/ca/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&esfilter_class_ca }, - { "esfilter/ca/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_ca }, - { "esfilter/ca/create", ACCESS_ADMIN, api_esfilter_create_ca, NULL }, - - { "esfilter/other/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&esfilter_class_other }, - { "esfilter/other/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_other }, - { "esfilter/other/create", ACCESS_ADMIN, api_esfilter_create_other, NULL }, - - { NULL }, + {"esfilter/video/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&esfilter_class_video}, + {"esfilter/video/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_video}, + {"esfilter/video/create", ACCESS_ADMIN, api_esfilter_create_video, NULL}, + + {"esfilter/audio/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&esfilter_class_audio}, + {"esfilter/audio/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_audio}, + {"esfilter/audio/create", ACCESS_ADMIN, api_esfilter_create_audio, NULL}, + + {"esfilter/teletext/class", + ACCESS_ANONYMOUS, + api_idnode_class, + (void*)&esfilter_class_teletext}, + {"esfilter/teletext/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_teletext}, + {"esfilter/teletext/create", ACCESS_ADMIN, api_esfilter_create_teletext, NULL}, + + {"esfilter/subtit/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&esfilter_class_subtit}, + {"esfilter/subtit/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_subtit}, + {"esfilter/subtit/create", ACCESS_ADMIN, api_esfilter_create_subtit, NULL}, + + {"esfilter/ca/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&esfilter_class_ca}, + {"esfilter/ca/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_ca}, + {"esfilter/ca/create", ACCESS_ADMIN, api_esfilter_create_ca, NULL}, + + {"esfilter/other/class", ACCESS_ANONYMOUS, api_idnode_class, (void*)&esfilter_class_other}, + {"esfilter/other/grid", ACCESS_ANONYMOUS, api_idnode_grid, api_esfilter_grid_other}, + {"esfilter/other/create", ACCESS_ADMIN, api_esfilter_create_other, NULL}, + + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_idnode.c b/src/api/api_idnode.c index 9096bfe9d..742b2bcae 100644 --- a/src/api/api_idnode.c +++ b/src/api/api_idnode.c @@ -23,20 +23,18 @@ #include "htsmsg.h" #include "api.h" -htsmsg_t * -api_idnode_flist_conf( htsmsg_t *args, const char *name ) -{ - htsmsg_t *m = NULL; - const char *s = htsmsg_get_str(args, name); - char *r, *saveptr = NULL; - int use = 1; +htsmsg_t* api_idnode_flist_conf(htsmsg_t* args, const char* name) { + htsmsg_t* m = NULL; + const char* s = htsmsg_get_str(args, name); + char * r, *saveptr = NULL; + int use = 1; if (s && s[0] == '-') { use = 0; s++; } if (s && s[0] != '\0') { s = r = strdup(s); - r = strtok_r(r, ",;:", &saveptr); + r = strtok_r(r, ",;:", &saveptr); while (r) { while (*r != '\0' && *r <= ' ') r++; @@ -47,24 +45,17 @@ api_idnode_flist_conf( htsmsg_t *args, const char *name ) } r = strtok_r(NULL, ",;:", &saveptr); } - free((char *)s); + free((char*)s); } return m; } -static struct strtab filtcmptab[] = { - { "gt", IC_GT }, - { "lt", IC_LT }, - { "eq", IC_EQ } -}; +static struct strtab filtcmptab[] = {{"gt", IC_GT}, {"lt", IC_LT}, {"eq", IC_EQ}}; -static void -api_idnode_grid_conf - ( access_t *perm, htsmsg_t *args, api_idnode_grid_conf_t *conf ) -{ +static void api_idnode_grid_conf(access_t* perm, htsmsg_t* args, api_idnode_grid_conf_t* conf) { htsmsg_field_t *f, *f2; - htsmsg_t *filter, *e; - const char *str; + htsmsg_t * filter, *e; + const char* str; conf->start = htsmsg_get_u32_or_default(args, "start", 0); conf->limit = htsmsg_get_u32_or_default(args, "limit", 50); @@ -73,9 +64,12 @@ api_idnode_grid_conf if ((filter = htsmsg_get_list(args, "filter"))) { HTSMSG_FOREACH(f, filter) { const char *k, *t, *v; - if (!(e = htsmsg_get_map_by_field(f))) continue; - if (!(k = htsmsg_get_str(e, "field"))) continue; - if (!(t = htsmsg_get_str(e, "type"))) continue; + if (!(e = htsmsg_get_map_by_field(f))) + continue; + if (!(k = htsmsg_get_str(e, "field"))) + continue; + if (!(t = htsmsg_get_str(e, "type"))) + continue; if (!strcmp(t, "string")) { if ((v = htsmsg_get_str(e, "value"))) idnode_filter_add_str(&conf->filter, k, v, IC_RE); @@ -115,17 +109,14 @@ api_idnode_grid_conf conf->sort.key = NULL; } -int -api_idnode_grid - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int i; - htsmsg_t *list, *e; - htsmsg_t *flist = api_idnode_flist_conf(args, "list"); - api_idnode_grid_conf_t conf = { 0 }; - idnode_t *in; - idnode_set_t ins = { 0 }; - api_idnode_grid_callback_t cb = opaque; +int api_idnode_grid(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + int i; + htsmsg_t * list, *e; + htsmsg_t* flist = api_idnode_flist_conf(args, "list"); + api_idnode_grid_conf_t conf = {0}; + idnode_t* in; + idnode_set_t ins = {0}; + api_idnode_grid_callback_t cb = opaque; /* Grid configuration */ api_idnode_grid_conf(perm, args, &conf); @@ -139,7 +130,7 @@ api_idnode_grid idnode_set_sort(&ins, &conf.sort); /* Paginate */ - list = htsmsg_create_list(); + list = htsmsg_create_list(); for (i = conf.start; i < ins.is_count && conf.limit != 0; i++) { in = ins.is_array[i]; if (idnode_perm(in, perm, NULL)) @@ -149,7 +140,8 @@ api_idnode_grid idnode_read0(in, e, flist, 0, conf.sort.lang); idnode_perm_unset(in); htsmsg_add_msg(list, NULL, e); - if (conf.limit > 0) conf.limit--; + if (conf.limit > 0) + conf.limit--; } tvh_mutex_unlock(&global_lock); @@ -157,7 +149,7 @@ api_idnode_grid /* Output */ *resp = htsmsg_create_map(); htsmsg_add_msg(*resp, "entries", list); - htsmsg_add_u32(*resp, "total", ins.is_count); + htsmsg_add_u32(*resp, "total", ins.is_count); /* Cleanup */ free(ins.is_array); @@ -167,16 +159,17 @@ api_idnode_grid return 0; } -static int -api_idnode_load_by_class0 - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int i, _enum; - const idclass_t *idc; - idnode_set_t *is; - idnode_t *in; - htsmsg_t *l, *e; - char ubuf[UUID_HEX_SIZE], buf[384]; +static int api_idnode_load_by_class0(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int i, _enum; + const idclass_t* idc; + idnode_set_t* is; + idnode_t* in; + htsmsg_t * l, *e; + char ubuf[UUID_HEX_SIZE], buf[384]; // TODO: this only works if pass as integer _enum = htsmsg_get_bool_or_default(args, "enum", 0); @@ -196,12 +189,12 @@ api_idnode_load_by_class0 /* Name/UUID only */ if (_enum) { e = htsmsg_create_key_val(idnode_uuid_as_str(in, ubuf), - idnode_get_title(in, perm->aa_lang_ui, buf, sizeof(buf))); + idnode_get_title(in, perm->aa_lang_ui, buf, sizeof(buf))); - /* Full record */ + /* Full record */ } else { - htsmsg_t *flist = api_idnode_flist_conf(args, "list"); - e = idnode_serialize0(in, flist, 0, perm->aa_lang_ui); + htsmsg_t* flist = api_idnode_flist_conf(args, "list"); + e = idnode_serialize0(in, flist, 0, perm->aa_lang_ui); htsmsg_destroy(flist); } @@ -220,10 +213,11 @@ api_idnode_load_by_class0 return 0; } -int -api_idnode_load_by_class - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +int api_idnode_load_by_class(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { int ret; tvh_mutex_lock(&global_lock); ret = api_idnode_load_by_class0(perm, opaque, op, args, resp); @@ -232,18 +226,16 @@ api_idnode_load_by_class } static int -api_idnode_load - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err = 0, meta, grid, count = 0; - idnode_t *in; - htsmsg_t *uuids, *l = NULL, *m, *flist; - htsmsg_field_t *f; - const char *uuid = NULL, *class; +api_idnode_load(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + int err = 0, meta, grid, count = 0; + idnode_t* in; + htsmsg_t * uuids, *l = NULL, *m, *flist; + htsmsg_field_t* f; + const char * uuid = NULL, *class; /* Class based */ if ((class = htsmsg_get_str(args, "class"))) { - const idclass_t *idc; + const idclass_t* idc; tvh_mutex_lock(&global_lock); idc = idclass_find(class); if (idc) @@ -253,7 +245,7 @@ api_idnode_load tvh_mutex_unlock(&global_lock); return err; } - + /* UUIDs */ if (!(f = htsmsg_field_find(args, "uuid"))) return EINVAL; @@ -272,11 +264,13 @@ api_idnode_load /* Multiple */ if (uuids) { - const idnodes_rb_t *domain = NULL; - l = htsmsg_create_list(); + const idnodes_rb_t* domain = NULL; + l = htsmsg_create_list(); HTSMSG_FOREACH(f, uuids) { - if (!(uuid = htsmsg_field_get_str(f))) continue; - if (!(in = idnode_find(uuid, NULL, domain))) continue; + if (!(uuid = htsmsg_field_get_str(f))) + continue; + if (!(in = idnode_find(uuid, NULL, domain))) + continue; domain = in->in_domain; if (idnode_perm(in, perm, NULL)) { err = EPERM; @@ -299,7 +293,7 @@ api_idnode_load if (count) err = 0; - /* Single */ + /* Single */ } else { l = htsmsg_create_list(); if ((in = idnode_find(uuid, NULL, NULL)) != NULL) { @@ -335,14 +329,15 @@ api_idnode_load return err; } -int -api_idnode_load_simple - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err = 0, meta; - htsmsg_t *l = NULL, *m, *flist; - const char *class; - idnode_t *in = (idnode_t *)opaque; +int api_idnode_load_simple(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int err = 0, meta; + htsmsg_t *l = NULL, *m, *flist; + const char* class; + idnode_t* in = (idnode_t*)opaque; /* Class based */ if ((class = htsmsg_get_str(args, "class"))) { @@ -383,16 +378,14 @@ api_idnode_load_simple } static int -api_idnode_save - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err = EINVAL; - idnode_t *in; - htsmsg_t *msg, *conf; - htsmsg_field_t *f; - const char *uuid; - int count = 0; - const idnodes_rb_t *domain = NULL; +api_idnode_save(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + int err = EINVAL; + idnode_t* in; + htsmsg_t * msg, *conf; + htsmsg_field_t* f; + const char* uuid; + int count = 0; + const idnodes_rb_t* domain = NULL; if (!(f = htsmsg_field_find(args, "node"))) return EINVAL; @@ -439,10 +432,9 @@ api_idnode_save idnode_update(in, msg); idnode_perm_unset(in); err = 0; - } - /* Multiple */ + /* Multiple */ } else { HTSMSG_FOREACH(f, msg) { @@ -463,7 +455,6 @@ api_idnode_save } if (count) err = 0; - } // TODO: return updated UUIDs? @@ -474,19 +465,20 @@ exit: return err; } -int -api_idnode_save_simple - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err = 0; - htsmsg_t *msg; - htsmsg_field_t *f; - idnode_t *in = (idnode_t *)opaque; +int api_idnode_save_simple(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int err = 0; + htsmsg_t* msg; + htsmsg_field_t* f; + idnode_t* in = (idnode_t*)opaque; if (!(f = htsmsg_field_find(args, "node"))) return EINVAL; if (!(msg = htsmsg_field_get_map(f))) - return EINVAL; + return EINVAL; tvh_mutex_lock(&global_lock); @@ -503,14 +495,11 @@ api_idnode_save_simple return err; } -int -api_idnode_tree - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - const char *uuid; - const char *root = NULL; - int isroot; - idnode_t *node = NULL; +int api_idnode_tree(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + const char* uuid; + const char* root = NULL; + int isroot; + idnode_t* node = NULL; api_idnode_tree_callback_t rootfn = opaque; /* UUID */ @@ -526,7 +515,7 @@ api_idnode_tree if (isroot && !(root || rootfn)) return EINVAL; - tvh_mutex_lock(&global_lock); + tvh_mutex_lock(&global_lock); if (!isroot || root) { if (!(node = idnode_find(isroot ? root : uuid, NULL, NULL))) { @@ -539,7 +528,7 @@ api_idnode_tree /* Root node */ if (isroot && node) { - htsmsg_t *m; + htsmsg_t* m; if (idnode_perm(node, perm, NULL)) { tvh_mutex_unlock(&global_lock); return EINVAL; @@ -549,15 +538,15 @@ api_idnode_tree htsmsg_add_u32(m, "leaf", idnode_is_leaf(node)); htsmsg_add_msg(*resp, NULL, m); - /* Children */ + /* Children */ } else { - idnode_set_t *v = node ? idnode_get_childs(node) : rootfn(perm); + idnode_set_t* v = node ? idnode_get_childs(node) : rootfn(perm); if (v) { int i; idnode_set_sort_by_title(v, perm->aa_lang_ui); - for(i = 0; i < v->is_count; i++) { - idnode_t *in = v->is_array[i]; - htsmsg_t *m; + for (i = 0; i < v->is_count; i++) { + idnode_t* in = v->is_array[i]; + htsmsg_t* m; if (idnode_perm(in, perm, NULL)) continue; m = idnode_serialize(v->is_array[i], perm->aa_lang_ui); @@ -573,14 +562,15 @@ api_idnode_tree return 0; } -int -api_idnode_class - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err = EINVAL; - const char *name; - const idclass_t *idc; - htsmsg_t *flist = api_idnode_flist_conf(args, "list"); +int api_idnode_class(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int err = EINVAL; + const char* name; + const idclass_t* idc; + htsmsg_t* flist = api_idnode_flist_conf(args, "list"); tvh_mutex_lock(&global_lock); @@ -588,9 +578,9 @@ api_idnode_class if (!opaque) { if (!(name = htsmsg_get_str(args, "name"))) goto exit; - if (!(idc = idclass_find(name))) + if (!(idc = idclass_find(name))) goto exit; - + } else { idc = opaque; } @@ -606,18 +596,18 @@ exit: return err; } -int -api_idnode_handler - ( const idclass_t *idc, - access_t *perm, htsmsg_t *args, htsmsg_t **resp, - void (*handler)(access_t *perm, idnode_t *in), - const char *op, int destroyed ) -{ - int err = 0; - idnode_t *in; - htsmsg_t *uuids, *msg; - htsmsg_field_t *f; - const char *uuid; +int api_idnode_handler(const idclass_t* idc, + access_t* perm, + htsmsg_t* args, + htsmsg_t** resp, + void (*handler)(access_t* perm, idnode_t* in), + const char* op, + int destroyed) { + int err = 0; + idnode_t* in; + htsmsg_t * uuids, *msg; + htsmsg_field_t* f; + const char* uuid; /* ID based */ if (!(f = htsmsg_field_find(args, "uuid"))) @@ -628,12 +618,13 @@ api_idnode_handler /* Multiple */ if (uuids) { - const idnodes_rb_t *domain = NULL; - int cnt = 0, pcnt = 0; + const idnodes_rb_t* domain = NULL; + int cnt = 0, pcnt = 0; msg = htsmsg_create_map(); htsmsg_add_str(msg, "__op__", op); HTSMSG_FOREACH(f, uuids) { - if (!(uuid = htsmsg_field_get_string(f))) continue; + if (!(uuid = htsmsg_field_get_string(f))) + continue; tvh_mutex_lock(&global_lock); if ((in = idnode_find(uuid, idc, domain)) != NULL) { domain = in->in_domain; @@ -655,12 +646,12 @@ api_idnode_handler if (pcnt && !cnt) err = EPERM; - - /* Single */ + + /* Single */ } else { uuid = htsmsg_field_get_string(f); tvh_mutex_lock(&global_lock); - if (!(in = idnode_find(uuid, idc, NULL))) { + if (!(in = idnode_find(uuid, idc, NULL))) { err = ENOENT; } else { msg = htsmsg_create_map(); @@ -677,61 +668,44 @@ api_idnode_handler tvh_mutex_unlock(&global_lock); } - return err; } -static void -api_idnode_delete_ (access_t *perm, idnode_t *in) -{ +static void api_idnode_delete_(access_t* perm, idnode_t* in) { return idnode_delete(in); } static int -api_idnode_delete - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +api_idnode_delete(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { return api_idnode_handler(NULL, perm, args, resp, api_idnode_delete_, "delete", 1); } -static void -api_idnode_moveup_ (access_t *perm, idnode_t *in) -{ +static void api_idnode_moveup_(access_t* perm, idnode_t* in) { return idnode_moveup(in); } static int -api_idnode_moveup - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +api_idnode_moveup(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { return api_idnode_handler(NULL, perm, args, resp, api_idnode_moveup_, "moveup", 0); } -static void -api_idnode_movedown_ (access_t *perm, idnode_t *in) -{ +static void api_idnode_movedown_(access_t* perm, idnode_t* in) { return idnode_movedown(in); } static int -api_idnode_movedown - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +api_idnode_movedown(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { return api_idnode_handler(NULL, perm, args, resp, api_idnode_movedown_, "movedown", 0); } -void -api_idnode_create( htsmsg_t **resp, idnode_t *in ) -{ +void api_idnode_create(htsmsg_t** resp, idnode_t* in) { idnode_changed(in); if (*resp == NULL) *resp = htsmsg_create_map(); htsmsg_add_uuid(*resp, "uuid", &in->in_uuid); } -void -api_idnode_create_list( htsmsg_t **resp, htsmsg_t *list ) -{ +void api_idnode_create_list(htsmsg_t** resp, htsmsg_t* list) { if (list == NULL) { htsmsg_destroy(list); return; @@ -743,20 +717,19 @@ api_idnode_create_list( htsmsg_t **resp, htsmsg_t *list ) #define ACCESS_IDNODE (ACCESS_ANONYMOUS | ACCESS_NO_EMPTY_ARGS) -void api_idnode_init ( void ) -{ +void api_idnode_init(void) { /* * note: permissions are verified using idnode_perm() calls */ static api_hook_t ah[] = { - { "idnode/load", ACCESS_IDNODE, api_idnode_load, NULL }, - { "idnode/save", ACCESS_IDNODE, api_idnode_save, NULL }, - { "idnode/tree", ACCESS_IDNODE, api_idnode_tree, NULL }, - { "idnode/class", ACCESS_IDNODE, api_idnode_class, NULL }, - { "idnode/delete", ACCESS_IDNODE, api_idnode_delete, NULL }, - { "idnode/moveup", ACCESS_IDNODE, api_idnode_moveup, NULL }, - { "idnode/movedown", ACCESS_IDNODE, api_idnode_movedown, NULL }, - { NULL }, + {"idnode/load", ACCESS_IDNODE, api_idnode_load, NULL}, + {"idnode/save", ACCESS_IDNODE, api_idnode_save, NULL}, + {"idnode/tree", ACCESS_IDNODE, api_idnode_tree, NULL}, + {"idnode/class", ACCESS_IDNODE, api_idnode_class, NULL}, + {"idnode/delete", ACCESS_IDNODE, api_idnode_delete, NULL}, + {"idnode/moveup", ACCESS_IDNODE, api_idnode_moveup, NULL}, + {"idnode/movedown", ACCESS_IDNODE, api_idnode_movedown, NULL}, + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_imagecache.c b/src/api/api_imagecache.c index 35cda1e71..01dc5ad2d 100644 --- a/src/api/api_imagecache.c +++ b/src/api/api_imagecache.c @@ -23,10 +23,11 @@ #include "api.h" #include "imagecache.h" -static int -api_imagecache_clean - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_imagecache_clean(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { int b; if (htsmsg_get_bool(args, "clean", &b)) return EINVAL; @@ -35,10 +36,11 @@ api_imagecache_clean return 0; } -static int -api_imagecache_trigger - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_imagecache_trigger(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { int b; if (htsmsg_get_bool(args, "trigger", &b)) return EINVAL; @@ -47,15 +49,13 @@ api_imagecache_trigger return 0; } -void -api_imagecache_init ( void ) -{ +void api_imagecache_init(void) { static api_hook_t ah[] = { - { "imagecache/config/load", ACCESS_ADMIN, api_idnode_load_simple, &imagecache_conf }, - { "imagecache/config/save", ACCESS_ADMIN, api_idnode_save_simple, &imagecache_conf }, - { "imagecache/config/clean" , ACCESS_ADMIN, api_imagecache_clean, NULL }, - { "imagecache/config/trigger", ACCESS_ADMIN, api_imagecache_trigger, NULL }, - { NULL }, + {"imagecache/config/load", ACCESS_ADMIN, api_idnode_load_simple, &imagecache_conf}, + {"imagecache/config/save", ACCESS_ADMIN, api_idnode_save_simple, &imagecache_conf}, + {"imagecache/config/clean", ACCESS_ADMIN, api_imagecache_clean, NULL}, + {"imagecache/config/trigger", ACCESS_ADMIN, api_imagecache_trigger, NULL}, + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_input.c b/src/api/api_input.c index 55896819d..2573d038c 100644 --- a/src/api/api_input.c +++ b/src/api/api_input.c @@ -26,21 +26,20 @@ #include "access.h" #include "api.h" -static idnode_set_t * -api_input_hw_tree ( void ) -{ - tvh_hardware_t *th; - idnode_set_t *is = idnode_set_create(0); - TVH_HARDWARE_FOREACH(th) +static idnode_set_t* api_input_hw_tree(void) { + tvh_hardware_t* th; + idnode_set_t* is = idnode_set_create(0); + TVH_HARDWARE_FOREACH (th) idnode_set_add(is, &th->th_id, NULL, NULL); return is; } #if ENABLE_SATIP_CLIENT -static int -api_input_satip_discover - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_input_satip_discover(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { int err = 0; if (op == NULL || strcmp(op, "all")) @@ -56,18 +55,16 @@ api_input_satip_discover } #endif -void api_input_init ( void ) -{ +void api_input_init(void) { static api_hook_t ah[] = { - { "hardware/tree", ACCESS_ADMIN, api_idnode_tree, api_input_hw_tree }, + {"hardware/tree", ACCESS_ADMIN, api_idnode_tree, api_input_hw_tree}, #if ENABLE_SATIP_CLIENT - { "hardware/satip/discover", ACCESS_ADMIN, api_input_satip_discover, NULL }, + {"hardware/satip/discover", ACCESS_ADMIN, api_input_satip_discover, NULL}, #endif - { NULL }, + {NULL}, }; api_register_all(ah); } - #endif /* __TVH_API_INPUT_H__ */ diff --git a/src/api/api_intlconv.c b/src/api/api_intlconv.c index fc7b27f04..7c21f652f 100644 --- a/src/api/api_intlconv.c +++ b/src/api/api_intlconv.c @@ -25,14 +25,15 @@ #include "api.h" #include "intlconv.h" -static int -api_intlconv_charset_enum - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - const char **chrst; - htsmsg_t *l; - - l = htsmsg_create_list(); +static int api_intlconv_charset_enum(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + const char** chrst; + htsmsg_t* l; + + l = htsmsg_create_list(); chrst = intlconv_charsets; while (*chrst) { htsmsg_add_msg(l, NULL, htsmsg_create_key_val(*chrst, *chrst)); @@ -43,17 +44,15 @@ api_intlconv_charset_enum return 0; } -void api_intlconv_init ( void ) -{ +void api_intlconv_init(void) { static api_hook_t ah[] = { - { "intlconv/charsets", ACCESS_ANONYMOUS, api_intlconv_charset_enum, NULL }, + {"intlconv/charsets", ACCESS_ANONYMOUS, api_intlconv_charset_enum, NULL}, - { NULL }, + {NULL}, }; api_register_all(ah); } - #endif /* __TVH_API_INTLCONV_H__ */ diff --git a/src/api/api_language.c b/src/api/api_language.c index 8377c5cd4..a36150b7d 100644 --- a/src/api/api_language.c +++ b/src/api/api_language.c @@ -26,11 +26,9 @@ #include "lang_codes.h" static int -api_language_enum - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - const lang_code_t *c = lang_codes; - htsmsg_t *l; +api_language_enum(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + const lang_code_t* c = lang_codes; + htsmsg_t* l; l = htsmsg_create_list(); while (c->code2b) { @@ -42,15 +40,17 @@ api_language_enum return 0; } -static int -_api_language_locale_enum - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp, int all ) -{ - const lang_code_t *c = lang_codes; - htsmsg_t *l; - const char *s; - char buf1[8]; - char buf2[128]; +static int _api_language_locale_enum(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp, + int all) { + const lang_code_t* c = lang_codes; + htsmsg_t* l; + const char* s; + char buf1[8]; + char buf2[128]; l = htsmsg_create_list(); while (c->code2b) { @@ -76,33 +76,33 @@ _api_language_locale_enum return 0; } -static int -api_language_locale_enum - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_language_locale_enum(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { return _api_language_locale_enum(perm, opaque, op, args, resp, 1); } -static int -api_language_ui_locale_enum - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_language_ui_locale_enum(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { return _api_language_locale_enum(perm, opaque, op, args, resp, 0); } -void api_language_init ( void ) -{ +void api_language_init(void) { static api_hook_t ah[] = { - { "language/list", ACCESS_ANONYMOUS, api_language_enum, NULL }, - { "language/locale", ACCESS_ANONYMOUS, api_language_locale_enum, NULL }, - { "language/ui_locale", ACCESS_ANONYMOUS, api_language_ui_locale_enum, NULL }, + {"language/list", ACCESS_ANONYMOUS, api_language_enum, NULL}, + {"language/locale", ACCESS_ANONYMOUS, api_language_locale_enum, NULL}, + {"language/ui_locale", ACCESS_ANONYMOUS, api_language_ui_locale_enum, NULL}, - { NULL }, + {NULL}, }; api_register_all(ah); } - #endif /* __TVH_API_LANGUAGE_H__ */ diff --git a/src/api/api_mpegts.c b/src/api/api_mpegts.c index eacf07bab..a890688e0 100644 --- a/src/api/api_mpegts.c +++ b/src/api/api_mpegts.c @@ -29,16 +29,17 @@ /* * Inputs */ -static int -api_mpegts_input_network_list - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int i, err = EINVAL; - const char *uuid; - mpegts_input_t *mi; - mpegts_network_t *mn; - idnode_set_t *is; - char ubuf[UUID_HEX_SIZE]; +static int api_mpegts_input_network_list(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int i, err = EINVAL; + const char* uuid; + mpegts_input_t* mi; + mpegts_network_t* mn; + idnode_set_t* is; + char ubuf[UUID_HEX_SIZE]; extern const idclass_t mpegts_input_class; if (!(uuid = htsmsg_get_str(args, "uuid"))) @@ -50,7 +51,7 @@ api_mpegts_input_network_list if (!mi) goto exit; - htsmsg_t *l = htsmsg_create_list(); + htsmsg_t* l = htsmsg_create_list(); if ((is = mi->mi_network_list(mi))) { for (i = 0; i < is->is_count; i++) { char buf[256]; @@ -73,49 +74,51 @@ exit: /* * Networks */ -static void -api_mpegts_network_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - mpegts_network_t *mn; +static void api_mpegts_network_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + mpegts_network_t* mn; - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) { idnode_set_add(ins, (idnode_t*)mn, &conf->filter, perm->aa_lang_ui); } } -static int -api_mpegts_network_builders - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - mpegts_network_builder_t *mnb; - htsmsg_t *l, *e; +static int api_mpegts_network_builders(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + mpegts_network_builder_t* mnb; + htsmsg_t * l, *e; /* List of available builder classes */ l = htsmsg_create_list(); - LIST_FOREACH(mnb, &mpegts_network_builders, link) + LIST_FOREACH (mnb, &mpegts_network_builders, link) if ((e = idclass_serialize(mnb->idc, perm->aa_lang_ui))) htsmsg_add_msg(l, NULL, e); /* Output */ - *resp = htsmsg_create_map(); + *resp = htsmsg_create_map(); htsmsg_add_msg(*resp, "entries", l); return 0; } -static int -api_mpegts_network_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_mpegts_network_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { int err; - const char *class; - htsmsg_t *conf; - mpegts_network_t *mn; + const char* class; + htsmsg_t* conf; + mpegts_network_t* mn; if (!(class = htsmsg_get_str(args, "class"))) return EINVAL; - if (!(conf = htsmsg_get_map(args, "conf"))) + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; tvh_mutex_lock(&global_lock); @@ -131,20 +134,22 @@ api_mpegts_network_create return err; } -static int -api_mpegts_network_scan - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_field_t *f; - htsmsg_t *uuids; - mpegts_network_t *mn; - const char *uuid; +static int api_mpegts_network_scan(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_field_t* f; + htsmsg_t* uuids; + mpegts_network_t* mn; + const char* uuid; if (!(f = htsmsg_field_find(args, "uuid"))) return EINVAL; if ((uuids = htsmsg_field_get_list(f))) { HTSMSG_FOREACH(f, uuids) { - if (!(uuid = htsmsg_field_get_str(f))) continue; + if (!(uuid = htsmsg_field_get_str(f))) + continue; tvh_mutex_lock(&global_lock); mn = mpegts_network_find(uuid); if (mn && mn->mn_scan) @@ -166,54 +171,56 @@ api_mpegts_network_scan return 0; } -static int -api_mpegts_network_muxclass - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err = EINVAL; - const idclass_t *idc; - mpegts_network_t *mn; - const char *uuid; +static int api_mpegts_network_muxclass(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int err = EINVAL; + const idclass_t* idc; + mpegts_network_t* mn; + const char* uuid; if (!(uuid = htsmsg_get_str(args, "uuid"))) return EINVAL; - + tvh_mutex_lock(&global_lock); - - if (!(mn = mpegts_network_find(uuid))) + + if (!(mn = mpegts_network_find(uuid))) goto exit; if (!(idc = mn->mn_mux_class(mn))) goto exit; *resp = idclass_serialize(idc, perm->aa_lang_ui); - err = 0; + err = 0; exit: tvh_mutex_unlock(&global_lock); return err; } -static int -api_mpegts_network_muxcreate - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err = EINVAL; - mpegts_network_t *mn; - mpegts_mux_t *mm; - htsmsg_t *conf; - const char *uuid; +static int api_mpegts_network_muxcreate(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int err = EINVAL; + mpegts_network_t* mn; + mpegts_mux_t* mm; + htsmsg_t* conf; + const char* uuid; if (!(uuid = htsmsg_get_str(args, "uuid"))) return EINVAL; if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; - + tvh_mutex_lock(&global_lock); - - if (!(mn = mpegts_network_find(uuid))) + + if (!(mn = mpegts_network_find(uuid))) goto exit; - + if (!(mm = mn->mn_mux_create2(mn, conf))) goto exit; @@ -228,14 +235,14 @@ exit: /* * Muxes */ -static void -api_mpegts_mux_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - mpegts_network_t *mn; - mpegts_mux_t *mm; - int hide = 1; - const char *s = htsmsg_get_str(args, "hidemode"); +static void api_mpegts_mux_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + mpegts_network_t* mn; + mpegts_mux_t* mm; + int hide = 1; + const char* s = htsmsg_get_str(args, "hidemode"); if (s) { if (!strcmp(s, "all")) hide = 2; @@ -243,10 +250,12 @@ api_mpegts_mux_grid hide = 0; } - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { - if (hide && !mn->mn_enabled) continue; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { - if (hide == 2 && !mm->mm_is_enabled(mm)) continue; + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) { + if (hide && !mn->mn_enabled) + continue; + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) { + if (hide == 2 && !mm->mm_is_enabled(mm)) + continue; idnode_set_add(ins, (idnode_t*)mm, &conf->filter, perm->aa_lang_ui); } } @@ -255,15 +264,15 @@ api_mpegts_mux_grid /* * Services */ -static void -api_mpegts_service_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - mpegts_network_t *mn; - mpegts_mux_t *mm; - mpegts_service_t *ms; - int hide = 1; - const char *s = htsmsg_get_str(args, "hidemode"); +static void api_mpegts_service_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + mpegts_network_t* mn; + mpegts_mux_t* mm; + mpegts_service_t* ms; + int hide = 1; + const char* s = htsmsg_get_str(args, "hidemode"); if (s) { if (!strcmp(s, "all")) hide = 2; @@ -271,13 +280,17 @@ api_mpegts_service_grid hide = 0; } - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { - if (hide && !mn->mn_enabled) continue; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { - if (hide && !mm->mm_is_enabled(mm)) continue; - LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) { - if (hide && !ms->s_verified) continue; - if (hide == 2 && !ms->s_is_enabled((service_t*)ms, 0)) continue; + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) { + if (hide && !mn->mn_enabled) + continue; + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) { + if (hide && !mm->mm_is_enabled(mm)) + continue; + LIST_FOREACH (ms, &mm->mm_services, s_dvb_mux_link) { + if (hide && !ms->s_verified) + continue; + if (hide == 2 && !ms->s_is_enabled((service_t*)ms, 0)) + continue; idnode_set_add(ins, (idnode_t*)ms, &conf->filter, perm->aa_lang_ui); } } @@ -287,24 +300,25 @@ api_mpegts_service_grid /* * Mux scheduler */ -static void -api_mpegts_mux_sched_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf, htsmsg_t *args ) -{ - mpegts_mux_sched_t *mms; - LIST_FOREACH(mms, &mpegts_mux_sched_all, mms_link) +static void api_mpegts_mux_sched_grid(access_t* perm, + idnode_set_t* ins, + api_idnode_grid_conf_t* conf, + htsmsg_t* args) { + mpegts_mux_sched_t* mms; + LIST_FOREACH (mms, &mpegts_mux_sched_all, mms_link) idnode_set_add(ins, (idnode_t*)mms, &conf->filter, perm->aa_lang_ui); } -static int -api_mpegts_mux_sched_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err; - htsmsg_t *conf; - mpegts_mux_sched_t *mms; +static int api_mpegts_mux_sched_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int err; + htsmsg_t* conf; + mpegts_mux_sched_t* mms; - if (!(conf = htsmsg_get_map(args, "conf"))) + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; tvh_mutex_lock(&global_lock); @@ -321,26 +335,27 @@ api_mpegts_mux_sched_create } #if ENABLE_MPEGTS_DVB -static int -api_dvb_orbitalpos_list - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_t *l, *e, *c; - htsmsg_field_t *f; - const char *s; - int satpos, i; - char buf[128]; +static int api_dvb_orbitalpos_list(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_t * l, *e, *c; + htsmsg_field_t* f; + const char* s; + int satpos, i; + char buf[128]; if (!satellites) return 0; l = htsmsg_create_list(); HTSMSG_FOREACH(f, satellites) { - if((c = htsmsg_get_map_by_field(f)) == NULL) + if ((c = htsmsg_get_map_by_field(f)) == NULL) continue; - if(htsmsg_get_s32(c, "pos", &satpos)) + if (htsmsg_get_s32(c, "pos", &satpos)) continue; - if((s = htsmsg_get_str(c, "name")) == NULL) + if ((s = htsmsg_get_str(c, "name")) == NULL) continue; e = htsmsg_create_map(); dvb_sat_position_to_str(satpos, buf, sizeof(buf)); @@ -358,17 +373,18 @@ api_dvb_orbitalpos_list #endif #if ENABLE_MPEGTS_DVB -static int -api_dvb_scanfile_list - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - char buf[512]; - const char *type = htsmsg_get_str(args, "type"); - int satpos = htsmsg_get_s32_or_default(args, "satpos", INT_MAX); - scanfile_region_list_t *list = NULL; - htsmsg_t *l, *e; - scanfile_region_t *r; - scanfile_network_t *n; +static int api_dvb_scanfile_list(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + char buf[512]; + const char* type = htsmsg_get_str(args, "type"); + int satpos = htsmsg_get_s32_or_default(args, "satpos", INT_MAX); + scanfile_region_list_t* list = NULL; + htsmsg_t * l, *e; + scanfile_region_t* r; + scanfile_network_t* n; if (!type) return EINVAL; @@ -376,13 +392,12 @@ api_dvb_scanfile_list list = scanfile_find_region_list(type); if (!list) return EINVAL; - + l = htsmsg_create_list(); - LIST_FOREACH(r, &list->srl_regions, sfr_link) { - LIST_FOREACH(n, &r->sfr_networks, sfn_link) { - if (satpos != INT_MAX && - abs(n->sfn_satpos - satpos) > 2 && - abs(satpos - n->sfn_satpos) > 2) continue; + LIST_FOREACH (r, &list->srl_regions, sfr_link) { + LIST_FOREACH (n, &r->sfr_networks, sfn_link) { + if (satpos != INT_MAX && abs(n->sfn_satpos - satpos) > 2 && abs(satpos - n->sfn_satpos) > 2) + continue; e = htsmsg_create_map(); sprintf(buf, "%s/%s/%s", type, r->sfr_id, n->sfn_id); htsmsg_add_str(e, "key", buf); @@ -405,34 +420,32 @@ api_dvb_scanfile_list /* * Init */ -void -api_mpegts_init ( void ) -{ +void api_mpegts_init(void) { extern const idclass_t mpegts_network_class; extern const idclass_t mpegts_mux_class; extern const idclass_t mpegts_service_class; static api_hook_t ah[] = { - { "mpegts/input/network_list", ACCESS_ADMIN, api_mpegts_input_network_list, NULL }, - { "mpegts/network/grid", ACCESS_ADMIN, api_idnode_grid, api_mpegts_network_grid }, - { "mpegts/network/class", ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_network_class }, - { "mpegts/network/builders", ACCESS_ADMIN, api_mpegts_network_builders, NULL }, - { "mpegts/network/create", ACCESS_ADMIN, api_mpegts_network_create, NULL }, - { "mpegts/network/mux_class", ACCESS_ADMIN, api_mpegts_network_muxclass, NULL }, - { "mpegts/network/mux_create", ACCESS_ADMIN, api_mpegts_network_muxcreate, NULL }, - { "mpegts/network/scan", ACCESS_ADMIN, api_mpegts_network_scan, NULL }, - { "mpegts/mux/grid", ACCESS_ADMIN, api_idnode_grid, api_mpegts_mux_grid }, - { "mpegts/mux/class", ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_mux_class }, - { "mpegts/service/grid", ACCESS_ADMIN, api_idnode_grid, api_mpegts_service_grid }, - { "mpegts/service/class", ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_service_class }, - { "mpegts/mux_sched/class", ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_mux_sched_class }, - { "mpegts/mux_sched/grid", ACCESS_ADMIN, api_idnode_grid, api_mpegts_mux_sched_grid }, - { "mpegts/mux_sched/create", ACCESS_ADMIN, api_mpegts_mux_sched_create, NULL }, + {"mpegts/input/network_list", ACCESS_ADMIN, api_mpegts_input_network_list, NULL}, + {"mpegts/network/grid", ACCESS_ADMIN, api_idnode_grid, api_mpegts_network_grid}, + {"mpegts/network/class", ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_network_class}, + {"mpegts/network/builders", ACCESS_ADMIN, api_mpegts_network_builders, NULL}, + {"mpegts/network/create", ACCESS_ADMIN, api_mpegts_network_create, NULL}, + {"mpegts/network/mux_class", ACCESS_ADMIN, api_mpegts_network_muxclass, NULL}, + {"mpegts/network/mux_create", ACCESS_ADMIN, api_mpegts_network_muxcreate, NULL}, + {"mpegts/network/scan", ACCESS_ADMIN, api_mpegts_network_scan, NULL}, + {"mpegts/mux/grid", ACCESS_ADMIN, api_idnode_grid, api_mpegts_mux_grid}, + {"mpegts/mux/class", ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_mux_class}, + {"mpegts/service/grid", ACCESS_ADMIN, api_idnode_grid, api_mpegts_service_grid}, + {"mpegts/service/class", ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_service_class}, + {"mpegts/mux_sched/class", ACCESS_ADMIN, api_idnode_class, (void*)&mpegts_mux_sched_class}, + {"mpegts/mux_sched/grid", ACCESS_ADMIN, api_idnode_grid, api_mpegts_mux_sched_grid}, + {"mpegts/mux_sched/create", ACCESS_ADMIN, api_mpegts_mux_sched_create, NULL}, #if ENABLE_MPEGTS_DVB - { "dvb/orbitalpos/list", ACCESS_ADMIN, api_dvb_orbitalpos_list, NULL }, - { "dvb/scanfile/list", ACCESS_ADMIN, api_dvb_scanfile_list, NULL }, + {"dvb/orbitalpos/list", ACCESS_ADMIN, api_dvb_orbitalpos_list, NULL}, + {"dvb/scanfile/list", ACCESS_ADMIN, api_dvb_scanfile_list, NULL}, #endif - { NULL }, + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_profile.c b/src/api/api_profile.c index e07968d84..d820566a1 100644 --- a/src/api/api_profile.c +++ b/src/api/api_profile.c @@ -27,18 +27,13 @@ /* * */ -static int -api_profile_is_all(access_t *perm, htsmsg_t *args) -{ - return htsmsg_get_bool_or_default(args, "all", 0) && - !access_verify2(perm, ACCESS_ADMIN); +static int api_profile_is_all(access_t* perm, htsmsg_t* args) { + return htsmsg_get_bool_or_default(args, "all", 0) && !access_verify2(perm, ACCESS_ADMIN); } -static int -api_profile_find(access_t *perm, const char *uuid) -{ - htsmsg_field_t *f; - const char *uuid2; +static int api_profile_find(access_t* perm, const char* uuid) { + htsmsg_field_t* f; + const char* uuid2; if (perm->aa_profiles == NULL) return 1; @@ -54,19 +49,17 @@ api_profile_find(access_t *perm, const char *uuid) * */ static int -api_profile_list - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - profile_t *pro; - htsmsg_t *l; - int cfg = api_profile_is_all(perm, args); - int sflags = htsmsg_get_bool_or_default(args, "htsp", 0) ? SUBSCRIPTION_HTSP : 0; - char ubuf[UUID_HEX_SIZE]; - - sflags |= SUBSCRIPTION_PACKET|SUBSCRIPTION_MPEGTS; +api_profile_list(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + profile_t* pro; + htsmsg_t* l; + int cfg = api_profile_is_all(perm, args); + int sflags = htsmsg_get_bool_or_default(args, "htsp", 0) ? SUBSCRIPTION_HTSP : 0; + char ubuf[UUID_HEX_SIZE]; + + sflags |= SUBSCRIPTION_PACKET | SUBSCRIPTION_MPEGTS; l = htsmsg_create_list(); tvh_mutex_lock(&global_lock); - TAILQ_FOREACH(pro, &profiles, pro_link) { + TAILQ_FOREACH (pro, &profiles, pro_link) { idnode_uuid_as_str(&pro->pro_id, ubuf); if (!cfg && (!profile_verify(pro, sflags) || !api_profile_find(perm, ubuf))) continue; @@ -78,18 +71,19 @@ api_profile_list return 0; } -static int -api_profile_builders - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - profile_build_t *pb; - htsmsg_t *l, *e; +static int api_profile_builders(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + profile_build_t* pb; + htsmsg_t * l, *e; l = htsmsg_create_list(); tvh_mutex_lock(&global_lock); /* List of available builder classes */ - LIST_FOREACH(pb, &profile_builders, link) + LIST_FOREACH (pb, &profile_builders, link) if ((e = idclass_serialize(pb->clazz, perm->aa_lang_ui))) htsmsg_add_msg(l, NULL, e); tvh_mutex_unlock(&global_lock); @@ -102,17 +96,15 @@ api_profile_builders } static int -api_profile_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err = 0; - const char *clazz; - htsmsg_t *conf; - profile_t *pro; +api_profile_create(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + int err = 0; + const char* clazz; + htsmsg_t* conf; + profile_t* pro; if (!(clazz = htsmsg_get_str(args, "class"))) return EINVAL; - if (!(conf = htsmsg_get_map(args, "conf"))) + if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; htsmsg_set_str(conf, "class", clazz); @@ -130,15 +122,13 @@ api_profile_create /* * Init */ -void -api_profile_init ( void ) -{ +void api_profile_init(void) { static api_hook_t ah[] = { - { "profile/list", ACCESS_ANONYMOUS, api_profile_list, NULL }, - { "profile/class", ACCESS_ADMIN, api_idnode_class, (void*)&profile_class }, - { "profile/builders", ACCESS_ADMIN, api_profile_builders, NULL }, - { "profile/create", ACCESS_ADMIN, api_profile_create, NULL }, - { NULL }, + {"profile/list", ACCESS_ANONYMOUS, api_profile_list, NULL}, + {"profile/class", ACCESS_ADMIN, api_idnode_class, (void*)&profile_class}, + {"profile/builders", ACCESS_ADMIN, api_profile_builders, NULL}, + {"profile/create", ACCESS_ADMIN, api_profile_create, NULL}, + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_ratinglabel.c b/src/api/api_ratinglabel.c index 58e673be5..2cc4f003e 100644 --- a/src/api/api_ratinglabel.c +++ b/src/api/api_ratinglabel.c @@ -26,20 +26,22 @@ #include "access.h" #include "api.h" -static int -api_ratinglabel_list - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - ratinglabel_t *rl; - htsmsg_t *l; - char ubuf[UUID_HEX_SIZE]; +static int api_ratinglabel_list(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + ratinglabel_t* rl; + htsmsg_t* l; + char ubuf[UUID_HEX_SIZE]; l = htsmsg_create_list(); tvh_mutex_lock(&global_lock); - RB_FOREACH(rl, &ratinglabels, rl_link) - { - htsmsg_add_msg(l, NULL, htsmsg_create_key_val(idnode_uuid_as_str(&rl->rl_id, ubuf), rl->rl_country ?: "")); - } + RB_FOREACH (rl, &ratinglabels, rl_link) { + htsmsg_add_msg(l, + NULL, + htsmsg_create_key_val(idnode_uuid_as_str(&rl->rl_id, ubuf), rl->rl_country ?: "")); + } tvh_mutex_unlock(&global_lock); *resp = htsmsg_create_map(); htsmsg_add_msg(*resp, "entries", l); @@ -47,22 +49,20 @@ api_ratinglabel_list return 0; } -static void -api_ratinglabel_grid - ( access_t *perm, idnode_set_t *ins, api_idnode_grid_conf_t *conf ) -{ - ratinglabel_t *rl; +static void api_ratinglabel_grid(access_t* perm, idnode_set_t* ins, api_idnode_grid_conf_t* conf) { + ratinglabel_t* rl; - RB_FOREACH(rl, &ratinglabels, rl_link) + RB_FOREACH (rl, &ratinglabels, rl_link) idnode_set_add(ins, (idnode_t*)rl, &conf->filter, perm->aa_lang_ui); } -static int -api_ratinglabel_create - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_t *conf; - ratinglabel_t *rl; +static int api_ratinglabel_create(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_t* conf; + ratinglabel_t* rl; if (!(conf = htsmsg_get_map(args, "conf"))) return EINVAL; @@ -76,14 +76,13 @@ api_ratinglabel_create return 0; } -void api_ratinglabel_init ( void ) -{ +void api_ratinglabel_init(void) { static api_hook_t ah[] = { - { "ratinglabel/list", ACCESS_ADMIN, api_ratinglabel_list, NULL }, - { "ratinglabel/class", ACCESS_ADMIN, api_idnode_class, (void*)&ratinglabel_class }, - { "ratinglabel/grid", ACCESS_ADMIN, api_idnode_grid, api_ratinglabel_grid }, - { "ratinglabel/create", ACCESS_ADMIN, api_ratinglabel_create, NULL }, - { NULL }, + {"ratinglabel/list", ACCESS_ADMIN, api_ratinglabel_list, NULL}, + {"ratinglabel/class", ACCESS_ADMIN, api_idnode_class, (void*)&ratinglabel_class}, + {"ratinglabel/grid", ACCESS_ADMIN, api_idnode_grid, api_ratinglabel_grid}, + {"ratinglabel/create", ACCESS_ADMIN, api_ratinglabel_create, NULL}, + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_raw.c b/src/api/api_raw.c index 75338d2e6..dbd433336 100644 --- a/src/api/api_raw.c +++ b/src/api/api_raw.c @@ -24,11 +24,9 @@ #include "api.h" static int -api_idnode_classes - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +api_idnode_classes(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { idclass_t const **all, **all2; - const idclass_t *ic; + const idclass_t* ic; *resp = htsmsg_create_map(); tvh_mutex_lock(&global_lock); @@ -47,17 +45,16 @@ api_idnode_classes return 0; } - - -static int -api_idnode_raw_export_by_class0 - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int i; - const idclass_t *idc; - idnode_set_t *is; - idnode_t *in; - htsmsg_t *l, *e; +static int api_idnode_raw_export_by_class0(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int i; + const idclass_t* idc; + idnode_set_t* is; + idnode_t* in; + htsmsg_t * l, *e; /* Find class */ idc = opaque; @@ -89,19 +86,20 @@ api_idnode_raw_export_by_class0 return 0; } -static int -api_idnode_raw_export - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err = 0, count = 0; - idnode_t *in; - htsmsg_t *uuids, *l = NULL, *m; - htsmsg_field_t *f; - const char *uuid = NULL, *class; +static int api_idnode_raw_export(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int err = 0, count = 0; + idnode_t* in; + htsmsg_t * uuids, *l = NULL, *m; + htsmsg_field_t* f; + const char * uuid = NULL, *class; /* Class based */ if ((class = htsmsg_get_str(args, "class"))) { - const idclass_t *idc; + const idclass_t* idc; tvh_mutex_lock(&global_lock); idc = idclass_find(class); if (idc) @@ -111,7 +109,7 @@ api_idnode_raw_export tvh_mutex_unlock(&global_lock); return err; } - + /* UUIDs */ if (!(f = htsmsg_field_find(args, "uuid"))) return EINVAL; @@ -124,10 +122,12 @@ api_idnode_raw_export /* Multiple */ if (uuids) { - const idnodes_rb_t *domain = NULL; + const idnodes_rb_t* domain = NULL; HTSMSG_FOREACH(f, uuids) { - if (!(uuid = htsmsg_field_get_str(f))) continue; - if (!(in = idnode_find(uuid, NULL, domain))) continue; + if (!(uuid = htsmsg_field_get_str(f))) + continue; + if (!(in = idnode_find(uuid, NULL, domain))) + continue; domain = in->in_domain; if (idnode_perm(in, perm, NULL)) { err = EPERM; @@ -145,7 +145,7 @@ api_idnode_raw_export if (count) err = 0; - /* Single */ + /* Single */ } else { if ((in = idnode_find(uuid, NULL, NULL)) != NULL) { if (idnode_perm(in, perm, NULL)) { @@ -172,17 +172,18 @@ api_idnode_raw_export return err; } -static int -api_idnode_raw_import - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int err = EINVAL; - idnode_t *in; - htsmsg_t *msg, *conf; - htsmsg_field_t *f; - const char *uuid; - int count = 0; - const idnodes_rb_t *domain = NULL; +static int api_idnode_raw_import(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int err = EINVAL; + idnode_t* in; + htsmsg_t * msg, *conf; + htsmsg_field_t* f; + const char* uuid; + int count = 0; + const idnodes_rb_t* domain = NULL; if (!(f = htsmsg_field_find(args, "node"))) return EINVAL; @@ -229,10 +230,9 @@ api_idnode_raw_import idnode_loadfn(in, msg); idnode_perm_unset(in); err = 0; - } - /* Multiple */ + /* Multiple */ } else { HTSMSG_FOREACH(f, msg) { @@ -253,7 +253,6 @@ api_idnode_raw_import } if (count) err = 0; - } // TODO: return updated UUIDs? @@ -264,16 +263,15 @@ exit: return err; } -void api_idnode_raw_init ( void ) -{ +void api_idnode_raw_init(void) { /* * note: permissions are verified using idnode_perm() calls */ static api_hook_t ah[] = { - { "classes", ACCESS_ANONYMOUS, api_idnode_classes, NULL }, - { "raw/export", ACCESS_ANONYMOUS, api_idnode_raw_export, NULL }, - { "raw/import", ACCESS_ANONYMOUS, api_idnode_raw_import, NULL }, - { NULL }, + {"classes", ACCESS_ANONYMOUS, api_idnode_classes, NULL}, + {"raw/export", ACCESS_ANONYMOUS, api_idnode_raw_export, NULL}, + {"raw/import", ACCESS_ANONYMOUS, api_idnode_raw_import, NULL}, + {NULL}, }; api_register_all(ah); diff --git a/src/api/api_satip.c b/src/api/api_satip.c index cc1d3fc72..4760ea165 100644 --- a/src/api/api_satip.c +++ b/src/api/api_satip.c @@ -25,13 +25,11 @@ #if ENABLE_SATIP_SERVER -void -api_satip_server_init ( void ) -{ +void api_satip_server_init(void) { static api_hook_t ah[] = { - { "satips/config/load", ACCESS_ADMIN, api_idnode_load_simple, &satip_server_conf }, - { "satips/config/save", ACCESS_ADMIN, api_idnode_save_simple, &satip_server_conf }, - { NULL }, + {"satips/config/load", ACCESS_ADMIN, api_idnode_load_simple, &satip_server_conf}, + {"satips/config/save", ACCESS_ADMIN, api_idnode_save_simple, &satip_server_conf}, + {NULL}, }; api_register_all(ah); @@ -39,9 +37,6 @@ api_satip_server_init ( void ) #else /* ENABLE_SATIP_SERVER */ -void -api_satip_server_init ( void ) -{ -} +void api_satip_server_init(void) {} #endif diff --git a/src/api/api_service.c b/src/api/api_service.c index d74ba410e..da38be650 100644 --- a/src/api/api_service.c +++ b/src/api/api_service.c @@ -28,9 +28,7 @@ #include "notify.h" static int -api_mapper_stop - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +api_mapper_stop(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { tvh_mutex_lock(&global_lock); service_mapper_stop(); tvh_mutex_unlock(&global_lock); @@ -38,15 +36,13 @@ api_mapper_stop return 0; } -static htsmsg_t * -api_mapper_status_msg ( void ) -{ - htsmsg_t *m; +static htsmsg_t* api_mapper_status_msg(void) { + htsmsg_t* m; service_mapper_status_t stat = service_mapper_status(); - m = htsmsg_create_map(); - htsmsg_add_u32(m, "total", stat.total); - htsmsg_add_u32(m, "ok", stat.ok); - htsmsg_add_u32(m, "fail", stat.fail); + m = htsmsg_create_map(); + htsmsg_add_u32(m, "total", stat.total); + htsmsg_add_u32(m, "ok", stat.ok); + htsmsg_add_u32(m, "fail", stat.fail); htsmsg_add_u32(m, "ignore", stat.ignore); if (stat.active) htsmsg_add_uuid(m, "active", &stat.active->s_id.in_uuid); @@ -54,50 +50,44 @@ api_mapper_status_msg ( void ) } static int -api_mapper_status - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +api_mapper_status(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { tvh_mutex_lock(&global_lock); *resp = api_mapper_status_msg(); tvh_mutex_unlock(&global_lock); return 0; } -void -api_service_mapper_notify ( void ) -{ +void api_service_mapper_notify(void) { notify_by_msg("servicemapper", api_mapper_status_msg(), 1, 0); } -static htsmsg_t * -api_service_streams_get_one ( elementary_stream_t *es, int use_filter ) -{ - htsmsg_t *e = htsmsg_create_map(); - htsmsg_add_u32(e, "index", es->es_index); - htsmsg_add_u32(e, "pid", es->es_pid); - htsmsg_add_str(e, "type", streaming_component_type2txt(es->es_type)); +static htsmsg_t* api_service_streams_get_one(elementary_stream_t* es, int use_filter) { + htsmsg_t* e = htsmsg_create_map(); + htsmsg_add_u32(e, "index", es->es_index); + htsmsg_add_u32(e, "pid", es->es_pid); + htsmsg_add_str(e, "type", streaming_component_type2txt(es->es_type)); htsmsg_add_str(e, "language", es->es_lang); if (SCT_ISSUBTITLE(es->es_type)) { htsmsg_add_u32(e, "composition_id", es->es_composition_id); - htsmsg_add_u32(e, "ancillary_id", es->es_ancillary_id); + htsmsg_add_u32(e, "ancillary_id", es->es_ancillary_id); } else if (SCT_ISAUDIO(es->es_type)) { - htsmsg_add_u32(e, "audio_type", es->es_audio_type); + htsmsg_add_u32(e, "audio_type", es->es_audio_type); if (es->es_audio_version) htsmsg_add_u32(e, "audio_version", es->es_audio_version); } else if (SCT_ISVIDEO(es->es_type)) { - htsmsg_add_u32(e, "width", es->es_width); - htsmsg_add_u32(e, "height", es->es_height); - htsmsg_add_u32(e, "duration", es->es_frame_duration); - htsmsg_add_u32(e, "aspect_num", es->es_aspect_num); - htsmsg_add_u32(e, "aspect_den", es->es_aspect_den); + htsmsg_add_u32(e, "width", es->es_width); + htsmsg_add_u32(e, "height", es->es_height); + htsmsg_add_u32(e, "duration", es->es_frame_duration); + htsmsg_add_u32(e, "aspect_num", es->es_aspect_num); + htsmsg_add_u32(e, "aspect_den", es->es_aspect_den); } else if (es->es_type == SCT_CA) { - caid_t *ca; + caid_t* ca; htsmsg_t *e2, *l2 = htsmsg_create_list(); - LIST_FOREACH(ca, &es->es_caids, link) { + LIST_FOREACH (ca, &es->es_caids, link) { if (use_filter && !ca->use) continue; e2 = htsmsg_create_map(); - htsmsg_add_u32(e2, "caid", ca->caid); + htsmsg_add_u32(e2, "caid", ca->caid); htsmsg_add_u32(e2, "provider", ca->providerid); htsmsg_add_msg(l2, NULL, e2); } @@ -107,13 +97,11 @@ api_service_streams_get_one ( elementary_stream_t *es, int use_filter ) } static int -api_service_streams - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - const char *uuid; - htsmsg_t *e, *st, *stf, *hbbtv = NULL; - service_t *s; - elementary_stream_t *es; +api_service_streams(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + const char* uuid; + htsmsg_t * e, *st, *stf, *hbbtv = NULL; + service_t* s; + elementary_stream_t* es; /* No UUID */ if (!(uuid = htsmsg_get_str(args, "uuid"))) @@ -129,7 +117,7 @@ api_service_streams /* Build response */ tvh_mutex_lock(&s->s_stream_mutex); - st = htsmsg_create_list(); + st = htsmsg_create_list(); stf = htsmsg_create_list(); if (s->s_components.set_pcr_pid) { e = htsmsg_create_map(); @@ -143,14 +131,16 @@ api_service_streams htsmsg_add_str(e, "type", "PMT"); htsmsg_add_msg(st, NULL, e); } - TAILQ_FOREACH(es, &s->s_components.set_all, es_link) { - if (es->es_type == SCT_PCR) continue; + TAILQ_FOREACH (es, &s->s_components.set_all, es_link) { + if (es->es_type == SCT_PCR) + continue; htsmsg_add_msg(st, NULL, api_service_streams_get_one(es, 0)); } if (elementary_set_has_streams(&s->s_components, 1) || s->s_status == SERVICE_IDLE) elementary_set_filter_build(&s->s_components); - TAILQ_FOREACH(es, &s->s_components.set_filter, es_filter_link) { - if (es->es_type == SCT_PCR) continue; + TAILQ_FOREACH (es, &s->s_components.set_filter, es_filter_link) { + if (es->es_type == SCT_PCR) + continue; htsmsg_add_msg(stf, NULL, api_service_streams_get_one(es, 1)); } *resp = htsmsg_create_map(); @@ -169,12 +159,13 @@ api_service_streams return 0; } -static int -api_service_remove_unseen - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int days = htsmsg_get_s32_or_default(args, "days", 7); - const char *type = htsmsg_get_str(args, "type"); +static int api_service_remove_unseen(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int days = htsmsg_get_s32_or_default(args, "days", 7); + const char* type = htsmsg_get_str(args, "type"); tvh_mutex_lock(&global_lock); service_remove_unseen(type, days); @@ -182,22 +173,20 @@ api_service_remove_unseen return 0; } -void api_service_init ( void ) -{ +void api_service_init(void) { extern const idclass_t service_class; - static api_hook_t ah[] = { - { "service/mapper/load", ACCESS_ADMIN, api_idnode_load_simple, &service_mapper_conf }, - { "service/mapper/save", ACCESS_ADMIN, api_idnode_save_simple, &service_mapper_conf }, - { "service/mapper/stop", ACCESS_ADMIN, api_mapper_stop, NULL }, - { "service/mapper/status", ACCESS_ADMIN, api_mapper_status, NULL }, - { "service/list", ACCESS_ADMIN, api_idnode_load_by_class, (void*)&service_class }, - { "service/streams", ACCESS_ADMIN, api_service_streams, NULL }, - { "service/removeunseen", ACCESS_ADMIN, api_service_remove_unseen, NULL }, - { NULL }, + static api_hook_t ah[] = { + {"service/mapper/load", ACCESS_ADMIN, api_idnode_load_simple, &service_mapper_conf}, + {"service/mapper/save", ACCESS_ADMIN, api_idnode_save_simple, &service_mapper_conf}, + {"service/mapper/stop", ACCESS_ADMIN, api_mapper_stop, NULL}, + {"service/mapper/status", ACCESS_ADMIN, api_mapper_status, NULL}, + {"service/list", ACCESS_ADMIN, api_idnode_load_by_class, (void*)&service_class}, + {"service/streams", ACCESS_ADMIN, api_service_streams, NULL}, + {"service/removeunseen", ACCESS_ADMIN, api_service_remove_unseen, NULL}, + {NULL}, }; api_register_all(ah); } - #endif /* __TVH_API_SERVICE_H__ */ diff --git a/src/api/api_status.c b/src/api/api_status.c index 9b8e5c99a..0b2a11c3f 100644 --- a/src/api/api_status.c +++ b/src/api/api_status.c @@ -28,17 +28,15 @@ #include "input.h" static int -api_status_inputs - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int c = 0; - htsmsg_t *l, *e; - tvh_input_t *ti; - tvh_input_stream_t *st; - tvh_input_stream_list_t stl = { 0 }; - +api_status_inputs(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { + int c = 0; + htsmsg_t * l, *e; + tvh_input_t* ti; + tvh_input_stream_t* st; + tvh_input_stream_list_t stl = {0}; + tvh_mutex_lock(&global_lock); - TVH_INPUT_FOREACH(ti) + TVH_INPUT_FOREACH (ti) ti->ti_get_streams(ti, &stl); tvh_mutex_unlock(&global_lock); @@ -51,7 +49,7 @@ api_status_inputs free(st); c++; } - + *resp = htsmsg_create_map(); htsmsg_add_msg(*resp, "entries", l); htsmsg_add_u32(*resp, "totalCount", c); @@ -59,18 +57,19 @@ api_status_inputs return 0; } -static int -api_status_subscriptions - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int c; - htsmsg_t *l, *e; - th_subscription_t *ths; +static int api_status_subscriptions(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int c; + htsmsg_t * l, *e; + th_subscription_t* ths; l = htsmsg_create_list(); c = 0; tvh_mutex_lock(&global_lock); - LIST_FOREACH(ths, &subscriptions, ths_global_link) { + LIST_FOREACH (ths, &subscriptions, ths_global_link) { e = subscription_create_msg(ths, perm->aa_lang_ui); htsmsg_add_msg(l, NULL, e); c++; @@ -84,24 +83,26 @@ api_status_subscriptions return 0; } -static int -api_status_connections - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +static int api_status_connections(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { tvh_mutex_lock(&global_lock); *resp = tcp_server_connections(); tvh_mutex_unlock(&global_lock); return 0; } -static int -api_connections_cancel - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_field_t *f; - htsmsg_t *ids; - uint32_t id; - const char *s; +static int api_connections_cancel(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_field_t* f; + htsmsg_t* ids; + uint32_t id; + const char* s; if (!(f = htsmsg_field_find(args, "id"))) return EINVAL; @@ -118,8 +119,10 @@ api_connections_cancel if (ids) { HTSMSG_FOREACH(f, ids) { - if (htsmsg_field_get_u32(f, &id)) continue; - if (!id) continue; + if (htsmsg_field_get_u32(f, &id)) + continue; + if (!id) + continue; tvh_mutex_lock(&global_lock); tcp_connection_cancel(id); tvh_mutex_unlock(&global_lock); @@ -132,11 +135,9 @@ api_connections_cancel return 0; } -static void -input_clear_stats(const char *uuid) -{ - tvh_input_instance_t *tii; - tvh_input_t *ti; +static void input_clear_stats(const char* uuid) { + tvh_input_instance_t* tii; + tvh_input_t* ti; tvh_mutex_lock(&global_lock); if ((tii = tvh_input_instance_find_by_uuid(uuid)) != NULL) @@ -148,13 +149,14 @@ input_clear_stats(const char *uuid) tvh_mutex_unlock(&global_lock); } -static int -api_status_input_clear_stats - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - htsmsg_field_t *f; - htsmsg_t *ids; - const char *uuid; +static int api_status_input_clear_stats(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + htsmsg_field_t* f; + htsmsg_t* ids; + const char* uuid; if (!(f = htsmsg_field_find(args, "uuid"))) return EINVAL; @@ -164,26 +166,25 @@ api_status_input_clear_stats input_clear_stats(uuid); } else { HTSMSG_FOREACH(f, ids) { - if ((uuid = htsmsg_field_get_str(f)) == NULL) continue; + if ((uuid = htsmsg_field_get_str(f)) == NULL) + continue; input_clear_stats(uuid); } } return 0; } -void api_status_init ( void ) -{ +void api_status_init(void) { static api_hook_t ah[] = { - { "status/connections", ACCESS_ADMIN, api_status_connections, NULL }, - { "status/subscriptions", ACCESS_ADMIN, api_status_subscriptions, NULL }, - { "status/inputs", ACCESS_ADMIN, api_status_inputs, NULL }, - { "status/inputclrstats", ACCESS_ADMIN, api_status_input_clear_stats, NULL }, - { "connections/cancel", ACCESS_ADMIN, api_connections_cancel, NULL }, - { NULL }, + {"status/connections", ACCESS_ADMIN, api_status_connections, NULL}, + {"status/subscriptions", ACCESS_ADMIN, api_status_subscriptions, NULL}, + {"status/inputs", ACCESS_ADMIN, api_status_inputs, NULL}, + {"status/inputclrstats", ACCESS_ADMIN, api_status_input_clear_stats, NULL}, + {"connections/cancel", ACCESS_ADMIN, api_connections_cancel, NULL}, + {NULL}, }; api_register_all(ah); } - #endif /* __TVH_API_IDNODE_H__ */ diff --git a/src/api/api_timeshift.c b/src/api/api_timeshift.c index c780eb776..8e5e2e355 100644 --- a/src/api/api_timeshift.c +++ b/src/api/api_timeshift.c @@ -25,13 +25,11 @@ #if ENABLE_TIMESHIFT -void -api_timeshift_init ( void ) -{ +void api_timeshift_init(void) { static api_hook_t ah[] = { - { "timeshift/config/load", ACCESS_ADMIN, api_idnode_load_simple, ×hift_conf }, - { "timeshift/config/save", ACCESS_ADMIN, api_idnode_save_simple, ×hift_conf }, - { NULL }, + {"timeshift/config/load", ACCESS_ADMIN, api_idnode_load_simple, ×hift_conf}, + {"timeshift/config/save", ACCESS_ADMIN, api_idnode_save_simple, ×hift_conf}, + {NULL}, }; api_register_all(ah); @@ -39,9 +37,6 @@ api_timeshift_init ( void ) #else -void -api_timeshift_init ( void ) -{ -} +void api_timeshift_init(void) {} #endif diff --git a/src/api/api_wizard.c b/src/api/api_wizard.c index bc80f446f..96966bd62 100644 --- a/src/api/api_wizard.c +++ b/src/api/api_wizard.c @@ -25,9 +25,7 @@ #include "input.h" #include "wizard.h" -static int -wizard_page ( const char *page ) -{ +static int wizard_page(const char* page) { tvh_mutex_lock(&global_lock); if (strcmp(page, config.wizard ?: "")) { free(config.wizard); @@ -38,62 +36,62 @@ wizard_page ( const char *page ) return 0; } -static int -wizard_idnode_load_simple - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int r; - wizard_build_fcn_t fcn = opaque; - wizard_page_t *page = fcn(perm->aa_lang_ui); - r = api_idnode_load_simple(perm, &page->idnode, op, args, resp); +static int wizard_idnode_load_simple(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int r; + wizard_build_fcn_t fcn = opaque; + wizard_page_t* page = fcn(perm->aa_lang_ui); + r = api_idnode_load_simple(perm, &page->idnode, op, args, resp); wizard_page(page->name); page->free(page); return r; } -static int -wizard_idnode_save_simple - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int r; - wizard_build_fcn_t fcn = opaque; - wizard_page_t *page = fcn(perm->aa_lang_ui); - r = api_idnode_save_simple(perm, &page->idnode, op, args, resp); +static int wizard_idnode_save_simple(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int r; + wizard_build_fcn_t fcn = opaque; + wizard_page_t* page = fcn(perm->aa_lang_ui); + r = api_idnode_save_simple(perm, &page->idnode, op, args, resp); idnode_save_check(&page->idnode, 1); page->free(page); return r; } static int -wizard_cancel - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +wizard_cancel(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { return wizard_page(""); } static int -wizard_start - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ +wizard_start(access_t* perm, void* opaque, const char* op, htsmsg_t* args, htsmsg_t** resp) { return wizard_page("hello"); } -static int -wizard_status_progress - ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp ) -{ - int64_t active = 0, total = 0, services = 0; - mpegts_service_t *s; - mpegts_mux_t *mm; - mpegts_network_t *mn; +static int wizard_status_progress(access_t* perm, + void* opaque, + const char* op, + htsmsg_t* args, + htsmsg_t** resp) { + int64_t active = 0, total = 0, services = 0; + mpegts_service_t* s; + mpegts_mux_t* mm; + mpegts_network_t* mn; - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { - if (!mn->mn_wizard) continue; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) { + if (!mn->mn_wizard) + continue; + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) { total++; if (mm->mm_scan_state != MM_SCAN_STATE_IDLE) active++; - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) services++; } } @@ -104,28 +102,26 @@ wizard_status_progress return 0; } -void -api_wizard_init ( void ) -{ +void api_wizard_init(void) { static api_hook_t ah[] = { - { "wizard/hello/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_hello }, - { "wizard/hello/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_hello }, - { "wizard/login/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_login }, - { "wizard/login/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_login }, - { "wizard/network/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_network }, - { "wizard/network/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_network }, - { "wizard/muxes/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_muxes }, - { "wizard/muxes/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_muxes }, - { "wizard/status/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_status }, - { "wizard/status/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_status }, - { "wizard/status/progress", ACCESS_ADMIN, wizard_status_progress, NULL }, - { "wizard/mapping/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_mapping }, - { "wizard/mapping/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_mapping }, - { "wizard/channels/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_channels }, - { "wizard/channels/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_channels }, - { "wizard/start", ACCESS_ADMIN, wizard_start, NULL }, - { "wizard/cancel", ACCESS_ADMIN, wizard_cancel, NULL }, - { NULL }, + {"wizard/hello/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_hello}, + {"wizard/hello/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_hello}, + {"wizard/login/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_login}, + {"wizard/login/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_login}, + {"wizard/network/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_network}, + {"wizard/network/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_network}, + {"wizard/muxes/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_muxes}, + {"wizard/muxes/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_muxes}, + {"wizard/status/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_status}, + {"wizard/status/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_status}, + {"wizard/status/progress", ACCESS_ADMIN, wizard_status_progress, NULL}, + {"wizard/mapping/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_mapping}, + {"wizard/mapping/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_mapping}, + {"wizard/channels/load", ACCESS_ADMIN, wizard_idnode_load_simple, wizard_channels}, + {"wizard/channels/save", ACCESS_ADMIN, wizard_idnode_save_simple, wizard_channels}, + {"wizard/start", ACCESS_ADMIN, wizard_start, NULL}, + {"wizard/cancel", ACCESS_ADMIN, wizard_cancel, NULL}, + {NULL}, }; api_register_all(ah); diff --git a/src/atomic.h b/src/atomic.h index 76e842d4a..c068a4ba1 100644 --- a/src/atomic.h +++ b/src/atomic.h @@ -21,7 +21,7 @@ #include #include -typedef void * volatile * atomic_refptr_t; +typedef void* volatile* atomic_refptr_t; extern tvh_mutex_t atomic_lock; @@ -29,9 +29,7 @@ extern tvh_mutex_t atomic_lock; * Atomic FETCH and ADD operation */ -static inline int -atomic_add(volatile int *ptr, int incr) -{ +static inline int atomic_add(volatile int* ptr, int incr) { #if ENABLE_ATOMIC32 return __sync_fetch_and_add(ptr, incr); #else @@ -44,9 +42,7 @@ atomic_add(volatile int *ptr, int incr) #endif } -static inline uint64_t -atomic_add_u64(volatile uint64_t *ptr, uint64_t incr) -{ +static inline uint64_t atomic_add_u64(volatile uint64_t* ptr, uint64_t incr) { #if ENABLE_ATOMIC64 return __sync_fetch_and_add(ptr, incr); #else @@ -59,9 +55,7 @@ atomic_add_u64(volatile uint64_t *ptr, uint64_t incr) #endif } -static inline int64_t -atomic_add_s64(volatile int64_t *ptr, int64_t incr) -{ +static inline int64_t atomic_add_s64(volatile int64_t* ptr, int64_t incr) { #if ENABLE_ATOMIC64 return __sync_fetch_and_add(ptr, incr); #else @@ -74,9 +68,7 @@ atomic_add_s64(volatile int64_t *ptr, int64_t incr) #endif } -static inline time_t -atomic_add_time_t(volatile time_t *ptr, time_t incr) -{ +static inline time_t atomic_add_time_t(volatile time_t* ptr, time_t incr) { #if ENABLE_ATOMIC_TIME_T return __sync_fetch_and_add(ptr, incr); #else @@ -93,9 +85,7 @@ atomic_add_time_t(volatile time_t *ptr, time_t incr) * Atomic ADD and FETCH operation */ -static inline int64_t -atomic_pre_add_s64(volatile int64_t *ptr, int64_t incr) -{ +static inline int64_t atomic_pre_add_s64(volatile int64_t* ptr, int64_t incr) { #if ENABLE_ATOMIC64 return __sync_add_and_fetch(ptr, incr); #else @@ -108,9 +98,7 @@ atomic_pre_add_s64(volatile int64_t *ptr, int64_t incr) #endif } -static inline uint64_t -atomic_pre_add_u64(volatile uint64_t *ptr, uint64_t incr) -{ +static inline uint64_t atomic_pre_add_u64(volatile uint64_t* ptr, uint64_t incr) { #if ENABLE_ATOMIC64 return __sync_add_and_fetch(ptr, incr); #else @@ -128,9 +116,7 @@ atomic_pre_add_u64(volatile uint64_t *ptr, uint64_t incr) */ static inline int64_t -atomic_pre_add_s64_peak(volatile int64_t *ptr, int64_t incr, - volatile int64_t *peak) -{ +atomic_pre_add_s64_peak(volatile int64_t* ptr, int64_t incr, volatile int64_t* peak) { #if ENABLE_ATOMIC64 int64_t ret = __sync_add_and_fetch(ptr, incr); if (__sync_fetch_and_add(peak, 0) < ret) @@ -152,9 +138,7 @@ atomic_pre_add_s64_peak(volatile int64_t *ptr, int64_t incr, * Atomic DEC operation */ -static inline int -atomic_dec(volatile int *ptr, int decr) -{ +static inline int atomic_dec(volatile int* ptr, int decr) { #if ENABLE_ATOMIC32 return __sync_fetch_and_sub(ptr, decr); #else @@ -167,9 +151,7 @@ atomic_dec(volatile int *ptr, int decr) #endif } -static inline uint64_t -atomic_dec_u64(volatile uint64_t *ptr, uint64_t decr) -{ +static inline uint64_t atomic_dec_u64(volatile uint64_t* ptr, uint64_t decr) { #if ENABLE_ATOMIC64 return __sync_fetch_and_sub(ptr, decr); #else @@ -182,9 +164,7 @@ atomic_dec_u64(volatile uint64_t *ptr, uint64_t decr) #endif } -static inline int64_t -atomic_dec_s64(volatile int64_t *ptr, int64_t decr) -{ +static inline int64_t atomic_dec_s64(volatile int64_t* ptr, int64_t decr) { #if ENABLE_ATOMIC64 return __sync_fetch_and_sub(ptr, decr); #else @@ -201,75 +181,65 @@ atomic_dec_s64(volatile int64_t *ptr, int64_t decr) * Atomic EXCHANGE operation */ -static inline int -atomic_exchange(volatile int *ptr, int val) -{ +static inline int atomic_exchange(volatile int* ptr, int val) { #if ENABLE_ATOMIC32 - return __sync_lock_test_and_set(ptr, val); + return __sync_lock_test_and_set(ptr, val); #else int ret; tvh_mutex_lock(&atomic_lock); - ret = *ptr; + ret = *ptr; *ptr = val; tvh_mutex_unlock(&atomic_lock); return ret; #endif } -static inline uint64_t -atomic_exchange_u64(volatile uint64_t *ptr, uint64_t val) -{ +static inline uint64_t atomic_exchange_u64(volatile uint64_t* ptr, uint64_t val) { #if ENABLE_ATOMIC64 - return __sync_lock_test_and_set(ptr, val); + return __sync_lock_test_and_set(ptr, val); #else uint64_t ret; tvh_mutex_lock(&atomic_lock); - ret = *ptr; + ret = *ptr; *ptr = val; tvh_mutex_unlock(&atomic_lock); return ret; #endif } -static inline int64_t -atomic_exchange_s64(volatile int64_t *ptr, int64_t val) -{ +static inline int64_t atomic_exchange_s64(volatile int64_t* ptr, int64_t val) { #if ENABLE_ATOMIC64 - return __sync_lock_test_and_set(ptr, val); + return __sync_lock_test_and_set(ptr, val); #else int64_t ret; tvh_mutex_lock(&atomic_lock); - ret = *ptr; + ret = *ptr; *ptr = val; tvh_mutex_unlock(&atomic_lock); return ret; #endif } -static inline time_t -atomic_exchange_time_t(volatile time_t *ptr, time_t val) -{ +static inline time_t atomic_exchange_time_t(volatile time_t* ptr, time_t val) { #if ENABLE_ATOMIC_TIME_T - return __sync_lock_test_and_set(ptr, val); + return __sync_lock_test_and_set(ptr, val); #else time_t ret; tvh_mutex_lock(&atomic_lock); - ret = *ptr; + ret = *ptr; *ptr = val; tvh_mutex_unlock(&atomic_lock); return ret; #endif } -static inline void * -atomic_exchange_ptr(atomic_refptr_t ptr, void *val) -{ +static inline void* atomic_exchange_ptr(atomic_refptr_t ptr, void* val) { #if ENABLE_ATOMIC_PTR - return __sync_lock_test_and_set(ptr, val); + return __sync_lock_test_and_set(ptr, val); #else - void *ret; + void* ret; tvh_mutex_lock(&atomic_lock); - ret = *ptr; + ret = *ptr; *ptr = val; tvh_mutex_unlock(&atomic_lock); return ret; @@ -280,27 +250,19 @@ atomic_exchange_ptr(atomic_refptr_t ptr, void *val) * Atomic get operation */ -static inline int -atomic_get(volatile int *ptr) -{ +static inline int atomic_get(volatile int* ptr) { return atomic_add(ptr, 0); } -static inline uint64_t -atomic_get_u64(volatile uint64_t *ptr) -{ +static inline uint64_t atomic_get_u64(volatile uint64_t* ptr) { return atomic_add_u64(ptr, 0); } -static inline int64_t -atomic_get_s64(volatile int64_t *ptr) -{ +static inline int64_t atomic_get_s64(volatile int64_t* ptr) { return atomic_add_s64(ptr, 0); } -static inline time_t -atomic_get_time_t(volatile time_t *ptr) -{ +static inline time_t atomic_get_time_t(volatile time_t* ptr) { return atomic_add_time_t(ptr, 0); } @@ -308,33 +270,23 @@ atomic_get_time_t(volatile time_t *ptr) * Atomic set operation */ -static inline int -atomic_set(volatile int *ptr, int val) -{ +static inline int atomic_set(volatile int* ptr, int val) { return atomic_exchange(ptr, val); } -static inline uint64_t -atomic_set_u64(volatile uint64_t *ptr, uint64_t val) -{ +static inline uint64_t atomic_set_u64(volatile uint64_t* ptr, uint64_t val) { return atomic_exchange_u64(ptr, val); } -static inline int64_t -atomic_set_s64(volatile int64_t *ptr, int64_t val) -{ +static inline int64_t atomic_set_s64(volatile int64_t* ptr, int64_t val) { return atomic_exchange_s64(ptr, val); } -static inline time_t -atomic_set_time_t(volatile time_t *ptr, time_t val) -{ +static inline time_t atomic_set_time_t(volatile time_t* ptr, time_t val) { return atomic_exchange_time_t(ptr, val); } -static inline void * -atomic_set_ptr(atomic_refptr_t ptr, void *val) -{ +static inline void* atomic_set_ptr(atomic_refptr_t ptr, void* val) { return atomic_exchange_ptr(ptr, val); } @@ -343,8 +295,7 @@ atomic_set_ptr(atomic_refptr_t ptr, void *val) */ static inline int64_t -atomic_set_s64_peak(volatile int64_t *ptr, int64_t val, volatile int64_t *peak) -{ +atomic_set_s64_peak(volatile int64_t* ptr, int64_t val, volatile int64_t* peak) { #if ENABLE_ATOMIC64 int64_t ret = atomic_exchange_s64(ptr, val); if (val > atomic_get_s64(peak)) @@ -353,7 +304,7 @@ atomic_set_s64_peak(volatile int64_t *ptr, int64_t val, volatile int64_t *peak) #else int64_t ret; tvh_mutex_lock(&atomic_lock); - ret = *ptr; + ret = *ptr; *ptr = val; if (val > *peak) *peak = val; diff --git a/src/avahi.c b/src/avahi.c index 8372c405d..4fab6197f 100644 --- a/src/avahi.c +++ b/src/avahi.c @@ -54,73 +54,65 @@ #include "avahi.h" #include "config.h" -static AvahiEntryGroup *group = NULL; -static char *name = NULL, *name2 = NULL; -static AvahiSimplePoll *avahi_asp = NULL; -static const AvahiPoll *avahi_poll = NULL; -static int avahi_do_restart = 0; +static AvahiEntryGroup* group = NULL; +static char * name = NULL, *name2 = NULL; +static AvahiSimplePoll* avahi_asp = NULL; +static const AvahiPoll* avahi_poll = NULL; +static int avahi_do_restart = 0; -static void create_services(AvahiClient *c); +static void create_services(AvahiClient* c); -static inline int -avahi_required(void) -{ +static inline int avahi_required(void) { return tvheadend_webui_port > 0 || tvheadend_htsp_port > 0; } -static void -entry_group_callback(AvahiEntryGroup *g, AvahiEntryGroupState state, - void *userdata) -{ +static void entry_group_callback(AvahiEntryGroup* g, AvahiEntryGroupState state, void* userdata) { assert(g == group || group == NULL); group = g; /* Called whenever the entry group state changes */ switch (state) { - case AVAHI_ENTRY_GROUP_ESTABLISHED : - /* The entry group has been established successfully */ - tvhinfo(LS_AVAHI, "Service '%s' successfully established.", name); - break; - - case AVAHI_ENTRY_GROUP_COLLISION : { - char *n; - - /* A service name collision with a remote service - * happened. Let's pick a new name */ - n = avahi_alternative_service_name(name); - if (name != name2) avahi_free(name); - name = n; - - tvherror(LS_AVAHI, "Service name collision, renaming service to '%s'", name); - - /* And recreate the services */ - create_services(avahi_entry_group_get_client(g)); - break; - } + case AVAHI_ENTRY_GROUP_ESTABLISHED: + /* The entry group has been established successfully */ + tvhinfo(LS_AVAHI, "Service '%s' successfully established.", name); + break; + + case AVAHI_ENTRY_GROUP_COLLISION: { + char* n; + + /* A service name collision with a remote service + * happened. Let's pick a new name */ + n = avahi_alternative_service_name(name); + if (name != name2) + avahi_free(name); + name = n; + + tvherror(LS_AVAHI, "Service name collision, renaming service to '%s'", name); + + /* And recreate the services */ + create_services(avahi_entry_group_get_client(g)); + break; + } - case AVAHI_ENTRY_GROUP_FAILURE : - tvherror(LS_AVAHI, - "Entry group failure: %s", - avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g)))); - break; + case AVAHI_ENTRY_GROUP_FAILURE: + tvherror(LS_AVAHI, + "Entry group failure: %s", + avahi_strerror(avahi_client_errno(avahi_entry_group_get_client(g)))); + break; - case AVAHI_ENTRY_GROUP_UNCOMMITED: - case AVAHI_ENTRY_GROUP_REGISTERING: - ; + case AVAHI_ENTRY_GROUP_UNCOMMITED: + case AVAHI_ENTRY_GROUP_REGISTERING:; } } - /** * */ -static void -create_services(AvahiClient *c) -{ - char *n; - char *path = NULL; - int ret; +static void create_services(AvahiClient* c) { + char* n; + char* path = NULL; + int ret; assert(c); /* If this is the first time we're called, let's create a new @@ -129,8 +121,8 @@ create_services(AvahiClient *c) if (!group) if (!(group = avahi_entry_group_new(c, entry_group_callback, NULL))) { tvherror(LS_AVAHI, - "avahi_entry_group_new() failed: %s", - avahi_strerror(avahi_client_errno(c))); + "avahi_entry_group_new() failed: %s", + avahi_strerror(avahi_client_errno(c))); goto fail; } @@ -138,22 +130,25 @@ create_services(AvahiClient *c) * because it was reset previously, add our entries. */ if (avahi_entry_group_is_empty(group)) { - tvhdebug(LS_AVAHI, "Adding service '%s'", name); + tvhdebug(LS_AVAHI, "Adding service '%s'", name); /* Add the service for HTSP */ if (tvheadend_htsp_port > 0) { - if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, - AVAHI_PROTO_UNSPEC, 0, name, - "_htsp._tcp", NULL, NULL, - tvheadend_htsp_port, - NULL)) < 0) { + if ((ret = avahi_entry_group_add_service(group, + AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + 0, + name, + "_htsp._tcp", + NULL, + NULL, + tvheadend_htsp_port, + NULL)) < 0) { if (ret == AVAHI_ERR_COLLISION) goto collision; - tvherror(LS_AVAHI, - "Failed to add _htsp._tcp service: %s", - avahi_strerror(ret)); + tvherror(LS_AVAHI, "Failed to add _htsp._tcp service: %s", avahi_strerror(ret)); goto fail; } } @@ -167,27 +162,29 @@ create_services(AvahiClient *c) path = strdup("path=/"); } - if ((ret = avahi_entry_group_add_service(group, AVAHI_IF_UNSPEC, - AVAHI_PROTO_UNSPEC, 0, name, - "_http._tcp", NULL, NULL, tvheadend_webui_port, - path, - NULL)) < 0) { + if ((ret = avahi_entry_group_add_service(group, + AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + 0, + name, + "_http._tcp", + NULL, + NULL, + tvheadend_webui_port, + path, + NULL)) < 0) { if (ret == AVAHI_ERR_COLLISION) goto collision; - tvherror(LS_AVAHI, - "Failed to add _http._tcp service: %s", - avahi_strerror(ret)); + tvherror(LS_AVAHI, "Failed to add _http._tcp service: %s", avahi_strerror(ret)); goto fail; } } /* Tell the server to register the service */ if ((ret = avahi_entry_group_commit(group)) < 0) { - tvherror(LS_AVAHI, - "Failed to commit entry group: %s", - avahi_strerror(ret)); + tvherror(LS_AVAHI, "Failed to commit entry group: %s", avahi_strerror(ret)); goto fail; } } @@ -195,12 +192,13 @@ create_services(AvahiClient *c) free(path); return; - collision: +collision: /* A service name collision with a local service happened. Let's * pick a new name */ n = avahi_alternative_service_name(name); - if (name != name2) avahi_free(name); + if (name != name2) + avahi_free(name); name = n; tvherror(LS_AVAHI, "Service name collision, renaming service to '%s'", name); @@ -210,76 +208,69 @@ create_services(AvahiClient *c) create_services(c); return; - fail: +fail: free(path); } - /** * */ -static void -client_callback(AvahiClient *c, AvahiClientState state, void *userdata) -{ +static void client_callback(AvahiClient* c, AvahiClientState state, void* userdata) { assert(c); /* Called whenever the client or server state changes */ switch (state) { - case AVAHI_CLIENT_S_RUNNING: + case AVAHI_CLIENT_S_RUNNING: - /* The server has startup successfully and registered its host - * name on the network, so it's time to create our services */ - create_services(c); - break; + /* The server has startup successfully and registered its host + * name on the network, so it's time to create our services */ + create_services(c); + break; - case AVAHI_CLIENT_FAILURE: - tvherror(LS_AVAHI, "Client failure: %s", avahi_strerror(avahi_client_errno(c))); - break; + case AVAHI_CLIENT_FAILURE: + tvherror(LS_AVAHI, "Client failure: %s", avahi_strerror(avahi_client_errno(c))); + break; - case AVAHI_CLIENT_S_COLLISION: + case AVAHI_CLIENT_S_COLLISION: - /* Let's drop our registered services. When the server is back - * in AVAHI_SERVER_RUNNING state we will register them - * again with the new host name. */ + /* Let's drop our registered services. When the server is back + * in AVAHI_SERVER_RUNNING state we will register them + * again with the new host name. */ - case AVAHI_CLIENT_S_REGISTERING: + case AVAHI_CLIENT_S_REGISTERING: - /* The server records are now being established. This - * might be caused by a host name change. We need to wait - * for our own records to register until the host name is - * properly esatblished. */ + /* The server records are now being established. This + * might be caused by a host name change. We need to wait + * for our own records to register until the host name is + * properly esatblished. */ - if(group) - avahi_entry_group_reset(group); + if (group) + avahi_entry_group_reset(group); - break; + break; - case AVAHI_CLIENT_CONNECTING: - ; + case AVAHI_CLIENT_CONNECTING:; } } - /** * */ -static void * -avahi_thread(void *aux) -{ - AvahiClient *ac; +static void* avahi_thread(void* aux) { + AvahiClient* ac; do { if (avahi_poll) - avahi_simple_poll_free((AvahiSimplePoll *)avahi_poll); + avahi_simple_poll_free((AvahiSimplePoll*)avahi_poll); - avahi_asp = avahi_simple_poll_new(); + avahi_asp = avahi_simple_poll_new(); avahi_poll = avahi_simple_poll_get(avahi_asp); - if(avahi_do_restart) { + if (avahi_do_restart) { tvhinfo(LS_AVAHI, "Service restarted."); avahi_do_restart = 0; - group = NULL; + group = NULL; } name = name2 = avahi_strdup(config_get_server_name()); @@ -287,8 +278,8 @@ avahi_thread(void *aux) ac = avahi_client_new(avahi_poll, AVAHI_CLIENT_NO_FAIL, client_callback, NULL, NULL); if (ac) { - while((avahi_do_restart == 0) && - (avahi_simple_poll_iterate(avahi_asp, -1) == 0)); + while ((avahi_do_restart == 0) && (avahi_simple_poll_iterate(avahi_asp, -1) == 0)) + ; avahi_client_free(ac); } @@ -307,28 +298,22 @@ avahi_thread(void *aux) */ pthread_t avahi_tid; -void -avahi_init(void) -{ +void avahi_init(void) { if (!avahi_required()) return; tvh_thread_create(&avahi_tid, NULL, avahi_thread, NULL, "avahi"); } -void -avahi_done(void) -{ +void avahi_done(void) { if (!avahi_required()) return; avahi_simple_poll_quit(avahi_asp); tvh_thread_kill(avahi_tid, SIGTERM); pthread_join(avahi_tid, NULL); - avahi_simple_poll_free((AvahiSimplePoll *)avahi_poll); + avahi_simple_poll_free((AvahiSimplePoll*)avahi_poll); } -void -avahi_restart(void) -{ +void avahi_restart(void) { if (!avahi_required()) return; avahi_do_restart = 1; diff --git a/src/avahi.h b/src/avahi.h index 0aa0a2cd7..3061a3587 100644 --- a/src/avahi.h +++ b/src/avahi.h @@ -3,7 +3,7 @@ void avahi_init(void); void avahi_done(void); void avahi_restart(void); #else -static inline void avahi_init(void) { } -static inline void avahi_done(void) { } +static inline void avahi_init(void) {} +static inline void avahi_done(void) {} static inline void avahi_restart(void) {} #endif diff --git a/src/bitops.h b/src/bitops.h index 18827bae0..ca4c8a352 100644 --- a/src/bitops.h +++ b/src/bitops.h @@ -31,21 +31,19 @@ typedef uint32_t bitops_ulong_t; #define BIT_WORD(bit) ((bit) / BITS_PER_LONG) #define BIT_MASK(bit) (((bitops_ulong_t)1) << ((bit) % BITS_PER_LONG)) -#define TVHLOG_BITARRAY ((LS_LAST + (BITS_PER_LONG - 1)) / BITS_PER_LONG) //For tvhlog.c and api/api_config.c +#define TVHLOG_BITARRAY \ + ((LS_LAST + (BITS_PER_LONG - 1)) / BITS_PER_LONG) // For tvhlog.c and api/api_config.c -static inline void set_bit(int bit, void *addr) -{ - bitops_ulong_t *p = ((bitops_ulong_t *)addr) + BIT_WORD(bit); +static inline void set_bit(int bit, void* addr) { + bitops_ulong_t* p = ((bitops_ulong_t*)addr) + BIT_WORD(bit); *p |= BIT_MASK(bit); } -static inline void clear_bit(int bit, void *addr) -{ - bitops_ulong_t *p = ((bitops_ulong_t *)addr) + BIT_WORD(bit); +static inline void clear_bit(int bit, void* addr) { + bitops_ulong_t* p = ((bitops_ulong_t*)addr) + BIT_WORD(bit); *p &= ~BIT_MASK(bit); } -static inline int test_bit(int bit, void *addr) -{ - return 1UL & (((bitops_ulong_t *)addr)[BIT_WORD(bit)] >> (bit & (BITS_PER_LONG-1))); +static inline int test_bit(int bit, void* addr) { + return 1UL & (((bitops_ulong_t*)addr)[BIT_WORD(bit)] >> (bit & (BITS_PER_LONG - 1))); } diff --git a/src/bonjour.c b/src/bonjour.c index ac710fda8..574e4b1b0 100644 --- a/src/bonjour.c +++ b/src/bonjour.c @@ -26,57 +26,56 @@ #include typedef struct { - const char *key; - const char *value; + const char* key; + const char* value; } txt_rec_t; -pthread_t bonjour_tid; +pthread_t bonjour_tid; CFNetServiceRef svc_http, svc_htsp; -static void -bonjour_callback(CFNetServiceRef theService, CFStreamError* error, void* info) -{ +static void bonjour_callback(CFNetServiceRef theService, CFStreamError* error, void* info) { if (error->error) { - tvherror(LS_BONJOUR, "callback error (domain = %ld, error =%d)", - error->domain, error->error); - } + tvherror(LS_BONJOUR, "callback error (domain = %ld, error =%d)", error->domain, error->error); + } } -static void -bonjour_start_service(CFNetServiceRef *svc, const char *service_type, - uint32_t port, txt_rec_t *txt) -{ - CFStringRef str; - CFStreamError error = {0}; +static void bonjour_start_service(CFNetServiceRef* svc, + const char* service_type, + uint32_t port, + txt_rec_t* txt) { + CFStringRef str; + CFStreamError error = {0}; CFNetServiceClientContext context = {0, NULL, NULL, NULL, NULL}; - - str = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, service_type, - kCFStringEncodingASCII, - kCFAllocatorNull); + + str = CFStringCreateWithCStringNoCopy(kCFAllocatorDefault, + service_type, + kCFStringEncodingASCII, + kCFAllocatorNull); *svc = CFNetServiceCreate(NULL, CFSTR(""), str, CFSTR("Tvheadend"), port); if (!*svc) { - tvherror(LS_BONJOUR, "service creation failed"); + tvherror(LS_BONJOUR, "service creation failed"); return; } CFNetServiceSetClient(*svc, bonjour_callback, &context); - CFNetServiceScheduleWithRunLoop(*svc, CFRunLoopGetCurrent(), - kCFRunLoopCommonModes); + CFNetServiceScheduleWithRunLoop(*svc, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); if (txt) { - CFDataRef data = NULL; + CFDataRef data = NULL; CFMutableDictionaryRef dict; - dict = CFDictionaryCreateMutable(NULL, 0, &kCFTypeDictionaryKeyCallBacks, - &kCFTypeDictionaryValueCallBacks); - - while(txt->key) { - str = CFStringCreateWithCString (NULL, txt->key, kCFStringEncodingASCII); - data = CFDataCreate (NULL, (uint8_t *) txt->value, strlen(txt->value)); + dict = CFDictionaryCreateMutable(NULL, + 0, + &kCFTypeDictionaryKeyCallBacks, + &kCFTypeDictionaryValueCallBacks); + + while (txt->key) { + str = CFStringCreateWithCString(NULL, txt->key, kCFStringEncodingASCII); + data = CFDataCreate(NULL, (uint8_t*)txt->value, strlen(txt->value)); CFDictionaryAddValue(dict, str, data); txt++; } - + data = CFNetServiceCreateTXTDataWithDictionary(NULL, dict); CFNetServiceSetTXTData(*svc, data); CFRelease(data); @@ -84,41 +83,33 @@ bonjour_start_service(CFNetServiceRef *svc, const char *service_type, } if (!CFNetServiceRegisterWithOptions(*svc, 0, &error)) - tvherror(LS_BONJOUR, "registration failed (service type = %s, " - "domain = %ld, error =%d)", service_type, error.domain, error.error); + tvherror(LS_BONJOUR, + "registration failed (service type = %s, " + "domain = %ld, error =%d)", + service_type, + error.domain, + error.error); else - tvherror(LS_BONJOUR, "service '%s' successfully established", - service_type); + tvherror(LS_BONJOUR, "service '%s' successfully established", service_type); } -static void -bonjour_stop_service(CFNetServiceRef *svc) -{ - CFNetServiceUnscheduleFromRunLoop(*svc, CFRunLoopGetCurrent(), - kCFRunLoopCommonModes); - CFNetServiceSetClient(*svc, NULL, NULL); +static void bonjour_stop_service(CFNetServiceRef* svc) { + CFNetServiceUnscheduleFromRunLoop(*svc, CFRunLoopGetCurrent(), kCFRunLoopCommonModes); + CFNetServiceSetClient(*svc, NULL, NULL); CFRelease(*svc); } -void -bonjour_init(void) -{ - txt_rec_t txt_rec_http[] = { - { "path", tvheadend_webroot ? tvheadend_webroot : "/" }, - { .key = NULL } - }; +void bonjour_init(void) { + txt_rec_t txt_rec_http[] = {{"path", tvheadend_webroot ? tvheadend_webroot : "/"}, {.key = NULL}}; if (tvheadend_webui_port > 0) - bonjour_start_service(&svc_http, "_http._tcp", tvheadend_webui_port, - txt_rec_http); + bonjour_start_service(&svc_http, "_http._tcp", tvheadend_webui_port, txt_rec_http); if (tvheadend_htsp_port > 0) bonjour_start_service(&svc_htsp, "_htsp._tcp", tvheadend_htsp_port, NULL); } -void -bonjour_done(void) -{ +void bonjour_done(void) { if (tvheadend_webui_port > 0) bonjour_stop_service(&svc_http); if (tvheadend_htsp_port > 0) diff --git a/src/bonjour.h b/src/bonjour.h index 0e20c5f1e..8c80c2859 100644 --- a/src/bonjour.h +++ b/src/bonjour.h @@ -2,6 +2,6 @@ void bonjour_init(void); void bonjour_done(void); #else -static inline void bonjour_init(void) { } -static inline void bonjour_done(void) { } +static inline void bonjour_init(void) {} +static inline void bonjour_done(void) {} #endif diff --git a/src/bouquet.c b/src/bouquet.c index ce9754958..acc4d7bb1 100644 --- a/src/bouquet.c +++ b/src/bouquet.c @@ -27,36 +27,36 @@ #include "input.h" typedef struct bouquet_download { - bouquet_t *bq; - download_t download; - mtimer_t timer; + bouquet_t* bq; + download_t download; + mtimer_t timer; } bouquet_download_t; bouquet_tree_t bouquets; static int bouquet_init_completed = 0; -static void bouquet_remove_service(bouquet_t *bq, service_t *s, int delconf); -static void bouquet_download_trigger(bouquet_t *bq); -static void bouquet_download_stop(void *aux); -static int bouquet_download_process(void *aux, const char *last_url, const char *host_url, char *data, size_t len); +static void bouquet_remove_service(bouquet_t* bq, service_t* s, int delconf); +static void bouquet_download_trigger(bouquet_t* bq); +static void bouquet_download_stop(void* aux); +static int bouquet_download_process(void* aux, + const char* last_url, + const char* host_url, + char* data, + size_t len); /** * */ -static int -_bq_cmp(const void *a, const void *b) -{ - return strcmp(((bouquet_t *)a)->bq_src ?: "", ((bouquet_t *)b)->bq_src ?: ""); +static int _bq_cmp(const void* a, const void* b) { + return strcmp(((bouquet_t*)a)->bq_src ?: "", ((bouquet_t*)b)->bq_src ?: ""); } /** * */ -static void -bouquet_free(bouquet_t *bq) -{ - bouquet_download_t *bqd; +static void bouquet_free(bouquet_t* bq) { + bouquet_download_t* bqd; idnode_save_check(&bq->bq_id, 1); idnode_unlink(&bq->bq_id); @@ -70,7 +70,7 @@ bouquet_free(bouquet_t *bq) idnode_set_free(bq->bq_active_services); idnode_set_free(bq->bq_services); htsmsg_destroy(bq->bq_services_waiting); - free((char *)bq->bq_chtag_waiting); + free((char*)bq->bq_chtag_waiting); free(bq->bq_name); free(bq->bq_ext_url); free(bq->bq_src); @@ -81,25 +81,22 @@ bouquet_free(bouquet_t *bq) /** * */ -bouquet_t * -bouquet_create(const char *uuid, htsmsg_t *conf, - const char *name, const char *src) -{ - bouquet_t *bq, *bq2; - bouquet_download_t *bqd; - char buf[128], ubuf[UUID_HEX_SIZE]; - int i; +bouquet_t* bouquet_create(const char* uuid, htsmsg_t* conf, const char* name, const char* src) { + bouquet_t * bq, *bq2; + bouquet_download_t* bqd; + char buf[128], ubuf[UUID_HEX_SIZE]; + int i; lock_assert(&global_lock); - bq = calloc(1, sizeof(bouquet_t)); - bq->bq_services = idnode_set_create(1); + bq = calloc(1, sizeof(bouquet_t)); + bq->bq_services = idnode_set_create(1); bq->bq_active_services = idnode_set_create(1); - bq->bq_ext_url_period = 60; - bq->bq_mapencrypted = 1; - bq->bq_mapradio = 1; - bq->bq_maptoch = 1; - bq->bq_chtag = 1; + bq->bq_ext_url_period = 60; + bq->bq_mapencrypted = 1; + bq->bq_mapradio = 1; + bq->bq_maptoch = 1; + bq->bq_chtag = 1; if (idnode_insert(&bq->bq_id, uuid, &bouquet_class, 0)) { if (uuid) @@ -133,12 +130,12 @@ bouquet_create(const char *uuid, htsmsg_t *conf, } else { free(bq->bq_src); snprintf(buf, sizeof(buf), "exturl://%s", idnode_uuid_as_str(&bq->bq_id, ubuf)); - bq->bq_src = strdup(buf); + bq->bq_src = strdup(buf); bq->bq_download = bqd = calloc(1, sizeof(*bqd)); - bqd->bq = bq; + bqd->bq = bq; download_init(&bqd->download, LS_BOUQUET); bqd->download.process = bouquet_download_process; - bqd->download.stop = bouquet_download_stop; + bqd->download.stop = bouquet_download_stop; bouquet_change_comment(bq, bq->bq_ext_url, 0); } } @@ -161,9 +158,7 @@ bouquet_create(const char *uuid, htsmsg_t *conf, /** * */ -static void -bouquet_destroy(bouquet_t *bq) -{ +static void bouquet_destroy(bouquet_t* bq) { if (!bq) return; @@ -175,15 +170,13 @@ bouquet_destroy(bouquet_t *bq) /** * */ -void -bouquet_destroy_by_service(service_t *t, int delconf) -{ - bouquet_t *bq; - service_lcn_t *sl; +void bouquet_destroy_by_service(service_t* t, int delconf) { + bouquet_t* bq; + service_lcn_t* sl; lock_assert(&global_lock); - RB_FOREACH(bq, &bouquets, bq_link) + RB_FOREACH (bq, &bouquets, bq_link) if (idnode_set_exists(bq->bq_services, &t->s_id)) bouquet_remove_service(bq, t, delconf); while ((sl = LIST_FIRST(&t->s_lcns)) != NULL) { @@ -195,14 +188,12 @@ bouquet_destroy_by_service(service_t *t, int delconf) /** * */ -void -bouquet_destroy_by_channel_tag(channel_tag_t *ct) -{ - bouquet_t *bq; +void bouquet_destroy_by_channel_tag(channel_tag_t* ct) { + bouquet_t* bq; lock_assert(&global_lock); - RB_FOREACH(bq, &bouquets, bq_link) + RB_FOREACH (bq, &bouquets, bq_link) if (bq->bq_chtag_ptr == ct) bq->bq_chtag_ptr = NULL; } @@ -210,18 +201,16 @@ bouquet_destroy_by_channel_tag(channel_tag_t *ct) /* * */ -bouquet_t * -bouquet_find_by_source(const char *name, const char *src, int create) -{ - bouquet_t *bq; - bouquet_t bqs; +bouquet_t* bouquet_find_by_source(const char* name, const char* src, int create) { + bouquet_t* bq; + bouquet_t bqs; assert(src); lock_assert(&global_lock); - bqs.bq_src = (char *)src; - bq = RB_FIND(&bouquets, &bqs, bq_link, _bq_cmp); + bqs.bq_src = (char*)src; + bq = RB_FIND(&bouquets, &bqs, bq_link, _bq_cmp); if (bq) { if (name && *name && bq->bq_name && strcmp(name, bq->bq_name)) { tvhwarn(LS_BOUQUET, "bouquet name '%s' changed to '%s'", bq->bq_name ?: "", name); @@ -242,16 +231,14 @@ bouquet_find_by_source(const char *name, const char *src, int create) /* * */ -static channel_tag_t * -bouquet_tag(bouquet_t *bq, int create) -{ - channel_tag_t *ct; - char buf[128]; +static channel_tag_t* bouquet_tag(bouquet_t* bq, int create) { + channel_tag_t* ct; + char buf[128]; assert(!bq->bq_in_load); if (bq->bq_chtag_waiting) { bq->bq_chtag_ptr = channel_tag_find_by_uuid(bq->bq_chtag_waiting); - free((char *)bq->bq_chtag_waiting); + free((char*)bq->bq_chtag_waiting); bq->bq_chtag_waiting = NULL; } if (bq->bq_chtag_ptr) @@ -268,9 +255,7 @@ bouquet_tag(bouquet_t *bq, int create) /* * */ -static int -noname(const char *s) -{ +static int noname(const char* s) { if (!s) return 1; while (*s) { @@ -284,72 +269,61 @@ noname(const char *s) /* * */ -static void -bouquet_map_channel(bouquet_t *bq, service_t *t) -{ - channel_t *ch = NULL; - idnode_list_mapping_t *ilm; - static service_mapper_conf_t sm_conf = { - .check_availability = 0, - .encrypted = 1, - .merge_same_name = 0, - .merge_same_name_fuzzy = 0, - .tidy_channel_name = 0, - .type_tags = 0, - .provider_tags = 0, - .network_tags = 0 - }; +static void bouquet_map_channel(bouquet_t* bq, service_t* t) { + channel_t* ch = NULL; + idnode_list_mapping_t* ilm; + static service_mapper_conf_t sm_conf = {.check_availability = 0, + .encrypted = 1, + .merge_same_name = 0, + .merge_same_name_fuzzy = 0, + .tidy_channel_name = 0, + .type_tags = 0, + .provider_tags = 0, + .network_tags = 0}; if (!t->s_enabled) return; if (!bq->bq_mapradio && service_is_radio(t)) return; - if (!bq->bq_mapnolcn && - bouquet_get_channel_number(bq, t) <= 0) + if (!bq->bq_mapnolcn && bouquet_get_channel_number(bq, t) <= 0) return; if (!bq->bq_mapnoname && noname(service_get_channel_name(t))) return; if (!bq->bq_mapencrypted && service_is_encrypted(t)) return; - LIST_FOREACH(ilm, &t->s_channels, ilm_in1_link) - if (((channel_t *)ilm->ilm_in2)->ch_bouquet == bq) + LIST_FOREACH (ilm, &t->s_channels, ilm_in1_link) + if (((channel_t*)ilm->ilm_in2)->ch_bouquet == bq) break; if (!ilm) { - sm_conf.encrypted = bq->bq_mapencrypted; - sm_conf.merge_same_name = bq->bq_mapmergename; + sm_conf.encrypted = bq->bq_mapencrypted; + sm_conf.merge_same_name = bq->bq_mapmergename; sm_conf.merge_same_name_fuzzy = bq->bq_mapmergefuzzy; - sm_conf.tidy_channel_name = bq->bq_tidychannelname; - sm_conf.type_tags = bq->bq_chtag_type_tags; - sm_conf.provider_tags = bq->bq_chtag_provider_tags; - sm_conf.network_tags = bq->bq_chtag_network_tags; - ch = service_mapper_process(&sm_conf, t, bq); + sm_conf.tidy_channel_name = bq->bq_tidychannelname; + sm_conf.type_tags = bq->bq_chtag_type_tags; + sm_conf.provider_tags = bq->bq_chtag_provider_tags; + sm_conf.network_tags = bq->bq_chtag_network_tags; + ch = service_mapper_process(&sm_conf, t, bq); } else - ch = (channel_t *)ilm->ilm_in2; + ch = (channel_t*)ilm->ilm_in2; if (ch && bq->bq_chtag) if (channel_tag_map(bouquet_tag(bq, 1), ch, ch)) idnode_changed(&ch->ch_id); } - -static const char * -bouquet_get_global_bouquet_src(void) -{ +static const char* bouquet_get_global_bouquet_src(void) { static const char src[] = "tvh-network://global-bouquet"; return src; } - /// The global bouquet is a virtual bouquet. It contains services from /// other bouquets which are enabled and have maptoch disabled. If the /// global bouquet is enabled and has maptoch enabled then it means /// mappings such as "merge same name" can be done using services from /// multiple bouquets (which may be from different sources such as /// DVB-T and DVB-S). -static bouquet_t * -bouquet_get_global_bouquet(void) -{ +static bouquet_t* bouquet_get_global_bouquet(void) { static const char name[] = "Tvheadend Network"; - bouquet_t *global_bq; + bouquet_t* global_bq; enum { BOUQUET_CREATE = 1 }; /* Still initializing, so don't do anything with a global bouquet yet otherwise @@ -368,13 +342,11 @@ bouquet_get_global_bouquet(void) /// Internal function to scan a single bouquet and collect all /// services on that bouquet in to active_svcs and add them to the /// global bouquet. -static void -bouquet_global_rescan_single_bouquet(const bouquet_t *bq, idnode_set_t *active_svcs) -{ - size_t z; - bouquet_t *global_bq = bouquet_get_global_bouquet(); - service_t *s; - const service_lcn_t *lcn; +static void bouquet_global_rescan_single_bouquet(const bouquet_t* bq, idnode_set_t* active_svcs) { + size_t z; + bouquet_t* global_bq = bouquet_get_global_bouquet(); + service_t* s; + const service_lcn_t* lcn; /* Global bouquet must be enabled and mapping to channels to have * any services. @@ -389,29 +361,27 @@ bouquet_global_rescan_single_bouquet(const bouquet_t *bq, idnode_set_t *active_s return; for (z = 0; z < bq->bq_services->is_count; z++) { - s = (service_t *)bq->bq_services->is_array[z]; - LIST_FOREACH(lcn, &s->s_lcns, sl_link) { - if (lcn->sl_bouquet != bq) continue; + s = (service_t*)bq->bq_services->is_array[z]; + LIST_FOREACH (lcn, &s->s_lcns, sl_link) { + if (lcn->sl_bouquet != bq) + continue; bouquet_add_service(global_bq, s, (int64_t)lcn->sl_lcn, NULL); idnode_set_add(active_svcs, &s->s_id, NULL, NULL); } } } - /// Callback function to rescan the global bouquet /// for active services and update the stats. -static void -bouquet_global_rescan_cb(void *unused) -{ - bouquet_t *global_bq = bouquet_get_global_bouquet(); +static void bouquet_global_rescan_cb(void* unused) { + bouquet_t* global_bq = bouquet_get_global_bouquet(); if (!global_bq) return; - size_t z; - const bouquet_t *bq; - idnode_set_t *active_svcs = idnode_set_create(1); - service_t *s; + size_t z; + const bouquet_t* bq; + idnode_set_t* active_svcs = idnode_set_create(1); + service_t* s; tvhtrace(LS_BOUQUET, "Rescanning global bouquet"); @@ -425,7 +395,7 @@ bouquet_global_rescan_cb(void *unused) * have any services */ if (global_bq->bq_enabled && global_bq->bq_maptoch) { - RB_FOREACH(bq, &bouquets, bq_link) { + RB_FOREACH (bq, &bouquets, bq_link) { bouquet_global_rescan_single_bouquet(bq, active_svcs); } } @@ -434,9 +404,9 @@ bouquet_global_rescan_cb(void *unused) * global bouquet. */ for (z = 0; z < global_bq->bq_services->is_count; z++) { - s = (service_t *)global_bq->bq_services->is_array[z]; + s = (service_t*)global_bq->bq_services->is_array[z]; if (!idnode_set_exists(active_svcs, &s->s_id)) { - bouquet_remove_service(global_bq, s, 1); + bouquet_remove_service(global_bq, s, 1); } } @@ -451,39 +421,28 @@ bouquet_global_rescan_cb(void *unused) /// doing multiple scans. For example, my system can have 20 bouquets /// a second complete scanning, so we wait until the system is less /// busy. -static void -bouquet_global_rescan_i(int64_t mono) -{ +static void bouquet_global_rescan_i(int64_t mono) { static mtimer_t bouquet_global_bouquet_rescan_timer; mtimer_arm_rel(&bouquet_global_bouquet_rescan_timer, bouquet_global_rescan_cb, NULL, mono); } -static void -bouquet_global_rescan(void) -{ +static void bouquet_global_rescan(void) { bouquet_global_rescan_i(sec2mono(5)); } - /// Even though we say "now", it could get delayed /// if the system is busy. -static void -bouquet_global_rescan_now(void) -{ +static void bouquet_global_rescan_now(void) { bouquet_global_rescan_i(sec2mono(0)); } - - /* * */ -void -bouquet_add_service(bouquet_t *bq, service_t *s, uint64_t lcn, const char *tag) -{ - service_lcn_t *tl; - idnode_list_mapping_t *ilm; - bouquet_t *global_bq = NULL; +void bouquet_add_service(bouquet_t* bq, service_t* s, uint64_t lcn, const char* tag) { + service_lcn_t* tl; + idnode_list_mapping_t* ilm; + bouquet_t* global_bq = NULL; lock_assert(&global_lock); @@ -491,19 +450,23 @@ bouquet_add_service(bouquet_t *bq, service_t *s, uint64_t lcn, const char *tag) return; if (!idnode_set_exists(bq->bq_services, &s->s_id)) { - tvhtrace(LS_BOUQUET, "add service %s [%p] to %s lcn %"PRIu64"(.%"PRIu64")", - s->s_nicename, s, bq->bq_name ?: "", - lcn / CHANNEL_SPLIT, lcn % CHANNEL_SPLIT); + tvhtrace(LS_BOUQUET, + "add service %s [%p] to %s lcn %" PRIu64 "(.%" PRIu64 ")", + s->s_nicename, + s, + bq->bq_name ?: "", + lcn / CHANNEL_SPLIT, + lcn % CHANNEL_SPLIT); idnode_set_add(bq->bq_services, &s->s_id, NULL, NULL); bq->bq_saveflag = 1; } - LIST_FOREACH(tl, &s->s_lcns, sl_link) + LIST_FOREACH (tl, &s->s_lcns, sl_link) if (tl->sl_bouquet == bq) break; if (!tl) { - tl = calloc(1, sizeof(*tl)); + tl = calloc(1, sizeof(*tl)); tl->sl_bouquet = bq; LIST_INSERT_HEAD(&s->s_lcns, tl, sl_link); bq->bq_saveflag = 1; @@ -513,7 +476,7 @@ bouquet_add_service(bouquet_t *bq, service_t *s, uint64_t lcn, const char *tag) } if (lcn != tl->sl_lcn) { tl->sl_lcn = lcn; - LIST_FOREACH(ilm, &s->s_channels, ilm_in1_link) + LIST_FOREACH (ilm, &s->s_channels, ilm_in1_link) idnode_notify_changed(ilm->ilm_in2); } tl->sl_seen = 1; @@ -521,8 +484,7 @@ bouquet_add_service(bouquet_t *bq, service_t *s, uint64_t lcn, const char *tag) if (bq->bq_enabled && bq->bq_maptoch) bouquet_map_channel(bq, s); - if (!bq->bq_in_load && - !idnode_set_exists(bq->bq_active_services, &s->s_id)) + if (!bq->bq_in_load && !idnode_set_exists(bq->bq_active_services, &s->s_id)) idnode_set_add(bq->bq_active_services, &s->s_id, NULL, NULL); global_bq = bouquet_get_global_bouquet(); @@ -534,19 +496,19 @@ bouquet_add_service(bouquet_t *bq, service_t *s, uint64_t lcn, const char *tag) /* * */ -static void -bouquet_unmap_channel(bouquet_t *bq, service_t *t) -{ +static void bouquet_unmap_channel(bouquet_t* bq, service_t* t) { idnode_list_mapping_t *ilm, *ilm_next; ilm = LIST_FIRST(&t->s_channels); while (ilm) { ilm_next = LIST_NEXT(ilm, ilm_in1_link); - if (((channel_t *)ilm->ilm_in2)->ch_bouquet == bq) { - tvhinfo(LS_BOUQUET, "%s / %s: unmapped from %s", - channel_get_name((channel_t *)ilm->ilm_in2, channel_blank_name), - t->s_nicename, bq->bq_name ?: ""); - channel_delete((channel_t *)ilm->ilm_in2, 1); + if (((channel_t*)ilm->ilm_in2)->ch_bouquet == bq) { + tvhinfo(LS_BOUQUET, + "%s / %s: unmapped from %s", + channel_get_name((channel_t*)ilm->ilm_in2, channel_blank_name), + t->s_nicename, + bq->bq_name ?: ""); + channel_delete((channel_t*)ilm->ilm_in2, 1); } ilm = ilm_next; } @@ -555,14 +517,12 @@ bouquet_unmap_channel(bouquet_t *bq, service_t *t) /** * */ -void -bouquet_notify_service_enabled(service_t *t) -{ - bouquet_t *bq; +void bouquet_notify_service_enabled(service_t* t) { + bouquet_t* bq; lock_assert(&global_lock); - RB_FOREACH(bq, &bouquets, bq_link) + RB_FOREACH (bq, &bouquets, bq_link) if (idnode_set_exists(bq->bq_services, &t->s_id)) { if (!t->s_enabled) bouquet_unmap_channel(bq, t); @@ -574,12 +534,9 @@ bouquet_notify_service_enabled(service_t *t) /* * */ -static void -bouquet_remove_service(bouquet_t *bq, service_t *s, int delconf) -{ - bouquet_t *global_bq; - tvhtrace(LS_BOUQUET, "remove service %s from %s", - s->s_nicename, bq->bq_name ?: ""); +static void bouquet_remove_service(bouquet_t* bq, service_t* s, int delconf) { + bouquet_t* global_bq; + tvhtrace(LS_BOUQUET, "remove service %s from %s", s->s_nicename, bq->bq_name ?: ""); idnode_set_remove(bq->bq_services, &s->s_id); if (delconf) bouquet_unmap_channel(bq, s); @@ -595,25 +552,27 @@ bouquet_remove_service(bouquet_t *bq, service_t *s, int delconf) /* * */ -void -bouquet_completed(bouquet_t *bq, uint32_t seen) -{ - idnode_set_t *remove; - service_t *s; +void bouquet_completed(bouquet_t* bq, uint32_t seen) { + idnode_set_t* remove; + service_t* s; service_lcn_t *lcn, *lcn_next; - size_t z; + size_t z; if (!bq) return; if (seen != bq->bq_services_seen) { bq->bq_services_seen = seen; - bq->bq_saveflag = 1; + bq->bq_saveflag = 1; } - tvhtrace(LS_BOUQUET, "%s: completed: enabled=%d active=%zi old=%zi seen=%u", - bq->bq_name ?: "", bq->bq_enabled, bq->bq_active_services->is_count, - bq->bq_services->is_count, seen); + tvhtrace(LS_BOUQUET, + "%s: completed: enabled=%d active=%zi old=%zi seen=%u", + bq->bq_name ?: "", + bq->bq_enabled, + bq->bq_active_services->is_count, + bq->bq_services->is_count, + seen); if (!bq->bq_enabled) goto save; @@ -624,15 +583,16 @@ bouquet_completed(bouquet_t *bq, uint32_t seen) if (!idnode_set_exists(bq->bq_active_services, bq->bq_services->is_array[z])) idnode_set_add(remove, bq->bq_services->is_array[z], NULL, NULL); for (z = 0; z < remove->is_count; z++) - bouquet_remove_service(bq, (service_t *)remove->is_array[z], 1); + bouquet_remove_service(bq, (service_t*)remove->is_array[z], 1); idnode_set_free(remove); /* Remove no longer used LCNs */ for (z = 0; z < bq->bq_services->is_count; z++) { - s = (service_t *)bq->bq_services->is_array[z]; + s = (service_t*)bq->bq_services->is_array[z]; for (lcn = LIST_FIRST(&s->s_lcns); lcn; lcn = lcn_next) { lcn_next = LIST_NEXT(lcn, sl_link); - if (lcn->sl_bouquet != bq) continue; + if (lcn->sl_bouquet != bq) + continue; if (!lcn->sl_seen) { LIST_REMOVE(lcn, sl_link); free(lcn); @@ -642,7 +602,6 @@ bouquet_completed(bouquet_t *bq, uint32_t seen) } } - idnode_set_free(bq->bq_active_services); bq->bq_active_services = idnode_set_create(1); @@ -656,14 +615,12 @@ save: /* * */ -void -bouquet_map_to_channels(bouquet_t *bq) -{ - service_t *t; - size_t z; +void bouquet_map_to_channels(bouquet_t* bq) { + service_t* t; + size_t z; for (z = 0; z < bq->bq_services->is_count; z++) { - t = (service_t *)bq->bq_services->is_array[z]; + t = (service_t*)bq->bq_services->is_array[z]; if (bq->bq_enabled && bq->bq_maptoch) { bouquet_map_channel(bq, t); } else { @@ -687,17 +644,15 @@ bouquet_map_to_channels(bouquet_t *bq) /* * */ -void -bouquet_notify_channels(bouquet_t *bq) -{ - idnode_list_mapping_t *ilm; - service_t *t; - size_t z; +void bouquet_notify_channels(bouquet_t* bq) { + idnode_list_mapping_t* ilm; + service_t* t; + size_t z; for (z = 0; z < bq->bq_services->is_count; z++) { - t = (service_t *)bq->bq_services->is_array[z]; - LIST_FOREACH(ilm, &t->s_channels, ilm_in1_link) - if (((channel_t *)ilm->ilm_in2)->ch_bouquet == bq) + t = (service_t*)bq->bq_services->is_array[z]; + LIST_FOREACH (ilm, &t->s_channels, ilm_in1_link) + if (((channel_t*)ilm->ilm_in2)->ch_bouquet == bq) idnode_notify_changed(ilm->ilm_in2); } } @@ -705,12 +660,10 @@ bouquet_notify_channels(bouquet_t *bq) /* * */ -uint64_t -bouquet_get_channel_number(bouquet_t *bq, service_t *t) -{ - service_lcn_t *tl; +uint64_t bouquet_get_channel_number(bouquet_t* bq, service_t* t) { + service_lcn_t* tl; - LIST_FOREACH(tl, &t->s_lcns, sl_link) + LIST_FOREACH (tl, &t->s_lcns, sl_link) if (tl->sl_bouquet == bq) return (int64_t)tl->sl_lcn; return 0; @@ -719,20 +672,17 @@ bouquet_get_channel_number(bouquet_t *bq, service_t *t) /* * */ -static const char * -bouquet_get_tag_name(bouquet_t *bq, service_t *t) -{ +static const char* bouquet_get_tag_name(bouquet_t* bq, service_t* t) { return 0; } /** * */ -void -bouquet_delete(bouquet_t *bq) -{ +void bouquet_delete(bouquet_t* bq) { char ubuf[UUID_HEX_SIZE]; - if (bq == NULL) return; + if (bq == NULL) + return; bq->bq_enabled = 0; bouquet_map_to_channels(bq); if (!bq->bq_shield) { @@ -754,24 +704,20 @@ bouquet_delete(bouquet_t *bq) /** * */ -void -bouquet_change_comment ( bouquet_t *bq, const char *comment, int replace ) -{ +void bouquet_change_comment(bouquet_t* bq, const char* comment, int replace) { if (!replace && bq->bq_comment && bq->bq_comment[0]) return; free(bq->bq_comment); - bq->bq_comment = comment ? strdup(comment) : NULL; + bq->bq_comment = comment ? strdup(comment) : NULL; bq->bq_saveflag = 1; } /* * */ -void -bouquet_scan ( bouquet_t *bq ) -{ - void mpegts_mux_bouquet_rescan ( const char *src, const char *extra ); - char *mpegts_network_uuid = NULL; +void bouquet_scan(bouquet_t* bq) { + void mpegts_mux_bouquet_rescan(const char* src, const char* extra); + char* mpegts_network_uuid = NULL; if (bq->bq_src) { #if ENABLE_IPTV if (strncmp(bq->bq_src, "iptv-network://", 15) == 0) @@ -785,7 +731,7 @@ bouquet_scan ( bouquet_t *bq ) return bouquet_global_rescan_now(); if (mpegts_network_uuid) { - mpegts_network_t *mn = mpegts_network_find(mpegts_network_uuid); + mpegts_network_t* mn = mpegts_network_find(mpegts_network_uuid); if (mn) return mpegts_network_bouquet_trigger(mn, 0); } @@ -797,20 +743,18 @@ bouquet_scan ( bouquet_t *bq ) /* * */ -void -bouquet_detach ( channel_t *ch ) -{ - bouquet_t *bq = ch->ch_bouquet; - idnode_list_mapping_t *ilm; - service_lcn_t *tl; - service_t *t; - int64_t n = 0; +void bouquet_detach(channel_t* ch) { + bouquet_t* bq = ch->ch_bouquet; + idnode_list_mapping_t* ilm; + service_lcn_t* tl; + service_t* t; + int64_t n = 0; if (!bq) return; - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - t = (service_t *)ilm->ilm_in1; - LIST_FOREACH(tl, &t->s_lcns, sl_link) + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + t = (service_t*)ilm->ilm_in1; + LIST_FOREACH (tl, &t->s_lcns, sl_link) if (tl->sl_bouquet == bq) { n = (int64_t)tl->sl_lcn; goto found; @@ -829,12 +773,10 @@ found: * Class definition * **************************************************************************/ -static htsmsg_t * -bouquet_class_save(idnode_t *self, char *filename, size_t fsize) -{ - bouquet_t *bq = (bouquet_t *)self; - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* bouquet_class_save(idnode_t* self, char* filename, size_t fsize) { + bouquet_t* bq = (bouquet_t*)self; + htsmsg_t* c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(&bq->bq_id, c); if (filename) snprintf(filename, fsize, "bouquet/%s", idnode_uuid_as_str(&bq->bq_id, ubuf)); @@ -844,17 +786,12 @@ bouquet_class_save(idnode_t *self, char *filename, size_t fsize) return c; } -static void -bouquet_class_delete(idnode_t *self) -{ - bouquet_delete((bouquet_t *)self); +static void bouquet_class_delete(idnode_t* self) { + bouquet_delete((bouquet_t*)self); } -static void -bouquet_class_get_title - (idnode_t *self, const char *lang, char *dst, size_t dstsize) -{ - bouquet_t *bq = (bouquet_t *)self; +static void bouquet_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + bouquet_t* bq = (bouquet_t*)self; if (bq->bq_comment && bq->bq_comment[0] != '\0') snprintf(dst, dstsize, "%s", bq->bq_comment); @@ -863,20 +800,16 @@ bouquet_class_get_title } /* exported for others */ -htsmsg_t * -bouquet_class_get_list(void *o, const char *lang) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "bouquet/list"); +htsmsg_t* bouquet_class_get_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "bouquet/list"); htsmsg_add_str(m, "event", "bouquet"); return m; } -static void -bouquet_class_enabled_notify ( void *obj, const char *lang ) -{ - bouquet_t *bq = obj; +static void bouquet_class_enabled_notify(void* obj, const char* lang) { + bouquet_t* bq = obj; if (bq->bq_enabled) bouquet_scan(bq); @@ -889,10 +822,8 @@ bouquet_class_enabled_notify ( void *obj, const char *lang ) bq == bouquet_get_global_bouquet() ? bouquet_global_rescan_now() : bouquet_global_rescan(); } -static void -bouquet_class_maptoch_notify ( void *obj, const char *lang ) -{ - bouquet_t *bq = obj; +static void bouquet_class_maptoch_notify(void* obj, const char* lang) { + bouquet_t* bq = obj; bouquet_map_to_channels(bq); /* Ensure any service changes are reflected in the global bouquet */ if (bq != bouquet_get_global_bouquet()) { @@ -900,89 +831,75 @@ bouquet_class_maptoch_notify ( void *obj, const char *lang ) } } -static void -bouquet_class_lcn_offset_notify ( void *obj, const char *lang ) -{ - if (((bouquet_t *)obj)->bq_in_load) +static void bouquet_class_lcn_offset_notify(void* obj, const char* lang) { + if (((bouquet_t*)obj)->bq_in_load) return; - bouquet_notify_channels((bouquet_t *)obj); + bouquet_notify_channels((bouquet_t*)obj); } -static idnode_slist_t bouquest_class_mapopt_slist[] = { - { - .id = "mapnolcn", - .name = N_("Map zero-numbered channels"), - .off = offsetof(bouquet_t, bq_mapnolcn), - }, - { - .id = "mapnoname", - .name = N_("Map unnamed channels"), - .off = offsetof(bouquet_t, bq_mapnoname), - }, - { - .id = "mapradio", - .name = N_("Map radio channels"), - .off = offsetof(bouquet_t, bq_mapradio), - }, - { - .id = "encrypted", - .name = N_("Map encrypted services"), - .off = offsetof(bouquet_t, bq_mapencrypted), - }, - { - .id = "merge_name", - .name = N_("Merge same name"), - .off = offsetof(bouquet_t, bq_mapmergename), - }, - { - .id = "merge_same_name_fuzzy", - .name = N_("Use fuzzy mapping if merging same name"), - .off = offsetof(bouquet_t, bq_mapmergefuzzy), - }, - { - .id = "tidy_channel_name", - .name = N_("Tidy channel name (e.g., stripping HD/UHD suffix)"), - .off = offsetof(bouquet_t, bq_tidychannelname), - }, - {} -}; - -static htsmsg_t * -bouquet_class_mapopt_enum ( void *obj, const char *lang ) -{ +static idnode_slist_t bouquest_class_mapopt_slist[] = {{ + .id = "mapnolcn", + .name = N_("Map zero-numbered channels"), + .off = offsetof(bouquet_t, bq_mapnolcn), + }, + { + .id = "mapnoname", + .name = N_("Map unnamed channels"), + .off = offsetof(bouquet_t, bq_mapnoname), + }, + { + .id = "mapradio", + .name = N_("Map radio channels"), + .off = offsetof(bouquet_t, bq_mapradio), + }, + { + .id = "encrypted", + .name = N_("Map encrypted services"), + .off = offsetof(bouquet_t, bq_mapencrypted), + }, + { + .id = "merge_name", + .name = N_("Merge same name"), + .off = offsetof(bouquet_t, bq_mapmergename), + }, + { + .id = "merge_same_name_fuzzy", + .name = N_("Use fuzzy mapping if merging same name"), + .off = offsetof(bouquet_t, bq_mapmergefuzzy), + }, + { + .id = "tidy_channel_name", + .name = N_("Tidy channel name (e.g., stripping HD/UHD suffix)"), + .off = offsetof(bouquet_t, bq_tidychannelname), + }, + {}}; + +static htsmsg_t* bouquet_class_mapopt_enum(void* obj, const char* lang) { return idnode_slist_enum(obj, bouquest_class_mapopt_slist, lang); } -static const void * -bouquet_class_mapopt_get ( void *obj ) -{ +static const void* bouquet_class_mapopt_get(void* obj) { return idnode_slist_get(obj, bouquest_class_mapopt_slist); } -static char * -bouquet_class_mapopt_rend ( void *obj, const char *lang ) -{ +static char* bouquet_class_mapopt_rend(void* obj, const char* lang) { return idnode_slist_rend(obj, bouquest_class_mapopt_slist, lang); } -static int -bouquet_class_mapopt_set ( void *obj, const void *p ) -{ +static int bouquet_class_mapopt_set(void* obj, const void* p) { return idnode_slist_set(obj, bouquest_class_mapopt_slist, p); } -static void -bouquet_class_mapopt_notify ( void *obj, const char *lang ) -{ - bouquet_t *bq = obj; - service_t *t; - size_t z; +static void bouquet_class_mapopt_notify(void* obj, const char* lang) { + bouquet_t* bq = obj; + service_t* t; + size_t z; if (bq->bq_in_load) return; if (bq->bq_enabled && bq->bq_maptoch) { for (z = 0; z < bq->bq_services->is_count; z++) { - t = (service_t *)bq->bq_services->is_array[z]; + t = (service_t*)bq->bq_services->is_array[z]; if (!bq->bq_mapradio && service_is_radio(t)) bouquet_unmap_channel(bq, t); else if (!bq->bq_mapnoname && noname(service_get_channel_name(t))) @@ -996,62 +913,50 @@ bouquet_class_mapopt_notify ( void *obj, const char *lang ) bouquet_map_to_channels(bq); } -static idnode_slist_t bouquest_class_chtag_slist[] = { - { - .id = "bouquet_tag", - .name = N_("Create bouquet tag"), - .off = offsetof(bouquet_t, bq_chtag), - }, - { - .id = "type_tags", - .name = N_("Create type-based tags"), - .off = offsetof(bouquet_t, bq_chtag_type_tags), - }, - { - .id = "providers_tags", - .name = N_("Create provider name tags"), - .off = offsetof(bouquet_t, bq_chtag_provider_tags), - }, - { - .id = "network_tags", - .name = N_("Create network name tags"), - .off = offsetof(bouquet_t, bq_chtag_network_tags), - }, - {} -}; - -static htsmsg_t * -bouquet_class_chtag_enum ( void *obj, const char *lang ) -{ +static idnode_slist_t bouquest_class_chtag_slist[] = {{ + .id = "bouquet_tag", + .name = N_("Create bouquet tag"), + .off = offsetof(bouquet_t, bq_chtag), + }, + { + .id = "type_tags", + .name = N_("Create type-based tags"), + .off = offsetof(bouquet_t, bq_chtag_type_tags), + }, + { + .id = "providers_tags", + .name = N_("Create provider name tags"), + .off = offsetof(bouquet_t, bq_chtag_provider_tags), + }, + { + .id = "network_tags", + .name = N_("Create network name tags"), + .off = offsetof(bouquet_t, bq_chtag_network_tags), + }, + {}}; + +static htsmsg_t* bouquet_class_chtag_enum(void* obj, const char* lang) { return idnode_slist_enum(obj, bouquest_class_chtag_slist, lang); } -static const void * -bouquet_class_chtag_get ( void *obj ) -{ +static const void* bouquet_class_chtag_get(void* obj) { return idnode_slist_get(obj, bouquest_class_chtag_slist); } -static char * -bouquet_class_chtag_rend ( void *obj, const char *lang ) -{ +static char* bouquet_class_chtag_rend(void* obj, const char* lang) { return idnode_slist_rend(obj, bouquest_class_chtag_slist, lang); } -static int -bouquet_class_chtag_set ( void *obj, const void *p ) -{ +static int bouquet_class_chtag_set(void* obj, const void* p) { return idnode_slist_set(obj, bouquest_class_chtag_slist, p); } -static void -bouquet_class_chtag_notify ( void *obj, const char *lang ) -{ - bouquet_t *bq = obj; - service_t *t; - idnode_list_mapping_t *ilm; - channel_tag_t *ct; - size_t z; +static void bouquet_class_chtag_notify(void* obj, const char* lang) { + bouquet_t* bq = obj; + service_t* t; + idnode_list_mapping_t* ilm; + channel_tag_t* ct; + size_t z; if (bq->bq_in_load) return; @@ -1060,21 +965,19 @@ bouquet_class_chtag_notify ( void *obj, const char *lang ) if (!ct) return; for (z = 0; z < bq->bq_services->is_count; z++) { - t = (service_t *)bq->bq_services->is_array[z]; - LIST_FOREACH(ilm, &t->s_channels, ilm_in1_link) - if (((channel_t *)ilm->ilm_in2)->ch_bouquet == bq) + t = (service_t*)bq->bq_services->is_array[z]; + LIST_FOREACH (ilm, &t->s_channels, ilm_in1_link) + if (((channel_t*)ilm->ilm_in2)->ch_bouquet == bq) break; if (ilm) - channel_tag_unmap((channel_t *)ilm->ilm_in2, ct); + channel_tag_unmap((channel_t*)ilm->ilm_in2, ct); } } bouquet_map_to_channels(bq); } -static const void * -bouquet_class_chtag_ref_get ( void *obj ) -{ - bouquet_t *bq = obj; +static const void* bouquet_class_chtag_ref_get(void* obj) { + bouquet_t* bq = obj; if (bq->bq_chtag_ptr) idnode_uuid_as_str(&bq->bq_chtag_ptr->ct_id, prop_sbuf); @@ -1083,42 +986,36 @@ bouquet_class_chtag_ref_get ( void *obj ) return &prop_sbuf_ptr; } -static char * -bouquet_class_chtag_ref_rend ( void *obj, const char *lang ) -{ - bouquet_t *bq = obj; +static char* bouquet_class_chtag_ref_rend(void* obj, const char* lang) { + bouquet_t* bq = obj; if (bq->bq_chtag_ptr) return strdup(bq->bq_chtag_ptr->ct_name ?: ""); else return strdup(""); } -static int -bouquet_class_chtag_ref_set ( void *obj, const void *p ) -{ - bouquet_t *bq = obj; +static int bouquet_class_chtag_ref_set(void* obj, const void* p) { + bouquet_t* bq = obj; - free((char *)bq->bq_chtag_waiting); + free((char*)bq->bq_chtag_waiting); bq->bq_chtag_waiting = NULL; if (bq->bq_in_load) - bq->bq_chtag_waiting = strdup((const char *)p); + bq->bq_chtag_waiting = strdup((const char*)p); return 0; } -static const void * -bouquet_class_services_get ( void *obj ) -{ - htsmsg_t *m = htsmsg_create_map(), *e; - bouquet_t *bq = obj; - service_t *t; - int64_t lcn; - const char *tag; - size_t z; - char ubuf[UUID_HEX_SIZE]; +static const void* bouquet_class_services_get(void* obj) { + htsmsg_t * m = htsmsg_create_map(), *e; + bouquet_t* bq = obj; + service_t* t; + int64_t lcn; + const char* tag; + size_t z; + char ubuf[UUID_HEX_SIZE]; /* Add all */ for (z = 0; z < bq->bq_services->is_count; z++) { - t = (service_t *)bq->bq_services->is_array[z]; + t = (service_t*)bq->bq_services->is_array[z]; e = htsmsg_create_map(); if ((lcn = bouquet_get_channel_number(bq, t)) != 0) htsmsg_add_s64(e, "lcn", lcn); @@ -1130,272 +1027,262 @@ bouquet_class_services_get ( void *obj ) return m; } -static char * -bouquet_class_services_rend ( void *obj, const char *lang ) -{ - bouquet_t *bq = obj; - const char *sc = N_("Service count %zi"); - char buf[32]; +static char* bouquet_class_services_rend(void* obj, const char* lang) { + bouquet_t* bq = obj; + const char* sc = N_("Service count %zi"); + char buf[32]; snprintf(buf, sizeof(buf), tvh_gettext_lang(lang, sc), bq->bq_services->is_count); return strdup(buf); } -static int -bouquet_class_services_set ( void *obj, const void *p ) -{ - bouquet_t *bq = obj; +static int bouquet_class_services_set(void* obj, const void* p) { + bouquet_t* bq = obj; if (bq->bq_services_waiting) htsmsg_destroy(bq->bq_services_waiting); bq->bq_services_waiting = NULL; if (bq->bq_in_load) - bq->bq_services_waiting = htsmsg_copy((htsmsg_t *)p); + bq->bq_services_waiting = htsmsg_copy((htsmsg_t*)p); return 0; } -static const void * -bouquet_class_services_count_get ( void *obj ) -{ +static const void* bouquet_class_services_count_get(void* obj) { static uint32_t u32; - bouquet_t *bq = obj; + bouquet_t* bq = obj; u32 = bq->bq_services->is_count; return &u32; } -static void -bouquet_class_ext_url_notify ( void *obj, const char *lang ) -{ - bouquet_download_trigger((bouquet_t *)obj); +static void bouquet_class_ext_url_notify(void* obj, const char* lang) { + bouquet_download_trigger((bouquet_t*)obj); } CLASS_DOC(bouquet) PROP_DOC(bouquet_mapping_options) PROP_DOC(bouquet_tagging) -const idclass_t bouquet_class = { - .ic_class = "bouquet", - .ic_caption = N_("Channels / EPG - Bouquets"), - .ic_doc = tvh_doc_bouquet_class, - .ic_event = "bouquet", - .ic_perm_def = ACCESS_ADMIN, - .ic_save = bouquet_class_save, - .ic_get_title = bouquet_class_get_title, - .ic_delete = bouquet_class_delete, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable the bouquet."), - .def.i = 1, - .off = offsetof(bouquet_t, bq_enabled), - .notify = bouquet_class_enabled_notify, - }, - { - .type = PT_BOOL, - .id = "maptoch", - .name = N_("Auto-Map to channels"), - .desc = N_("Automatically map channels defined within the " - "bouquet."), - .off = offsetof(bouquet_t, bq_maptoch), - .notify = bouquet_class_maptoch_notify, - }, - { - .type = PT_INT, - .islist = 1, - .id = "mapopt", - .name = N_("Channel mapping options"), - .desc = N_("Options to use/used when mapping - see Help for details."), - .doc = prop_doc_bouquet_mapping_options, - .notify = bouquet_class_mapopt_notify, - .list = bouquet_class_mapopt_enum, - .get = bouquet_class_mapopt_get, - .set = bouquet_class_mapopt_set, - .rend = bouquet_class_mapopt_rend, - .opts = PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_INT, - .islist = 1, - .id = "chtag", - .name = N_("Create tags"), - .desc = N_("Create and link these tags to channels when " - "mapping."), - .doc = prop_doc_bouquet_tagging, - .notify = bouquet_class_chtag_notify, - .list = bouquet_class_chtag_enum, - .get = bouquet_class_chtag_get, - .set = bouquet_class_chtag_set, - .rend = bouquet_class_chtag_rend, - .opts = PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "chtag_ref", - .name = N_("Channel tag reference"), - .get = bouquet_class_chtag_ref_get, - .set = bouquet_class_chtag_ref_set, - .rend = bouquet_class_chtag_ref_rend, - .opts = PO_RDONLY | PO_HIDDEN | PO_NOUI, - }, - { - .type = PT_STR, - .id = "name", - .name = N_("Name"), - .desc = N_("Name of the bouquet."), - .off = offsetof(bouquet_t, bq_name), - }, - { - .type = PT_STR, - .id = "ext_url", - .name = N_("External URL"), - .desc = N_("External URL of the bouquet."), - .off = offsetof(bouquet_t, bq_ext_url), - .opts = PO_HIDDEN | PO_MULTILINE, - .notify = bouquet_class_ext_url_notify, - }, - { - .type = PT_BOOL, - .id = "ssl_peer_verify", - .name = N_("SSL verify peer"), - .desc = N_("Verify the SSL certificate."), - .off = offsetof(bouquet_t, bq_ssl_peer_verify), - .opts = PO_ADVANCED | PO_HIDDEN | PO_EXPERT, - .notify = bouquet_class_ext_url_notify, - }, - { - .type = PT_U32, - .id = "ext_url_period", - .name = N_("Re-fetch period (mins)"), - .desc = N_("Re-fetch the bouquet every x minutes."), - .off = offsetof(bouquet_t, bq_ext_url_period), - .opts = PO_ADVANCED | PO_HIDDEN, - .notify = bouquet_class_ext_url_notify, - .def.i = 60 - }, - { - .type = PT_STR, - .id = "source", - .name = N_("Source"), - .desc = N_("Bouquet source."), - .off = offsetof(bouquet_t, bq_src), - .opts = PO_RDONLY | PO_ADVANCED, - }, - { - .type = PT_STR, - .islist = 1, - .id = "services", - .name = N_("Services"), - .desc = N_("Number of services."), - .get = bouquet_class_services_get, - .set = bouquet_class_services_set, - .rend = bouquet_class_services_rend, - .opts = PO_RDONLY | PO_HIDDEN, - }, - { - .type = PT_U32, - .id = "services_seen", - .name = N_("Services seen"), - .desc = N_("Total number of services seen."), - .off = offsetof(bouquet_t, bq_services_seen), - .opts = PO_RDONLY, - }, - { - .type = PT_U32, - .id = "services_count", - .name = N_("Services"), - .desc = N_("Total number of services."), - .get = bouquet_class_services_count_get, - .opts = PO_RDONLY | PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-form text field, enter whatever you like."), - .off = offsetof(bouquet_t, bq_comment), - }, - { - .type = PT_U32, - .id = "lcn_off", - .name = N_("Channel number offset"), - .desc = N_("Offset the mapped channel numbers by x " - "(value here + channel number)."), - .off = offsetof(bouquet_t, bq_lcn_offset), - .notify = bouquet_class_lcn_offset_notify, - .opts = PO_ADVANCED - }, - {} - } -}; +const idclass_t bouquet_class = {.ic_class = "bouquet", + .ic_caption = N_("Channels / EPG - Bouquets"), + .ic_doc = tvh_doc_bouquet_class, + .ic_event = "bouquet", + .ic_perm_def = ACCESS_ADMIN, + .ic_save = bouquet_class_save, + .ic_get_title = bouquet_class_get_title, + .ic_delete = bouquet_class_delete, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable the bouquet."), + .def.i = 1, + .off = offsetof(bouquet_t, bq_enabled), + .notify = bouquet_class_enabled_notify, + }, + { + .type = PT_BOOL, + .id = "maptoch", + .name = N_("Auto-Map to channels"), + .desc = N_("Automatically map channels defined within the " + "bouquet."), + .off = offsetof(bouquet_t, bq_maptoch), + .notify = bouquet_class_maptoch_notify, + }, + { + .type = PT_INT, + .islist = 1, + .id = "mapopt", + .name = N_("Channel mapping options"), + .desc = N_("Options to use/used when mapping - see Help for details."), + .doc = prop_doc_bouquet_mapping_options, + .notify = bouquet_class_mapopt_notify, + .list = bouquet_class_mapopt_enum, + .get = bouquet_class_mapopt_get, + .set = bouquet_class_mapopt_set, + .rend = bouquet_class_mapopt_rend, + .opts = PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_INT, + .islist = 1, + .id = "chtag", + .name = N_("Create tags"), + .desc = N_("Create and link these tags to channels when " + "mapping."), + .doc = prop_doc_bouquet_tagging, + .notify = bouquet_class_chtag_notify, + .list = bouquet_class_chtag_enum, + .get = bouquet_class_chtag_get, + .set = bouquet_class_chtag_set, + .rend = bouquet_class_chtag_rend, + .opts = PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "chtag_ref", + .name = N_("Channel tag reference"), + .get = bouquet_class_chtag_ref_get, + .set = bouquet_class_chtag_ref_set, + .rend = bouquet_class_chtag_ref_rend, + .opts = PO_RDONLY | PO_HIDDEN | PO_NOUI, + }, + { + .type = PT_STR, + .id = "name", + .name = N_("Name"), + .desc = N_("Name of the bouquet."), + .off = offsetof(bouquet_t, bq_name), + }, + { + .type = PT_STR, + .id = "ext_url", + .name = N_("External URL"), + .desc = N_("External URL of the bouquet."), + .off = offsetof(bouquet_t, bq_ext_url), + .opts = PO_HIDDEN | PO_MULTILINE, + .notify = bouquet_class_ext_url_notify, + }, + { + .type = PT_BOOL, + .id = "ssl_peer_verify", + .name = N_("SSL verify peer"), + .desc = N_("Verify the SSL certificate."), + .off = offsetof(bouquet_t, bq_ssl_peer_verify), + .opts = PO_ADVANCED | PO_HIDDEN | PO_EXPERT, + .notify = bouquet_class_ext_url_notify, + }, + {.type = PT_U32, + .id = "ext_url_period", + .name = N_("Re-fetch period (mins)"), + .desc = N_("Re-fetch the bouquet every x minutes."), + .off = offsetof(bouquet_t, bq_ext_url_period), + .opts = PO_ADVANCED | PO_HIDDEN, + .notify = bouquet_class_ext_url_notify, + .def.i = 60}, + { + .type = PT_STR, + .id = "source", + .name = N_("Source"), + .desc = N_("Bouquet source."), + .off = offsetof(bouquet_t, bq_src), + .opts = PO_RDONLY | PO_ADVANCED, + }, + { + .type = PT_STR, + .islist = 1, + .id = "services", + .name = N_("Services"), + .desc = N_("Number of services."), + .get = bouquet_class_services_get, + .set = bouquet_class_services_set, + .rend = bouquet_class_services_rend, + .opts = PO_RDONLY | PO_HIDDEN, + }, + { + .type = PT_U32, + .id = "services_seen", + .name = N_("Services seen"), + .desc = N_("Total number of services seen."), + .off = offsetof(bouquet_t, bq_services_seen), + .opts = PO_RDONLY, + }, + { + .type = PT_U32, + .id = "services_count", + .name = N_("Services"), + .desc = N_("Total number of services."), + .get = bouquet_class_services_count_get, + .opts = PO_RDONLY | PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-form text field, enter whatever you like."), + .off = offsetof(bouquet_t, bq_comment), + }, + {.type = PT_U32, + .id = "lcn_off", + .name = N_("Channel number offset"), + .desc = N_("Offset the mapped channel numbers by x " + "(value here + channel number)."), + .off = offsetof(bouquet_t, bq_lcn_offset), + .notify = bouquet_class_lcn_offset_notify, + .opts = PO_ADVANCED}, + {}}}; /** * */ -static void -bouquet_download_trigger0(void *aux) -{ - bouquet_download_t *bqd = aux; - bouquet_t *bq = bqd->bq; +static void bouquet_download_trigger0(void* aux) { + bouquet_download_t* bqd = aux; + bouquet_t* bq = bqd->bq; download_start(&bqd->download, bq->bq_ext_url, bqd); - mtimer_arm_rel(&bqd->timer, bouquet_download_trigger0, bqd, - sec2mono(MAX(1, bq->bq_ext_url_period) * 60)); + mtimer_arm_rel(&bqd->timer, + bouquet_download_trigger0, + bqd, + sec2mono(MAX(1, bq->bq_ext_url_period) * 60)); } -static void -bouquet_download_trigger(bouquet_t *bq) -{ - bouquet_download_t *bqd = bq->bq_download; +static void bouquet_download_trigger(bouquet_t* bq) { + bouquet_download_t* bqd = bq->bq_download; if (bqd) { bqd->download.ssl_peer_verify = bq->bq_ssl_peer_verify; bouquet_download_trigger0(bqd); } } -static void -bouquet_download_stop(void *aux) -{ - bouquet_download_t *bqd = aux; +static void bouquet_download_stop(void* aux) { + bouquet_download_t* bqd = aux; mtimer_disarm(&bqd->timer); } -static int -parse_enigma2(bouquet_t *bq, char *data) -{ - extern service_t *mpegts_service_find_e2(uint32_t stype, uint32_t sid, - uint32_t tsid, uint32_t onid, - uint32_t hash); - char *argv[11], *p, *tagname = NULL, *name; - uint32_t lv, stype, sid, tsid, onid, hash; - uint32_t seen = 0; - int n, ver = 2; +static int parse_enigma2(bouquet_t* bq, char* data) { + extern service_t* mpegts_service_find_e2(uint32_t stype, + uint32_t sid, + uint32_t tsid, + uint32_t onid, + uint32_t hash); + char * argv[11], *p, *tagname = NULL, *name; + uint32_t lv, stype, sid, tsid, onid, hash; + uint32_t seen = 0; + int n, ver = 2; while (*data) { if (strncmp(data, "#NAME ", 6) == 0) { - for (data += 6, p = data; *data && *data != '\r' && *data != '\n'; data++); - if (*data) { *data = '\0'; data++; } + for (data += 6, p = data; *data && *data != '\r' && *data != '\n'; data++) + ; + if (*data) { + *data = '\0'; + data++; + } if (bq->bq_name == NULL || bq->bq_name[0] == '\0') bq->bq_name = strdup(p); } else if (strncmp(data, "#SERVICE ", 9) == 0) { data += 9, p = data; -service: - while (*data && *data != '\r' && *data != '\n') data++; - if (*data) { *data = '\0'; data++; } + service: + while (*data && *data != '\r' && *data != '\n') + data++; + if (*data) { + *data = '\0'; + data++; + } n = http_tokenize(p, argv, ARRAY_SIZE(argv), ':'); if (n >= 10) { - if (strtol(argv[0], NULL, 0) != 1) goto next; /* item type */ - lv = strtol(argv[1], NULL, 16); /* service flags? */ - if (lv != 0 && lv != 0x64) goto next; - stype = strtoul(argv[2], NULL, 16); /* DVB service type */ - sid = strtoul(argv[3], NULL, 16); /* DVB service ID */ + if (strtol(argv[0], NULL, 0) != 1) + goto next; /* item type */ + lv = strtol(argv[1], NULL, 16); /* service flags? */ + if (lv != 0 && lv != 0x64) + goto next; + stype = strtoul(argv[2], NULL, 16); /* DVB service type */ + sid = strtoul(argv[3], NULL, 16); /* DVB service ID */ tsid = strtoul(argv[4], NULL, 16); onid = strtoul(argv[5], NULL, 16); hash = strtoul(argv[6], NULL, 16); name = n > 10 ? argv[10] : NULL; if (lv == 0) { - service_t *s = mpegts_service_find_e2(stype, sid, tsid, onid, hash); + service_t* s = mpegts_service_find_e2(stype, sid, tsid, onid, hash); if (s) bouquet_add_service(bq, s, ((int64_t)++seen) * CHANNEL_SPLIT, tagname); } else if (lv == 0x64) { @@ -1406,23 +1293,27 @@ service: ver = 1, data += 10, p = data; goto service; } else { - while (*data && *data != '\r' && *data != '\n') data++; + while (*data && *data != '\r' && *data != '\n') + data++; } -next: - while (*data && (*data == '\r' || *data == '\n')) data++; + next: + while (*data && (*data == '\r' || *data == '\n')) + data++; } bouquet_completed(bq, seen); tvhinfo(LS_BOUQUET, "parsed Enigma%d bouquet %s (%u services)", ver, bq->bq_name, seen); return 0; } -static int -bouquet_download_process(void *aux, const char *last_url, const char *host_url, - char *data, size_t len) -{ - bouquet_download_t *bqd = aux; +static int bouquet_download_process(void* aux, + const char* last_url, + const char* host_url, + char* data, + size_t len) { + bouquet_download_t* bqd = aux; while (*data) { - while (*data && *data < ' ') data++; + while (*data && *data < ' ') + data++; if (*data && !strncmp(data, "#NAME ", 6)) return parse_enigma2(bqd->bq, data); } @@ -1432,12 +1323,10 @@ bouquet_download_process(void *aux, const char *last_url, const char *host_url, /** * */ -void -bouquet_init(void) -{ - htsmsg_t *c, *m; - htsmsg_field_t *f; - bouquet_t *bq; +void bouquet_init(void) { + htsmsg_t * c, *m; + htsmsg_field_t* f; + bouquet_t* bq; RB_INIT(&bouquets); idclass_register(&bouquet_class); @@ -1445,7 +1334,8 @@ bouquet_init(void) /* Load */ if ((c = hts_settings_load("bouquet")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(m = htsmsg_field_get_map(f))) continue; + if (!(m = htsmsg_field_get_map(f))) + continue; bq = bouquet_create(htsmsg_field_name(f), m, NULL, NULL); if (bq) bq->bq_saveflag = 0; @@ -1463,43 +1353,40 @@ bouquet_init(void) bouquet_global_rescan_now(); } -void -bouquet_service_resolve(void) -{ - bouquet_t *bq; - htsmsg_t *e; - htsmsg_field_t *f; - service_t *s; - int64_t lcn; - const char *tag; - int saveflag; +void bouquet_service_resolve(void) { + bouquet_t* bq; + htsmsg_t* e; + htsmsg_field_t* f; + service_t* s; + int64_t lcn; + const char* tag; + int saveflag; lock_assert(&global_lock); - RB_FOREACH(bq, &bouquets, bq_link) { + RB_FOREACH (bq, &bouquets, bq_link) { if (!bq->bq_services_waiting) continue; saveflag = bq->bq_saveflag; if (bq->bq_enabled) { HTSMSG_FOREACH(f, bq->bq_services_waiting) { - if ((e = htsmsg_field_get_map(f)) == NULL) continue; + if ((e = htsmsg_field_get_map(f)) == NULL) + continue; lcn = htsmsg_get_s64_or_default(e, "lcn", 0); tag = htsmsg_get_str(e, "tag"); - s = service_find_by_uuid(htsmsg_field_name(f)); + s = service_find_by_uuid(htsmsg_field_name(f)); if (s) bouquet_add_service(bq, s, lcn, tag); } } htsmsg_destroy(bq->bq_services_waiting); bq->bq_services_waiting = NULL; - bq->bq_saveflag = saveflag; + bq->bq_saveflag = saveflag; } } -void -bouquet_done(void) -{ - bouquet_t *bq; +void bouquet_done(void) { + bouquet_t* bq; tvh_mutex_lock(&global_lock); while ((bq = RB_FIRST(&bouquets)) != NULL) diff --git a/src/bouquet.h b/src/bouquet.h index ceba6ec3d..6918808a2 100644 --- a/src/bouquet.h +++ b/src/bouquet.h @@ -28,48 +28,48 @@ typedef struct bouquet { idnode_t bq_id; RB_ENTRY(bouquet) bq_link; - int bq_saveflag; - int bq_in_load; - - int bq_shield; - int bq_enabled; - int bq_rescan; - int bq_maptoch; - int bq_mapnolcn; - int bq_mapnoname; - int bq_mapradio; - int bq_mapencrypted; - int bq_mapmergename; - int bq_mapmergefuzzy; - int bq_tidychannelname; - int bq_chtag; - int bq_chtag_type_tags; - int bq_chtag_provider_tags; - int bq_chtag_network_tags; - channel_tag_t*bq_chtag_ptr; - const char *bq_chtag_waiting; - char *bq_name; - char *bq_ext_url; - int bq_ssl_peer_verify; - int bq_ext_url_period; - char *bq_src; - char *bq_comment; - idnode_set_t *bq_services; - idnode_set_t *bq_active_services; - htsmsg_t *bq_services_waiting; - uint32_t bq_services_seen; - uint32_t bq_lcn_offset; + int bq_saveflag; + int bq_in_load; + + int bq_shield; + int bq_enabled; + int bq_rescan; + int bq_maptoch; + int bq_mapnolcn; + int bq_mapnoname; + int bq_mapradio; + int bq_mapencrypted; + int bq_mapmergename; + int bq_mapmergefuzzy; + int bq_tidychannelname; + int bq_chtag; + int bq_chtag_type_tags; + int bq_chtag_provider_tags; + int bq_chtag_network_tags; + channel_tag_t* bq_chtag_ptr; + const char* bq_chtag_waiting; + char* bq_name; + char* bq_ext_url; + int bq_ssl_peer_verify; + int bq_ext_url_period; + char* bq_src; + char* bq_comment; + idnode_set_t* bq_services; + idnode_set_t* bq_active_services; + htsmsg_t* bq_services_waiting; + uint32_t bq_services_seen; + uint32_t bq_lcn_offset; /* fastscan bouquet helpers */ - int bq_fastscan_nit; - int bq_fastscan_sdt; - void *bq_fastscan_bi; + int bq_fastscan_nit; + int bq_fastscan_sdt; + void* bq_fastscan_bi; - void *bq_download; + void* bq_download; } bouquet_t; -typedef RB_HEAD(,bouquet) bouquet_tree_t; +typedef RB_HEAD(, bouquet) bouquet_tree_t; extern bouquet_tree_t bouquets; @@ -79,33 +79,32 @@ extern const idclass_t bouquet_class; * */ -htsmsg_t * bouquet_class_get_list(void *o, const char *lang); +htsmsg_t* bouquet_class_get_list(void* o, const char* lang); -bouquet_t * bouquet_create(const char *uuid, htsmsg_t *conf, - const char *name, const char *src); +bouquet_t* bouquet_create(const char* uuid, htsmsg_t* conf, const char* name, const char* src); -void bouquet_delete(bouquet_t *bq); +void bouquet_delete(bouquet_t* bq); -void bouquet_destroy_by_service(service_t *t, int delconf); -void bouquet_destroy_by_channel_tag(channel_tag_t *ct); +void bouquet_destroy_by_service(service_t* t, int delconf); +void bouquet_destroy_by_channel_tag(channel_tag_t* ct); -void bouquet_notify_service_enabled(service_t *t); +void bouquet_notify_service_enabled(service_t* t); -static inline bouquet_t * -bouquet_find_by_uuid(const char *uuid) - { return (bouquet_t *)idnode_find(uuid, &bouquet_class, NULL); } +static inline bouquet_t* bouquet_find_by_uuid(const char* uuid) { + return (bouquet_t*)idnode_find(uuid, &bouquet_class, NULL); +} -bouquet_t * bouquet_find_by_source(const char *name, const char *src, int create); +bouquet_t* bouquet_find_by_source(const char* name, const char* src, int create); -void bouquet_map_to_channels(bouquet_t *bq); -void bouquet_notify_channels(bouquet_t *bq); -void bouquet_add_service(bouquet_t *bq, service_t *s, uint64_t lcn, const char *tag); -void bouquet_completed(bouquet_t *bq, uint32_t seen); -void bouquet_change_comment(bouquet_t *bq, const char *comment, int replace); -void bouquet_scan(bouquet_t *bq); -void bouquet_detach(channel_t *ch); +void bouquet_map_to_channels(bouquet_t* bq); +void bouquet_notify_channels(bouquet_t* bq); +void bouquet_add_service(bouquet_t* bq, service_t* s, uint64_t lcn, const char* tag); +void bouquet_completed(bouquet_t* bq, uint32_t seen); +void bouquet_change_comment(bouquet_t* bq, const char* comment, int replace); +void bouquet_scan(bouquet_t* bq); +void bouquet_detach(channel_t* ch); -uint64_t bouquet_get_channel_number(bouquet_t *bq, service_t *t); +uint64_t bouquet_get_channel_number(bouquet_t* bq, service_t* t); /** * diff --git a/src/channels.c b/src/channels.c index d06eacb23..62e9f1902 100644 --- a/src/channels.c +++ b/src/channels.c @@ -36,37 +36,31 @@ #include "intlconv.h" #include "memoryinfo.h" -typedef int (sortfcn_t)(const void *, const void *); +typedef int(sortfcn_t)(const void*, const void*); struct channel_tree channels; -int channels_count; +int channels_count; struct channel_tag_queue channel_tags; -int channel_tags_count; +int channel_tags_count; -const char *channel_blank_name = N_("{name-not-set}"); -static int channel_in_load; +const char* channel_blank_name = N_("{name-not-set}"); +static int channel_in_load; -static void channel_tag_init ( void ); -static void channel_tag_done ( void ); -static void channel_tag_mapping_destroy(idnode_list_mapping_t *ilm, void *origin); -static void channel_epg_update_all ( channel_t *ch ); +static void channel_tag_init(void); +static void channel_tag_done(void); +static void channel_tag_mapping_destroy(idnode_list_mapping_t* ilm, void* origin); +static void channel_epg_update_all(channel_t* ch); -static int -ch_id_cmp ( channel_t *a, channel_t *b ) -{ +static int ch_id_cmp(channel_t* a, channel_t* b) { return channel_get_id(a) - channel_get_id(b); } -static void -channel_load_icon ( channel_t *ch ) -{ +static void channel_load_icon(channel_t* ch) { (void)imagecache_get_id(channel_get_icon(ch)); } -static void -channel_tag_load_icon ( channel_tag_t *tag ) -{ +static void channel_tag_load_icon(channel_tag_t* tag) { (void)imagecache_get_id(channel_tag_get_icon(tag)); } @@ -74,10 +68,8 @@ channel_tag_load_icon ( channel_tag_t *tag ) * Class definition * *************************************************************************/ -static void -channel_class_changed ( idnode_t *self ) -{ - channel_t *ch = (channel_t *)self; +static void channel_class_changed(idnode_t* self) { + channel_t* ch = (channel_t*)self; if (atomic_add(&ch->ch_changed_ref, 1) > 0) goto end; @@ -95,12 +87,10 @@ end: atomic_dec(&ch->ch_changed_ref, 0); } -static htsmsg_t * -channel_class_save ( idnode_t *self, char *filename, size_t fsize ) -{ - channel_t *ch = (channel_t *)self; - htsmsg_t *c = NULL; - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* channel_class_save(idnode_t* self, char* filename, size_t fsize) { + channel_t* ch = (channel_t*)self; + htsmsg_t* c = NULL; + char ubuf[UUID_HEX_SIZE]; /* save channel (on demand) */ if (ch->ch_dont_save == 0) { tvhdebug(LS_CHANNEL, "channel '%s' save", channel_get_name(ch, channel_blank_name)); @@ -112,26 +102,20 @@ channel_class_save ( idnode_t *self, char *filename, size_t fsize ) return c; } -static void -channel_class_delete ( idnode_t *self ) -{ +static void channel_class_delete(idnode_t* self) { channel_delete((channel_t*)self, 1); } -static void -channel_class_notify_enabled ( void *obj, const char *lang ) -{ - channel_t *ch = (channel_t *)obj; +static void channel_class_notify_enabled(void* obj, const char* lang) { + channel_t* ch = (channel_t*)obj; if (!ch->ch_enabled) channel_remove_subscriber(ch, SM_CODE_CHN_NOT_ENABLED); } -static int -channel_class_autoname_set ( void *obj, const void *p ) -{ - channel_t *ch = (channel_t *)obj; - const char *s; - int b = *(int *)p; +static int channel_class_autoname_set(void* obj, const void* p) { + channel_t* ch = (channel_t*)obj; + const char* s; + int b = *(int*)p; if (ch->ch_autoname != b) { if (b == 0 && tvh_str_default(ch->ch_name, NULL) == NULL) { s = channel_get_name(ch, NULL); @@ -151,35 +135,29 @@ channel_class_autoname_set ( void *obj, const void *p ) return 0; } -static const void * -channel_class_services_get ( void *obj ) -{ - channel_t *ch = obj; +static const void* channel_class_services_get(void* obj) { + channel_t* ch = obj; return idnode_list_get2(&ch->ch_services); } -static char * -channel_class_services_rend ( void *obj, const char *lang ) -{ - channel_t *ch = obj; +static char* channel_class_services_rend(void* obj, const char* lang) { + channel_t* ch = obj; return idnode_list_get_csv2(&ch->ch_services, lang); } -static int -channel_class_services_set ( void *obj, const void *p ) -{ - channel_t *ch = obj; - return idnode_list_set2(&ch->ch_id, &ch->ch_services, - &service_class, (htsmsg_t *)p, - service_mapper_create); +static int channel_class_services_set(void* obj, const void* p) { + channel_t* ch = obj; + return idnode_list_set2(&ch->ch_id, + &ch->ch_services, + &service_class, + (htsmsg_t*)p, + service_mapper_create); } -static htsmsg_t * -channel_class_services_enum ( void *obj, const char *lang ) -{ +static htsmsg_t* channel_class_services_enum(void* obj, const char* lang) { htsmsg_t *e, *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "service/list"); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "service/list"); htsmsg_add_str(m, "event", "service"); e = htsmsg_create_map(); htsmsg_add_bool(e, "enum", 1); @@ -187,71 +165,55 @@ channel_class_services_enum ( void *obj, const char *lang ) return m; } -static const void * -channel_class_tags_get ( void *obj ) -{ - channel_t *ch = obj; +static const void* channel_class_tags_get(void* obj) { + channel_t* ch = obj; return idnode_list_get2(&ch->ch_ctms); } -static char * -channel_class_tags_rend ( void *obj, const char *lang ) -{ - channel_t *ch = obj; +static char* channel_class_tags_rend(void* obj, const char* lang) { + channel_t* ch = obj; return idnode_list_get_csv2(&ch->ch_ctms, lang); } -static int -channel_class_tags_set_cb ( idnode_t *in1, idnode_t *in2, void *origin ) -{ - return channel_tag_map((channel_tag_t *)in1, (channel_t *)in2, origin); +static int channel_class_tags_set_cb(idnode_t* in1, idnode_t* in2, void* origin) { + return channel_tag_map((channel_tag_t*)in1, (channel_t*)in2, origin); } -static int -channel_class_tags_set ( void *obj, const void *p ) -{ - channel_t *ch = obj; - return idnode_list_set2(&ch->ch_id, &ch->ch_ctms, - &channel_tag_class, (htsmsg_t *)p, - channel_class_tags_set_cb); +static int channel_class_tags_set(void* obj, const void* p) { + channel_t* ch = obj; + return idnode_list_set2(&ch->ch_id, + &ch->ch_ctms, + &channel_tag_class, + (htsmsg_t*)p, + channel_class_tags_set_cb); } -static void -channel_class_icon_notify ( void *obj, const char *lang ) -{ - channel_t *ch = obj; +static void channel_class_icon_notify(void* obj, const char* lang) { + channel_t* ch = obj; if (!ch->ch_load) channel_load_icon(obj); } -const void * -channel_class_get_icon ( void *obj ) -{ +const void* channel_class_get_icon(void* obj) { prop_ptr = channel_get_icon(obj); if (!strempty(prop_ptr)) prop_ptr = imagecache_get_propstr(prop_ptr, prop_sbuf, PROP_SBUF_LEN); return &prop_ptr; } -static void -channel_class_get_title - ( idnode_t *self, const char *lang, char *dst, size_t dstsize ) -{ - const char *s = channel_get_name((channel_t*)self, - tvh_gettext_lang(lang, channel_blank_name)); +static void channel_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + const char* s = channel_get_name((channel_t*)self, tvh_gettext_lang(lang, channel_blank_name)); snprintf(dst, dstsize, "%s", s); } /* exported for others */ -htsmsg_t * -channel_class_get_list(void *o, const char *lang) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_t *p = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "channel/list"); +htsmsg_t* channel_class_get_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_t* p = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "channel/list"); htsmsg_add_str(m, "event", "channel"); - htsmsg_add_u32(p, "all", 1); + htsmsg_add_u32(p, "all", 1); if (config.chname_num) htsmsg_add_u32(p, "numbers", 1); if (config.chname_src) @@ -260,11 +222,9 @@ channel_class_get_list(void *o, const char *lang) return m; } -static int -channel_class_set_name ( void *o, const void *p ) -{ - channel_t *ch = o; - const char *s = p; +static int channel_class_set_name(void* o, const void* p) { + channel_t* ch = o; + const char* s = p; if (ch->ch_load) ch->ch_autoname = p == NULL || *s == 0; if (strcmp(s ?: "", ch->ch_name ?: "")) { @@ -275,43 +235,35 @@ channel_class_set_name ( void *o, const void *p ) return 0; } -static const void * -channel_class_get_name ( void *o ) -{ +static const void* channel_class_get_name(void* o) { prop_ptr = channel_get_name(o, channel_blank_name); return &prop_ptr; } -static const void * -channel_class_get_number ( void *o ) -{ +static const void* channel_class_get_number(void* o) { static int64_t i; i = channel_get_number(o); return &i; } -static const void * -channel_class_epggrab_get ( void *o ) -{ - channel_t *ch = o; +static const void* channel_class_epggrab_get(void* o) { + channel_t* ch = o; return idnode_list_get2(&ch->ch_epggrab); } -static int -channel_class_epggrab_set ( void *o, const void *v ) -{ - channel_t *ch = o; - return idnode_list_set2(&ch->ch_id, &ch->ch_epggrab, - &epggrab_channel_class, (htsmsg_t *)v, - epggrab_channel_map); +static int channel_class_epggrab_set(void* o, const void* v) { + channel_t* ch = o; + return idnode_list_set2(&ch->ch_id, + &ch->ch_epggrab, + &epggrab_channel_class, + (htsmsg_t*)v, + epggrab_channel_map); } -static htsmsg_t * -channel_class_epggrab_list ( void *o, const char *lang ) -{ +static htsmsg_t* channel_class_epggrab_list(void* o, const char* lang) { htsmsg_t *e, *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "epggrab/channel/list"); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "epggrab/channel/list"); htsmsg_add_str(m, "event", "epggrab_channel"); e = htsmsg_create_map(); htsmsg_add_bool(e, "enum", 1); @@ -319,10 +271,8 @@ channel_class_epggrab_list ( void *o, const char *lang ) return m; } -static const void * -channel_class_bouquet_get ( void *o ) -{ - channel_t *ch = o; +static const void* channel_class_bouquet_get(void* o) { + channel_t* ch = o; if (ch->ch_bouquet) idnode_uuid_as_str(&ch->ch_bouquet->bq_id, prop_sbuf); else @@ -330,11 +280,9 @@ channel_class_bouquet_get ( void *o ) return &prop_sbuf_ptr; } -static int -channel_class_bouquet_set ( void *o, const void *v ) -{ - channel_t *ch = o; - bouquet_t *bq = bouquet_find_by_uuid(v); +static int channel_class_bouquet_set(void* o, const void* v) { + channel_t* ch = o; + bouquet_t* bq = bouquet_find_by_uuid(v); if (bq == NULL && ch->ch_bouquet) { ch->ch_bouquet = NULL; return 1; @@ -345,12 +293,9 @@ channel_class_bouquet_set ( void *o, const void *v ) return 0; } -static int -channel_class_epg_parent_set_noupdate - ( void *o, const void *v, channel_t **parent ) -{ - channel_t *ch = o; - const char *uuid = v; +static int channel_class_epg_parent_set_noupdate(void* o, const void* v, channel_t** parent) { + channel_t* ch = o; + const char* uuid = v; if (strcmp(v ?: "", ch->ch_epg_parent ?: "")) { if (ch->ch_epg_parent) { LIST_REMOVE(ch, ch_epg_slave_link); @@ -374,23 +319,19 @@ channel_class_epg_parent_set_noupdate return 0; } -static int -channel_class_epg_parent_set ( void *o, const void *v ) -{ - channel_t *parent = NULL; - int save = channel_class_epg_parent_set_noupdate(o, v, &parent); +static int channel_class_epg_parent_set(void* o, const void* v) { + channel_t* parent = NULL; + int save = channel_class_epg_parent_set_noupdate(o, v, &parent); if (parent) channel_epg_update_all(parent); return save; } -static htsmsg_t * -channel_class_epg_running_list ( void *o, const char *lang ) -{ +static htsmsg_t* channel_class_epg_running_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Not set"), -1 }, - { N_("Disabled"), 0 }, - { N_("Enabled"), 1 }, + {N_("Not set"), -1}, + {N_("Disabled"), 0}, + {N_("Enabled"), 1}, }; return strtab2htsmsg(tab, 1, lang); } @@ -398,207 +339,195 @@ channel_class_epg_running_list ( void *o, const char *lang ) CLASS_DOC(channel) PROP_DOC(runningstate) -const idclass_t channel_class = { - .ic_class = "channel", - .ic_caption = N_("Channels / EPG - Channels"), - .ic_doc = tvh_doc_channel_class, - .ic_event = "channel", - .ic_changed = channel_class_changed, - .ic_save = channel_class_save, - .ic_get_title = channel_class_get_title, - .ic_delete = channel_class_delete, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable the channel."), - .def.i = 1, - .off = offsetof(channel_t, ch_enabled), - .notify = channel_class_notify_enabled, - }, - { - .type = PT_BOOL, - .id = "autoname", - .name = N_("Automatically name from network"), - .desc = N_("Always use the name defined by the network."), - .off = offsetof(channel_t, ch_autoname), - .set = channel_class_autoname_set, - .opts = PO_ADVANCED | PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "name", - .name = N_("Name"), - .desc = N_("The name given to/of the channel (This is " - "how it'll appear in your EPG.)"), - .off = offsetof(channel_t, ch_name), - .set = channel_class_set_name, - .get = channel_class_get_name, - .notify = channel_class_icon_notify, /* try to re-render default icon path */ - }, - { - .type = PT_S64, - .intextra = CHANNEL_SPLIT, - .id = "number", - .name = N_("Number"), - .desc = N_("The position the channel will appear on " - "your EPG. This is not used by Tvheadend " - "internally, but rather intended to be used by " - "HTSP clients for mapping to remote control " - "buttons, presentation order, etc."), - .off = offsetof(channel_t, ch_number), - .get = channel_class_get_number, - }, - { - .type = PT_STR, - .id = "icon", - .name = N_("User icon"), - .desc = N_("The URL to the icon to use/used for the channel. " - "The local files are referred using file:/// URLs."), - .off = offsetof(channel_t, ch_icon), - .notify = channel_class_icon_notify, - .opts = PO_ADVANCED, - }, - { - .type = PT_STR, - .id = "icon_public_url", - .name = N_("Icon URL"), - .desc = N_("The imagecache path to the icon to use/used " - "for the channel."), - .get = channel_class_get_icon, - .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_EXPERT, - }, - { - .type = PT_BOOL, - .id = "epgauto", - .name = N_("Automatically map EPG source"), - .desc = N_("Automatically link EPG data to the channel " - "(using the channel name for matching). If you " - "turn this option off, only the OTA EPG grabber " - "will be used for this channel unless you've " - "specifically set a different EPG Source."), - .def.i = 1, - .off = offsetof(channel_t, ch_epgauto), - .opts = PO_ADVANCED, - }, - { - .type = PT_U32, - .id = "epglimit", - .name = N_("Limit EPG (days)"), - .desc = N_("Limit EPG data to specified days to reduce " - "the memory consumption. The zero value means " - "unlimited EPG."), - .def.i = 1, - .off = offsetof(channel_t, ch_epg_limit), - .opts = PO_ADVANCED, - }, - { - .type = PT_STR, - .islist = 1, - .id = "epggrab", - .name = N_("EPG source"), - .desc = N_("Name of the module, grabber or channel " - "that should be used to update this channels " - "EPG info."), - .set = channel_class_epggrab_set, - .get = channel_class_epggrab_get, - .list = channel_class_epggrab_list, - .opts = PO_NOSAVE | PO_ADVANCED, - }, - { - .type = PT_INT, - .id = "dvr_pre_time", - .name = N_("Pre-recording padding"), // TODO: better text? - .desc = N_("Start recording earlier " - "than the EPG/timer defined " - "start time by x minutes, for example if a program " - "is to start at 13:00 and you set a padding of 5 " - "minutes it will start recording at 12:54:30 " - "(including a warming-up time of 30 seconds). If this " - "isn't set the pre-recording padding if set in the " - "DVR entry or DVR profile will be used."), - .off = offsetof(channel_t, ch_dvr_extra_time_pre), - .opts = PO_ADVANCED - }, - { - .type = PT_INT, - .id = "dvr_pst_time", - .name = N_("Post-recording padding"), // TODO: better text? - .desc = N_("Continue recording for x " - "minutes after scheduled stop time."), - .off = offsetof(channel_t, ch_dvr_extra_time_post), - .opts = PO_ADVANCED - }, - { - .type = PT_INT, - .id = "epg_running", - .name = N_("Use EPG running state"), - .desc = N_("Use EITp/f to decide " - "event start/stop. This is also known as " - "\"Accurate Recording\". See Help for details."), - .doc = prop_doc_runningstate, - .off = offsetof(channel_t, ch_epg_running), - .list = channel_class_epg_running_list, - .opts = PO_EXPERT | PO_DOC_NLIST, - }, +const idclass_t channel_class = {.ic_class = "channel", + .ic_caption = N_("Channels / EPG - Channels"), + .ic_doc = tvh_doc_channel_class, + .ic_event = "channel", + .ic_changed = channel_class_changed, + .ic_save = channel_class_save, + .ic_get_title = channel_class_get_title, + .ic_delete = channel_class_delete, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable the channel."), + .def.i = 1, + .off = offsetof(channel_t, ch_enabled), + .notify = channel_class_notify_enabled, + }, + { + .type = PT_BOOL, + .id = "autoname", + .name = N_("Automatically name from network"), + .desc = N_("Always use the name defined by the network."), + .off = offsetof(channel_t, ch_autoname), + .set = channel_class_autoname_set, + .opts = PO_ADVANCED | PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "name", + .name = N_("Name"), + .desc = N_("The name given to/of the channel (This is " + "how it'll appear in your EPG.)"), + .off = offsetof(channel_t, ch_name), + .set = channel_class_set_name, + .get = channel_class_get_name, + .notify = channel_class_icon_notify, /* try to re-render default icon path */ + }, + { + .type = PT_S64, + .intextra = CHANNEL_SPLIT, + .id = "number", + .name = N_("Number"), + .desc = N_("The position the channel will appear on " + "your EPG. This is not used by Tvheadend " + "internally, but rather intended to be used by " + "HTSP clients for mapping to remote control " + "buttons, presentation order, etc."), + .off = offsetof(channel_t, ch_number), + .get = channel_class_get_number, + }, + { + .type = PT_STR, + .id = "icon", + .name = N_("User icon"), + .desc = N_("The URL to the icon to use/used for the channel. " + "The local files are referred using file:/// URLs."), + .off = offsetof(channel_t, ch_icon), + .notify = channel_class_icon_notify, + .opts = PO_ADVANCED, + }, + { + .type = PT_STR, + .id = "icon_public_url", + .name = N_("Icon URL"), + .desc = N_("The imagecache path to the icon to use/used " + "for the channel."), + .get = channel_class_get_icon, + .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_EXPERT, + }, + { + .type = PT_BOOL, + .id = "epgauto", + .name = N_("Automatically map EPG source"), + .desc = N_("Automatically link EPG data to the channel " + "(using the channel name for matching). If you " + "turn this option off, only the OTA EPG grabber " + "will be used for this channel unless you've " + "specifically set a different EPG Source."), + .def.i = 1, + .off = offsetof(channel_t, ch_epgauto), + .opts = PO_ADVANCED, + }, + { + .type = PT_U32, + .id = "epglimit", + .name = N_("Limit EPG (days)"), + .desc = N_("Limit EPG data to specified days to reduce " + "the memory consumption. The zero value means " + "unlimited EPG."), + .def.i = 1, + .off = offsetof(channel_t, ch_epg_limit), + .opts = PO_ADVANCED, + }, + { + .type = PT_STR, + .islist = 1, + .id = "epggrab", + .name = N_("EPG source"), + .desc = N_("Name of the module, grabber or channel " + "that should be used to update this channels " + "EPG info."), + .set = channel_class_epggrab_set, + .get = channel_class_epggrab_get, + .list = channel_class_epggrab_list, + .opts = PO_NOSAVE | PO_ADVANCED, + }, + {.type = PT_INT, + .id = "dvr_pre_time", + .name = N_("Pre-recording padding"), // TODO: better text? + .desc = N_("Start recording earlier " + "than the EPG/timer defined " + "start time by x minutes, for example if a program " + "is to start at 13:00 and you set a padding of 5 " + "minutes it will start recording at 12:54:30 " + "(including a warming-up time of 30 seconds). If this " + "isn't set the pre-recording padding if set in the " + "DVR entry or DVR profile will be used."), + .off = offsetof(channel_t, ch_dvr_extra_time_pre), + .opts = PO_ADVANCED}, + {.type = PT_INT, + .id = "dvr_pst_time", + .name = N_("Post-recording padding"), // TODO: better text? + .desc = N_("Continue recording for x " + "minutes after scheduled stop time."), + .off = offsetof(channel_t, ch_dvr_extra_time_post), + .opts = PO_ADVANCED}, + { + .type = PT_INT, + .id = "epg_running", + .name = N_("Use EPG running state"), + .desc = N_("Use EITp/f to decide " + "event start/stop. This is also known as " + "\"Accurate Recording\". See Help for details."), + .doc = prop_doc_runningstate, + .off = offsetof(channel_t, ch_epg_running), + .list = channel_class_epg_running_list, + .opts = PO_EXPERT | PO_DOC_NLIST, + }, #if ENABLE_TIMESHIFT - { - .type = PT_BOOL, - .id = "remote_timeshift", - .name = N_("Remote timeshift"), - .desc = N_("Pass timeshift commands to a remote RTSP server"), - .off = offsetof(channel_t, ch_remote_timeshift), - .opts = PO_ADVANCED, - }, + { + .type = PT_BOOL, + .id = "remote_timeshift", + .name = N_("Remote timeshift"), + .desc = N_("Pass timeshift commands to a remote RTSP server"), + .off = offsetof(channel_t, ch_remote_timeshift), + .opts = PO_ADVANCED, + }, #endif - { - .type = PT_STR, - .islist = 1, - .id = "services", - .name = N_("Services"), - .desc = N_("Services associated with the channel."), - .get = channel_class_services_get, - .set = channel_class_services_set, - .list = channel_class_services_enum, - .rend = channel_class_services_rend, - }, - { - .type = PT_STR, - .islist = 1, - .id = "tags", - .name = N_("Tags"), - .desc = N_("Tags linked/to link to the channel."), - .get = channel_class_tags_get, - .set = channel_class_tags_set, - .list = channel_tag_class_get_list, - .rend = channel_class_tags_rend, - }, - { - .type = PT_STR, - .id = "bouquet", - .name = N_("Bouquet (auto)"), - .desc = N_("The bouquet the channel is " - "associated with."), - .get = channel_class_bouquet_get, - .set = channel_class_bouquet_set, - .list = bouquet_class_get_list, - .opts = PO_RDONLY | PO_ADVANCED - }, - { - .type = PT_STR, - .id = "epg_parent", - .name = N_("Reuse EPG from"), - .desc = N_("Reuse the EPG from another " - "channel."), - .set = channel_class_epg_parent_set, - .list = channel_class_get_list, - .off = offsetof(channel_t, ch_epg_parent), - .opts = PO_EXPERT - }, - {} - } -}; + { + .type = PT_STR, + .islist = 1, + .id = "services", + .name = N_("Services"), + .desc = N_("Services associated with the channel."), + .get = channel_class_services_get, + .set = channel_class_services_set, + .list = channel_class_services_enum, + .rend = channel_class_services_rend, + }, + { + .type = PT_STR, + .islist = 1, + .id = "tags", + .name = N_("Tags"), + .desc = N_("Tags linked/to link to the channel."), + .get = channel_class_tags_get, + .set = channel_class_tags_set, + .list = channel_tag_class_get_list, + .rend = channel_class_tags_rend, + }, + {.type = PT_STR, + .id = "bouquet", + .name = N_("Bouquet (auto)"), + .desc = N_("The bouquet the channel is " + "associated with."), + .get = channel_class_bouquet_get, + .set = channel_class_bouquet_set, + .list = bouquet_class_get_list, + .opts = PO_RDONLY | PO_ADVANCED}, + {.type = PT_STR, + .id = "epg_parent", + .name = N_("Reuse EPG from"), + .desc = N_("Reuse the EPG from another " + "channel."), + .set = channel_class_epg_parent_set, + .list = channel_class_get_list, + .off = offsetof(channel_t, ch_epg_parent), + .opts = PO_EXPERT}, + {}}}; /* ************************************************************************** * Find @@ -606,50 +535,49 @@ const idclass_t channel_class = { // Note: since channel names are no longer unique this method will simply // return the first entry encountered, so could be somewhat random -channel_t * -channel_find_by_name_and_bouquet ( const char *name, const struct bouquet *bq ) -{ - channel_t *ch; - const char *s; +channel_t* channel_find_by_name_and_bouquet(const char* name, const struct bouquet* bq) { + channel_t* ch; + const char* s; if (name == NULL) return NULL; CHANNEL_FOREACH(ch) { - if (!ch->ch_enabled) continue; + if (!ch->ch_enabled) + continue; s = channel_get_name(ch, NULL); - if (s == NULL) continue; - if (bq && ch->ch_bouquet != bq) continue; - if (strcmp(s, name) == 0) break; + if (s == NULL) + continue; + if (bq && ch->ch_bouquet != bq) + continue; + if (strcmp(s, name) == 0) + break; } return ch; } -channel_t * -channel_find_by_name(const char *name) -{ +channel_t* channel_find_by_name(const char* name) { return channel_find_by_name_and_bouquet(name, NULL); } /// Copy name without space and (U)HD suffix, lowercase in to a new /// buffer -static char * -channel_make_fuzzy_name(const char *name) -{ - if (!name) return NULL; - const size_t len = strlen(name); - char *fuzzy_name = malloc(len + 1); - char *ch_fuzzy = fuzzy_name; - const char *ch = name; - - for (; *ch ; ++ch) { +static char* channel_make_fuzzy_name(const char* name) { + if (!name) + return NULL; + const size_t len = strlen(name); + char* fuzzy_name = malloc(len + 1); + char* ch_fuzzy = fuzzy_name; + const char* ch = name; + + for (; *ch; ++ch) { /* Strip trailing 'HD'. */ - if (*ch == 'H' && *(ch+1) == 'D' && *(ch+2) == 0) + if (*ch == 'H' && *(ch + 1) == 'D' && *(ch + 2) == 0) break; /* Strip trailing 'UHD'. */ - if (*ch == 'U' && *(ch+1) == 'H' && *(ch+2) == 'D' && *(ch+3) == 0) + if (*ch == 'U' && *(ch + 1) == 'H' && *(ch + 2) == 'D' && *(ch + 3) == 0) break; /* Strip trailing 'FHD'. */ - if (*ch == 'F' && *(ch+1) == 'H' && *(ch+2) == 'D' && *(ch+3) == 0) + if (*ch == 'F' && *(ch + 1) == 'H' && *(ch + 2) == 'D' && *(ch + 3) == 0) break; if (!isspace(*ch)) { @@ -661,91 +589,88 @@ channel_make_fuzzy_name(const char *name) return fuzzy_name; } -channel_t * -channel_find_by_name_bouquet_fuzzy ( const char *name, const struct bouquet *bq ) -{ - channel_t *ch; - const char *s; +channel_t* channel_find_by_name_bouquet_fuzzy(const char* name, const struct bouquet* bq) { + channel_t* ch; + const char* s; if (name == NULL) return NULL; - char *fuzzy_name = channel_make_fuzzy_name(name); + char* fuzzy_name = channel_make_fuzzy_name(name); CHANNEL_FOREACH(ch) { - if (!ch->ch_enabled) continue; - if (bq && ch->ch_bouquet != bq) continue; + if (!ch->ch_enabled) + continue; + if (bq && ch->ch_bouquet != bq) + continue; s = channel_get_name(ch, NULL); - if (s == NULL) continue; + if (s == NULL) + continue; /* We need case insensitive since historical constraints means we * often have channels with slightly different case on DVB-T vs * DVB-S such as 'One' and 'ONE'. */ - if (strcasecmp(s, name) == 0) break; - if (strcasecmp(s, fuzzy_name) == 0) break; + if (strcasecmp(s, name) == 0) + break; + if (strcasecmp(s, fuzzy_name) == 0) + break; /* If here, we don't have an obvious match, so we need to fixup * the ch name to see if it then matches. We can use strcmp * since both names are already lowercased. */ - char *s_fuzzy_name = channel_make_fuzzy_name(s); - const int is_match = !strcmp(s_fuzzy_name, fuzzy_name); + char* s_fuzzy_name = channel_make_fuzzy_name(s); + const int is_match = !strcmp(s_fuzzy_name, fuzzy_name); free(s_fuzzy_name); - if (is_match) break; + if (is_match) + break; } free(fuzzy_name); return ch; } -channel_t * -channel_find_by_id ( uint32_t i ) -{ +channel_t* channel_find_by_id(uint32_t i) { channel_t skel; memcpy(skel.ch_id.in_uuid.bin, &i, sizeof(i)); return RB_FIND(&channels, &skel, ch_link, ch_id_cmp); } -channel_t * -channel_find_by_number ( const char *no ) -{ - channel_t *ch; - uint32_t maj, min = 0; - uint64_t cno; - char *s; +channel_t* channel_find_by_number(const char* no) { + channel_t* ch; + uint32_t maj, min = 0; + uint64_t cno; + char* s; if (no == NULL) return NULL; if ((s = strchr(no, '.')) != NULL) { - *s = '\0'; + *s = '\0'; min = atoi(s + 1); } maj = atoi(no); cno = (uint64_t)maj * CHANNEL_SPLIT + (uint64_t)min; CHANNEL_FOREACH(ch) - if(channel_get_number(ch) == cno) - break; + if (channel_get_number(ch) == cno) + break; return ch; } /** * Check if user can access the channel */ -int -channel_access(channel_t *ch, access_t *a, int disabled) -{ - char ubuf[UUID_HEX_SIZE]; - idnode_list_mapping_t *ilm; - htsmsg_field_t *f; +int channel_access(channel_t* ch, access_t* a, int disabled) { + char ubuf[UUID_HEX_SIZE]; + idnode_list_mapping_t* ilm; + htsmsg_field_t* f; if (!a) return 0; if (!ch) { /* If user has full rights, allow access to removed chanels */ - if (a->aa_chrange == NULL && a->aa_chtags == NULL && - a->aa_chtags_exclude == NULL) + if (a->aa_chrange == NULL && a->aa_chtags == NULL && a->aa_chtags_exclude == NULL) return 1; return 0; } @@ -756,26 +681,24 @@ channel_access(channel_t *ch, access_t *a, int disabled) /* Channel number check */ if (a->aa_chrange) { int64_t chnum = channel_get_number(ch); - int i; + int i; for (i = 0; i < a->aa_chrange_count; i += 2) - if (chnum < a->aa_chrange[i] || chnum > a->aa_chrange[i+1]) + if (chnum < a->aa_chrange[i] || chnum > a->aa_chrange[i + 1]) return 0; } /* Channel tag check */ if (a->aa_chtags_exclude) { HTSMSG_FOREACH(f, a->aa_chtags_exclude) - LIST_FOREACH(ilm, &ch->ch_ctms, ilm_in2_link) - if (!strcmp(htsmsg_field_get_str(f) ?: "", - idnode_uuid_as_str(ilm->ilm_in1, ubuf))) - return 0; + LIST_FOREACH (ilm, &ch->ch_ctms, ilm_in2_link) + if (!strcmp(htsmsg_field_get_str(f) ?: "", idnode_uuid_as_str(ilm->ilm_in1, ubuf))) + return 0; } if (a->aa_chtags) { HTSMSG_FOREACH(f, a->aa_chtags) - LIST_FOREACH(ilm, &ch->ch_ctms, ilm_in2_link) - if (!strcmp(htsmsg_field_get_str(f) ?: "", - idnode_uuid_as_str(ilm->ilm_in1, ubuf))) - return 1; + LIST_FOREACH (ilm, &ch->ch_ctms, ilm_in2_link) + if (!strcmp(htsmsg_field_get_str(f) ?: "", idnode_uuid_as_str(ilm->ilm_in1, ubuf))) + return 1; return 0; } return 1; @@ -784,42 +707,36 @@ channel_access(channel_t *ch, access_t *a, int disabled) /** * */ -void -channel_event_updated ( epg_broadcast_t *e ) -{ - channel_t *ch; - int save; +void channel_event_updated(epg_broadcast_t* e) { + channel_t* ch; + int save; - LIST_FOREACH(ch, &e->channel->ch_epg_slaves, ch_epg_slave_link) + LIST_FOREACH (ch, &e->channel->ch_epg_slaves, ch_epg_slave_link) epg_broadcast_clone(ch, e, &save); } /** * */ -static void -channel_epg_update_all ( channel_t *ch ) -{ - epg_broadcast_t *e; +static void channel_epg_update_all(channel_t* ch) { + epg_broadcast_t* e; - RB_FOREACH(e, &ch->ch_epg_schedule, sched_link) - channel_event_updated(e); + RB_FOREACH (e, &ch->ch_epg_schedule, sched_link) + channel_event_updated(e); } /** * Remove all subscribers for given channel */ -void channel_remove_subscriber - ( channel_t *ch, int reason ) -{ - th_subscription_t *s, *s_next; - idnode_list_mapping_t *ilm; - service_t *t; +void channel_remove_subscriber(channel_t* ch, int reason) { + th_subscription_t * s, *s_next; + idnode_list_mapping_t* ilm; + service_t* t; lock_assert(&global_lock); - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - t = (service_t *)ilm->ilm_in1; + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + t = (service_t*)ilm->ilm_in1; for (s = LIST_FIRST(&t->s_subscriptions); s; s = s_next) { s_next = LIST_NEXT(s, ths_service_link); if (s->ths_channel == ch) @@ -832,35 +749,33 @@ void channel_remove_subscriber * Property updating * *************************************************************************/ -const char * -channel_get_name ( const channel_t *ch, const char *blank ) -{ - const char *s; - const idnode_list_mapping_t *ilm; - if (ch->ch_name && *ch->ch_name) return ch->ch_name; - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) - if ((s = service_get_channel_name((service_t *)ilm->ilm_in1))) +const char* channel_get_name(const channel_t* ch, const char* blank) { + const char* s; + const idnode_list_mapping_t* ilm; + if (ch->ch_name && *ch->ch_name) + return ch->ch_name; + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) + if ((s = service_get_channel_name((service_t*)ilm->ilm_in1))) return s; return blank; } -char * -channel_get_ename - ( channel_t *ch, char *dst, size_t dstlen, const char *blank, uint32_t flags ) -{ - size_t l = 0; - int64_t number; - char buf[128]; - const char *s; +char* channel_get_ename(channel_t* ch, + char* dst, + size_t dstlen, + const char* blank, + uint32_t flags) { + size_t l = 0; + int64_t number; + char buf[128]; + const char* s; dst[0] = '\0'; if (flags & CHANNEL_ENAME_NUMBERS) { number = channel_get_number(ch); if (number > 0) { if (number % CHANNEL_SPLIT) { - tvh_strlcatf(dst, dstlen, l, "%u.%u", - channel_get_major(number), - channel_get_minor(number)); + tvh_strlcatf(dst, dstlen, l, "%u.%u", channel_get_major(number), channel_get_minor(number)); } else { tvh_strlcatf(dst, dstlen, l, "%u", channel_get_major(number)); } @@ -877,33 +792,33 @@ channel_get_ename return dst; } -int -channel_set_name ( channel_t *ch, const char *name ) -{ +int channel_set_name(channel_t* ch, const char* name) { int save = 0; - if (!ch || !name) return 0; - if (!ch->ch_name || strcmp(ch->ch_name, name) ) { - if (ch->ch_name) free(ch->ch_name); + if (!ch || !name) + return 0; + if (!ch->ch_name || strcmp(ch->ch_name, name)) { + if (ch->ch_name) + free(ch->ch_name); ch->ch_name = strdup(name); - save = 1; + save = 1; } return save; } -int -channel_rename_and_save ( const char *from, const char *to ) -{ - channel_t *ch; - const char *s; - int num_match = 0; +int channel_rename_and_save(const char* from, const char* to) { + channel_t* ch; + const char* s; + int num_match = 0; if (!from || !to || !*from || !*to) return 0; CHANNEL_FOREACH(ch) { - if (!ch->ch_enabled) continue; + if (!ch->ch_enabled) + continue; s = channel_get_name(ch, NULL); - if (s == NULL) continue; + if (s == NULL) + continue; if (strcmp(s, from) == 0) { ++num_match; if (channel_set_name(ch, to)) { @@ -914,24 +829,22 @@ channel_rename_and_save ( const char *from, const char *to ) return num_match; } -int64_t -channel_get_number ( const channel_t *ch ) -{ - int64_t n = 0, v; - idnode_list_mapping_t *ilm; +int64_t channel_get_number(const channel_t* ch) { + int64_t n = 0, v; + idnode_list_mapping_t* ilm; if (ch->ch_number) { n = ch->ch_number; } else { if (ch->ch_bouquet) { - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - v = bouquet_get_channel_number(ch->ch_bouquet, (service_t *)ilm->ilm_in1); + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + v = bouquet_get_channel_number(ch->ch_bouquet, (service_t*)ilm->ilm_in1); if (v > 0 && (n == 0 || v < n)) n = v; } } if (n == 0) { - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - v = service_get_channel_number((service_t *)ilm->ilm_in1); + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + v = service_get_channel_number((service_t*)ilm->ilm_in1); if (v > 0 && (n == 0 || v < n)) n = v; } @@ -945,25 +858,23 @@ channel_get_number ( const channel_t *ch ) return 0; } -int -channel_set_number ( channel_t *ch, uint32_t major, uint32_t minor ) -{ - int save = 0; +int channel_set_number(channel_t* ch, uint32_t major, uint32_t minor) { + int save = 0; int64_t chnum = (uint64_t)major * CHANNEL_SPLIT + (uint64_t)minor; - if (!ch || !chnum) return 0; + if (!ch || !chnum) + return 0; if (!ch->ch_number || ch->ch_number != chnum) { ch->ch_number = chnum; - save = 1; + save = 1; } return save; } -char * -channel_get_number_as_str ( channel_t *ch, char *dst, size_t dstlen ) -{ - int64_t num = channel_get_number(ch); +char* channel_get_number_as_str(channel_t* ch, char* dst, size_t dstlen) { + int64_t num = channel_get_number(ch); uint32_t major, minor; - if (num == 0) return NULL; + if (num == 0) + return NULL; major = channel_get_major(num); minor = channel_get_minor(num); if (minor) @@ -973,26 +884,22 @@ channel_get_number_as_str ( channel_t *ch, char *dst, size_t dstlen ) return dst; } -int64_t -channel_get_number_from_str ( const char *str ) -{ +int64_t channel_get_number_from_str(const char* str) { return prop_intsplit_from_str(str, CHANNEL_SPLIT); } -char * -channel_get_source ( channel_t *ch, char *dst, size_t dstlen ) -{ - const char *s; - idnode_list_mapping_t *ilm; +char* channel_get_source(channel_t* ch, char* dst, size_t dstlen) { + const char* s; + idnode_list_mapping_t* ilm; /* Unique sorted string list since many services with * same source may be mapped so we want to avoid * 'DVB-S, DVB-S, DVB-S'. */ - string_list_t *sources = string_list_create(); - char *csv; + string_list_t* sources = string_list_create(); + char* csv; dst[0] = '\0'; - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) - if ((s = service_get_source((service_t *)ilm->ilm_in1))) + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) + if ((s = service_get_source((service_t*)ilm->ilm_in1))) string_list_insert(sources, s); /* We own the returned list */ csv = string_list_2_csv(sources, ',', 1); @@ -1006,13 +913,11 @@ channel_get_source ( channel_t *ch, char *dst, size_t dstlen ) } } -static char * -svcnamepicons(const char *svcname) -{ - const char *s; - char *r, *d; - int count; - char c; +static char* svcnamepicons(const char* svcname) { + const char* s; + char * r, *d; + int count; + char c; for (s = svcname, count = 0; *s; s++) { c = *s; @@ -1023,11 +928,22 @@ svcnamepicons(const char *svcname) for (s = svcname; *s; s++) { c = *s; if (c == '&') { - d[0] = 'a'; d[1] = 'n'; d[2] = 'd'; d += 3; + d[0] = 'a'; + d[1] = 'n'; + d[2] = 'd'; + d += 3; } else if (c == '+') { - d[0] = 'p'; d[1] = 'l'; d[2] = 'u'; d[3] = 's'; d += 4; + d[0] = 'p'; + d[1] = 'l'; + d[2] = 'u'; + d[3] = 's'; + d += 4; } else if (c == '*') { - d[0] = 's'; d[1] = 't'; d[2] = 'a'; d[3] = 'r'; d += 4; + d[0] = 's'; + d[1] = 't'; + d[2] = 'a'; + d[3] = 'r'; + d += 4; } else { if (c >= 'a' && c <= 'z') *d++ = c; @@ -1041,27 +957,21 @@ svcnamepicons(const char *svcname) return r; } -static int -check_file( const char *url ) -{ +static int check_file(const char* url) { if (url && !strncmp(url, "file://", 7)) { - char *s = tvh_strdupa(url + 7); + char* s = tvh_strdupa(url + 7); http_deescape(s); return access(s, R_OK) == 0; } return 1; } -const char * -channel_get_icon ( channel_t *ch ) -{ - static char buf[512], buf2[512]; - idnode_list_mapping_t *ilm; - const char *chicon = config.chicon_path, - *picon = config.picon_path, - *icon = ch->ch_icon, - *chname, *icn; - int i, pick, prefer = config.prefer_picon ? 1 : 0; +const char* channel_get_icon(channel_t* ch) { + static char buf[512], buf2[512]; + idnode_list_mapping_t* ilm; + const char *chicon = config.chicon_path, *picon = config.picon_path, *icon = ch->ch_icon, *chname, + *icn; + int i, pick, prefer = config.prefer_picon ? 1 : 0; char c; if (tvh_str_default(icon, NULL) == NULL) @@ -1071,9 +981,11 @@ channel_get_icon ( channel_t *ch ) * Initial lookup - for services with predefined icons (like M3U sources) */ if (icon == NULL) { - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - if (!(icn = service_get_channel_icon((service_t *)ilm->ilm_in1))) continue; - if (strncmp(icn, "picon://", 8) == 0) continue; + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + if (!(icn = service_get_channel_icon((service_t*)ilm->ilm_in1))) + continue; + if (strncmp(icn, "picon://", 8) == 0) + continue; if (check_file(icn)) { icon = ch->ch_icon = strdup(icn); idnode_changed(&ch->ch_id); @@ -1099,24 +1011,24 @@ channel_get_icon ( channel_t *ch ) /* Check for and replace placeholders */ if ((send = strstr(chi, "%C")) || (send = strstr(chi, "%c"))) { - sname = intlconv_utf8safestr(intlconv_charset_id("ASCII", 1, 1), - chname, strlen(chname) * 2); + sname = + intlconv_utf8safestr(intlconv_charset_id("ASCII", 1, 1), chname, strlen(chname) * 2); if (sname == NULL) sname = strdup(chname); /* Remove problematic characters */ if (config.chicon_scheme == CHICON_SVCNAME) { s = svcnamepicons(sname); - free((char *)sname); + free((char*)sname); sname = s; } else { s = sname; while (s && *s) { c = *s; if (send[1] == 'C' && (c > 122 || strchr(":<>|*?'\"", c) != NULL)) - *(char *)s = '_'; + *(char*)s = '_'; else if (config.chicon_scheme == CHICON_LOWERCASE && c >= 'A' && c <= 'Z') - *(char *)s = c - 'A' + 'a'; + *(char*)s = c - 'A' + 'a'; s++; } } @@ -1124,44 +1036,44 @@ channel_get_icon ( channel_t *ch ) sname = strdup(chname); if (config.chicon_scheme == CHICON_LOWERCASE) { - utf8_lowercase_inplace((char *)sname); + utf8_lowercase_inplace((char*)sname); } else if (config.chicon_scheme == CHICON_SVCNAME) { s = svcnamepicons(sname); - free((char *)sname); - sname = (char *)s; + free((char*)sname); + sname = (char*)s; } } else { buf[0] = '\0'; - sname = NULL; + sname = NULL; } if (send) { - *(char *)send = '\0'; - send = url_encode(send + 2); + *(char*)send = '\0'; + send = url_encode(send + 2); } if (sname) { - char *aname; + char* aname; for (s = sname; *s == '.'; s++) - *(char *)s = '_'; + *(char*)s = '_'; - for ( ; *s; s++) + for (; *s; s++) if (*s == '/' || *s == '\\') - *(char *)s = '-'; + *(char*)s = '-'; else if (*s < ' ') - *(char *)s = '_'; + *(char*)s = '_'; aname = url_encode(sname); - free((char *)sname); + free((char*)sname); sname = aname; } snprintf(buf, sizeof(buf), "%s%s%s", chi, sname ?: "", send ?: ""); - free((char *)sname); - free((char *)send); - free((char *)chi); + free((char*)sname); + free((char*)send); + free((char*)chi); if (i > 1 || check_file(buf)) { icon = ch->ch_icon = strdup(buf); @@ -1171,11 +1083,12 @@ channel_get_icon ( channel_t *ch ) /* No user icon - try access from services */ if (pick && picon) { - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - if (!(icn = service_get_channel_icon((service_t *)ilm->ilm_in1))) continue; + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + if (!(icn = service_get_channel_icon((service_t*)ilm->ilm_in1))) + continue; if (strncmp(icn, "picon://", 8)) continue; - snprintf(buf2, sizeof(buf2), "%s/%s", picon, icn+8); + snprintf(buf2, sizeof(buf2), "%s/%s", picon, icn + 8); if (i > 1 || check_file(buf2)) { icon = ch->ch_icon = strdup(icn); idnode_changed(&ch->ch_id); @@ -1183,7 +1096,6 @@ channel_get_icon ( channel_t *ch ) } } } - } found: @@ -1194,33 +1106,33 @@ found: /* Picon? */ if (!strncmp(icon, "picon://", 8)) { - if (!picon) return NULL; - sprintf(buf2, "%s/%s", picon, icon+8); + if (!picon) + return NULL; + sprintf(buf2, "%s/%s", picon, icon + 8); icon = buf2; } return icon; } -int channel_set_icon ( channel_t *ch, const char *icon ) -{ +int channel_set_icon(channel_t* ch, const char* icon) { int save = 0; - if (!ch || !icon) return 0; + if (!ch || !icon) + return 0; if (!ch->ch_icon || strcmp(ch->ch_icon, icon)) { - if (ch->ch_icon) free(ch->ch_icon); + if (ch->ch_icon) + free(ch->ch_icon); ch->ch_icon = strdup(icon); - save = 1; + save = 1; } return save; } -const char * -channel_get_epgid ( channel_t *ch ) -{ - const char *s; - idnode_list_mapping_t *ilm; - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) - if ((s = service_get_channel_epgid((service_t *)ilm->ilm_in1))) +const char* channel_get_epgid(channel_t* ch) { + const char* s; + idnode_list_mapping_t* ilm; + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) + if ((s = service_get_channel_epgid((service_t*)ilm->ilm_in1))) return s; return channel_get_name(ch, NULL); } @@ -1229,11 +1141,11 @@ channel_get_epgid ( channel_t *ch ) * Creation/Deletion * *************************************************************************/ -channel_t * -channel_create0 - ( channel_t *ch, const idclass_t *idc, const char *uuid, htsmsg_t *conf, - const char *name ) -{ +channel_t* channel_create0(channel_t* ch, + const idclass_t* idc, + const char* uuid, + htsmsg_t* conf, + const char* name) { lock_assert(&global_lock); LIST_INIT(&ch->ch_services); @@ -1255,9 +1167,9 @@ channel_create0 channels_count++; /* Defaults */ - ch->ch_enabled = 1; - ch->ch_autoname = 1; - ch->ch_epgauto = 1; + ch->ch_enabled = 1; + ch->ch_autoname = 1; + ch->ch_epgauto = 1; ch->ch_epg_running = -1; atomic_set(&ch->ch_changed_ref, 0); @@ -1286,13 +1198,11 @@ channel_create0 return ch; } -void -channel_delete ( channel_t *ch, int delconf ) -{ - th_subscription_t *s; - idnode_list_mapping_t *ilm; - channel_t *ch1, *ch2; - char ubuf[UUID_HEX_SIZE]; +void channel_delete(channel_t* ch, int delconf) { + th_subscription_t* s; + idnode_list_mapping_t* ilm; + channel_t * ch1, *ch2; + char ubuf[UUID_HEX_SIZE]; lock_assert(&global_lock); @@ -1302,7 +1212,7 @@ channel_delete ( channel_t *ch, int delconf ) tvhinfo(LS_CHANNEL, "%s - deleting", channel_get_name(ch, channel_blank_name)); /* Tags */ - while((ilm = LIST_FIRST(&ch->ch_ctms)) != NULL) + while ((ilm = LIST_FIRST(&ch->ch_ctms)) != NULL) channel_tag_mapping_destroy(ilm, delconf ? ch : NULL); /* DVR */ @@ -1311,11 +1221,11 @@ channel_delete ( channel_t *ch, int delconf ) dvr_destroy_by_channel(ch, delconf); /* Services */ - while((ilm = LIST_FIRST(&ch->ch_services)) != NULL) + while ((ilm = LIST_FIRST(&ch->ch_services)) != NULL) idnode_list_unlink(ilm, delconf ? ch : NULL); /* Subscriptions */ - while((s = LIST_FIRST(&ch->ch_subscriptions)) != NULL) { + while ((s = LIST_FIRST(&ch->ch_subscriptions)) != NULL) { LIST_REMOVE(s, ths_channel_link); s->ths_channel = NULL; } @@ -1358,12 +1268,10 @@ channel_delete ( channel_t *ch, int delconf ) /** * sorting */ -static int -channel_cmp1(const void *a, const void *b) -{ - int r; - channel_t *c1 = *(channel_t **)a, *c2 = *(channel_t **)b; - int64_t n1 = channel_get_number(c1), n2 = channel_get_number(c2); +static int channel_cmp1(const void* a, const void* b) { + int r; + channel_t *c1 = *(channel_t**)a, *c2 = *(channel_t**)b; + int64_t n1 = channel_get_number(c1), n2 = channel_get_number(c2); if (n1 > n2) r = 1; else if (n1 < n2) @@ -1373,15 +1281,12 @@ channel_cmp1(const void *a, const void *b) return r; } -static int -channel_cmp2(const void *a, const void *b) -{ - channel_t *c1 = *(channel_t **)a, *c2 = *(channel_t **)b; +static int channel_cmp2(const void* a, const void* b) { + channel_t *c1 = *(channel_t**)a, *c2 = *(channel_t**)b; return strcasecmp(channel_get_name(c1, ""), channel_get_name(c2, "")); } -static sortfcn_t *channel_sort_fcn(const char *sort_type) -{ +static sortfcn_t* channel_sort_fcn(const char* sort_type) { if (sort_type) { if (!strcmp(sort_type, "numname")) return &channel_cmp1; @@ -1391,39 +1296,35 @@ static sortfcn_t *channel_sort_fcn(const char *sort_type) return &channel_cmp1; } -channel_t ** -channel_get_sorted_list(const char *sort_type, int all, int *_count) -{ - int count = 0; - channel_t *ch, **chlist = malloc(channels_count * sizeof(channel_t *)); +channel_t** channel_get_sorted_list(const char* sort_type, int all, int* _count) { + int count = 0; + channel_t *ch, **chlist = malloc(channels_count * sizeof(channel_t*)); CHANNEL_FOREACH(ch) - if (all || ch->ch_enabled) - chlist[count++] = ch; + if (all || ch->ch_enabled) + chlist[count++] = ch; assert(count <= channels_count); - qsort(chlist, count, sizeof(channel_t *), channel_sort_fcn(sort_type)); + qsort(chlist, count, sizeof(channel_t*), channel_sort_fcn(sort_type)); *_count = count; return chlist; } -channel_t ** -channel_get_sorted_list_for_tag - (const char *sort_type, channel_tag_t *tag, int *_count) -{ - int count = 0; - channel_t *ch, **chlist = malloc(channels_count * sizeof(channel_t *)); - idnode_list_mapping_t *ilm; +channel_t** +channel_get_sorted_list_for_tag(const char* sort_type, channel_tag_t* tag, int* _count) { + int count = 0; + channel_t * ch, **chlist = malloc(channels_count * sizeof(channel_t*)); + idnode_list_mapping_t* ilm; - LIST_FOREACH(ilm, &tag->ct_ctms, ilm_in1_link) { - ch = (channel_t *)ilm->ilm_in2; + LIST_FOREACH (ilm, &tag->ct_ctms, ilm_in1_link) { + ch = (channel_t*)ilm->ilm_in2; if (ch->ch_enabled) chlist[count++] = ch; } assert(count <= channels_count); - qsort(chlist, count, sizeof(channel_t *), channel_sort_fcn(sort_type)); + qsort(chlist, count, sizeof(channel_t*), channel_sort_fcn(sort_type)); *_count = count; return chlist; @@ -1432,10 +1333,9 @@ channel_get_sorted_list_for_tag /** * */ -static void channels_memoryinfo_update(memoryinfo_t *my) -{ - channel_t *ch; - int64_t size = 0, count = 0; +static void channels_memoryinfo_update(memoryinfo_t* my) { + channel_t* ch; + int64_t size = 0, count = 0; lock_assert(&global_lock); CHANNEL_FOREACH(ch) { @@ -1448,21 +1348,17 @@ static void channels_memoryinfo_update(memoryinfo_t *my) memoryinfo_update(my, size, count); } -static memoryinfo_t channels_memoryinfo = { - .my_name = "Channels", - .my_update = channels_memoryinfo_update -}; +static memoryinfo_t channels_memoryinfo = {.my_name = "Channels", + .my_update = channels_memoryinfo_update}; /** * */ -void -channel_init ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - channel_t *ch, *parent; - char *s; +void channel_init(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + channel_t * ch, *parent; + char* s; channels_count = 0; RB_INIT(&channels); @@ -1479,7 +1375,8 @@ channel_init ( void ) channel_in_load = 1; HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; (void)channel_create(htsmsg_field_name(f), e, NULL); } channel_in_load = 0; @@ -1487,22 +1384,20 @@ channel_init ( void ) /* Pair slave EPG, set parent again without channel_in_load */ CHANNEL_FOREACH(ch) - if ((s = ch->ch_epg_parent) != NULL) { - ch->ch_epg_parent = NULL; - channel_class_epg_parent_set_noupdate(ch, s, &parent); - free(s); - } + if ((s = ch->ch_epg_parent) != NULL) { + ch->ch_epg_parent = NULL; + channel_class_epg_parent_set_noupdate(ch, s, &parent); + free(s); + } CHANNEL_FOREACH(ch) - channel_epg_update_all(ch); + channel_epg_update_all(ch); } /** * */ -void -channel_done ( void ) -{ - channel_t *ch; +void channel_done(void) { + channel_t* ch; tvh_mutex_lock(&global_lock); while ((ch = RB_FIRST(&channels)) != NULL) @@ -1519,19 +1414,15 @@ channel_done ( void ) /** * */ -int -channel_tag_map(channel_tag_t *ct, channel_t *ch, void *origin) -{ - idnode_list_mapping_t *ilm; +int channel_tag_map(channel_tag_t* ct, channel_t* ch, void* origin) { + idnode_list_mapping_t* ilm; if (ct == NULL || ch == NULL) return 0; - ilm = idnode_list_link(&ct->ct_id, &ct->ct_ctms, - &ch->ch_id, &ch->ch_ctms, - origin, 2); + ilm = idnode_list_link(&ct->ct_id, &ct->ct_ctms, &ch->ch_id, &ch->ch_ctms, origin, 2); if (ilm) { - if(ct->ct_enabled && !ct->ct_internal) { + if (ct->ct_enabled && !ct->ct_internal) { htsp_tag_update(ct); htsp_channel_update(ch); } @@ -1540,22 +1431,19 @@ channel_tag_map(channel_tag_t *ct, channel_t *ch, void *origin) return 0; } - /** * */ -static void -channel_tag_mapping_destroy(idnode_list_mapping_t *ilm, void *origin) -{ - channel_tag_t *ct = (channel_tag_t *)ilm->ilm_in1; - channel_t *ch = (channel_t *)ilm->ilm_in2; +static void channel_tag_mapping_destroy(idnode_list_mapping_t* ilm, void* origin) { + channel_tag_t* ct = (channel_tag_t*)ilm->ilm_in1; + channel_t* ch = (channel_t*)ilm->ilm_in2; idnode_list_unlink(ilm, origin); - if(ct->ct_enabled && !ct->ct_internal) { - if(origin == ch) + if (ct->ct_enabled && !ct->ct_internal) { + if (origin == ch) htsp_tag_update(ct); - if(origin == ct) + if (origin == ct) htsp_channel_update(ch); } } @@ -1563,14 +1451,12 @@ channel_tag_mapping_destroy(idnode_list_mapping_t *ilm, void *origin) /** * */ -void -channel_tag_unmap(channel_t *ch, void *origin) -{ +void channel_tag_unmap(channel_t* ch, void* origin) { idnode_list_mapping_t *ilm, *n; for (ilm = LIST_FIRST(&ch->ch_ctms); ilm != NULL; ilm = n) { n = LIST_NEXT(ilm, ilm_in2_link); - if ((channel_t *)ilm->ilm_in2 == ch) { + if ((channel_t*)ilm->ilm_in2 == ch) { channel_tag_mapping_destroy(ilm, origin); return; } @@ -1580,10 +1466,8 @@ channel_tag_unmap(channel_t *ch, void *origin) /** * */ -channel_tag_t * -channel_tag_create(const char *uuid, htsmsg_t *conf) -{ - channel_tag_t *ct; +channel_tag_t* channel_tag_create(const char* uuid, htsmsg_t* conf) { + channel_tag_t* ct; ct = calloc(1, sizeof(channel_tag_t)); LIST_INIT(&ct->ct_ctms); @@ -1619,15 +1503,13 @@ channel_tag_create(const char *uuid, htsmsg_t *conf) /** * */ -static void -channel_tag_destroy(channel_tag_t *ct, int delconf) -{ - idnode_list_mapping_t *ilm; - char ubuf[UUID_HEX_SIZE]; +static void channel_tag_destroy(channel_tag_t* ct, int delconf) { + idnode_list_mapping_t* ilm; + char ubuf[UUID_HEX_SIZE]; idnode_save_check(&ct->ct_id, delconf); - while((ilm = LIST_FIRST(&ct->ct_ctms)) != NULL) + while ((ilm = LIST_FIRST(&ct->ct_ctms)) != NULL) channel_tag_mapping_destroy(ilm, delconf ? ilm->ilm_in1 : NULL); if (delconf) @@ -1653,21 +1535,17 @@ channel_tag_destroy(channel_tag_t *ct, int delconf) /** * */ -const char * -channel_tag_get_icon(channel_tag_t *ct) -{ +const char* channel_tag_get_icon(channel_tag_t* ct) { return ct->ct_icon; } /** * Check if user can access the channel tag */ -int -channel_tag_access(channel_tag_t *ct, access_t *a, int disabled) -{ - htsmsg_field_t *f; - char ubuf[UUID_HEX_SIZE]; - const char *uuid = idnode_uuid_as_str(&ct->ct_id, ubuf); +int channel_tag_access(channel_tag_t* ct, access_t* a, int disabled) { + htsmsg_field_t* f; + char ubuf[UUID_HEX_SIZE]; + const char* uuid = idnode_uuid_as_str(&ct->ct_id, ubuf); if (!ct) return 0; @@ -1681,13 +1559,13 @@ channel_tag_access(channel_tag_t *ct, access_t *a, int disabled) /* Channel tag check */ if (a->aa_chtags_exclude) { HTSMSG_FOREACH(f, a->aa_chtags_exclude) - if (!strcmp(htsmsg_field_get_str(f) ?: "", uuid)) - return 0; + if (!strcmp(htsmsg_field_get_str(f) ?: "", uuid)) + return 0; } if (a->aa_chtags) { HTSMSG_FOREACH(f, a->aa_chtags) - if (!strcmp(htsmsg_field_get_str(f) ?: "", uuid)) - return 1; + if (!strcmp(htsmsg_field_get_str(f) ?: "", uuid)) + return 1; return 0; } return 1; @@ -1697,48 +1575,36 @@ channel_tag_access(channel_tag_t *ct, access_t *a, int disabled) * Channel Tag Class definition * **************************************************************************/ -static void -channel_tag_class_changed(idnode_t *self) -{ +static void channel_tag_class_changed(idnode_t* self) { /* HTSP */ - htsp_tag_update((channel_tag_t *)self); + htsp_tag_update((channel_tag_t*)self); } -static htsmsg_t * -channel_tag_class_save(idnode_t *self, char *filename, size_t fsize) -{ - channel_tag_t *ct = (channel_tag_t *)self; - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* channel_tag_class_save(idnode_t* self, char* filename, size_t fsize) { + channel_tag_t* ct = (channel_tag_t*)self; + htsmsg_t* c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(&ct->ct_id, c); if (filename) snprintf(filename, fsize, "channel/tag/%s", idnode_uuid_as_str(&ct->ct_id, ubuf)); return c; } -static void -channel_tag_class_delete(idnode_t *self) -{ - channel_tag_destroy((channel_tag_t *)self, 1); +static void channel_tag_class_delete(idnode_t* self) { + channel_tag_destroy((channel_tag_t*)self, 1); } static void -channel_tag_class_get_title - (idnode_t *self, const char *lang, char *dst, size_t dstsize) -{ - channel_tag_t *ct = (channel_tag_t *)self; +channel_tag_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + channel_tag_t* ct = (channel_tag_t*)self; snprintf(dst, dstsize, "%s", ct->ct_name ?: ""); } -static void -channel_tag_class_icon_notify ( void *obj, const char *lang ) -{ +static void channel_tag_class_icon_notify(void* obj, const char* lang) { channel_tag_load_icon(obj); } -static const void * -channel_tag_class_get_icon ( void *obj ) -{ +static const void* channel_tag_class_get_icon(void* obj) { prop_ptr = channel_tag_get_icon(obj); if (!strempty(prop_ptr)) prop_ptr = imagecache_get_propstr(prop_ptr, prop_sbuf, PROP_SBUF_LEN); @@ -1746,129 +1612,113 @@ channel_tag_class_get_icon ( void *obj ) } /* exported for others */ -htsmsg_t * -channel_tag_class_get_list(void *o, const char *lang) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_t *p = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "channeltag/list"); +htsmsg_t* channel_tag_class_get_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_t* p = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "channeltag/list"); htsmsg_add_str(m, "event", "channeltag"); - htsmsg_add_u32(p, "all", 1); + htsmsg_add_u32(p, "all", 1); htsmsg_add_msg(m, "params", p); return m; } CLASS_DOC(channeltag) -const idclass_t channel_tag_class = { - .ic_class = "channeltag", - .ic_caption = N_("Channels / EPG - Channel Tags"), - .ic_doc = tvh_doc_channeltag_class, - .ic_event = "channeltag", - .ic_changed = channel_tag_class_changed, - .ic_save = channel_tag_class_save, - .ic_get_title = channel_tag_class_get_title, - .ic_delete = channel_tag_class_delete, - .ic_properties = (const property_t[]) { - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable the tag."), - .def.i = 1, - .off = offsetof(channel_tag_t, ct_enabled), - }, - { - .type = PT_U32, - .id = "index", - .name = N_("Sort index"), - .desc = N_("Sort index."), - .off = offsetof(channel_tag_t, ct_index), - .opts = PO_ADVANCED, - }, - { - .type = PT_STR, - .id = "name", - .name = N_("Name"), - .desc = N_("Name of the tag."), - .off = offsetof(channel_tag_t, ct_name), - }, - { - .type = PT_BOOL, - .id = "internal", - .name = N_("Internal"), - .desc = N_("Use tag internally (don't expose to clients)."), - .off = offsetof(channel_tag_t, ct_internal), - .opts = PO_ADVANCED - }, - { - .type = PT_BOOL, - .id = "private", - .name = N_("Private"), - .desc = N_("Only allow users with this tag (or those with " - "no tags at all) set in " - "access configuration to use the tag."), - .off = offsetof(channel_tag_t, ct_private), - .opts = PO_EXPERT - }, - { - .type = PT_STR, - .id = "icon", - .name = N_("Icon (full URL)"), - .desc = N_("Full path to an icon used to depict the tag. " - "This can be a TV network logotype, etc."), - .off = offsetof(channel_tag_t, ct_icon), - .notify = channel_tag_class_icon_notify, - .opts = PO_ADVANCED - }, - { - .type = PT_STR, - .id = "icon_public_url", - .name = N_("Icon URL"), - .desc = N_("Relative path to the imagecache copy of the icon."), - .get = channel_tag_class_get_icon, - .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_EXPERT, - }, - { - .type = PT_BOOL, - .id = "titled_icon", - .name = N_("Icon has title"), - .desc = N_("If set, presentation of the tag icon will not " - "superimpose the tag name on top of the icon."), - .off = offsetof(channel_tag_t, ct_titled_icon), - .opts = PO_EXPERT - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-form text field, enter whatever you like here."), - .off = offsetof(channel_tag_t, ct_comment), - }, - {} - } -}; +const idclass_t channel_tag_class = {.ic_class = "channeltag", + .ic_caption = N_("Channels / EPG - Channel Tags"), + .ic_doc = tvh_doc_channeltag_class, + .ic_event = "channeltag", + .ic_changed = channel_tag_class_changed, + .ic_save = channel_tag_class_save, + .ic_get_title = channel_tag_class_get_title, + .ic_delete = channel_tag_class_delete, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable the tag."), + .def.i = 1, + .off = offsetof(channel_tag_t, ct_enabled), + }, + { + .type = PT_U32, + .id = "index", + .name = N_("Sort index"), + .desc = N_("Sort index."), + .off = offsetof(channel_tag_t, ct_index), + .opts = PO_ADVANCED, + }, + { + .type = PT_STR, + .id = "name", + .name = N_("Name"), + .desc = N_("Name of the tag."), + .off = offsetof(channel_tag_t, ct_name), + }, + {.type = PT_BOOL, + .id = "internal", + .name = N_("Internal"), + .desc = N_("Use tag internally (don't expose to clients)."), + .off = offsetof(channel_tag_t, ct_internal), + .opts = PO_ADVANCED}, + {.type = PT_BOOL, + .id = "private", + .name = N_("Private"), + .desc = N_("Only allow users with this tag (or those with " + "no tags at all) set in " + "access configuration to use the tag."), + .off = offsetof(channel_tag_t, ct_private), + .opts = PO_EXPERT}, + {.type = PT_STR, + .id = "icon", + .name = N_("Icon (full URL)"), + .desc = N_("Full path to an icon used to depict the tag. " + "This can be a TV network logotype, etc."), + .off = offsetof(channel_tag_t, ct_icon), + .notify = channel_tag_class_icon_notify, + .opts = PO_ADVANCED}, + { + .type = PT_STR, + .id = "icon_public_url", + .name = N_("Icon URL"), + .desc = N_("Relative path to the imagecache copy of the icon."), + .get = channel_tag_class_get_icon, + .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_EXPERT, + }, + {.type = PT_BOOL, + .id = "titled_icon", + .name = N_("Icon has title"), + .desc = N_("If set, presentation of the tag icon will not " + "superimpose the tag name on top of the icon."), + .off = offsetof(channel_tag_t, ct_titled_icon), + .opts = PO_EXPERT}, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-form text field, enter whatever you like here."), + .off = offsetof(channel_tag_t, ct_comment), + }, + {}}}; /** * */ -channel_tag_t * -channel_tag_find_by_name(const char *name, int create) -{ - channel_tag_t *ct; +channel_tag_t* channel_tag_find_by_name(const char* name, int create) { + channel_tag_t* ct; if (tvh_str_default(name, NULL) == NULL) return NULL; - TAILQ_FOREACH(ct, &channel_tags, ct_link) - if(!strcasecmp(ct->ct_name, name)) + TAILQ_FOREACH (ct, &channel_tags, ct_link) + if (!strcasecmp(ct->ct_name, name)) return ct; - if(!create) + if (!create) return NULL; - ct = channel_tag_create(NULL, NULL); + ct = channel_tag_create(NULL, NULL); ct->ct_enabled = 1; tvh_str_update(&ct->ct_name, name); @@ -1879,12 +1729,11 @@ channel_tag_find_by_name(const char *name, int create) /** * */ -channel_tag_t * -channel_tag_find_by_id(uint32_t id) { - channel_tag_t *ct; +channel_tag_t* channel_tag_find_by_id(uint32_t id) { + channel_tag_t* ct; - TAILQ_FOREACH(ct, &channel_tags, ct_link) { - if(idnode_get_short_uuid(&ct->ct_id) == id) + TAILQ_FOREACH (ct, &channel_tags, ct_link) { + if (idnode_get_short_uuid(&ct->ct_id) == id) return ct; } @@ -1894,25 +1743,20 @@ channel_tag_find_by_id(uint32_t id) { /** * */ -static int -channel_tag_cmp1(const void *a, const void *b) -{ - channel_tag_t *ct1 = *(channel_tag_t **)a, *ct2 = *(channel_tag_t **)b; - int r = ct1->ct_index - ct2->ct_index; +static int channel_tag_cmp1(const void* a, const void* b) { + channel_tag_t *ct1 = *(channel_tag_t**)a, *ct2 = *(channel_tag_t**)b; + int r = ct1->ct_index - ct2->ct_index; if (r == 0) r = strcasecmp(ct1->ct_name, ct2->ct_name); return r; } -static int -channel_tag_cmp2(const void *a, const void *b) -{ - channel_tag_t *ct1 = *(channel_tag_t **)a, *ct2 = *(channel_tag_t **)b; +static int channel_tag_cmp2(const void* a, const void* b) { + channel_tag_t *ct1 = *(channel_tag_t**)a, *ct2 = *(channel_tag_t**)b; return strcasecmp(ct1->ct_name, ct2->ct_name); } -static sortfcn_t *channel_tag_sort_fcn(const char *sort_type) -{ +static sortfcn_t* channel_tag_sort_fcn(const char* sort_type) { if (sort_type) { if (!strcmp(sort_type, "idxname")) return &channel_tag_cmp1; @@ -1922,20 +1766,18 @@ static sortfcn_t *channel_tag_sort_fcn(const char *sort_type) return &channel_tag_cmp1; } -channel_tag_t ** -channel_tag_get_sorted_list(const char *sort_type, int *_count) -{ - int count = 0; +channel_tag_t** channel_tag_get_sorted_list(const char* sort_type, int* _count) { + int count = 0; channel_tag_t *ct, **ctlist; - ctlist = malloc(channel_tags_count * sizeof(channel_tag_t *)); + ctlist = malloc(channel_tags_count * sizeof(channel_tag_t*)); - TAILQ_FOREACH(ct, &channel_tags, ct_link) - if(ct->ct_enabled && !ct->ct_internal) + TAILQ_FOREACH (ct, &channel_tags, ct_link) + if (ct->ct_enabled && !ct->ct_internal) ctlist[count++] = ct; assert(count <= channel_tags_count); - qsort(ctlist, count, sizeof(channel_tag_t *), channel_tag_sort_fcn(sort_type)); + qsort(ctlist, count, sizeof(channel_tag_t*), channel_tag_sort_fcn(sort_type)); *_count = count; return ctlist; @@ -1943,13 +1785,12 @@ channel_tag_get_sorted_list(const char *sort_type, int *_count) /** * */ -static void channel_tags_memoryinfo_update(memoryinfo_t *my) -{ - channel_tag_t *ct; - int64_t size = 0, count = 0; +static void channel_tags_memoryinfo_update(memoryinfo_t* my) { + channel_tag_t* ct; + int64_t size = 0, count = 0; lock_assert(&global_lock); - TAILQ_FOREACH(ct, &channel_tags, ct_link) { + TAILQ_FOREACH (ct, &channel_tags, ct_link) { size += sizeof(*ct); size += tvh_strlen(ct->ct_name); size += tvh_strlen(ct->ct_comment); @@ -1959,37 +1800,32 @@ static void channel_tags_memoryinfo_update(memoryinfo_t *my) memoryinfo_update(my, size, count); } -static memoryinfo_t channel_tags_memoryinfo = { - .my_name = "Channel tags", - .my_update = channel_tags_memoryinfo_update -}; +static memoryinfo_t channel_tags_memoryinfo = {.my_name = "Channel tags", + .my_update = channel_tags_memoryinfo_update}; /** * Init / Done */ -static void -channel_tag_init ( void ) -{ - htsmsg_t *c, *m; - htsmsg_field_t *f; +static void channel_tag_init(void) { + htsmsg_t * c, *m; + htsmsg_field_t* f; memoryinfo_register(&channel_tags_memoryinfo); channel_tags_count = 0; TAILQ_INIT(&channel_tags); if ((c = hts_settings_load("channel/tag")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(m = htsmsg_field_get_map(f))) continue; + if (!(m = htsmsg_field_get_map(f))) + continue; (void)channel_tag_create(htsmsg_field_name(f), m); } htsmsg_destroy(c); } } -static void -channel_tag_done ( void ) -{ - channel_tag_t *ct; +static void channel_tag_done(void) { + channel_tag_t* ct; tvh_mutex_lock(&global_lock); while ((ct = TAILQ_FIRST(&channel_tags)) != NULL) @@ -1997,15 +1833,13 @@ channel_tag_done ( void ) tvh_mutex_unlock(&global_lock); } -int -channel_has_correct_service_filter(const channel_t *ch, int svf) -{ - const idnode_list_mapping_t *ilm; - const service_t *service; +int channel_has_correct_service_filter(const channel_t* ch, int svf) { + const idnode_list_mapping_t* ilm; + const service_t* service; if (!ch || !svf || svf == PROFILE_SVF_NONE) return 1; - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { service = (const service_t*)ilm->ilm_in1; if ((svf == PROFILE_SVF_SD && service_is_sdtv(service)) || (svf == PROFILE_SVF_HD && service_is_hdtv(service)) || diff --git a/src/channels.h b/src/channels.h index 268e2fa81..1910f6213 100644 --- a/src/channels.h +++ b/src/channels.h @@ -34,13 +34,12 @@ extern int channel_tags_count; extern struct channel_tree channels; extern int channels_count; -#define CHANNEL_FOREACH(ch) RB_FOREACH(ch, &channels, ch_link) +#define CHANNEL_FOREACH(ch) RB_FOREACH (ch, &channels, ch_link) /* * Channel definition - */ -typedef struct channel -{ + */ +typedef struct channel { idnode_t ch_id; RB_ENTRY(channel) ch_link; @@ -51,45 +50,44 @@ typedef struct channel int ch_changed_ref; /* Channel info */ - int ch_enabled; - int ch_autoname; - char *ch_name; /* Note: do not access directly! */ - int64_t ch_number; - char *ch_icon; + int ch_enabled; + int ch_autoname; + char* ch_name; /* Note: do not access directly! */ + int64_t ch_number; + char* ch_icon; idnode_list_head_t ch_ctms; - struct bouquet *ch_bouquet; + struct bouquet* ch_bouquet; /* Service/subscriptions */ - idnode_list_head_t ch_services; + idnode_list_head_t ch_services; LIST_HEAD(, th_subscription) ch_subscriptions; /* EPG fields */ - char *ch_epg_parent; - LIST_HEAD(, channel) ch_epg_slaves; - LIST_ENTRY(channel) ch_epg_slave_link; - epg_broadcast_tree_t ch_epg_schedule; - epg_broadcast_t *ch_epg_now; - epg_broadcast_t *ch_epg_next; - gtimer_t ch_epg_timer; - gtimer_t ch_epg_timer_head; - gtimer_t ch_epg_timer_current; - uint32_t ch_epg_limit; - - int ch_epgauto; - idnode_list_head_t ch_epggrab; /* 1 = epggrab channel, 2 = channel */ + char* ch_epg_parent; + LIST_HEAD(, channel) ch_epg_slaves; + LIST_ENTRY(channel) ch_epg_slave_link; + epg_broadcast_tree_t ch_epg_schedule; + epg_broadcast_t* ch_epg_now; + epg_broadcast_t* ch_epg_next; + gtimer_t ch_epg_timer; + gtimer_t ch_epg_timer_head; + gtimer_t ch_epg_timer_current; + uint32_t ch_epg_limit; + + int ch_epgauto; + idnode_list_head_t ch_epggrab; /* 1 = epggrab channel, 2 = channel */ /* DVR */ - int ch_dvr_extra_time_pre; - int ch_dvr_extra_time_post; - int ch_epg_running; - int ch_remote_timeshift; - LIST_HEAD(, dvr_entry) ch_dvrs; + int ch_dvr_extra_time_pre; + int ch_dvr_extra_time_post; + int ch_epg_running; + int ch_remote_timeshift; + LIST_HEAD(, dvr_entry) ch_dvrs; LIST_HEAD(, dvr_autorec_entry) ch_autorecs; LIST_HEAD(, dvr_timerec_entry) ch_timerecs; } channel_t; - /** * Channel tag */ @@ -99,14 +97,14 @@ typedef struct channel_tag { TAILQ_ENTRY(channel_tag) ct_link; - int ct_enabled; + int ct_enabled; uint32_t ct_index; - int ct_internal; - int ct_private; - int ct_titled_icon; - char *ct_name; - char *ct_comment; - char *ct_icon; + int ct_internal; + int ct_private; + int ct_titled_icon; + char* ct_name; + char* ct_comment; + char* ct_icon; idnode_list_head_t ct_ctms; @@ -120,23 +118,25 @@ typedef struct channel_tag { extern const idclass_t channel_class; extern const idclass_t channel_tag_class; -extern const char *channel_blank_name; +extern const char* channel_blank_name; void channel_init(void); void channel_done(void); -channel_t *channel_create0 - (channel_t *ch, const idclass_t *idc, const char *uuid, htsmsg_t *conf, - const char *name); -#define channel_create(u, c, n)\ +channel_t* channel_create0(channel_t* ch, + const idclass_t* idc, + const char* uuid, + htsmsg_t* conf, + const char* name); +#define channel_create(u, c, n) \ channel_create0(calloc(1, sizeof(channel_t)), &channel_class, u, c, n) -void channel_delete(channel_t *ch, int delconf); +void channel_delete(channel_t* ch, int delconf); -void channel_remove_subscriber(channel_t *ch, int reason); +void channel_remove_subscriber(channel_t* ch, int reason); -channel_t *channel_find_by_name_and_bouquet(const char *name, const struct bouquet *bq); -channel_t *channel_find_by_name(const char *name); +channel_t* channel_find_by_name_and_bouquet(const char* name, const struct bouquet* bq); +channel_t* channel_find_by_name(const char* name); /// Apply fuzzy matching when finding a channel such as ignoring /// whitespace, case, and stripping HD suffix. This means that /// 'Channel 5+1', 'Channel 5 +1', 'Channel 5+1HD' and @@ -144,85 +144,85 @@ channel_t *channel_find_by_name(const char *name); /// Since channel names aren't unique, this returns the /// first match (similar to channel_find_by_name). /// @param bouquet - Bouquet to use: can be NULL -channel_t *channel_find_by_name_bouquet_fuzzy(const char *name, const struct bouquet *bq); -#define channel_find_by_uuid(u)\ - (channel_t*)idnode_find(u, &channel_class, NULL) +channel_t* channel_find_by_name_bouquet_fuzzy(const char* name, const struct bouquet* bq); +#define channel_find_by_uuid(u) (channel_t*)idnode_find(u, &channel_class, NULL) -channel_t *channel_find_by_id(uint32_t id); +channel_t* channel_find_by_id(uint32_t id); -channel_t *channel_find_by_number(const char *no); +channel_t* channel_find_by_number(const char* no); #define channel_find channel_find_by_uuid -htsmsg_t * channel_class_get_list(void *o, const char *lang); +htsmsg_t* channel_class_get_list(void* o, const char* lang); -const void * channel_class_get_icon ( void *obj ); +const void* channel_class_get_icon(void* obj); -int channel_set_tags_by_list ( channel_t *ch, htsmsg_t *tags ); +int channel_set_tags_by_list(channel_t* ch, htsmsg_t* tags); -channel_tag_t *channel_tag_create(const char *uuid, htsmsg_t *conf); +channel_tag_t* channel_tag_create(const char* uuid, htsmsg_t* conf); -channel_tag_t *channel_tag_find_by_name(const char *name, int create); +channel_tag_t* channel_tag_find_by_name(const char* name, int create); -channel_tag_t *channel_tag_find_by_id(uint32_t id); +channel_tag_t* channel_tag_find_by_id(uint32_t id); -static inline channel_tag_t *channel_tag_find_by_uuid(const char *uuid) - { return (channel_tag_t*)idnode_find(uuid, &channel_tag_class, NULL); } +static inline channel_tag_t* channel_tag_find_by_uuid(const char* uuid) { + return (channel_tag_t*)idnode_find(uuid, &channel_tag_class, NULL); +} -htsmsg_t * channel_tag_class_get_list(void *o, const char *lang); +htsmsg_t* channel_tag_class_get_list(void* o, const char* lang); -const char * channel_tag_get_icon(channel_tag_t *ct); +const char* channel_tag_get_icon(channel_tag_t* ct); -int channel_access(channel_t *ch, struct access *a, int disabled); +int channel_access(channel_t* ch, struct access* a, int disabled); -void channel_event_updated(epg_broadcast_t *e); +void channel_event_updated(epg_broadcast_t* e); -int channel_tag_map(channel_tag_t *ct, channel_t *ch, void *origin); -void channel_tag_unmap(channel_t *ch, void *origin); +int channel_tag_map(channel_tag_t* ct, channel_t* ch, void* origin); +void channel_tag_unmap(channel_t* ch, void* origin); -int channel_tag_access(channel_tag_t *ct, struct access *a, int disabled); +int channel_tag_access(channel_tag_t* ct, struct access* a, int disabled); -const char *channel_get_name ( const channel_t *ch, const char *blank ); -int channel_set_name ( channel_t *ch, const char *name ); +const char* channel_get_name(const channel_t* ch, const char* blank); +int channel_set_name(channel_t* ch, const char* name); /// User API convenience function to rename all channels that /// match "from". Lock must be held prior to call. /// @return number channels that matched "from". -int channel_rename_and_save ( const char *from, const char *to ); +int channel_rename_and_save(const char* from, const char* to); -#define CHANNEL_ENAME_NUMBERS (1<<0) -#define CHANNEL_ENAME_SOURCES (1<<1) +#define CHANNEL_ENAME_NUMBERS (1 << 0) +#define CHANNEL_ENAME_SOURCES (1 << 1) -char *channel_get_ename ( channel_t *ch, char *dst, size_t dstlen, - const char *blank, uint32_t flags ); +char* channel_get_ename(channel_t* ch, char* dst, size_t dstlen, const char* blank, uint32_t flags); #define CHANNEL_SPLIT ((int64_t)1000000) -static inline uint32_t channel_get_major ( int64_t chnum ) { return chnum / CHANNEL_SPLIT; } -static inline uint32_t channel_get_minor ( int64_t chnum ) { return chnum % CHANNEL_SPLIT; } +static inline uint32_t channel_get_major(int64_t chnum) { + return chnum / CHANNEL_SPLIT; +} +static inline uint32_t channel_get_minor(int64_t chnum) { + return chnum % CHANNEL_SPLIT; +} -int64_t channel_get_number ( const channel_t *ch ); -int channel_set_number ( channel_t *ch, uint32_t major, uint32_t minor ); +int64_t channel_get_number(const channel_t* ch); +int channel_set_number(channel_t* ch, uint32_t major, uint32_t minor); -char *channel_get_number_as_str ( channel_t *ch, char *dst, size_t dstlen ); -int64_t channel_get_number_from_str ( const char *str ); +char* channel_get_number_as_str(channel_t* ch, char* dst, size_t dstlen); +int64_t channel_get_number_from_str(const char* str); -char *channel_get_source ( channel_t *ch, char *dst, size_t dstlen ); +char* channel_get_source(channel_t* ch, char* dst, size_t dstlen); -const char *channel_get_icon ( channel_t *ch ); -int channel_set_icon ( channel_t *ch, const char *icon ); +const char* channel_get_icon(channel_t* ch); +int channel_set_icon(channel_t* ch, const char* icon); -const char *channel_get_epgid ( channel_t *ch ); +const char* channel_get_epgid(channel_t* ch); -#define channel_get_uuid(ch,ub) idnode_uuid_as_str(&(ch)->ch_id, ub) +#define channel_get_uuid(ch, ub) idnode_uuid_as_str(&(ch)->ch_id, ub) -#define channel_get_id(ch) idnode_get_short_uuid((&(ch)->ch_id)) +#define channel_get_id(ch) idnode_get_short_uuid((&(ch)->ch_id)) -channel_t **channel_get_sorted_list - ( const char *sort_type, int all, int *_count ) ; -channel_t **channel_get_sorted_list_for_tag - ( const char *sort_type, channel_tag_t *tag, int *_count ); -channel_tag_t **channel_tag_get_sorted_list - ( const char *sort_type, int *_count ); -int channel_has_correct_service_filter(const channel_t *ch, int svf); +channel_t** channel_get_sorted_list(const char* sort_type, int all, int* _count); +channel_t** channel_get_sorted_list_for_tag(const char* sort_type, channel_tag_t* tag, int* _count); +channel_tag_t** channel_tag_get_sorted_list(const char* sort_type, int* _count); +int channel_has_correct_service_filter(const channel_t* ch, int svf); #endif /* CHANNELS_H */ diff --git a/src/clock.h b/src/clock.h index 2be967c33..a261b3df9 100644 --- a/src/clock.h +++ b/src/clock.h @@ -28,90 +28,72 @@ #if defined(PLATFORM_DARWIN) && !defined(CLOCK_MONOTONIC) #error "Platforms without monotonic clocks are not supported!" #define CLOCK_MONOTONIC 0 -#define CLOCK_REALTIME 0 +#define CLOCK_REALTIME 0 static inline int clock_gettime(int clk_id, struct timespec* t) { - struct timeval now; - int rv = gettimeofday(&now, NULL); - if (rv) return rv; - t->tv_sec = now.tv_sec; - t->tv_nsec = now.tv_usec * 1000; - return 0; + struct timeval now; + int rv = gettimeofday(&now, NULL); + if (rv) + return rv; + t->tv_sec = now.tv_sec; + t->tv_nsec = now.tv_usec * 1000; + return 0; } #endif extern int64_t __mdispatch_clock; extern time_t __gdispatch_clock; -static inline int64_t mclk(void) -{ +static inline int64_t mclk(void) { return atomic_get_s64(&__mdispatch_clock); } -static inline time_t gclk(void) -{ +static inline time_t gclk(void) { return atomic_get_time_t(&__gdispatch_clock); } #define MONOCLOCK_RESOLUTION 1000000LL /* microseconds */ #define MONOCLOCK_FASTSEC 0xfffffLL /* 1048575 */ -static inline int64_t -sec2mono(int64_t sec) -{ +static inline int64_t sec2mono(int64_t sec) { return sec * MONOCLOCK_RESOLUTION; } -static inline int64_t -mono2sec(int64_t monosec) -{ +static inline int64_t mono2sec(int64_t monosec) { return monosec / MONOCLOCK_RESOLUTION; } -static inline int64_t -ms2mono(int64_t ms) -{ +static inline int64_t ms2mono(int64_t ms) { return ms * (MONOCLOCK_RESOLUTION / 1000LL); } -static inline int64_t -mono2ms(int64_t monosec) -{ +static inline int64_t mono2ms(int64_t monosec) { return monosec / (MONOCLOCK_RESOLUTION / 1000LL); } -static inline int64_t -getmonoclock(void) -{ +static inline int64_t getmonoclock(void) { struct timespec tp; clock_gettime(CLOCK_MONOTONIC, &tp); - return tp.tv_sec * MONOCLOCK_RESOLUTION + - (tp.tv_nsec / (1000000000LL/MONOCLOCK_RESOLUTION)); + return tp.tv_sec * MONOCLOCK_RESOLUTION + (tp.tv_nsec / (1000000000LL / MONOCLOCK_RESOLUTION)); } -static inline int64_t -getfastmonoclock(void) -{ +static inline int64_t getfastmonoclock(void) { struct timespec tp; clock_gettime(CLOCK_MONOTONIC_COARSE, &tp); - return tp.tv_sec * MONOCLOCK_RESOLUTION + - (tp.tv_nsec / (1000000000LL/MONOCLOCK_RESOLUTION)); + return tp.tv_sec * MONOCLOCK_RESOLUTION + (tp.tv_nsec / (1000000000LL / MONOCLOCK_RESOLUTION)); } -static inline int -monocmpfastsec(int64_t m1, int64_t m2) -{ +static inline int monocmpfastsec(int64_t m1, int64_t m2) { return (m1 & ~MONOCLOCK_FASTSEC) == (m2 & ~MONOCLOCK_FASTSEC); } void time_t_out_of_range_notify(int64_t val); -static inline time_t time_t_out_of_range(uint64_t val) -{ +static inline time_t time_t_out_of_range(uint64_t val) { time_t r = val; if ((int64_t)r != val) { time_t_out_of_range_notify(val); diff --git a/src/compat.h b/src/compat.h index 24fac8062..70f3c7db0 100644 --- a/src/compat.h +++ b/src/compat.h @@ -52,45 +52,44 @@ #ifdef COMPAT_IPTOS #ifndef IPTOS_DSCP_MASK -#define IPTOS_DSCP_MASK 0xfc +#define IPTOS_DSCP_MASK 0xfc #endif #ifndef IPTOS_DSCP -#define IPTOS_DSCP(x) ((x) & IPTOS_DSCP_MASK) +#define IPTOS_DSCP(x) ((x) & IPTOS_DSCP_MASK) #endif #ifndef IPTOS_DSCP_AF11 -#define IPTOS_DSCP_AF11 0x28 -#define IPTOS_DSCP_AF12 0x30 -#define IPTOS_DSCP_AF13 0x38 -#define IPTOS_DSCP_AF21 0x48 -#define IPTOS_DSCP_AF22 0x50 -#define IPTOS_DSCP_AF23 0x58 -#define IPTOS_DSCP_AF31 0x68 -#define IPTOS_DSCP_AF32 0x70 -#define IPTOS_DSCP_AF33 0x78 -#define IPTOS_DSCP_AF41 0x88 -#define IPTOS_DSCP_AF42 0x90 -#define IPTOS_DSCP_AF43 0x98 -#define IPTOS_DSCP_EF 0xb8 +#define IPTOS_DSCP_AF11 0x28 +#define IPTOS_DSCP_AF12 0x30 +#define IPTOS_DSCP_AF13 0x38 +#define IPTOS_DSCP_AF21 0x48 +#define IPTOS_DSCP_AF22 0x50 +#define IPTOS_DSCP_AF23 0x58 +#define IPTOS_DSCP_AF31 0x68 +#define IPTOS_DSCP_AF32 0x70 +#define IPTOS_DSCP_AF33 0x78 +#define IPTOS_DSCP_AF41 0x88 +#define IPTOS_DSCP_AF42 0x90 +#define IPTOS_DSCP_AF43 0x98 +#define IPTOS_DSCP_EF 0xb8 #endif #ifndef IPTOS_CLASS_MASK -#define IPTOS_CLASS_MASK 0xe0 +#define IPTOS_CLASS_MASK 0xe0 #endif #ifndef IPTOS_CLASS -#define IPTOS_CLASS(class) ((class) & IPTOS_CLASS_MASK) +#define IPTOS_CLASS(class) ((class) & IPTOS_CLASS_MASK) #endif #ifndef IPTOS_CLASS_CS0 -#define IPTOS_CLASS_CS0 0x00 -#define IPTOS_CLASS_CS1 0x20 -#define IPTOS_CLASS_CS2 0x40 -#define IPTOS_CLASS_CS3 0x60 -#define IPTOS_CLASS_CS4 0x80 -#define IPTOS_CLASS_CS5 0xa0 -#define IPTOS_CLASS_CS6 0xc0 -#define IPTOS_CLASS_CS7 0xe0 +#define IPTOS_CLASS_CS0 0x00 +#define IPTOS_CLASS_CS1 0x20 +#define IPTOS_CLASS_CS2 0x40 +#define IPTOS_CLASS_CS3 0x60 +#define IPTOS_CLASS_CS4 0x80 +#define IPTOS_CLASS_CS5 0xa0 +#define IPTOS_CLASS_CS6 0xc0 +#define IPTOS_CLASS_CS7 0xe0 #endif -#define IPTOS_CLASS_DEFAULT IPTOS_CLASS_CS0 +#define IPTOS_CLASS_DEFAULT IPTOS_CLASS_CS0 #endif /* COMPAT_IPTOS */ - diff --git a/src/config.c b/src/config.c index d5926df64..83953a027 100644 --- a/src/config.c +++ b/src/config.c @@ -43,38 +43,38 @@ #define COMPAT_IPTOS #include "compat.h" -static void config_muxconfpath_notify ( void *o, const char *lang ); +static void config_muxconfpath_notify(void* o, const char* lang); -void tvh_str_set(char **strp, const char *src); -int tvh_str_update(char **strp, const char *src); +void tvh_str_set(char** strp, const char* src); +int tvh_str_update(char** strp, const char* src); /* ************************************************************************* * Global data * ************************************************************************/ struct config config; -static char config_lock[PATH_MAX]; -static int config_lock_fd; -static int config_scanfile_ok; +static char config_lock[PATH_MAX]; +static int config_lock_fd; +static int config_scanfile_ok; /* ************************************************************************* * Config migration * ************************************************************************/ -typedef void (*config_migrate_t) (void); +typedef void (*config_migrate_t)(void); /* * Get channel UUID (by number) */ -static const char * -config_migrate_v1_chn_id_to_uuid ( htsmsg_t *chns, uint32_t id ) -{ - htsmsg_field_t *f; - htsmsg_t *e; - uint32_t u32; +static const char* config_migrate_v1_chn_id_to_uuid(htsmsg_t* chns, uint32_t id) { + htsmsg_field_t* f; + htsmsg_t* e; + uint32_t u32; HTSMSG_FOREACH(f, chns) { - if (!(e = htsmsg_field_get_map(f))) continue; - if (htsmsg_get_u32(e, "channelid", &u32)) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; + if (htsmsg_get_u32(e, "channelid", &u32)) + continue; if (u32 == id) { return htsmsg_get_str(e, "uuid"); } @@ -85,10 +85,8 @@ config_migrate_v1_chn_id_to_uuid ( htsmsg_t *chns, uint32_t id ) /* * Get channel UUID (by name) */ -static const char * -config_migrate_v1_chn_name_to_uuid ( htsmsg_t *chns, const char *name ) -{ - htsmsg_t *chn = htsmsg_get_map(chns, name); +static const char* config_migrate_v1_chn_name_to_uuid(htsmsg_t* chns, const char* name) { + htsmsg_t* chn = htsmsg_get_map(chns, name); if (chn) return htsmsg_get_str(chn, "uuid"); return NULL; @@ -98,12 +96,10 @@ config_migrate_v1_chn_name_to_uuid ( htsmsg_t *chns, const char *name ) * Helper to add service to channel */ static void -config_migrate_v1_chn_add_svc - ( htsmsg_t *chns, const char *chnname, const char *svcuuid ) -{ - htsmsg_t *chn = htsmsg_get_map(chns, chnname); +config_migrate_v1_chn_add_svc(htsmsg_t* chns, const char* chnname, const char* svcuuid) { + htsmsg_t* chn = htsmsg_get_map(chns, chnname); if (chn) { - htsmsg_t *l = htsmsg_get_list(chn, "services"); + htsmsg_t* l = htsmsg_get_list(chn, "services"); if (l) htsmsg_add_str(l, NULL, svcuuid); } @@ -112,20 +108,21 @@ config_migrate_v1_chn_add_svc /* * Helper function to migrate a muxes services */ -static void -config_migrate_v1_dvb_svcs - ( const char *name, const char *netu, const char *muxu, htsmsg_t *channels ) -{ - tvh_uuid_t svcu; - char ubuf[UUID_HEX_SIZE]; - htsmsg_t *c, *e, *svc; - htsmsg_field_t *f; - const char *str; - uint32_t u32; +static void config_migrate_v1_dvb_svcs(const char* name, + const char* netu, + const char* muxu, + htsmsg_t* channels) { + tvh_uuid_t svcu; + char ubuf[UUID_HEX_SIZE]; + htsmsg_t * c, *e, *svc; + htsmsg_field_t* f; + const char* str; + uint32_t u32; if ((c = hts_settings_load_r(1, "dvbtransports/%s", name))) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; svc = htsmsg_create_map(); uuid_set(&svcu, NULL); @@ -148,8 +145,11 @@ config_migrate_v1_dvb_svcs // TODO: dvb_eit_enable - hts_settings_save(svc, "input/linuxdvb/networks/%s/muxes/%s/services/%s", - netu, muxu, uuid_get_hex(&svcu, ubuf)); + hts_settings_save(svc, + "input/linuxdvb/networks/%s/muxes/%s/services/%s", + netu, + muxu, + uuid_get_hex(&svcu, ubuf)); htsmsg_destroy(svc); @@ -164,31 +164,26 @@ config_migrate_v1_dvb_svcs /* * Helper to convert a DVB network */ -static void -config_migrate_v1_dvb_network - ( const char *name, htsmsg_t *c, htsmsg_t *channels ) -{ - int i; - tvh_uuid_t netu, muxu; - char ubuf[UUID_HEX_SIZE], ubuf2[UUID_HEX_SIZE]; - htsmsg_t *e, *net, *mux, *tun; - htsmsg_field_t *f; - const char *str, *type; - uint32_t u32; - const char *mux_str_props[] = { - "bandwidth", - "consellation", - "transmission_mode", - "guard_interval", - "hierarchy", - "fec_hi", - "fec_lo", - "fec" - }; - +static void config_migrate_v1_dvb_network(const char* name, htsmsg_t* c, htsmsg_t* channels) { + int i; + tvh_uuid_t netu, muxu; + char ubuf[UUID_HEX_SIZE], ubuf2[UUID_HEX_SIZE]; + htsmsg_t * e, *net, *mux, *tun; + htsmsg_field_t* f; + const char * str, *type; + uint32_t u32; + const char* mux_str_props[] = {"bandwidth", + "consellation", + "transmission_mode", + "guard_interval", + "hierarchy", + "fec_hi", + "fec_lo", + "fec"}; /* Load the adapter config */ - if (!(tun = hts_settings_load("dvbadapters/%s", name))) return; + if (!(tun = hts_settings_load("dvbadapters/%s", name))) + return; if (!(str = htsmsg_get_str(tun, "type"))) { htsmsg_destroy(tun); return; @@ -207,13 +202,14 @@ config_migrate_v1_dvb_network else htsmsg_add_str(net, "class", "linuxdvb_network_dvbt"); if (!htsmsg_get_u32(tun, "autodiscovery", &u32)) - htsmsg_add_u32(net, "autodiscovery", u32); + htsmsg_add_u32(net, "autodiscovery", u32); if (!htsmsg_get_u32(tun, "skip_initialscan", &u32)) - htsmsg_add_u32(net, "skipinitscan", u32); + htsmsg_add_u32(net, "skipinitscan", u32); /* Each mux */ HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; mux = htsmsg_create_map(); if (!htsmsg_get_u32(e, "transportstreamid", &u32)) @@ -240,7 +236,7 @@ config_migrate_v1_dvb_network } if ((str = htsmsg_get_str(e, "polarisation"))) { - char tmp[2] = { *str, 0 }; + char tmp[2] = {*str, 0}; htsmsg_add_str(mux, "polarisation", tmp); } if ((str = htsmsg_get_str(e, "modulation"))) { @@ -251,11 +247,10 @@ config_migrate_v1_dvb_network } if ((str = htsmsg_get_str(e, "rolloff"))) if (strlen(str) > 8) - htsmsg_add_str(mux, "rolloff", str+8); + htsmsg_add_str(mux, "rolloff", str + 8); - if ((str = htsmsg_get_str(e, "delivery_system")) && - strlen(str) > 4 ) - htsmsg_add_str(mux, "delsys", str+4); + if ((str = htsmsg_get_str(e, "delivery_system")) && strlen(str) > 4) + htsmsg_add_str(mux, "delsys", str + 4); else if (!strcmp(type, "ATSC")) htsmsg_add_str(mux, "delsys", "ATSC"); else if (!strcmp(type, "DVB-S")) @@ -267,9 +262,10 @@ config_migrate_v1_dvb_network /* Save */ uuid_set(&muxu, NULL); - hts_settings_save(mux, "input/linuxdvb/networks/%s/muxes/%s/config", - uuid_get_hex(&netu, ubuf), - uuid_get_hex(&muxu, ubuf2)); + hts_settings_save(mux, + "input/linuxdvb/networks/%s/muxes/%s/config", + uuid_get_hex(&netu, ubuf), + uuid_get_hex(&muxu, ubuf2)); htsmsg_destroy(mux); /* Services */ @@ -278,8 +274,7 @@ config_migrate_v1_dvb_network /* Add properties derived from network */ htsmsg_add_str(net, "networkname", name); - hts_settings_save(net, "input/linuxdvb/networks/%s/config", - uuid_get_hex(&netu, ubuf)); + hts_settings_save(net, "input/linuxdvb/networks/%s/config", uuid_get_hex(&netu, ubuf)); htsmsg_destroy(tun); htsmsg_destroy(net); } @@ -287,16 +282,15 @@ config_migrate_v1_dvb_network /* * Migrate DVR/autorec entries */ -static void -config_migrate_v1_dvr ( const char *path, htsmsg_t *channels ) -{ - htsmsg_t *c, *e, *m; - htsmsg_field_t *f; - const char *str; +static void config_migrate_v1_dvr(const char* path, htsmsg_t* channels) { + htsmsg_t * c, *e, *m; + htsmsg_field_t* f; + const char* str; if ((c = hts_settings_load_r(1, path))) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if ((str = htsmsg_get_str(e, "channel"))) { m = htsmsg_copy(e); if (!htsmsg_get_str(e, "channelname")) @@ -316,17 +310,16 @@ config_migrate_v1_dvr ( const char *path, htsmsg_t *channels ) /* * Migrate Epggrab entries */ -static void -config_migrate_v1_epggrab ( const char *path, htsmsg_t *channels ) -{ - htsmsg_t *c, *e, *m, *l, *chns; +static void config_migrate_v1_epggrab(const char* path, htsmsg_t* channels) { + htsmsg_t * c, *e, *m, *l, *chns; htsmsg_field_t *f, *f2; - const char *str; - uint32_t u32; + const char* str; + uint32_t u32; if ((c = hts_settings_load_r(1, path))) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; m = htsmsg_copy(e); chns = htsmsg_create_list(); if ((l = htsmsg_get_list(e, "channels"))) { @@ -355,29 +348,29 @@ config_migrate_v1_epggrab ( const char *path, htsmsg_t *channels ) * Strictly speaking there were earlier versions than this, but most people * using early versions of 4.0 would already have been on this version. */ -static void -config_migrate_v1 ( void ) -{ - tvh_uuid_t netu, muxu, svcu, chnu; - htsmsg_t *c, *e, *l, *m = NULL; - htsmsg_field_t *f; - uint32_t u32; - const char *str; - char buf[1024]; - char ubufc[UUID_HEX_SIZE]; - char ubufn[UUID_HEX_SIZE]; - char ubufm[UUID_HEX_SIZE]; - char ubufs[UUID_HEX_SIZE]; - htsmsg_t *channels = htsmsg_create_map(); +static void config_migrate_v1(void) { + tvh_uuid_t netu, muxu, svcu, chnu; + htsmsg_t * c, *e, *l, *m = NULL; + htsmsg_field_t* f; + uint32_t u32; + const char* str; + char buf[1024]; + char ubufc[UUID_HEX_SIZE]; + char ubufn[UUID_HEX_SIZE]; + char ubufm[UUID_HEX_SIZE]; + char ubufs[UUID_HEX_SIZE]; + htsmsg_t* channels = htsmsg_create_map(); /* Channels */ if ((c = hts_settings_load_r(1, "channels"))) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; /* Build entry */ uuid_set(&chnu, NULL); - if(m != NULL) htsmsg_destroy(m); + if (m != NULL) + htsmsg_destroy(m); m = htsmsg_create_map(); htsmsg_add_u32(m, "channelid", atoi(htsmsg_field_name(f))); htsmsg_add_str(m, "uuid", uuid_get_hex(&chnu, ubufc)); @@ -407,22 +400,25 @@ config_migrate_v1 ( void ) /* Create a network */ uuid_set(&netu, NULL); - if(m != NULL) htsmsg_destroy(m); + if (m != NULL) + htsmsg_destroy(m); m = htsmsg_create_map(); - htsmsg_add_str(m, "networkname", "IPTV Network"); - htsmsg_add_u32(m, "skipinitscan", 1); - htsmsg_add_u32(m, "autodiscovery", 0); - htsmsg_add_u32(m, "max_streams", 0); - htsmsg_add_u32(m, "max_bandwidth", 0); - hts_settings_save(m, "input/iptv/networks/%s/config", - uuid_get_hex(&netu, ubufn)); + htsmsg_add_str(m, "networkname", "IPTV Network"); + htsmsg_add_u32(m, "skipinitscan", 1); + htsmsg_add_u32(m, "autodiscovery", 0); + htsmsg_add_u32(m, "max_streams", 0); + htsmsg_add_u32(m, "max_bandwidth", 0); + hts_settings_save(m, "input/iptv/networks/%s/config", uuid_get_hex(&netu, ubufn)); htsmsg_destroy(m); /* Process services */ HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; - if (!(str = htsmsg_get_str(e, "group"))) continue; - if (htsmsg_get_u32(e, "port", &u32)) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; + if (!(str = htsmsg_get_str(e, "group"))) + continue; + if (htsmsg_get_u32(e, "port", &u32)) + continue; /* Create mux entry */ uuid_set(&muxu, NULL); @@ -433,11 +429,12 @@ config_migrate_v1 ( void ) htsmsg_add_str(m, "iptv_interface", str); if ((str = htsmsg_get_str(e, "channelname"))) htsmsg_add_str(m, "iptv_svcname", str); - htsmsg_add_u32(m, "enabled", - !!htsmsg_get_u32_or_default(e, "disabled", 0)); + htsmsg_add_u32(m, "enabled", !!htsmsg_get_u32_or_default(e, "disabled", 0)); htsmsg_add_u32(m, "initscan", 1); - hts_settings_save(m, "input/iptv/networks/%s/muxes/%s/config", - ubufn, uuid_get_hex(&muxu, ubufm)); + hts_settings_save(m, + "input/iptv/networks/%s/muxes/%s/config", + ubufn, + uuid_get_hex(&muxu, ubufm)); htsmsg_destroy(m); /* Create svc entry */ @@ -454,8 +451,7 @@ config_migrate_v1 ( void ) htsmsg_add_str(m, "svcname", str); config_migrate_v1_chn_add_svc(channels, str, ubufs); } - hts_settings_save(m, "input/iptv/networks/%s/muxes/%s/services/%s", - ubufn, ubufm, ubufs); + hts_settings_save(m, "input/iptv/networks/%s/muxes/%s/services/%s", ubufn, ubufm, ubufs); htsmsg_destroy(m); } @@ -465,7 +461,8 @@ config_migrate_v1 ( void ) /* DVB Networks */ if ((c = hts_settings_load_r(2, "dvbmuxes"))) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; config_migrate_v1_dvb_network(htsmsg_field_name(f), e, channels); } htsmsg_destroy(c); @@ -482,8 +479,10 @@ config_migrate_v1 ( void ) /* Save the channels */ // Note: UUID will be stored in the file (redundant) but that's no biggy HTSMSG_FOREACH(f, channels) { - if (!(e = htsmsg_field_get_map(f))) continue; - if (!(str = htsmsg_get_str(e, "uuid"))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; + if (!(str = htsmsg_get_str(e, "uuid"))) + continue; hts_settings_save(e, "channel/%s", str); } htsmsg_destroy(channels); @@ -492,13 +491,11 @@ config_migrate_v1 ( void ) /* * v1 -> v2 : changes to IPTV arrangements */ -static void -config_migrate_v2 ( void ) -{ - htsmsg_t *m; +static void config_migrate_v2(void) { + htsmsg_t* m; tvh_uuid_t u; - char ubuf[UUID_HEX_SIZE]; - char src[1024], dst[1024]; + char ubuf[UUID_HEX_SIZE]; + char src[1024], dst[1024]; /* Do we have IPTV config to migrate ? */ if (hts_settings_exists("input/iptv/muxes")) { @@ -514,10 +511,8 @@ config_migrate_v2 ( void ) htsmsg_destroy(m); /* Move muxes */ - hts_settings_buildpath(src, sizeof(src), - "input/iptv/muxes"); - hts_settings_buildpath(dst, sizeof(dst), - "input/iptv/networks/%s/muxes", ubuf); + hts_settings_buildpath(src, sizeof(src), "input/iptv/muxes"); + hts_settings_buildpath(dst, sizeof(dst), "input/iptv/networks/%s/muxes", ubuf); rename(src, dst); } } @@ -525,9 +520,7 @@ config_migrate_v2 ( void ) /* * v2 -> v3 : changes to DVB layout */ -static void -config_migrate_v3 ( void ) -{ +static void config_migrate_v3(void) { char src[1024], dst[1024]; /* Due to having to potentially run this twice! */ @@ -545,21 +538,22 @@ config_migrate_v3 ( void ) /* * v3 -> v5 : fix broken DVB network / mux files */ -static void -config_migrate_v5 ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - const char *str; +static void config_migrate_v5(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + const char* str; /* Remove linux prefix from class */ if ((c = hts_settings_load_r(1, "input/dvb/networks"))) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; - if (!(e = htsmsg_get_map(e, "config"))) continue; - if (!(str = htsmsg_get_str(e, "class"))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; + if (!(e = htsmsg_get_map(e, "config"))) + continue; + if (!(str = htsmsg_get_str(e, "class"))) + continue; if (!strncmp(str, "linux", 5)) { - str = tvh_strdupa(str+5); + str = tvh_strdupa(str + 5); htsmsg_delete_field(e, "class"); htsmsg_add_str(e, "class", str); hts_settings_save(e, "input/dvb/networks/%s/config", htsmsg_field_name(f)); @@ -572,16 +566,14 @@ config_migrate_v5 ( void ) /* * v5 -> v6 : epggrab changes, also xmltv/config */ -static void -config_migrate_v6 ( void ) -{ - htsmsg_t *c, *m; - htsmsg_field_t *f; - const char *str; - uint32_t interval; - char buf[128]; - const char *s; - int old = 0; +static void config_migrate_v6(void) { + htsmsg_t * c, *m; + htsmsg_field_t* f; + const char* str; + uint32_t interval; + char buf[128]; + const char* s; + int old = 0; c = hts_settings_load_r(1, "epggrab/config"); @@ -591,7 +583,8 @@ config_migrate_v6 ( void ) if (c) { if (!htsmsg_get_u32(c, old ? "grab-interval" : "interval", &interval)) { - if (old) interval *= 3600; + if (old) + interval *= 3600; if (interval <= 600) strcpy(buf, "*/10 * * * *"); else if (interval <= 900) @@ -645,8 +638,8 @@ config_migrate_v6 ( void ) /* Migrate XMLTV channels */ htsmsg_t *xc, *ch; - htsmsg_t *xchs = hts_settings_load("xmltv/channels"); - htsmsg_t *chs = hts_settings_load_r(1, "channel"); + htsmsg_t* xchs = hts_settings_load("xmltv/channels"); + htsmsg_t* chs = hts_settings_load_r(1, "channel"); if (chs) { HTSMSG_FOREACH(f, chs) { if ((ch = htsmsg_get_map_by_field(f))) { @@ -671,36 +664,32 @@ config_migrate_v6 ( void ) htsmsg_destroy(c); } - /* * v6 -> v7 : acesscontrol changes */ -static void -config_migrate_simple ( const char *dir, htsmsg_t *list, - void (*modify)(htsmsg_t *record, - uint32_t id, - const char *uuid, - const void *aux), - const void *aux ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - tvh_uuid_t u; - char ubuf[UUID_HEX_SIZE]; - uint32_t index = 1, id; +static void config_migrate_simple(const char* dir, + htsmsg_t* list, + void (*modify)(htsmsg_t* record, uint32_t id, const char* uuid, const void* aux), + const void* aux) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + tvh_uuid_t u; + char ubuf[UUID_HEX_SIZE]; + uint32_t index = 1, id; if (!(c = hts_settings_load(dir))) return; HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; uuid_set(&u, NULL); uuid_get_hex(&u, ubuf); if (htsmsg_get_u32(e, "id", &id)) id = 0; else if (list) { - htsmsg_t *m = htsmsg_create_map(); - char buf[16]; + htsmsg_t* m = htsmsg_create_map(); + char buf[16]; snprintf(buf, sizeof(buf), "%d", id); htsmsg_add_str(m, "id", buf); htsmsg_add_str(m, "uuid", ubuf); @@ -717,36 +706,30 @@ config_migrate_simple ( const char *dir, htsmsg_t *list, htsmsg_destroy(c); } -static void -config_modify_acl( htsmsg_t *c, uint32_t id, const char *uuid, const void *aux ) -{ - uint32_t a, b; - const char *s; +static void config_modify_acl(htsmsg_t* c, uint32_t id, const char* uuid, const void* aux) { + uint32_t a, b; + const char* s; if (htsmsg_get_u32(c, "adv_streaming", &a)) if (!htsmsg_get_u32(c, "streaming", &b)) htsmsg_add_u32(c, "adv_streaming", b); if ((s = htsmsg_get_str(c, "password")) != NULL) { char buf[256], result[300]; snprintf(buf, sizeof(buf), "TVHeadend-Hide-%s", s); - base64_encode(result, sizeof(result), (uint8_t *)buf, strlen(buf)); + base64_encode(result, sizeof(result), (uint8_t*)buf, strlen(buf)); htsmsg_add_str(c, "password2", result); htsmsg_delete_field(c, "password"); } } -static void -config_migrate_v7 ( void ) -{ +static void config_migrate_v7(void) { config_migrate_simple("accesscontrol", NULL, config_modify_acl, NULL); } -static void -config_modify_tag( htsmsg_t *c, uint32_t id, const char *uuid, const void *aux ) -{ - htsmsg_t *ch = (htsmsg_t *)aux; - htsmsg_t *e, *m, *t; +static void config_modify_tag(htsmsg_t* c, uint32_t id, const char* uuid, const void* aux) { + htsmsg_t* ch = (htsmsg_t*)aux; + htsmsg_t * e, *m, *t; htsmsg_field_t *f, *f2; - uint32_t u32; + uint32_t u32; htsmsg_delete_field(c, "index"); @@ -754,7 +737,8 @@ config_modify_tag( htsmsg_t *c, uint32_t id, const char *uuid, const void *aux ) return; HTSMSG_FOREACH(f, ch) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; m = htsmsg_get_list(e, "tags"); if (m == NULL) continue; @@ -773,18 +757,17 @@ config_modify_tag( htsmsg_t *c, uint32_t id, const char *uuid, const void *aux ) } } -static void -config_migrate_v8 ( void ) -{ - htsmsg_t *ch, *e, *m; - htsmsg_field_t *f; +static void config_migrate_v8(void) { + htsmsg_t * ch, *e, *m; + htsmsg_field_t* f; ch = hts_settings_load_r(1, "channel"); config_migrate_simple("channeltags", NULL, config_modify_tag, ch); if (ch == NULL) return; HTSMSG_FOREACH(f, ch) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; htsmsg_delete_field(e, "tags"); m = htsmsg_get_list(e, "tags_new"); if (m) { @@ -796,9 +779,7 @@ config_migrate_v8 ( void ) htsmsg_destroy(ch); } -static void -config_modify_autorec( htsmsg_t *c, uint32_t id, const char *uuid, const void *aux ) -{ +static void config_modify_autorec(htsmsg_t* c, uint32_t id, const char* uuid, const void* aux) { uint32_t u32; htsmsg_delete_field(c, "index"); if (!htsmsg_get_u32(c, "approx_time", &u32)) { @@ -814,17 +795,15 @@ config_modify_autorec( htsmsg_t *c, uint32_t id, const char *uuid, const void *a } } -static void -config_modify_dvr_log( htsmsg_t *c, uint32_t id, const char *uuid, const void *aux ) -{ - const htsmsg_t *list = aux; - const char *chname = htsmsg_get_str(c, "channelname"); - const char *chuuid = htsmsg_get_str(c, "channel"); - htsmsg_t *e; - htsmsg_field_t *f; - tvh_uuid_t uuid0; - const char *s1; - uint32_t u32; +static void config_modify_dvr_log(htsmsg_t* c, uint32_t id, const char* uuid, const void* aux) { + const htsmsg_t* list = aux; + const char* chname = htsmsg_get_str(c, "channelname"); + const char* chuuid = htsmsg_get_str(c, "channel"); + htsmsg_t* e; + htsmsg_field_t* f; + tvh_uuid_t uuid0; + const char* s1; + uint32_t u32; htsmsg_delete_field(c, "index"); if (chname == NULL || (chuuid != NULL && uuid_set(&uuid0, chuuid))) { @@ -832,7 +811,7 @@ config_modify_dvr_log( htsmsg_t *c, uint32_t id, const char *uuid, const void *a htsmsg_delete_field(c, "channelname"); htsmsg_delete_field(c, "channel"); htsmsg_add_str(c, "channelname", chname); - free((char *)chname); + free((char*)chname); if (!htsmsg_get_u32(c, "contenttype", &u32)) { htsmsg_delete_field(c, "contenttype"); htsmsg_add_u32(c, "content_type", u32 / 16); @@ -843,27 +822,26 @@ config_modify_dvr_log( htsmsg_t *c, uint32_t id, const char *uuid, const void *a htsmsg_delete_field(c, "autorec"); if (s1 != NULL) { HTSMSG_FOREACH(f, list) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if (strcmp(s1, htsmsg_get_str(e, "id") ?: "") == 0) { - const char *s2 = htsmsg_get_str(e, "uuid"); + const char* s2 = htsmsg_get_str(e, "uuid"); if (s2) htsmsg_add_str(c, "autorec", s2); break; } } - free((char *)s1); + free((char*)s1); } } } -static void -config_migrate_v9 ( void ) -{ - htsmsg_t *list = htsmsg_create_list(); - htsmsg_t *c, *e; - htsmsg_field_t *f; - tvh_uuid_t u; - char ubuf[UUID_HEX_SIZE]; +static void config_migrate_v9(void) { + htsmsg_t* list = htsmsg_create_list(); + htsmsg_t * c, *e; + htsmsg_field_t* f; + tvh_uuid_t u; + char ubuf[UUID_HEX_SIZE]; config_migrate_simple("autorec", list, config_modify_autorec, NULL); config_migrate_simple("dvr/log", NULL, config_modify_dvr_log, list); @@ -872,8 +850,10 @@ config_migrate_v9 ( void ) if ((c = hts_settings_load("dvr")) != NULL) { /* step 1: only "config" */ HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; - if (strcmp(htsmsg_field_name(f), "config")) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; + if (strcmp(htsmsg_field_name(f), "config")) + continue; htsmsg_add_str(e, "name", htsmsg_field_name(f) + 6); uuid_set(&u, NULL); hts_settings_remove("dvr/%s", htsmsg_field_name(f)); @@ -881,9 +861,12 @@ config_migrate_v9 ( void ) } /* step 2: reset (without "config") */ HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; - if (strcmp(htsmsg_field_name(f), "config") == 0) continue; - if (strncmp(htsmsg_field_name(f), "config", 6)) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; + if (strcmp(htsmsg_field_name(f), "config") == 0) + continue; + if (strncmp(htsmsg_field_name(f), "config", 6)) + continue; htsmsg_add_str(e, "name", htsmsg_field_name(f) + 6); uuid_set(&u, NULL); hts_settings_remove("dvr/%s", htsmsg_field_name(f)); @@ -894,7 +877,8 @@ config_migrate_v9 ( void ) if ((c = hts_settings_load("autorec")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; hts_settings_remove("autorec/%s", htsmsg_field_name(f)); hts_settings_save(e, "dvr/autorec/%s", htsmsg_field_name(f)); } @@ -902,18 +886,16 @@ config_migrate_v9 ( void ) } } -static void -config_migrate_move ( const char *dir, - const char *newdir ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; +static void config_migrate_move(const char* dir, const char* newdir) { + htsmsg_t * c, *e; + htsmsg_field_t* f; if (!(c = hts_settings_load(dir))) return; HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; hts_settings_save(e, "%s/%s", newdir, htsmsg_field_name(f)); hts_settings_remove("%s/%s", dir, htsmsg_field_name(f)); } @@ -921,24 +903,21 @@ config_migrate_move ( const char *dir, htsmsg_destroy(c); } -static void -config_migrate_v10 ( void ) -{ +static void config_migrate_v10(void) { config_migrate_move("channel", "channel/config"); config_migrate_move("channeltags", "channel/tag"); } -static const char * -config_find_uuid( htsmsg_t *map, const char *name, const char *value ) -{ - htsmsg_t *e; - htsmsg_field_t *f; - const char *s; +static const char* config_find_uuid(htsmsg_t* map, const char* name, const char* value) { + htsmsg_t* e; + htsmsg_field_t* f; + const char* s; if (!map || !name || !value) return NULL; HTSMSG_FOREACH(f, map) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if ((s = htsmsg_get_str(e, name)) != NULL) { if (!strcmp(s, value)) return htsmsg_field_name(f); @@ -947,10 +926,8 @@ config_find_uuid( htsmsg_t *map, const char *name, const char *value ) return NULL; } -static void -config_modify_acl_dvallcfg( htsmsg_t *c, htsmsg_t *dvr_config ) -{ - uint32_t a; +static void config_modify_acl_dvallcfg(htsmsg_t* c, htsmsg_t* dvr_config) { + uint32_t a; const char *username, *uuid; username = htsmsg_get_str(c, "username"); @@ -963,14 +940,12 @@ config_modify_acl_dvallcfg( htsmsg_t *c, htsmsg_t *dvr_config ) htsmsg_delete_field(c, "dvallcfg"); } -static void -config_modify_acl_tag_only( htsmsg_t *c, htsmsg_t *channel_tag ) -{ - uint32_t a; +static void config_modify_acl_tag_only(htsmsg_t* c, htsmsg_t* channel_tag) { + uint32_t a; const char *username, *tag, *uuid; username = htsmsg_get_str(c, "username"); - tag = htsmsg_get_str(c, "channel_tag"); + tag = htsmsg_get_str(c, "channel_tag"); if (!tag || tag[0] == '\0') tag = NULL; if (tag == NULL && !htsmsg_get_u32(c, "tag_only", &a)) { @@ -989,32 +964,28 @@ config_modify_acl_tag_only( htsmsg_t *c, htsmsg_t *channel_tag ) htsmsg_delete_field(c, "tag_only"); } -static void -config_modify_dvr_config_name( htsmsg_t *c, htsmsg_t *dvr_config ) -{ +static void config_modify_dvr_config_name(htsmsg_t* c, htsmsg_t* dvr_config) { const char *config_name, *uuid; config_name = htsmsg_get_str(c, "config_name"); - uuid = config_name ? config_find_uuid(dvr_config, "name", config_name) : NULL; + uuid = config_name ? config_find_uuid(dvr_config, "name", config_name) : NULL; htsmsg_delete_field(c, "config_name"); htsmsg_add_str(c, "config_name", uuid ?: ""); } +static void config_migrate_v11(void) { + htsmsg_t* dvr_config; + htsmsg_t* channel_tag; + htsmsg_t * c, *e; + htsmsg_field_t* f; -static void -config_migrate_v11 ( void ) -{ - htsmsg_t *dvr_config; - htsmsg_t *channel_tag; - htsmsg_t *c, *e; - htsmsg_field_t *f; - - dvr_config = hts_settings_load("dvr/config"); + dvr_config = hts_settings_load("dvr/config"); channel_tag = hts_settings_load("channel/tag"); if ((c = hts_settings_load("accesscontrol")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; config_modify_acl_dvallcfg(e, dvr_config); config_modify_acl_tag_only(e, channel_tag); } @@ -1023,7 +994,8 @@ config_migrate_v11 ( void ) if ((c = hts_settings_load("dvr/log")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; config_modify_dvr_config_name(e, dvr_config); } htsmsg_destroy(c); @@ -1033,9 +1005,7 @@ config_migrate_v11 ( void ) htsmsg_destroy(dvr_config); } -static void -config_modify_caclient( htsmsg_t *c, uint32_t id, const char *uuid, const void *aux ) -{ +static void config_modify_caclient(htsmsg_t* c, uint32_t id, const char* uuid, const void* aux) { uint32_t u; htsmsg_delete_field(c, "index"); @@ -1047,18 +1017,17 @@ config_modify_caclient( htsmsg_t *c, uint32_t id, const char *uuid, const void * } } -static void -config_migrate_v12 ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; +static void config_migrate_v12(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; config_migrate_simple("cwc", NULL, config_modify_caclient, "caclient_cwc"); config_migrate_simple("capmt", NULL, config_modify_caclient, "caclient_capmt"); if ((c = hts_settings_load("cwc")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; hts_settings_remove("cwc/%s", htsmsg_field_name(f)); hts_settings_save(e, "caclient/%s", htsmsg_field_name(f)); } @@ -1066,7 +1035,8 @@ config_migrate_v12 ( void ) } if ((c = hts_settings_load("capmt")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; hts_settings_remove("capmt/%s", htsmsg_field_name(f)); hts_settings_save(e, "caclient/%s", htsmsg_field_name(f)); } @@ -1074,16 +1044,15 @@ config_migrate_v12 ( void ) } } -static void -config_migrate_v13 ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - int i; +static void config_migrate_v13(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + int i; if ((c = hts_settings_load("dvr/config")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if (!htsmsg_get_bool(e, "container", &i)) { htsmsg_delete_field(e, "container"); if (i == 1) @@ -1099,31 +1068,36 @@ config_migrate_v13 ( void ) } } -static const char * -config_migrate_v14_codec(int i) -{ +static const char* config_migrate_v14_codec(int i) { switch (i) { - case 1: return "mpeg2video"; - case 2: return "mp2"; - case 3: return "libx264"; - case 4: return "ac3"; - case 8: return "aac"; - case 13: return "libvpx"; - case 14: return "libvorbis"; - default: return ""; - } -} - -static void -config_migrate_v14 ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - int i; + case 1: + return "mpeg2video"; + case 2: + return "mp2"; + case 3: + return "libx264"; + case 4: + return "ac3"; + case 8: + return "aac"; + case 13: + return "libvpx"; + case 14: + return "libvorbis"; + default: + return ""; + } +} + +static void config_migrate_v14(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + int i; if ((c = hts_settings_load("profile")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if (!htsmsg_get_s32(e, "vcodec", &i)) { htsmsg_delete_field(e, "vcodec"); htsmsg_set_str(e, "vcodec", config_migrate_v14_codec(i)); @@ -1140,16 +1114,15 @@ config_migrate_v14 ( void ) } } -static void -config_migrate_v15 ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - int i; +static void config_migrate_v15(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + int i; if ((c = hts_settings_load("profile")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if (htsmsg_get_s32(e, "timeout", &i)) { htsmsg_set_s32(e, "timeout", 5); hts_settings_save(e, "profile/%s", htsmsg_field_name(f)); @@ -1159,14 +1132,12 @@ config_migrate_v15 ( void ) } } -static int -config_dvr_autorec_start_set(const char *s, int *tm) -{ +static int config_dvr_autorec_start_set(const char* s, int* tm) { int t; - if(s == NULL || s[0] == '\0' || !isdigit(s[0])) + if (s == NULL || s[0] == '\0' || !isdigit(s[0])) t = -1; - else if(strchr(s, ':') != NULL) + else if (strchr(s, ':') != NULL) // formatted time string - convert t = (atoi(s) * 60) + atoi(s + 3); else { @@ -1181,10 +1152,8 @@ config_dvr_autorec_start_set(const char *s, int *tm) return 0; } -static void -config_modify_dvrauto( htsmsg_t *c ) -{ - int tm = -1, tw = -1; +static void config_modify_dvrauto(htsmsg_t* c) { + int tm = -1, tw = -1; char buf[16]; if (config_dvr_autorec_start_set(htsmsg_get_str(c, "start"), &tm) > 0 && tm >= 0) { @@ -1203,15 +1172,14 @@ config_modify_dvrauto( htsmsg_t *c ) } } -static void -config_migrate_v16 ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; +static void config_migrate_v16(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; if ((c = hts_settings_load("dvr/autorec")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; config_modify_dvrauto(e); hts_settings_save(e, "dvr/autorec/%s", htsmsg_field_name(f)); } @@ -1219,16 +1187,15 @@ config_migrate_v16 ( void ) } } -static void -config_migrate_v17 ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - int i, p; +static void config_migrate_v17(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + int i, p; if ((c = hts_settings_load("profile")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if (htsmsg_get_s32(e, "priority", &i)) { p = PROFILE_SPRIO_NORMAL; if (strcmp(htsmsg_get_str(e, "name") ?: "", "htsp") == 0) @@ -1241,16 +1208,15 @@ config_migrate_v17 ( void ) } } -static void -config_migrate_v18 ( void ) -{ - htsmsg_t *c, *e, *l, *m; - htsmsg_field_t *f; - const char *filename; +static void config_migrate_v18(void) { + htsmsg_t * c, *e, *l, *m; + htsmsg_field_t* f; + const char* filename; if ((c = hts_settings_load("dvr/log")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if ((filename = htsmsg_get_str(e, "filename")) == NULL) continue; if ((l = htsmsg_get_list(e, "files")) != NULL) @@ -1267,18 +1233,17 @@ config_migrate_v18 ( void ) } } -static void -config_migrate_v19 ( void ) -{ - htsmsg_t *c, *e, *m; - htsmsg_field_t *f; - const char *username, *passwd; - tvh_uuid_t u; - char ubuf[UUID_HEX_SIZE]; +static void config_migrate_v19(void) { + htsmsg_t * c, *e, *m; + htsmsg_field_t* f; + const char * username, *passwd; + tvh_uuid_t u; + char ubuf[UUID_HEX_SIZE]; if ((c = hts_settings_load("accesscontrol")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if ((username = htsmsg_get_str(e, "username")) == NULL) continue; if ((passwd = htsmsg_get_str(e, "password2")) == NULL) @@ -1296,12 +1261,10 @@ config_migrate_v19 ( void ) htsmsg_destroy(c); } -static void -config_migrate_v20_helper ( htsmsg_t *e, const char *fname ) -{ - htsmsg_t *l; - const char *str; - char *p; +static void config_migrate_v20_helper(htsmsg_t* e, const char* fname) { + htsmsg_t* l; + const char* str; + char* p; if ((str = htsmsg_get_str(e, fname)) != NULL) { p = strdup(str); @@ -1313,15 +1276,14 @@ config_migrate_v20_helper ( htsmsg_t *e, const char *fname ) } } -static void -config_migrate_v20 ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; +static void config_migrate_v20(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; if ((c = hts_settings_load("accesscontrol")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; config_migrate_v20_helper(e, "profile"); config_migrate_v20_helper(e, "dvr_config"); config_migrate_v20_helper(e, "channel_tag"); @@ -1334,24 +1296,21 @@ config_migrate_v20 ( void ) /* * v20 -> v21 : epggrab changes */ -static void -config_migrate_v21 ( void ) -{ - htsmsg_t *c, *m, *e, *a; - htsmsg_field_t *f; - const char *str; - int64_t s64; +static void config_migrate_v21(void) { + htsmsg_t * c, *m, *e, *a; + htsmsg_field_t* f; + const char* str; + int64_t s64; if ((c = hts_settings_load_r(1, "epggrab/config")) != NULL) { str = htsmsg_get_str(c, "module"); - m = htsmsg_get_map(c, "mod_enabled"); - e = htsmsg_create_map(); + m = htsmsg_get_map(c, "mod_enabled"); + e = htsmsg_create_map(); if (m) { HTSMSG_FOREACH(f, m) { s64 = 0; htsmsg_field_get_s64(f, &s64); - if ((s64 || !strcmp(str ?: "", htsmsg_field_name(f))) && - htsmsg_field_name(f)[0]) { + if ((s64 || !strcmp(str ?: "", htsmsg_field_name(f))) && htsmsg_field_name(f)[0]) { a = htsmsg_create_map(); htsmsg_add_bool(a, "enabled", 1); htsmsg_add_msg(e, htsmsg_field_name(f), a); @@ -1369,11 +1328,9 @@ config_migrate_v21 ( void ) /* * v21 -> v22 : epggrab missing changes */ -static void -config_migrate_v22 ( void ) -{ - htsmsg_t *c; - uint32_t u32; +static void config_migrate_v22(void) { + htsmsg_t* c; + uint32_t u32; if ((c = hts_settings_load("epggrab/config")) != NULL) { if (htsmsg_get_u32(c, "epgdb_periodicsave", &u32) == 0) @@ -1392,20 +1349,19 @@ config_migrate_v22 ( void ) /* * v21 -> v23 : epggrab xmltv/pyepg channels */ -static void -config_migrate_v23_one ( const char *modname ) -{ - htsmsg_t *c, *m, *n; - htsmsg_field_t *f; - uint32_t maj, min; - int64_t num; - tvh_uuid_t u; - char ubuf[UUID_HEX_SIZE]; +static void config_migrate_v23_one(const char* modname) { + htsmsg_t * c, *m, *n; + htsmsg_field_t* f; + uint32_t maj, min; + int64_t num; + tvh_uuid_t u; + char ubuf[UUID_HEX_SIZE]; if ((c = hts_settings_load_r(1, "epggrab/%s/channels", modname)) != NULL) { HTSMSG_FOREACH(f, c) { m = htsmsg_field_get_map(f); - if (m == NULL) continue; + if (m == NULL) + continue; n = htsmsg_copy(m); htsmsg_add_str(n, "id", htsmsg_field_name(f)); maj = htsmsg_get_u32_or_default(m, "major", 0); @@ -1424,18 +1380,14 @@ config_migrate_v23_one ( const char *modname ) } } -static void -config_migrate_v23 ( void ) -{ +static void config_migrate_v23(void) { config_migrate_v23_one("xmltv"); config_migrate_v23_one("pyepg"); } -static void -config_migrate_v24_helper ( const char **list, htsmsg_t *e, const char *name ) -{ - htsmsg_t *l = htsmsg_create_list(); - const char **p = list; +static void config_migrate_v24_helper(const char** list, htsmsg_t* e, const char* name) { + htsmsg_t* l = htsmsg_create_list(); + const char** p = list; if (!strcmp(name, "dvr") && !htsmsg_get_bool_or_default(e, "failed_dvr", 0)) htsmsg_add_str(l, NULL, "failed"); for (p = list; *p; p += 2) @@ -1446,28 +1398,26 @@ config_migrate_v24_helper ( const char **list, htsmsg_t *e, const char *name ) htsmsg_add_msg(e, name, l); } -static void -config_migrate_v24 ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - static const char *streaming_list[] = { - "streaming", "basic", - "adv_streaming", "advanced", - "htsp_streaming", "htsp", - NULL - }; - static const char *dvr_list[] = { - "dvr", "basic", - "htsp_dvr", "htsp", - "all_dvr", "all", - "all_rw_dvr", "all_rw", - "failed_dvr", "failed", - NULL - }; +static void config_migrate_v24(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + static const char* streaming_list[] = + {"streaming", "basic", "adv_streaming", "advanced", "htsp_streaming", "htsp", NULL}; + static const char* dvr_list[] = {"dvr", + "basic", + "htsp_dvr", + "htsp", + "all_dvr", + "all", + "all_rw_dvr", + "all_rw", + "failed_dvr", + "failed", + NULL}; if ((c = hts_settings_load("accesscontrol")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; config_migrate_v24_helper(streaming_list, e, "streaming"); config_migrate_v24_helper(dvr_list, e, "dvr"); hts_settings_save(e, "accesscontrol/%s", htsmsg_field_name(f)); @@ -1479,30 +1429,34 @@ config_migrate_v24 ( void ) /* * Perform backup */ -static void -dobackup(const char *oldver) -{ - char outfile[PATH_MAX], cwd[PATH_MAX]; - const char *argv[] = { - "/usr/bin/tar", "cjf", outfile, - "--exclude", "backup", - "--exclude", "recordings", - "--exclude", "epggrab/*.sock", - "--exclude", "timeshift/buffer", - "--exclude", "imagecache/meta", - "--exclude", "imagecache/data", - ".", NULL - }; - const char *root = hts_settings_get_root(); - char errtxt[128]; - const char **arg; - pid_t pid; - int code; +static void dobackup(const char* oldver) { + char outfile[PATH_MAX], cwd[PATH_MAX]; + const char* argv[] = {"/usr/bin/tar", + "cjf", + outfile, + "--exclude", + "backup", + "--exclude", + "recordings", + "--exclude", + "epggrab/*.sock", + "--exclude", + "timeshift/buffer", + "--exclude", + "imagecache/meta", + "--exclude", + "imagecache/data", + ".", + NULL}; + const char* root = hts_settings_get_root(); + char errtxt[128]; + const char** arg; + pid_t pid; + int code; assert(root); - tvhinfo(LS_CONFIG, "backup: migrating config from %s (running %s)", - oldver, tvheadend_version); + tvhinfo(LS_CONFIG, "backup: migrating config from %s (running %s)", oldver, tvheadend_version); if (getcwd(cwd, sizeof(cwd)) == NULL) { tvherror(LS_CONFIG, "unable to get the current working directory"); @@ -1528,11 +1482,10 @@ dobackup(const char *oldver) goto fatal; } - snprintf(outfile, sizeof(outfile), "%s/backup/%s.tar.bz2", - root, oldver); + snprintf(outfile, sizeof(outfile), "%s/backup/%s.tar.bz2", root, oldver); tvhinfo(LS_CONFIG, "backup: running, output file %s", outfile); - if (spawnv(argv[0], (void *)argv, &pid, 1, 1)) { + if (spawnv(argv[0], (void*)argv, &pid, 1, 1)) { code = -ENOENT; } else { while ((code = spawn_reap(pid, errtxt, sizeof(errtxt))) == -EAGAIN) @@ -1544,7 +1497,7 @@ dobackup(const char *oldver) if (code) { htsbuf_queue_t q; - char *s; + char* s; htsbuf_queue_init(&q, 0); for (arg = argv; *arg; arg++) { htsbuf_append_str(&q, *arg); @@ -1577,41 +1530,37 @@ fatal: /* * Migration table */ -static const config_migrate_t config_migrate_table[] = { - config_migrate_v1, - config_migrate_v2, - config_migrate_v3, - config_migrate_v3, // Re-run due to bug in previous version of function - config_migrate_v5, - config_migrate_v6, - config_migrate_v7, - config_migrate_v8, - config_migrate_v9, - config_migrate_v10, - config_migrate_v11, - config_migrate_v12, - config_migrate_v13, - config_migrate_v14, - config_migrate_v15, - config_migrate_v16, - config_migrate_v17, - config_migrate_v18, - config_migrate_v19, - config_migrate_v20, - config_migrate_v21, - config_migrate_v22, - config_migrate_v23, - config_migrate_v24 -}; +static const config_migrate_t config_migrate_table[] = {config_migrate_v1, + config_migrate_v2, + config_migrate_v3, + config_migrate_v3, // Re-run due to bug in previous version of function + config_migrate_v5, + config_migrate_v6, + config_migrate_v7, + config_migrate_v8, + config_migrate_v9, + config_migrate_v10, + config_migrate_v11, + config_migrate_v12, + config_migrate_v13, + config_migrate_v14, + config_migrate_v15, + config_migrate_v16, + config_migrate_v17, + config_migrate_v18, + config_migrate_v19, + config_migrate_v20, + config_migrate_v21, + config_migrate_v22, + config_migrate_v23, + config_migrate_v24}; /* * Perform migrations (if required) */ -static int -config_migrate ( int backup ) -{ - uint32_t v; - const char *s; +static int config_migrate(int backup) { + uint32_t v; + const char* s; /* Get the current version */ v = config.version; @@ -1638,8 +1587,8 @@ config_migrate ( int backup ) } /* Run migrations */ - for ( ; v < ARRAY_SIZE(config_migrate_table); v++) { - tvhinfo(LS_CONFIG, "migrating config from v%d to v%d", v, v+1); + for (; v < ARRAY_SIZE(config_migrate_table); v++) { + tvhinfo(LS_CONFIG, "migrating config from v%d to v%d", v, v + 1); config_migrate_table[v](); } @@ -1654,19 +1603,22 @@ update: /* * */ -static void -config_check_one ( const char *dir ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; +static void config_check_one(const char* dir) { + htsmsg_t * c, *e; + htsmsg_field_t* f; if (!(c = hts_settings_load(dir))) return; HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if (strlen(htsmsg_field_name(f)) != UUID_HEX_SIZE - 1) { - tvherror(LS_START, "filename %s/%s/%s is invalid", hts_settings_get_root(), dir, htsmsg_field_name(f)); + tvherror(LS_START, + "filename %s/%s/%s is invalid", + hts_settings_get_root(), + dir, + htsmsg_field_name(f)); exit(1); } } @@ -1676,9 +1628,7 @@ config_check_one ( const char *dir ) /* * Perform a simple check for UUID files */ -static void -config_check ( void ) -{ +static void config_check(void) { config_check_one("accesscontrol"); config_check_one("channel/config"); config_check_one("channel/tag"); @@ -1694,11 +1644,11 @@ config_check ( void ) static int config_newcfg = 0; -static char *config_get_dir ( uid_t uid ) -{ - char hts_home[PATH_MAX + sizeof("/.hts/tvheadend")]; /* Must be largest of the 3 config strings! */ - char config_home[PATH_MAX]; - char home_dir[PATH_MAX]; +static char* config_get_dir(uid_t uid) { + char + hts_home[PATH_MAX + sizeof("/.hts/tvheadend")]; /* Must be largest of the 3 config strings! */ + char config_home[PATH_MAX]; + char home_dir[PATH_MAX]; struct stat st; if (uid == -1) @@ -1733,9 +1683,9 @@ static char *config_get_dir ( uid_t uid ) tvherror(LS_CONFIG, ".hts/tvheadend exists, but is not a directory"); return NULL; } - tvhwarn(LS_CONFIG, "Found legacy '.hts/tvheadend', consider moving this to '.config/hts' instead."); - } else if ((realpath(getenv("XDG_CONFIG_HOME"), config_home) != NULL) && - (config_home[0] != 0)) { + tvhwarn(LS_CONFIG, + "Found legacy '.hts/tvheadend', consider moving this to '.config/hts' instead."); + } else if ((realpath(getenv("XDG_CONFIG_HOME"), config_home) != NULL) && (config_home[0] != 0)) { snprintf(hts_home, sizeof(hts_home), "%s/hts", config_home); } else { snprintf(hts_home, sizeof(hts_home), "%s/.config/hts", home_dir); @@ -1744,39 +1694,36 @@ static char *config_get_dir ( uid_t uid ) return strndup(hts_home, sizeof(hts_home)); } -void -config_boot - ( const char *path, gid_t gid, uid_t uid, const char *http_user_agent ) -{ - struct stat st; - htsmsg_t *config2; - htsmsg_field_t *f; - const char *s; +void config_boot(const char* path, gid_t gid, uid_t uid, const char* http_user_agent) { + struct stat st; + htsmsg_t* config2; + htsmsg_field_t* f; + const char* s; memset(&config, 0, sizeof(config)); - config.idnode.in_class = &config_class; - config.ui_quicktips = 1; - config.http_auth = HTTP_AUTH_DIGEST; - config.http_auth_algo = HTTP_AUTH_ALGO_MD5; - config.proxy = 0; - config.realm = strdup("tvheadend"); - config.info_area = strdup("login,storage,time"); - config.cookie_expires = 7; - config.ticket_expires = 5 * 60; - config.dscp = -1; + config.idnode.in_class = &config_class; + config.ui_quicktips = 1; + config.http_auth = HTTP_AUTH_DIGEST; + config.http_auth_algo = HTTP_AUTH_ALGO_MD5; + config.proxy = 0; + config.realm = strdup("tvheadend"); + config.info_area = strdup("login,storage,time"); + config.cookie_expires = 7; + config.ticket_expires = 5 * 60; + config.dscp = -1; config.descrambler_buffer = 9000; - config.epg_compress = 1; - config.epg_cut_window = 5*60; - config.epg_update_window = 24*3600; - config_scanfile_ok = 0; - config.theme_ui = strdup("blue"); - config.chname_num = 1; - config.iptv_tpool_count = 2; - config.date_mask = strdup(""); - config.label_formatting = 0; - config.hdhomerun_ip = strdup(""); - config.local_ip = strdup(""); - config.local_port = 0; + config.epg_compress = 1; + config.epg_cut_window = 5 * 60; + config.epg_update_window = 24 * 3600; + config_scanfile_ok = 0; + config.theme_ui = strdup("blue"); + config.chname_num = 1; + config.iptv_tpool_count = 2; + config.date_mask = strdup(""); + config.label_formatting = 0; + config.hdhomerun_ip = strdup(""); + config.local_ip = strdup(""); + config.local_port = 0; /* Generate default */ if (!path) @@ -1795,18 +1742,24 @@ config_boot if (stat(config.confdir, &st)) { config_newcfg = 1; if (makedirs(LS_CONFIG, config.confdir, 0700, 1, gid, uid)) { - tvhwarn(LS_START, "failed to create settings directory %s," - " settings will not be saved", config.confdir); + tvhwarn(LS_START, + "failed to create settings directory %s," + " settings will not be saved", + config.confdir); return; } } /* And is usable */ else if (access(config.confdir, R_OK | W_OK)) { - tvhwarn(LS_START, "configuration path %s is not r/w" - " for UID:%d GID:%d [e=%s]," - " settings will not be saved", - config.confdir, getuid(), getgid(), strerror(errno)); + tvhwarn(LS_START, + "configuration path %s is not r/w" + " for UID:%d GID:%d [e=%s]," + " settings will not be saved", + config.confdir, + getuid(), + getgid(), + strerror(errno)); return; } @@ -1836,13 +1789,13 @@ config_boot if (f && f->hmf_type == HMF_STR) { s = htsmsg_get_str(config2, "language"); if (s) { - htsmsg_t *m = htsmsg_csv_2_list(s, ','); + htsmsg_t* m = htsmsg_csv_2_list(s, ','); htsmsg_delete_field(config2, "language"); htsmsg_add_msg(config2, "language", m); } } config.version = htsmsg_get_u32_or_default(config2, "config", 0); - s = htsmsg_get_str(config2, "full_version"); + s = htsmsg_get_str(config2, "full_version"); if (s) config.full_version = strdup(s); idnode_load(&config.idnode, config2); @@ -1857,8 +1810,7 @@ config_boot config.realm = strdup("tvheadend"); if (tvh_str_default(config.http_server_name, NULL) == NULL) config.http_server_name = strdup("HTS/tvheadend"); - if ((config.http_user_agent && - strncmp(config.http_user_agent, "TVHeadend/", 10) == 0) || + if ((config.http_user_agent && strncmp(config.http_user_agent, "TVHeadend/", 10) == 0) || tvh_str_default(config.http_user_agent, NULL) == NULL) { char buf[1024]; @@ -1869,16 +1821,18 @@ config_boot config_muxconfpath_notify(&config.idnode, NULL); } -void -config_init ( int backup ) -{ - const char *path = hts_settings_get_root(); +void config_init(int backup) { + const char* path = hts_settings_get_root(); if (path == NULL || access(path, R_OK | W_OK)) { - tvhwarn(LS_START, "configuration path %s is not r/w" - " for UID:%d GID:%d [e=%s]," - " settings will not be saved", - path, getuid(), getgid(), strerror(errno)); + tvhwarn(LS_START, + "configuration path %s is not r/w" + " for UID:%d GID:%d [e=%s]," + " settings will not be saved", + path, + getuid(), + getgid(), + strerror(errno)); return; } @@ -1891,7 +1845,7 @@ config_init ( int backup ) tvh_str_set(&config.http_server_name, "HTS/tvheadend"); idnode_changed(&config.idnode); - /* Perform migrations */ + /* Perform migrations */ } else { if (config_migrate(backup)) config_check(); @@ -1899,8 +1853,7 @@ config_init ( int backup ) tvhinfo(LS_CONFIG, "loaded"); } -void config_done ( void ) -{ +void config_done(void) { /* note: tvhlog is inactive !!! */ free(config.confdir); free(config.wizard); @@ -1927,10 +1880,8 @@ void config_done ( void ) * Config Class * *************************************************************************/ -static htsmsg_t * -config_class_save(idnode_t *self, char *filename, size_t fsize) -{ - htsmsg_t *c = htsmsg_create_map(); +static htsmsg_t* config_class_save(idnode_t* self, char* filename, size_t fsize) { + htsmsg_t* c = htsmsg_create_map(); idnode_save(&config.idnode, c); #if ENABLE_SATIP_SERVER idnode_save(&satip_server_conf.idnode, c); @@ -1940,11 +1891,9 @@ config_class_save(idnode_t *self, char *filename, size_t fsize) return c; } -static int -config_class_cors_origin_set ( void *o, const void *v ) -{ - const char *s = v; - url_t u; +static int config_class_cors_origin_set(void* o, const void* v) { + const char* s = v; + url_t u; while (s && *s && *s <= ' ') s++; @@ -1961,7 +1910,7 @@ config_class_cors_origin_set ( void *o, const void *v ) else snprintf(prop_sbuf, PROP_SBUF_LEN, "%s://%s", u.scheme, u.host); } else { -wrong: + wrong: prop_sbuf[0] = '\0'; } urlreset(&u); @@ -1974,16 +1923,12 @@ wrong: return 0; } -static const void * -config_class_language_get ( void *o ) -{ +static const void* config_class_language_get(void* o) { return htsmsg_csv_2_list(config.language, ','); } -static int -config_class_language_set ( void *o, const void *v ) -{ - char *s = htsmsg_list_2_csv((htsmsg_t *)v, ',', 3); +static int config_class_language_set(void* o, const void* v) { + char* s = htsmsg_list_2_csv((htsmsg_t*)v, ',', 3); if (strcmp(s ?: "", config.language ?: "")) { free(config.language); config.language = s; @@ -1994,25 +1939,19 @@ config_class_language_set ( void *o, const void *v ) return 0; } -static htsmsg_t * -config_class_language_list ( void *o, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "language/list"); +static htsmsg_t* config_class_language_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "language/list"); return m; } -static const void * -config_class_info_area_get ( void *o ) -{ +static const void* config_class_info_area_get(void* o) { return htsmsg_csv_2_list(config.info_area, ','); } -static int -config_class_info_area_set ( void *o, const void *v ) -{ - char *s = htsmsg_list_2_csv((htsmsg_t *)v, ',', 3); +static int config_class_info_area_set(void* o, const void* v) { + char* s = htsmsg_list_2_csv((htsmsg_t*)v, ',', 3); if (strcmp(s ?: "", config.info_area ?: "")) { free(config.info_area); config.info_area = s; @@ -2024,112 +1963,94 @@ config_class_info_area_set ( void *o, const void *v ) } static void -config_class_info_area_list1 ( htsmsg_t *m, const char *key, - const char *val, const char *lang ) -{ - htsmsg_t *e = htsmsg_create_key_val(key, tvh_gettext_lang(lang, val)); +config_class_info_area_list1(htsmsg_t* m, const char* key, const char* val, const char* lang) { + htsmsg_t* e = htsmsg_create_key_val(key, tvh_gettext_lang(lang, val)); htsmsg_add_msg(m, NULL, e); } -static htsmsg_t * -config_class_info_area_list ( void *o, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_list(); +static htsmsg_t* config_class_info_area_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_list(); config_class_info_area_list1(m, "login", N_("Login/Logout"), lang); config_class_info_area_list1(m, "storage", N_("Storage space"), lang); config_class_info_area_list1(m, "time", N_("Time"), lang); return m; } -static htsmsg_t * -config_class_dscp_list ( void *o, const char *lang ) -{ +static htsmsg_t* config_class_dscp_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Default"), -1 }, - { N_("CS0"), IPTOS_CLASS_CS0 }, - { N_("CS1"), IPTOS_CLASS_CS1 }, - { N_("AF11"), IPTOS_DSCP_AF11 }, - { N_("AF12"), IPTOS_DSCP_AF12 }, - { N_("AF13"), IPTOS_DSCP_AF13 }, - { N_("CS2"), IPTOS_CLASS_CS2 }, - { N_("AF21"), IPTOS_DSCP_AF21 }, - { N_("AF22"), IPTOS_DSCP_AF22 }, - { N_("AF23"), IPTOS_DSCP_AF23 }, - { N_("CS3"), IPTOS_CLASS_CS3 }, - { N_("AF31"), IPTOS_DSCP_AF31 }, - { N_("AF32"), IPTOS_DSCP_AF32 }, - { N_("AF33"), IPTOS_DSCP_AF33 }, - { N_("CS4"), IPTOS_CLASS_CS4 }, - { N_("AF41"), IPTOS_DSCP_AF41 }, - { N_("AF42"), IPTOS_DSCP_AF42 }, - { N_("AF43"), IPTOS_DSCP_AF43 }, - { N_("CS5"), IPTOS_CLASS_CS5 }, - { N_("EF"), IPTOS_DSCP_EF }, - { N_("CS6"), IPTOS_CLASS_CS6 }, - { N_("CS7"), IPTOS_CLASS_CS7 }, + {N_("Default"), -1}, + {N_("CS0"), IPTOS_CLASS_CS0}, + {N_("CS1"), IPTOS_CLASS_CS1}, + {N_("AF11"), IPTOS_DSCP_AF11}, + {N_("AF12"), IPTOS_DSCP_AF12}, + {N_("AF13"), IPTOS_DSCP_AF13}, + {N_("CS2"), IPTOS_CLASS_CS2}, + {N_("AF21"), IPTOS_DSCP_AF21}, + {N_("AF22"), IPTOS_DSCP_AF22}, + {N_("AF23"), IPTOS_DSCP_AF23}, + {N_("CS3"), IPTOS_CLASS_CS3}, + {N_("AF31"), IPTOS_DSCP_AF31}, + {N_("AF32"), IPTOS_DSCP_AF32}, + {N_("AF33"), IPTOS_DSCP_AF33}, + {N_("CS4"), IPTOS_CLASS_CS4}, + {N_("AF41"), IPTOS_DSCP_AF41}, + {N_("AF42"), IPTOS_DSCP_AF42}, + {N_("AF43"), IPTOS_DSCP_AF43}, + {N_("CS5"), IPTOS_CLASS_CS5}, + {N_("EF"), IPTOS_DSCP_EF}, + {N_("CS6"), IPTOS_CLASS_CS6}, + {N_("CS7"), IPTOS_CLASS_CS7}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -config_class_uilevel ( void *o, const char *lang ) -{ +static htsmsg_t* config_class_uilevel(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Basic"), UILEVEL_BASIC }, - { N_("Advanced"), UILEVEL_ADVANCED }, - { N_("Expert"), UILEVEL_EXPERT }, + {N_("Basic"), UILEVEL_BASIC}, + {N_("Advanced"), UILEVEL_ADVANCED}, + {N_("Expert"), UILEVEL_EXPERT}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -config_class_chiconscheme_list ( void *o, const char *lang ) -{ +static htsmsg_t* config_class_chiconscheme_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("No scheme"), CHICON_NONE }, - { N_("All lower-case"), CHICON_LOWERCASE }, - { N_("Service name picons"), CHICON_SVCNAME }, + {N_("No scheme"), CHICON_NONE}, + {N_("All lower-case"), CHICON_LOWERCASE}, + {N_("Service name picons"), CHICON_SVCNAME}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -config_class_piconscheme_list ( void *o, const char *lang ) -{ +static htsmsg_t* config_class_piconscheme_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Standard"), PICON_STANDARD }, - { N_("Force service type to 1"), PICON_ISVCTYPE }, + {N_("Standard"), PICON_STANDARD}, + {N_("Force service type to 1"), PICON_ISVCTYPE}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -config_class_http_auth_list ( void *o, const char *lang ) -{ +static htsmsg_t* config_class_http_auth_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Plain (insecure)"), HTTP_AUTH_PLAIN }, - { N_("Digest"), HTTP_AUTH_DIGEST }, - { N_("Both plain and digest"), HTTP_AUTH_PLAIN_DIGEST }, + {N_("Plain (insecure)"), HTTP_AUTH_PLAIN}, + {N_("Digest"), HTTP_AUTH_DIGEST}, + {N_("Both plain and digest"), HTTP_AUTH_PLAIN_DIGEST}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -config_class_http_auth_algo_list ( void *o, const char *lang ) -{ +static htsmsg_t* config_class_http_auth_algo_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("MD5"), HTTP_AUTH_ALGO_MD5 }, - { N_("SHA-256"), HTTP_AUTH_ALGO_SHA256 }, - { N_("SHA-512/256"), HTTP_AUTH_ALGO_SHA512_256 }, + {N_("MD5"), HTTP_AUTH_ALGO_MD5}, + {N_("SHA-256"), HTTP_AUTH_ALGO_SHA256}, + {N_("SHA-512/256"), HTTP_AUTH_ALGO_SHA512_256}, }; return strtab2htsmsg(tab, 1, lang); } #if ENABLE_MPEGTS_DVB -static void -config_muxconfpath_notify_cb(void *opaque, int disarmed) -{ - char *muxconf_path = opaque; +static void config_muxconfpath_notify_cb(void* opaque, int disarmed) { + char* muxconf_path = opaque; if (disarmed) { free(muxconf_path); return; @@ -2140,17 +2061,14 @@ config_muxconfpath_notify_cb(void *opaque, int disarmed) } #endif -static void -config_muxconfpath_notify ( void *o, const char *lang ) -{ +static void config_muxconfpath_notify(void* o, const char* lang) { #if ENABLE_MPEGTS_DVB config_scanfile_ok = 1; tasklet_arm_alloc(config_muxconfpath_notify_cb, - config.muxconf_path ? strdup(config.muxconf_path) : NULL); + config.muxconf_path ? strdup(config.muxconf_path) : NULL); #endif } - CLASS_DOC(config) PROP_DOC(config_channelicon_path) PROP_DOC(config_channelname_scheme) @@ -2159,632 +2077,563 @@ PROP_DOC(config_picon_servicetype) PROP_DOC(viewlevel_config) PROP_DOC(themes) -const idclass_t config_class = { - .ic_snode = &config.idnode, - .ic_class = "config", - .ic_caption = N_("Configuration - Base"), - .ic_event = "config", - .ic_perm_def = ACCESS_ADMIN, - .ic_doc = tvh_doc_config_class, - .ic_save = config_class_save, - .ic_groups = (const property_group_t[]) { - { - .name = N_("Server Settings"), - .number = 1, - }, - { - .name = N_("Web Interface Settings"), - .number = 2, - }, - { - .name = N_("EPG Settings"), - .number = 3, - }, - { - .name = N_("Channel icon/Picon Settings"), - .number = 4, - }, - { - .name = N_("HTTP Server Settings"), - .number = 5, - }, - { - .name = N_("HDHomeRun"), - .number = 6, - }, - { - .name = N_("Miscellaneous Settings"), - .number = 7, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "server_name", - .name = N_("Tvheadend server name"), - .desc = N_("Set the name of the server so you can distinguish " - "multiple instances apart."), - .off = offsetof(config_t, server_name), - .group = 1 - }, - { - .type = PT_U32, - .id = "version", - .name = N_("Configuration version"), - .desc = N_("The current configuration version."), - .off = offsetof(config_t, version), - .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, - .group = 1 - }, - { - .type = PT_STR, - .id = "full_version", - .name = N_("Last updated from"), - .desc = N_("The version of Tvheadend that last updated the " - "config."), - .off = offsetof(config_t, full_version), - .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, - .group = 1 - }, - { - .type = PT_STR, - .id = "language_ui", - .name = N_("Default language"), - .desc = N_("The default language to use if the user " - " language isn't set (in the Access Entries tab)."), - .list = language_get_ui_list, - .off = offsetof(config_t, language_ui), - .group = 2 - }, - { - .type = PT_STR, - .id = "theme_ui", - .name = N_("Theme"), - .desc = N_("The default web interface theme, if a user-specific " - "one isn't set (in the Access Entries tab)."), - .doc = prop_doc_themes, - .list = theme_get_ui_list, - .off = offsetof(config_t, theme_ui), - .opts = PO_DOC_NLIST, - .group = 2 - }, - { - .type = PT_BOOL, - .id = "ui_quicktips", - .name = N_("Tooltips"), - .desc = N_("Enable/Disable web interface mouse-over tooltips."), - .off = offsetof(config_t, ui_quicktips), - .opts = PO_ADVANCED, - .group = 2 - }, - { - .type = PT_INT, - .id = "uilevel", - .name = N_("Default view level"), - .desc = N_("The default interface view level (next to the " - "Help button)."), - .doc = prop_doc_viewlevel_config, - .off = offsetof(config_t, uilevel), - .list = config_class_uilevel, - .opts = PO_DOC_NLIST, - .group = 2 - }, - { - .type = PT_BOOL, - .id = "uilevel_nochange", - .name = N_("Persistent view level"), - .desc = N_("Prevent users from overriding the view level " - "setting. This option shows or hides the View level " - "drop-down (next to the Help button)."), - .off = offsetof(config_t, uilevel_nochange), - .opts = PO_ADVANCED, - .group = 2 - }, - { - .type = PT_BOOL, - .id = "caclient_ui", - .name = N_("Conditional Access (for advanced view level)"), - .desc = N_("Enable/Disable the CAs (conditional accesses) tab " - "for the advanced view level. By default, it's " - "visible only to the Expert level."), - .off = offsetof(config_t, caclient_ui), - .opts = PO_ADVANCED, - .group = 2 - }, - { - .type = PT_STR, - .islist = 1, - .id = "info_area", - .name = N_("Information area"), - .desc = N_("Show, hide and sort the various details that " - "appear on the interface next to the About tab."), - .set = config_class_info_area_set, - .get = config_class_info_area_get, - .list = config_class_info_area_list, - .opts = PO_LORDER | PO_ADVANCED | PO_DOC_NLIST, - .group = 2 - }, - { - .type = PT_BOOL, - .id = "chname_num", - .name = N_("Channel name with numbers"), - .desc = N_("Add channel numbers to the channel name list"), - .off = offsetof(config_t, chname_num), - .group = 2, - .def.i = 1 - }, - { - .type = PT_BOOL, - .id = "chname_src", - .name = N_("Channel name with sources"), - .desc = N_("Add sources (like DVB-T string) to the channel name list"), - .off = offsetof(config_t, chname_src), - .group = 2 - }, - { - .type = PT_STR, - .id = "date_mask", - .name = N_("Custom date Format"), - .desc = N_("Custom date mask like (%yyyy-%M-%dd %h:%m:%s)"), - .opts = PO_ADVANCED, - .off = offsetof(config_t, date_mask), - .group = 2, - }, - { - .type = PT_BOOL, - .id = "label_formatting", - .name = N_("Kodi label formatting support"), - .desc = N_("Enable parser for kodi label formatting"), - .off = offsetof(config_t, label_formatting), - .group = 2 - }, - { - .type = PT_STR, - .islist = 1, - .id = "language", - .name = N_("Default language(s)"), - .desc = N_("Select the list of languages (in order of " - "priority) to be used for supplying EPG information " - "to clients that don't provide their own " - "configuration."), - .set = config_class_language_set, - .get = config_class_language_get, - .list = config_class_language_list, - .opts = PO_LORDER, - .group = 3 - }, +const idclass_t config_class = {.ic_snode = &config.idnode, + .ic_class = "config", + .ic_caption = N_("Configuration - Base"), + .ic_event = "config", + .ic_perm_def = ACCESS_ADMIN, + .ic_doc = tvh_doc_config_class, + .ic_save = config_class_save, + .ic_groups = (const property_group_t[]){{ + .name = N_("Server Settings"), + .number = 1, + }, + { + .name = N_("Web Interface Settings"), + .number = 2, + }, + { + .name = N_("EPG Settings"), + .number = 3, + }, + { + .name = N_("Channel icon/Picon Settings"), + .number = 4, + }, + { + .name = N_("HTTP Server Settings"), + .number = 5, + }, + { + .name = N_("HDHomeRun"), + .number = 6, + }, + { + .name = N_("Miscellaneous Settings"), + .number = 7, + }, + {}}, + .ic_properties = (const property_t[]){ + {.type = PT_STR, + .id = "server_name", + .name = N_("Tvheadend server name"), + .desc = N_("Set the name of the server so you can distinguish " + "multiple instances apart."), + .off = offsetof(config_t, server_name), + .group = 1}, + {.type = PT_U32, + .id = "version", + .name = N_("Configuration version"), + .desc = N_("The current configuration version."), + .off = offsetof(config_t, version), + .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, + .group = 1}, + {.type = PT_STR, + .id = "full_version", + .name = N_("Last updated from"), + .desc = N_("The version of Tvheadend that last updated the " + "config."), + .off = offsetof(config_t, full_version), + .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, + .group = 1}, + {.type = PT_STR, + .id = "language_ui", + .name = N_("Default language"), + .desc = N_("The default language to use if the user " + " language isn't set (in the Access Entries tab)."), + .list = language_get_ui_list, + .off = offsetof(config_t, language_ui), + .group = 2}, + {.type = PT_STR, + .id = "theme_ui", + .name = N_("Theme"), + .desc = N_("The default web interface theme, if a user-specific " + "one isn't set (in the Access Entries tab)."), + .doc = prop_doc_themes, + .list = theme_get_ui_list, + .off = offsetof(config_t, theme_ui), + .opts = PO_DOC_NLIST, + .group = 2}, + {.type = PT_BOOL, + .id = "ui_quicktips", + .name = N_("Tooltips"), + .desc = N_("Enable/Disable web interface mouse-over tooltips."), + .off = offsetof(config_t, ui_quicktips), + .opts = PO_ADVANCED, + .group = 2}, + {.type = PT_INT, + .id = "uilevel", + .name = N_("Default view level"), + .desc = N_("The default interface view level (next to the " + "Help button)."), + .doc = prop_doc_viewlevel_config, + .off = offsetof(config_t, uilevel), + .list = config_class_uilevel, + .opts = PO_DOC_NLIST, + .group = 2}, + {.type = PT_BOOL, + .id = "uilevel_nochange", + .name = N_("Persistent view level"), + .desc = N_("Prevent users from overriding the view level " + "setting. This option shows or hides the View level " + "drop-down (next to the Help button)."), + .off = offsetof(config_t, uilevel_nochange), + .opts = PO_ADVANCED, + .group = 2}, + {.type = PT_BOOL, + .id = "caclient_ui", + .name = N_("Conditional Access (for advanced view level)"), + .desc = N_("Enable/Disable the CAs (conditional accesses) tab " + "for the advanced view level. By default, it's " + "visible only to the Expert level."), + .off = offsetof(config_t, caclient_ui), + .opts = PO_ADVANCED, + .group = 2}, + {.type = PT_STR, + .islist = 1, + .id = "info_area", + .name = N_("Information area"), + .desc = N_("Show, hide and sort the various details that " + "appear on the interface next to the About tab."), + .set = config_class_info_area_set, + .get = config_class_info_area_get, + .list = config_class_info_area_list, + .opts = PO_LORDER | PO_ADVANCED | PO_DOC_NLIST, + .group = 2}, + {.type = PT_BOOL, + .id = "chname_num", + .name = N_("Channel name with numbers"), + .desc = N_("Add channel numbers to the channel name list"), + .off = offsetof(config_t, chname_num), + .group = 2, + .def.i = 1}, + {.type = PT_BOOL, + .id = "chname_src", + .name = N_("Channel name with sources"), + .desc = N_("Add sources (like DVB-T string) to the channel name list"), + .off = offsetof(config_t, chname_src), + .group = 2}, + { + .type = PT_STR, + .id = "date_mask", + .name = N_("Custom date Format"), + .desc = N_("Custom date mask like (%yyyy-%M-%dd %h:%m:%s)"), + .opts = PO_ADVANCED, + .off = offsetof(config_t, date_mask), + .group = 2, + }, + {.type = PT_BOOL, + .id = "label_formatting", + .name = N_("Kodi label formatting support"), + .desc = N_("Enable parser for kodi label formatting"), + .off = offsetof(config_t, label_formatting), + .group = 2}, + {.type = PT_STR, + .islist = 1, + .id = "language", + .name = N_("Default language(s)"), + .desc = N_("Select the list of languages (in order of " + "priority) to be used for supplying EPG information " + "to clients that don't provide their own " + "configuration."), + .set = config_class_language_set, + .get = config_class_language_get, + .list = config_class_language_list, + .opts = PO_LORDER, + .group = 3}, #if ENABLE_ZLIB - { - .type = PT_BOOL, - .id = "epg_compress", - .name = N_("Compress EPG database"), - .desc = N_("Compress the EPG database to reduce disk I/O " - "and space."), - .off = offsetof(config_t, epg_compress), - .opts = PO_EXPERT, - .def.i = 1, - .group = 3 - }, + {.type = PT_BOOL, + .id = "epg_compress", + .name = N_("Compress EPG database"), + .desc = N_("Compress the EPG database to reduce disk I/O " + "and space."), + .off = offsetof(config_t, epg_compress), + .opts = PO_EXPERT, + .def.i = 1, + .group = 3}, #endif - { - .type = PT_U32, - .id = "epg_cutwindow", - .name = N_("EPG overlap cut"), - .desc = N_("The time window to cut the stop time from the overlapped event in seconds."), - .off = offsetof(config_t, epg_cut_window), - .opts = PO_EXPERT, - .group = 3 - }, - { - .type = PT_U32, - .id = "epg_window", - .name = N_("EPG update window"), - .desc = N_("Maximum allowed difference between event start time when " - "the EPG event is changed (in seconds)."), - .off = offsetof(config_t, epg_update_window), - .opts = PO_EXPERT, - .group = 3 - }, - { - .type = PT_BOOL, - .id = "prefer_picon", - .name = N_("Prefer picons over channel icons"), - .desc = N_("If both a picon and a channel-specific " - "(e.g. channelname.jpg) icon are defined, prefer the picon."), - .off = offsetof(config_t, prefer_picon), - .opts = PO_ADVANCED, - .group = 4, - }, - { - .type = PT_STR, - .id = "chiconpath", - .name = N_("Channel icon path"), - .desc = N_("Path to an icon for this channel. This can be " - "named however you wish, as either a local " - "(file://) or remote (http://) image. " - "See Help for more infomation."), - .off = offsetof(config_t, chicon_path), - .doc = prop_doc_config_channelicon_path, - .opts = PO_ADVANCED, - .group = 4, - }, - { - .type = PT_INT, - .id = "chiconscheme", - .name = N_("Channel icon name scheme"), - .desc = N_("Scheme to generate the channel icon names " - "(all lower-case, service name picons etc.)."), - .list = config_class_chiconscheme_list, - .doc = prop_doc_config_channelname_scheme, - .off = offsetof(config_t, chicon_scheme), - .opts = PO_ADVANCED | PO_DOC_NLIST, - .group = 4, - }, - { - .type = PT_STR, - .id = "piconpath", - .name = N_("Picon path"), - .desc = N_("Path to a directory (folder) containing your picon " - "collection. See Help for more detailed " - "information."), - .doc = prop_doc_config_picon_path, - .off = offsetof(config_t, picon_path), - .opts = PO_ADVANCED, - .group = 4, - }, - { - .type = PT_INT, - .id = "piconscheme", - .name = N_("Picon name scheme"), - .desc = N_("Select scheme to generate the picon names " - "(standard, force service type to 1)"), - .list = config_class_piconscheme_list, - .doc = prop_doc_config_picon_servicetype, - .off = offsetof(config_t, picon_scheme), - .opts = PO_ADVANCED | PO_DOC_NLIST, - .group = 4, - }, - { - .type = PT_STR, - .id = "http_server_name", - .name = N_("Server name"), - .desc = N_("The server name for 'Server:' HTTP headers."), - .off = offsetof(config_t, http_server_name), - .opts = PO_HIDDEN | PO_EXPERT, - .group = 5 - }, - { - .type = PT_STR, - .id = "http_realm_name", - .name = N_("Realm name"), - .desc = N_("The realm name for HTTP authorization."), - .off = offsetof(config_t, realm), - .opts = PO_HIDDEN | PO_EXPERT, - .group = 5 - }, - { - .type = PT_INT, - .id = "digest", - .name = N_("Authentication type"), - .desc = N_("Digest access authentication is intended as a security trade-off. " - "It is intended to replace unencrypted HTTP basic access authentication. " - "This option should be enabled for standard usage."), - .list = config_class_http_auth_list, - .off = offsetof(config_t, http_auth), - .opts = PO_EXPERT, - .group = 5 - }, - { - .type = PT_INT, - .id = "digest_algo", - .name = N_("Digest hash type"), - .desc = N_("The hash algorithm type for the digest authentication."), - .list = config_class_http_auth_algo_list, - .off = offsetof(config_t, http_auth_algo), - .opts = PO_EXPERT, - .group = 5 - }, - { - .type = PT_U32, - .intextra = INTEXTRA_RANGE(1, 0x7ff, 1), - .id = "cookie_expires", - .name = N_("Cookie expiration (days)"), - .desc = N_("The number of days cookies set by Tvheadend should " - "expire."), - .off = offsetof(config_t, cookie_expires), - .opts = PO_EXPERT, - .group = 5 - }, - { - .type = PT_U32, - .intextra = INTEXTRA_RANGE(30, 3600, 1), - .id = "ticket_expires", - .name = N_("Ticket expiration (seconds)"), - .desc = N_("The number of seconds in which authentication tickets generated by " - "Tvheadend should expire."), - .off = offsetof(config_t, ticket_expires), - .opts = PO_EXPERT, - .group = 5 - }, - { - .type = PT_BOOL, - .id = "proxy", - .name = N_("PROXY protocol & X-Forwarded-For"), - .desc = N_("PROXY protocol is an extension for support incoming " - "TCP connections from a remote server (like a firewall) " - "sending the original IP address of the client. " - "The HTTP header 'X-Forwarded-For' do the same with " - "HTTP connections. Both enable tunneled connections." - "This option should be disabled for standard usage."), - .off = offsetof(config_t, proxy), - .opts = PO_EXPERT, - .group = 5 - }, - { - .type = PT_STR, - .id = "cors_origin", - .name = N_("CORS origin"), - .desc = N_("HTTP CORS (cross-origin resource sharing) origin. This " - "option is usually set when Tvheadend is behind a " - "proxy. Enter the URL (domain or IP address, prefixed " - "with http:// or https://) to allow cross-domain requests."), - .set = config_class_cors_origin_set, - .off = offsetof(config_t, cors_origin), - .opts = PO_EXPERT, - .group = 5 - }, - { - .type = PT_STR, - .id = "hdhomerun_ip", - .name = N_("HDHomerun IP Address"), - .desc = N_("IP address of the HDHomerun device. This is needed if you " - "plan to run TVheadend in a container and you want to stream " - "from an HDHomerun without enabling host networking for " - "the container."), - .off = offsetof(config_t, hdhomerun_ip), - .opts = PO_HIDDEN | PO_EXPERT, - .group = 6 - }, - { - .type = PT_STR, - .id = "local_ip", - .name = N_("Local IP Address"), - .desc = N_("IP of the Docker host. Each HDHomeRun tuner sends data " - "to TVheadend through a socket. This lets you define the " - "IP address that HDHomeRun needs to send to. Leave this " - "blank if you want TVheadend to automatically pick an " - "address."), - .off = offsetof(config_t, local_ip), - .opts = PO_HIDDEN | PO_EXPERT, - .group = 6 - }, - { - .type = PT_INT, - .id = "local_port", - .name = N_("Local Socket Port Number"), - .desc = N_("Starting port number of the UDP listeners. The listeners " - "listen for traffic from the HDHomerun tuners. This is " - "needed if you plan to run TVheadend in a container and " - "you want to stream from an HDHomerun without enabling " - "host networking for the container. Set this to 0 if you " - "want the port numbers to be assigned dynamically. If you " - "have multiple tuners, this will be the start of the port " - "range. For example, if you have 4 tuners and you set this " - "to 9983, then tuner 0 will talk to port 9983, tuner 1 " - "will talk to port 9984, tuner 2 will talk to port 9985, " - "and tuner 3 will talk to port 9986."), - .off = offsetof(config_t, local_port), - .opts = PO_HIDDEN | PO_EXPERT, - .group = 6 - }, - { - .type = PT_U32, - .id = "hdhomerun_server_tuner_count", - .name = N_("Number of tuners to export for HDHomeRun Server Emulation"), - .desc = N_("When Tvheadend is acting as an HDHomeRun Server " - "(emulating an HDHomeRun device for downstream " - "media devices to stream Live TV) then " - "we tell clients that we have this number of tuners. " - "This is necessary since some clients artificially limit " - "connections based on tuner count, even though several " - "channels may share a multiplex on one tuner. " - "The HDHomeRun interface can not distinguish between " - "different types of tuner in a mixed system with " - "satellite, aerial and cable. " - "The actual number or types of tuners used by Tvheadend is " - "not affected by this value. Tvheadend will " - "allocate tuners automatically. " - "Set to zero for Tvheadend to use a default value." - ), - .off = offsetof(config_t, hdhomerun_server_tuner_count), - .opts = PO_EXPERT + {.type = PT_U32, + .id = "epg_cutwindow", + .name = N_("EPG overlap cut"), + .desc = + N_("The time window to cut the stop time from the overlapped event in seconds."), + .off = offsetof(config_t, epg_cut_window), + .opts = PO_EXPERT, + .group = 3}, + {.type = PT_U32, + .id = "epg_window", + .name = N_("EPG update window"), + .desc = N_("Maximum allowed difference between event start time when " + "the EPG event is changed (in seconds)."), + .off = offsetof(config_t, epg_update_window), + .opts = PO_EXPERT, + .group = 3}, + { + .type = PT_BOOL, + .id = "prefer_picon", + .name = N_("Prefer picons over channel icons"), + .desc = N_("If both a picon and a channel-specific " + "(e.g. channelname.jpg) icon are defined, prefer the picon."), + .off = offsetof(config_t, prefer_picon), + .opts = PO_ADVANCED, + .group = 4, + }, + { + .type = PT_STR, + .id = "chiconpath", + .name = N_("Channel icon path"), + .desc = N_("Path to an icon for this channel. This can be " + "named however you wish, as either a local " + "(file://) or remote (http://) image. " + "See Help for more infomation."), + .off = offsetof(config_t, chicon_path), + .doc = prop_doc_config_channelicon_path, + .opts = PO_ADVANCED, + .group = 4, + }, + { + .type = PT_INT, + .id = "chiconscheme", + .name = N_("Channel icon name scheme"), + .desc = N_("Scheme to generate the channel icon names " + "(all lower-case, service name picons etc.)."), + .list = config_class_chiconscheme_list, + .doc = prop_doc_config_channelname_scheme, + .off = offsetof(config_t, chicon_scheme), + .opts = PO_ADVANCED | PO_DOC_NLIST, + .group = 4, + }, + { + .type = PT_STR, + .id = "piconpath", + .name = N_("Picon path"), + .desc = N_("Path to a directory (folder) containing your picon " + "collection. See Help for more detailed " + "information."), + .doc = prop_doc_config_picon_path, + .off = offsetof(config_t, picon_path), + .opts = PO_ADVANCED, + .group = 4, + }, + { + .type = PT_INT, + .id = "piconscheme", + .name = N_("Picon name scheme"), + .desc = N_("Select scheme to generate the picon names " + "(standard, force service type to 1)"), + .list = config_class_piconscheme_list, + .doc = prop_doc_config_picon_servicetype, + .off = offsetof(config_t, picon_scheme), + .opts = PO_ADVANCED | PO_DOC_NLIST, + .group = 4, + }, + {.type = PT_STR, + .id = "http_server_name", + .name = N_("Server name"), + .desc = N_("The server name for 'Server:' HTTP headers."), + .off = offsetof(config_t, http_server_name), + .opts = PO_HIDDEN | PO_EXPERT, + .group = 5}, + {.type = PT_STR, + .id = "http_realm_name", + .name = N_("Realm name"), + .desc = N_("The realm name for HTTP authorization."), + .off = offsetof(config_t, realm), + .opts = PO_HIDDEN | PO_EXPERT, + .group = 5}, + {.type = PT_INT, + .id = "digest", + .name = N_("Authentication type"), + .desc = N_("Digest access authentication is intended as a security trade-off. " + "It is intended to replace unencrypted HTTP basic access authentication. " + "This option should be enabled for standard usage."), + .list = config_class_http_auth_list, + .off = offsetof(config_t, http_auth), + .opts = PO_EXPERT, + .group = 5}, + {.type = PT_INT, + .id = "digest_algo", + .name = N_("Digest hash type"), + .desc = N_("The hash algorithm type for the digest authentication."), + .list = config_class_http_auth_algo_list, + .off = offsetof(config_t, http_auth_algo), + .opts = PO_EXPERT, + .group = 5}, + {.type = PT_U32, + .intextra = INTEXTRA_RANGE(1, 0x7ff, 1), + .id = "cookie_expires", + .name = N_("Cookie expiration (days)"), + .desc = N_("The number of days cookies set by Tvheadend should " + "expire."), + .off = offsetof(config_t, cookie_expires), + .opts = PO_EXPERT, + .group = 5}, + {.type = PT_U32, + .intextra = INTEXTRA_RANGE(30, 3600, 1), + .id = "ticket_expires", + .name = N_("Ticket expiration (seconds)"), + .desc = N_("The number of seconds in which authentication tickets generated by " + "Tvheadend should expire."), + .off = offsetof(config_t, ticket_expires), + .opts = PO_EXPERT, + .group = 5}, + {.type = PT_BOOL, + .id = "proxy", + .name = N_("PROXY protocol & X-Forwarded-For"), + .desc = N_("PROXY protocol is an extension for support incoming " + "TCP connections from a remote server (like a firewall) " + "sending the original IP address of the client. " + "The HTTP header 'X-Forwarded-For' do the same with " + "HTTP connections. Both enable tunneled connections." + "This option should be disabled for standard usage."), + .off = offsetof(config_t, proxy), + .opts = PO_EXPERT, + .group = 5}, + {.type = PT_STR, + .id = "cors_origin", + .name = N_("CORS origin"), + .desc = N_("HTTP CORS (cross-origin resource sharing) origin. This " + "option is usually set when Tvheadend is behind a " + "proxy. Enter the URL (domain or IP address, prefixed " + "with http:// or https://) to allow cross-domain requests."), + .set = config_class_cors_origin_set, + .off = offsetof(config_t, cors_origin), + .opts = PO_EXPERT, + .group = 5}, + {.type = PT_STR, + .id = "hdhomerun_ip", + .name = N_("HDHomerun IP Address"), + .desc = N_("IP address of the HDHomerun device. This is needed if you " + "plan to run TVheadend in a container and you want to stream " + "from an HDHomerun without enabling host networking for " + "the container."), + .off = offsetof(config_t, hdhomerun_ip), + .opts = PO_HIDDEN | PO_EXPERT, + .group = 6}, + {.type = PT_STR, + .id = "local_ip", + .name = N_("Local IP Address"), + .desc = N_("IP of the Docker host. Each HDHomeRun tuner sends data " + "to TVheadend through a socket. This lets you define the " + "IP address that HDHomeRun needs to send to. Leave this " + "blank if you want TVheadend to automatically pick an " + "address."), + .off = offsetof(config_t, local_ip), + .opts = PO_HIDDEN | PO_EXPERT, + .group = 6}, + {.type = PT_INT, + .id = "local_port", + .name = N_("Local Socket Port Number"), + .desc = N_("Starting port number of the UDP listeners. The listeners " + "listen for traffic from the HDHomerun tuners. This is " + "needed if you plan to run TVheadend in a container and " + "you want to stream from an HDHomerun without enabling " + "host networking for the container. Set this to 0 if you " + "want the port numbers to be assigned dynamically. If you " + "have multiple tuners, this will be the start of the port " + "range. For example, if you have 4 tuners and you set this " + "to 9983, then tuner 0 will talk to port 9983, tuner 1 " + "will talk to port 9984, tuner 2 will talk to port 9985, " + "and tuner 3 will talk to port 9986."), + .off = offsetof(config_t, local_port), + .opts = PO_HIDDEN | PO_EXPERT, + .group = 6}, + { + .type = PT_U32, + .id = "hdhomerun_server_tuner_count", + .name = N_("Number of tuners to export for HDHomeRun Server Emulation"), + .desc = N_("When Tvheadend is acting as an HDHomeRun Server " + "(emulating an HDHomeRun device for downstream " + "media devices to stream Live TV) then " + "we tell clients that we have this number of tuners. " + "This is necessary since some clients artificially limit " + "connections based on tuner count, even though several " + "channels may share a multiplex on one tuner. " + "The HDHomeRun interface can not distinguish between " + "different types of tuner in a mixed system with " + "satellite, aerial and cable. " + "The actual number or types of tuners used by Tvheadend is " + "not affected by this value. Tvheadend will " + "allocate tuners automatically. " + "Set to zero for Tvheadend to use a default value."), + .off = offsetof(config_t, hdhomerun_server_tuner_count), + .opts = PO_EXPERT #if !ENABLE_HDHOMERUN_SERVER - | PO_PHIDDEN + | PO_PHIDDEN #endif - , - .group = 6, - }, - { - .type = PT_STR, - .id = "hdhomerun_server_model_name", - .name = N_("Tvheadend model name for HDHomeRun Server Emulation"), - .desc = N_("When Tvheadend is acting as an HDHomeRun Server " - "(emulating an HDHomeRun device for downstream " - "media devices to stream Live TV) then " - "we use this as the type of HDHomeRun model number " - "that we send to clients. Some clients may require " - "a specific model number to work. Leave blank " - "for Tvheadend to use a default." - ), - .off = offsetof(config_t, hdhomerun_server_model_name), - .opts = PO_EXPERT + , + .group = 6, + }, + { + .type = PT_STR, + .id = "hdhomerun_server_model_name", + .name = N_("Tvheadend model name for HDHomeRun Server Emulation"), + .desc = N_("When Tvheadend is acting as an HDHomeRun Server " + "(emulating an HDHomeRun device for downstream " + "media devices to stream Live TV) then " + "we use this as the type of HDHomeRun model number " + "that we send to clients. Some clients may require " + "a specific model number to work. Leave blank " + "for Tvheadend to use a default."), + .off = offsetof(config_t, hdhomerun_server_model_name), + .opts = PO_EXPERT #if !ENABLE_HDHOMERUN_SERVER - | PO_PHIDDEN + | PO_PHIDDEN #endif - , - .group = 6, - }, - { - .type = PT_BOOL, - .id = "hdhomerun_server_enable", - .name = N_("Enable HDHomeRun Server Emulation"), - .desc = N_("Enable the Tvheadend server to emulate " - "an HDHomeRun server. This allows LiveTV " - "to be used on some media servers." - ), - .off = offsetof(config_t, hdhomerun_server_enable), - .opts = PO_EXPERT + , + .group = 6, + }, + {.type = PT_BOOL, + .id = "hdhomerun_server_enable", + .name = N_("Enable HDHomeRun Server Emulation"), + .desc = N_("Enable the Tvheadend server to emulate " + "an HDHomeRun server. This allows LiveTV " + "to be used on some media servers."), + .off = offsetof(config_t, hdhomerun_server_enable), + .opts = PO_EXPERT #if !ENABLE_HDHOMERUN_SERVER - | PO_PHIDDEN + | PO_PHIDDEN #endif -, - .group = 6 - }, - { - .type = PT_STR, - .id = "http_user_agent", - .name = N_("HTTP User Agent"), - .desc = N_("The user agent string for the build-in HTTP client."), - .off = offsetof(config_t, http_user_agent), - .opts = PO_HIDDEN | PO_EXPERT, - .group = 7, - }, - { - .type = PT_INT, - .id = "iptv_tpool", - .name = N_("IPTV threads"), - .desc = N_("Set the number of threads for IPTV to split load " - "across more CPUs."), - .off = offsetof(config_t, iptv_tpool_count), - .group = 7, - }, - { - .type = PT_INT, - .id = "dscp", - .name = N_("DSCP/TOS for streaming"), - .desc = N_("Differentiated Services Code Point / Type of " - "Service: Set the service class Tvheadend sends " - "with each packet. Depending on the option selected " - "this tells your router the prority in which to " - "give packets sent from Tvheadend, this option does " - "not usually need changing. See " - "https://en.wikipedia.org/wiki/" - "Differentiated_services for more information. "), - .off = offsetof(config_t, dscp), - .list = config_class_dscp_list, - .opts = PO_EXPERT | PO_DOC_NLIST, - .group = 7, - }, - { - .type = PT_U32, - .id = "descrambler_buffer", - .name = N_("Descrambler buffer (TS packets)"), - .desc = N_("The number of MPEG-TS packets Tvheadend buffers in case " - "there is a delay receiving CA keys. "), - .off = offsetof(config_t, descrambler_buffer), - .opts = PO_EXPERT, - .group = 7, - }, - { - .type = PT_BOOL, - .id = "parser_backlog", - .name = N_("Packet backlog"), - .desc = N_("Send previous stream frames to upper layers " - "(before frame start is signalled in the stream). " - "It may cause issues with some clients / players."), - .off = offsetof(config_t, parser_backlog), - .opts = PO_EXPERT, - .group = 7, - }, - { - .type = PT_STR, - .id = "muxconfpath", - .name = N_("DVB scan files path"), - .desc = N_("Select the path to use for DVB scan configuration " - "files. Typically dvb-apps stores these in " - "/usr/share/dvb/. Leave blank to use the " - "internal file set."), - .off = offsetof(config_t, muxconf_path), - .notify = config_muxconfpath_notify, - .opts = PO_ADVANCED, - .group = 7, - }, - { - .type = PT_BOOL, - .id = "hbbtv", - .name = N_("Parse HbbTV info"), - .desc = N_("Parse HbbTV information from services."), - .off = offsetof(config_t, hbbtv), - .group = 7, - .def.i = 1, - }, - { - .type = PT_BOOL, - .id = "tvhtime_update_enabled", - .name = N_("Update time"), - .desc = N_("Enable system time updates. This will only work if " - "the user running Tvheadend has rights to update " - "the system clock (normally only root)."), - .off = offsetof(config_t, tvhtime_update_enabled), - .opts = PO_EXPERT, - .group = 7, - }, - { - .type = PT_BOOL, - .id = "tvhtime_ntp_enabled", - .name = N_("Enable NTP driver"), - .desc = N_("This will create an NTP driver (using shmem " - "interface) that you can feed into ntpd. This can " - "be run without root privileges, but generally the " - "performance is not that great."), - .off = offsetof(config_t, tvhtime_ntp_enabled), - .opts = PO_EXPERT, - .group = 7, - }, - { - .type = PT_U32, - .id = "tvhtime_tolerance", - .name = N_("Update tolerance (ms)"), - .desc = N_("Only update the system clock (doesn't affect NTP " - "driver) if the delta between the system clock and " - "DVB time is greater than this. This can help stop " - "excessive oscillations on the system clock."), - .off = offsetof(config_t, tvhtime_tolerance), - .opts = PO_EXPERT, - .group = 7, - }, - { - .type = PT_STR, - .id = "wizard", - .name = "Wizard level", /* untranslated */ - .off = offsetof(config_t, wizard), - .opts = PO_NOUI, - }, - {} - } -}; + , + .group = 6}, + { + .type = PT_STR, + .id = "http_user_agent", + .name = N_("HTTP User Agent"), + .desc = N_("The user agent string for the build-in HTTP client."), + .off = offsetof(config_t, http_user_agent), + .opts = PO_HIDDEN | PO_EXPERT, + .group = 7, + }, + { + .type = PT_INT, + .id = "iptv_tpool", + .name = N_("IPTV threads"), + .desc = N_("Set the number of threads for IPTV to split load " + "across more CPUs."), + .off = offsetof(config_t, iptv_tpool_count), + .group = 7, + }, + { + .type = PT_INT, + .id = "dscp", + .name = N_("DSCP/TOS for streaming"), + .desc = N_("Differentiated Services Code Point / Type of " + "Service: Set the service class Tvheadend sends " + "with each packet. Depending on the option selected " + "this tells your router the prority in which to " + "give packets sent from Tvheadend, this option does " + "not usually need changing. See " + "https://en.wikipedia.org/wiki/" + "Differentiated_services for more information. "), + .off = offsetof(config_t, dscp), + .list = config_class_dscp_list, + .opts = PO_EXPERT | PO_DOC_NLIST, + .group = 7, + }, + { + .type = PT_U32, + .id = "descrambler_buffer", + .name = N_("Descrambler buffer (TS packets)"), + .desc = N_("The number of MPEG-TS packets Tvheadend buffers in case " + "there is a delay receiving CA keys. "), + .off = offsetof(config_t, descrambler_buffer), + .opts = PO_EXPERT, + .group = 7, + }, + { + .type = PT_BOOL, + .id = "parser_backlog", + .name = N_("Packet backlog"), + .desc = N_("Send previous stream frames to upper layers " + "(before frame start is signalled in the stream). " + "It may cause issues with some clients / players."), + .off = offsetof(config_t, parser_backlog), + .opts = PO_EXPERT, + .group = 7, + }, + { + .type = PT_STR, + .id = "muxconfpath", + .name = N_("DVB scan files path"), + .desc = N_("Select the path to use for DVB scan configuration " + "files. Typically dvb-apps stores these in " + "/usr/share/dvb/. Leave blank to use the " + "internal file set."), + .off = offsetof(config_t, muxconf_path), + .notify = config_muxconfpath_notify, + .opts = PO_ADVANCED, + .group = 7, + }, + { + .type = PT_BOOL, + .id = "hbbtv", + .name = N_("Parse HbbTV info"), + .desc = N_("Parse HbbTV information from services."), + .off = offsetof(config_t, hbbtv), + .group = 7, + .def.i = 1, + }, + { + .type = PT_BOOL, + .id = "tvhtime_update_enabled", + .name = N_("Update time"), + .desc = N_("Enable system time updates. This will only work if " + "the user running Tvheadend has rights to update " + "the system clock (normally only root)."), + .off = offsetof(config_t, tvhtime_update_enabled), + .opts = PO_EXPERT, + .group = 7, + }, + { + .type = PT_BOOL, + .id = "tvhtime_ntp_enabled", + .name = N_("Enable NTP driver"), + .desc = N_("This will create an NTP driver (using shmem " + "interface) that you can feed into ntpd. This can " + "be run without root privileges, but generally the " + "performance is not that great."), + .off = offsetof(config_t, tvhtime_ntp_enabled), + .opts = PO_EXPERT, + .group = 7, + }, + { + .type = PT_U32, + .id = "tvhtime_tolerance", + .name = N_("Update tolerance (ms)"), + .desc = N_("Only update the system clock (doesn't affect NTP " + "driver) if the delta between the system clock and " + "DVB time is greater than this. This can help stop " + "excessive oscillations on the system clock."), + .off = offsetof(config_t, tvhtime_tolerance), + .opts = PO_EXPERT, + .group = 7, + }, + { + .type = PT_STR, + .id = "wizard", + .name = "Wizard level", /* untranslated */ + .off = offsetof(config_t, wizard), + .opts = PO_NOUI, + }, + {}}}; /* ************************************************************************** * Access routines * *************************************************************************/ -const char *config_get_server_name ( void ) -{ +const char* config_get_server_name(void) { return tvh_str_default(config.server_name, "Tvheadend"); } -const char *config_get_http_server_name ( void ) -{ +const char* config_get_http_server_name(void) { return tvh_str_default(config.http_server_name, "HTS/tvheadend"); } -const char *config_get_language ( void ) -{ +const char* config_get_language(void) { return tvh_str_default(config.language, "eng"); } -const char *config_get_language_ui ( void ) -{ +const char* config_get_language_ui(void) { return tvh_str_default(config.language_ui, NULL); } diff --git a/src/config.h b/src/config.h index 8cdb54d70..bca2b8140 100644 --- a/src/config.h +++ b/src/config.h @@ -30,67 +30,66 @@ typedef struct config { idnode_t idnode; uint32_t version; - char *confdir; - int hbbtv; - int uilevel; - int uilevel_nochange; - int ui_quicktips; - int http_auth; - int http_auth_algo; - int proxy; - char *realm; - char *wizard; - char *full_version; - char *server_name; - char *http_server_name; - char *http_user_agent; - char *language; - char *info_area; - int chname_num; - int chname_src; - char *language_ui; - char *theme_ui; - char *muxconf_path; - int prefer_picon; - char *chicon_path; - int chicon_scheme; - char *picon_path; - int picon_scheme; - int tvhtime_update_enabled; - int tvhtime_ntp_enabled; + char* confdir; + int hbbtv; + int uilevel; + int uilevel_nochange; + int ui_quicktips; + int http_auth; + int http_auth_algo; + int proxy; + char* realm; + char* wizard; + char* full_version; + char* server_name; + char* http_server_name; + char* http_user_agent; + char* language; + char* info_area; + int chname_num; + int chname_src; + char* language_ui; + char* theme_ui; + char* muxconf_path; + int prefer_picon; + char* chicon_path; + int chicon_scheme; + char* picon_path; + int picon_scheme; + int tvhtime_update_enabled; + int tvhtime_ntp_enabled; uint32_t tvhtime_tolerance; - char *cors_origin; + char* cors_origin; uint32_t cookie_expires; - int dscp; + int dscp; uint32_t descrambler_buffer; - int caclient_ui; - int parser_backlog; - int epg_compress; + int caclient_ui; + int parser_backlog; + int epg_compress; uint32_t epg_cut_window; uint32_t epg_update_window; - int iptv_tpool_count; - char *date_mask; - int label_formatting; + int iptv_tpool_count; + char* date_mask; + int label_formatting; uint32_t ticket_expires; - char *hdhomerun_ip; - char *local_ip; - int local_port; + char* hdhomerun_ip; + char* local_ip; + int local_port; uint32_t hdhomerun_server_tuner_count; - char *hdhomerun_server_model_name; - int hdhomerun_server_enable; + char* hdhomerun_server_model_name; + int hdhomerun_server_enable; } config_t; extern const idclass_t config_class; -extern config_t config; +extern config_t config; -void config_boot - ( const char *path, gid_t gid, uid_t uid, const char *http_user_agent ); -void config_init( int backup ); -void config_done( void ); +void config_boot(const char* path, gid_t gid, uid_t uid, const char* http_user_agent); +void config_init(int backup); +void config_done(void); -const char *config_get_server_name ( void ); -const char *config_get_http_server_name ( void ); -const char *config_get_language ( void ); -const char *config_get_language_ui ( void ); +const char* config_get_server_name(void); +const char* config_get_http_server_name(void); +const char* config_get_language(void); +const char* config_get_language_ui(void); #endif /* __TVH_CONFIG__H__ */ diff --git a/src/cron.c b/src/cron.c index b2484070f..8c31b0fcc 100644 --- a/src/cron.c +++ b/src/cron.c @@ -33,9 +33,7 @@ /* * Parse value */ -static int -cron_parse_val ( const char *str, const char **key, int *v ) -{ +static int cron_parse_val(const char* str, const char** key, int* v) { int i = 0; if (!str) return 0; @@ -55,98 +53,107 @@ cron_parse_val ( const char *str, const char **key, int *v ) /* * Parse individual field in cron spec */ -static int -cron_parse_field - ( const char **istr, uint64_t *field, uint64_t mask, int bits, int off, - const char **key ) -{ - int sn = -1, en = -1, mn = -1; - const char *str = *istr; - const char *beg = str; +static int cron_parse_field(const char** istr, + uint64_t* field, + uint64_t mask, + int bits, + int off, + const char** key) { + int sn = -1, en = -1, mn = -1; + const char* str = *istr; + const char* beg = str; uint64_t val = 0; - while ( 1 ) { - if ( *str == '*' ) { - sn = off; - en = bits + off - 1; - beg = NULL; - } else if ( *str == ',' || *str == ' ' || *str == '\0' ) { + while (1) { + if (*str == '*') { + sn = off; + en = bits + off - 1; + beg = NULL; + } else if (*str == ',' || *str == ' ' || *str == '\0') { if (beg) if (cron_parse_val(beg, key, en == -1 ? (sn == -1 ? &sn : &en) : &mn)) return 1; if ((sn - off) >= bits || (en - off) >= bits || mn > bits) return 1; - if (en < 0) en = sn; - if (mn <= 0) mn = 1; + if (en < 0) + en = sn; + if (mn <= 0) + mn = 1; while (sn <= en) { - if ( (sn % mn) == 0 ) + if ((sn % mn) == 0) val |= (0x1ULL << (sn - off)); sn++; } - if (*str != ',') break; + if (*str != ',') + break; sn = en = mn = -1; - beg = (str + 1); - } else if ( *str == '/' ) { + beg = (str + 1); + } else if (*str == '/') { if (beg) if (en == -1 || cron_parse_val(beg, key, sn == -1 ? &sn : &en)) return 1; beg = (str + 1); - } else if ( *str == '-' ) { - if (sn != -1 || cron_parse_val(beg, key, &sn)) + } else if (*str == '-') { + if (sn != -1 || cron_parse_val(beg, key, &sn)) return 1; beg = (str + 1); } str++; } - if (*str == ' ') str++; - *istr = str; - *field = (val | ((val >> bits) & 0x1)) & mask; + if (*str == ' ') + str++; + *istr = str; + *field = (val | ((val >> bits) & 0x1)) & mask; return 0; } /* * Set value */ -int -cron_set ( cron_t *c, const char *str ) -{ - uint64_t ho, mi, mo, dm, dw; - static const char *days[] = { - "sun", "mon", "tue", "wed", "thu", "fri", "sat", NULL - }; - static const char *months[] = { - "ignore", - "jan", "feb", "mar", "apr", "may", "jun", - "jul", "aug", "sep", "oct", "nov", "dec", - NULL - }; +int cron_set(cron_t* c, const char* str) { + uint64_t ho, mi, mo, dm, dw; + static const char* days[] = {"sun", "mon", "tue", "wed", "thu", "fri", "sat", NULL}; + static const char* months[] = {"ignore", + "jan", + "feb", + "mar", + "apr", + "may", + "jun", + "jul", + "aug", + "sep", + "oct", + "nov", + "dec", + NULL}; /* Daily (01:01) */ - if ( !strcmp(str, "@daily") ) { + if (!strcmp(str, "@daily")) { c->c_min = 1; c->c_hour = 1; c->c_mday = CRON_MDAY_MASK; c->c_mon = CRON_MON_MASK; c->c_wday = CRON_WDAY_MASK; - /* Hourly (XX:02) */ - } else if ( !strcmp(str, "@hourly") ) { + /* Hourly (XX:02) */ + } else if (!strcmp(str, "@hourly")) { c->c_min = 2; c->c_hour = CRON_HOUR_MASK; c->c_mday = CRON_MDAY_MASK; c->c_mon = CRON_MON_MASK; c->c_wday = CRON_WDAY_MASK; - - /* Standard */ + + /* Standard */ } else { - if (cron_parse_field(&str, &mi, CRON_MIN_MASK, 60, 0, NULL) || !mi) + if (cron_parse_field(&str, &mi, CRON_MIN_MASK, 60, 0, NULL) || !mi) return 1; - if (cron_parse_field(&str, &ho, CRON_HOUR_MASK, 24, 0, NULL) || !ho) + if (cron_parse_field(&str, &ho, CRON_HOUR_MASK, 24, 0, NULL) || !ho) return 1; - if (cron_parse_field(&str, &dm, CRON_MDAY_MASK, 31, 1, NULL) || !dm) + if (cron_parse_field(&str, &dm, CRON_MDAY_MASK, 31, 1, NULL) || !dm) return 1; - if (cron_parse_field(&str, &mo, CRON_MON_MASK, 12, 1, months) || !mo) + if (cron_parse_field(&str, &mo, CRON_MON_MASK, 12, 1, months) || !mo) return 1; - if (cron_parse_field(&str, &dw, CRON_WDAY_MASK, 7, 0, days) || !dw) + if (cron_parse_field(&str, &dw, CRON_WDAY_MASK, 7, 0, days) || !dw) return 1; c->c_min = mi; c->c_hour = ho; @@ -161,14 +168,12 @@ cron_set ( cron_t *c, const char *str ) /* * Set value */ -cron_multi_t * -cron_multi_set ( const char *str ) -{ - char *s = str ? alloca(strlen(str) + 1) : NULL; - char *line, *sptr = NULL; - cron_t cron; - cron_multi_t *cm = NULL, *cm2; - int count = 0; +cron_multi_t* cron_multi_set(const char* str) { + char* s = str ? alloca(strlen(str) + 1) : NULL; + char * line, *sptr = NULL; + cron_t cron; + cron_multi_t *cm = NULL, *cm2; + int count = 0; if (s == NULL) return NULL; @@ -185,7 +190,7 @@ cron_multi_set ( const char *str ) free(cm); return NULL; } - cm = cm2; + cm = cm2; cm->cm_crons[count - 1] = cron; } line = strtok_r(NULL, "\n", &sptr); @@ -198,9 +203,7 @@ cron_multi_set ( const char *str ) /* * Check for leap year */ -static int -is_leep_year ( int year ) -{ +static int is_leep_year(int year) { if (!(year % 400)) return 1; if (!(year % 100)) @@ -211,9 +214,7 @@ is_leep_year ( int year ) /* * Check for days in month */ -static int -days_in_month ( int year, int mon ) -{ +static int days_in_month(int year, int mon) { int d; if (mon == 2) d = 28 + is_leep_year(year); @@ -225,11 +226,9 @@ days_in_month ( int year, int mon ) /* * Find the next time (starting from now) that the cron should fire */ -int -cron_next ( cron_t *c, const time_t now, time_t *ret ) -{ +int cron_next(cron_t* c, const time_t now, time_t* ret) { struct tm nxt, tmp; - int endyear, loops = 1000; + int endyear, loops = 1000; localtime_r(&now, &nxt); endyear = nxt.tm_year + 10; @@ -237,17 +236,16 @@ cron_next ( cron_t *c, const time_t now, time_t *ret ) nxt.tm_sec = 0; /* Invalid day */ - if (!(c->c_mday & (0x1LL << (nxt.tm_mday-1))) || - !(c->c_wday & (0x1LL << (nxt.tm_wday))) || - !(c->c_mon & (0x1LL << (nxt.tm_mon))) ) { + if (!(c->c_mday & (0x1LL << (nxt.tm_mday - 1))) || !(c->c_wday & (0x1LL << (nxt.tm_wday))) || + !(c->c_mon & (0x1LL << (nxt.tm_mon)))) { nxt.tm_min = 0; nxt.tm_hour = 0; - /* Invalid hour */ + /* Invalid hour */ } else if (!(c->c_hour & (0x1LL << nxt.tm_hour))) { - nxt.tm_min = 0; + nxt.tm_min = 0; - /* Increment */ + /* Increment */ } else { ++nxt.tm_min; } @@ -274,7 +272,7 @@ cron_next ( cron_t *c, const time_t now, time_t *ret ) /* Date */ if (nxt.tm_wday == 7) nxt.tm_wday = 0; - if (nxt.tm_mday > days_in_month(nxt.tm_year+1900, nxt.tm_mon+1)) { + if (nxt.tm_mday > days_in_month(nxt.tm_year + 1900, nxt.tm_mon + 1)) { nxt.tm_mday = 1; nxt.tm_mon++; if (nxt.tm_mon == 12) { @@ -282,9 +280,8 @@ cron_next ( cron_t *c, const time_t now, time_t *ret ) ++nxt.tm_year; } } - while (!(c->c_mday & (0x1LL << (nxt.tm_mday-1))) || - !(c->c_wday & (0x1LL << (nxt.tm_wday))) || - !(c->c_mon & (0x1LL << (nxt.tm_mon))) ) { + while (!(c->c_mday & (0x1LL << (nxt.tm_mday - 1))) || !(c->c_wday & (0x1LL << (nxt.tm_wday))) || + !(c->c_mon & (0x1LL << (nxt.tm_mon)))) { /* Endless loop protection */ if (loops-- == 0) @@ -299,7 +296,7 @@ cron_next ( cron_t *c, const time_t now, time_t *ret ) nxt.tm_wday = 0; /* Increment day */ - if (++nxt.tm_mday > days_in_month(nxt.tm_year+1900, nxt.tm_mon+1)) { + if (++nxt.tm_mday > days_in_month(nxt.tm_year + 1900, nxt.tm_mon + 1)) { nxt.tm_mday = 1; if (++nxt.tm_mon == 12) { nxt.tm_mon = 0; @@ -309,8 +306,7 @@ cron_next ( cron_t *c, const time_t now, time_t *ret ) /* Shortcut the month */ while (!(c->c_mon & (0x1LL << nxt.tm_mon))) { - nxt.tm_wday - += 1 + (days_in_month(nxt.tm_year+1900, nxt.tm_mon+1) - nxt.tm_mday); + nxt.tm_wday += 1 + (days_in_month(nxt.tm_year + 1900, nxt.tm_mon + 1) - nxt.tm_mday); nxt.tm_mday = 1; if (++nxt.tm_mon >= 12) { nxt.tm_mon = 0; @@ -329,9 +325,9 @@ cron_next ( cron_t *c, const time_t now, time_t *ret ) *ret = mktime(&tmp); if (*ret <= now) { #ifndef CRON_TEST - tvherror(LS_CRON, "invalid time, now %"PRItime_t", result %"PRItime_t, now, *ret); + tvherror(LS_CRON, "invalid time, now %" PRItime_t ", result %" PRItime_t, now, *ret); #else - printf("ERROR: invalid time, now %"PRItime_t", result %"PRItime_t"\n", now, *ret); + printf("ERROR: invalid time, now %" PRItime_t ", result %" PRItime_t "\n", now, *ret); #endif *ret = now + 600; } @@ -341,11 +337,9 @@ cron_next ( cron_t *c, const time_t now, time_t *ret ) /* * Find the next time (starting from now) that the cron should fire */ -int -cron_multi_next ( cron_multi_t *cm, const time_t now, time_t *ret ) -{ +int cron_multi_next(cron_multi_t* cm, const time_t now, time_t* ret) { uint32_t i; - time_t r = (time_t)-1, t; + time_t r = (time_t)-1, t; if (cm == NULL) return -1; @@ -365,9 +359,7 @@ cron_multi_next ( cron_multi_t *cm, const time_t now, time_t *ret ) * gcc -g -DCRON_TEST -I./build.linux src/cron.c */ #ifdef CRON_TEST -static -void print_bits ( uint64_t b, int n ) -{ +static void print_bits(uint64_t b, int n) { while (n) { printf("%d", (int)(b & 0x1)); b >>= 1; @@ -375,13 +367,11 @@ void print_bits ( uint64_t b, int n ) } } -int -main ( int argc, char **argv ) -{ - cron_t c; - time_t n; +int main(int argc, char** argv) { + cron_t c; + time_t n; struct tm tm; - char buf[128]; + char buf[128]; if (argc < 2) { printf("Specify: CRON [NOW]\n"); @@ -394,11 +384,21 @@ main ( int argc, char **argv ) if (cron_set(&c, argv[1])) printf("INVALID CRON: %s\n", argv[1]); else { - printf("min = "); print_bits(c.c_min, 60); printf("\n"); - printf("hour = "); print_bits(c.c_hour, 24); printf("\n"); - printf("mday = "); print_bits(c.c_mday, 31); printf("\n"); - printf("mon = "); print_bits(c.c_mon, 12); printf("\n"); - printf("wday = "); print_bits(c.c_wday, 7); printf("\n"); + printf("min = "); + print_bits(c.c_min, 60); + printf("\n"); + printf("hour = "); + print_bits(c.c_hour, 24); + printf("\n"); + printf("mday = "); + print_bits(c.c_mday, 31); + printf("\n"); + printf("mon = "); + print_bits(c.c_mon, 12); + printf("\n"); + printf("wday = "); + print_bits(c.c_wday, 7); + printf("\n"); localtime_r(&n, &tm); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M", &tm); @@ -411,7 +411,6 @@ main ( int argc, char **argv ) localtime_r(&n, &tm); strftime(buf, sizeof(buf), "%Y-%m-%d %H:%M", &tm); printf("NXT: %ld - %s (DST %d) (ZONE %s)\n", (long)n, buf, tm.tm_isdst, tm.tm_zone); - } return 0; } diff --git a/src/cron.h b/src/cron.h index 81a8cd051..1a85513c6 100644 --- a/src/cron.h +++ b/src/cron.h @@ -23,24 +23,22 @@ #include #include -#define CRON_MIN_MASK (0x0FFFFFFFFFFFFFFFLL) // 60 bits -#define CRON_HOUR_MASK (0x00FFFFFF) // 24 bits -#define CRON_MDAY_MASK (0x7FFFFFFF) // 31 bits -#define CRON_MON_MASK (0x0FFF) // 12 bits -#define CRON_WDAY_MASK (0x7F) // 7 bits +#define CRON_MIN_MASK (0x0FFFFFFFFFFFFFFFLL) // 60 bits +#define CRON_HOUR_MASK (0x00FFFFFF) // 24 bits +#define CRON_MDAY_MASK (0x7FFFFFFF) // 31 bits +#define CRON_MON_MASK (0x0FFF) // 12 bits +#define CRON_WDAY_MASK (0x7F) // 7 bits -typedef struct cron -{ - uint64_t c_min; ///< Minute mask - uint32_t c_hour; ///< Hour mask - uint32_t c_mday; ///< Day of the Month mask - uint16_t c_mon; ///< Month mask - uint8_t c_wday; ///< Day of the Week mask +typedef struct cron { + uint64_t c_min; ///< Minute mask + uint32_t c_hour; ///< Hour mask + uint32_t c_mday; ///< Day of the Month mask + uint16_t c_mon; ///< Month mask + uint8_t c_wday; ///< Day of the Week mask } cron_t; -typedef struct cron_multi -{ - uint32_t cm_count; ///< Count of multiple crons +typedef struct cron_multi { + uint32_t cm_count; ///< Count of multiple crons cron_t cm_crons[0]; ///< Allocated cron structures } cron_multi_t; @@ -52,7 +50,7 @@ typedef struct cron_multi * * @return 0 if OK, 1 if failed to parse */ -int cron_set ( cron_t *c, const char *str ); +int cron_set(cron_t* c, const char* str); /** * Determine the next time a cron will run (from cur) @@ -63,7 +61,7 @@ int cron_set ( cron_t *c, const char *str ); * * @return 0 if next time was found */ -int cron_next ( cron_t *c, const time_t cur, time_t *nxt ); +int cron_next(cron_t* c, const time_t cur, time_t* nxt); /** * Initialise from a string @@ -72,7 +70,7 @@ int cron_next ( cron_t *c, const time_t cur, time_t *nxt ); * * @return cron_multi_t pointer if OK, NULL if failed to parse */ -cron_multi_t *cron_multi_set ( const char *str ); +cron_multi_t* cron_multi_set(const char* str); /** * Determine the next time a cron will run (from cur) @@ -83,7 +81,7 @@ cron_multi_t *cron_multi_set ( const char *str ); * * @return 0 if next time was found */ -int cron_multi_next ( cron_multi_t *cm, const time_t cur, time_t *nxt ); +int cron_multi_next(cron_multi_t* cm, const time_t cur, time_t* nxt); #endif /* __TVH_CRON_H__ */ diff --git a/src/dbus.c b/src/dbus.c index 2f752ba70..1245f2b40 100644 --- a/src/dbus.c +++ b/src/dbus.c @@ -30,70 +30,63 @@ #include "subscriptions.h" #include "dbus.h" - typedef struct dbus_sig { TAILQ_ENTRY(dbus_sig) link; - char *obj_name; - char *sig_name; - htsmsg_t *msg; + char* obj_name; + char* sig_name; + htsmsg_t* msg; } dbus_sig_t; typedef struct dbus_rpc { LIST_ENTRY(dbus_rpc) link; - char *call_name; - void *opaque; - int64_t (*rpc_s64)(void *opaque, const char *path, int64_t value); - char *(*rpc_str)(void *opaque, const char *path, char *value); + char* call_name; + void* opaque; + int64_t (*rpc_s64)(void* opaque, const char* path, int64_t value); + char* (*rpc_str)(void* opaque, const char* path, char* value); } dbus_rpc_t; TAILQ_HEAD(dbus_signal_queue, dbus_sig); LIST_HEAD(dbus_rpc_list, dbus_rpc); static struct dbus_signal_queue dbus_signals; -static struct dbus_rpc_list dbus_rpcs; -static th_pipe_t dbus_pipe; -static tvh_mutex_t dbus_lock; -static int dbus_running; -static int dbus_session; +static struct dbus_rpc_list dbus_rpcs; +static th_pipe_t dbus_pipe; +static tvh_mutex_t dbus_lock; +static int dbus_running; +static int dbus_session; /** * */ -void -dbus_emit_signal(const char *obj_name, const char *sig_name, htsmsg_t *msg) -{ - dbus_sig_t *ds; - int unused __attribute__((unused)); - size_t l; +void dbus_emit_signal(const char* obj_name, const char* sig_name, htsmsg_t* msg) { + dbus_sig_t* ds; + int unused __attribute__((unused)); + size_t l; if (!atomic_get(&dbus_running)) { htsmsg_destroy(msg); return; } - ds = calloc(1, sizeof(dbus_sig_t)); - l = strlen(obj_name); + ds = calloc(1, sizeof(dbus_sig_t)); + l = strlen(obj_name); ds->obj_name = malloc(l + 15); strcpy(ds->obj_name, "/org/tvheadend"); strcpy(ds->obj_name + 14, obj_name); ds->sig_name = strdup(sig_name); - ds->msg = msg; + ds->msg = msg; tvh_mutex_lock(&dbus_lock); TAILQ_INSERT_TAIL(&dbus_signals, ds, link); tvh_mutex_unlock(&dbus_lock); unused = write(dbus_pipe.wr, "s", 1); /* do not wait here - no tvh_write() */ } -void -dbus_emit_signal_str(const char *obj_name, const char *sig_name, const char *value) -{ - htsmsg_t *l = htsmsg_create_list(); +void dbus_emit_signal_str(const char* obj_name, const char* sig_name, const char* value) { + htsmsg_t* l = htsmsg_create_list(); htsmsg_add_str(l, NULL, value); dbus_emit_signal(obj_name, sig_name, l); } -void -dbus_emit_signal_s64(const char *obj_name, const char *sig_name, int64_t value) -{ - htsmsg_t *l = htsmsg_create_list(); +void dbus_emit_signal_s64(const char* obj_name, const char* sig_name, int64_t value) { + htsmsg_t* l = htsmsg_create_list(); htsmsg_add_s64(l, NULL, value); dbus_emit_signal(obj_name, sig_name, l); } @@ -101,27 +94,25 @@ dbus_emit_signal_s64(const char *obj_name, const char *sig_name, int64_t value) /** * */ -static void -dbus_from_htsmsg(htsmsg_t *msg, DBusMessageIter *args) -{ - htsmsg_field_t *f; - - TAILQ_FOREACH(f, &msg->hm_fields, hmf_link) { - switch(f->hmf_type) { - case HMF_STR: - dbus_message_iter_append_basic(args, DBUS_TYPE_STRING, &f->hmf_str); - break; - case HMF_S64: - dbus_message_iter_append_basic(args, DBUS_TYPE_INT64, &f->hmf_s64); - break; - case HMF_BOOL: - dbus_message_iter_append_basic(args, DBUS_TYPE_BOOLEAN, &f->hmf_bool); - break; - case HMF_DBL: - dbus_message_iter_append_basic(args, DBUS_TYPE_DOUBLE, &f->hmf_dbl); - break; - default: - assert(0); +static void dbus_from_htsmsg(htsmsg_t* msg, DBusMessageIter* args) { + htsmsg_field_t* f; + + TAILQ_FOREACH (f, &msg->hm_fields, hmf_link) { + switch (f->hmf_type) { + case HMF_STR: + dbus_message_iter_append_basic(args, DBUS_TYPE_STRING, &f->hmf_str); + break; + case HMF_S64: + dbus_message_iter_append_basic(args, DBUS_TYPE_INT64, &f->hmf_s64); + break; + case HMF_BOOL: + dbus_message_iter_append_basic(args, DBUS_TYPE_BOOLEAN, &f->hmf_bool); + break; + case HMF_DBL: + dbus_message_iter_append_basic(args, DBUS_TYPE_DOUBLE, &f->hmf_dbl); + break; + default: + assert(0); } } } @@ -129,10 +120,8 @@ dbus_from_htsmsg(htsmsg_t *msg, DBusMessageIter *args) /** * */ -static DBusConnection * -dbus_create_session(const char *name) -{ - DBusConnection *conn; +static DBusConnection* dbus_create_session(const char* name) { + DBusConnection* conn; DBusError err; int ret; @@ -165,26 +154,24 @@ dbus_create_session(const char *name) /** * Send a signal */ -static int -dbus_send_signal(DBusConnection *conn, const char *obj_name, - const char *if_name, const char *sig_name, - htsmsg_t *value) -{ - DBusMessage *msg; +static int dbus_send_signal(DBusConnection* conn, + const char* obj_name, + const char* if_name, + const char* sig_name, + htsmsg_t* value) { + DBusMessage* msg; DBusMessageIter args; msg = dbus_message_new_signal(obj_name, if_name, sig_name); if (msg == NULL) { - tvherror(LS_DBUS, "Unable to create signal %s %s %s", - obj_name, if_name, sig_name); + tvherror(LS_DBUS, "Unable to create signal %s %s %s", obj_name, if_name, sig_name); dbus_connection_unref(conn); return -1; } dbus_message_iter_init_append(msg, &args); dbus_from_htsmsg(value, &args); if (!dbus_connection_send(conn, msg, NULL)) { - tvherror(LS_DBUS, "Unable to send signal %s %s %s", - obj_name, if_name, sig_name); + tvherror(LS_DBUS, "Unable to send signal %s %s %s", obj_name, if_name, sig_name); dbus_message_unref(msg); dbus_connection_unref(conn); return -1; @@ -197,12 +184,10 @@ dbus_send_signal(DBusConnection *conn, const char *obj_name, /** * Simple ping (alive) RPC, just return the string */ -static void -dbus_reply_to_ping(DBusMessage *msg, DBusConnection *conn) -{ +static void dbus_reply_to_ping(DBusMessage* msg, DBusConnection* conn) { DBusMessageIter args; - DBusMessage *reply; - char *param; + DBusMessage* reply; + char* param; if (!dbus_message_iter_init(msg, &args)) return; @@ -220,14 +205,12 @@ dbus_reply_to_ping(DBusMessage *msg, DBusConnection *conn) /** * Set the subscription postpone delay */ -static void -dbus_reply_to_rpc(dbus_rpc_t *rpc, DBusMessage *msg, DBusConnection *conn) -{ +static void dbus_reply_to_rpc(dbus_rpc_t* rpc, DBusMessage* msg, DBusConnection* conn) { DBusMessageIter args; - DBusMessage *reply; - const char *path; + DBusMessage* reply; + const char* path; int64_t param_s64; - char *param_str; + char* param_str; path = dbus_message_get_path(msg); if (path == NULL) @@ -242,7 +225,7 @@ dbus_reply_to_rpc(dbus_rpc_t *rpc, DBusMessage *msg, DBusConnection *conn) return; dbus_message_iter_get_basic(&args, ¶m_s64); param_s64 = rpc->rpc_s64(rpc->opaque, path, param_s64); - reply = dbus_message_new_method_return(msg); + reply = dbus_message_new_method_return(msg); dbus_message_iter_init_append(reply, &args); dbus_message_iter_append_basic(&args, DBUS_TYPE_INT64, ¶m_s64); } else if (rpc->rpc_str) { @@ -250,7 +233,7 @@ dbus_reply_to_rpc(dbus_rpc_t *rpc, DBusMessage *msg, DBusConnection *conn) return; dbus_message_iter_get_basic(&args, ¶m_str); param_str = rpc->rpc_str(rpc->opaque, path, param_str); - reply = dbus_message_new_method_return(msg); + reply = dbus_message_new_method_return(msg); dbus_message_iter_init_append(reply, &args); dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, ¶m_str); free(param_str); @@ -265,14 +248,13 @@ dbus_reply_to_rpc(dbus_rpc_t *rpc, DBusMessage *msg, DBusConnection *conn) /** * */ -void -dbus_register_rpc_s64(const char *call_name, void *opaque, - int64_t (*fcn)(void *, const char *, int64_t)) -{ - dbus_rpc_t *rpc = calloc(1, sizeof(*rpc)); - rpc->call_name = strdup(call_name); - rpc->rpc_s64 = fcn; - rpc->opaque = opaque; +void dbus_register_rpc_s64(const char* call_name, + void* opaque, + int64_t (*fcn)(void*, const char*, int64_t)) { + dbus_rpc_t* rpc = calloc(1, sizeof(*rpc)); + rpc->call_name = strdup(call_name); + rpc->rpc_s64 = fcn; + rpc->opaque = opaque; tvh_mutex_lock(&dbus_lock); LIST_INSERT_HEAD(&dbus_rpcs, rpc, link); tvh_mutex_unlock(&dbus_lock); @@ -281,14 +263,13 @@ dbus_register_rpc_s64(const char *call_name, void *opaque, /** * */ -void -dbus_register_rpc_str(const char *call_name, void *opaque, - char *(*fcn)(void *, const char *, char *)) -{ - dbus_rpc_t *rpc = calloc(1, sizeof(*rpc)); - rpc->call_name = strdup(call_name); - rpc->rpc_str = fcn; - rpc->opaque = opaque; +void dbus_register_rpc_str(const char* call_name, + void* opaque, + char* (*fcn)(void*, const char*, char*)) { + dbus_rpc_t* rpc = calloc(1, sizeof(*rpc)); + rpc->call_name = strdup(call_name); + rpc->rpc_str = fcn; + rpc->opaque = opaque; tvh_mutex_lock(&dbus_lock); LIST_INSERT_HEAD(&dbus_rpcs, rpc, link); tvh_mutex_unlock(&dbus_lock); @@ -298,9 +279,7 @@ dbus_register_rpc_str(const char *call_name, void *opaque, * */ -static void -dbus_connection_safe_close(DBusConnection *conn) -{ +static void dbus_connection_safe_close(DBusConnection* conn) { dbus_connection_flush(conn); dbus_connection_close(conn); dbus_connection_unref(conn); @@ -309,10 +288,8 @@ dbus_connection_safe_close(DBusConnection *conn) /** * */ -static void -dbus_flush_queue(DBusConnection *conn) -{ - dbus_sig_t *ds; +static void dbus_flush_queue(DBusConnection* conn) { + dbus_sig_t* ds; while (1) { tvh_mutex_lock(&dbus_lock); @@ -325,9 +302,7 @@ dbus_flush_queue(DBusConnection *conn) break; if (conn) - dbus_send_signal(conn, - ds->obj_name, "org.tvheadend.notify", - ds->sig_name, ds->msg); + dbus_send_signal(conn, ds->obj_name, "org.tvheadend.notify", ds->sig_name, ds->msg); htsmsg_destroy(ds->msg); free(ds->sig_name); @@ -341,14 +316,12 @@ dbus_flush_queue(DBusConnection *conn) /** * Listen for remote requests */ -static void * -dbus_server_thread(void *aux) -{ - DBusMessage *msg; +static void* dbus_server_thread(void* aux) { + DBusMessage* msg; DBusConnection *conn, *notify; - tvhpoll_t *poll; + tvhpoll_t* poll; tvhpoll_event_t ev; - dbus_rpc_t *rpc; + dbus_rpc_t* rpc; int n; uint8_t c; @@ -408,7 +381,7 @@ dbus_server_thread(void *aux) } tvh_mutex_lock(&dbus_lock); - LIST_FOREACH(rpc, &dbus_rpcs, link) + LIST_FOREACH (rpc, &dbus_rpcs, link) if (dbus_message_is_method_call(msg, "org.tvheadend", rpc->call_name)) break; tvh_mutex_unlock(&dbus_lock); @@ -432,9 +405,7 @@ dbus_server_thread(void *aux) */ pthread_t dbus_tid; -void -dbus_server_init(int enabled, int session) -{ +void dbus_server_init(int enabled, int session) { dbus_session = session; tvh_mutex_init(&dbus_lock, NULL); TAILQ_INIT(&dbus_signals); @@ -447,17 +418,13 @@ dbus_server_init(int enabled, int session) } } -void -dbus_server_start(void) -{ +void dbus_server_start(void) { if (dbus_pipe.wr > 0) tvh_thread_create(&dbus_tid, NULL, dbus_server_thread, NULL, "dbus"); } -void -dbus_server_done(void) -{ - dbus_rpc_t *rpc; +void dbus_server_done(void) { + dbus_rpc_t* rpc; dbus_emit_signal_str("/main", "stop", "bye"); atomic_set(&dbus_running, 0); diff --git a/src/dbus.h b/src/dbus.h index 2acd6c282..d00930f86 100644 --- a/src/dbus.h +++ b/src/dbus.h @@ -24,20 +24,17 @@ #if ENABLE_DBUS_1 -void -dbus_emit_signal(const char *obj_name, const char *sig_name, htsmsg_t *msg); -void -dbus_emit_signal_str(const char *obj_name, const char *sig_name, const char *value); -void -dbus_emit_signal_s64(const char *obj_name, const char *sig_name, int64_t value); +void dbus_emit_signal(const char* obj_name, const char* sig_name, htsmsg_t* msg); +void dbus_emit_signal_str(const char* obj_name, const char* sig_name, const char* value); +void dbus_emit_signal_s64(const char* obj_name, const char* sig_name, int64_t value); -void -dbus_register_rpc_s64(const char *call_name, void *opaque, - int64_t (*fcn)(void *, const char *, int64_t)); +void dbus_register_rpc_s64(const char* call_name, + void* opaque, + int64_t (*fcn)(void*, const char*, int64_t)); -void -dbus_register_rpc_str(const char *call_name, void *opaque, - char *(*fcn)(void *, const char *, char *)); +void dbus_register_rpc_str(const char* call_name, + void* opaque, + char* (*fcn)(void*, const char*, char*)); void dbus_server_init(int enabled, int session); void dbus_server_start(void); @@ -45,24 +42,25 @@ void dbus_server_done(void); #else +static inline void dbus_emit_signal(const char* obj_name, const char* sig_name, htsmsg_t* msg) { + htsmsg_destroy(msg); +} static inline void -dbus_emit_signal(const char *obj_name, const char *sig_name, htsmsg_t *msg) { htsmsg_destroy(msg); } -static inline void -dbus_emit_signal_str(const char *obj_name, const char *sig_name, const char *value) { } -static inline void -dbus_emit_signal_s64(const char *obj_name, const char *sig_name, int64_t value) { } +dbus_emit_signal_str(const char* obj_name, const char* sig_name, const char* value) {} +static inline void dbus_emit_signal_s64(const char* obj_name, const char* sig_name, int64_t value) { +} -static inline void -dbus_register_rpc_s64(const char *call_name, void *opaque, - int64_t (*fcn)(void *, const char *, int64_t)) { } +static inline void dbus_register_rpc_s64(const char* call_name, + void* opaque, + int64_t (*fcn)(void*, const char*, int64_t)) {} -static inline void -dbus_register_rpc_str(const char *call_name, void *opaque, - char *(*fcn)(void *, const char *, char *)) { } +static inline void dbus_register_rpc_str(const char* call_name, + void* opaque, + char* (*fcn)(void*, const char*, char*)) {} -static inline void dbus_server_init(int enabled, int session) { } -static inline void dbus_server_start(void) { } -static inline void dbus_server_done(void) { } +static inline void dbus_server_init(int enabled, int session) {} +static inline void dbus_server_start(void) {} +static inline void dbus_server_done(void) {} #endif diff --git a/src/descrambler/algo/libaes128dec.c b/src/descrambler/algo/libaes128dec.c index 5e5088d61..be902f834 100644 --- a/src/descrambler/algo/libaes128dec.c +++ b/src/descrambler/algo/libaes128dec.c @@ -20,69 +20,61 @@ typedef struct aes128_priv { } aes128_priv_t; /* even cw represents one full 128-bit AES key */ -void aes128_set_even_control_word(void *keys, const uint8_t *pk) -{ - AES_set_decrypt_key(pk, 128, &((aes128_priv_t *) keys)->keys[0]); +void aes128_set_even_control_word(void* keys, const uint8_t* pk) { + AES_set_decrypt_key(pk, 128, &((aes128_priv_t*)keys)->keys[0]); } /* odd cw represents one full 128-bit AES key */ -void aes128_set_odd_control_word(void *keys, const uint8_t *pk) -{ - AES_set_decrypt_key(pk, 128, &((aes128_priv_t *) keys)->keys[1]); +void aes128_set_odd_control_word(void* keys, const uint8_t* pk) { + AES_set_decrypt_key(pk, 128, &((aes128_priv_t*)keys)->keys[1]); } /* set control words */ -void aes128_set_control_words(void *keys, - const uint8_t *ev, - const uint8_t *od) -{ - AES_set_decrypt_key(ev, 128, &((aes128_priv_t *) keys)->keys[0]); - AES_set_decrypt_key(od, 128, &((aes128_priv_t *) keys)->keys[1]); +void aes128_set_control_words(void* keys, const uint8_t* ev, const uint8_t* od) { + AES_set_decrypt_key(ev, 128, &((aes128_priv_t*)keys)->keys[0]); + AES_set_decrypt_key(od, 128, &((aes128_priv_t*)keys)->keys[1]); } /* allocate key structure */ -void * aes128_get_priv_struct(void) -{ - aes128_priv_t *keys; +void* aes128_get_priv_struct(void) { + aes128_priv_t* keys; - keys = (aes128_priv_t *) malloc(sizeof(aes128_priv_t)); + keys = (aes128_priv_t*)malloc(sizeof(aes128_priv_t)); if (keys) { - static const uint8_t pk[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + static const uint8_t pk[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; aes128_set_control_words(keys, pk, pk); } return keys; } /* free key structure */ -void aes128_free_priv_struct(void *keys) -{ +void aes128_free_priv_struct(void* keys) { free(keys); } /* decrypt */ -void aes128_decrypt_packet(void *keys, const uint8_t *pkt) -{ +void aes128_decrypt_packet(void* keys, const uint8_t* pkt) { uint_fast8_t ev_od = 0; uint_fast8_t xc0, offset; - AES_KEY *k; + AES_KEY* k; // skip reserved and not encrypted pkt if (((xc0 = pkt[3]) & 0x80) == 0) return; - ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd - ((uint8_t *)pkt)[3] = xc0 & 0x3f; // consider it decrypted now - if (xc0 & 0x20) { // incomplete packet + ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd + ((uint8_t*)pkt)[3] = xc0 & 0x3f; // consider it decrypted now + if (xc0 & 0x20) { // incomplete packet offset = 4 + pkt[4] + 1; if (offset + 16 > 188) { // decrypted==encrypted! - return; // this doesn't need more processing + return; // this doesn't need more processing } } else { offset = 4; } - k = &((aes128_priv_t *) keys)->keys[ev_od]; + k = &((aes128_priv_t*)keys)->keys[ev_od]; for (; offset <= (188 - 16); offset += 16) { - AES_ecb_encrypt(pkt + offset, (uint8_t *)(pkt + offset), k, AES_DECRYPT); + AES_ecb_encrypt(pkt + offset, (uint8_t*)(pkt + offset), k, AES_DECRYPT); } } diff --git a/src/descrambler/algo/libaes128dec.h b/src/descrambler/algo/libaes128dec.h index 380008b7b..c683c99d6 100644 --- a/src/descrambler/algo/libaes128dec.h +++ b/src/descrambler/algo/libaes128dec.h @@ -13,22 +13,34 @@ #if ENABLE_SSL -void *aes128_get_priv_struct(void); -void aes128_free_priv_struct(void *keys); -void aes128_set_control_words(void *keys, const uint8_t *even, const uint8_t *odd); -void aes128_set_even_control_word(void *keys, const uint8_t *even); -void aes128_set_odd_control_word(void *keys, const uint8_t *odd); -void aes128_decrypt_packet(void *keys, const uint8_t *pkt); +void* aes128_get_priv_struct(void); +void aes128_free_priv_struct(void* keys); +void aes128_set_control_words(void* keys, const uint8_t* even, const uint8_t* odd); +void aes128_set_even_control_word(void* keys, const uint8_t* even); +void aes128_set_odd_control_word(void* keys, const uint8_t* odd); +void aes128_decrypt_packet(void* keys, const uint8_t* pkt); #else // empty functions -static inline void *aes128_get_priv_struct(void) { return NULL; }; -static inline void aes128_free_priv_struct(void *keys) { return; }; -static inline void aes128_set_control_words(void *keys, const uint8_t *even, const uint8_t *odd) { return; }; -static inline void aes128_set_even_control_word(void *keys, const uint8_t *even) { return; }; -static inline void aes128_set_odd_control_word(void *keys, const uint8_t *odd) { return; }; -static inline void aes128_decrypt_packet(void *keys, const uint8_t *pkt) { return; }; +static inline void* aes128_get_priv_struct(void) { + return NULL; +}; +static inline void aes128_free_priv_struct(void* keys) { + return; +}; +static inline void aes128_set_control_words(void* keys, const uint8_t* even, const uint8_t* odd) { + return; +}; +static inline void aes128_set_even_control_word(void* keys, const uint8_t* even) { + return; +}; +static inline void aes128_set_odd_control_word(void* keys, const uint8_t* odd) { + return; +}; +static inline void aes128_decrypt_packet(void* keys, const uint8_t* pkt) { + return; +}; #endif diff --git a/src/descrambler/algo/libaesdec.c b/src/descrambler/algo/libaesdec.c index 81374cb15..c7277cdf5 100644 --- a/src/descrambler/algo/libaesdec.c +++ b/src/descrambler/algo/libaesdec.c @@ -19,69 +19,61 @@ typedef struct aes_priv { } aes_priv_t; /* even cw represents one full 64-bit AES key */ -void aes_set_even_control_word(void *keys, const uint8_t *pk) -{ - AES_set_decrypt_key(pk, 64, &((aes_priv_t *) keys)->keys[0]); +void aes_set_even_control_word(void* keys, const uint8_t* pk) { + AES_set_decrypt_key(pk, 64, &((aes_priv_t*)keys)->keys[0]); } /* odd cw represents one full 64-bit AES key */ -void aes_set_odd_control_word(void *keys, const uint8_t *pk) -{ - AES_set_decrypt_key(pk, 64, &((aes_priv_t *) keys)->keys[1]); +void aes_set_odd_control_word(void* keys, const uint8_t* pk) { + AES_set_decrypt_key(pk, 64, &((aes_priv_t*)keys)->keys[1]); } /* set control words */ -void aes_set_control_words(void *keys, - const uint8_t *ev, - const uint8_t *od) -{ - AES_set_decrypt_key(ev, 64, &((aes_priv_t *) keys)->keys[0]); - AES_set_decrypt_key(od, 64, &((aes_priv_t *) keys)->keys[1]); +void aes_set_control_words(void* keys, const uint8_t* ev, const uint8_t* od) { + AES_set_decrypt_key(ev, 64, &((aes_priv_t*)keys)->keys[0]); + AES_set_decrypt_key(od, 64, &((aes_priv_t*)keys)->keys[1]); } /* allocate key structure */ -void * aes_get_priv_struct(void) -{ - aes_priv_t *keys; +void* aes_get_priv_struct(void) { + aes_priv_t* keys; - keys = (aes_priv_t *) malloc(sizeof(aes_priv_t)); + keys = (aes_priv_t*)malloc(sizeof(aes_priv_t)); if (keys) { - static const uint8_t pk[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + static const uint8_t pk[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; aes_set_control_words(keys, pk, pk); } return keys; } /* free key structure */ -void aes_free_priv_struct(void *keys) -{ +void aes_free_priv_struct(void* keys) { free(keys); } /* decrypt */ -void aes_decrypt_packet(void *keys, const uint8_t *pkt) -{ +void aes_decrypt_packet(void* keys, const uint8_t* pkt) { uint_fast8_t ev_od = 0; uint_fast8_t xc0, offset; - AES_KEY *k; + AES_KEY* k; // skip reserved and not encrypted pkt if (((xc0 = pkt[3]) & 0x80) == 0) return; - ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd - ((uint8_t *)pkt)[3] = xc0 & 0x3f; // consider it decrypted now - if (xc0 & 0x20) { // incomplete packet + ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd + ((uint8_t*)pkt)[3] = xc0 & 0x3f; // consider it decrypted now + if (xc0 & 0x20) { // incomplete packet offset = 4 + pkt[4] + 1; if (offset + 16 > 188) { // decrypted==encrypted! - return; // this doesn't need more processing + return; // this doesn't need more processing } } else { offset = 4; } - k = &((aes_priv_t *) keys)->keys[ev_od]; + k = &((aes_priv_t*)keys)->keys[ev_od]; for (; offset <= (188 - 8); offset += 8) { - AES_ecb_encrypt(pkt + offset, (uint8_t *)(pkt + offset), k, AES_DECRYPT); + AES_ecb_encrypt(pkt + offset, (uint8_t*)(pkt + offset), k, AES_DECRYPT); } } diff --git a/src/descrambler/algo/libaesdec.h b/src/descrambler/algo/libaesdec.h index a3198f327..825c8f745 100644 --- a/src/descrambler/algo/libaesdec.h +++ b/src/descrambler/algo/libaesdec.h @@ -13,22 +13,34 @@ #if ENABLE_SSL -void *aes_get_priv_struct(void); -void aes_free_priv_struct(void *keys); -void aes_set_control_words(void *keys, const uint8_t *even, const uint8_t *odd); -void aes_set_even_control_word(void *keys, const uint8_t *even); -void aes_set_odd_control_word(void *keys, const uint8_t *odd); -void aes_decrypt_packet(void *keys, const uint8_t *pkt); +void* aes_get_priv_struct(void); +void aes_free_priv_struct(void* keys); +void aes_set_control_words(void* keys, const uint8_t* even, const uint8_t* odd); +void aes_set_even_control_word(void* keys, const uint8_t* even); +void aes_set_odd_control_word(void* keys, const uint8_t* odd); +void aes_decrypt_packet(void* keys, const uint8_t* pkt); #else // empty functions -static inline void *aes_get_priv_struct(void) { return NULL; }; -static inline void aes_free_priv_struct(void *keys) { return; }; -static inline void aes_set_control_words(void *keys, const uint8_t *even, const uint8_t *odd) { return; }; -static inline void aes_set_even_control_word(void *keys, const uint8_t *even) { return; }; -static inline void aes_set_odd_control_word(void *keys, const uint8_t *odd) { return; }; -static inline void aes_decrypt_packet(void *keys, const uint8_t *pkt) { return; }; +static inline void* aes_get_priv_struct(void) { + return NULL; +}; +static inline void aes_free_priv_struct(void* keys) { + return; +}; +static inline void aes_set_control_words(void* keys, const uint8_t* even, const uint8_t* odd) { + return; +}; +static inline void aes_set_even_control_word(void* keys, const uint8_t* even) { + return; +}; +static inline void aes_set_odd_control_word(void* keys, const uint8_t* odd) { + return; +}; +static inline void aes_decrypt_packet(void* keys, const uint8_t* pkt) { + return; +}; #endif diff --git a/src/descrambler/algo/libdesdec.c b/src/descrambler/algo/libdesdec.c index 74880d607..575bafd96 100644 --- a/src/descrambler/algo/libdesdec.c +++ b/src/descrambler/algo/libdesdec.c @@ -17,80 +17,72 @@ typedef struct des_priv { } des_priv_t; /* even cw represents one 64-bit DES key */ -void des_set_even_control_word(void *priv, const uint8_t *pk) -{ - DES_set_key_unchecked((const_DES_cblock *)pk, &((des_priv_t *)priv)->sched[0]); +void des_set_even_control_word(void* priv, const uint8_t* pk) { + DES_set_key_unchecked((const_DES_cblock*)pk, &((des_priv_t*)priv)->sched[0]); } /* odd cw represents one 64-bit DES key */ -void des_set_odd_control_word(void *priv, const uint8_t *pk) -{ - DES_set_key_unchecked((const_DES_cblock *)pk, &((des_priv_t *)priv)->sched[1]); +void des_set_odd_control_word(void* priv, const uint8_t* pk) { + DES_set_key_unchecked((const_DES_cblock*)pk, &((des_priv_t*)priv)->sched[1]); } /* set control words */ -void des_set_control_words(void *priv, - const uint8_t *ev, - const uint8_t *od) -{ - DES_set_key_unchecked((const_DES_cblock *)ev, &((des_priv_t *)priv)->sched[0]); - DES_set_key_unchecked((const_DES_cblock *)od, &((des_priv_t *)priv)->sched[1]); +void des_set_control_words(void* priv, const uint8_t* ev, const uint8_t* od) { + DES_set_key_unchecked((const_DES_cblock*)ev, &((des_priv_t*)priv)->sched[0]); + DES_set_key_unchecked((const_DES_cblock*)od, &((des_priv_t*)priv)->sched[1]); } /* allocate key structure */ -void * des_get_priv_struct(void) -{ - des_priv_t *priv; +void* des_get_priv_struct(void) { + des_priv_t* priv; - priv = (des_priv_t *) malloc(sizeof(des_priv_t)); + priv = (des_priv_t*)malloc(sizeof(des_priv_t)); if (priv) { - static const uint8_t pk[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + static const uint8_t pk[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; des_set_control_words(priv, pk, pk); } return priv; } /* free key structure */ -void des_free_priv_struct(void *priv) -{ +void des_free_priv_struct(void* priv) { free(priv); } /* decrypt */ -void des_decrypt_packet(void *priv, const uint8_t *pkt) -{ - uint_fast8_t ev_od = 0; - uint_fast8_t xc0, offset, offset2, offset3; - DES_key_schedule *sched; - uint8_t buf[188]; +void des_decrypt_packet(void* priv, const uint8_t* pkt) { + uint_fast8_t ev_od = 0; + uint_fast8_t xc0, offset, offset2, offset3; + DES_key_schedule* sched; + uint8_t buf[188]; // skip reserved and not encrypted pkt if (((xc0 = pkt[3]) & 0x80) == 0) return; - ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd - ((uint8_t *)pkt)[3] = xc0 & 0x3f; // consider it decrypted now - if (xc0 & 0x20) { // incomplete packet + ev_od = (xc0 & 0x40) >> 6; // 0 even, 1 odd + ((uint8_t*)pkt)[3] = xc0 & 0x3f; // consider it decrypted now + if (xc0 & 0x20) { // incomplete packet offset = 4 + pkt[4] + 1; if (offset + 8 > 188) { // decrypted==encrypted! - return; // this doesn't need more processing + return; // this doesn't need more processing } } else { offset = 4; } - sched = &((des_priv_t *)priv)->sched[ev_od]; + sched = &((des_priv_t*)priv)->sched[ev_od]; if (offset & 3) { /* data must be aligned for DES_encrypt1() */ offset2 = (offset + 3) & ~3; memcpy(buf + offset2, pkt + offset, 188 - offset2); for (offset3 = offset2; offset3 <= (188 - 8); offset3 += 8) { - DES_encrypt1((DES_LONG *)(buf + offset3), sched, 0); + DES_encrypt1((DES_LONG*)(buf + offset3), sched, 0); } - memcpy((uint8_t *)(pkt + offset), buf + offset2, 188 - offset2); + memcpy((uint8_t*)(pkt + offset), buf + offset2, 188 - offset2); } else { for (; offset <= (188 - 8); offset += 8) { - DES_encrypt1((DES_LONG *)(pkt + offset), sched, 0); + DES_encrypt1((DES_LONG*)(pkt + offset), sched, 0); } } } diff --git a/src/descrambler/algo/libdesdec.h b/src/descrambler/algo/libdesdec.h index 80bdbd122..9edfe3c74 100644 --- a/src/descrambler/algo/libdesdec.h +++ b/src/descrambler/algo/libdesdec.h @@ -10,22 +10,34 @@ #if ENABLE_SSL -void *des_get_priv_struct(void); -void des_free_priv_struct(void *priv); -void des_set_control_words(void *priv, const uint8_t *even, const uint8_t *odd); -void des_set_even_control_word(void *priv, const uint8_t *even); -void des_set_odd_control_word(void *priv, const uint8_t *odd); -void des_decrypt_packet(void *priv, const uint8_t *pkt); +void* des_get_priv_struct(void); +void des_free_priv_struct(void* priv); +void des_set_control_words(void* priv, const uint8_t* even, const uint8_t* odd); +void des_set_even_control_word(void* priv, const uint8_t* even); +void des_set_odd_control_word(void* priv, const uint8_t* odd); +void des_decrypt_packet(void* priv, const uint8_t* pkt); #else // empty functions -static inline void *des_get_priv_struct(void) { return NULL; }; -static inline void des_free_priv_struct(void *priv) { return; }; -static inline void des_set_control_words(void *priv, const uint8_t *even, const uint8_t *odd) { return; }; -static inline void des_set_even_control_word(void *priv, const uint8_t *even) { return; }; -static inline void des_set_odd_control_word(void *priv, const uint8_t *odd) { return; }; -static inline void des_decrypt_packet(void *priv, const uint8_t *pkt) { return; }; +static inline void* des_get_priv_struct(void) { + return NULL; +}; +static inline void des_free_priv_struct(void* priv) { + return; +}; +static inline void des_set_control_words(void* priv, const uint8_t* even, const uint8_t* odd) { + return; +}; +static inline void des_set_even_control_word(void* priv, const uint8_t* even) { + return; +}; +static inline void des_set_odd_control_word(void* priv, const uint8_t* odd) { + return; +}; +static inline void des_decrypt_packet(void* priv, const uint8_t* pkt) { + return; +}; #endif diff --git a/src/descrambler/caclient.c b/src/descrambler/caclient.c index 945206224..92ef383e5 100644 --- a/src/descrambler/caclient.c +++ b/src/descrambler/caclient.c @@ -21,35 +21,32 @@ #include "caclient.h" #include "dvbcam.h" -const idclass_t *caclient_classes[] = { +const idclass_t* caclient_classes[] = { #if ENABLE_LINUXDVB_CA - &caclient_dvbcam_class, + &caclient_dvbcam_class, #endif #if ENABLE_CWC - &caclient_cwc_class, + &caclient_cwc_class, #endif #if ENABLE_CCCAM - &caclient_cccam_class, + &caclient_cccam_class, #endif #if ENABLE_CAPMT - &caclient_capmt_class, + &caclient_capmt_class, #endif #if ENABLE_CONSTCW - &caclient_ccw_csa_cbc_class, - &caclient_ccw_des_ncb_class, - &caclient_ccw_aes_ecb_class, - &caclient_ccw_aes128_ecb_class, + &caclient_ccw_csa_cbc_class, + &caclient_ccw_des_ncb_class, + &caclient_ccw_aes_ecb_class, + &caclient_ccw_aes128_ecb_class, #endif - NULL -}; + NULL}; struct caclient_entry_queue caclients; -static tvh_mutex_t caclients_mutex; +static tvh_mutex_t caclients_mutex; -static const idclass_t * -caclient_class_find(const char *name) -{ - const idclass_t **r; +static const idclass_t* caclient_class_find(const char* name) { + const idclass_t** r; for (r = caclient_classes; *r; r++) { if (strcmp((*r)->ic_class, name) == 0) return *r; @@ -57,41 +54,34 @@ caclient_class_find(const char *name) return NULL; } -static void -caclient_reindex(void) -{ - caclient_t *cac; - int i = 1; +static void caclient_reindex(void) { + caclient_t* cac; + int i = 1; - TAILQ_FOREACH(cac, &caclients, cac_link) + TAILQ_FOREACH (cac, &caclients, cac_link) cac->cac_save = 0; - TAILQ_FOREACH(cac, &caclients, cac_link) { + TAILQ_FOREACH (cac, &caclients, cac_link) { if (cac->cac_index != i) { cac->cac_index = i; - cac->cac_save = 1; + cac->cac_save = 1; } i++; } - TAILQ_FOREACH(cac, &caclients, cac_link) + TAILQ_FOREACH (cac, &caclients, cac_link) if (cac->cac_save) { cac->cac_save = 0; - idnode_changed((idnode_t *)cac); + idnode_changed((idnode_t*)cac); } } -static int -cac_cmp(caclient_t *a, caclient_t *b) -{ +static int cac_cmp(caclient_t* a, caclient_t* b) { return a->cac_index - b->cac_index; } -caclient_t * -caclient_create - (const char *uuid, htsmsg_t *conf, int save) -{ - caclient_t *cac = NULL; - const idclass_t *c = NULL; - const char *s; +caclient_t* caclient_create(const char* uuid, htsmsg_t* conf, int save) { + caclient_t* cac = NULL; + const idclass_t* c = NULL; + const char* s; lock_assert(&global_lock); @@ -118,10 +108,8 @@ caclient_create cac = capmt_create(); #endif #if ENABLE_CONSTCW - if (c == &caclient_ccw_csa_cbc_class || - c == &caclient_ccw_des_ncb_class || - c == &caclient_ccw_aes_ecb_class || - c == &caclient_ccw_aes128_ecb_class) + if (c == &caclient_ccw_csa_cbc_class || c == &caclient_ccw_des_ncb_class || + c == &caclient_ccw_aes_ecb_class || c == &caclient_ccw_aes128_ecb_class) cac = constcw_create(); #endif if (cac == NULL) { @@ -145,14 +133,12 @@ caclient_create } tvh_mutex_unlock(&caclients_mutex); if (save) - idnode_changed((idnode_t *)cac); + idnode_changed((idnode_t*)cac); cac->cac_conf_changed(cac); return cac; } -static void -caclient_delete(caclient_t *cac, int delconf) -{ +static void caclient_delete(caclient_t* cac, int delconf) { char ubuf[UUID_HEX_SIZE]; idnode_save_check(&cac->cac_id, delconf); @@ -171,49 +157,37 @@ caclient_delete(caclient_t *cac, int delconf) free(cac); } -static void -caclient_class_changed ( idnode_t *in ) -{ - caclient_t *cac = (caclient_t *)in; +static void caclient_class_changed(idnode_t* in) { + caclient_t* cac = (caclient_t*)in; cac->cac_conf_changed(cac); } -static htsmsg_t * -caclient_class_save ( idnode_t *in, char *filename, size_t fsize ) -{ - char ubuf[UUID_HEX_SIZE]; - htsmsg_t *c = htsmsg_create_map(); +static htsmsg_t* caclient_class_save(idnode_t* in, char* filename, size_t fsize) { + char ubuf[UUID_HEX_SIZE]; + htsmsg_t* c = htsmsg_create_map(); idnode_save(in, c); if (filename) snprintf(filename, fsize, "caclient/%s", idnode_uuid_as_str(in, ubuf)); return c; } -static void -caclient_class_get_title - ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) -{ - caclient_t *cac = (caclient_t *)in; +static void caclient_class_get_title(idnode_t* in, const char* lang, char* dst, size_t dstsize) { + caclient_t* cac = (caclient_t*)in; if (cac->cac_name && cac->cac_name[0]) { snprintf(dst, dstsize, "%s", cac->cac_name); } else { - snprintf(dst, dstsize, - tvh_gettext_lang(lang, N_("CA client %i")), cac->cac_index); + snprintf(dst, dstsize, tvh_gettext_lang(lang, N_("CA client %i")), cac->cac_index); } } -static void -caclient_class_delete(idnode_t *self) -{ - caclient_t *cac = (caclient_t *)self; +static void caclient_class_delete(idnode_t* self) { + caclient_t* cac = (caclient_t*)self; caclient_delete(cac, 1); } -static void -caclient_class_moveup(idnode_t *self) -{ - caclient_t *cac = (caclient_t *)self; - caclient_t *prev = TAILQ_PREV(cac, caclient_entry_queue, cac_link); +static void caclient_class_moveup(idnode_t* self) { + caclient_t* cac = (caclient_t*)self; + caclient_t* prev = TAILQ_PREV(cac, caclient_entry_queue, cac_link); if (prev) { TAILQ_REMOVE(&caclients, cac, cac_link); TAILQ_INSERT_BEFORE(prev, cac, cac_link); @@ -221,11 +195,9 @@ caclient_class_moveup(idnode_t *self) } } -static void -caclient_class_movedown(idnode_t *self) -{ - caclient_t *cac = (caclient_t *)self; - caclient_t *next = TAILQ_NEXT(cac, cac_link); +static void caclient_class_movedown(idnode_t* self) { + caclient_t* cac = (caclient_t*)self; + caclient_t* next = TAILQ_NEXT(cac, cac_link); if (next) { TAILQ_REMOVE(&caclients, cac, cac_link); TAILQ_INSERT_AFTER(&caclients, next, cac, cac_link); @@ -233,113 +205,98 @@ caclient_class_movedown(idnode_t *self) } } -static const void * -caclient_class_class_get(void *o) -{ - caclient_t *cac = o; - static const char *ret; +static const void* caclient_class_class_get(void* o) { + caclient_t* cac = o; + static const char* ret; ret = cac->cac_id.in_class->ic_class; return &ret; } -static int -caclient_class_class_set(void *o, const void *v) -{ +static int caclient_class_class_set(void* o, const void* v) { /* just ignore, create fcn does the right job */ return 0; } -static const void * -caclient_class_status_get(void *o) -{ - caclient_t *cac = o; - prop_ptr = caclient_get_status(cac); +static const void* caclient_class_status_get(void* o) { + caclient_t* cac = o; + prop_ptr = caclient_get_status(cac); return &prop_ptr; } CLASS_DOC(caclient) -const idclass_t caclient_class = -{ - .ic_class = "caclient", - .ic_caption = N_("Conditional Access Client"), - .ic_changed = caclient_class_changed, - .ic_save = caclient_class_save, - .ic_event = "caclient", - .ic_doc = tvh_doc_caclient_class, - .ic_get_title = caclient_class_get_title, - .ic_delete = caclient_class_delete, - .ic_moveup = caclient_class_moveup, - .ic_movedown = caclient_class_movedown, - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "class", - .name = N_("Class"), - .opts = PO_RDONLY | PO_HIDDEN | PO_NOUI, - .get = caclient_class_class_get, - .set = caclient_class_class_set, - .group = 1, - }, - { - .type = PT_INT, - .id = "index", - .name = N_("Index"), - .opts = PO_RDONLY | PO_HIDDEN | PO_NOUI, - .off = offsetof(caclient_t, cac_index), - .group = 1, - }, - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/Disable CA client."), - .off = offsetof(caclient_t, cac_enabled), - .group = 1, - }, - { - .type = PT_STR, - .id = "name", - .name = N_("Client name"), - .desc = N_("Name of the client."), - .off = offsetof(caclient_t, cac_name), - .notify = idnode_notify_title_changed_lang, - .group = 1, - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-form text field, enter whatever you like."), - .off = offsetof(caclient_t, cac_comment), - .group = 1, - }, - { - .type = PT_STR, - .id = "status", - .name = N_("Status"), - .get = caclient_class_status_get, - .opts = PO_RDONLY | PO_HIDDEN | PO_NOSAVE | PO_NOUI, - .group = 1, - }, - { } - } -}; - -void -caclient_start ( struct service *t ) -{ - caclient_t *cac; +const idclass_t caclient_class = {.ic_class = "caclient", + .ic_caption = N_("Conditional Access Client"), + .ic_changed = caclient_class_changed, + .ic_save = caclient_class_save, + .ic_event = "caclient", + .ic_doc = tvh_doc_caclient_class, + .ic_get_title = caclient_class_get_title, + .ic_delete = caclient_class_delete, + .ic_moveup = caclient_class_moveup, + .ic_movedown = caclient_class_movedown, + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + {}}, + .ic_properties = (const property_t[]){{ + .type = PT_STR, + .id = "class", + .name = N_("Class"), + .opts = PO_RDONLY | PO_HIDDEN | PO_NOUI, + .get = caclient_class_class_get, + .set = caclient_class_class_set, + .group = 1, + }, + { + .type = PT_INT, + .id = "index", + .name = N_("Index"), + .opts = PO_RDONLY | PO_HIDDEN | PO_NOUI, + .off = offsetof(caclient_t, cac_index), + .group = 1, + }, + { + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/Disable CA client."), + .off = offsetof(caclient_t, cac_enabled), + .group = 1, + }, + { + .type = PT_STR, + .id = "name", + .name = N_("Client name"), + .desc = N_("Name of the client."), + .off = offsetof(caclient_t, cac_name), + .notify = idnode_notify_title_changed_lang, + .group = 1, + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-form text field, enter whatever you like."), + .off = offsetof(caclient_t, cac_comment), + .group = 1, + }, + { + .type = PT_STR, + .id = "status", + .name = N_("Status"), + .get = caclient_class_status_get, + .opts = PO_RDONLY | PO_HIDDEN | PO_NOSAVE | PO_NOUI, + .group = 1, + }, + {}}}; + +void caclient_start(struct service* t) { + caclient_t* cac; tvh_mutex_lock(&caclients_mutex); - TAILQ_FOREACH(cac, &caclients, cac_link) + TAILQ_FOREACH (cac, &caclients, cac_link) if (cac->cac_enabled) cac->cac_start(cac, t); tvh_mutex_unlock(&caclients_mutex); @@ -348,62 +305,59 @@ caclient_start ( struct service *t ) #endif } -void -caclient_cat_update - ( struct mpegts_mux *mux, const uint8_t *data, int len ) -{ - caclient_t *cac; +void caclient_cat_update(struct mpegts_mux* mux, const uint8_t* data, int len) { + caclient_t* cac; lock_assert(&global_lock); tvh_mutex_lock(&caclients_mutex); - TAILQ_FOREACH(cac, &caclients, cac_link) + TAILQ_FOREACH (cac, &caclients, cac_link) if (cac->cac_cat_update && cac->cac_enabled) cac->cac_cat_update(cac, mux, data, len); tvh_mutex_unlock(&caclients_mutex); } -void -caclient_caid_update - ( struct mpegts_mux *mux, uint16_t caid, uint32_t provid, uint16_t pid, int valid ) -{ - caclient_t *cac; +void caclient_caid_update(struct mpegts_mux* mux, + uint16_t caid, + uint32_t provid, + uint16_t pid, + int valid) { + caclient_t* cac; lock_assert(&global_lock); tvh_mutex_lock(&caclients_mutex); - TAILQ_FOREACH(cac, &caclients, cac_link) + TAILQ_FOREACH (cac, &caclients, cac_link) if (cac->cac_caid_update && cac->cac_enabled) cac->cac_caid_update(cac, mux, caid, provid, pid, valid); tvh_mutex_unlock(&caclients_mutex); } -void -caclient_set_status(caclient_t *cac, caclient_status_t status) -{ +void caclient_set_status(caclient_t* cac, caclient_status_t status) { if (atomic_exchange(&cac->cac_status, status) != status) idnode_lnotify_changed(&cac->cac_id); } -const char * -caclient_get_status(caclient_t *cac) -{ +const char* caclient_get_status(caclient_t* cac) { switch (cac->cac_status) { - case CACLIENT_STATUS_NONE: return "caclientNone"; - case CACLIENT_STATUS_READY: return "caclientReady"; - case CACLIENT_STATUS_CONNECTED: return "caclientConnected"; - case CACLIENT_STATUS_DISCONNECTED: return "caclientDisconnected"; - default: return "caclientUnknown"; + case CACLIENT_STATUS_NONE: + return "caclientNone"; + case CACLIENT_STATUS_READY: + return "caclientReady"; + case CACLIENT_STATUS_CONNECTED: + return "caclientConnected"; + case CACLIENT_STATUS_DISCONNECTED: + return "caclientDisconnected"; + default: + return "caclientUnknown"; } } -void -caclient_foreach(void (*cb)(caclient_t *)) -{ - caclient_t *cac; +void caclient_foreach(void (*cb)(caclient_t*)) { + caclient_t* cac; tvh_mutex_lock(&caclients_mutex); - TAILQ_FOREACH(cac, &caclients, cac_link) + TAILQ_FOREACH (cac, &caclients, cac_link) cb(cac); tvh_mutex_unlock(&caclients_mutex); } @@ -411,12 +365,10 @@ caclient_foreach(void (*cb)(caclient_t *)) /* * Initialize */ -void -caclient_init(void) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - const idclass_t **r; +void caclient_init(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + const idclass_t** r; tvh_mutex_init(&caclients_mutex, NULL); TAILQ_INIT(&caclients); @@ -439,11 +391,11 @@ caclient_init(void) #if ENABLE_LINUXDVB_CA { - caclient_t *cac; + caclient_t* cac; dvbcam_init(); tvh_mutex_lock(&caclients_mutex); - TAILQ_FOREACH(cac, &caclients, cac_link) + TAILQ_FOREACH (cac, &caclients, cac_link) if (idnode_is_instance(&cac->cac_id, &caclient_dvbcam_class)) break; tvh_mutex_unlock(&caclients_mutex); @@ -459,10 +411,8 @@ caclient_init(void) #endif } -void -caclient_done(void) -{ - caclient_t *cac; +void caclient_done(void) { + caclient_t* cac; tvh_mutex_lock(&global_lock); while ((cac = TAILQ_FIRST(&caclients)) != NULL) diff --git a/src/descrambler/caclient.h b/src/descrambler/caclient.h index 397c86ac1..da555c28a 100644 --- a/src/descrambler/caclient.h +++ b/src/descrambler/caclient.h @@ -40,7 +40,7 @@ TAILQ_HEAD(caclient_entry_queue, caclient); extern struct caclient_entry_queue caclients; -extern const idclass_t *caclient_classes[]; +extern const idclass_t* caclient_classes[]; typedef enum caclient_status { CACLIENT_STATUS_NONE, @@ -53,53 +53,54 @@ typedef struct caclient { idnode_t cac_id; TAILQ_ENTRY(caclient) cac_link; - int cac_save; - int cac_index; - int cac_enabled; - char *cac_name; - char *cac_comment; - int cac_status; - - void (*cac_free)(struct caclient *cac); - void (*cac_start)(struct caclient *cac, struct service *t); - void (*cac_conf_changed)(struct caclient *cac); - void (*cac_cat_update)(struct caclient *cac, - struct mpegts_mux *mux, - const uint8_t *data, int len); - void (*cac_caid_update)(struct caclient *cac, - struct mpegts_mux *mux, - uint16_t caid, uint32_t prov, - uint16_t pid, int valid); + int cac_save; + int cac_index; + int cac_enabled; + char* cac_name; + char* cac_comment; + int cac_status; + + void (*cac_free)(struct caclient* cac); + void (*cac_start)(struct caclient* cac, struct service* t); + void (*cac_conf_changed)(struct caclient* cac); + void ( + *cac_cat_update)(struct caclient* cac, struct mpegts_mux* mux, const uint8_t* data, int len); + void (*cac_caid_update)(struct caclient* cac, + struct mpegts_mux* mux, + uint16_t caid, + uint32_t prov, + uint16_t pid, + int valid); } caclient_t; -caclient_t *caclient_create - (const char *uuid, htsmsg_t *conf, int save); +caclient_t* caclient_create(const char* uuid, htsmsg_t* conf, int save); -void caclient_start( struct service *t ); -void caclient_caid_update(struct mpegts_mux *mux, - uint16_t caid, uint32_t prov, - uint16_t pid, int valid); -void caclient_cat_update(struct mpegts_mux *mux, - const uint8_t *data, int len); +void caclient_start(struct service* t); +void caclient_caid_update(struct mpegts_mux* mux, + uint16_t caid, + uint32_t prov, + uint16_t pid, + int valid); +void caclient_cat_update(struct mpegts_mux* mux, const uint8_t* data, int len); -void caclient_set_status(caclient_t *cac, caclient_status_t status); -const char *caclient_get_status(caclient_t *cac); +void caclient_set_status(caclient_t* cac, caclient_status_t status); +const char* caclient_get_status(caclient_t* cac); -void caclient_foreach(void (*cb)(caclient_t *)); +void caclient_foreach(void (*cb)(caclient_t*)); void caclient_init(void); void caclient_done(void); -void tsdebugcw_service_start(struct service *t); -void tsdebugcw_new_keys(struct service *t, int type, uint16_t pid, uint8_t *odd, uint8_t *even); +void tsdebugcw_service_start(struct service* t); +void tsdebugcw_new_keys(struct service* t, int type, uint16_t pid, uint8_t* odd, uint8_t* even); void tsdebugcw_go(void); void tsdebugcw_init(void); -caclient_t *dvbcam_create(void); -caclient_t *cwc_create(void); -caclient_t *cccam_create(void); -caclient_t *capmt_create(void); -caclient_t *constcw_create(void); -caclient_t *tsdebugcw_create(void); +caclient_t* dvbcam_create(void); +caclient_t* cwc_create(void); +caclient_t* cccam_create(void); +caclient_t* capmt_create(void); +caclient_t* constcw_create(void); +caclient_t* tsdebugcw_create(void); #endif /* __TVH_CACLIENT_H__ */ diff --git a/src/descrambler/caid.c b/src/descrambler/caid.c index fef27e9f1..27a23a764 100644 --- a/src/descrambler/caid.c +++ b/src/descrambler/caid.c @@ -20,70 +20,68 @@ #include "descrambler/caid.h" struct caid_tab { - const char *name; - uint16_t caid; - uint16_t mask; + const char* name; + uint16_t caid; + uint16_t mask; }; static struct caid_tab caidnametab[] = { - { "Seca", 0x0100, 0xff00 }, - { "CCETT", 0x0200, 0xff00 }, - { "Deutsche Telekom", 0x0300, 0xff00 }, - { "Eurodec", 0x0400, 0xff00 }, - { "Viaccess", 0x0500, 0xff00 }, - { "Irdeto", 0x0600, 0xff00 }, - { "Jerroldgi", 0x0700, 0xff00 }, - { "Matra", 0x0800, 0xff00 }, - { "NDS", 0x0900, 0xff00 }, - { "Nokia", 0x0A00, 0xff00 }, - { "Conax", 0x0B00, 0xff00 }, - { "NTL", 0x0C00, 0xff00 }, - { "CryptoWorks", 0x0D00, 0xff80 }, - { "CryptoWorks ICE", 0x0D80, 0xff80 }, - { "PowerVu", 0x0E00, 0xff00 }, - { "Sony", 0x0F00, 0xff00 }, - { "Tandberg", 0x1000, 0xff00 }, - { "Thompson", 0x1100, 0xff00 }, - { "TV-Com", 0x1200, 0xff00 }, - { "HPT", 0x1300, 0xff00 }, - { "HRT", 0x1400, 0xff00 }, - { "IBM", 0x1500, 0xff00 }, - { "Nera", 0x1600, 0xff00 }, - { "BetaCrypt", 0x1700, 0xff00 }, - { "NagraVision", 0x1800, 0xff00 }, - { "Titan", 0x1900, 0xff00 }, - { "Telefonica", 0x2000, 0xff00 }, - { "Stentor", 0x2100, 0xff00 }, - { "Tadiran Scopus", 0x2200, 0xff00 }, - { "BARCO AS", 0x2300, 0xff00 }, - { "StarGuide", 0x2400, 0xff00 }, - { "Mentor", 0x2500, 0xff00 }, - { "EBU", 0x2600, 0xff00 }, - { "DRECrypt ", 0x2710, 0xffff }, - { "GI", 0x4700, 0xff00 }, - { "Telemann", 0x4800, 0xff00 }, - { "TongFang", 0x4a02, 0xffff }, - { "DVN", 0x4a30, 0xffff }, - { "DGCrypt", 0x4abf, 0xffff }, - { "XCrypt", 0x4ad0, 0xfffe }, - { "StreamGuard", 0x4ad2, 0xffff }, - { "DRECrypt", 0x4ae0, 0xffff }, - { "DRECrypt2", 0x4ae1, 0xffff }, - { "Bulcrypt", 0x4aee, 0xffff }, - { "TongFang", 0x4b00, 0xff00 }, - { "Griffin", 0x5500, 0xffe0 }, - { "Bulcrypt", 0x5581, 0xffff }, - { "Verimatrix", 0x5601, 0xffff }, - { "DRECrypt", 0x7be0, 0xfffe }, + {"Seca", 0x0100, 0xff00}, + {"CCETT", 0x0200, 0xff00}, + {"Deutsche Telekom", 0x0300, 0xff00}, + {"Eurodec", 0x0400, 0xff00}, + {"Viaccess", 0x0500, 0xff00}, + {"Irdeto", 0x0600, 0xff00}, + {"Jerroldgi", 0x0700, 0xff00}, + {"Matra", 0x0800, 0xff00}, + {"NDS", 0x0900, 0xff00}, + {"Nokia", 0x0A00, 0xff00}, + {"Conax", 0x0B00, 0xff00}, + {"NTL", 0x0C00, 0xff00}, + {"CryptoWorks", 0x0D00, 0xff80}, + {"CryptoWorks ICE", 0x0D80, 0xff80}, + {"PowerVu", 0x0E00, 0xff00}, + {"Sony", 0x0F00, 0xff00}, + {"Tandberg", 0x1000, 0xff00}, + {"Thompson", 0x1100, 0xff00}, + {"TV-Com", 0x1200, 0xff00}, + {"HPT", 0x1300, 0xff00}, + {"HRT", 0x1400, 0xff00}, + {"IBM", 0x1500, 0xff00}, + {"Nera", 0x1600, 0xff00}, + {"BetaCrypt", 0x1700, 0xff00}, + {"NagraVision", 0x1800, 0xff00}, + {"Titan", 0x1900, 0xff00}, + {"Telefonica", 0x2000, 0xff00}, + {"Stentor", 0x2100, 0xff00}, + {"Tadiran Scopus", 0x2200, 0xff00}, + {"BARCO AS", 0x2300, 0xff00}, + {"StarGuide", 0x2400, 0xff00}, + {"Mentor", 0x2500, 0xff00}, + {"EBU", 0x2600, 0xff00}, + {"DRECrypt ", 0x2710, 0xffff}, + {"GI", 0x4700, 0xff00}, + {"Telemann", 0x4800, 0xff00}, + {"TongFang", 0x4a02, 0xffff}, + {"DVN", 0x4a30, 0xffff}, + {"DGCrypt", 0x4abf, 0xffff}, + {"XCrypt", 0x4ad0, 0xfffe}, + {"StreamGuard", 0x4ad2, 0xffff}, + {"DRECrypt", 0x4ae0, 0xffff}, + {"DRECrypt2", 0x4ae1, 0xffff}, + {"Bulcrypt", 0x4aee, 0xffff}, + {"TongFang", 0x4b00, 0xff00}, + {"Griffin", 0x5500, 0xffe0}, + {"Bulcrypt", 0x5581, 0xffff}, + {"Verimatrix", 0x5601, 0xffff}, + {"DRECrypt", 0x7be0, 0xfffe}, }; -const char * -caid2name(uint16_t caid) -{ - const char *s = NULL; +const char* caid2name(uint16_t caid) { + const char* s = NULL; static __thread char buf[20]; - struct caid_tab *tab; - int i; + struct caid_tab* tab; + int i; for (i = 0; i < ARRAY_SIZE(caidnametab); i++) { tab = &caidnametab[i]; @@ -92,17 +90,15 @@ caid2name(uint16_t caid) break; } } - if(s != NULL) + if (s != NULL) return s; snprintf(buf, sizeof(buf), "0x%x", caid); return buf; } -uint16_t -name2caid(const char *s) -{ - int i, r = -1; - struct caid_tab *tab; +uint16_t name2caid(const char* s) { + int i, r = -1; + struct caid_tab* tab; for (i = 0; i < ARRAY_SIZE(caidnametab); i++) { tab = &caidnametab[i]; @@ -122,12 +118,10 @@ name2caid(const char *s) * * based on the equivalent in sasc-ng */ -card_type_t -detect_card_type(const uint16_t caid) -{ +card_type_t detect_card_type(const uint16_t caid) { uint8_t c_sys = caid >> 8; - switch(caid) { + switch (caid) { case 0x2710: return CARD_DRE; case 0x4a02: @@ -148,8 +142,8 @@ detect_card_type(const uint16_t caid) case 0x5581: return CARD_BULCRYPT; } - - switch(c_sys) { + + switch (c_sys) { case 0x01: return CARD_SECA; case 0x05: diff --git a/src/descrambler/caid.h b/src/descrambler/caid.h index 726999d74..0342e31fc 100644 --- a/src/descrambler/caid.h +++ b/src/descrambler/caid.h @@ -40,15 +40,25 @@ typedef enum { CARD_UNKNOWN } card_type_t; -const char *caid2name(uint16_t caid); -uint16_t name2caid(const char *str); +const char* caid2name(uint16_t caid); +uint16_t name2caid(const char* str); card_type_t detect_card_type(const uint16_t caid); -static inline int caid_is_irdeto(uint16_t caid) { return (caid >> 8) == 0x06; } -static inline int caid_is_videoguard(uint16_t caid) { return (caid >> 8) == 0x09; } -static inline int caid_is_powervu(uint16_t caid) { return (caid >> 8) == 0x0e; } -static inline int caid_is_betacrypt(uint16_t caid) { return (caid >> 8) == 0x17; } -static inline int caid_is_dvn(uint16_t caid) { return caid == 0x4a30; } +static inline int caid_is_irdeto(uint16_t caid) { + return (caid >> 8) == 0x06; +} +static inline int caid_is_videoguard(uint16_t caid) { + return (caid >> 8) == 0x09; +} +static inline int caid_is_powervu(uint16_t caid) { + return (caid >> 8) == 0x0e; +} +static inline int caid_is_betacrypt(uint16_t caid) { + return (caid >> 8) == 0x17; +} +static inline int caid_is_dvn(uint16_t caid) { + return caid == 0x4a30; +} #endif /* __TVH_CAID_H__ */ diff --git a/src/descrambler/capmt.c b/src/descrambler/capmt.c index f37a0c22a..ab51e6bbe 100644 --- a/src/descrambler/capmt.c +++ b/src/descrambler/capmt.c @@ -53,7 +53,7 @@ typedef struct dmx_filter { uint8_t mode[DMX_FILTER_SIZE]; } dmx_filter_t; -#define DVBAPI_PROTOCOL_VERSION 2 +#define DVBAPI_PROTOCOL_VERSION 2 #define CA_SET_DESCR_ 0x40106f86 #define CA_SET_DESCR_X 0x866f1040 @@ -75,12 +75,20 @@ typedef struct dmx_filter { #define PID_BLOCKED (0xfffe) // ca_pmt_list_management values: -#define CAPMT_LIST_MORE 0x00 // append a 'MORE' CAPMT object the list and start receiving the next object -#define CAPMT_LIST_FIRST 0x01 // clear the list when a 'FIRST' CAPMT object is received, and start receiving the next object -#define CAPMT_LIST_LAST 0x02 // append a 'LAST' CAPMT object to the list and start working with the list -#define CAPMT_LIST_ONLY 0x03 // clear the list when an 'ONLY' CAPMT object is received, and start working with the object -#define CAPMT_LIST_ADD 0x04 // append an 'ADD' CAPMT object to the current list and start working with the updated list -#define CAPMT_LIST_UPDATE 0x05 // replace an entry in the list with an 'UPDATE' CAPMT object, and start working with the updated list +#define CAPMT_LIST_MORE \ + 0x00 // append a 'MORE' CAPMT object the list and start receiving the next object +#define CAPMT_LIST_FIRST \ + 0x01 // clear the list when a 'FIRST' CAPMT object is received, and start receiving the next + // object +#define CAPMT_LIST_LAST \ + 0x02 // append a 'LAST' CAPMT object to the list and start working with the list +#define CAPMT_LIST_ONLY \ + 0x03 // clear the list when an 'ONLY' CAPMT object is received, and start working with the object +#define CAPMT_LIST_ADD \ + 0x04 // append an 'ADD' CAPMT object to the current list and start working with the updated list +#define CAPMT_LIST_UPDATE \ + 0x05 // replace an entry in the list with an 'UPDATE' CAPMT object, and start working with the + // updated list // ca_pmt_descriptor types #define CAPMT_DESC_ENIGMA 0x81 @@ -89,36 +97,36 @@ typedef struct dmx_filter { #define CAPMT_DESC_PID 0x84 // message type -#define CAPMT_MSG_FAST 0x01 -#define CAPMT_MSG_CLEAR 0x02 -#define CAPMT_MSG_NODUP 0x04 -#define CAPMT_MSG_HELLO 0x08 +#define CAPMT_MSG_FAST 0x01 +#define CAPMT_MSG_CLEAR 0x02 +#define CAPMT_MSG_NODUP 0x04 +#define CAPMT_MSG_HELLO 0x08 // cw modes -#define CAPMT_CWMODE_AUTO 0 -#define CAPMT_CWMODE_OE22 1 // CA_SET_DESCR_MODE before CA_SET_DESCR -#define CAPMT_CWMODE_OE22SW 2 // CA_SET_DESCR_MODE follows CA_SET_DESCR -#define CAPMT_CWMODE_OE20 3 // DES signalled through PID index +#define CAPMT_CWMODE_AUTO 0 +#define CAPMT_CWMODE_OE22 1 // CA_SET_DESCR_MODE before CA_SET_DESCR +#define CAPMT_CWMODE_OE22SW 2 // CA_SET_DESCR_MODE follows CA_SET_DESCR +#define CAPMT_CWMODE_OE20 3 // DES signalled through PID index // pmt modes #define CAPMT_PMTMODE_AUTO 0 -#define CAPMT_PMTMODE_INDEX 1 // mix enigma2 / PC boxtype messages -#define CAPMT_PMTMODE_UNIVERSAL 2 // use fixed PC boxtype messages +#define CAPMT_PMTMODE_INDEX 1 // mix enigma2 / PC boxtype messages +#define CAPMT_PMTMODE_UNIVERSAL 2 // use fixed PC boxtype messages // limits #define MAX_CA 16 #define MAX_INDEX 128 #define MAX_FILTER 64 -#define MAX_SOCKETS 16 // max sockets (simultaneous channels) per demux -#define MAX_PIDS 64 // max opened pids +#define MAX_SOCKETS 16 // max sockets (simultaneous channels) per demux +#define MAX_PIDS 64 // max opened pids #define MAX_INFO_LEN 255 #if 0 // really old implementations -#define CAPMT_OSCAM_SO_WRAPPER 0 -#define CAPMT_OSCAM_OLD 1 -#define CAPMT_OSCAM_MULTILIST 2 -#define CAPMT_OSCAM_TCP 3 -#define CAPMT_OSCAM_UNIX_SOCKET 4 +#define CAPMT_OSCAM_SO_WRAPPER 0 +#define CAPMT_OSCAM_OLD 1 +#define CAPMT_OSCAM_MULTILIST 2 +#define CAPMT_OSCAM_TCP 3 +#define CAPMT_OSCAM_UNIX_SOCKET 4 #endif #define CAPMT_OSCAM_NET_PROTO 5 #define CAPMT_OSCAM_UNIX_SOCKET_NP 6 /* NET_PROTO through socket */ @@ -133,7 +141,7 @@ LIST_HEAD(capmt_caid_ecm_list, capmt_caid_ecm); * ECM descriptor */ typedef struct ca_info { - uint16_t pids[MAX_PIDS]; // elementary stream pids (was: sequence / service id number) + uint16_t pids[MAX_PIDS]; // elementary stream pids (was: sequence / service id number) enum { CA_ALGO_DVBCSA, CA_ALGO_DES, @@ -146,7 +154,7 @@ typedef struct ca_info { } ca_info_t; /** - * caid <-> ecm mapping + * caid <-> ecm mapping */ typedef struct capmt_caid_ecm { /** ca system id */ @@ -156,7 +164,7 @@ typedef struct capmt_caid_ecm { /** provider id */ uint32_t cce_providerid; /** service */ - mpegts_service_t *cce_service; + mpegts_service_t* cce_service; LIST_ENTRY(capmt_caid_ecm) cce_link; @@ -169,7 +177,7 @@ typedef struct capmt_caid_ecm { typedef struct capmt_service { th_descrambler_t; - struct capmt *ct_capmt; + struct capmt* ct_capmt; LIST_ENTRY(capmt_service) ct_link; @@ -188,7 +196,7 @@ typedef struct capmt_service { uint8_t ct_type_sok[MAX_PIDS]; /* OK flag - seems that descrambling is going on */ - uint8_t ct_ok_flag; + uint8_t ct_ok_flag; mtimer_t ct_ok_timer; } capmt_service_t; @@ -197,26 +205,26 @@ typedef struct capmt_service { */ typedef struct capmt_dmx { dmx_filter_t filter; - uint16_t pid; - uint32_t flags; + uint16_t pid; + uint32_t flags; } capmt_dmx_t; typedef struct capmt_filters { - int max; - int adapter; + int max; + int adapter; capmt_dmx_t dmx[MAX_FILTER]; } capmt_filters_t; typedef struct capmt_demuxes { - int max; + int max; capmt_filters_t filters[MAX_INDEX]; } capmt_demuxes_t; typedef struct capmt_message { TAILQ_ENTRY(capmt_message) cm_link; - int cm_adapter; - int cm_sid; - int cm_flags; + int cm_adapter; + int cm_sid; + int cm_flags; sbuf_t cm_sb; } capmt_message_t; @@ -225,18 +233,18 @@ typedef struct capmt_message { */ struct capmt; typedef struct capmt_opaque { - struct capmt *capmt; - uint16_t adapter; - uint16_t pid; - uint32_t pid_refs; - int ecm; + struct capmt* capmt; + uint16_t adapter; + uint16_t pid; + uint32_t pid_refs; + int ecm; } capmt_opaque_t; typedef struct capmt_adapter { ca_info_t ca_info[MAX_INDEX]; int ca_number; int ca_sock; - mpegts_input_t *ca_tuner; + mpegts_input_t* ca_tuner; capmt_opaque_t ca_pids[MAX_PIDS]; sbuf_t ca_rbuf; } capmt_adapter_t; @@ -256,7 +264,7 @@ typedef struct capmt { char capmt_name[128]; /* from capmt configuration */ - char *capmt_sockfile; + char* capmt_sockfile; int capmt_port; int capmt_oscam; int capmt_cwmode; @@ -264,24 +272,24 @@ typedef struct capmt { int capmt_oscam_rev; /* capmt sockets */ - int sids[MAX_SOCKETS]; - int adps[MAX_SOCKETS]; - int capmt_sock[MAX_SOCKETS]; - int capmt_sock_reconnect[MAX_SOCKETS]; + int sids[MAX_SOCKETS]; + int adps[MAX_SOCKETS]; + int capmt_sock[MAX_SOCKETS]; + int capmt_sock_reconnect[MAX_SOCKETS]; /* thread flags */ - int capmt_connected; - int capmt_running; - int capmt_reconfigure; + int capmt_connected; + int capmt_running; + int capmt_reconfigure; /* runtime status */ - tvhpoll_t *capmt_poll; + tvhpoll_t* capmt_poll; th_pipe_t capmt_pipe; capmt_demuxes_t capmt_demuxes; capmt_adapter_t capmt_adapters[MAX_CA]; TAILQ_HEAD(, capmt_message) capmt_writeq; tvh_mutex_t capmt_mutex; - uint8_t capmt_pmtversion; + uint8_t capmt_pmtversion; /* last key */ struct { @@ -292,25 +300,20 @@ typedef struct capmt { } capmt_last_key; } capmt_t; -static void capmt_enumerate_services(capmt_t *capmt, int force); -static void capmt_notify_server(capmt_t *capmt, capmt_service_t *ct, int force); -static void capmt_send_request(capmt_service_t *ct, int lm); -static void capmt_table_input(void *opaque, int pid, - const uint8_t *data, int len, int emm); -static void capmt_send_client_info(capmt_t *capmt); +static void capmt_enumerate_services(capmt_t* capmt, int force); +static void capmt_notify_server(capmt_t* capmt, capmt_service_t* ct, int force); +static void capmt_send_request(capmt_service_t* ct, int lm); +static void capmt_table_input(void* opaque, int pid, const uint8_t* data, int len, int emm); +static void capmt_send_client_info(capmt_t* capmt); /** * */ -static inline const char * -capmt_name(capmt_t *capmt) -{ +static inline const char* capmt_name(capmt_t* capmt) { return capmt->capmt_name; } -static inline int -capmt_oscam_so_wrapper(capmt_t *capmt) -{ +static inline int capmt_oscam_so_wrapper(capmt_t* capmt) { #ifdef CAPMT_OSCAM_SO_WRAPPER if (capmt->capmt_oscam == CAPMT_OSCAM_SO_WRAPPER) return 1; @@ -318,9 +321,7 @@ capmt_oscam_so_wrapper(capmt_t *capmt) return 0; } -static inline int -capmt_oscam_new(capmt_t *capmt) -{ +static inline int capmt_oscam_new(capmt_t* capmt) { if (capmt_oscam_so_wrapper(capmt)) return 0; #ifdef CAPMT_OSCAM_OLD @@ -330,9 +331,7 @@ capmt_oscam_new(capmt_t *capmt) return 1; } -static inline int -capmt_oscam_network(capmt_t *capmt) -{ +static inline int capmt_oscam_network(capmt_t* capmt) { #ifdef CAPMT_OSCAM_TCP if (capmt->capmt_oscam == CAPMT_OSCAM_TCP) return 1; @@ -344,9 +343,7 @@ capmt_oscam_network(capmt_t *capmt) return 0; } -static inline int -capmt_oscam_socket(capmt_t *capmt) -{ +static inline int capmt_oscam_socket(capmt_t* capmt) { #ifdef CAPMT_OSCAM_UNIX_SOCKET if (capmt->capmt_oscam == CAPMT_OSCAM_UNIX_SOCKET) return 1; @@ -358,44 +355,33 @@ capmt_oscam_socket(capmt_t *capmt) return 0; } -static inline int -capmt_oscam_netproto(capmt_t *capmt) -{ +static inline int capmt_oscam_netproto(capmt_t* capmt) { int oscam = capmt->capmt_oscam; - return oscam == CAPMT_OSCAM_NET_PROTO || - oscam == CAPMT_OSCAM_UNIX_SOCKET_NP; + return oscam == CAPMT_OSCAM_NET_PROTO || oscam == CAPMT_OSCAM_UNIX_SOCKET_NP; } -static inline int -capmt_include_elementary_stream(streaming_component_type_t type) -{ +static inline int capmt_include_elementary_stream(streaming_component_type_t type) { return SCT_ISAV(type) || type == SCT_DVBSUB || type == SCT_TELETEXT; } -static int -capmt_poll_add(capmt_t *capmt, int fd, void *ptr) -{ +static int capmt_poll_add(capmt_t* capmt, int fd, void* ptr) { if (capmt->capmt_poll == NULL) return 0; return tvhpoll_add1(capmt->capmt_poll, fd, TVHPOLL_IN, ptr); } -static int -capmt_poll_rem(capmt_t *capmt, int fd) -{ +static int capmt_poll_rem(capmt_t* capmt, int fd) { if (capmt->capmt_poll == NULL) return 0; return tvhpoll_rem1(capmt->capmt_poll, fd); } -static void -capmt_pid_add(capmt_t *capmt, int adapter, int pid, mpegts_service_t *s) -{ - capmt_adapter_t *ca = &capmt->capmt_adapters[adapter]; - capmt_opaque_t *o = NULL, *t; - mpegts_mux_instance_t *mmi; - mpegts_mux_t *mux; - int i = 0, ecm = s != NULL; +static void capmt_pid_add(capmt_t* capmt, int adapter, int pid, mpegts_service_t* s) { + capmt_adapter_t* ca = &capmt->capmt_adapters[adapter]; + capmt_opaque_t * o = NULL, *t; + mpegts_mux_instance_t* mmi; + mpegts_mux_t* mux; + int i = 0, ecm = s != NULL; lock_assert(&capmt->capmt_mutex); @@ -403,8 +389,12 @@ capmt_pid_add(capmt_t *capmt, int adapter, int pid, mpegts_service_t *s) t = &ca->ca_pids[i]; if (t->pid == pid && t->ecm == ecm) { t->pid_refs++; - tvhtrace(LS_CAPMT, "%s: adding pid %d adapter %d - reusing (%d)", - capmt_name(capmt), pid, adapter, t->pid_refs); + tvhtrace(LS_CAPMT, + "%s: adding pid %d adapter %d - reusing (%d)", + capmt_name(capmt), + pid, + adapter, + t->pid_refs); return; } if (t->pid == PID_UNUSED) @@ -418,25 +408,32 @@ capmt_pid_add(capmt_t *capmt, int adapter, int pid, mpegts_service_t *s) o->ecm = ecm; mmi = ca->ca_tuner ? LIST_FIRST(&ca->ca_tuner->mi_mux_active) : NULL; mux = mmi ? mmi->mmi_mux : NULL; - tvhtrace(LS_CAPMT, "%s: adding pid %d adapter %d, tuner %p, mmi %p, mux %p", capmt_name(capmt), pid, adapter, ca->ca_tuner, mmi, mux); + tvhtrace(LS_CAPMT, + "%s: adding pid %d adapter %d, tuner %p, mmi %p, mux %p", + capmt_name(capmt), + pid, + adapter, + ca->ca_tuner, + mmi, + mux); if (mux) { tvh_mutex_unlock(&capmt->capmt_mutex); - descrambler_open_pid(mux, o, - s ? DESCRAMBLER_ECM_PID(pid) : pid, - capmt_table_input, (service_t *)s); + descrambler_open_pid(mux, + o, + s ? DESCRAMBLER_ECM_PID(pid) : pid, + capmt_table_input, + (service_t*)s); tvh_mutex_lock(&capmt->capmt_mutex); } } } -static void -capmt_pid_remove(capmt_t *capmt, int adapter, int pid, uint32_t flags) -{ - capmt_adapter_t *ca = &capmt->capmt_adapters[adapter]; - capmt_opaque_t *o; - mpegts_mux_instance_t *mmi; - mpegts_mux_t *mux; - int i = 0, ecm = (flags & CAPMT_MSG_FAST) != 0; +static void capmt_pid_remove(capmt_t* capmt, int adapter, int pid, uint32_t flags) { + capmt_adapter_t* ca = &capmt->capmt_adapters[adapter]; + capmt_opaque_t* o; + mpegts_mux_instance_t* mmi; + mpegts_mux_t* mux; + int i = 0, ecm = (flags & CAPMT_MSG_FAST) != 0; lock_assert(&capmt->capmt_mutex); @@ -452,9 +449,9 @@ capmt_pid_remove(capmt_t *capmt, int adapter, int pid, uint32_t flags) } if (i >= MAX_PIDS) return; - mmi = ca->ca_tuner ? LIST_FIRST(&ca->ca_tuner->mi_mux_active) : NULL; - mux = mmi ? mmi->mmi_mux : NULL; - o->pid = PID_BLOCKED; + mmi = ca->ca_tuner ? LIST_FIRST(&ca->ca_tuner->mi_mux_active) : NULL; + mux = mmi ? mmi->mmi_mux : NULL; + o->pid = PID_BLOCKED; o->pid_refs = 0; if (o->ecm) pid = DESCRAMBLER_ECM_PID(pid); @@ -467,24 +464,22 @@ capmt_pid_remove(capmt_t *capmt, int adapter, int pid, uint32_t flags) o->pid = PID_UNUSED; } -static void -capmt_pid_flush_adapter(capmt_t *capmt, int adapter) -{ - capmt_adapter_t *ca; - mpegts_mux_instance_t *mmi; - mpegts_input_t *tuner; - mpegts_mux_t *mux; - capmt_opaque_t *o; - int pid, i; +static void capmt_pid_flush_adapter(capmt_t* capmt, int adapter) { + capmt_adapter_t* ca; + mpegts_mux_instance_t* mmi; + mpegts_input_t* tuner; + mpegts_mux_t* mux; + capmt_opaque_t* o; + int pid, i; tvhtrace(LS_CAPMT, "%s: pid flush for adapter %d", capmt_name(capmt), adapter); - ca = &capmt->capmt_adapters[adapter]; + ca = &capmt->capmt_adapters[adapter]; tuner = capmt->capmt_adapters[adapter].ca_tuner; if (tuner == NULL) { /* clean all pids (to be sure) */ for (i = 0; i < MAX_PIDS; i++) { - o = &ca->ca_pids[i]; - o->pid = PID_UNUSED; + o = &ca->ca_pids[i]; + o->pid = PID_UNUSED; o->pid_refs = 0; } return; @@ -494,7 +489,7 @@ capmt_pid_flush_adapter(capmt_t *capmt, int adapter) for (i = 0; i < MAX_PIDS; i++) { o = &ca->ca_pids[i]; if ((pid = o->pid) > 0) { - o->pid = PID_BLOCKED; + o->pid = PID_BLOCKED; o->pid_refs = 0; if (mux) { tvh_mutex_unlock(&capmt->capmt_mutex); @@ -506,9 +501,7 @@ capmt_pid_flush_adapter(capmt_t *capmt, int adapter) } } -static void -capmt_pid_flush(capmt_t *capmt) -{ +static void capmt_pid_flush(capmt_t* capmt) { int adapter; for (adapter = 0; adapter < MAX_CA; adapter++) capmt_pid_flush_adapter(capmt, adapter); @@ -517,9 +510,7 @@ capmt_pid_flush(capmt_t *capmt) /* * */ -static int -capmt_connect(capmt_t *capmt, int i) -{ +static int capmt_connect(capmt_t* capmt, int i) { int fd; capmt->capmt_sock[i] = -1; @@ -532,12 +523,14 @@ capmt_connect(capmt_t *capmt, int i) char errbuf[256]; - fd = tcp_connect(capmt->capmt_sockfile, capmt->capmt_port, NULL, - errbuf, sizeof(errbuf), 2); + fd = tcp_connect(capmt->capmt_sockfile, capmt->capmt_port, NULL, errbuf, sizeof(errbuf), 2); if (fd < 0 && tvheadend_is_running()) { tvherror(LS_CAPMT, - "%s: Cannot connect to %s:%i (%s); Do you have OSCam running?", - capmt_name(capmt), capmt->capmt_sockfile, capmt->capmt_port, errbuf); + "%s: Cannot connect to %s:%i (%s); Do you have OSCam running?", + capmt_name(capmt), + capmt->capmt_sockfile, + capmt->capmt_port, + errbuf); fd = -1; } @@ -549,24 +542,21 @@ capmt_connect(capmt_t *capmt, int i) memset(&serv_addr_un, 0, sizeof(serv_addr_un)); serv_addr_un.sun_family = AF_LOCAL; - snprintf(serv_addr_un.sun_path, - sizeof(serv_addr_un.sun_path), - "%s", capmt->capmt_sockfile); + snprintf(serv_addr_un.sun_path, sizeof(serv_addr_un.sun_path), "%s", capmt->capmt_sockfile); fd = tvh_socket(AF_LOCAL, SOCK_STREAM, 0); - if (fd < 0 || - connect(fd, (const struct sockaddr*)&serv_addr_un, - sizeof(serv_addr_un)) != 0) { + if (fd < 0 || connect(fd, (const struct sockaddr*)&serv_addr_un, sizeof(serv_addr_un)) != 0) { if (tvheadend_is_running()) tvherror(LS_CAPMT, - "%s: Cannot connect to %s (%s); Do you have OSCam running?", - capmt_name(capmt), capmt->capmt_sockfile, strerror(errno)); + "%s: Cannot connect to %s (%s); Do you have OSCam running?", + capmt_name(capmt), + capmt->capmt_sockfile, + strerror(errno)); if (fd >= 0) { close(fd); fd = -1; } } - } if (fd >= 0) { @@ -584,9 +574,7 @@ capmt_connect(capmt_t *capmt, int i) /** * */ -static void -capmt_socket_close(capmt_t *capmt, int sock_idx) -{ +static void capmt_socket_close(capmt_t* capmt, int sock_idx) { int fd = capmt->capmt_sock[sock_idx]; lock_assert(&capmt->capmt_mutex); if (fd < 0) @@ -603,9 +591,7 @@ capmt_socket_close(capmt_t *capmt, int sock_idx) #endif } -static void -capmt_socket_close_lock(capmt_t *capmt, int sock_idx) -{ +static void capmt_socket_close_lock(capmt_t* capmt, int sock_idx) { tvh_mutex_lock(&capmt->capmt_mutex); capmt_socket_close(capmt, sock_idx); tvh_mutex_unlock(&capmt->capmt_mutex); @@ -614,10 +600,8 @@ capmt_socket_close_lock(capmt_t *capmt, int sock_idx) /** * */ -static int -capmt_write_msg(capmt_t *capmt, int adapter, int sid, const uint8_t *buf, size_t len) -{ - int i = 0, found = 0, fd; +static int capmt_write_msg(capmt_t* capmt, int adapter, int sid, const uint8_t* buf, size_t len) { + int i = 0, found = 0, fd; ssize_t res; if (!capmt_oscam_so_wrapper(capmt)) { @@ -625,9 +609,18 @@ capmt_write_msg(capmt_t *capmt, int adapter, int sid, const uint8_t *buf, size_t if (capmt->capmt_oscam == CAPMT_OSCAM_OLD) { // dumping current SID table for (i = 0; i < MAX_SOCKETS; i++) - tvhdebug(LS_CAPMT, "%s: %s: SOCKETS TABLE DUMP [%d]: sid=%d socket=%d", capmt_name(capmt), __FUNCTION__, i, capmt->sids[i], capmt->capmt_sock[i]); + tvhdebug(LS_CAPMT, + "%s: %s: SOCKETS TABLE DUMP [%d]: sid=%d socket=%d", + capmt_name(capmt), + __FUNCTION__, + i, + capmt->sids[i], + capmt->capmt_sock[i]); if (sid == 0) { - tvhdebug(LS_CAPMT, "%s: %s: got empty SID - returning from function", capmt_name(capmt), __FUNCTION__); + tvhdebug(LS_CAPMT, + "%s: %s: got empty SID - returning from function", + capmt_name(capmt), + __FUNCTION__); return -1; } @@ -640,8 +633,12 @@ capmt_write_msg(capmt_t *capmt, int adapter, int sid, const uint8_t *buf, size_t } if (found) - tvhdebug(LS_CAPMT, "%s: %s: found sid, reusing socket, i=%d", capmt_name(capmt), __FUNCTION__, i); - else { //not found - adding to first free in table + tvhdebug(LS_CAPMT, + "%s: %s: found sid, reusing socket, i=%d", + capmt_name(capmt), + __FUNCTION__, + i); + else { // not found - adding to first free in table for (i = 0; i < MAX_SOCKETS; i++) { if (capmt->sids[i] == 0) { capmt->sids[i] = sid; @@ -671,13 +668,12 @@ capmt_write_msg(capmt_t *capmt, int adapter, int sid, const uint8_t *buf, size_t // opening socket and sending if (capmt->capmt_sock[i] < 0) { fd = capmt_connect(capmt, i); - caclient_set_status((caclient_t *)capmt, - fd >= 0 ? CACLIENT_STATUS_CONNECTED : - CACLIENT_STATUS_READY); + caclient_set_status((caclient_t*)capmt, + fd >= 0 ? CACLIENT_STATUS_CONNECTED : CACLIENT_STATUS_READY); if (fd >= 0) capmt_notify_server(capmt, NULL, 1); } - } else { // standard old capmt mode + } else { // standard old capmt mode i = 0; } @@ -694,7 +690,11 @@ capmt_write_msg(capmt_t *capmt, int adapter, int sid, const uint8_t *buf, size_t res = send(fd, buf, len, MSG_DONTWAIT); if (res < len) { #if ENABLE_ANDROID - tvhdebug(LS_CAPMT, "%s: Message send failed to socket %i (%li)", capmt_name(capmt), fd, (long int)res); // Android bug, ssize_t is long int + tvhdebug(LS_CAPMT, + "%s: Message send failed to socket %i (%li)", + capmt_name(capmt), + fd, + (long int)res); // Android bug, ssize_t is long int #else tvhdebug(LS_CAPMT, "%s: Message send failed to socket %i (%zi)", capmt_name(capmt), fd, res); #endif @@ -711,17 +711,13 @@ capmt_write_msg(capmt_t *capmt, int adapter, int sid, const uint8_t *buf, size_t * */ static void -capmt_queue_msg - (capmt_t *capmt, int adapter, int sid, - const uint8_t *buf, size_t len, int flags) -{ +capmt_queue_msg(capmt_t* capmt, int adapter, int sid, const uint8_t* buf, size_t len, int flags) { capmt_message_t *msg, *msg2; if (flags & CAPMT_MSG_CLEAR) { for (msg = TAILQ_FIRST(&capmt->capmt_writeq); msg; msg = msg2) { msg2 = TAILQ_NEXT(msg, cm_link); - if ((adapter == 0xff || msg->cm_adapter == adapter) && - (sid == 0 || msg->cm_sid == sid)) { + if ((adapter == 0xff || msg->cm_adapter == adapter) && (sid == 0 || msg->cm_sid == sid)) { TAILQ_REMOVE(&capmt->capmt_writeq, msg, cm_link); sbuf_free(&msg->cm_sb); free(msg); @@ -729,9 +725,8 @@ capmt_queue_msg } } if (flags & CAPMT_MSG_NODUP) { - TAILQ_FOREACH(msg, &capmt->capmt_writeq, cm_link) - if (msg->cm_sb.sb_ptr == len && - memcmp(msg->cm_sb.sb_data, buf, len) == 0) + TAILQ_FOREACH (msg, &capmt->capmt_writeq, cm_link) + if (msg->cm_sb.sb_ptr == len && memcmp(msg->cm_sb.sb_data, buf, len) == 0) return; } msg = malloc(sizeof(*msg)); @@ -755,10 +750,8 @@ capmt_queue_msg /** * */ -static void -capmt_flush_queue(capmt_t *capmt, int del_only) -{ - capmt_message_t *msg; +static void capmt_flush_queue(capmt_t* capmt, int del_only) { + capmt_message_t* msg; while (1) { tvh_mutex_lock(&capmt->capmt_mutex); @@ -770,8 +763,7 @@ capmt_flush_queue(capmt_t *capmt, int del_only) break; if (!del_only) - capmt_write_msg(capmt, msg->cm_adapter, msg->cm_sid, - msg->cm_sb.sb_data, msg->cm_sb.sb_ptr); + capmt_write_msg(capmt, msg->cm_adapter, msg->cm_sid, msg->cm_sb.sb_data, msg->cm_sb.sb_ptr); sbuf_free(&msg->cm_sb); free(msg); } @@ -780,17 +772,15 @@ capmt_flush_queue(capmt_t *capmt, int del_only) /** * */ -static void -capmt_send_stop(capmt_service_t *t) -{ - capmt_t *capmt = t->ct_capmt; +static void capmt_send_stop(capmt_service_t* t) { + capmt_t* capmt = t->ct_capmt; lock_assert(&capmt->capmt_mutex); #ifdef CAPMT_OSCAM_OLD if (capmt->capmt_oscam == CAPMT_OSCAM_OLD) { - mpegts_service_t *s = (mpegts_service_t *)t->td_service; - int i; + mpegts_service_t* s = (mpegts_service_t*)t->td_service; + int i; // searching for socket to close for (i = 0; i < MAX_SOCKETS; i++) if (capmt->sids[i] == service_id16(s)) @@ -802,33 +792,38 @@ capmt_send_stop(capmt_service_t *t) } // closing socket (oscam handle this as event and stop decrypting) - tvhdebug(LS_CAPMT, "%s: %s: closing socket i=%d, socket_fd=%d", capmt_name(capmt), __FUNCTION__, i, capmt->capmt_sock[i]); + tvhdebug(LS_CAPMT, + "%s: %s: closing socket i=%d, socket_fd=%d", + capmt_name(capmt), + __FUNCTION__, + i, + capmt->capmt_sock[i]); capmt->sids[i] = 0; capmt->adps[i] = 0; capmt_socket_close(capmt, i); } #endif #ifdef CAPMT_OSCAM_SO_WRAPPER - if (capmt->capmt_oscam == CAPMT_OSCAM_SO_WRAPPER) { // standard old capmt mode - mpegts_service_t *s = (mpegts_service_t *)t->td_service; - /* buffer for capmt */ - int pos = 0; + if (capmt->capmt_oscam == CAPMT_OSCAM_SO_WRAPPER) { // standard old capmt mode + mpegts_service_t* s = (mpegts_service_t*)t->td_service; + /* buffer for capmt */ + int pos = 0; uint8_t buf[4094]; - buf[pos++] = 0x9f; - buf[pos++] = 0x80; - buf[pos++] = 0x32; - buf[pos++] = 0x82; - buf[pos++] = 0; /* total length */ - buf[pos++] = 0; /* total length */ - buf[pos++] = CAPMT_LIST_ONLY; - buf[pos++] = service_id16(s) >> 8; - buf[pos++] = service_id16(s); - buf[pos++] = capmt->capmt_pmtversion; + buf[pos++] = 0x9f; + buf[pos++] = 0x80; + buf[pos++] = 0x32; + buf[pos++] = 0x82; + buf[pos++] = 0; /* total length */ + buf[pos++] = 0; /* total length */ + buf[pos++] = CAPMT_LIST_ONLY; + buf[pos++] = service_id16(s) >> 8; + buf[pos++] = service_id16(s); + buf[pos++] = capmt->capmt_pmtversion; capmt->capmt_pmtversion = (capmt->capmt_pmtversion + 1) & 0x1F; - buf[pos++] = 0; /* room for length - program info tags */ - buf[pos++] = 0; /* room for length - program info tags */ - buf[pos++] = 1; /* 1 = OK DESCRAMBLING or 4 = NOT SELECTED */ + buf[pos++] = 0; /* room for length - program info tags */ + buf[pos++] = 0; /* room for length - program info tags */ + buf[pos++] = 1; /* 1 = OK DESCRAMBLING or 4 = NOT SELECTED */ /* tags length */ buf[10] = ((pos - 12) & 0xF00) >> 8; @@ -842,11 +837,10 @@ capmt_send_stop(capmt_service_t *t) buf[pos++] = 0; /* SI tag length */ /* update total length */ - buf[4] = ((pos - 6) >> 8); - buf[5] = ((pos - 6) & 0xFF); - - capmt_queue_msg(capmt, t->ct_adapter, service_id16(s), - buf, pos, CAPMT_MSG_CLEAR); + buf[4] = ((pos - 6) >> 8); + buf[5] = ((pos - 6) & 0xFF); + + capmt_queue_msg(capmt, t->ct_adapter, service_id16(s), buf, pos, CAPMT_MSG_CLEAR); } #endif } @@ -854,18 +848,16 @@ capmt_send_stop(capmt_service_t *t) /** * */ -static void -capmt_send_stop_descrambling(capmt_t *capmt, uint8_t demuxer) -{ +static void capmt_send_stop_descrambling(capmt_t* capmt, uint8_t demuxer) { uint8_t buf[8] = { - 0x9F, - 0x80, - 0x3F, - 0x04, - 0x83, - 0x02, - 0x00, - demuxer /* 0xFF is wildcard demux id */ + 0x9F, + 0x80, + 0x3F, + 0x04, + 0x83, + 0x02, + 0x00, + demuxer /* 0xFF is wildcard demux id */ }; capmt_queue_msg(capmt, demuxer, 0, buf, ARRAY_SIZE(buf), CAPMT_MSG_CLEAR); } @@ -873,9 +865,7 @@ capmt_send_stop_descrambling(capmt_t *capmt, uint8_t demuxer) /** * */ -static void -capmt_init_demuxes(capmt_t *capmt) -{ +static void capmt_init_demuxes(capmt_t* capmt) { int i, j; memset(&capmt->capmt_demuxes, 0, sizeof(capmt->capmt_demuxes)); @@ -887,18 +877,18 @@ capmt_init_demuxes(capmt_t *capmt) /** * global_lock is held */ -static void -capmt_service_destroy(th_descrambler_t *td) -{ - capmt_service_t *ct = (capmt_service_t *)td, *ct2; - mpegts_service_t *s = (mpegts_service_t *)ct->td_service; - int oscam_new = capmt_oscam_new(ct->ct_capmt); - capmt_caid_ecm_t *cce; - capmt_t *capmt = ct->ct_capmt; +static void capmt_service_destroy(th_descrambler_t* td) { + capmt_service_t * ct = (capmt_service_t*)td, *ct2; + mpegts_service_t* s = (mpegts_service_t*)ct->td_service; + int oscam_new = capmt_oscam_new(ct->ct_capmt); + capmt_caid_ecm_t* cce; + capmt_t* capmt = ct->ct_capmt; tvhdebug(LS_CAPMT, - "%s: Removing CAPMT Server from service \"%s\" on adapter %d", - capmt_name(capmt), s->s_dvb_svcname, ct->ct_adapter); + "%s: Removing CAPMT Server from service \"%s\" on adapter %d", + capmt_name(capmt), + s->s_dvb_svcname, + ct->ct_adapter); mtimer_disarm(&ct->ct_ok_timer); @@ -908,7 +898,7 @@ capmt_service_destroy(th_descrambler_t *td) if (!oscam_new) capmt_send_stop(ct); - while (!LIST_EMPTY(&ct->ct_caid_ecm)) { + while (!LIST_EMPTY(&ct->ct_caid_ecm)) { /* List Deletion. */ cce = LIST_FIRST(&ct->ct_caid_ecm); LIST_REMOVE(cce, cce_link); @@ -922,7 +912,7 @@ capmt_service_destroy(th_descrambler_t *td) if (oscam_new) capmt_enumerate_services(capmt, 1); - LIST_FOREACH(ct2, &capmt->capmt_services, ct_link) + LIST_FOREACH (ct2, &capmt->capmt_services, ct_link) if (ct2->ct_adapter == ct->ct_adapter) break; if (ct2 == NULL) { @@ -939,58 +929,62 @@ capmt_service_destroy(th_descrambler_t *td) free(ct); } -static void -capmt_send_client_info(capmt_t *capmt) -{ +static void capmt_send_client_info(capmt_t* capmt) { char buf[MAX_INFO_LEN + 7]; - int len; + int len; - *(uint32_t *)(buf + 0) = htonl(DVBAPI_CLIENT_INFO); - *(uint16_t *)(buf + 4) = htons(DVBAPI_PROTOCOL_VERSION); //supported protocol version - len = snprintf(buf + 7, sizeof(buf) - 7, "Tvheadend %s", tvheadend_version); + *(uint32_t*)(buf + 0) = htonl(DVBAPI_CLIENT_INFO); + *(uint16_t*)(buf + 4) = htons(DVBAPI_PROTOCOL_VERSION); // supported protocol version + len = snprintf(buf + 7, sizeof(buf) - 7, "Tvheadend %s", tvheadend_version); if (len >= sizeof(buf) - 7) len = sizeof(buf) - 7 - 1; buf[6] = len; - capmt_queue_msg(capmt, 0, 0, (uint8_t *)&buf, len + 7, - CAPMT_MSG_FAST|CAPMT_MSG_NODUP|CAPMT_MSG_HELLO); + capmt_queue_msg(capmt, + 0, + 0, + (uint8_t*)&buf, + len + 7, + CAPMT_MSG_FAST | CAPMT_MSG_NODUP | CAPMT_MSG_HELLO); } -static void -capmt_filter_data(capmt_t *capmt, uint8_t adapter, uint8_t demux_index, - uint8_t filter_index, const uint8_t *data, int len, - int flags) -{ - uint8_t *buf = alloca(len + 6); - - *(uint32_t *)(buf + 0) = htonl(DVBAPI_FILTER_DATA); - buf[4] = demux_index; - buf[5] = filter_index; +static void capmt_filter_data(capmt_t* capmt, + uint8_t adapter, + uint8_t demux_index, + uint8_t filter_index, + const uint8_t* data, + int len, + int flags) { + uint8_t* buf = alloca(len + 6); + + *(uint32_t*)(buf + 0) = htonl(DVBAPI_FILTER_DATA); + buf[4] = demux_index; + buf[5] = filter_index; memcpy(buf + 6, data, len); if (len - 3 == ((((uint16_t)buf[7] << 8) | buf[8]) & 0xfff)) capmt_queue_msg(capmt, adapter, 0x10000, buf, len + 6, flags); } -static void -capmt_set_filter(capmt_t *capmt, int adapter, sbuf_t *sb, int offset) -{ - uint8_t demux_index = sbuf_peek_u8 (sb, offset + 0); - uint8_t filter_index = sbuf_peek_u8 (sb, offset + 1); - uint16_t pid = sbuf_peek_u16(sb, offset + 2); - capmt_dmx_t *filter; - capmt_filters_t *cf; - capmt_service_t *ct; - mpegts_service_t *t; - capmt_caid_ecm_t *cce; - int i, flags = 0, add = 0; - uint16_t caid; - - tvhtrace(LS_CAPMT, "%s: setting filter: adapter=%d, demux=%d, filter=%d, pid=%d", - capmt_name(capmt), adapter, demux_index, filter_index, pid); - if (adapter >= MAX_CA || - demux_index >= MAX_INDEX || - filter_index >= MAX_FILTER || - pid > 8191) +static void capmt_set_filter(capmt_t* capmt, int adapter, sbuf_t* sb, int offset) { + uint8_t demux_index = sbuf_peek_u8(sb, offset + 0); + uint8_t filter_index = sbuf_peek_u8(sb, offset + 1); + uint16_t pid = sbuf_peek_u16(sb, offset + 2); + capmt_dmx_t* filter; + capmt_filters_t* cf; + capmt_service_t* ct; + mpegts_service_t* t; + capmt_caid_ecm_t* cce; + int i, flags = 0, add = 0; + uint16_t caid; + + tvhtrace(LS_CAPMT, + "%s: setting filter: adapter=%d, demux=%d, filter=%d, pid=%d", + capmt_name(capmt), + adapter, + demux_index, + filter_index, + pid); + if (adapter >= MAX_CA || demux_index >= MAX_INDEX || filter_index >= MAX_FILTER || pid > 8191) return; tvh_mutex_lock(&capmt->capmt_mutex); cf = &capmt->capmt_demuxes.filters[demux_index]; @@ -998,48 +992,55 @@ capmt_set_filter(capmt_t *capmt, int adapter, sbuf_t *sb, int offset) goto end; /* ECM messages have the higher priority */ - t = NULL; + t = NULL; caid = 0; - LIST_FOREACH(ct, &capmt->capmt_services, ct_link) { - LIST_FOREACH(cce, &ct->ct_caid_ecm, cce_link) + LIST_FOREACH (ct, &capmt->capmt_services, ct_link) { + LIST_FOREACH (cce, &ct->ct_caid_ecm, cce_link) if (cce->cce_ecmpid == pid) { flags = CAPMT_MSG_FAST; - t = cce->cce_service; - caid = cce->cce_caid; + t = cce->cce_service; + caid = cce->cce_caid; goto service_found; } } service_found: if (t) { - dmx_filter_t *pf = (dmx_filter_t *)sbuf_peek(sb, offset + 4); - uint8_t f0, m0; + dmx_filter_t* pf = (dmx_filter_t*)sbuf_peek(sb, offset + 4); + uint8_t f0, m0; /* OK, probably ECM, but sometimes, it's shared */ /* Inspect the filter */ for (i = 1; i < DMX_FILTER_SIZE; i++) { - if (pf->mode[i]) break; - if (pf->filter[i]) break; - if (pf->mask[i]) break; + if (pf->mode[i]) + break; + if (pf->filter[i]) + break; + if (pf->mask[i]) + break; } - if (i >= DMX_FILTER_SIZE) goto cont; - if (pf->mode[0]) goto cont; + if (i >= DMX_FILTER_SIZE) + goto cont; + if (pf->mode[0]) + goto cont; f0 = pf->filter[0]; m0 = pf->filter[1]; - if ((f0 & 0xf0) == 0x80 && (m0 & 0xf0) == 0xf0) goto cont; - if (caid_is_dvn(caid) && f0 == 0x50 && m0 == 0xff) goto cont; /* DVN */ + if ((f0 & 0xf0) == 0x80 && (m0 & 0xf0) == 0xf0) + goto cont; + if (caid_is_dvn(caid) && f0 == 0x50 && m0 == 0xff) + goto cont; /* DVN */ } cont: if (t) ct->ct_ok_flag = 1; cf->adapter = adapter; - filter = &cf->dmx[filter_index]; + filter = &cf->dmx[filter_index]; if (filter->pid == PID_UNUSED) { add = 1; } else if (pid != filter->pid || flags != filter->flags) { capmt_pid_remove(capmt, adapter, filter->pid, filter->flags); add = 1; } - filter->pid = pid; + filter->pid = pid; filter->flags = flags; memcpy(&filter->filter, sbuf_peek(sb, offset + 4), sizeof(filter->filter)); tvhlog_hexdump(LS_CAPMT, filter->filter.filter, DMX_FILTER_SIZE); @@ -1058,29 +1059,30 @@ end: tvh_mutex_unlock(&capmt->capmt_mutex); } -static void -capmt_stop_filter(capmt_t *capmt, int adapter, sbuf_t *sb, int offset) -{ - uint8_t demux_index = sbuf_peek_u8 (sb, offset + 0); - uint8_t filter_index = sbuf_peek_u8 (sb, offset + 1); - int16_t pid; - uint32_t flags; - capmt_dmx_t *filter; - capmt_filters_t *cf; +static void capmt_stop_filter(capmt_t* capmt, int adapter, sbuf_t* sb, int offset) { + uint8_t demux_index = sbuf_peek_u8(sb, offset + 0); + uint8_t filter_index = sbuf_peek_u8(sb, offset + 1); + int16_t pid; + uint32_t flags; + capmt_dmx_t* filter; + capmt_filters_t* cf; if (capmt_oscam_netproto(capmt)) - pid = sbuf_peek_s16 (sb, offset + 2); + pid = sbuf_peek_s16(sb, offset + 2); else - pid = sbuf_peek_s16be(sb, offset + 2); - - tvhtrace(LS_CAPMT, "%s: stopping filter: adapter=%d, demux=%d, filter=%d, pid=%d", - capmt_name(capmt), adapter, demux_index, filter_index, pid); - if (adapter >= MAX_CA || - demux_index >= MAX_INDEX || - filter_index >= MAX_FILTER) + pid = sbuf_peek_s16be(sb, offset + 2); + + tvhtrace(LS_CAPMT, + "%s: stopping filter: adapter=%d, demux=%d, filter=%d, pid=%d", + capmt_name(capmt), + adapter, + demux_index, + filter_index, + pid); + if (adapter >= MAX_CA || demux_index >= MAX_INDEX || filter_index >= MAX_FILTER) return; tvh_mutex_lock(&capmt->capmt_mutex); - cf = &capmt->capmt_demuxes.filters[demux_index]; + cf = &capmt->capmt_demuxes.filters[demux_index]; filter = &cf->dmx[filter_index]; if (filter->pid != pid) goto end; @@ -1092,7 +1094,7 @@ capmt_stop_filter(capmt_t *capmt, int adapter, sbuf_t *sb, int offset) filter_index = cf->max - 1; while (filter_index != 255 && cf->dmx[filter_index].pid == PID_UNUSED) filter_index--; - cf->max = filter_index == 255 ? 0 : filter_index + 1; + cf->max = filter_index == 255 ? 0 : filter_index + 1; demux_index = capmt->capmt_demuxes.max - 1; while (demux_index != 255 && capmt->capmt_demuxes.filters[demux_index].max == 0) demux_index--; @@ -1101,9 +1103,7 @@ end: tvh_mutex_unlock(&capmt->capmt_mutex); } -static void -capmt_notify_server(capmt_t *capmt, capmt_service_t *ct, int force) -{ +static void capmt_notify_server(capmt_t* capmt, capmt_service_t* ct, int force) { /* flush out the greeting */ if (capmt_oscam_netproto(capmt)) capmt_flush_queue(capmt, 0); @@ -1116,7 +1116,7 @@ capmt_notify_server(capmt_t *capmt, capmt_service_t *ct, int force) if (ct) capmt_send_request(ct, CAPMT_LIST_ONLY); else - LIST_FOREACH(ct, &capmt->capmt_services, ct_link) + LIST_FOREACH (ct, &capmt->capmt_services, ct_link) capmt_send_request(ct, CAPMT_LIST_ONLY); } tvh_mutex_unlock(&capmt->capmt_mutex); @@ -1124,24 +1124,21 @@ capmt_notify_server(capmt_t *capmt, capmt_service_t *ct, int force) #if CONFIG_LINUXDVB #ifdef CAPMT_OSCAM_SO_WRAPPER -static void -capmt_abort(capmt_t *capmt, int keystate) -{ - mpegts_service_t *t; - capmt_service_t *ct; +static void capmt_abort(capmt_t* capmt, int keystate) { + mpegts_service_t* t; + capmt_service_t* ct; tvh_mutex_lock(&capmt->capmt_mutex); - LIST_FOREACH(ct, &capmt->capmt_services, ct_link) { - t = (mpegts_service_t *)ct->td_service; + LIST_FOREACH (ct, &capmt->capmt_services, ct_link) { + t = (mpegts_service_t*)ct->td_service; if (ct->td_keystate != keystate) { tvherror(LS_CAPMT, - "%s: Can not descramble service \"%s\", %s", - capmt_name(capmt), - t->s_dvb_svcname, - keystate == DS_FORBIDDEN ? - "access denied" : "connection close"); - descrambler_change_keystate((th_descrambler_t *)ct, keystate, 1); + "%s: Can not descramble service \"%s\", %s", + capmt_name(capmt), + t->s_dvb_svcname, + keystate == DS_FORBIDDEN ? "access denied" : "connection close"); + descrambler_change_keystate((th_descrambler_t*)ct, keystate, 1); } } tvh_mutex_unlock(&capmt->capmt_mutex); @@ -1149,33 +1146,34 @@ capmt_abort(capmt_t *capmt, int keystate) #endif #endif -static int -capmt_ecm_reset(th_descrambler_t *th) -{ +static int capmt_ecm_reset(th_descrambler_t* th) { descrambler_change_keystate(th, DS_READY, 1); return 0; } -static void -capmt_process_key(capmt_t *capmt, uint8_t adapter, ca_info_t *cai, - int type, const uint8_t *even, const uint8_t *odd, - int ok) -{ - mpegts_service_t *t; - capmt_service_t *ct; - uint16_t *pids; - int i, j, pid; +static void capmt_process_key(capmt_t* capmt, + uint8_t adapter, + ca_info_t* cai, + int type, + const uint8_t* even, + const uint8_t* odd, + int ok) { + mpegts_service_t* t; + capmt_service_t* ct; + uint16_t* pids; + int i, j, pid; tvh_mutex_lock(&capmt->capmt_mutex); - LIST_FOREACH(ct, &capmt->capmt_services, ct_link) { - t = (mpegts_service_t *)ct->td_service; + LIST_FOREACH (ct, &capmt->capmt_services, ct_link) { + t = (mpegts_service_t*)ct->td_service; if (!ok) { if (ct->td_keystate != DS_FORBIDDEN) { tvherror(LS_CAPMT, - "%s: Can not descramble service \"%s\", access denied", - capmt_name(capmt), t->s_dvb_svcname); - descrambler_change_keystate((th_descrambler_t *)ct, DS_FORBIDDEN, 1); + "%s: Can not descramble service \"%s\", access denied", + capmt_name(capmt), + t->s_dvb_svcname); + descrambler_change_keystate((th_descrambler_t*)ct, DS_FORBIDDEN, 1); } continue; } @@ -1186,14 +1184,16 @@ capmt_process_key(capmt_t *capmt, uint8_t adapter, ca_info_t *cai, pids = cai->pids; for (i = 0; i < MAX_PIDS; i++) { - if (pids[i] == 0) continue; + if (pids[i] == 0) + continue; for (j = 0; j < MAX_PIDS; j++) { pid = ct->ct_pids[j]; - if (pid == 0) break; + if (pid == 0) + break; if (pid == pids[i]) { if (ct->ct_multipid) { ct->ct_ok_flag = 1; - descrambler_keys((th_descrambler_t *)ct, type, pid, even, odd); + descrambler_keys((th_descrambler_t*)ct, type, pid, even, odd); continue; } else if (ct->ct_type_sok[j]) goto found; @@ -1202,45 +1202,43 @@ capmt_process_key(capmt_t *capmt, uint8_t adapter, ca_info_t *cai, } continue; -found: + found: ct->ct_ok_flag = 1; - descrambler_keys((th_descrambler_t *)ct, type, pid, even, odd); + descrambler_keys((th_descrambler_t*)ct, type, pid, even, odd); } tvh_mutex_unlock(&capmt->capmt_mutex); } -static void -capmt_send_key(capmt_t *capmt) -{ - const int adapter = capmt->capmt_last_key.adapter; - const int index = capmt->capmt_last_key.index; - const int parity = capmt->capmt_last_key.parity; - const uint8_t *cw = capmt->capmt_last_key.cw; - ca_info_t *cai; - int type; +static void capmt_send_key(capmt_t* capmt) { + const int adapter = capmt->capmt_last_key.adapter; + const int index = capmt->capmt_last_key.index; + const int parity = capmt->capmt_last_key.parity; + const uint8_t* cw = capmt->capmt_last_key.cw; + ca_info_t* cai; + int type; capmt->capmt_last_key.adapter = -1; if (adapter < 0) return; cai = &capmt->capmt_adapters[adapter].ca_info[index]; switch (cai->algo) { - case CA_ALGO_DVBCSA: - type = DESCRAMBLER_CSA_CBC; - break; - case CA_ALGO_DES: - type = DESCRAMBLER_DES_NCB; - break; - case CA_ALGO_AES: - if (cai->cipher_mode == CA_MODE_ECB) { - type = DESCRAMBLER_AES_ECB; - } else { - tvherror(LS_CAPMT, "uknown cipher mode %d", cai->cipher_mode); + case CA_ALGO_DVBCSA: + type = DESCRAMBLER_CSA_CBC; + break; + case CA_ALGO_DES: + type = DESCRAMBLER_DES_NCB; + break; + case CA_ALGO_AES: + if (cai->cipher_mode == CA_MODE_ECB) { + type = DESCRAMBLER_AES_ECB; + } else { + tvherror(LS_CAPMT, "uknown cipher mode %d", cai->cipher_mode); + return; + } + break; + default: + tvherror(LS_CAPMT, "unknown crypto algorithm %d (mode %d)", cai->algo, cai->cipher_mode); return; - } - break; - default: - tvherror(LS_CAPMT, "unknown crypto algorithm %d (mode %d)", cai->algo, cai->cipher_mode); - return; } if (parity == 0) { @@ -1250,38 +1248,48 @@ capmt_send_key(capmt_t *capmt) } } -static void -capmt_process_notify(capmt_t *capmt, uint8_t adapter, - uint16_t sid, uint16_t caid, uint32_t provid, - const char *cardsystem, uint16_t pid, uint32_t ecmtime, - uint16_t hops, const char *reader, const char *from, - const char *protocol ) -{ - mpegts_service_t *t; - capmt_service_t *ct; +static void capmt_process_notify(capmt_t* capmt, + uint8_t adapter, + uint16_t sid, + uint16_t caid, + uint32_t provid, + const char* cardsystem, + uint16_t pid, + uint32_t ecmtime, + uint16_t hops, + const char* reader, + const char* from, + const char* protocol) { + mpegts_service_t* t; + capmt_service_t* ct; tvh_mutex_lock(&capmt->capmt_mutex); - LIST_FOREACH(ct, &capmt->capmt_services, ct_link) { - t = (mpegts_service_t *)ct->td_service; + LIST_FOREACH (ct, &capmt->capmt_services, ct_link) { + t = (mpegts_service_t*)ct->td_service; if (sid != service_id16(t)) continue; if (adapter != ct->ct_adapter) continue; - descrambler_notify((th_descrambler_t *)ct, caid, provid, - cardsystem, pid, ecmtime, hops, reader, from, - protocol); + descrambler_notify((th_descrambler_t*)ct, + caid, + provid, + cardsystem, + pid, + ecmtime, + hops, + reader, + from, + protocol); } tvh_mutex_unlock(&capmt->capmt_mutex); -} +} -static int -capmt_msg_size(capmt_t *capmt, sbuf_t *sb, int offset) -{ +static int capmt_msg_size(capmt_t* capmt, sbuf_t* sb, int offset) { uint32_t cmd; - uint8_t adapter_byte = 0; - int oscam_new = capmt_oscam_new(capmt); + uint8_t adapter_byte = 0; + int oscam_new = capmt_oscam_new(capmt); if (sb->sb_ptr - offset < 4) return 0; @@ -1291,13 +1299,10 @@ capmt_msg_size(capmt_t *capmt, sbuf_t *sb, int offset) adapter_byte = 1; } else { if (!sb->sb_bswap && !sb->sb_err) { - if (cmd == CA_SET_PID_X || - cmd == CA_SET_DESCR_X || - cmd == CA_SET_DESCR_AES_X || - cmd == DMX_SET_FILTER_X || - cmd == DMX_STOP_X) { + if (cmd == CA_SET_PID_X || cmd == CA_SET_DESCR_X || cmd == CA_SET_DESCR_AES_X || + cmd == DMX_SET_FILTER_X || cmd == DMX_STOP_X) { sb->sb_bswap = 1; - cmd = sbuf_peek_u32(sb, offset); + cmd = sbuf_peek_u32(sb, offset); } } } @@ -1323,52 +1328,54 @@ capmt_msg_size(capmt_t *capmt, sbuf_t *sb, int offset) return 0; int len = 4 + adapter_byte + 2 + 2 + 2 + 4 + 4; int i; - for (i=0; i<4; i++) { + for (i = 0; i < 4; i++) { if (len >= sb->sb_ptr) return 0; len += sbuf_peek_u8(sb, len) + 1; } len += 1; return len; - } - else { + } else { sb->sb_err = 0; return -1; /* fatal */ } } -static char * -capmt_peek_str(sbuf_t *sb, int *offset) -{ +static char* capmt_peek_str(sbuf_t* sb, int* offset) { uint8_t len = sbuf_peek_u8(sb, *offset); - char *str = malloc(len + 1), *p; + char * str = malloc(len + 1), *p; memcpy(str, sbuf_peek(sb, *offset + 1), len); str[len] = '\0'; for (p = str; *p; p++) - if (*p < ' ') *p = ' '; + if (*p < ' ') + *p = ' '; *offset += len + 1; return str; } -static void -capmt_analyze_cmd(capmt_t *capmt, uint32_t cmd, int adapter, sbuf_t *sb, int offset) -{ +static void capmt_analyze_cmd(capmt_t* capmt, uint32_t cmd, int adapter, sbuf_t* sb, int offset) { if (cmd == CA_SET_PID_) { - uint32_t pid = sbuf_peek_u32(sb, offset + 0); - int32_t index = sbuf_peek_s32(sb, offset + 4); - int i, j; - ca_info_t *cai; - - tvhdebug(LS_CAPMT, "%s: CA_SET_PID adapter %d index %d pid %d (0x%04x)", capmt_name(capmt), adapter, index, pid, pid); + uint32_t pid = sbuf_peek_u32(sb, offset + 0); + int32_t index = sbuf_peek_s32(sb, offset + 4); + int i, j; + ca_info_t* cai; + + tvhdebug(LS_CAPMT, + "%s: CA_SET_PID adapter %d index %d pid %d (0x%04x)", + capmt_name(capmt), + adapter, + index, + pid, + pid); if (index > 0x100 && index < 0x200 && (index & 0xff) < MAX_INDEX) { index &= 0xff; if (capmt->capmt_cwmode != CAPMT_CWMODE_OE20) { tvhwarn(LS_CAPMT, "Autoswitch to Extended DES (OE 2.0) CW Mode"); capmt->capmt_cwmode = CAPMT_CWMODE_OE20; } - cai = &capmt->capmt_adapters[adapter].ca_info[index]; - cai->algo = CA_ALGO_DES; + cai = &capmt->capmt_adapters[adapter].ca_info[index]; + cai->algo = CA_ALGO_DES; cai->cipher_mode = 0; } if (adapter < MAX_CA && index >= 0 && index < MAX_INDEX) { @@ -1389,47 +1396,85 @@ capmt_analyze_cmd(capmt_t *capmt, uint32_t cmd, int adapter, sbuf_t *sb, int off cai->pids[i] = 0; } } else { - tvherror(LS_CAPMT, "%s: Invalid index %d in CA_SET_PID (%d) for adapter %d", capmt_name(capmt), index, MAX_INDEX, adapter); + tvherror(LS_CAPMT, + "%s: Invalid index %d in CA_SET_PID (%d) for adapter %d", + capmt_name(capmt), + index, + MAX_INDEX, + adapter); } } else if (cmd == CA_SET_DESCR_) { - int32_t index = sbuf_peek_s32(sb, offset + 0); - int32_t parity = sbuf_peek_s32(sb, offset + 4); - uint8_t *cw = sbuf_peek (sb, offset + 8); - - tvhdebug(LS_CAPMT, "%s: CA_SET_DESCR adapter %d par %d idx %d %02x%02x%02x%02x%02x%02x%02x%02x", - capmt_name(capmt), adapter, parity, index, - cw[0], cw[1], cw[2], cw[3], cw[4], cw[5], cw[6], cw[7]); - if (index < 0) // skipping removal request + int32_t index = sbuf_peek_s32(sb, offset + 0); + int32_t parity = sbuf_peek_s32(sb, offset + 4); + uint8_t* cw = sbuf_peek(sb, offset + 8); + + tvhdebug(LS_CAPMT, + "%s: CA_SET_DESCR adapter %d par %d idx %d %02x%02x%02x%02x%02x%02x%02x%02x", + capmt_name(capmt), + adapter, + parity, + index, + cw[0], + cw[1], + cw[2], + cw[3], + cw[4], + cw[5], + cw[6], + cw[7]); + if (index < 0) // skipping removal request return; if (adapter >= MAX_CA || index >= MAX_INDEX) { tvherror(LS_CAPMT, "%s: Invalid adapter %d or index %d", capmt_name(capmt), adapter, index); return; } if (parity > 1) { - tvherror(LS_CAPMT, "%s: Invalid parity %d in CA_SET_DESCR for adapter%d", capmt_name(capmt), parity, adapter); + tvherror(LS_CAPMT, + "%s: Invalid parity %d in CA_SET_DESCR for adapter%d", + capmt_name(capmt), + parity, + adapter); return; } capmt->capmt_last_key.adapter = adapter; - capmt->capmt_last_key.index = index; - capmt->capmt_last_key.parity = parity; + capmt->capmt_last_key.index = index; + capmt->capmt_last_key.parity = parity; memcpy(capmt->capmt_last_key.cw, cw, 8); if (capmt->capmt_cwmode != CAPMT_CWMODE_OE22SW) /* wait for CA_SET_DESCR_MODE */ capmt_send_key(capmt); } else if (cmd == CA_SET_DESCR_AES) { - int32_t index = sbuf_peek_s32(sb, offset + 0); - int32_t parity = sbuf_peek_s32(sb, offset + 4); - uint8_t *cw = sbuf_peek (sb, offset + 8); - ca_info_t *cai; - - tvhdebug(LS_CAPMT, "%s: CA_SET_DESCR_AES adapter %d par %d idx %d " - "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", - capmt_name(capmt), adapter, parity, index, - cw[0], cw[1], cw[2], cw[3], cw[4], cw[5], cw[6], cw[7], - cw[8], cw[9], cw[10], cw[11], cw[12], cw[13], cw[14], cw[15]); - if (index < 0) // skipping removal request + int32_t index = sbuf_peek_s32(sb, offset + 0); + int32_t parity = sbuf_peek_s32(sb, offset + 4); + uint8_t* cw = sbuf_peek(sb, offset + 8); + ca_info_t* cai; + + tvhdebug(LS_CAPMT, + "%s: CA_SET_DESCR_AES adapter %d par %d idx %d " + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + capmt_name(capmt), + adapter, + parity, + index, + cw[0], + cw[1], + cw[2], + cw[3], + cw[4], + cw[5], + cw[6], + cw[7], + cw[8], + cw[9], + cw[10], + cw[11], + cw[12], + cw[13], + cw[14], + cw[15]); + if (index < 0) // skipping removal request return; if (adapter >= MAX_CA || index >= MAX_INDEX) return; @@ -1439,17 +1484,26 @@ capmt_analyze_cmd(capmt_t *capmt, uint32_t cmd, int adapter, sbuf_t *sb, int off } else if (parity == 1) { capmt_process_key(capmt, adapter, cai, DESCRAMBLER_AES128_ECB, NULL, cw, 1); } else - tvherror(LS_CAPMT, "%s: Invalid parity %d in CA_SET_DESCR_AES for adapter%d", capmt_name(capmt), parity, adapter); + tvherror(LS_CAPMT, + "%s: Invalid parity %d in CA_SET_DESCR_AES for adapter%d", + capmt_name(capmt), + parity, + adapter); } else if (cmd == CA_SET_DESCR_MODE) { - int32_t index = sbuf_peek_s32(sb, offset + 0); - int32_t algo = sbuf_peek_s32(sb, offset + 4); - int32_t cipher_mode = sbuf_peek_s32(sb, offset + 8); - ca_info_t *cai; - - tvhdebug(LS_CAPMT, "%s: CA_SET_DESCR_MODE adapter %d index %d algo %d cipher mode %d", - capmt_name(capmt), adapter, index, algo, cipher_mode); + int32_t index = sbuf_peek_s32(sb, offset + 0); + int32_t algo = sbuf_peek_s32(sb, offset + 4); + int32_t cipher_mode = sbuf_peek_s32(sb, offset + 8); + ca_info_t* cai; + + tvhdebug(LS_CAPMT, + "%s: CA_SET_DESCR_MODE adapter %d index %d algo %d cipher mode %d", + capmt_name(capmt), + adapter, + index, + algo, + cipher_mode); if (adapter >= MAX_CA || index < 0 || index >= MAX_INDEX) { tvherror(LS_CAPMT, "%s: Invalid adapter %d or index %d", capmt_name(capmt), adapter, index); return; @@ -1481,24 +1535,46 @@ capmt_analyze_cmd(capmt_t *capmt, uint32_t cmd, int adapter, sbuf_t *sb, int off } else if (cmd == DVBAPI_ECM_INFO) { - uint16_t sid = sbuf_peek_u16(sb, offset + 0); - uint16_t caid = sbuf_peek_u16(sb, offset + 2); - uint16_t pid = sbuf_peek_u16(sb, offset + 4); - uint32_t provid = sbuf_peek_u32(sb, offset + 6); - uint32_t ecmtime = sbuf_peek_u32(sb, offset + 10); - int offset2 = offset + 14; - char *cardsystem = capmt_peek_str(sb, &offset2); - char *reader = capmt_peek_str(sb, &offset2); - char *from = capmt_peek_str(sb, &offset2); - char *protocol = capmt_peek_str(sb, &offset2); - uint8_t hops = sbuf_peek_u8(sb, offset2); - - capmt_process_notify(capmt, adapter, sid, caid, provid, - cardsystem, pid, ecmtime, hops, reader, - from, protocol); - - tvhdebug(LS_CAPMT, "%s: ECM_INFO: adapter=%d sid=%d caid=%04X(%s) pid=%04X provid=%06X ecmtime=%d hops=%d reader=%s from=%s protocol=%s", - capmt_name(capmt), adapter, sid, caid, cardsystem, pid, provid, ecmtime, hops, reader, from, protocol); + uint16_t sid = sbuf_peek_u16(sb, offset + 0); + uint16_t caid = sbuf_peek_u16(sb, offset + 2); + uint16_t pid = sbuf_peek_u16(sb, offset + 4); + uint32_t provid = sbuf_peek_u32(sb, offset + 6); + uint32_t ecmtime = sbuf_peek_u32(sb, offset + 10); + int offset2 = offset + 14; + char* cardsystem = capmt_peek_str(sb, &offset2); + char* reader = capmt_peek_str(sb, &offset2); + char* from = capmt_peek_str(sb, &offset2); + char* protocol = capmt_peek_str(sb, &offset2); + uint8_t hops = sbuf_peek_u8(sb, offset2); + + capmt_process_notify(capmt, + adapter, + sid, + caid, + provid, + cardsystem, + pid, + ecmtime, + hops, + reader, + from, + protocol); + + tvhdebug(LS_CAPMT, + "%s: ECM_INFO: adapter=%d sid=%d caid=%04X(%s) pid=%04X provid=%06X ecmtime=%d hops=%d " + "reader=%s from=%s protocol=%s", + capmt_name(capmt), + adapter, + sid, + caid, + cardsystem, + pid, + provid, + ecmtime, + hops, + reader, + from, + protocol); free(protocol); free(from); @@ -1508,11 +1584,15 @@ capmt_analyze_cmd(capmt_t *capmt, uint32_t cmd, int adapter, sbuf_t *sb, int off } else if (cmd == DVBAPI_SERVER_INFO) { uint16_t protover = sbuf_peek_u16(sb, offset); - int offset2 = offset + 2; - char *info = capmt_peek_str(sb, &offset2); - char *rev = strstr(info, "build r"); + int offset2 = offset + 2; + char* info = capmt_peek_str(sb, &offset2); + char* rev = strstr(info, "build r"); - tvhinfo(LS_CAPMT, "%s: Connected to server '%s' (protocol version %d)", capmt_name(capmt), info, protover); + tvhinfo(LS_CAPMT, + "%s: Connected to server '%s' (protocol version %d)", + capmt_name(capmt), + info, + protover); if (rev) capmt->capmt_oscam_rev = strtol(rev + 7, NULL, 10); @@ -1523,43 +1603,41 @@ capmt_analyze_cmd(capmt_t *capmt, uint32_t cmd, int adapter, sbuf_t *sb, int off } } -static void -show_connection(capmt_t *capmt, const char *what) -{ +static void show_connection(capmt_t* capmt, const char* what) { if (capmt_oscam_network(capmt)) { tvhinfo(LS_CAPMT, - "%s: mode %i connected to %s:%i (%s)", - capmt_name(capmt), - capmt->capmt_oscam, - capmt->capmt_sockfile, capmt->capmt_port, - what); + "%s: mode %i connected to %s:%i (%s)", + capmt_name(capmt), + capmt->capmt_oscam, + capmt->capmt_sockfile, + capmt->capmt_port, + what); } else if (capmt_oscam_socket(capmt)) { tvhinfo(LS_CAPMT, - "%s: mode %i sockfile %s got connection from client (%s)", - capmt_name(capmt), - capmt->capmt_oscam, - capmt->capmt_sockfile, - what); + "%s: mode %i sockfile %s got connection from client (%s)", + capmt_name(capmt), + capmt->capmt_oscam, + capmt->capmt_sockfile, + what); } else { tvhinfo(LS_CAPMT, - "%s: mode %i sockfile %s port %i got connection from client (%s)", - capmt_name(capmt), - capmt->capmt_oscam, - capmt->capmt_sockfile, capmt->capmt_port, - what); + "%s: mode %i sockfile %s port %i got connection from client (%s)", + capmt_name(capmt), + capmt->capmt_oscam, + capmt->capmt_sockfile, + capmt->capmt_port, + what); } } #if CONFIG_LINUXDVB -static void -handle_ca0(capmt_t *capmt) -{ - int i, ret, recvsock, nfds, cmd_size; - uint32_t cmd; - uint8_t buf[256]; - sbuf_t *pbuf; - capmt_adapter_t *adapter; - tvhpoll_event_t ev[MAX_CA + 1]; +static void handle_ca0(capmt_t* capmt) { + int i, ret, recvsock, nfds, cmd_size; + uint32_t cmd; + uint8_t buf[256]; + sbuf_t* pbuf; + capmt_adapter_t* adapter; + tvhpoll_event_t ev[MAX_CA + 1]; show_connection(capmt, "ca0"); @@ -1616,7 +1694,7 @@ handle_ca0(capmt_t *capmt) adapter->ca_sock = -1; continue; } - + if (ret < 0) continue; @@ -1641,7 +1719,6 @@ handle_ca0(capmt_t *capmt) break; } } - } } @@ -1654,15 +1731,13 @@ handle_ca0(capmt_t *capmt) } #endif -static void -handle_single(capmt_t *capmt) -{ - int ret, recvsock, adapter = -1, nfds, cmd_size = 0, reconnect, offset = 0; - uint32_t cmd = 0; - uint8_t buf[256]; - sbuf_t buffer; +static void handle_single(capmt_t* capmt) { + int ret, recvsock, adapter = -1, nfds, cmd_size = 0, reconnect, offset = 0; + uint32_t cmd = 0; + uint8_t buf[256]; + sbuf_t buffer; tvhpoll_event_t ev; - int netproto = capmt_oscam_netproto(capmt); + int netproto = capmt_oscam_netproto(capmt); show_connection(capmt, "single"); @@ -1688,12 +1763,12 @@ handle_single(capmt_t *capmt) capmt_flush_queue(capmt, 0); continue; } - + tvhtrace(LS_CAPMT, "%s: thread received shutdown", capmt_name(capmt)); atomic_set(&capmt->capmt_running, 0); continue; } - + if (reconnect != capmt->capmt_sock_reconnect[0]) { buffer.sb_bswap = 0; sbuf_reset(&buffer, 1024); @@ -1702,14 +1777,14 @@ handle_single(capmt_t *capmt) } recvsock = capmt->capmt_sock[0]; - ret = recv(recvsock, buf, sizeof(buf), MSG_DONTWAIT); + ret = recv(recvsock, buf, sizeof(buf), MSG_DONTWAIT); if (ret == 0) { tvhinfo(LS_CAPMT, "%s: normal socket shutdown", capmt_name(capmt)); capmt_poll_rem(capmt, recvsock); break; } - + if (ret < 0) continue; @@ -1720,15 +1795,15 @@ handle_single(capmt_t *capmt) while (buffer.sb_ptr > 0) { while (buffer.sb_ptr > 0) { - adapter = -1; - offset = 0; + adapter = -1; + offset = 0; cmd_size = 0; - cmd = 0; + cmd = 0; if (buffer.sb_ptr < 5) break; if (netproto) { buffer.sb_bswap = 1; - cmd_size = capmt_msg_size(capmt, &buffer, 0); + cmd_size = capmt_msg_size(capmt, &buffer, 0); if (cmd_size > 0) { cmd = sbuf_peek_u32(&buffer, 0); if (cmd != DVBAPI_SERVER_INFO) { @@ -1753,7 +1828,7 @@ handle_single(capmt_t *capmt) cmd_size = capmt_msg_size(capmt, &buffer, 1); if (cmd_size > 0) { cmd_size -= 4; - cmd = sbuf_peek_u32(&buffer, 1); + cmd = sbuf_peek_u32(&buffer, 1); offset = 5; break; } else if (cmd_size == 0) @@ -1778,13 +1853,11 @@ handle_single(capmt_t *capmt) #if CONFIG_LINUXDVB #ifdef CAPMT_OSCAM_SO_WRAPPER -static void -handle_ca0_wrapper(capmt_t *capmt) -{ - uint8_t buffer[18]; - uint32_t index; - ca_info_t *cai; - int ret; +static void handle_ca0_wrapper(capmt_t* capmt) { + uint8_t buffer[18]; + uint32_t index; + ca_info_t* cai; + int ret; show_connection(capmt, ".so wrapper"); @@ -1807,17 +1880,16 @@ handle_ca0_wrapper(capmt_t *capmt) break; } else { - tvhtrace(LS_CAPMT, "%s: Received message from socket %i", capmt_name(capmt), capmt->capmt_adapters[0].ca_sock); + tvhtrace(LS_CAPMT, + "%s: Received message from socket %i", + capmt_name(capmt), + capmt->capmt_adapters[0].ca_sock); tvhlog_hexdump(LS_CAPMT, buffer, ret); index = buffer[0] | ((uint16_t)buffer[1] << 8); if (index < MAX_INDEX) { cai = &capmt->capmt_adapters[0].ca_info[index]; - capmt_process_key(capmt, 0, - cai, - DESCRAMBLER_CSA_CBC, - buffer + 2, buffer + 10, - ret == 18); + capmt_process_key(capmt, 0, cai, DESCRAMBLER_CSA_CBC, buffer + 2, buffer + 10, ret == 18); } } } @@ -1829,9 +1901,7 @@ handle_ca0_wrapper(capmt_t *capmt) #endif #if ENABLE_LINUXDVB -static int -capmt_create_udp_socket(capmt_t *capmt, int *socket, int port) -{ +static int capmt_create_udp_socket(capmt_t* capmt, int* socket, int port) { *socket = tvh_socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); if (*socket < 0) { tvherror(LS_CAPMT, "%s: failed to create UDP socket", capmt_name(capmt)); @@ -1841,15 +1911,13 @@ capmt_create_udp_socket(capmt_t *capmt, int *socket, int port) struct sockaddr_in serv_addr; memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); - serv_addr.sin_port = htons( (unsigned short int)port); - serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons((unsigned short int)port); + serv_addr.sin_family = AF_INET; - if (bind(*socket, (const struct sockaddr*)&serv_addr, sizeof(serv_addr)) != 0) - { + if (bind(*socket, (const struct sockaddr*)&serv_addr, sizeof(serv_addr)) != 0) { tvherror(LS_CAPMT, "%s: failed to bind to ca0 (port %d)", capmt_name(capmt), port); return 0; - } - else + } else return 1; } #endif @@ -1857,14 +1925,12 @@ capmt_create_udp_socket(capmt_t *capmt, int *socket, int port) /** * */ -static void * -capmt_thread(void *aux) -{ - capmt_t *capmt = aux; - capmt_adapter_t *ca; - capmt_opaque_t *t; - int d, i, j, fatal; - int64_t mono; +static void* capmt_thread(void* aux) { + capmt_t* capmt = aux; + capmt_adapter_t* ca; + capmt_opaque_t* t; + int d, i, j, fatal; + int64_t mono; tvhinfo(LS_CAPMT, "%s active", capmt_name(capmt)); @@ -1872,20 +1938,20 @@ capmt_thread(void *aux) fatal = 0; tvh_mutex_lock(&capmt->capmt_mutex); for (i = 0; i < MAX_CA; i++) { - ca = &capmt->capmt_adapters[i]; + ca = &capmt->capmt_adapters[i]; ca->ca_number = i; - ca->ca_sock = -1; + ca->ca_sock = -1; memset(&ca->ca_info, 0, sizeof(ca->ca_info)); for (j = 0; j < MAX_PIDS; j++) { - t = &ca->ca_pids[j]; - t->pid = PID_UNUSED; + t = &ca->ca_pids[j]; + t->pid = PID_UNUSED; t->pid_refs = 0; } } for (i = 0; i < MAX_SOCKETS; i++) { - capmt->sids[i] = 0; - capmt->adps[i] = -1; - capmt->capmt_sock[i] = -1; + capmt->sids[i] = 0; + capmt->adps[i] = -1; + capmt->capmt_sock[i] = -1; capmt->capmt_sock_reconnect[i] = 0; } capmt_init_demuxes(capmt); @@ -1894,24 +1960,25 @@ capmt_thread(void *aux) /* Accessible */ if (capmt->capmt_sockfile && !capmt_oscam_network(capmt) && !access(capmt->capmt_sockfile, R_OK | W_OK)) - caclient_set_status((caclient_t *)capmt, CACLIENT_STATUS_NONE); + caclient_set_status((caclient_t*)capmt, CACLIENT_STATUS_NONE); else - caclient_set_status((caclient_t *)capmt, CACLIENT_STATUS_READY); - + caclient_set_status((caclient_t*)capmt, CACLIENT_STATUS_READY); + tvh_mutex_lock(&capmt->capmt_mutex); - while(atomic_get(&capmt->capmt_running) && capmt->cac_enabled == 0) + while (atomic_get(&capmt->capmt_running) && capmt->cac_enabled == 0) tvh_cond_wait(&capmt->capmt_cond, &capmt->capmt_mutex); tvh_mutex_unlock(&capmt->capmt_mutex); - if (!atomic_get(&capmt->capmt_running)) continue; + if (!atomic_get(&capmt->capmt_running)) + continue; /* open connection to camd.socket */ capmt_connect(capmt, 0); if (capmt->capmt_sock[0] >= 0) { - caclient_set_status((caclient_t *)capmt, CACLIENT_STATUS_CONNECTED); + caclient_set_status((caclient_t*)capmt, CACLIENT_STATUS_CONNECTED); #if CONFIG_LINUXDVB if (capmt_oscam_new(capmt)) { handle_single(capmt); @@ -1920,21 +1987,21 @@ capmt_thread(void *aux) #ifdef CAPMT_OSCAM_SO_WRAPPER /* open connection to emulated ca0 device */ if (capmt->capmt_oscam == CAPMT_OSCAM_SO_WRAPPER) { - bind_ok = capmt_create_udp_socket(capmt, - &capmt->capmt_adapters[0].ca_sock, - capmt->capmt_port); + bind_ok = + capmt_create_udp_socket(capmt, &capmt->capmt_adapters[0].ca_sock, capmt->capmt_port); if (bind_ok) handle_ca0_wrapper(capmt); } else #endif { - int i, n; + int i, n; extern const idclass_t linuxdvb_adapter_class; - linuxdvb_adapter_t *la; - idnode_set_t *is = idnode_find_all(&linuxdvb_adapter_class, NULL); + linuxdvb_adapter_t* la; + idnode_set_t* is = idnode_find_all(&linuxdvb_adapter_class, NULL); for (i = 0; i < is->is_count; i++) { la = (linuxdvb_adapter_t*)is->is_array[i]; - if (!la || !la->la_is_enabled(la)) continue; + if (!la || !la->la_is_enabled(la)) + continue; n = la->la_dvb_number; if (n < 0 || n >= MAX_CA) { tvherror(LS_CAPMT, "%s: adapter number > MAX_CA", capmt_name(capmt)); @@ -1942,8 +2009,8 @@ capmt_thread(void *aux) } tvhinfo(LS_CAPMT, "%s: created UDP socket %d", capmt_name(capmt), n); bind_ok = capmt_create_udp_socket(capmt, - &capmt->capmt_adapters[n].ca_sock, - capmt->capmt_port + n); + &capmt->capmt_adapters[n].ca_sock, + capmt->capmt_port + n); } idnode_set_free(is); if (bind_ok) @@ -1953,19 +2020,20 @@ capmt_thread(void *aux) fatal = 1; } #else - if (capmt_oscam_network(capmt) || - capmt_oscam_socket(capmt)) { - handle_single(capmt); - } else { - tvherror(LS_CAPMT, "%s: Only modes 3,4,5,6 are supported for non-linuxdvb devices", capmt_name(capmt)); - fatal = 1; - } + if (capmt_oscam_network(capmt) || capmt_oscam_socket(capmt)) { + handle_single(capmt); + } else { + tvherror(LS_CAPMT, + "%s: Only modes 3,4,5,6 are supported for non-linuxdvb devices", + capmt_name(capmt)); + fatal = 1; + } #endif } tvh_mutex_lock(&capmt->capmt_mutex); - caclient_set_status((caclient_t *)capmt, CACLIENT_STATUS_DISCONNECTED); + caclient_set_status((caclient_t*)capmt, CACLIENT_STATUS_DISCONNECTED); /* close opened sockets */ for (i = 0; i < MAX_SOCKETS; i++) @@ -1990,7 +2058,7 @@ capmt_thread(void *aux) } /* schedule reconnection */ - if(subscriptions_active() && !fatal) { + if (subscriptions_active() && !fatal) { d = 3; } else { d = 60; @@ -2015,19 +2083,18 @@ capmt_thread(void *aux) /** * */ -static void -capmt_table_input(void *opaque, int pid, const uint8_t *data, int len, int emm) -{ - capmt_opaque_t *o = opaque; - capmt_t *capmt = o->capmt; - int i, demux_index, filter_index; - capmt_dmx_t *df; - capmt_filters_t *cf; - dmx_filter_t *f; - int flags = emm ? 0 : CAPMT_MSG_FAST; +static void capmt_table_input(void* opaque, int pid, const uint8_t* data, int len, int emm) { + capmt_opaque_t* o = opaque; + capmt_t* capmt = o->capmt; + int i, demux_index, filter_index; + capmt_dmx_t* df; + capmt_filters_t* cf; + dmx_filter_t* f; + int flags = emm ? 0 : CAPMT_MSG_FAST; /* Validate */ - if (data == NULL || len > 4096) return; + if (data == NULL || len > 4096) + return; tvh_mutex_lock(&capmt->capmt_mutex); @@ -2053,9 +2120,12 @@ capmt_table_input(void *opaque, int pid, const uint8_t *data, int len, int emm) if (i >= DMX_FILTER_SIZE || i + 2 == len) { tvhtrace(LS_CAPMT, "filter match pid %d len %d emm %d", pid, len, emm); capmt_filter_data(capmt, - o->adapter, demux_index, - filter_index, data, len, - cf->dmx[filter_index].flags); + o->adapter, + demux_index, + filter_index, + data, + len, + cf->dmx[filter_index].flags); } } } @@ -2064,90 +2134,107 @@ capmt_table_input(void *opaque, int pid, const uint8_t *data, int len, int emm) tvh_mutex_unlock(&capmt->capmt_mutex); } -static void -capmt_caid_add(capmt_service_t *ct, mpegts_service_t *t, int pid, caid_t *c) -{ - capmt_caid_ecm_t *cce; +static void capmt_caid_add(capmt_service_t* ct, mpegts_service_t* t, int pid, caid_t* c) { + capmt_caid_ecm_t* cce; tvhdebug(LS_CAPMT, - "%s: New caid 0x%04X:0x%06X (pid 0x%04X) for service \"%s\"", - capmt_name(ct->ct_capmt), c->caid, c->providerid, pid, t->s_dvb_svcname); - - cce = calloc(1, sizeof(capmt_caid_ecm_t)); - cce->cce_caid = c->caid; - cce->cce_ecmpid = pid; + "%s: New caid 0x%04X:0x%06X (pid 0x%04X) for service \"%s\"", + capmt_name(ct->ct_capmt), + c->caid, + c->providerid, + pid, + t->s_dvb_svcname); + + cce = calloc(1, sizeof(capmt_caid_ecm_t)); + cce->cce_caid = c->caid; + cce->cce_ecmpid = pid; cce->cce_providerid = c->providerid; - cce->cce_service = t; + cce->cce_service = t; LIST_INSERT_HEAD(&ct->ct_caid_ecm, cce, cce_link); } -static int -capmt_update_elementary_stream(capmt_service_t *ct, int *_i, - elementary_stream_t *st) -{ +static int capmt_update_elementary_stream(capmt_service_t* ct, int* _i, elementary_stream_t* st) { uint8_t type; - int i = *_i; + int i = *_i; switch (st->es_type) { - case SCT_MPEG2VIDEO: type = 0x02; break; - case SCT_MPEG2AUDIO: type = 0x04; break; - case SCT_AC3: type = 0x81; break; - case SCT_EAC3: type = 0x81; break; - case SCT_MP4A: type = 0x0f; break; - case SCT_AAC: type = 0x11; break; - case SCT_H264: type = 0x1b; break; - case SCT_HEVC: type = 0x24; break; - case SCT_DVBSUB: type = 0x06; break; - case SCT_TELETEXT: type = 0x06; break; - default: - if (SCT_ISVIDEO(st->es_type)) type = 0x02; - else if (SCT_ISAUDIO(st->es_type)) type = 0x04; - else return 0; + case SCT_MPEG2VIDEO: + type = 0x02; + break; + case SCT_MPEG2AUDIO: + type = 0x04; + break; + case SCT_AC3: + type = 0x81; + break; + case SCT_EAC3: + type = 0x81; + break; + case SCT_MP4A: + type = 0x0f; + break; + case SCT_AAC: + type = 0x11; + break; + case SCT_H264: + type = 0x1b; + break; + case SCT_HEVC: + type = 0x24; + break; + case SCT_DVBSUB: + type = 0x06; + break; + case SCT_TELETEXT: + type = 0x06; + break; + default: + if (SCT_ISVIDEO(st->es_type)) + type = 0x02; + else if (SCT_ISAUDIO(st->es_type)) + type = 0x04; + else + return 0; } *_i = i + 1; if (st->es_pid != ct->ct_pids[i] || type != ct->ct_types[i]) { - ct->ct_pids[i] = st->es_pid; + ct->ct_pids[i] = st->es_pid; ct->ct_types[i] = type; /* mark as valid for !multipid - TELETEXT may be shared */ - ct->ct_type_sok[i] = SCT_ISVIDEO(st->es_type) || - SCT_ISAUDIO(st->es_type) || - st->es_type == SCT_DVBSUB; + ct->ct_type_sok[i] = + SCT_ISVIDEO(st->es_type) || SCT_ISAUDIO(st->es_type) || st->es_type == SCT_DVBSUB; return 1; } return 0; } -static void -capmt_caid_change(th_descrambler_t *td) -{ - capmt_service_t *ct = (capmt_service_t *)td; - capmt_t *capmt = ct->ct_capmt; - mpegts_service_t *t = (mpegts_service_t*)td->td_service; - elementary_stream_t *st; - capmt_caid_ecm_t *cce, *cce_next; - caid_t *c; - int i, change = 0; +static void capmt_caid_change(th_descrambler_t* td) { + capmt_service_t* ct = (capmt_service_t*)td; + capmt_t* capmt = ct->ct_capmt; + mpegts_service_t* t = (mpegts_service_t*)td->td_service; + elementary_stream_t* st; + capmt_caid_ecm_t * cce, *cce_next; + caid_t* c; + int i, change = 0; tvh_mutex_lock(&capmt->capmt_mutex); tvh_mutex_lock(&t->s_stream_mutex); /* add missing A/V PIDs and ECM PIDs */ i = 0; - TAILQ_FOREACH(st, &t->s_components.set_filter, es_filter_link) { + TAILQ_FOREACH (st, &t->s_components.set_filter, es_filter_link) { if (i < MAX_PIDS && capmt_include_elementary_stream(st->es_type)) { if (capmt_update_elementary_stream(ct, &i, st)) change = 1; } - if (t->s_dvb_prefcapid_lock == PREFCAPID_FORCE && - t->s_dvb_prefcapid != st->es_pid) + if (t->s_dvb_prefcapid_lock == PREFCAPID_FORCE && t->s_dvb_prefcapid != st->es_pid) continue; - LIST_FOREACH(c, &st->es_caids, link) { + LIST_FOREACH (c, &st->es_caids, link) { /* search ecmpid in list */ - LIST_FOREACH(cce, &ct->ct_caid_ecm, cce_link) - if (c->use && cce->cce_caid == c->caid && - cce->cce_providerid == c->providerid && + LIST_FOREACH (cce, &ct->ct_caid_ecm, cce_link) + if (c->use && cce->cce_caid == c->caid && cce->cce_providerid == c->providerid && st->es_pid == cce->cce_ecmpid && (!t->s_dvb_forcecaid || t->s_dvb_forcecaid == cce->cce_caid)) break; @@ -2160,27 +2247,26 @@ capmt_caid_change(th_descrambler_t *td) /* clear rest */ for (; i < MAX_PIDS; i++) { - ct->ct_pids[i] = 0; + ct->ct_pids[i] = 0; ct->ct_types[i] = 0; } /* find removed ECM PIDs */ - LIST_FOREACH(cce, &ct->ct_caid_ecm, cce_link) { - if (t->s_dvb_prefcapid_lock == PREFCAPID_FORCE && - cce->cce_ecmpid != t->s_dvb_prefcapid) { + LIST_FOREACH (cce, &ct->ct_caid_ecm, cce_link) { + if (t->s_dvb_prefcapid_lock == PREFCAPID_FORCE && cce->cce_ecmpid != t->s_dvb_prefcapid) { st = NULL; } else { - TAILQ_FOREACH(st, &t->s_components.set_filter, es_filter_link) { - LIST_FOREACH(c, &st->es_caids, link) - if (c->use && cce->cce_caid == c->caid && - cce->cce_providerid == c->providerid && + TAILQ_FOREACH (st, &t->s_components.set_filter, es_filter_link) { + LIST_FOREACH (c, &st->es_caids, link) + if (c->use && cce->cce_caid == c->caid && cce->cce_providerid == c->providerid && st->es_pid == cce->cce_ecmpid) break; - if (c) break; + if (c) + break; } } if (!st) { - change = 3; + change = 3; cce->cce_delete_me = 1; } else { cce->cce_delete_me = 0; @@ -2212,62 +2298,58 @@ capmt_caid_change(th_descrambler_t *td) capmt_notify_server(capmt, ct, 1); } -static void -capmt_ok_timer_cb(void *aux) -{ - capmt_service_t *ct = aux; +static void capmt_ok_timer_cb(void* aux) { + capmt_service_t* ct = aux; if (!ct->ct_ok_flag) - descrambler_change_keystate((th_descrambler_t *)ct, DS_FATAL, 1); + descrambler_change_keystate((th_descrambler_t*)ct, DS_FATAL, 1); } -static void -capmt_send_request(capmt_service_t *ct, int lm) -{ - capmt_t *capmt = ct->ct_capmt; - mpegts_service_t *t = (mpegts_service_t *)ct->td_service; - uint16_t sid = service_id16(t); - uint16_t pmtpid = t->s_components.set_pmt_pid; - uint16_t transponder = t->s_dvb_mux->mm_tsid; - uint16_t onid = t->s_dvb_mux->mm_onid; - const int adapter_num = ct->ct_adapter; - const int wrapper = capmt_oscam_so_wrapper(capmt); - int i, pc_desc = 0; +static void capmt_send_request(capmt_service_t* ct, int lm) { + capmt_t* capmt = ct->ct_capmt; + mpegts_service_t* t = (mpegts_service_t*)ct->td_service; + uint16_t sid = service_id16(t); + uint16_t pmtpid = t->s_components.set_pmt_pid; + uint16_t transponder = t->s_dvb_mux->mm_tsid; + uint16_t onid = t->s_dvb_mux->mm_onid; + const int adapter_num = ct->ct_adapter; + const int wrapper = capmt_oscam_so_wrapper(capmt); + int i, pc_desc = 0; /* choose the PMT composing mode */ if (!wrapper) { switch (capmt->capmt_pmtmode) { - case CAPMT_PMTMODE_INDEX: - pc_desc = 0; - break; - case CAPMT_PMTMODE_UNIVERSAL: - pc_desc = 1; - break; - default: - pc_desc = adapter_num >= 8 || capmt->capmt_oscam_rev >= 11396; - break; + case CAPMT_PMTMODE_INDEX: + pc_desc = 0; + break; + case CAPMT_PMTMODE_UNIVERSAL: + pc_desc = 1; + break; + default: + pc_desc = adapter_num >= 8 || capmt->capmt_oscam_rev >= 11396; + break; } } /* buffer for capmt */ - int pos = 0, pos2; + int pos = 0, pos2; uint8_t buf[4094]; - buf[pos++] = 0x9f; - buf[pos++] = 0x80; - buf[pos++] = 0x32; - buf[pos++] = 0x82; - buf[pos++] = 0; /* total length */ - buf[pos++] = 0; /* total length */ - buf[pos++] = lm; - buf[pos++] = sid >> 8; - buf[pos++] = sid & 0xFF; - buf[pos++] = capmt->capmt_pmtversion; + buf[pos++] = 0x9f; + buf[pos++] = 0x80; + buf[pos++] = 0x32; + buf[pos++] = 0x82; + buf[pos++] = 0; /* total length */ + buf[pos++] = 0; /* total length */ + buf[pos++] = lm; + buf[pos++] = sid >> 8; + buf[pos++] = sid & 0xFF; + buf[pos++] = capmt->capmt_pmtversion; capmt->capmt_pmtversion = (capmt->capmt_pmtversion + 1) & 0x1F; - buf[pos++] = 0; /* room for length - program info tags */ - buf[pos++] = 0; /* room for length - program info tags */ - buf[pos++] = 1; /* OK DESCRAMBLING, skipped for parse_descriptors, but */ - /* mandatory for getDemuxOptions() */ + buf[pos++] = 0; /* room for length - program info tags */ + buf[pos++] = 0; /* room for length - program info tags */ + buf[pos++] = 1; /* OK DESCRAMBLING, skipped for parse_descriptors, but */ + /* mandatory for getDemuxOptions() */ if (pc_desc) { /* build SI tag */ @@ -2310,10 +2392,10 @@ capmt_send_request(capmt_service_t *ct, int lm) buf[pos++] = adapter_num; } - capmt_caid_ecm_t *cce2; - LIST_FOREACH(cce2, &ct->ct_caid_ecm, cce_link) { + capmt_caid_ecm_t* cce2; + LIST_FOREACH (cce2, &ct->ct_caid_ecm, cce_link) { /* build SI tag */ - pos2 = pos; + pos2 = pos; buf[pos2++] = 0x09; buf[pos2++] = 4; buf[pos2++] = cce2->cce_caid >> 8; @@ -2322,62 +2404,69 @@ capmt_send_request(capmt_service_t *ct, int lm) buf[pos2++] = cce2->cce_ecmpid; if (cce2->cce_providerid) { // we need to add provider ID to the data if (cce2->cce_caid >> 8 == 0x01) { - buf[pos+1] = 17; - buf[pos2++] = cce2->cce_providerid >> 8; - buf[pos2++] = cce2->cce_providerid & 0xff; + buf[pos + 1] = 17; + buf[pos2++] = cce2->cce_providerid >> 8; + buf[pos2++] = cce2->cce_providerid & 0xff; memset(buf + pos2, 0, 17 - 6); pos2 += 17 - 6; } else if (cce2->cce_caid >> 8 == 0x05) { - buf[pos+1] = 15; - buf[pos2++] = 0x00; - buf[pos2++] = 0x00; - buf[pos2++] = 0x00; - buf[pos2++] = 0x00; - buf[pos2++] = 0x00; - buf[pos2++] = 0x00; - buf[pos2++] = 0x14; - buf[pos2++] = 0x00; - buf[pos2++] = cce2->cce_providerid >> 16; - buf[pos2++] = cce2->cce_providerid >> 8; - buf[pos2++] = cce2->cce_providerid & 0xff; + buf[pos + 1] = 15; + buf[pos2++] = 0x00; + buf[pos2++] = 0x00; + buf[pos2++] = 0x00; + buf[pos2++] = 0x00; + buf[pos2++] = 0x00; + buf[pos2++] = 0x00; + buf[pos2++] = 0x14; + buf[pos2++] = 0x00; + buf[pos2++] = cce2->cce_providerid >> 16; + buf[pos2++] = cce2->cce_providerid >> 8; + buf[pos2++] = cce2->cce_providerid & 0xff; } else if (cce2->cce_caid >> 8 == 0x18) { - buf[pos+1] = 7; - buf[pos2++] = 0; - buf[pos2++] = cce2->cce_providerid >> 8; - buf[pos2++] = cce2->cce_providerid & 0xff; + buf[pos + 1] = 7; + buf[pos2++] = 0; + buf[pos2++] = cce2->cce_providerid >> 8; + buf[pos2++] = cce2->cce_providerid & 0xff; } else if (cce2->cce_caid >> 8 == 0x4a && cce2->cce_caid != 0x4ad2) { - buf[pos+1] = 5; - buf[pos2++] = cce2->cce_providerid & 0xff; + buf[pos + 1] = 5; + buf[pos2++] = cce2->cce_providerid & 0xff; } else if (((cce2->cce_caid >> 8) == 0x4a) || (cce2->cce_caid == 0x2710)) { if (cce2->cce_caid == 0x4AE0 || cce2->cce_caid == 0x4AE1 || cce2->cce_caid == 0x2710) { - buf[pos+1] = 10; - buf[pos2++] = cce2->cce_providerid & 0xff; - buf[pos2++] = 0x00; - buf[pos2++] = 0x00; /* CA data */ - buf[pos2++] = 0x00; /* CA data */ - buf[pos2++] = 0x00; /* CA data */ - buf[pos2++] = 0x00; /* CA data */ + buf[pos + 1] = 10; + buf[pos2++] = cce2->cce_providerid & 0xff; + buf[pos2++] = 0x00; + buf[pos2++] = 0x00; /* CA data */ + buf[pos2++] = 0x00; /* CA data */ + buf[pos2++] = 0x00; /* CA data */ + buf[pos2++] = 0x00; /* CA data */ } else { - buf[pos+1] = 5; - buf[pos2++] = cce2->cce_providerid & 0xff; + buf[pos + 1] = 5; + buf[pos2++] = cce2->cce_providerid & 0xff; } } else { - tvhwarn(LS_CAPMT, "%s: Unknown CAID type, don't know where to put provider ID", capmt_name(capmt)); + tvhwarn(LS_CAPMT, + "%s: Unknown CAID type, don't know where to put provider ID", + capmt_name(capmt)); } } pos = pos2; - tvhdebug(LS_CAPMT, "%s: adding ECMPID=0x%X (%d), " - "CAID=0x%X (%d) PROVID=0x%X (%d), SID=%d, ADAPTER=%d", - capmt_name(capmt), - cce2->cce_ecmpid, cce2->cce_ecmpid, - cce2->cce_caid, cce2->cce_caid, - cce2->cce_providerid, cce2->cce_providerid, - sid, adapter_num); + tvhdebug(LS_CAPMT, + "%s: adding ECMPID=0x%X (%d), " + "CAID=0x%X (%d) PROVID=0x%X (%d), SID=%d, ADAPTER=%d", + capmt_name(capmt), + cce2->cce_ecmpid, + cce2->cce_ecmpid, + cce2->cce_caid, + cce2->cce_caid, + cce2->cce_providerid, + cce2->cce_providerid, + sid, + adapter_num); } /* update length of program info tags */ buf[10] = ((pos - 12) & 0xF00) >> 8; - buf[11] = pos - 12; + buf[11] = pos - 12; /* build elementary stream info */ if (capmt_oscam_new(capmt)) { @@ -2397,28 +2486,28 @@ capmt_send_request(capmt_service_t *ct, int lm) } /* update total length (except 4 byte header) */ - buf[4] = (pos - 6) >> 8; - buf[5] = pos - 6; + buf[4] = (pos - 6) >> 8; + buf[5] = pos - 6; - if(ct->td_keystate != DS_RESOLVED) - tvhdebug(LS_CAPMT, "%s: Trying to obtain key for service \"%s\"", - capmt_name(capmt), t->s_dvb_svcname); + if (ct->td_keystate != DS_RESOLVED) + tvhdebug(LS_CAPMT, + "%s: Trying to obtain key for service \"%s\"", + capmt_name(capmt), + t->s_dvb_svcname); capmt_queue_msg(capmt, adapter_num, sid, buf, pos, 0); } -static void -capmt_enumerate_services(capmt_t *capmt, int force) -{ - int lm = CAPMT_LIST_FIRST; //list management - int all_srv_count = 0; //all services - int res_srv_count = 0; //services with resolved state - int i = 0; - capmt_service_t *ct; +static void capmt_enumerate_services(capmt_t* capmt, int force) { + int lm = CAPMT_LIST_FIRST; // list management + int all_srv_count = 0; // all services + int res_srv_count = 0; // services with resolved state + int i = 0; + capmt_service_t* ct; lock_assert(&capmt->capmt_mutex); - LIST_FOREACH(ct, &capmt->capmt_services, ct_link) { + LIST_FOREACH (ct, &capmt->capmt_services, ct_link) { all_srv_count++; if (ct->td_keystate == DS_RESOLVED) res_srv_count++; @@ -2426,10 +2515,13 @@ capmt_enumerate_services(capmt_t *capmt, int force) if (!all_srv_count) { // closing socket (oscam handle this as event and stop decrypting) - tvhdebug(LS_CAPMT, "%s: %s: no subscribed services, closing socket, fd=%d", - capmt_name(capmt), __FUNCTION__, capmt->capmt_sock[0]); + tvhdebug(LS_CAPMT, + "%s: %s: no subscribed services, closing socket, fd=%d", + capmt_name(capmt), + __FUNCTION__, + capmt->capmt_sock[0]); if (capmt->capmt_sock[0] >= 0) - caclient_set_status((caclient_t *)capmt, CACLIENT_STATUS_READY); + caclient_set_status((caclient_t*)capmt, CACLIENT_STATUS_READY); if (capmt_oscam_netproto(capmt)) { capmt_send_stop_descrambling(capmt, 0xff); capmt_pid_flush(capmt); @@ -2437,7 +2529,7 @@ capmt_enumerate_services(capmt_t *capmt, int force) capmt_socket_close(capmt, 0); } } else if (force || (res_srv_count != all_srv_count)) { - LIST_FOREACH(ct, &capmt->capmt_services, ct_link) { + LIST_FOREACH (ct, &capmt->capmt_services, ct_link) { if (all_srv_count == i + 1) lm |= CAPMT_LIST_LAST; capmt_send_request(ct, lm); @@ -2452,28 +2544,27 @@ capmt_enumerate_services(capmt_t *capmt, int force) * * global_lock is held */ -static void -capmt_service_start(caclient_t *cac, service_t *s) -{ - capmt_t *capmt = (capmt_t *)cac; - capmt_service_t *ct; - th_descrambler_t *td; - mpegts_service_t *t = (mpegts_service_t*)s; - elementary_stream_t *st; - int tuner = -1, i, change = 0; - char buf[512]; - caid_t *c, sca; - +static void capmt_service_start(caclient_t* cac, service_t* s) { + capmt_t* capmt = (capmt_t*)cac; + capmt_service_t* ct; + th_descrambler_t* td; + mpegts_service_t* t = (mpegts_service_t*)s; + elementary_stream_t* st; + int tuner = -1, i, change = 0; + char buf[512]; + caid_t * c, sca; + lock_assert(&global_lock); /* Validate */ if (!idnode_is_instance(&s->s_id, &mpegts_service_class)) return; - if (!t->s_dvb_active_input) return; + if (!t->s_dvb_active_input) + return; #if ENABLE_LINUXDVB extern const idclass_t linuxdvb_frontend_class; - linuxdvb_frontend_t *lfe; + linuxdvb_frontend_t* lfe; lfe = (linuxdvb_frontend_t*)t->s_dvb_active_input; if (idnode_is_instance(&lfe->ti_id, &linuxdvb_frontend_class)) tuner = lfe->lfe_adapter->la_dvb_number; @@ -2482,15 +2573,16 @@ capmt_service_start(caclient_t *cac, service_t *s) tvh_mutex_lock(&capmt->capmt_mutex); tvh_mutex_lock(&t->s_stream_mutex); - LIST_FOREACH(ct, &capmt->capmt_services, ct_link) + LIST_FOREACH (ct, &capmt->capmt_services, ct_link) /* skip, if we already have this service */ - if (ct->td_service == (service_t *)t) + if (ct->td_service == (service_t*)t) goto fin; if (tuner < 0 && !capmt_oscam_network(capmt) && !capmt_oscam_socket(capmt)) { tvhwarn(LS_CAPMT, - "%s: Virtual adapters are supported only in modes 3, 4, 5 and 6 (service \"%s\")", - capmt_name(capmt), t->s_dvb_svcname); + "%s: Virtual adapters are supported only in modes 3, 4, 5 and 6 (service \"%s\")", + capmt_name(capmt), + t->s_dvb_svcname); goto fin; } @@ -2505,8 +2597,9 @@ capmt_service_start(caclient_t *cac, service_t *s) } if (tuner < 0 || tuner >= MAX_CA) { tvherror(LS_CAPMT, - "%s: No free adapter slot available for service \"%s\"", - capmt_name(capmt), t->s_dvb_svcname); + "%s: No free adapter slot available for service \"%s\"", + capmt_name(capmt), + t->s_dvb_svcname); tvh_mutex_unlock(&capmt->capmt_mutex); tvh_mutex_unlock(&t->s_stream_mutex); return; @@ -2514,25 +2607,26 @@ capmt_service_start(caclient_t *cac, service_t *s) } tvhinfo(LS_CAPMT, - "%s: Starting CAPMT server for service \"%s\" on adapter %d", - capmt_name(capmt), t->s_dvb_svcname, tuner); + "%s: Starting CAPMT server for service \"%s\" on adapter %d", + capmt_name(capmt), + t->s_dvb_svcname, + tuner); capmt->capmt_adapters[tuner].ca_tuner = t->s_dvb_active_input; /* create new capmt service */ - ct = calloc(1, sizeof(capmt_service_t)); - ct->ct_capmt = capmt; - ct->ct_adapter = tuner; + ct = calloc(1, sizeof(capmt_service_t)); + ct->ct_capmt = capmt; + ct->ct_adapter = tuner; i = 0; - TAILQ_FOREACH(st, &t->s_components.set_filter, es_filter_link) { + TAILQ_FOREACH (st, &t->s_components.set_filter, es_filter_link) { if (i < MAX_PIDS && capmt_include_elementary_stream(st->es_type)) capmt_update_elementary_stream(ct, &i, st); - if (t->s_dvb_prefcapid_lock == PREFCAPID_FORCE && - t->s_dvb_prefcapid != st->es_pid) + if (t->s_dvb_prefcapid_lock == PREFCAPID_FORCE && t->s_dvb_prefcapid != st->es_pid) continue; - LIST_FOREACH(c, &st->es_caids, link) { - if(c == NULL || c->use == 0) + LIST_FOREACH (c, &st->es_caids, link) { + if (c == NULL || c->use == 0) continue; if (t->s_dvb_forcecaid && t->s_dvb_forcecaid != c->caid) continue; @@ -2548,11 +2642,9 @@ capmt_service_start(caclient_t *cac, service_t *s) change = 1; } - td = (th_descrambler_t *)ct; + td = (th_descrambler_t*)ct; if (capmt_oscam_network(capmt)) { - snprintf(buf, sizeof(buf), "capmt-%s-%i", - capmt->capmt_sockfile, - capmt->capmt_port); + snprintf(buf, sizeof(buf), "capmt-%s-%i", capmt->capmt_sockfile, capmt->capmt_port); } else { snprintf(buf, sizeof(buf), "capmt-%s", capmt->capmt_sockfile); } @@ -2565,15 +2657,15 @@ capmt_service_start(caclient_t *cac, service_t *s) LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link); LIST_INSERT_HEAD(&capmt->capmt_services, ct, ct_link); - ct->ct_multipid = descrambler_multi_pid((th_descrambler_t *)ct); - descrambler_change_keystate((th_descrambler_t *)td, DS_READY, 0); + ct->ct_multipid = descrambler_multi_pid((th_descrambler_t*)ct); + descrambler_change_keystate((th_descrambler_t*)td, DS_READY, 0); /* wake-up idle thread */ tvh_cond_signal(&capmt->capmt_cond, 0); fin: if (ct) - mtimer_arm_rel(&ct->ct_ok_timer, capmt_ok_timer_cb, ct, sec2mono(3)/2); + mtimer_arm_rel(&ct->ct_ok_timer, capmt_ok_timer_cb, ct, sec2mono(3) / 2); tvh_mutex_unlock(&t->s_stream_mutex); tvh_mutex_unlock(&capmt->capmt_mutex); @@ -2581,19 +2673,18 @@ fin: capmt_notify_server(capmt, NULL, 0); } - /** * */ -static void -capmt_free(caclient_t *cac) -{ - capmt_t *capmt = (capmt_t *)cac; - tvhinfo(LS_CAPMT, "%s: mode %i %s %s port %i destroyed", - capmt_name(capmt), - capmt->capmt_oscam, - capmt_oscam_network(capmt) ? "IP address" : "sockfile", - capmt->capmt_sockfile, capmt->capmt_port); +static void capmt_free(caclient_t* cac) { + capmt_t* capmt = (capmt_t*)cac; + tvhinfo(LS_CAPMT, + "%s: mode %i %s %s port %i destroyed", + capmt_name(capmt), + capmt->capmt_oscam, + capmt_oscam_network(capmt) ? "IP address" : "sockfile", + capmt->capmt_sockfile, + capmt->capmt_port); capmt_flush_queue(capmt, 1); free(capmt->capmt_sockfile); } @@ -2603,40 +2694,39 @@ capmt_free(caclient_t *cac) */ static const struct strtab caclient_capmt_oscam_mode_tab[] = { #ifdef CAPMT_OSCAM_NET_PROTO - { N_("OSCam net protocol (rev >= 10389)"), CAPMT_OSCAM_NET_PROTO }, + {N_("OSCam net protocol (rev >= 10389)"), CAPMT_OSCAM_NET_PROTO}, #endif #ifdef CAPMT_OSCAM_UNIX_SOCKET_NP - { N_("Problematic: OSCam new pc-nodmx (rev >= 10389)"), CAPMT_OSCAM_UNIX_SOCKET_NP }, + {N_("Problematic: OSCam new pc-nodmx (rev >= 10389)"), CAPMT_OSCAM_UNIX_SOCKET_NP}, #endif #ifdef CAPMT_OSCAM_TCP - { N_("OSCam TCP (rev >= 9574)"), CAPMT_OSCAM_TCP }, + {N_("OSCam TCP (rev >= 9574)"), CAPMT_OSCAM_TCP}, #endif #ifdef CAPMT_OSCAM_UNIX_SOCKET - { N_("OSCam pc-nodmx (rev >= 9756)"), CAPMT_OSCAM_UNIX_SOCKET }, + {N_("OSCam pc-nodmx (rev >= 9756)"), CAPMT_OSCAM_UNIX_SOCKET}, #endif #ifdef CAPMT_OSCAM_MULTILIST - { N_("OSCam (rev >= 9095)"), CAPMT_OSCAM_MULTILIST }, + {N_("OSCam (rev >= 9095)"), CAPMT_OSCAM_MULTILIST}, #endif #ifdef CAPMT_OSCAM_OLD - { N_("Older OSCam"), CAPMT_OSCAM_OLD }, + {N_("Older OSCam"), CAPMT_OSCAM_OLD}, #endif #ifdef CAPMT_OSCAM_SO_WRAPPER - { N_("Wrapper (capmt_ca.so)"), CAPMT_OSCAM_SO_WRAPPER }, + {N_("Wrapper (capmt_ca.so)"), CAPMT_OSCAM_SO_WRAPPER}, #endif }; -static void -capmt_conf_changed(caclient_t *cac) -{ - capmt_t *capmt = (capmt_t *)cac; +static void capmt_conf_changed(caclient_t* cac) { + capmt_t* capmt = (capmt_t*)cac; pthread_t tid; - idnode_get_title(&capmt->cac_id, NULL, - capmt->capmt_name, sizeof(capmt->capmt_name)); + idnode_get_title(&capmt->cac_id, NULL, capmt->capmt_name, sizeof(capmt->capmt_name)); if (val2str(capmt->capmt_oscam, caclient_capmt_oscam_mode_tab) == NULL) { - tvherror(LS_CAPMT, "Unknown mode %d, disabling capmt client %s", - capmt->capmt_oscam, capmt->capmt_name); + tvherror(LS_CAPMT, + "Unknown mode %d, disabling capmt client %s", + capmt->capmt_oscam, + capmt->capmt_name); capmt->cac_enabled = 0; } @@ -2669,103 +2759,88 @@ capmt_conf_changed(caclient_t *cac) pthread_join(tid, NULL); caclient_set_status(cac, CACLIENT_STATUS_NONE); } - } -static htsmsg_t * -caclient_capmt_class_oscam_mode_list ( void *o, const char *lang ) -{ +static htsmsg_t* caclient_capmt_class_oscam_mode_list(void* o, const char* lang) { return strtab2htsmsg(caclient_capmt_oscam_mode_tab, 1, lang); } -static htsmsg_t * -caclient_capmt_class_cwmode_list ( void *o, const char *lang ) -{ +static htsmsg_t* caclient_capmt_class_cwmode_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Standard / auto"), CAPMT_CWMODE_AUTO }, - { N_("Extended (OE 2.2)"), CAPMT_CWMODE_OE22 }, - { N_("Extended (OE 2.2), mode follows key"), CAPMT_CWMODE_OE22SW }, - { N_("Extended DES (OE 2.0)"), CAPMT_CWMODE_OE20 }, + {N_("Standard / auto"), CAPMT_CWMODE_AUTO}, + {N_("Extended (OE 2.2)"), CAPMT_CWMODE_OE22}, + {N_("Extended (OE 2.2), mode follows key"), CAPMT_CWMODE_OE22SW}, + {N_("Extended DES (OE 2.0)"), CAPMT_CWMODE_OE20}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -caclient_capmt_class_pmtmode_list ( void *o, const char *lang ) -{ +static htsmsg_t* caclient_capmt_class_pmtmode_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Auto"), CAPMT_PMTMODE_AUTO }, - { N_("Byte index tag order"), CAPMT_PMTMODE_INDEX }, - { N_("Universal tag order"), CAPMT_PMTMODE_UNIVERSAL }, + {N_("Auto"), CAPMT_PMTMODE_AUTO}, + {N_("Byte index tag order"), CAPMT_PMTMODE_INDEX}, + {N_("Universal tag order"), CAPMT_PMTMODE_UNIVERSAL}, }; return strtab2htsmsg(tab, 1, lang); } CLASS_DOC(caclient) -const idclass_t caclient_capmt_class = -{ - .ic_super = &caclient_class, - .ic_class = "caclient_capmt", - .ic_caption = N_("CAPMT (Linux Network DVBAPI)"), - .ic_doc = tvh_doc_caclient_class, - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "mode", - .name = N_("Mode"), - .desc = N_("Oscam mode."), - .off = offsetof(capmt_t, capmt_oscam), - .list = caclient_capmt_class_oscam_mode_list, - .def.i = CAPMT_OSCAM_NET_PROTO, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "camdfilename", - .name = N_("Camd.socket filename / IP Address (TCP mode)"), - .desc = N_("Socket or IP Address (when in TCP mode)."), - .off = offsetof(capmt_t, capmt_sockfile), - .def.s = "127.0.0.1", - }, - { - .type = PT_INT, - .id = "port", - .name = N_("Listen / Connect port"), - .desc = N_("Port to listen on or to connect to."), - .off = offsetof(capmt_t, capmt_port), - .def.i = 9000 - }, - { - .type = PT_INT, - .id = "cwmode", - .name = N_("CW Mode"), - .desc = N_("CryptoWord mode."), - .off = offsetof(capmt_t, capmt_cwmode), - .list = caclient_capmt_class_cwmode_list, - .def.i = CAPMT_CWMODE_AUTO, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_INT, - .id = "pmtmode", - .name = N_("PMT Mode"), - .desc = N_("PMT mode."), - .off = offsetof(capmt_t, capmt_pmtmode), - .list = caclient_capmt_class_pmtmode_list, - .def.i = CAPMT_PMTMODE_AUTO, - .opts = PO_DOC_NLIST, - }, - { } - } -}; +const idclass_t caclient_capmt_class = {.ic_super = &caclient_class, + .ic_class = "caclient_capmt", + .ic_caption = N_("CAPMT (Linux Network DVBAPI)"), + .ic_doc = tvh_doc_caclient_class, + .ic_properties = (const property_t[]){{ + .type = PT_INT, + .id = "mode", + .name = N_("Mode"), + .desc = N_("Oscam mode."), + .off = offsetof(capmt_t, capmt_oscam), + .list = caclient_capmt_class_oscam_mode_list, + .def.i = CAPMT_OSCAM_NET_PROTO, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "camdfilename", + .name = N_("Camd.socket filename / IP Address (TCP mode)"), + .desc = N_("Socket or IP Address (when in TCP mode)."), + .off = offsetof(capmt_t, capmt_sockfile), + .def.s = "127.0.0.1", + }, + {.type = PT_INT, + .id = "port", + .name = N_("Listen / Connect port"), + .desc = N_("Port to listen on or to connect to."), + .off = offsetof(capmt_t, capmt_port), + .def.i = 9000}, + { + .type = PT_INT, + .id = "cwmode", + .name = N_("CW Mode"), + .desc = N_("CryptoWord mode."), + .off = offsetof(capmt_t, capmt_cwmode), + .list = caclient_capmt_class_cwmode_list, + .def.i = CAPMT_CWMODE_AUTO, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_INT, + .id = "pmtmode", + .name = N_("PMT Mode"), + .desc = N_("PMT mode."), + .off = offsetof(capmt_t, capmt_pmtmode), + .list = caclient_capmt_class_pmtmode_list, + .def.i = CAPMT_PMTMODE_AUTO, + .opts = PO_DOC_NLIST, + }, + {}}}; /* * */ -caclient_t *capmt_create(void) -{ - capmt_t *capmt = calloc(1, sizeof(*capmt)); +caclient_t* capmt_create(void) { + capmt_t* capmt = calloc(1, sizeof(*capmt)); capmt->capmt_pmtversion = 1; @@ -2778,5 +2853,5 @@ caclient_t *capmt_create(void) capmt->cac_start = capmt_service_start; capmt->cac_conf_changed = capmt_conf_changed; - return (caclient_t *)capmt; + return (caclient_t*)capmt; } diff --git a/src/descrambler/cccam.c b/src/descrambler/cccam.c index f9a3230ed..32b1d4853 100644 --- a/src/descrambler/cccam.c +++ b/src/descrambler/cccam.c @@ -26,9 +26,8 @@ /** * */ -#define CCCAM_KEEPALIVE_INTERVAL 0 -#define CCCAM_NETMSGSIZE 1024 - +#define CCCAM_KEEPALIVE_INTERVAL 0 +#define CCCAM_NETMSGSIZE 1024 typedef enum { MSG_CLI_DATA, // client -> server @@ -36,24 +35,24 @@ typedef enum { MSG_EMM_REQUEST, // client -> server MSG_CARD_REMOVED = 4, // server -> client MSG_CMD_05, - MSG_KEEPALIVE, // client -> server - MSG_NEW_CARD, // server -> client - MSG_SRV_DATA, // server -> client - MSG_CMD_0A = 0x0a, - MSG_CMD_0B = 0x0b, - MSG_CMD_0C = 0x0c, // CCcam 2.2.x fake client checks - MSG_CMD_0D = 0x0d, // " - MSG_CMD_0E = 0x0e, // " + MSG_KEEPALIVE, // client -> server + MSG_NEW_CARD, // server -> client + MSG_SRV_DATA, // server -> client + MSG_CMD_0A = 0x0a, + MSG_CMD_0B = 0x0b, + MSG_CMD_0C = 0x0c, // CCcam 2.2.x fake client checks + MSG_CMD_0D = 0x0d, // " + MSG_CMD_0E = 0x0e, // " MSG_NEW_CARD_SIDINFO = 0x0f, - MSG_SLEEPSEND = 0x80, // Sleepsend support - MSG_ECM_NOK1 = 0xfe, // server -> client ecm queue full, card not found - MSG_ECM_NOK2 = 0xff, // server -> client - MSG_NO_HEADER = 0xffff + MSG_SLEEPSEND = 0x80, // Sleepsend support + MSG_ECM_NOK1 = 0xfe, // server -> client ecm queue full, card not found + MSG_ECM_NOK2 = 0xff, // server -> client + MSG_NO_HEADER = 0xffff } cccam_msg_type_t; typedef enum { CCCAM_EXTENDED_NONE = 0, - CCCAM_EXTENDED_EXT = 1, + CCCAM_EXTENDED_EXT = 1, } cccam_extended_t; typedef enum { @@ -68,14 +67,26 @@ typedef enum { CCCAM_VERSION_COUNT, } cccam_version_t; -static const char *cccam_version_str[CCCAM_VERSION_COUNT] = { - "2.0.11", "2.1.1", "2.1.2", "2.1.3", - "2.1.4", "2.2.0", "2.2.1", "2.3.0", +static const char* cccam_version_str[CCCAM_VERSION_COUNT] = { + "2.0.11", + "2.1.1", + "2.1.2", + "2.1.3", + "2.1.4", + "2.2.0", + "2.2.1", + "2.3.0", }; -static const char *cccam_build_str[CCCAM_VERSION_COUNT] = { - "2892", "2971", "3094", "3165", - "3191", "3290", "3316", "3367", +static const char* cccam_build_str[CCCAM_VERSION_COUNT] = { + "2892", + "2971", + "3094", + "3165", + "3191", + "3290", + "3316", + "3367", }; /** @@ -96,9 +107,9 @@ typedef struct cccam { /* From configuration */ uint8_t cccam_nodeid[8]; - int cccam_extended_conf; - int cccam_extended; - int cccam_version; + int cccam_extended_conf; + int cccam_extended; + int cccam_version; uint8_t cccam_oscam; uint8_t cccam_sendsleep; @@ -111,16 +122,14 @@ typedef struct cccam { } cccam_t; - static const uint8_t cccam_str[] = "CCcam"; -static void cccam_send_oscam_extended(cccam_t *cccam); +static void cccam_send_oscam_extended(cccam_t* cccam); /** * */ -static inline const char *cccam_get_version_str(cccam_t *cccam) -{ +static inline const char* cccam_get_version_str(cccam_t* cccam) { int ver = MINMAX(cccam->cccam_version, 0, ARRAY_SIZE(cccam_version_str) - 1); return cccam_version_str[ver]; } @@ -128,8 +137,7 @@ static inline const char *cccam_get_version_str(cccam_t *cccam) /** * */ -static inline const char *cccam_get_build_str(cccam_t *cccam) -{ +static inline const char* cccam_get_build_str(cccam_t* cccam) { int ver = MINMAX(cccam->cccam_version, 0, ARRAY_SIZE(cccam_version_str) - 1); return cccam_build_str[ver]; } @@ -137,8 +145,7 @@ static inline const char *cccam_get_build_str(cccam_t *cccam) /** * */ -static inline int cccam_set_busy(cccam_t *cccam) -{ +static inline int cccam_set_busy(cccam_t* cccam) { if (cccam->cccam_extended) return 0; if (cccam->cccam_busy) @@ -150,26 +157,23 @@ static inline int cccam_set_busy(cccam_t *cccam) /** * */ -static inline void cccam_unset_busy(cccam_t *cccam) -{ +static inline void cccam_unset_busy(cccam_t* cccam) { cccam->cccam_busy = 0; } /** * */ -static inline void -uint8_swap(uint8_t *p1, uint8_t *p2) -{ - uint8_t tmp = *p1; *p1 = *p2; *p2 = tmp; +static inline void uint8_swap(uint8_t* p1, uint8_t* p2) { + uint8_t tmp = *p1; + *p1 = *p2; + *p2 = tmp; } /** * */ -static void -cccam_crypt_xor(uint8_t *buf) -{ +static void cccam_crypt_xor(uint8_t* buf) { uint8_t i; for (i = 0; i < 8; i++) { @@ -182,11 +186,9 @@ cccam_crypt_xor(uint8_t *buf) /** * */ -static void -cccam_crypt_init(struct cccam_crypt_block *block, uint8_t *key, int32_t len) -{ +static void cccam_crypt_init(struct cccam_crypt_block* block, uint8_t* key, int32_t len) { uint32_t i = 0; - uint8_t j = 0; + uint8_t j = 0; for (i = 0; i < 256; i++) { block->keytable[i] = i; @@ -195,17 +197,15 @@ cccam_crypt_init(struct cccam_crypt_block *block, uint8_t *key, int32_t len) j += key[i % len] + block->keytable[i]; uint8_swap(&block->keytable[i], &block->keytable[j]); } - block->state = *key; + block->state = *key; block->counter = 0; - block->sum = 0; + block->sum = 0; } /** * */ -static void -cccam_decrypt(struct cccam_crypt_block *block, uint8_t *data, int32_t len) -{ +static void cccam_decrypt(struct cccam_crypt_block* block, uint8_t* data, int32_t len) { int32_t i; uint8_t z; @@ -213,9 +213,10 @@ cccam_decrypt(struct cccam_crypt_block *block, uint8_t *data, int32_t len) block->counter++; block->sum += block->keytable[block->counter]; uint8_swap(&block->keytable[block->counter], &block->keytable[block->sum]); - z = data[i]; - data[i] = z ^ block->keytable[(block->keytable[block->counter] + - block->keytable[block->sum]) & 0xff] ^ block->state; + z = data[i]; + data[i] = z ^ + block->keytable[(block->keytable[block->counter] + block->keytable[block->sum]) & 0xff] ^ + block->state; z = data[i]; block->state ^= z; } @@ -224,27 +225,24 @@ cccam_decrypt(struct cccam_crypt_block *block, uint8_t *data, int32_t len) /** * */ -static void -cccam_encrypt(struct cccam_crypt_block *block, uint8_t *data, int32_t len) -{ +static void cccam_encrypt(struct cccam_crypt_block* block, uint8_t* data, int32_t len) { int32_t i; uint8_t z; for (i = 0; i < len; i++) { block->counter++; block->sum += block->keytable[block->counter]; uint8_swap(&block->keytable[block->counter], &block->keytable[block->sum]); - z = data[i]; - data[i] = z ^ block->keytable[(block->keytable[block->counter] + - block->keytable[block->sum]) & 0xff] ^ block->state; + z = data[i]; + data[i] = z ^ + block->keytable[(block->keytable[block->counter] + block->keytable[block->sum]) & 0xff] ^ + block->state; block->state ^= z; } } -static void -cccam_decrypt_cw(uint8_t *nodeid, uint32_t card_id, uint8_t *cws) -{ - uint8_t tmp, i; - uint64_t node_id = be64toh(*((uint64_t *) nodeid)); +static void cccam_decrypt_cw(uint8_t* nodeid, uint32_t card_id, uint8_t* cws) { + uint8_t tmp, i; + uint64_t node_id = be64toh(*((uint64_t*)nodeid)); for (i = 0; i < 16; i++) { tmp = cws[i] ^ (node_id >> (4 * i)); @@ -257,17 +255,18 @@ cccam_decrypt_cw(uint8_t *nodeid, uint32_t card_id, uint8_t *cws) /** * */ -static int -cccam_oscam_check(cccam_t *cccam, uint8_t *buf) -{ +static int cccam_oscam_check(cccam_t* cccam, uint8_t* buf) { if (!cccam->cccam_oscam) { - uint16_t sum = 0x1234; + uint16_t sum = 0x1234; uint16_t recv_sum = (buf[14] << 8) | buf[15]; - int32_t i; + int32_t i; for (i = 0; i < 14; i++) sum += buf[i]; - tvhtrace(cccam->cc_subsys, "%s: oscam check sum %04X recv sum %04X", - cccam->cc_name, sum, recv_sum); + tvhtrace(cccam->cc_subsys, + "%s: oscam check sum %04X recv sum %04X", + cccam->cc_name, + sum, + recv_sum); cccam->cccam_oscam = sum == recv_sum; if (cccam->cccam_oscam) tvhinfo(cccam->cc_subsys, "%s: oscam server detected", cccam->cc_name); @@ -278,17 +277,18 @@ cccam_oscam_check(cccam_t *cccam, uint8_t *buf) /** * */ -static int -cccam_oscam_nodeid_check(cccam_t *cccam, uint8_t *buf) -{ +static int cccam_oscam_nodeid_check(cccam_t* cccam, uint8_t* buf) { if (!cccam->cccam_oscam) { - uint16_t sum = 0x1234; + uint16_t sum = 0x1234; uint16_t recv_sum = (buf[6] << 8) | buf[7]; - int32_t i; + int32_t i; for (i = 0; i < 6; i++) sum += buf[i]; - tvhtrace(cccam->cc_subsys, "%s: oscam nodeid check sum %04X recv sum %04X", - cccam->cc_name, sum, recv_sum); + tvhtrace(cccam->cc_subsys, + "%s: oscam nodeid check sum %04X recv sum %04X", + cccam->cc_name, + sum, + recv_sum); cccam->cccam_oscam = sum == recv_sum; if (cccam->cccam_oscam) tvhinfo(cccam->cc_subsys, "%s: oscam server detected", cccam->cc_name); @@ -299,9 +299,7 @@ cccam_oscam_nodeid_check(cccam_t *cccam, uint8_t *buf) /** * */ -static inline uint8_t * -cccam_set_ua(uint8_t *dst, uint8_t *src) -{ +static inline uint8_t* cccam_set_ua(uint8_t* dst, uint8_t* src) { /* FIXME */ return memcpy(dst, src, 8); } @@ -309,28 +307,24 @@ cccam_set_ua(uint8_t *dst, uint8_t *src) /** * */ -static inline uint8_t * -cccam_set_sa(uint8_t *dst, uint8_t *src) -{ +static inline uint8_t* cccam_set_sa(uint8_t* dst, uint8_t* src) { return memcpy(dst, src, 4); } /** * Handle reply to card data request */ -static int -cccam_decode_card_data_reply(cccam_t *cccam, uint8_t *msg) -{ - cc_card_data_t *pcard; - int i; - unsigned int nprov; - uint8_t **pid, **psa, *saa, *msg2, ua[8]; +static int cccam_decode_card_data_reply(cccam_t* cccam, uint8_t* msg) { + cc_card_data_t* pcard; + int i; + unsigned int nprov; + uint8_t ** pid, **psa, *saa, *msg2, ua[8]; /* nr of providers */ nprov = msg[24]; - pid = nprov ? alloca(nprov * sizeof(uint8_t *)) : NULL; - psa = nprov ? alloca(nprov * sizeof(uint8_t *)) : NULL; + pid = nprov ? alloca(nprov * sizeof(uint8_t*)) : NULL; + psa = nprov ? alloca(nprov * sizeof(uint8_t*)) : NULL; saa = nprov ? alloca(nprov * 8) : NULL; if (pid == NULL || psa == NULL || saa == NULL) @@ -344,15 +338,20 @@ cccam_decode_card_data_reply(cccam_t *cccam, uint8_t *msg) msg2 += 7; } - caclient_set_status((caclient_t *)cccam, CACLIENT_STATUS_CONNECTED); + caclient_set_status((caclient_t*)cccam, CACLIENT_STATUS_CONNECTED); cccam_set_ua(ua, msg + 16); - pcard = cc_new_card((cclient_t *)cccam, (msg[12] << 8) | msg[13], - (msg[4] << 24) | (msg[5] << 16) | (msg[6] << 8) | msg[7], - ua, nprov, pid, psa, 0); + pcard = cc_new_card((cclient_t*)cccam, + (msg[12] << 8) | msg[13], + (msg[4] << 24) | (msg[5] << 16) | (msg[6] << 8) | msg[7], + ua, + nprov, + pid, + psa, + 0); if (pcard) { pcard->cccam.cs_remote_id = (msg[8] << 24) | (msg[9] << 16) | (msg[10] << 8) | msg[11]; - pcard->cccam.cs_hop = msg[14]; - pcard->cccam.cs_reshare = msg[15]; + pcard->cccam.cs_hop = msg[14]; + pcard->cccam.cs_reshare = msg[15]; } return 0; @@ -361,10 +360,12 @@ cccam_decode_card_data_reply(cccam_t *cccam, uint8_t *msg) /** * */ -static void -cccam_handle_keys(cccam_t *cccam, cc_service_t *ct, cc_ecm_section_t *es, - uint8_t *buf, int len, int seq) -{ +static void cccam_handle_keys(cccam_t* cccam, + cc_service_t* ct, + cc_ecm_section_t* es, + uint8_t* buf, + int len, + int seq) { uint8_t *dcw_even, *dcw_odd, _dcw[16]; if (buf[1] == MSG_ECM_REQUEST) { @@ -388,12 +389,10 @@ cccam_handle_keys(cccam_t *cccam, cc_service_t *ct, cc_ecm_section_t *es, /** * */ -static void -cccam_handle_partner(cccam_t *cccam, uint8_t *msg) -{ - char *saveptr; - char *p; - p = strtok_r((char *)msg, "[", &saveptr); +static void cccam_handle_partner(cccam_t* cccam, uint8_t* msg) { + char* saveptr; + char* p; + p = strtok_r((char*)msg, "[", &saveptr); while (p) { if ((p = strtok_r(NULL, ",]", &saveptr)) == NULL) break; @@ -404,30 +403,28 @@ cccam_handle_partner(cccam_t *cccam, uint8_t *msg) else if (strncmp(p, "SLP", 3) == 0) cccam->cccam_sendsleep = 1; } - tvhinfo(cccam->cc_subsys, "%s: server supports extended capabilities%s%s%s", - cccam->cc_name, - cccam->cccam_extended ? " EXT" : "", - cccam->cccam_cansid ? " SID" : "", - cccam->cccam_sendsleep ? " SLP" : ""); + tvhinfo(cccam->cc_subsys, + "%s: server supports extended capabilities%s%s%s", + cccam->cc_name, + cccam->cccam_extended ? " EXT" : "", + cccam->cccam_cansid ? " SID" : "", + cccam->cccam_sendsleep ? " SLP" : ""); } /** * Handle running reply * cc_mutex is held */ -static int -cccam_running_reply(cccam_t *cccam, uint8_t *buf, int len) -{ - cc_service_t *ct; - cc_ecm_section_t *es; - uint32_t cardid; - uint8_t seq; +static int cccam_running_reply(cccam_t* cccam, uint8_t* buf, int len) { + cc_service_t* ct; + cc_ecm_section_t* es; + uint32_t cardid; + uint8_t seq; if (len < 4) return -1; - tvhtrace(cccam->cc_subsys, "%s: response msg type=%d, response", - cccam->cc_name, buf[1]); + tvhtrace(cccam->cc_subsys, "%s: response msg type=%d, response", cccam->cc_name, buf[1]); tvhlog_hexdump(cccam->cc_subsys, buf, len); switch (buf[1]) { @@ -440,37 +437,39 @@ cccam_running_reply(cccam_t *cccam, uint8_t *buf, int len) if (len >= 8) { cardid = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7]; tvhtrace(cccam->cc_subsys, "%s: del card %08X message received", cccam->cc_name, cardid); - cc_remove_card_by_id((cclient_t *)cccam, cardid); + cc_remove_card_by_id((cclient_t*)cccam, cardid); } break; case MSG_KEEPALIVE: tvhtrace(cccam->cc_subsys, "%s: keepalive", cccam->cc_name); break; - case MSG_EMM_REQUEST: /* emm ack */ + case MSG_EMM_REQUEST: /* emm ack */ tvhtrace(cccam->cc_subsys, "%s: EMM message ACK received", cccam->cc_name); cccam_unset_busy(cccam); break; case MSG_SLEEPSEND: tvhtrace(cccam->cc_subsys, "%s: Sleep send received", cccam->cc_name); - if (len >= 5) goto req; + if (len >= 5) + goto req; break; - case MSG_ECM_NOK1: /* retry */ - case MSG_ECM_NOK2: /* decode failed */ - if (len >= 2 && len < 8) goto req; + case MSG_ECM_NOK1: /* retry */ + case MSG_ECM_NOK2: /* decode failed */ + if (len >= 2 && len < 8) + goto req; if (len > 5) { /* partner detection */ - if (len >= 12 && strncmp((char *)buf + 4, "PARTNER:", 8) == 0) { + if (len >= 12 && strncmp((char*)buf + 4, "PARTNER:", 8) == 0) { cccam_handle_partner(cccam, buf + 4); } else { goto req; } } break; - //case MSG_CMD_05: /* ? */ + // case MSG_CMD_05: /* ? */ case MSG_ECM_REQUEST: { /* request reply */ -req: + req: seq = cccam->cccam_extended ? buf[0] : 1; - es = cc_find_pending_section((cclient_t *)cccam, seq, &ct); + es = cc_find_pending_section((cclient_t*)cccam, seq, &ct); if (es) cccam_handle_keys(cccam, ct, es, buf, len, seq); cccam_unset_busy(cccam); @@ -479,23 +478,28 @@ req: case MSG_SRV_DATA: if (len == 0x4c) { tvhinfo(cccam->cc_subsys, - "%s: CCcam server version %s nodeid=%02x%02x%02x%02x%02x%02x%02x%02x", - cccam->cc_name, buf + 12, - buf[4], buf[5], buf[6], buf[7], buf[8], buf[9], buf[10], buf[11]); + "%s: CCcam server version %s nodeid=%02x%02x%02x%02x%02x%02x%02x%02x", + cccam->cc_name, + buf + 12, + buf[4], + buf[5], + buf[6], + buf[7], + buf[8], + buf[9], + buf[10], + buf[11]); if (cccam_oscam_nodeid_check(cccam, buf + 4)) cccam_send_oscam_extended(cccam); } else { - tvhtrace(cccam->cc_subsys, "%s: SRV_DATA: unknown length %d", - cccam->cc_name, len); + tvhtrace(cccam->cc_subsys, "%s: SRV_DATA: unknown length %d", cccam->cc_name, len); } break; case MSG_CLI_DATA: - tvhinfo(cccam->cc_subsys, "%s: CCcam server authentication completed", - cccam->cc_name); + tvhinfo(cccam->cc_subsys, "%s: CCcam server authentication completed", cccam->cc_name); break; default: - tvhwarn(cccam->cc_subsys, "%s: Unknown message received", - cccam->cc_name); + tvhwarn(cccam->cc_subsys, "%s: Unknown message received", cccam->cc_name); break; } return 0; @@ -504,11 +508,9 @@ req: /** * */ -static int -cccam_read_message0(cccam_t *cccam, const char *state, sbuf_t *rbuf, int timeout) -{ - uint16_t msglen; - uint8_t hdr[4]; +static int cccam_read_message0(cccam_t* cccam, const char* state, sbuf_t* rbuf, int timeout) { + uint16_t msglen; + uint8_t hdr[4]; struct cccam_crypt_block block; if (rbuf->sb_ptr < 4) @@ -530,13 +532,15 @@ cccam_read_message0(cccam_t *cccam, const char *state, sbuf_t *rbuf, int timeout /** * */ -static int -cccam_send_msg(cccam_t *cccam, cccam_msg_type_t cmd, - uint8_t *buf, size_t len, int enq, - uint8_t seq, uint32_t card_id) -{ - cc_message_t *cm; - uint8_t *netbuf; +static int cccam_send_msg(cccam_t* cccam, + cccam_msg_type_t cmd, + uint8_t* buf, + size_t len, + int enq, + uint8_t seq, + uint32_t card_id) { + cc_message_t* cm; + uint8_t* netbuf; if (len + 4 > CCCAM_NETMSGSIZE) return -1; @@ -560,7 +564,7 @@ cccam_send_msg(cccam_t *cccam, cccam_msg_type_t cmd, cccam_encrypt(&cccam->sendblock, cm->cm_data, len); cm->cm_len = len; - cc_write_message((cclient_t *)cccam, cm, enq); + cc_write_message((cclient_t*)cccam, cm, enq); return 0; } @@ -568,11 +572,9 @@ cccam_send_msg(cccam_t *cccam, cccam_msg_type_t cmd, /** * Send keep alive */ -static void -cccam_send_ka(void *cc) -{ - cccam_t *cccam = cc; - uint8_t buf[4]; +static void cccam_send_ka(void* cc) { + cccam_t* cccam = cc; + uint8_t buf[4]; buf[0] = 0; buf[1] = MSG_KEEPALIVE; @@ -586,23 +588,22 @@ cccam_send_ka(void *cc) /** * Send keep alive */ -static void -cccam_send_oscam_extended(cccam_t *cccam) -{ +static void cccam_send_oscam_extended(cccam_t* cccam) { char buf[256]; tvhdebug(cccam->cc_subsys, "%s: send oscam extended", cccam->cc_name); - snprintf(buf, sizeof(buf), "PARTNER: OSCam v%s, build r%s (%s) [EXT,SID,SLP]", - cccam_get_version_str(cccam), cccam_get_build_str(cccam), - "unknown"); - cccam_send_msg(cccam, MSG_ECM_NOK1, (uint8_t *)buf, strlen(buf) + 1, 1, 0, 0); + snprintf(buf, + sizeof(buf), + "PARTNER: OSCam v%s, build r%s (%s) [EXT,SID,SLP]", + cccam_get_version_str(cccam), + cccam_get_build_str(cccam), + "unknown"); + cccam_send_msg(cccam, MSG_ECM_NOK1, (uint8_t*)buf, strlen(buf) + 1, 1, 0, 0); } /** * */ -static void -sha1_make_login_key(cccam_t *cccam, uint8_t *buf) -{ +static void sha1_make_login_key(cccam_t* cccam, uint8_t* buf) { SHA_CTX sha1; uint8_t hash[SHA_DIGEST_LENGTH]; @@ -628,11 +629,9 @@ sha1_make_login_key(cccam_t *cccam, uint8_t *buf) /** * Login command */ -static int -cccam_send_login(cccam_t *cccam) -{ +static int cccam_send_login(cccam_t* cccam) { uint8_t buf[20], data[20], *pwd; - size_t l; + size_t l; if (cccam->cc_username == NULL) return 1; @@ -648,15 +647,15 @@ cccam_send_login(cccam_t *cccam) memcpy(buf, cccam_str, 5); buf[5] = 0; if (cccam->cc_password && cccam->cc_password[0]) { - l = strlen(cccam->cc_password); + l = strlen(cccam->cc_password); pwd = alloca(l + 1); - strcpy((char *)pwd, cccam->cc_password); + strcpy((char*)pwd, cccam->cc_password); cccam_encrypt(&cccam->sendblock, pwd, l); } cccam_send_msg(cccam, MSG_NO_HEADER, buf, 6, 0, 0, 0); tvhdebug(cccam->cc_subsys, "%s: login response", cccam->cc_name); - if (cc_read((cclient_t *)cccam, data, 20, 5000)) { + if (cc_read((cclient_t*)cccam, data, 20, 5000)) { tvherror(cccam->cc_subsys, "%s: login failed, pwd ack not received", cccam->cc_name); return -2; } @@ -675,17 +674,15 @@ cccam_send_login(cccam_t *cccam) /** * */ -static void -cccam_send_cli_data(cccam_t *cccam) -{ +static void cccam_send_cli_data(cccam_t* cccam) { const int32_t size = 20 + 8 + 6 + 26 + 4 + 28 + 1; - uint8_t buf[size]; + uint8_t buf[size]; memset(buf, 0, sizeof(buf)); - strncpy((char *)buf, cccam->cc_username ?: "", 20); + strncpy((char*)buf, cccam->cc_username ?: "", 20); memcpy(buf + 20, cccam->cccam_nodeid, 8); buf[28] = 0; // TODO: wantemus = 1; - strncpy((char *)buf + 29, cccam_get_version_str(cccam), 31); + strncpy((char*)buf + 29, cccam_get_version_str(cccam), 31); memcpy(buf + 61, "tvh", 3); // build number (ascii) cccam_send_msg(cccam, MSG_CLI_DATA, buf, size, 0, 0, 0); } @@ -693,12 +690,10 @@ cccam_send_cli_data(cccam_t *cccam) /** * */ -static void -cccam_oscam_update_idnode(cccam_t *cccam) -{ - uint8_t p[8]; +static void cccam_oscam_update_idnode(cccam_t* cccam) { + uint8_t p[8]; uint16_t sum = 0x1234; - int32_t i; + int32_t i; memcpy(p, cccam->cccam_nodeid, 4); p[4] = 'T'; /* identify ourselves as TVH */ @@ -715,23 +710,21 @@ cccam_oscam_update_idnode(cccam_t *cccam) /** * */ -static int -cccam_init_session(void *cc) -{ - cccam_t *cccam = cc; - uint8_t buf[256]; - int r; - - cccam->cccam_oscam = 0; - cccam->cccam_extended = 0; +static int cccam_init_session(void* cc) { + cccam_t* cccam = cc; + uint8_t buf[256]; + int r; + + cccam->cccam_oscam = 0; + cccam->cccam_extended = 0; cccam->cccam_sendsleep = 0; - cccam->cccam_cansid = 0; + cccam->cccam_cansid = 0; /** * Get init seed */ tvhtrace(cccam->cc_subsys, "%s: init seed", cccam->cc_name); - if((r = cc_read(cc, buf, 16, 5000))) { + if ((r = cc_read(cc, buf, 16, 5000))) { tvhinfo(cccam->cc_subsys, "%s: init error (no init seed received)", cccam->cc_name); return -1; } @@ -755,16 +748,18 @@ cccam_init_session(void *cc) /** * */ -static int -cccam_send_ecm(void *cc, cc_service_t *ct, cc_ecm_section_t *es, - cc_card_data_t *pcard, const uint8_t *msg, int len) -{ - mpegts_service_t *t = (mpegts_service_t *)ct->td_service; - cccam_t *cccam = cc; - uint8_t *buf; - uint16_t caid, sid; - uint32_t provid, card_id; - int seq; +static int cccam_send_ecm(void* cc, + cc_service_t* ct, + cc_ecm_section_t* es, + cc_card_data_t* pcard, + const uint8_t* msg, + int len) { + mpegts_service_t* t = (mpegts_service_t*)ct->td_service; + cccam_t* cccam = cc; + uint8_t* buf; + uint16_t caid, sid; + uint32_t provid, card_id; + int seq; if (len > 255) { tvherror(cccam->cc_subsys, "%s: ECM too big (%d bytes)", cccam->cc_name, len); @@ -772,30 +767,32 @@ cccam_send_ecm(void *cc, cc_service_t *ct, cc_ecm_section_t *es, } if (cccam_set_busy(cccam)) { - tvhinfo(cccam->cc_subsys, "%s: Ignore ECM request %02X (server is busy)", - cccam->cc_name, msg[0]); + tvhinfo(cccam->cc_subsys, + "%s: Ignore ECM request %02X (server is busy)", + cccam->cc_name, + msg[0]); return -1; } - seq = atomic_add(&cccam->cc_seq, 1); - caid = es->es_caid; - provid = es->es_provid; - card_id = pcard->cs_id; + seq = atomic_add(&cccam->cc_seq, 1); + caid = es->es_caid; + provid = es->es_provid; + card_id = pcard->cs_id; es->es_card_id = card_id; - sid = service_id16(t); - es->es_seq = seq & 0xff; - - buf = alloca(len + 13); - buf[ 0] = caid >> 8; - buf[ 1] = caid & 0xff; - buf[ 2] = provid >> 24; - buf[ 3] = provid >> 16; - buf[ 4] = provid >> 8; - buf[ 5] = provid & 0xff; - buf[ 6] = card_id >> 24; - buf[ 7] = card_id >> 16; - buf[ 8] = card_id >> 8; - buf[ 9] = card_id & 0xff; + sid = service_id16(t); + es->es_seq = seq & 0xff; + + buf = alloca(len + 13); + buf[0] = caid >> 8; + buf[1] = caid & 0xff; + buf[2] = provid >> 24; + buf[3] = provid >> 16; + buf[4] = provid >> 8; + buf[5] = provid & 0xff; + buf[6] = card_id >> 24; + buf[7] = card_id >> 16; + buf[8] = card_id >> 8; + buf[9] = card_id & 0xff; buf[10] = sid >> 8; buf[11] = sid & 0xff; buf[12] = len; @@ -807,43 +804,46 @@ cccam_send_ecm(void *cc, cc_service_t *ct, cc_ecm_section_t *es, /** * */ -static void -cccam_send_emm(void *cc, cc_service_t *ct, cc_card_data_t *pcard, - uint32_t provid, const uint8_t *msg, int len) -{ - cccam_t *cccam = cc; - uint8_t *buf; +static void cccam_send_emm(void* cc, + cc_service_t* ct, + cc_card_data_t* pcard, + uint32_t provid, + const uint8_t* msg, + int len) { + cccam_t* cccam = cc; + uint8_t* buf; uint16_t caid; uint32_t card_id; - int seq; + int seq; if (len > 255) { - tvherror(cccam->cc_subsys, "%s: EMM too big (%d bytes)", - cccam->cc_name, len); + tvherror(cccam->cc_subsys, "%s: EMM too big (%d bytes)", cccam->cc_name, len); return; } if (cccam_set_busy(cccam)) { - tvhinfo(cccam->cc_subsys, "%s: Ignore EMM request %02X (server is busy)", - cccam->cc_name, msg[0]); + tvhinfo(cccam->cc_subsys, + "%s: Ignore EMM request %02X (server is busy)", + cccam->cc_name, + msg[0]); return; } - seq = atomic_add(&cccam->cc_seq, 1); - caid = pcard->cs_ra.caid; + seq = atomic_add(&cccam->cc_seq, 1); + caid = pcard->cs_ra.caid; card_id = pcard->cs_id; - buf = alloca(len + 12); - buf[ 0] = caid >> 8; - buf[ 1] = caid & 0xff; - buf[ 2] = 0; - buf[ 3] = provid >> 24; - buf[ 4] = provid >> 16; - buf[ 5] = provid >> 8; - buf[ 6] = provid & 0xff; - buf[ 7] = card_id >> 24; - buf[ 8] = card_id >> 16; - buf[ 9] = card_id >> 8; + buf = alloca(len + 12); + buf[0] = caid >> 8; + buf[1] = caid & 0xff; + buf[2] = 0; + buf[3] = provid >> 24; + buf[4] = provid >> 16; + buf[5] = provid >> 8; + buf[6] = provid & 0xff; + buf[7] = card_id >> 24; + buf[8] = card_id >> 16; + buf[9] = card_id >> 8; buf[10] = card_id & 0xff; buf[11] = len; memcpy(buf + 12, msg, len); @@ -856,12 +856,10 @@ cccam_send_emm(void *cc, cc_service_t *ct, cc_card_data_t *pcard, /** * */ -static int -cccam_read(void *cc, sbuf_t *rbuf) -{ - cccam_t *cccam = cc; +static int cccam_read(void* cc, sbuf_t* rbuf) { + cccam_t* cccam = cc; const int ka_interval = cccam->cc_keepalive_interval * 2 * 1000; - int r; + int r; while (1) { r = cccam_read_message0(cccam, "Decoderloop", rbuf, ka_interval); @@ -882,19 +880,15 @@ cccam_read(void *cc, sbuf_t *rbuf) /** * */ -static void -cccam_no_services(void *cc) -{ - cccam_unset_busy((cccam_t *)cc); +static void cccam_no_services(void* cc) { + cccam_unset_busy((cccam_t*)cc); } /** * */ -static void -cccam_conf_changed(caclient_t *cac) -{ - cccam_t *cccam = (cccam_t *)cac; +static void cccam_conf_changed(caclient_t* cac) { + cccam_t* cccam = (cccam_t*)cac; /** * Update nodeid for the oscam extended mode @@ -907,42 +901,40 @@ cccam_conf_changed(caclient_t *cac) /** * */ -static int -nibble(char c) -{ - switch(c) { - case '0' ... '9': - return c - '0'; - case 'a' ... 'f': - return c - 'a' + 10; - case 'A' ... 'F': - return c - 'A' + 10; - default: - return 0; +static int nibble(char c) { + switch (c) { + case '0' ... '9': + return c - '0'; + case 'a' ... 'f': + return c - 'a' + 10; + case 'A' ... 'F': + return c - 'A' + 10; + default: + return 0; } } /** * */ -static int -caclient_cccam_nodeid_set(void *o, const void *v) -{ - cccam_t *cccam = o; - const char *s = v ?: ""; - uint8_t key[8]; - int i, u, l; - uint64_t node_id; - - for(i = 0; i < ARRAY_SIZE(key); i++) { - while(*s != 0 && !isxdigit(*s)) s++; +static int caclient_cccam_nodeid_set(void* o, const void* v) { + cccam_t* cccam = o; + const char* s = v ?: ""; + uint8_t key[8]; + int i, u, l; + uint64_t node_id; + + for (i = 0; i < ARRAY_SIZE(key); i++) { + while (*s != 0 && !isxdigit(*s)) + s++; u = *s ? nibble(*s++) : 0; - while(*s != 0 && !isxdigit(*s)) s++; - l = *s ? nibble(*s++) : 0; + while (*s != 0 && !isxdigit(*s)) + s++; + l = *s ? nibble(*s++) : 0; key[i] = (u << 4) | l; } - node_id = be64toh(*((uint64_t*) key)); + node_id = be64toh(*((uint64_t*)key)); if (!node_id) uuid_random(key, 8); @@ -951,122 +943,112 @@ caclient_cccam_nodeid_set(void *o, const void *v) return i; } -static const void * -caclient_cccam_nodeid_get(void *o) -{ - cccam_t *cccam = o; - snprintf(prop_sbuf, PROP_SBUF_LEN, - "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - cccam->cccam_nodeid[0x0], - cccam->cccam_nodeid[0x1], - cccam->cccam_nodeid[0x2], - cccam->cccam_nodeid[0x3], - cccam->cccam_nodeid[0x4], - cccam->cccam_nodeid[0x5], - cccam->cccam_nodeid[0x6], - cccam->cccam_nodeid[0x7]); +static const void* caclient_cccam_nodeid_get(void* o) { + cccam_t* cccam = o; + snprintf(prop_sbuf, + PROP_SBUF_LEN, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + cccam->cccam_nodeid[0x0], + cccam->cccam_nodeid[0x1], + cccam->cccam_nodeid[0x2], + cccam->cccam_nodeid[0x3], + cccam->cccam_nodeid[0x4], + cccam->cccam_nodeid[0x5], + cccam->cccam_nodeid[0x6], + cccam->cccam_nodeid[0x7]); return &prop_sbuf_ptr; } -static htsmsg_t * -caclient_cccam_class_cccam_extended_list ( void *o, const char *lang ) -{ +static htsmsg_t* caclient_cccam_class_cccam_extended_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("None"), CCCAM_EXTENDED_NONE }, - { N_("Oscam-EXT"), CCCAM_EXTENDED_EXT }, + {N_("None"), CCCAM_EXTENDED_NONE}, + {N_("Oscam-EXT"), CCCAM_EXTENDED_EXT}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -caclient_cccam_class_cccam_version_list ( void *o, const char *lang ) -{ +static htsmsg_t* caclient_cccam_class_cccam_version_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("2.0.11"), CCCAM_VERSION_2_0_11 }, - { N_("2.1.1"), CCCAM_VERSION_2_1_1 }, - { N_("2.1.2"), CCCAM_VERSION_2_1_2 }, - { N_("2.1.3"), CCCAM_VERSION_2_1_3 }, - { N_("2.1.4"), CCCAM_VERSION_2_1_4 }, - { N_("2.2.0"), CCCAM_VERSION_2_2_0 }, - { N_("2.2.1"), CCCAM_VERSION_2_2_1 }, - { N_("2.3.0"), CCCAM_VERSION_2_3_0 }, + {N_("2.0.11"), CCCAM_VERSION_2_0_11}, + {N_("2.1.1"), CCCAM_VERSION_2_1_1}, + {N_("2.1.2"), CCCAM_VERSION_2_1_2}, + {N_("2.1.3"), CCCAM_VERSION_2_1_3}, + {N_("2.1.4"), CCCAM_VERSION_2_1_4}, + {N_("2.2.0"), CCCAM_VERSION_2_2_0}, + {N_("2.2.1"), CCCAM_VERSION_2_2_1}, + {N_("2.3.0"), CCCAM_VERSION_2_3_0}, }; return strtab2htsmsg(tab, 1, lang); } -const idclass_t caclient_cccam_class = -{ - .ic_super = &caclient_cc_class, - .ic_class = "caclient_cccam", - .ic_caption = N_("CCcam"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "nodeid", - .name = N_("Node ID"), - .desc = N_("Client node ID. Leave field empty to generate a random ID."), - .set = caclient_cccam_nodeid_set, - .get = caclient_cccam_nodeid_get, - .group = 2, - }, - { - .type = PT_INT, - .id = "extended", - .name = N_("Extended mode"), - .desc = N_("Extended mode settings."), - .off = offsetof(cccam_t, cccam_extended_conf), - .list = caclient_cccam_class_cccam_extended_list, - .def.i = CCCAM_EXTENDED_EXT, - .opts = PO_DOC_NLIST, - .group = 2, - }, - { - .type = PT_INT, - .id = "version", - .name = N_("Version"), - .desc = N_("Protocol version."), - .off = offsetof(cccam_t, cccam_version), - .list = caclient_cccam_class_cccam_version_list, - .def.i = CCCAM_VERSION_2_3_0, - .opts = PO_DOC_NLIST, - .group = 2, - }, - { - .type = PT_INT, - .id = "keepalive_interval", - .name = N_("Keepalive interval (0=disable)"), - .desc = N_("Keepalive interval in seconds"), - .off = offsetof(cccam_t, cc_keepalive_interval), - .def.i = CCCAM_KEEPALIVE_INTERVAL, - .group = 4, - }, - { } - } -}; +const idclass_t caclient_cccam_class = {.ic_super = &caclient_cc_class, + .ic_class = "caclient_cccam", + .ic_caption = N_("CCcam"), + .ic_properties = (const property_t[]){ + { + .type = PT_STR, + .id = "nodeid", + .name = N_("Node ID"), + .desc = N_("Client node ID. Leave field empty to generate a random ID."), + .set = caclient_cccam_nodeid_set, + .get = caclient_cccam_nodeid_get, + .group = 2, + }, + { + .type = PT_INT, + .id = "extended", + .name = N_("Extended mode"), + .desc = N_("Extended mode settings."), + .off = offsetof(cccam_t, cccam_extended_conf), + .list = caclient_cccam_class_cccam_extended_list, + .def.i = CCCAM_EXTENDED_EXT, + .opts = PO_DOC_NLIST, + .group = 2, + }, + { + .type = PT_INT, + .id = "version", + .name = N_("Version"), + .desc = N_("Protocol version."), + .off = offsetof(cccam_t, cccam_version), + .list = caclient_cccam_class_cccam_version_list, + .def.i = CCCAM_VERSION_2_3_0, + .opts = PO_DOC_NLIST, + .group = 2, + }, + { + .type = PT_INT, + .id = "keepalive_interval", + .name = N_("Keepalive interval (0=disable)"), + .desc = N_("Keepalive interval in seconds"), + .off = offsetof(cccam_t, cc_keepalive_interval), + .def.i = CCCAM_KEEPALIVE_INTERVAL, + .group = 4, + }, + {}}}; /* * */ -caclient_t *cccam_create(void) -{ - cccam_t *cccam = calloc(1, sizeof(*cccam)); +caclient_t* cccam_create(void) { + cccam_t* cccam = calloc(1, sizeof(*cccam)); cccam->cc_subsys = LS_CCCAM; cccam->cc_id = "cccam"; tvh_mutex_init(&cccam->cc_mutex, NULL); tvh_cond_init(&cccam->cc_cond, 1); - cccam->cac_free = cc_free; - cccam->cac_start = cc_service_start; - cccam->cac_conf_changed = cccam_conf_changed; - cccam->cac_caid_update = cc_caid_update; + cccam->cac_free = cc_free; + cccam->cac_start = cc_service_start; + cccam->cac_conf_changed = cccam_conf_changed; + cccam->cac_caid_update = cc_caid_update; cccam->cc_keepalive_interval = CCCAM_KEEPALIVE_INTERVAL; - cccam->cccam_version = CCCAM_VERSION_2_3_0; - cccam->cc_init_session = cccam_init_session; - cccam->cc_read = cccam_read; - cccam->cc_send_ecm = cccam_send_ecm; - cccam->cc_send_emm = cccam_send_emm; - cccam->cc_keepalive = cccam_send_ka; - cccam->cc_no_services = cccam_no_services; - return (caclient_t *)cccam; + cccam->cccam_version = CCCAM_VERSION_2_3_0; + cccam->cc_init_session = cccam_init_session; + cccam->cc_read = cccam_read; + cccam->cc_send_ecm = cccam_send_ecm; + cccam->cc_send_emm = cccam_send_emm; + cccam->cc_keepalive = cccam_send_ka; + cccam->cc_no_services = cccam_no_services; + return (caclient_t*)cccam; } diff --git a/src/descrambler/cclient.c b/src/descrambler/cclient.c index 9f2e7c321..ebafb3609 100644 --- a/src/descrambler/cclient.c +++ b/src/descrambler/cclient.c @@ -28,11 +28,10 @@ /* * */ -static int -cc_check_empty(const uint8_t *str, int len) -{ +static int cc_check_empty(const uint8_t* str, int len) { while (len--) { - if (*str) return 0; + if (*str) + return 0; str++; } return 1; @@ -41,9 +40,7 @@ cc_check_empty(const uint8_t *str, int len) /** * */ -static void -cc_free_ecm_section(cc_ecm_section_t *es) -{ +static void cc_free_ecm_section(cc_ecm_section_t* es) { LIST_REMOVE(es, es_link); free(es->es_data); free(es); @@ -52,10 +49,8 @@ cc_free_ecm_section(cc_ecm_section_t *es) /** * */ -static void -cc_free_ecm_pid(cc_ecm_pid_t *ep) -{ - cc_ecm_section_t *es; +static void cc_free_ecm_pid(cc_ecm_pid_t* ep) { + cc_ecm_section_t* es; while ((es = LIST_FIRST(&ep->ep_sections)) != NULL) cc_free_ecm_section(es); LIST_REMOVE(ep, ep_link); @@ -65,23 +60,19 @@ cc_free_ecm_pid(cc_ecm_pid_t *ep) /** * */ -static void -cc_service_ecm_pid_free(cc_service_t *ct) -{ - cc_ecm_pid_t *ep; +static void cc_service_ecm_pid_free(cc_service_t* ct) { + cc_ecm_pid_t* ep; - while((ep = LIST_FIRST(&ct->cs_ecm_pids)) != NULL) + while ((ep = LIST_FIRST(&ct->cs_ecm_pids)) != NULL) cc_free_ecm_pid(ep); } /** * */ -static void -cc_free_card(cc_card_data_t *cd) -{ - emm_provider_t *emmp; - int i; +static void cc_free_card(cc_card_data_t* cd) { + emm_provider_t* emmp; + int i; LIST_REMOVE(cd, cs_card); @@ -97,37 +88,35 @@ cc_free_card(cc_card_data_t *cd) /** * */ -static void -cc_free_cards(cclient_t *cc) -{ - cc_card_data_t *cd; +static void cc_free_cards(cclient_t* cc) { + cc_card_data_t* cd; - while((cd = LIST_FIRST(&cc->cc_cards)) != NULL) + while ((cd = LIST_FIRST(&cc->cc_cards)) != NULL) cc_free_card(cd); } /** * */ -char * -cc_get_card_name(cc_card_data_t *pcard, char *buf, size_t buflen) -{ - snprintf(buf, buflen, "ID:%08x CAID:%04x with %d provider%s", - pcard->cs_id, pcard->cs_ra.caid, pcard->cs_ra.providers_count, - pcard->cs_ra.providers_count != 1 ? "s" : ""); +char* cc_get_card_name(cc_card_data_t* pcard, char* buf, size_t buflen) { + snprintf(buf, + buflen, + "ID:%08x CAID:%04x with %d provider%s", + pcard->cs_id, + pcard->cs_ra.caid, + pcard->cs_ra.providers_count, + pcard->cs_ra.providers_count != 1 ? "s" : ""); return buf; } /** * */ -static int -provider_exists(cc_card_data_t *pcard, uint32_t providerid) -{ +static int provider_exists(cc_card_data_t* pcard, uint32_t providerid) { int i; - for(i = 0; i < pcard->cs_ra.providers_count; i++) - if(providerid == pcard->cs_ra.providers[i].id) + for (i = 0; i < pcard->cs_ra.providers_count; i++) + if (providerid == pcard->cs_ra.providers[i].id) return 1; return 0; } @@ -135,10 +124,8 @@ provider_exists(cc_card_data_t *pcard, uint32_t providerid) /** * */ -static int -verify_provider(cc_card_data_t *pcard, uint32_t providerid) -{ - if(providerid == 0) +static int verify_provider(cc_card_data_t* pcard, uint32_t providerid) { + if (providerid == 0) return 1; return provider_exists(pcard, providerid); @@ -147,28 +134,31 @@ verify_provider(cc_card_data_t *pcard, uint32_t providerid) /** * */ -cc_card_data_t * -cc_new_card(cclient_t *cc, uint16_t caid, uint32_t cardid, uint8_t *ua, - int pcount, uint8_t **pid, uint8_t **psa, int add) -{ - cc_card_data_t *pcard = NULL; +cc_card_data_t* cc_new_card(cclient_t* cc, + uint16_t caid, + uint32_t cardid, + uint8_t* ua, + int pcount, + uint8_t** pid, + uint8_t** psa, + int add) { + cc_card_data_t* pcard = NULL; emm_provider_t *ep, *providers; - const char *n; - const uint8_t *id, *sa; - int i, j, c, add_pcount = 0, start_index = 0, ua_changed = 0, allocated = 0; - uint32_t id32; - char buf[256]; - - LIST_FOREACH(pcard, &cc->cc_cards, cs_card) - if (pcard->cs_ra.caid == caid && - pcard->cs_id == cardid) + const char* n; + const uint8_t * id, *sa; + int i, j, c, add_pcount = 0, start_index = 0, ua_changed = 0, allocated = 0; + uint32_t id32; + char buf[256]; + + LIST_FOREACH (pcard, &cc->cc_cards, cs_card) + if (pcard->cs_ra.caid == caid && pcard->cs_id == cardid) break; if (pcard == NULL) { pcard = calloc(1, sizeof(cc_card_data_t)); emm_reass_init(&pcard->cs_ra, cc->cc_subsys, caid); pcard->cs_id = cardid; - allocated = 1; + allocated = 1; } if (ua) { @@ -184,8 +174,8 @@ cc_new_card(cclient_t *cc, uint16_t caid, uint32_t cardid, uint8_t *ua, } if (add && !allocated) { - uint8_t **add_pid = alloca(sizeof(void *) * pcount); - uint8_t **add_psa = alloca(sizeof(void *) * pcount); + uint8_t** add_pid = alloca(sizeof(void*) * pcount); + uint8_t** add_psa = alloca(sizeof(void*) * pcount); for (i = 0; i < pcount; i++) { id = pid[i]; @@ -193,19 +183,26 @@ cc_new_card(cclient_t *cc, uint16_t caid, uint32_t cardid, uint8_t *ua, continue; id32 = (id[0] << 16) | (id[1] << 8) | id[2]; if (provider_exists(pcard, id32)) { - tvhtrace(cc->cc_subsys, "%s: Provider %06X skip [ID:%08X CAID:%04X]", - cc->cc_name, id32, cardid, caid); + tvhtrace(cc->cc_subsys, + "%s: Provider %06X skip [ID:%08X CAID:%04X]", + cc->cc_name, + id32, + cardid, + caid); continue; } add_pid[add_pcount] = pid[i]; add_psa[add_pcount] = psa ? psa[i] : NULL; add_pcount++; } - + start_index = pcard->cs_ra.providers_count; if (add_pcount == 0) { - tvhdebug(cc->cc_subsys, "%s: All providers already registered [ID:%08X CAID:%04X]", - cc->cc_name, cardid, caid); + tvhdebug(cc->cc_subsys, + "%s: All providers already registered [ID:%08X CAID:%04X]", + cc->cc_name, + cardid, + caid); goto skip_providers; } @@ -214,7 +211,7 @@ cc_new_card(cclient_t *cc, uint16_t caid, uint32_t cardid, uint8_t *ua, pid = add_pid; psa = add_psa; } else { - providers = calloc(pcount, sizeof(pcard->cs_ra.providers[0])); + providers = calloc(pcount, sizeof(pcard->cs_ra.providers[0])); add_pcount = pcount; } @@ -227,60 +224,105 @@ cc_new_card(cclient_t *cc, uint16_t caid, uint32_t cardid, uint8_t *ua, } free(pcard->cs_ra.providers); - pcard->cs_ra.providers = providers; - pcount = start_index + add_pcount; + pcard->cs_ra.providers = providers; + pcount = start_index + add_pcount; pcard->cs_ra.providers_count = pcount; skip_providers: n = caid2name(caid) ?: "Unknown"; if (ua && (!add || ua_changed)) { - tvhinfo(cc->cc_subsys, "%s: Connected as user %s " - "to a %s-card-%08x [CAID:%04x : %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x] " - "with %d provider%s%s", - cc->cc_name, cc->cc_username, n, cardid, caid, - ua[0], ua[1], ua[2], ua[3], ua[4], ua[5], ua[6], ua[7], - pcount, pcount != 1 ? "s" : "", add ? " /ADD" : ""); + tvhinfo(cc->cc_subsys, + "%s: Connected as user %s " + "to a %s-card-%08x [CAID:%04x : %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x] " + "with %d provider%s%s", + cc->cc_name, + cc->cc_username, + n, + cardid, + caid, + ua[0], + ua[1], + ua[2], + ua[3], + ua[4], + ua[5], + ua[6], + ua[7], + pcount, + pcount != 1 ? "s" : "", + add ? " /ADD" : ""); } else if (!add) { - tvhinfo(cc->cc_subsys, "%s: Connected as user %s " - "to a %s-card-%08x [CAID:%04x] with %d provider%s", - cc->cc_name, cc->cc_username, n, cardid, caid, - pcount, pcount != 1 ? "s" : ""); + tvhinfo(cc->cc_subsys, + "%s: Connected as user %s " + "to a %s-card-%08x [CAID:%04x] with %d provider%s", + cc->cc_name, + cc->cc_username, + n, + cardid, + caid, + pcount, + pcount != 1 ? "s" : ""); } buf[0] = '\0'; - i = start_index; + i = start_index; for (j = c = 0, ep = pcard->cs_ra.providers + start_index; i < pcount; i++, ep++) { if (psa && !cc_check_empty(ep->sa, 8)) { sa = ep->sa; if (buf[0]) { - tvhdebug(cc->cc_subsys, "%s: Providers: ID:%08x CAID:%04X:[%s]%s", - cc->cc_name, cardid, caid, buf, add ? " /ADD" : ""); + tvhdebug(cc->cc_subsys, + "%s: Providers: ID:%08x CAID:%04X:[%s]%s", + cc->cc_name, + cardid, + caid, + buf, + add ? " /ADD" : ""); buf[0] = '\0'; - c = 0; + c = 0; } - tvhdebug(cc->cc_subsys, "%s: Provider ID #%d: 0x%04x:0x%06x %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x", - cc->cc_name, i + 1, caid, ep->id, - sa[0], sa[1], sa[2], sa[3], sa[4], sa[5], sa[6], sa[7]); + tvhdebug(cc->cc_subsys, + "%s: Provider ID #%d: 0x%04x:0x%06x %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x", + cc->cc_name, + i + 1, + caid, + ep->id, + sa[0], + sa[1], + sa[2], + sa[3], + sa[4], + sa[5], + sa[6], + sa[7]); } else { tvh_strlcatf(buf, sizeof(buf), c, "%s0x%06x", c > 0 ? "," : "", ep->id); if (++j > 5) { - tvhdebug(cc->cc_subsys, "%s: Providers: ID:%08x CAID:%04X:[%s]%s", - cc->cc_name, cardid, caid, buf, add ? " /ADD" : ""); + tvhdebug(cc->cc_subsys, + "%s: Providers: ID:%08x CAID:%04X:[%s]%s", + cc->cc_name, + cardid, + caid, + buf, + add ? " /ADD" : ""); buf[0] = '\0'; c = j = 0; } } } if (j > 0) - tvhdebug(cc->cc_subsys, "%s: Providers: ID:%08x CAID:%04X:[%s]%s", - cc->cc_name, cardid, caid, buf, add ? " /ADD" : ""); + tvhdebug(cc->cc_subsys, + "%s: Providers: ID:%08x CAID:%04X:[%s]%s", + cc->cc_name, + cardid, + caid, + buf, + add ? " /ADD" : ""); if (allocated) LIST_INSERT_HEAD(&cc->cc_cards, pcard, cs_card); if (cc->cc_emm && ua && ua_changed) { ua = pcard->cs_ra.ua; - i = ua[0] || ua[1] || ua[2] || ua[3] || - ua[4] || ua[5] || ua[6] || ua[7]; + i = ua[0] || ua[1] || ua[2] || ua[3] || ua[4] || ua[5] || ua[6] || ua[7]; if (i) cc_emm_set_allowed(cc, 1); } @@ -292,21 +334,21 @@ skip_providers: /** * */ -void -cc_remove_card(cclient_t *cc, cc_card_data_t *pcard) -{ - cc_service_t *ct; - cc_ecm_pid_t *ep, *epn; +void cc_remove_card(cclient_t* cc, cc_card_data_t* pcard) { + cc_service_t* ct; + cc_ecm_pid_t * ep, *epn; cc_ecm_section_t *es, *esn; - emm_provider_t *emmp; - char buf[256]; - int i, changed = 0; + emm_provider_t* emmp; + char buf[256]; + int i, changed = 0; - tvhinfo(cc->cc_subsys, "%s: card %s removed", cc->cc_name, - cc_get_card_name(pcard, buf, sizeof(buf))); + tvhinfo(cc->cc_subsys, + "%s: card %s removed", + cc->cc_name, + cc_get_card_name(pcard, buf, sizeof(buf))); /* invalidate all requests */ - LIST_FOREACH(ct, &cc->cc_services, cs_link) { + LIST_FOREACH (ct, &cc->cc_services, cs_link) { for (ep = LIST_FIRST(&ct->cs_ecm_pids); ep; ep = epn) { epn = LIST_NEXT(ep, ep_link); for (es = LIST_FIRST(&ep->ep_sections); es; es = esn) { @@ -326,9 +368,9 @@ cc_remove_card(cclient_t *cc, cc_card_data_t *pcard) cc_free_ecm_pid(ep); } if (changed) { - ct->cs_capid = 0xffff; + ct->cs_capid = 0xffff; ct->ecm_state = ECM_INIT; - changed = 0; + changed = 0; } } @@ -338,12 +380,10 @@ cc_remove_card(cclient_t *cc, cc_card_data_t *pcard) /** * */ -void -cc_remove_card_by_id(cclient_t *cc, uint32_t id) -{ - cc_card_data_t *pcard; +void cc_remove_card_by_id(cclient_t* cc, uint32_t id) { + cc_card_data_t* pcard; - LIST_FOREACH(pcard, &cc->cc_cards, cs_card) + LIST_FOREACH (pcard, &cc->cc_cards, cs_card) if (pcard->cs_id == id) { cc_remove_card(cc, pcard); break; @@ -353,21 +393,19 @@ cc_remove_card_by_id(cclient_t *cc, uint32_t id) /** * */ -static int -cc_ecm_reset(th_descrambler_t *th) -{ - cc_service_t *ct = (cc_service_t *)th; - cclient_t *cc = ct->cs_client; - cc_ecm_pid_t *ep; - cc_ecm_section_t *es; +static int cc_ecm_reset(th_descrambler_t* th) { + cc_service_t* ct = (cc_service_t*)th; + cclient_t* cc = ct->cs_client; + cc_ecm_pid_t* ep; + cc_ecm_section_t* es; tvh_mutex_lock(&cc->cc_mutex); descrambler_change_keystate(th, DS_READY, 1); - LIST_FOREACH(ep, &ct->cs_ecm_pids, ep_link) - LIST_FOREACH(es, &ep->ep_sections, es_link) { + LIST_FOREACH (ep, &ct->cs_ecm_pids, ep_link) + LIST_FOREACH (es, &ep->ep_sections, es_link) { es->es_keystate = ES_UNKNOWN; free(es->es_data); - es->es_data = NULL; + es->es_data = NULL; es->es_data_len = 0; } ct->ecm_state = ECM_RESET; @@ -378,20 +416,18 @@ cc_ecm_reset(th_descrambler_t *th) /** * */ -static void -cc_ecm_idle(th_descrambler_t *th) -{ - cc_service_t *ct = (cc_service_t *)th; - cclient_t *cc = ct->cs_client; - cc_ecm_pid_t *ep; - cc_ecm_section_t *es; +static void cc_ecm_idle(th_descrambler_t* th) { + cc_service_t* ct = (cc_service_t*)th; + cclient_t* cc = ct->cs_client; + cc_ecm_pid_t* ep; + cc_ecm_section_t* es; tvh_mutex_lock(&cc->cc_mutex); - LIST_FOREACH(ep, &ct->cs_ecm_pids, ep_link) - LIST_FOREACH(es, &ep->ep_sections, es_link) { + LIST_FOREACH (ep, &ct->cs_ecm_pids, ep_link) + LIST_FOREACH (es, &ep->ep_sections, es_link) { es->es_keystate = ES_IDLE; free(es->es_data); - es->es_data = NULL; + es->es_data = NULL; es->es_data_len = 0; } ct->ecm_state = ECM_RESET; @@ -401,18 +437,19 @@ cc_ecm_idle(th_descrambler_t *th) /** * */ -void -cc_ecm_reply(cc_service_t *ct, cc_ecm_section_t *es, - int key_type, uint8_t *key_even, uint8_t *key_odd, - int seq) -{ - mpegts_service_t *t = (mpegts_service_t *)ct->td_service; - cclient_t *cc = ct->cs_client; - cc_ecm_pid_t *ep; +void cc_ecm_reply(cc_service_t* ct, + cc_ecm_section_t* es, + int key_type, + uint8_t* key_even, + uint8_t* key_odd, + int seq) { + mpegts_service_t* t = (mpegts_service_t*)ct->td_service; + cclient_t* cc = ct->cs_client; + cc_ecm_pid_t* ep; cc_ecm_section_t *es2, es3; - char chaninfo[128]; - int i, resolved = 0; - int64_t delay = (getfastmonoclock() - es->es_time) / 1000LL; // in ms + char chaninfo[128]; + int i, resolved = 0; + int64_t delay = (getfastmonoclock() - es->es_time) / 1000LL; // in ms es->es_pending = 0; @@ -424,54 +461,65 @@ cc_ecm_reply(cc_service_t *ct, cc_ecm_section_t *es, if (es->es_nok < CC_MAX_NOKS) es->es_nok++; - if(es->es_keystate == ES_FORBIDDEN) + if (es->es_keystate == ES_FORBIDDEN) return; // We already know it's bad - resolved = descrambler_resolved((service_t *)t, (th_descrambler_t *)ct); + resolved = descrambler_resolved((service_t*)t, (th_descrambler_t*)ct); if (es->es_nok >= CC_MAX_NOKS) { tvhdebug(cc->cc_subsys, - "%s: Too many NOKs[%i] for service \"%s\"%s from %s", - cc->cc_name, es->es_section, t->s_dvb_svcname, chaninfo, ct->td_nicename); + "%s: Too many NOKs[%i] for service \"%s\"%s from %s", + cc->cc_name, + es->es_section, + t->s_dvb_svcname, + chaninfo, + ct->td_nicename); es->es_keystate = ES_FORBIDDEN; goto forbid; } if (resolved) { tvhdebug(cc->cc_subsys, - "%s: NOK[%i] from %s: Already has a key for service \"%s\"", - cc->cc_name, es->es_section, ct->td_nicename, t->s_dvb_svcname); - es->es_nok = CC_MAX_NOKS; /* do not send more ECM requests */ + "%s: NOK[%i] from %s: Already has a key for service \"%s\"", + cc->cc_name, + es->es_section, + ct->td_nicename, + t->s_dvb_svcname); + es->es_nok = CC_MAX_NOKS; /* do not send more ECM requests */ es->es_keystate = ES_IDLE; if (ct->td_keystate == DS_READY) - descrambler_change_keystate((th_descrambler_t *)ct, DS_IDLE, 1); + descrambler_change_keystate((th_descrambler_t*)ct, DS_IDLE, 1); } tvhdebug(cc->cc_subsys, - "%s: Received NOK[%i] for service \"%s\"%s " - "(seqno: %d Req delay: %"PRId64" ms)", - cc->cc_name, es->es_section, t->s_dvb_svcname, chaninfo, seq, delay); - -forbid: + "%s: Received NOK[%i] for service \"%s\"%s " + "(seqno: %d Req delay: %" PRId64 " ms)", + cc->cc_name, + es->es_section, + t->s_dvb_svcname, + chaninfo, + seq, + delay); + + forbid: i = 0; - LIST_FOREACH(ep, &ct->cs_ecm_pids, ep_link) - LIST_FOREACH(es2, &ep->ep_sections, es_link) - if(es2 && es2 != es && es2->es_nok == 0) { + LIST_FOREACH (ep, &ct->cs_ecm_pids, ep_link) + LIST_FOREACH (es2, &ep->ep_sections, es_link) + if (es2 && es2 != es && es2->es_nok == 0) { if (es2->es_pending) return; i++; } if (i && es->es_nok < CC_MAX_NOKS) return; - + es->es_keystate = ES_FORBIDDEN; if (resolved) /* another reader handles those requests */ return; - LIST_FOREACH(ep, &ct->cs_ecm_pids, ep_link) { - LIST_FOREACH(es2, &ep->ep_sections, es_link) - if (es2->es_keystate == ES_UNKNOWN || - es2->es_keystate == ES_RESOLVED) + LIST_FOREACH (ep, &ct->cs_ecm_pids, ep_link) { + LIST_FOREACH (es2, &ep->ep_sections, es_link) + if (es2->es_keystate == ES_UNKNOWN || es2->es_keystate == ES_RESOLVED) break; if (es2) break; @@ -479,54 +527,72 @@ forbid: if (ep == NULL) { /* !UNKNOWN && !RESOLVED */ tvherror(cc->cc_subsys, - "%s: Can not descramble service \"%s\", access denied (seqno: %d " - "Req delay: %"PRId64" ms) from %s", - cc->cc_name, t->s_dvb_svcname, seq, delay, ct->td_nicename); - descrambler_change_keystate((th_descrambler_t *)ct, DS_FORBIDDEN, 1); + "%s: Can not descramble service \"%s\", access denied (seqno: %d " + "Req delay: %" PRId64 " ms) from %s", + cc->cc_name, + t->s_dvb_svcname, + seq, + delay, + ct->td_nicename); + descrambler_change_keystate((th_descrambler_t*)ct, DS_FORBIDDEN, 1); ct->ecm_state = ECM_RESET; /* this pid is not valid, force full scan */ - if (t->s_dvb_prefcapid == ct->cs_capid && - t->s_dvb_prefcapid_lock == PREFCAPID_OFF) + if (t->s_dvb_prefcapid == ct->cs_capid && t->s_dvb_prefcapid_lock == PREFCAPID_OFF) t->s_dvb_prefcapid = 0; } return; } else { - es->es_nok = 0; - ct->cs_capid = es->es_capid; + es->es_nok = 0; + ct->cs_capid = es->es_capid; ct->ecm_state = ECM_VALID; - if(t->s_dvb_prefcapid == 0 || - (t->s_dvb_prefcapid != ct->cs_capid && - t->s_dvb_prefcapid_lock == PREFCAPID_OFF)) { + if (t->s_dvb_prefcapid == 0 || + (t->s_dvb_prefcapid != ct->cs_capid && t->s_dvb_prefcapid_lock == PREFCAPID_OFF)) { t->s_dvb_prefcapid = ct->cs_capid; - tvhdebug(cc->cc_subsys, "%s: Saving prefered PID %d for %s", - cc->cc_name, t->s_dvb_prefcapid, ct->td_nicename); + tvhdebug(cc->cc_subsys, + "%s: Saving prefered PID %d for %s", + cc->cc_name, + t->s_dvb_prefcapid, + ct->td_nicename); service_request_save((service_t*)t); } tvhdebug(cc->cc_subsys, - "%s: Received ECM reply%s for service \"%s\" [%d] " - "(seqno: %d Req delay: %"PRId64" ms)", - cc->cc_name, chaninfo, t->s_dvb_svcname, es->es_section, seq, delay); - - if(es->es_keystate != ES_RESOLVED) + "%s: Received ECM reply%s for service \"%s\" [%d] " + "(seqno: %d Req delay: %" PRId64 " ms)", + cc->cc_name, + chaninfo, + t->s_dvb_svcname, + es->es_section, + seq, + delay); + + if (es->es_keystate != ES_RESOLVED) tvhdebug(cc->cc_subsys, - "%s: Obtained DES keys for service \"%s\" in %"PRId64" ms, from %s", - cc->cc_name, t->s_dvb_svcname, delay, ct->td_nicename); + "%s: Obtained DES keys for service \"%s\" in %" PRId64 " ms, from %s", + cc->cc_name, + t->s_dvb_svcname, + delay, + ct->td_nicename); es->es_keystate = ES_RESOLVED; es->es_resolved = 1; es3 = *es; tvh_mutex_unlock(&cc->cc_mutex); - descrambler_keys((th_descrambler_t *)ct, key_type, 0, key_even, key_odd); + descrambler_keys((th_descrambler_t*)ct, key_type, 0, key_even, key_odd); snprintf(chaninfo, sizeof(chaninfo), "%s:%i", cc->cc_hostname, cc->cc_port); - descrambler_notify((th_descrambler_t *)ct, - es3.es_caid, es3.es_provid, - caid2name(es3.es_caid), - es3.es_capid, delay, - 1, "", chaninfo, cc->cc_id); + descrambler_notify((th_descrambler_t*)ct, + es3.es_caid, + es3.es_provid, + caid2name(es3.es_caid), + es3.es_capid, + delay, + 1, + "", + chaninfo, + cc->cc_id); tvh_mutex_lock(&cc->cc_mutex); } } @@ -534,68 +600,65 @@ forbid: /** * */ -cc_ecm_section_t * -cc_find_pending_section(cclient_t *cc, uint32_t seq, cc_service_t **_ct) -{ - cc_service_t *ct; - cc_ecm_pid_t *ep; - cc_ecm_section_t *es; - - if (_ct) *_ct = NULL; - LIST_FOREACH(ct, &cc->cc_services, cs_link) - LIST_FOREACH(ep, &ct->cs_ecm_pids, ep_link) - LIST_FOREACH(es, &ep->ep_sections, es_link) - if(es->es_seq == seq) { +cc_ecm_section_t* cc_find_pending_section(cclient_t* cc, uint32_t seq, cc_service_t** _ct) { + cc_service_t* ct; + cc_ecm_pid_t* ep; + cc_ecm_section_t* es; + + if (_ct) + *_ct = NULL; + LIST_FOREACH (ct, &cc->cc_services, cs_link) + LIST_FOREACH (ep, &ct->cs_ecm_pids, ep_link) + LIST_FOREACH (es, &ep->ep_sections, es_link) + if (es->es_seq == seq) { if (es->es_resolved) { - mpegts_service_t *t = (mpegts_service_t *)ct->td_service; + mpegts_service_t* t = (mpegts_service_t*)ct->td_service; tvhdebug(cc->cc_subsys, - "%s: Ignore %sECM (PID %d) for service \"%s\" from %s (seq %i)", - cc->cc_name, - es->es_pending ? "duplicate " : "", - ep->ep_capid, t->s_dvb_svcname, ct->td_nicename, es->es_seq); - if (_ct) *_ct = ct; + "%s: Ignore %sECM (PID %d) for service \"%s\" from %s (seq %i)", + cc->cc_name, + es->es_pending ? "duplicate " : "", + ep->ep_capid, + t->s_dvb_svcname, + ct->td_nicename, + es->es_seq); + if (_ct) + *_ct = ct; return NULL; } if (es->es_pending) { - if (_ct) *_ct = ct; + if (_ct) + *_ct = ct; return es; } } - tvhwarn(cc->cc_subsys, "%s: Got unexpected ECM reply (seqno: %d)", - cc->cc_name, seq); + tvhwarn(cc->cc_subsys, "%s: Got unexpected ECM reply (seqno: %d)", cc->cc_name, seq); return NULL; } /** * */ -static void -cc_invalidate_cards(cclient_t *cc) -{ - cc_card_data_t *cd; +static void cc_invalidate_cards(cclient_t* cc) { + cc_card_data_t* cd; - LIST_FOREACH(cd, &cc->cc_cards, cs_card) + LIST_FOREACH (cd, &cc->cc_cards, cs_card) cd->cs_running = 0; } /** * */ -static void -cc_flush_services(cclient_t *cc) -{ - cc_service_t *ct; +static void cc_flush_services(cclient_t* cc) { + cc_service_t* ct; - LIST_FOREACH(ct, &cc->cc_services, cs_link) + LIST_FOREACH (ct, &cc->cc_services, cs_link) descrambler_flush_table_data(ct->td_service); } /** * */ -int -cc_read(cclient_t *cc, void *buf, size_t len, int timeout) -{ +int cc_read(cclient_t* cc, void* buf, size_t len, int timeout) { int r; tvh_mutex_unlock(&cc->cc_mutex); @@ -603,8 +666,7 @@ cc_read(cclient_t *cc, void *buf, size_t len, int timeout) tvh_mutex_lock(&cc->cc_mutex); if (r && tvheadend_is_running()) - tvhwarn(cc->cc_subsys, "%s: read error %d (%s)", - cc->cc_name, r, strerror(r)); + tvhwarn(cc->cc_subsys, "%s: read error %d (%s)", cc->cc_name, r, strerror(r)); if (cc_must_break(cc)) return ECONNABORTED; @@ -617,9 +679,7 @@ cc_read(cclient_t *cc, void *buf, size_t len, int timeout) /** * */ -void -cc_write_message(cclient_t *cc, cc_message_t *msg, int enq) -{ +void cc_write_message(cclient_t* cc, cc_message_t* msg, int enq) { if (enq) { lock_assert(&cc->cc_mutex); if (cc->cc_write_running) { @@ -629,12 +689,10 @@ cc_write_message(cclient_t *cc, cc_message_t *msg, int enq) free(msg); } } else { - tvhtrace(cc->cc_subsys, "%s: sending message len %u", - cc->cc_name, msg->cm_len); + tvhtrace(cc->cc_subsys, "%s: sending message len %u", cc->cc_name, msg->cm_len); tvhlog_hexdump(cc->cc_subsys, msg->cm_data, msg->cm_len); if (tvh_write(cc->cc_fd, msg->cm_data, msg->cm_len)) - tvhinfo(cc->cc_subsys, "%s: write error: %s", - cc->cc_name, strerror(errno)); + tvhinfo(cc->cc_subsys, "%s: write error: %s", cc->cc_name, strerror(errno)); free(msg); } } @@ -642,17 +700,15 @@ cc_write_message(cclient_t *cc, cc_message_t *msg, int enq) /** * */ -static void -cc_session(cclient_t *cc) -{ - tvhpoll_t *poll; +static void cc_session(cclient_t* cc) { + tvhpoll_t* poll; tvhpoll_event_t ev; - char buf[16]; - sbuf_t rbuf; - cc_message_t *cm; - ssize_t len; - int64_t mono; - int r; + char buf[16]; + sbuf_t rbuf; + cc_message_t* cm; + ssize_t len; + int64_t mono; + int r; if (cc->cc_init_session(cc)) return; @@ -698,8 +754,10 @@ cc_session(cclient_t *cc) if (cc->cc_read(cc, &rbuf)) break; } else { - tvhtrace(cc->cc_subsys, "%s: %s", cc->cc_name, - len == 0 ? "connection close" : "read error"); + tvhtrace(cc->cc_subsys, + "%s: %s", + cc->cc_name, + len == 0 ? "connection close" : "read error"); break; } } else { @@ -707,8 +765,7 @@ cc_session(cclient_t *cc) } if ((cm = TAILQ_FIRST(&cc->cc_writeq)) != NULL) { TAILQ_REMOVE(&cc->cc_writeq, cm, cm_link); - tvhtrace(cc->cc_subsys, "%s: sending queued message len %u", - cc->cc_name, cm->cm_len); + tvhtrace(cc->cc_subsys, "%s: sending queued message len %u", cc->cc_name, cm->cm_len); tvhlog_hexdump(cc->cc_subsys, cm->cm_data, cm->cm_len); if (tvh_nonblock_write(cc->cc_fd, cm->cm_data, cm->cm_len)) { free(cm); @@ -716,7 +773,7 @@ cc_session(cclient_t *cc) } free(cm); } -keepalive: + keepalive: if (mono < mclk()) { mono = mclk() + sec2mono(cc->cc_keepalive_interval); if (cc->cc_keepalive) @@ -732,25 +789,23 @@ keepalive: /** * */ -static void * -cc_thread(void *aux) -{ - cclient_t *cc = aux; - int fd, d, r; - char errbuf[100]; - char name[256]; - char hostname[256]; - int port; - int attempts = 0; - int64_t mono; +static void* cc_thread(void* aux) { + cclient_t* cc = aux; + int fd, d, r; + char errbuf[100]; + char name[256]; + char hostname[256]; + int port; + int attempts = 0; + int64_t mono; tvh_mutex_lock(&cc->cc_mutex); - while(cc->cc_running) { + while (cc->cc_running) { cc_invalidate_cards(cc); - caclient_set_status((caclient_t *)cc, CACLIENT_STATUS_READY); - + caclient_set_status((caclient_t*)cc, CACLIENT_STATUS_READY); + snprintf(name, sizeof(name), "%s:%d", cc->cc_hostname, cc->cc_port); cc->cc_name = name; @@ -765,13 +820,12 @@ cc_thread(void *aux) tvh_mutex_lock(&cc->cc_mutex); - if(fd == -1) { + if (fd == -1) { attempts++; - tvhinfo(cc->cc_subsys, - "%s: Connection failed: %s", cc->cc_name, errbuf); + tvhinfo(cc->cc_subsys, "%s: Connection failed: %s", cc->cc_name, errbuf); } else { - if(cc->cc_running == 0) { + if (cc->cc_running == 0) { close(fd); break; } @@ -779,7 +833,7 @@ cc_thread(void *aux) tvhdebug(cc->cc_subsys, "%s: Connected", cc->cc_name); attempts = 0; - cc->cc_fd = fd; + cc->cc_fd = fd; cc->cc_reconfigure = 0; cc_session(cc); @@ -789,19 +843,18 @@ cc_thread(void *aux) tvhinfo(cc->cc_subsys, "%s: Disconnected", cc->cc_name); } - if(cc->cc_running == 0) continue; - if(attempts == 1 || cc->cc_reconfigure) { + if (cc->cc_running == 0) + continue; + if (attempts == 1 || cc->cc_reconfigure) { cc->cc_reconfigure = 0; continue; // Retry immediately } - caclient_set_status((caclient_t *)cc, CACLIENT_STATUS_DISCONNECTED); + caclient_set_status((caclient_t*)cc, CACLIENT_STATUS_DISCONNECTED); d = 3; - tvhinfo(cc->cc_subsys, - "%s: Automatic connection attempt in %d seconds", - cc->cc_name, d-1); + tvhinfo(cc->cc_subsys, "%s: Automatic connection attempt in %d seconds", cc->cc_name, d - 1); mono = mclk() + sec2mono(d); do { @@ -818,28 +871,22 @@ cc_thread(void *aux) return NULL; } - /** * */ -void -cc_emm_set_allowed(cclient_t *cc, int emm_allowed) -{ - cc_card_data_t *pcard; +void cc_emm_set_allowed(cclient_t* cc, int emm_allowed) { + cc_card_data_t* pcard; if (!emm_allowed) { - tvhinfo(cc->cc_subsys, - "%s: Will not forward EMMs (not allowed by server)", - cc->cc_name); + tvhinfo(cc->cc_subsys, "%s: Will not forward EMMs (not allowed by server)", cc->cc_name); } else { - LIST_FOREACH(pcard, &cc->cc_cards, cs_card) - if (pcard->cs_ra.type != CARD_UNKNOWN) break; + LIST_FOREACH (pcard, &cc->cc_cards, cs_card) + if (pcard->cs_ra.type != CARD_UNKNOWN) + break; if (pcard) { tvhinfo(cc->cc_subsys, "%s: Will forward EMMs", cc->cc_name); } else { - tvhinfo(cc->cc_subsys, - "%s: Will not forward EMMs (unsupported CA system)", - cc->cc_name); + tvhinfo(cc->cc_subsys, "%s: Will not forward EMMs (unsupported CA system)", cc->cc_name); emm_allowed = 0; } } @@ -849,14 +896,11 @@ cc_emm_set_allowed(cclient_t *cc, int emm_allowed) /** * */ -static void -cc_emm_send(void *aux, const uint8_t *radata, int ralen, void *mux) -{ - cc_card_data_t *pcard = aux; - cclient_t *cc = pcard->cs_client; - - tvhtrace(cc->cc_subsys, "%s: sending EMM for %04x mux %p", - cc->cc_name, pcard->cs_ra.caid, mux); +static void cc_emm_send(void* aux, const uint8_t* radata, int ralen, void* mux) { + cc_card_data_t* pcard = aux; + cclient_t* cc = pcard->cs_client; + + tvhtrace(cc->cc_subsys, "%s: sending EMM for %04x mux %p", cc->cc_name, pcard->cs_ra.caid, mux); tvhlog_hexdump(cc->cc_subsys, radata, ralen); cc->cc_send_emm(cc, NULL, pcard, 0, radata, ralen); } @@ -864,14 +908,12 @@ cc_emm_send(void *aux, const uint8_t *radata, int ralen, void *mux) /** * */ -static void -cc_emm(void *opaque, int pid, const uint8_t *data, int len, int emm) -{ - cc_card_data_t *pcard = opaque; - cclient_t *cc; - void *mux; - - if (data == NULL) { /* end-of-data */ +static void cc_emm(void* opaque, int pid, const uint8_t* data, int len, int emm) { + cc_card_data_t* pcard = opaque; + cclient_t* cc; + void* mux; + + if (data == NULL) { /* end-of-data */ pcard->cs_mux = NULL; return; } @@ -898,21 +940,19 @@ end_of_job: /** * */ -static void -cc_table_input(void *opaque, int pid, const uint8_t *data, int len, int emm) -{ - cc_service_t *ct = opaque; - elementary_stream_t *st; - mpegts_service_t *t = (mpegts_service_t*)ct->td_service; - cclient_t *cc = ct->cs_client; - int section, ecm; - cc_ecm_pid_t *ep; - cc_ecm_section_t *es; - char chaninfo[40]; - cc_card_data_t *pcard = NULL; - caid_t *c; - uint16_t caid; - uint32_t provid; +static void cc_table_input(void* opaque, int pid, const uint8_t* data, int len, int emm) { + cc_service_t* ct = opaque; + elementary_stream_t* st; + mpegts_service_t* t = (mpegts_service_t*)ct->td_service; + cclient_t* cc = ct->cs_client; + int section, ecm; + cc_ecm_pid_t* ep; + cc_ecm_section_t* es; + char chaninfo[40]; + cc_card_data_t* pcard = NULL; + caid_t* c; + uint16_t caid; + uint32_t provid; if (data == NULL) return; @@ -930,87 +970,96 @@ cc_table_input(void *opaque, int pid, const uint8_t *data, int len, int emm) /* clean all */ cc_service_ecm_pid_free(ct); /* move to init state */ - ct->ecm_state = ECM_INIT; - ct->cs_capid = 0xffff; + ct->ecm_state = ECM_INIT; + ct->cs_capid = 0xffff; t->s_dvb_prefcapid = 0; - tvhdebug(cc->cc_subsys, "%s: Reset after unexpected or no reply for service \"%s\"", - cc->cc_name, t->s_dvb_svcname); + tvhdebug(cc->cc_subsys, + "%s: Reset after unexpected or no reply for service \"%s\"", + cc->cc_name, + t->s_dvb_svcname); } - LIST_FOREACH(ep, &ct->cs_ecm_pids, ep_link) - if(ep->ep_capid == pid) break; + LIST_FOREACH (ep, &ct->cs_ecm_pids, ep_link) + if (ep->ep_capid == pid) + break; - if(ep == NULL) { + if (ep == NULL) { if (ct->ecm_state == ECM_INIT) { // Validate prefered ECM PID tvhdebug(cc->cc_subsys, "%s: ECM state INIT (PID %d)", cc->cc_name, pid); - if(t->s_dvb_prefcapid_lock != PREFCAPID_OFF) { + if (t->s_dvb_prefcapid_lock != PREFCAPID_OFF) { st = elementary_stream_find(&t->s_components, t->s_dvb_prefcapid); if (st && st->es_type == SCT_CA) - LIST_FOREACH(c, &st->es_caids, link) - LIST_FOREACH(pcard, &cc->cc_cards, cs_card) - if(pcard->cs_running && - pcard->cs_ra.caid == c->caid && - verify_provider(pcard, c->providerid)) + LIST_FOREACH (c, &st->es_caids, link) + LIST_FOREACH (pcard, &cc->cc_cards, cs_card) + if (pcard->cs_running && pcard->cs_ra.caid == c->caid && + verify_provider(pcard, c->providerid)) goto prefcapid_ok; - tvhdebug(cc->cc_subsys, "%s: Invalid prefered ECM (PID %d) found for service \"%s\"", - cc->cc_name, cc->cc_port, t->s_dvb_svcname); + tvhdebug(cc->cc_subsys, + "%s: Invalid prefered ECM (PID %d) found for service \"%s\"", + cc->cc_name, + cc->cc_port, + t->s_dvb_svcname); t->s_dvb_prefcapid = 0; } -prefcapid_ok: - if(t->s_dvb_prefcapid == pid || t->s_dvb_prefcapid == 0 || - t->s_dvb_prefcapid_lock == PREFCAPID_OFF) { - ep = calloc(1, sizeof(cc_ecm_pid_t)); + prefcapid_ok: + if (t->s_dvb_prefcapid == pid || t->s_dvb_prefcapid == 0 || + t->s_dvb_prefcapid_lock == PREFCAPID_OFF) { + ep = calloc(1, sizeof(cc_ecm_pid_t)); ep->ep_capid = pid; LIST_INSERT_HEAD(&ct->cs_ecm_pids, ep, ep_link); - tvhdebug(cc->cc_subsys, "%s: Insert %s ECM (PID %d) for service \"%s\"", - cc->cc_name, t->s_dvb_prefcapid ? "preferred" : "new", pid, t->s_dvb_svcname); + tvhdebug(cc->cc_subsys, + "%s: Insert %s ECM (PID %d) for service \"%s\"", + cc->cc_name, + t->s_dvb_prefcapid ? "preferred" : "new", + pid, + t->s_dvb_svcname); } } - if(ep == NULL) + if (ep == NULL) goto end; } st = elementary_stream_find(&t->s_components, pid); if (st) { - LIST_FOREACH(c, &st->es_caids, link) - LIST_FOREACH(pcard, &cc->cc_cards, cs_card) - if(pcard->cs_running && - pcard->cs_ra.caid == c->caid && - verify_provider(pcard, c->providerid)) + LIST_FOREACH (c, &st->es_caids, link) + LIST_FOREACH (pcard, &cc->cc_cards, cs_card) + if (pcard->cs_running && pcard->cs_ra.caid == c->caid && + verify_provider(pcard, c->providerid)) goto found; } goto end; found: - caid = c->caid; + caid = c->caid; provid = c->providerid; ecm = data[0] == 0x80 || data[0] == 0x81; - if (caid_is_dvn(caid)) ecm |= data[0] == 0x50; /* DVN */ + if (caid_is_dvn(caid)) + ecm |= data[0] == 0x50; /* DVN */ if (ecm) { if (caid_is_irdeto(caid)) { ep->ep_last_section = data[5]; - section = data[4]; + section = data[4]; } else if (caid_is_powervu(caid)) { ep->ep_last_section = 0; - section = data[0] & 1; + section = data[0] & 1; } else { ep->ep_last_section = 0; - section = 0; + section = 0; } snprintf(chaninfo, sizeof(chaninfo), " (PID %d CAID %04X)", pid, caid); - LIST_FOREACH(es, &ep->ep_sections, es_link) + LIST_FOREACH (es, &ep->ep_sections, es_link) if (es->es_section == section) break; if (es == NULL) { - es = calloc(1, sizeof(cc_ecm_section_t)); + es = calloc(1, sizeof(cc_ecm_section_t)); es->es_section = section; LIST_INSERT_HEAD(&ep->ep_sections, es, es_link); } @@ -1023,42 +1072,52 @@ found: memcpy(es->es_data, data, len); es->es_data_len = len; - if(cc->cc_fd == -1) { + if (cc->cc_fd == -1) { // New key, but we are not connected (anymore), can not descramble - descrambler_change_keystate((th_descrambler_t *)ct, DS_READY, 0); + descrambler_change_keystate((th_descrambler_t*)ct, DS_READY, 0); goto end; } if (es->es_keystate == ES_FORBIDDEN || es->es_keystate == ES_IDLE) goto end; - es->es_caid = caid; - es->es_provid = provid; - es->es_capid = pid; - es->es_pending = 1; + es->es_caid = caid; + es->es_provid = provid; + es->es_capid = pid; + es->es_pending = 1; es->es_resolved = 0; - if (ct->cs_capid != 0xffff && ct->cs_capid > 0 && - pid > 0 && ct->cs_capid != pid) { - tvhdebug(cc->cc_subsys, "%s: Filtering ECM (PID %d CAID %04X), using PID %d", - cc->cc_name, pid, caid, ct->cs_capid); + if (ct->cs_capid != 0xffff && ct->cs_capid > 0 && pid > 0 && ct->cs_capid != pid) { + tvhdebug(cc->cc_subsys, + "%s: Filtering ECM (PID %d CAID %04X), using PID %d", + cc->cc_name, + pid, + caid, + ct->cs_capid); goto end; } if (cc->cc_send_ecm(cc, ct, es, pcard, data, len) == 0) { tvhdebug(cc->cc_subsys, - "%s: Sending ECM%s section=%d/%d for service \"%s\" (seqno: %d)", - cc->cc_name, chaninfo, section, - ep->ep_last_section, t->s_dvb_svcname, es->es_seq); + "%s: Sending ECM%s section=%d/%d for service \"%s\" (seqno: %d)", + cc->cc_name, + chaninfo, + section, + ep->ep_last_section, + t->s_dvb_svcname, + es->es_seq); es->es_time = getfastmonoclock(); } else { es->es_pending = 0; } } else { if (cc->cc_forward_emm && data[0] >= 0x82 && data[0] <= 0x92) { - tvhtrace(cc->cc_subsys, "%s: sending EMM for %04X:%06X service \"%s\"", - cc->cc_name, pcard->cs_ra.caid, provid, - t->s_dvb_svcname); + tvhtrace(cc->cc_subsys, + "%s: sending EMM for %04X:%06X service \"%s\"", + cc->cc_name, + pcard->cs_ra.caid, + provid, + t->s_dvb_svcname); tvhlog_hexdump(cc->cc_subsys, data, len); emm_filter(&pcard->cs_ra, data, len, t->s_dvb_mux, cc_emm_send, pcard); } @@ -1072,11 +1131,9 @@ end: /** * cc_mutex is held */ -static void -cc_service_destroy0(cclient_t *cc, th_descrambler_t *td) -{ - cc_service_t *ct = (cc_service_t *)td; - int i, pid; +static void cc_service_destroy0(cclient_t* cc, th_descrambler_t* td) { + cc_service_t* ct = (cc_service_t*)td; + int i, pid; for (i = 0; i < ct->cs_epids.count; i++) { pid = DESCRAMBLER_ECM_PID(ct->cs_epids.pids[i].pid); @@ -1100,11 +1157,9 @@ cc_service_destroy0(cclient_t *cc, th_descrambler_t *td) /** * cc_mutex is held */ -static void -cc_service_destroy(th_descrambler_t *td) -{ - cc_service_t *ct = (cc_service_t *)td; - cclient_t *cc = ct->cs_client; +static void cc_service_destroy(th_descrambler_t* td) { + cc_service_t* ct = (cc_service_t*)td; + cclient_t* cc = ct->cs_client; tvh_mutex_lock(&cc->cc_mutex); cc_service_destroy0(cc, td); @@ -1116,18 +1171,16 @@ cc_service_destroy(th_descrambler_t *td) * * global_lock is held. Not that we care about that, but either way, it is. */ -void -cc_service_start(caclient_t *cac, service_t *t) -{ - cclient_t *cc = (cclient_t *)cac; - cc_service_t *ct; - th_descrambler_t *td; - elementary_stream_t *st; - caid_t *c; - cc_card_data_t *pcard; - char buf[512]; - int i, pid, reuse = 0, prefpid, prefpid_lock, forcecaid; - mpegts_apids_t epids; +void cc_service_start(caclient_t* cac, service_t* t) { + cclient_t* cc = (cclient_t*)cac; + cc_service_t* ct; + th_descrambler_t* td; + elementary_stream_t* st; + caid_t* c; + cc_card_data_t* pcard; + char buf[512]; + int i, pid, reuse = 0, prefpid, prefpid_lock, forcecaid; + mpegts_apids_t epids; extern const idclass_t mpegts_service_class; if (!idnode_is_instance(&t->s_id, &mpegts_service_class)) @@ -1135,42 +1188,49 @@ cc_service_start(caclient_t *cac, service_t *t) tvh_mutex_lock(&cc->cc_mutex); tvh_mutex_lock(&t->s_stream_mutex); - LIST_FOREACH(ct, &cc->cc_services, cs_link) { + LIST_FOREACH (ct, &cc->cc_services, cs_link) { if (ct->td_service == t && ct->cs_client == cc) break; } - prefpid = ((mpegts_service_t *)t)->s_dvb_prefcapid; - prefpid_lock = ((mpegts_service_t *)t)->s_dvb_prefcapid_lock; - forcecaid = ((mpegts_service_t *)t)->s_dvb_forcecaid; - LIST_FOREACH(pcard, &cc->cc_cards, cs_card) { - if (!pcard->cs_running) continue; - if (pcard->cs_ra.caid == 0) continue; - TAILQ_FOREACH(st, &t->s_components.set_filter, es_filter_link) { + prefpid = ((mpegts_service_t*)t)->s_dvb_prefcapid; + prefpid_lock = ((mpegts_service_t*)t)->s_dvb_prefcapid_lock; + forcecaid = ((mpegts_service_t*)t)->s_dvb_forcecaid; + LIST_FOREACH (pcard, &cc->cc_cards, cs_card) { + if (!pcard->cs_running) + continue; + if (pcard->cs_ra.caid == 0) + continue; + TAILQ_FOREACH (st, &t->s_components.set_filter, es_filter_link) { if (prefpid_lock == PREFCAPID_FORCE && prefpid != st->es_pid) continue; - LIST_FOREACH(c, &st->es_caids, link) { + LIST_FOREACH (c, &st->es_caids, link) { if (c->use && c->caid == pcard->cs_ra.caid) if (!forcecaid || forcecaid == c->caid) break; } - if (c) break; + if (c) + break; } - if (st) break; + if (st) + break; } if (!pcard) { - if (ct) cc_service_destroy0(cc, (th_descrambler_t*)ct); + if (ct) + cc_service_destroy0(cc, (th_descrambler_t*)ct); goto end; } if (ct) { reuse = 1; for (i = 0; i < ct->cs_epids.count; i++) { pid = ct->cs_epids.pids[i].pid; - TAILQ_FOREACH(st, &t->s_components.set_filter, es_filter_link) { - if (st->es_pid != pid) continue; - LIST_FOREACH(c, &st->es_caids, link) + TAILQ_FOREACH (st, &t->s_components.set_filter, es_filter_link) { + if (st->es_pid != pid) + continue; + LIST_FOREACH (c, &st->es_caids, link) if (c->use && c->caid == pcard->cs_ra.caid) break; - if (c) break; + if (c) + break; } if (st == NULL) { descrambler_close_pid(ct->cs_mux, ct, DESCRAMBLER_ECM_PID(pid)); @@ -1185,19 +1245,18 @@ cc_service_start(caclient_t *cac, service_t *t) } else { ct = calloc(1, sizeof(*ct)); } - ct->cs_client = cc; - ct->cs_capid = 0xffff; - ct->cs_mux = ((mpegts_service_t *)t)->s_dvb_mux; - ct->ecm_state = ECM_INIT; - - td = (th_descrambler_t *)ct; - snprintf(buf, sizeof(buf), "%s-%s-%04X", - cc->cc_id, cc->cc_name, pcard->cs_ra.caid); - td->td_nicename = strdup(buf); - td->td_service = t; - td->td_stop = cc_service_destroy; - td->td_ecm_reset = cc_ecm_reset; - td->td_ecm_idle = cc_ecm_idle; + ct->cs_client = cc; + ct->cs_capid = 0xffff; + ct->cs_mux = ((mpegts_service_t*)t)->s_dvb_mux; + ct->ecm_state = ECM_INIT; + + td = (th_descrambler_t*)ct; + snprintf(buf, sizeof(buf), "%s-%s-%04X", cc->cc_id, cc->cc_name, pcard->cs_ra.caid); + td->td_nicename = strdup(buf); + td->td_service = t; + td->td_stop = cc_service_destroy; + td->td_ecm_reset = cc_ecm_reset; + td->td_ecm_idle = cc_ecm_idle; LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link); LIST_INSERT_HEAD(&cc->cc_services, ct, cs_link); @@ -1207,8 +1266,8 @@ cc_service_start(caclient_t *cac, service_t *t) add: i = 0; mpegts_pid_init(&epids); - TAILQ_FOREACH(st, &t->s_components.set_filter, es_filter_link) { - LIST_FOREACH(c, &st->es_caids, link) + TAILQ_FOREACH (st, &t->s_components.set_filter, es_filter_link) { + LIST_FOREACH (c, &st->es_caids, link) if (c->use && c->caid == pcard->cs_ra.caid) mpegts_pid_add(&epids, st->es_pid, 0); } @@ -1223,13 +1282,18 @@ add: } if (reuse & 2) { - ct->cs_capid = 0xffff; + ct->cs_capid = 0xffff; ct->ecm_state = ECM_INIT; } if (reuse != 1) - tvhdebug(cc->cc_subsys, "%s: %s %susing CWC %s:%d", - cc->cc_name, service_nicename(t), reuse ? "re" : "", cc->cc_hostname, cc->cc_port); + tvhdebug(cc->cc_subsys, + "%s: %s %susing CWC %s:%d", + cc->cc_name, + service_nicename(t), + reuse ? "re" : "", + cc->cc_hostname, + cc->cc_port); end: tvh_mutex_unlock(&t->s_stream_mutex); @@ -1239,40 +1303,53 @@ end: /** * */ -void -cc_free(caclient_t *cac) -{ - cclient_t *cc = (cclient_t *)cac; - cc_service_t *ct; +void cc_free(caclient_t* cac) { + cclient_t* cc = (cclient_t*)cac; + cc_service_t* ct; - while((ct = LIST_FIRST(&cc->cc_services)) != NULL) - cc_service_destroy((th_descrambler_t *)ct); + while ((ct = LIST_FIRST(&cc->cc_services)) != NULL) + cc_service_destroy((th_descrambler_t*)ct); cc_free_cards(cc); - free((void *)cc->cc_password); - free((void *)cc->cc_username); - free((void *)cc->cc_hostname); + free((void*)cc->cc_password); + free((void*)cc->cc_username); + free((void*)cc->cc_hostname); } /** * */ -void -cc_caid_update(caclient_t *cac, mpegts_mux_t *mux, uint16_t caid, uint32_t prov, uint16_t pid, int valid) -{ - cclient_t *cc = (cclient_t *)cac;; - cc_card_data_t *pcard; - emm_provider_t *emmp; - int i; +void cc_caid_update(caclient_t* cac, + mpegts_mux_t* mux, + uint16_t caid, + uint32_t prov, + uint16_t pid, + int valid) { + cclient_t* cc = (cclient_t*)cac; + ; + cc_card_data_t* pcard; + emm_provider_t* emmp; + int i; tvhtrace(cc->cc_subsys, - "%s: caid update event - client %s mux %p caid %04x (%i) prov %06x (%i) pid %04x (%i) valid %i", - cc->cc_name, cac->cac_name, mux, caid, caid, prov, prov, pid, pid, valid); + "%s: caid update event - client %s mux %p caid %04x (%i) prov %06x (%i) pid %04x (%i) valid " + "%i", + cc->cc_name, + cac->cac_name, + mux, + caid, + caid, + prov, + prov, + pid, + pid, + valid); tvh_mutex_lock(&cc->cc_mutex); if (valid < 0 || cc->cc_running) { - LIST_FOREACH(pcard, &cc->cc_cards, cs_card) { + LIST_FOREACH (pcard, &cc->cc_cards, cs_card) { if (valid < 0 || pcard->cs_ra.caid == caid) { - if (pcard->cs_mux && pcard->cs_mux != mux) continue; + if (pcard->cs_mux && pcard->cs_mux != mux) + continue; emmp = pcard->cs_ra.providers; for (i = 0; i < pcard->cs_ra.providers_count; i++, emmp++) { if (prov == emmp->id) { @@ -1281,7 +1358,7 @@ cc_caid_update(caclient_t *cac, mpegts_mux_t *mux, uint16_t caid, uint32_t prov, pcard->cs_mux = mux; descrambler_open_emm(mux, pcard, caid, prov, cc_emm); } else { - pcard->cs_mux = NULL; + pcard->cs_mux = NULL; descrambler_close_emm(mux, pcard, caid, prov); } } @@ -1295,13 +1372,11 @@ cc_caid_update(caclient_t *cac, mpegts_mux_t *mux, uint16_t caid, uint32_t prov, /** * */ -void -cc_conf_changed(caclient_t *cac) -{ - cclient_t *cc = (cclient_t *)cac; - pthread_t tid; - cc_message_t *cm; - char tname[32]; +void cc_conf_changed(caclient_t* cac) { + cclient_t* cc = (cclient_t*)cac; + pthread_t tid; + cc_message_t* cm; + char tname[32]; if (cac->cac_enabled) { if (cc->cc_hostname == NULL || cc->cc_hostname[0] == '\0') { @@ -1318,7 +1393,7 @@ cc_conf_changed(caclient_t *cac) return; } cc->cc_reconfigure = 1; - if(cc->cc_fd >= 0) + if (cc->cc_fd >= 0) shutdown(cc->cc_fd, SHUT_RDWR); tvh_cond_signal(&cc->cc_cond, 0); tvh_mutex_unlock(&cc->cc_mutex); @@ -1347,94 +1422,87 @@ cc_conf_changed(caclient_t *cac) /** * */ -const idclass_t caclient_cc_class = -{ - .ic_super = &caclient_class, - .ic_class = "caclient_card", - .ic_caption = N_("Card client"), - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - { - .name = N_("Login Settings"), - .number = 2, - }, - { - .name = N_("EMM Settings"), - .number = 3, - }, - { - .name = N_("Connection Settings"), - .number = 4, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "username", - .name = N_("Username"), - .desc = N_("Login username."), - .off = offsetof(cclient_t, cc_username), - .opts = PO_TRIM, - .group = 2, - }, - { - .type = PT_STR, - .id = "password", - .name = N_("Password"), - .desc = N_("Login password."), - .off = offsetof(cclient_t, cc_password), - .opts = PO_PASSWORD, - .group = 2, - }, - { - .type = PT_STR, - .id = "hostname", - .name = N_("Hostname/IP"), - .desc = N_("Hostname (or IP) of the server."), - .off = offsetof(cclient_t, cc_hostname), - .def.s = "localhost", - .opts = PO_TRIM, - .group = 2, - }, - { - .type = PT_INT, - .id = "port", - .name = N_("Port"), - .desc = N_("Port to connect to."), - .off = offsetof(cclient_t, cc_port), - .group = 2, - }, - { - .type = PT_BOOL, - .id = "emm", - .name = N_("Update card (EMM)"), - .desc = N_("Enable/disable offering of Entitlement Management Message updates."), - .off = offsetof(cclient_t, cc_emm), - .def.i = 1, - .group = 3, - }, - { - .type = PT_BOOL, - .id = "emmex", - .name = N_("Updates from one mux (EMM)"), - .desc = N_("Update Entitlement Management Messages from one mux only."), - .off = offsetof(cclient_t, cc_emmex), - .def.i = 1, - .group = 3, - }, - { - .type = PT_INT, - .id = "keepalive_interval", - .name = N_("Keepalive interval"), - .desc = N_("Keepalive interval in seconds"), - .off = offsetof(cclient_t, cc_keepalive_interval), - .def.i = CC_KEEPALIVE_INTERVAL, - .group = 4, - }, - { } - } -}; +const idclass_t caclient_cc_class = {.ic_super = &caclient_class, + .ic_class = "caclient_card", + .ic_caption = N_("Card client"), + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + { + .name = N_("Login Settings"), + .number = 2, + }, + { + .name = N_("EMM Settings"), + .number = 3, + }, + { + .name = N_("Connection Settings"), + .number = 4, + }, + {}}, + .ic_properties = (const property_t[]){{ + .type = PT_STR, + .id = "username", + .name = N_("Username"), + .desc = N_("Login username."), + .off = offsetof(cclient_t, cc_username), + .opts = PO_TRIM, + .group = 2, + }, + { + .type = PT_STR, + .id = "password", + .name = N_("Password"), + .desc = N_("Login password."), + .off = offsetof(cclient_t, cc_password), + .opts = PO_PASSWORD, + .group = 2, + }, + { + .type = PT_STR, + .id = "hostname", + .name = N_("Hostname/IP"), + .desc = N_("Hostname (or IP) of the server."), + .off = offsetof(cclient_t, cc_hostname), + .def.s = "localhost", + .opts = PO_TRIM, + .group = 2, + }, + { + .type = PT_INT, + .id = "port", + .name = N_("Port"), + .desc = N_("Port to connect to."), + .off = offsetof(cclient_t, cc_port), + .group = 2, + }, + { + .type = PT_BOOL, + .id = "emm", + .name = N_("Update card (EMM)"), + .desc = N_("Enable/disable offering of Entitlement Management Message updates."), + .off = offsetof(cclient_t, cc_emm), + .def.i = 1, + .group = 3, + }, + { + .type = PT_BOOL, + .id = "emmex", + .name = N_("Updates from one mux (EMM)"), + .desc = N_("Update Entitlement Management Messages from one mux only."), + .off = offsetof(cclient_t, cc_emmex), + .def.i = 1, + .group = 3, + }, + { + .type = PT_INT, + .id = "keepalive_interval", + .name = N_("Keepalive interval"), + .desc = N_("Keepalive interval in seconds"), + .off = offsetof(cclient_t, cc_keepalive_interval), + .def.i = CC_KEEPALIVE_INTERVAL, + .group = 4, + }, + {}}}; diff --git a/src/descrambler/cclient.h b/src/descrambler/cclient.h index 7e3c27632..bec17dd47 100644 --- a/src/descrambler/cclient.h +++ b/src/descrambler/cclient.h @@ -35,15 +35,10 @@ typedef struct cc_ecm_section { LIST_ENTRY(cc_ecm_section) es_link; - enum { - ES_UNKNOWN, - ES_RESOLVED, - ES_FORBIDDEN, - ES_IDLE - } es_keystate; + enum { ES_UNKNOWN, ES_RESOLVED, ES_FORBIDDEN, ES_IDLE } es_keystate; int es_section; - uint8_t *es_data; + uint8_t* es_data; uint32_t es_data_len; uint32_t es_card_id; @@ -55,7 +50,7 @@ typedef struct cc_ecm_section { uint8_t es_nok; uint8_t es_pending; uint8_t es_resolved; - int64_t es_time; // time request was sent + int64_t es_time; // time request was sent } cc_ecm_section_t; @@ -77,23 +72,19 @@ typedef struct cc_ecm_pid { typedef struct cc_service { th_descrambler_t; - void *cs_client; + void* cs_client; LIST_ENTRY(cc_service) cs_link; - uint16_t cs_capid; + uint16_t cs_capid; mpegts_apids_t cs_epids; - mpegts_mux_t *cs_mux; + mpegts_mux_t* cs_mux; /** * ECM Status */ - enum { - ECM_INIT, - ECM_VALID, - ECM_RESET - } ecm_state; + enum { ECM_INIT, ECM_VALID, ECM_RESET } ecm_state; LIST_HEAD(, cc_ecm_pid) cs_ecm_pids; @@ -115,14 +106,14 @@ typedef struct cc_card_data { LIST_ENTRY(cc_card_data) cs_card; uint32_t cs_id; emm_reass_t cs_ra; - void *cs_client; - mpegts_mux_t *cs_mux; + void* cs_client; + mpegts_mux_t* cs_mux; uint8_t cs_running; union { struct { - uint32_t cs_remote_id; - uint8_t cs_hop; - uint8_t cs_reshare; + uint32_t cs_remote_id; + uint8_t cs_hop; + uint8_t cs_reshare; } cccam; }; } cc_card_data_t; @@ -133,20 +124,28 @@ typedef struct cc_card_data { typedef struct cclient { caclient_t; - int cc_subsys; - char *cc_name; - const char *cc_id; + int cc_subsys; + char* cc_name; + const char* cc_id; /* Callbacks */ - void *(*cc_alloc_service)(void *cc); - int (*cc_init_session)(void *cc); - int (*cc_read)(void *cc, sbuf_t *sbuf); - void (*cc_keepalive)(void *cc); - int (*cc_send_ecm)(void *cc, cc_service_t *ct, cc_ecm_section_t *es, - cc_card_data_t *pcard, const uint8_t *data, int len); - void (*cc_send_emm)(void *cc, cc_service_t *ct, cc_card_data_t *pcard, - uint32_t provid, const uint8_t *data, int len); - void (*cc_no_services)(void *cc); + void* (*cc_alloc_service)(void* cc); + int (*cc_init_session)(void* cc); + int (*cc_read)(void* cc, sbuf_t* sbuf); + void (*cc_keepalive)(void* cc); + int (*cc_send_ecm)(void* cc, + cc_service_t* ct, + cc_ecm_section_t* es, + cc_card_data_t* pcard, + const uint8_t* data, + int len); + void (*cc_send_emm)(void* cc, + cc_service_t* ct, + cc_card_data_t* pcard, + uint32_t provid, + const uint8_t* data, + int len); + void (*cc_no_services)(void* cc); /* Connection */ int cc_fd; @@ -154,10 +153,10 @@ typedef struct cclient { int cc_retry_delay; /* Thread */ - pthread_t cc_tid; - tvh_cond_t cc_cond; + pthread_t cc_tid; + tvh_cond_t cc_cond; tvh_mutex_t cc_mutex; - th_pipe_t cc_pipe; + th_pipe_t cc_pipe; /* Database */ LIST_HEAD(, cc_service) cc_services; @@ -173,15 +172,15 @@ typedef struct cclient { /* Emm exclusive update */ int64_t cc_emm_update_time; - void *cc_emm_mux; + void* cc_emm_mux; /* From configuration */ - char *cc_username; - char *cc_password; - char *cc_hostname; - int cc_port; - int cc_emm; - int cc_emmex; + char* cc_username; + char* cc_password; + char* cc_hostname; + int cc_port; + int cc_emm; + int cc_emmex; uint8_t cc_running; uint8_t cc_reconfigure; @@ -190,28 +189,41 @@ typedef struct cclient { /* * */ -static inline int cc_must_break(cclient_t *cc) - { return !cc->cc_running || !cc->cac_enabled || cc->cc_reconfigure; } - -char *cc_get_card_name(cc_card_data_t *pcard, char *buf, size_t buflen); -cc_card_data_t *cc_new_card - (cclient_t *cc, uint16_t caid, uint32_t cardid, - uint8_t *ua, int pcount, uint8_t **pid, uint8_t **psa, int add); -void cc_emm_set_allowed(cclient_t *cc, int emm_allowed); -void cc_remove_card(cclient_t *cc, cc_card_data_t *pcard); -void cc_remove_card_by_id(cclient_t *cc, uint32_t card_id); - -void cc_ecm_reply - (cc_service_t *ct, cc_ecm_section_t *es, int key_type, - uint8_t *key_even, uint8_t *key_odd, int seq); - -cc_ecm_section_t *cc_find_pending_section - (cclient_t *cc, uint32_t seq, cc_service_t **ct); - -void cc_write_message(cclient_t *cc, cc_message_t *msg, int enq); -int cc_read(cclient_t *cc, void *buf, size_t len, int timeout); - -void cc_service_start(caclient_t *cac, service_t *t); -void cc_free(caclient_t *cac); -void cc_caid_update(caclient_t *cac, mpegts_mux_t *mux, uint16_t caid, uint32_t provid, uint16_t pid, int valid); -void cc_conf_changed(caclient_t *cac); +static inline int cc_must_break(cclient_t* cc) { + return !cc->cc_running || !cc->cac_enabled || cc->cc_reconfigure; +} + +char* cc_get_card_name(cc_card_data_t* pcard, char* buf, size_t buflen); +cc_card_data_t* cc_new_card(cclient_t* cc, + uint16_t caid, + uint32_t cardid, + uint8_t* ua, + int pcount, + uint8_t** pid, + uint8_t** psa, + int add); +void cc_emm_set_allowed(cclient_t* cc, int emm_allowed); +void cc_remove_card(cclient_t* cc, cc_card_data_t* pcard); +void cc_remove_card_by_id(cclient_t* cc, uint32_t card_id); + +void cc_ecm_reply(cc_service_t* ct, + cc_ecm_section_t* es, + int key_type, + uint8_t* key_even, + uint8_t* key_odd, + int seq); + +cc_ecm_section_t* cc_find_pending_section(cclient_t* cc, uint32_t seq, cc_service_t** ct); + +void cc_write_message(cclient_t* cc, cc_message_t* msg, int enq); +int cc_read(cclient_t* cc, void* buf, size_t len, int timeout); + +void cc_service_start(caclient_t* cac, service_t* t); +void cc_free(caclient_t* cac); +void cc_caid_update(caclient_t* cac, + mpegts_mux_t* mux, + uint16_t caid, + uint32_t provid, + uint16_t pid, + int valid); +void cc_conf_changed(caclient_t* cac); diff --git a/src/descrambler/constcw.c b/src/descrambler/constcw.c index c84b36a74..1d481f7c6 100644 --- a/src/descrambler/constcw.c +++ b/src/descrambler/constcw.c @@ -26,7 +26,7 @@ * */ typedef struct constcw_service { - th_descrambler_t; + th_descrambler_t; LIST_ENTRY(constcw_service) cs_link; } constcw_service_t; @@ -36,35 +36,30 @@ typedef struct constcw_service { typedef struct constcw { caclient_t; - char ccw_name[128]; + char ccw_name[128]; /* From configuration */ - uint16_t ccw_caid; /* CA ID */ - uint32_t ccw_providerid; /* CA provider ID */ - uint16_t ccw_tsid; /* transponder ID */ - uint16_t ccw_sid; /* service ID */ - uint8_t ccw_key_even[16]; /* DES or AES key */ - uint8_t ccw_key_odd [16]; /* DES or AES key */ + uint16_t ccw_caid; /* CA ID */ + uint32_t ccw_providerid; /* CA provider ID */ + uint16_t ccw_tsid; /* transponder ID */ + uint16_t ccw_sid; /* service ID */ + uint8_t ccw_key_even[16]; /* DES or AES key */ + uint8_t ccw_key_odd[16]; /* DES or AES key */ LIST_HEAD(, constcw_service) ccw_services; /* active services */ } constcw_t; /* * */ -static const char * -constcw_name(constcw_t *ccw) -{ - return idnode_get_title(&ccw->cac_id, NULL, - ccw->ccw_name, sizeof(ccw->ccw_name)); +static const char* constcw_name(constcw_t* ccw) { + return idnode_get_title(&ccw->cac_id, NULL, ccw->ccw_name, sizeof(ccw->ccw_name)); } /** * */ -static int -constcw_algo(caclient_t *cac) -{ - constcw_t *ccw = (constcw_t *)cac; +static int constcw_algo(caclient_t* cac) { + constcw_t* ccw = (constcw_t*)cac; if (idnode_is_instance(&ccw->cac_id, &caclient_ccw_des_ncb_class)) return DESCRAMBLER_DES_NCB; @@ -78,10 +73,8 @@ constcw_algo(caclient_t *cac) /** * */ -static int -constcw_key_size(caclient_t *cac) -{ - constcw_t *ccw = (constcw_t *)cac; +static int constcw_key_size(caclient_t* cac) { + constcw_t* ccw = (constcw_t*)cac; if (idnode_is_instance(&ccw->cac_id, &caclient_ccw_aes128_ecb_class)) return 16; @@ -91,44 +84,38 @@ constcw_key_size(caclient_t *cac) /* * */ -static int -constcw_ecm_reset(th_descrambler_t *th) -{ +static int constcw_ecm_reset(th_descrambler_t* th) { return 1; } /** * s_stream_mutex is held */ -static void -constcw_service_destroy(th_descrambler_t *td) -{ - constcw_service_t *ct = (constcw_service_t *)td; - +static void constcw_service_destroy(th_descrambler_t* td) { + constcw_service_t* ct = (constcw_service_t*)td; + LIST_REMOVE(td, td_service_link); LIST_REMOVE(ct, cs_link); free(ct->td_nicename); free(ct); -} +} /** * global_lock is held. Not that we care about that, but either way, it is. */ -static void -constcw_service_start(caclient_t *cac, service_t *t) -{ - constcw_t *ccw = (constcw_t *)cac; - constcw_service_t *ct; - th_descrambler_t *td; - elementary_stream_t *st; - mpegts_service_t *mt; - char buf[128]; - caid_t *c; +static void constcw_service_start(caclient_t* cac, service_t* t) { + constcw_t* ccw = (constcw_t*)cac; + constcw_service_t* ct; + th_descrambler_t* td; + elementary_stream_t* st; + mpegts_service_t* mt; + char buf[128]; + caid_t* c; extern const idclass_t mpegts_service_class; if (!idnode_is_instance(&t->s_id, &mpegts_service_class)) return; - mt = (mpegts_service_t *)t; + mt = (mpegts_service_t*)t; if (mt->s_dvb_forcecaid && mt->s_dvb_forcecaid != ccw->ccw_caid) return; @@ -139,7 +126,7 @@ constcw_service_start(caclient_t *cac, service_t *t) if (mt->s_dvb_mux->mm_tsid != ccw->ccw_tsid) return; - LIST_FOREACH(ct, &ccw->ccw_services, cs_link) + LIST_FOREACH (ct, &ccw->ccw_services, cs_link) if (ct->td_service == t) break; if (ct) @@ -147,48 +134,44 @@ constcw_service_start(caclient_t *cac, service_t *t) if (!mt->s_dvb_forcecaid) { tvh_mutex_lock(&t->s_stream_mutex); - TAILQ_FOREACH(st, &t->s_components.set_filter, es_filter_link) { - LIST_FOREACH(c, &st->es_caids, link) { - if (c->use && c->caid == ccw->ccw_caid && - c->providerid == ccw->ccw_providerid) + TAILQ_FOREACH (st, &t->s_components.set_filter, es_filter_link) { + LIST_FOREACH (c, &st->es_caids, link) { + if (c->use && c->caid == ccw->ccw_caid && c->providerid == ccw->ccw_providerid) break; } - if (c) break; + if (c) + break; } tvh_mutex_unlock(&t->s_stream_mutex); if (st == NULL) return; } - ct = calloc(1, sizeof(constcw_service_t)); - td = (th_descrambler_t *)ct; + ct = calloc(1, sizeof(constcw_service_t)); + td = (th_descrambler_t*)ct; snprintf(buf, sizeof(buf), "constcw-%s", constcw_name(ccw)); - td->td_nicename = strdup(buf); - td->td_service = t; - td->td_stop = constcw_service_destroy; - td->td_ecm_reset = constcw_ecm_reset; + td->td_nicename = strdup(buf); + td->td_service = t; + td->td_stop = constcw_service_destroy; + td->td_ecm_reset = constcw_ecm_reset; LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link); LIST_INSERT_HEAD(&ccw->ccw_services, ct, cs_link); - descrambler_keys(td, constcw_algo(cac), - 0, ccw->ccw_key_even, ccw->ccw_key_odd); + descrambler_keys(td, constcw_algo(cac), 0, ccw->ccw_key_even, ccw->ccw_key_odd); } - /** * */ -static void -constcw_free(caclient_t *cac) -{ - constcw_t *ccw = (constcw_t *)cac; - constcw_service_t *ct; - - while((ct = LIST_FIRST(&ccw->ccw_services)) != NULL) { - service_t *t = ct->td_service; +static void constcw_free(caclient_t* cac) { + constcw_t* ccw = (constcw_t*)cac; + constcw_service_t* ct; + + while ((ct = LIST_FIRST(&ccw->ccw_services)) != NULL) { + service_t* t = ct->td_service; tvh_mutex_lock(&t->s_stream_mutex); - constcw_service_destroy((th_descrambler_t *)ct); + constcw_service_destroy((th_descrambler_t*)ct); tvh_mutex_unlock(&t->s_stream_mutex); } } @@ -196,27 +179,23 @@ constcw_free(caclient_t *cac) /** * */ -static int -nibble(char c) -{ - switch(c) { - case '0' ... '9': - return c - '0'; - case 'a' ... 'f': - return c - 'a' + 10; - case 'A' ... 'F': - return c - 'A' + 10; - default: - return 0; +static int nibble(char c) { + switch (c) { + case '0' ... '9': + return c - '0'; + case 'a' ... 'f': + return c - 'a' + 10; + case 'A' ... 'F': + return c - 'A' + 10; + default: + return 0; } } /** * */ -static void -constcw_conf_changed(caclient_t *cac) -{ +static void constcw_conf_changed(caclient_t* cac) { if (cac->cac_enabled) { caclient_set_status(cac, CACLIENT_STATUS_CONNECTED); } else { @@ -227,19 +206,19 @@ constcw_conf_changed(caclient_t *cac) /** * */ -static int -constcw_class_key_set(void *o, const void *v, uint8_t *dkey) -{ - const char *s = v ?: ""; - int keysize = constcw_key_size(o); - char key[16]; - int i, u, l; - - for(i = 0; i < keysize; i++) { - while(*s != 0 && !isxdigit(*s)) s++; +static int constcw_class_key_set(void* o, const void* v, uint8_t* dkey) { + const char* s = v ?: ""; + int keysize = constcw_key_size(o); + char key[16]; + int i, u, l; + + for (i = 0; i < keysize; i++) { + while (*s != 0 && !isxdigit(*s)) + s++; u = *s ? nibble(*s++) : 0; - while(*s != 0 && !isxdigit(*s)) s++; - l = *s ? nibble(*s++) : 0; + while (*s != 0 && !isxdigit(*s)) + s++; + l = *s ? nibble(*s++) : 0; key[i] = (u << 4) | l; } i = memcmp(dkey, key, keysize) != 0; @@ -247,371 +226,358 @@ constcw_class_key_set(void *o, const void *v, uint8_t *dkey) return i; } -static int -constcw_class_key_even_set(void *o, const void *v) -{ - constcw_t *ccw = o; +static int constcw_class_key_even_set(void* o, const void* v) { + constcw_t* ccw = o; return constcw_class_key_set(o, v, ccw->ccw_key_even); } -static int -constcw_class_key_odd_set(void *o, const void *v) -{ - constcw_t *ccw = o; +static int constcw_class_key_odd_set(void* o, const void* v) { + constcw_t* ccw = o; return constcw_class_key_set(o, v, ccw->ccw_key_odd); } -static const void * -constcw_class_key_get(void *o, const uint8_t *key) -{ +static const void* constcw_class_key_get(void* o, const uint8_t* key) { if (constcw_key_size(o) == 8) { - snprintf(prop_sbuf, PROP_SBUF_LEN, - "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - key[0x0], key[0x1], key[0x2], key[0x3], - key[0x4], key[0x5], key[0x6], key[0x7]); + snprintf(prop_sbuf, + PROP_SBUF_LEN, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + key[0x0], + key[0x1], + key[0x2], + key[0x3], + key[0x4], + key[0x5], + key[0x6], + key[0x7]); } else { - snprintf(prop_sbuf, PROP_SBUF_LEN, - "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" - "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - key[0x0], key[0x1], key[0x2], key[0x3], - key[0x4], key[0x5], key[0x6], key[0x7], - key[0x8], key[0x9], key[0xa], key[0xb], - key[0xc], key[0xd], key[0xe], key[0xf]); + snprintf(prop_sbuf, + PROP_SBUF_LEN, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + key[0x0], + key[0x1], + key[0x2], + key[0x3], + key[0x4], + key[0x5], + key[0x6], + key[0x7], + key[0x8], + key[0x9], + key[0xa], + key[0xb], + key[0xc], + key[0xd], + key[0xe], + key[0xf]); } return &prop_sbuf_ptr; } -static const void * -constcw_class_key_even_get(void *o) -{ - constcw_t *ccw = o; +static const void* constcw_class_key_even_get(void* o) { + constcw_t* ccw = o; return constcw_class_key_get(o, ccw->ccw_key_even); } -static const void * -constcw_class_key_odd_get(void *o) -{ - constcw_t *ccw = o; +static const void* constcw_class_key_odd_get(void* o) { + constcw_t* ccw = o; return constcw_class_key_get(o, ccw->ccw_key_odd); } -static property_group_t caclient_ic_groups[] = { - { - .name = N_("Client"), - .number = 1, - }, - { - .name = N_("Filter"), - .number = 2, - }, - { - .name = N_("Keys"), - .number = 3, - }, - {} -}; - -const idclass_t caclient_ccw_csa_cbc_class = -{ - .ic_super = &caclient_class, - .ic_class = "caclient_ccw_csa_cbc", - .ic_caption = N_("CSA CBC Constant Code Word"), - .ic_groups = caclient_ic_groups, - .ic_properties = (const property_t[]){ - { - .type = PT_U16, - .id = "caid", - .name = N_("CA ID"), - .desc = N_("Conditional Access Identification."), - .off = offsetof(constcw_t, ccw_caid), - .opts = PO_HEXA, - .def.u16 = 0x2600, - .group = 2, - }, - { - .type = PT_U32, - .id = "providerid", - .name = N_("Provider ID"), - .desc = N_("The provider's ID."), - .off = offsetof(constcw_t, ccw_providerid), - .opts = PO_HEXA, - .def.u32 = 0, - .group = 2, - }, - { - .type = PT_U16, - .id = "tsid", - .name = N_("Transponder ID"), - .desc = N_("The transponder ID."), - .off = offsetof(constcw_t, ccw_tsid), - .opts = PO_HEXA, - .def.u16 = 1, - .group = 2, - }, - { - .type = PT_U16, - .id = "sid", - .name = N_("Service ID"), - .desc = N_("The service ID."), - .off = offsetof(constcw_t, ccw_sid), - .opts = PO_HEXA, - .def.u16 = 1, - .group = 2, - }, - { - .type = PT_STR, - .id = "key_even", - .name = N_("Even key"), - .desc = N_("Even key."), - .set = constcw_class_key_even_set, - .get = constcw_class_key_even_get, - .opts = PO_PASSWORD, - .def.s = "00:00:00:00:00:00:00:00", - .group = 3, - }, - { - .type = PT_STR, - .id = "key_odd", - .name = N_("Odd key"), - .desc = N_("Odd key."), - .set = constcw_class_key_odd_set, - .get = constcw_class_key_odd_get, - .opts = PO_PASSWORD, - .def.s = "00:00:00:00:00:00:00:00", - .group = 3, - }, - { } - } -}; - -const idclass_t caclient_ccw_des_ncb_class = -{ - .ic_super = &caclient_class, - .ic_class = "caclient_ccw_des_ncb", - .ic_caption = N_("DES NCB Constant Code Word"), - .ic_groups = caclient_ic_groups, - .ic_properties = (const property_t[]){ - { - .type = PT_U16, - .id = "caid", - .name = N_("CA ID"), - .desc = N_("Conditional Access Identification."), - .off = offsetof(constcw_t, ccw_caid), - .opts = PO_HEXA, - .def.u16 = 0x2600, - .group = 2, - }, - { - .type = PT_U32, - .id = "providerid", - .name = N_("Provider ID"), - .desc = N_("The provider's ID."), - .off = offsetof(constcw_t, ccw_providerid), - .opts = PO_HEXA, - .def.u32 = 0, - .group = 2, - }, - { - .type = PT_U16, - .id = "tsid", - .name = N_("Transponder ID"), - .desc = N_("The transponder ID."), - .off = offsetof(constcw_t, ccw_tsid), - .opts = PO_HEXA, - .def.u16 = 1, - .group = 2, - }, +static property_group_t caclient_ic_groups[] = {{ + .name = N_("Client"), + .number = 1, + }, { - .type = PT_U16, - .id = "sid", - .name = N_("Service ID"), - .desc = N_("The service ID."), - .off = offsetof(constcw_t, ccw_sid), - .opts = PO_HEXA, - .def.u16 = 1, - .group = 2, + .name = N_("Filter"), + .number = 2, }, { - .type = PT_STR, - .id = "key_even", - .name = N_("Even key"), - .desc = N_("Even key."), - .set = constcw_class_key_even_set, - .get = constcw_class_key_even_get, - .opts = PO_PASSWORD, - .def.s = "00:00:00:00:00:00:00:00", - .group = 3, + .name = N_("Keys"), + .number = 3, }, - { - .type = PT_STR, - .id = "key_odd", - .name = N_("Odd key"), - .desc = N_("Odd key."), - .set = constcw_class_key_odd_set, - .get = constcw_class_key_odd_get, - .opts = PO_PASSWORD, - .def.s = "00:00:00:00:00:00:00:00", - .group = 3, - }, - { } - } -}; - -const idclass_t caclient_ccw_aes_ecb_class = -{ - .ic_super = &caclient_class, - .ic_class = "caclient_ccw_aes_ecb", - .ic_caption = N_("AES ECB Constant Code Word"), - .ic_groups = caclient_ic_groups, - .ic_properties = (const property_t[]){ - { - .type = PT_U16, - .id = "caid", - .name = N_("CA ID"), - .desc = N_("Conditional Access Identification."), - .off = offsetof(constcw_t, ccw_caid), - .opts = PO_HEXA, - .def.u16 = 0x2600, - .group = 2, - }, - { - .type = PT_U32, - .id = "providerid", - .name = N_("Provider ID"), - .desc = N_("The provider's ID."), - .off = offsetof(constcw_t, ccw_providerid), - .opts = PO_HEXA, - .def.u32 = 0, - .group = 2, - }, - { - .type = PT_U16, - .id = "tsid", - .name = N_("Transponder ID"), - .desc = N_("The transponder ID."), - .off = offsetof(constcw_t, ccw_tsid), - .opts = PO_HEXA, - .def.u16 = 1, - .group = 2, - }, - { - .type = PT_U16, - .id = "sid", - .name = N_("Service ID"), - .desc = N_("The service ID."), - .off = offsetof(constcw_t, ccw_sid), - .opts = PO_HEXA, - .def.u16 = 1, - .group = 2, - }, - { - .type = PT_STR, - .id = "key_even", - .name = N_("Even key"), - .desc = N_("Even key."), - .set = constcw_class_key_even_set, - .get = constcw_class_key_even_get, - .opts = PO_PASSWORD, - .def.s = "00:00:00:00:00:00:00:00", - .group = 3, - }, - { - .type = PT_STR, - .id = "key_odd", - .name = N_("Odd key"), - .desc = N_("Odd key."), - .set = constcw_class_key_odd_set, - .get = constcw_class_key_odd_get, - .opts = PO_PASSWORD, - .def.s = "00:00:00:00:00:00:00:00", - .group = 3, - }, - { } - } -}; - -const idclass_t caclient_ccw_aes128_ecb_class = -{ - .ic_super = &caclient_class, - .ic_class = "caclient_ccw_aes128_ecb", - .ic_caption = N_("AES128 ECB Constant Code Word"), - .ic_groups = caclient_ic_groups, - .ic_properties = (const property_t[]){ - { - .type = PT_U16, - .id = "caid", - .name = N_("CA ID"), - .desc = N_("Conditional Access Identification."), - .off = offsetof(constcw_t, ccw_caid), - .opts = PO_HEXA, - .def.u16 = 0x2600, - .group = 2, - }, - { - .type = PT_U32, - .id = "providerid", - .name = N_("Provider ID"), - .desc = N_("The provider's ID."), - .off = offsetof(constcw_t, ccw_providerid), - .opts = PO_HEXA, - .def.u32 = 0, - .group = 2, - }, - { - .type = PT_U16, - .id = "tsid", - .name = N_("Transponder ID"), - .desc = N_("The transponder ID."), - .off = offsetof(constcw_t, ccw_tsid), - .opts = PO_HEXA, - .def.u16 = 1, - .group = 2, - }, - { - .type = PT_U16, - .id = "sid", - .name = N_("Service ID"), - .desc = N_("The service ID"), - .off = offsetof(constcw_t, ccw_sid), - .opts = PO_HEXA, - .def.u16 = 1, - .group = 2, - }, - { - .type = PT_STR, - .id = "key_even", - .name = N_("Even key"), - .desc = N_("Even key."), - .set = constcw_class_key_even_set, - .get = constcw_class_key_even_get, - .opts = PO_PASSWORD, - .def.s = "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00", - .group = 3, - }, - { - .type = PT_STR, - .id = "key_odd", - .name = N_("Odd key"), - .desc = N_("Odd key."), - .set = constcw_class_key_odd_set, - .get = constcw_class_key_odd_get, - .opts = PO_PASSWORD, - .def.s = "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00", - .group = 3, - }, - { } - } -}; + {}}; + +const idclass_t caclient_ccw_csa_cbc_class = {.ic_super = &caclient_class, + .ic_class = "caclient_ccw_csa_cbc", + .ic_caption = N_("CSA CBC Constant Code Word"), + .ic_groups = caclient_ic_groups, + .ic_properties = (const property_t[]){{ + .type = PT_U16, + .id = "caid", + .name = N_("CA ID"), + .desc = N_("Conditional Access Identification."), + .off = offsetof(constcw_t, ccw_caid), + .opts = PO_HEXA, + .def.u16 = 0x2600, + .group = 2, + }, + { + .type = PT_U32, + .id = "providerid", + .name = N_("Provider ID"), + .desc = N_("The provider's ID."), + .off = offsetof(constcw_t, ccw_providerid), + .opts = PO_HEXA, + .def.u32 = 0, + .group = 2, + }, + { + .type = PT_U16, + .id = "tsid", + .name = N_("Transponder ID"), + .desc = N_("The transponder ID."), + .off = offsetof(constcw_t, ccw_tsid), + .opts = PO_HEXA, + .def.u16 = 1, + .group = 2, + }, + { + .type = PT_U16, + .id = "sid", + .name = N_("Service ID"), + .desc = N_("The service ID."), + .off = offsetof(constcw_t, ccw_sid), + .opts = PO_HEXA, + .def.u16 = 1, + .group = 2, + }, + { + .type = PT_STR, + .id = "key_even", + .name = N_("Even key"), + .desc = N_("Even key."), + .set = constcw_class_key_even_set, + .get = constcw_class_key_even_get, + .opts = PO_PASSWORD, + .def.s = "00:00:00:00:00:00:00:00", + .group = 3, + }, + { + .type = PT_STR, + .id = "key_odd", + .name = N_("Odd key"), + .desc = N_("Odd key."), + .set = constcw_class_key_odd_set, + .get = constcw_class_key_odd_get, + .opts = PO_PASSWORD, + .def.s = "00:00:00:00:00:00:00:00", + .group = 3, + }, + {}}}; + +const idclass_t caclient_ccw_des_ncb_class = {.ic_super = &caclient_class, + .ic_class = "caclient_ccw_des_ncb", + .ic_caption = N_("DES NCB Constant Code Word"), + .ic_groups = caclient_ic_groups, + .ic_properties = (const property_t[]){{ + .type = PT_U16, + .id = "caid", + .name = N_("CA ID"), + .desc = N_("Conditional Access Identification."), + .off = offsetof(constcw_t, ccw_caid), + .opts = PO_HEXA, + .def.u16 = 0x2600, + .group = 2, + }, + { + .type = PT_U32, + .id = "providerid", + .name = N_("Provider ID"), + .desc = N_("The provider's ID."), + .off = offsetof(constcw_t, ccw_providerid), + .opts = PO_HEXA, + .def.u32 = 0, + .group = 2, + }, + { + .type = PT_U16, + .id = "tsid", + .name = N_("Transponder ID"), + .desc = N_("The transponder ID."), + .off = offsetof(constcw_t, ccw_tsid), + .opts = PO_HEXA, + .def.u16 = 1, + .group = 2, + }, + { + .type = PT_U16, + .id = "sid", + .name = N_("Service ID"), + .desc = N_("The service ID."), + .off = offsetof(constcw_t, ccw_sid), + .opts = PO_HEXA, + .def.u16 = 1, + .group = 2, + }, + { + .type = PT_STR, + .id = "key_even", + .name = N_("Even key"), + .desc = N_("Even key."), + .set = constcw_class_key_even_set, + .get = constcw_class_key_even_get, + .opts = PO_PASSWORD, + .def.s = "00:00:00:00:00:00:00:00", + .group = 3, + }, + { + .type = PT_STR, + .id = "key_odd", + .name = N_("Odd key"), + .desc = N_("Odd key."), + .set = constcw_class_key_odd_set, + .get = constcw_class_key_odd_get, + .opts = PO_PASSWORD, + .def.s = "00:00:00:00:00:00:00:00", + .group = 3, + }, + {}}}; + +const idclass_t caclient_ccw_aes_ecb_class = {.ic_super = &caclient_class, + .ic_class = "caclient_ccw_aes_ecb", + .ic_caption = N_("AES ECB Constant Code Word"), + .ic_groups = caclient_ic_groups, + .ic_properties = (const property_t[]){{ + .type = PT_U16, + .id = "caid", + .name = N_("CA ID"), + .desc = N_("Conditional Access Identification."), + .off = offsetof(constcw_t, ccw_caid), + .opts = PO_HEXA, + .def.u16 = 0x2600, + .group = 2, + }, + { + .type = PT_U32, + .id = "providerid", + .name = N_("Provider ID"), + .desc = N_("The provider's ID."), + .off = offsetof(constcw_t, ccw_providerid), + .opts = PO_HEXA, + .def.u32 = 0, + .group = 2, + }, + { + .type = PT_U16, + .id = "tsid", + .name = N_("Transponder ID"), + .desc = N_("The transponder ID."), + .off = offsetof(constcw_t, ccw_tsid), + .opts = PO_HEXA, + .def.u16 = 1, + .group = 2, + }, + { + .type = PT_U16, + .id = "sid", + .name = N_("Service ID"), + .desc = N_("The service ID."), + .off = offsetof(constcw_t, ccw_sid), + .opts = PO_HEXA, + .def.u16 = 1, + .group = 2, + }, + { + .type = PT_STR, + .id = "key_even", + .name = N_("Even key"), + .desc = N_("Even key."), + .set = constcw_class_key_even_set, + .get = constcw_class_key_even_get, + .opts = PO_PASSWORD, + .def.s = "00:00:00:00:00:00:00:00", + .group = 3, + }, + { + .type = PT_STR, + .id = "key_odd", + .name = N_("Odd key"), + .desc = N_("Odd key."), + .set = constcw_class_key_odd_set, + .get = constcw_class_key_odd_get, + .opts = PO_PASSWORD, + .def.s = "00:00:00:00:00:00:00:00", + .group = 3, + }, + {}}}; + +const idclass_t caclient_ccw_aes128_ecb_class = {.ic_super = &caclient_class, + .ic_class = "caclient_ccw_aes128_ecb", + .ic_caption = N_("AES128 ECB Constant Code Word"), + .ic_groups = caclient_ic_groups, + .ic_properties = (const property_t[]){{ + .type = PT_U16, + .id = "caid", + .name = N_("CA ID"), + .desc = N_("Conditional Access Identification."), + .off = offsetof(constcw_t, ccw_caid), + .opts = PO_HEXA, + .def.u16 = 0x2600, + .group = 2, + }, + { + .type = PT_U32, + .id = "providerid", + .name = N_("Provider ID"), + .desc = N_("The provider's ID."), + .off = offsetof(constcw_t, ccw_providerid), + .opts = PO_HEXA, + .def.u32 = 0, + .group = 2, + }, + { + .type = PT_U16, + .id = "tsid", + .name = N_("Transponder ID"), + .desc = N_("The transponder ID."), + .off = offsetof(constcw_t, ccw_tsid), + .opts = PO_HEXA, + .def.u16 = 1, + .group = 2, + }, + { + .type = PT_U16, + .id = "sid", + .name = N_("Service ID"), + .desc = N_("The service ID"), + .off = offsetof(constcw_t, ccw_sid), + .opts = PO_HEXA, + .def.u16 = 1, + .group = 2, + }, + { + .type = PT_STR, + .id = "key_even", + .name = N_("Even key"), + .desc = N_("Even key."), + .set = constcw_class_key_even_set, + .get = constcw_class_key_even_get, + .opts = PO_PASSWORD, + .def.s = "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00", + .group = 3, + }, + { + .type = PT_STR, + .id = "key_odd", + .name = N_("Odd key"), + .desc = N_("Odd key."), + .set = constcw_class_key_odd_set, + .get = constcw_class_key_odd_get, + .opts = PO_PASSWORD, + .def.s = "00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00", + .group = 3, + }, + {}}}; /* * */ -caclient_t *constcw_create(void) -{ - constcw_t *ccw = calloc(1, sizeof(*ccw)); +caclient_t* constcw_create(void) { + constcw_t* ccw = calloc(1, sizeof(*ccw)); ccw->cac_free = constcw_free; ccw->cac_start = constcw_service_start; ccw->cac_conf_changed = constcw_conf_changed; - return (caclient_t *)ccw; + return (caclient_t*)ccw; } diff --git a/src/descrambler/cwc.c b/src/descrambler/cwc.c index 4f89a5eaa..56907e5b8 100644 --- a/src/descrambler/cwc.c +++ b/src/descrambler/cwc.c @@ -54,7 +54,6 @@ typedef enum { MSG_KEEPALIVE = CWS_FIRSTCMDNO + 0x1d } net_msg_type_t; - /** * */ @@ -66,49 +65,45 @@ typedef struct cwc { /* From configuration */ uint8_t cwc_confedkey[14]; - char *cwc_password_salted; /* salted version */ + char* cwc_password_salted; /* salted version */ } cwc_t; - /** * */ -static char * crypt_md5(const char *pw, const char *salt); +static char* crypt_md5(const char* pw, const char* salt); /** * */ -static void -des_key_parity_adjust(uint8_t *key, uint8_t len) -{ +static void des_key_parity_adjust(uint8_t* key, uint8_t len) { uint8_t i, j, parity; - + for (i = 0; i < len; i++) { parity = 1; - for (j = 1; j < 8; j++) if ((key[i] >> j) & 0x1) parity = ~parity & 0x01; + for (j = 1; j < 8; j++) + if ((key[i] >> j) & 0x1) + parity = ~parity & 0x01; key[i] |= parity; } } - /** * */ -static void -des_key_spread(uint8_t *normal, uint8_t *spread) -{ - spread[ 0] = normal[ 0] & 0xfe; - spread[ 1] = ((normal[ 0] << 7) | (normal[ 1] >> 1)) & 0xfe; - spread[ 2] = ((normal[ 1] << 6) | (normal[ 2] >> 2)) & 0xfe; - spread[ 3] = ((normal[ 2] << 5) | (normal[ 3] >> 3)) & 0xfe; - spread[ 4] = ((normal[ 3] << 4) | (normal[ 4] >> 4)) & 0xfe; - spread[ 5] = ((normal[ 4] << 3) | (normal[ 5] >> 5)) & 0xfe; - spread[ 6] = ((normal[ 5] << 2) | (normal[ 6] >> 6)) & 0xfe; - spread[ 7] = normal[ 6] << 1; - spread[ 8] = normal[ 7] & 0xfe; - spread[ 9] = ((normal[ 7] << 7) | (normal[ 8] >> 1)) & 0xfe; - spread[10] = ((normal[ 8] << 6) | (normal[ 9] >> 2)) & 0xfe; - spread[11] = ((normal[ 9] << 5) | (normal[10] >> 3)) & 0xfe; +static void des_key_spread(uint8_t* normal, uint8_t* spread) { + spread[0] = normal[0] & 0xfe; + spread[1] = ((normal[0] << 7) | (normal[1] >> 1)) & 0xfe; + spread[2] = ((normal[1] << 6) | (normal[2] >> 2)) & 0xfe; + spread[3] = ((normal[2] << 5) | (normal[3] >> 3)) & 0xfe; + spread[4] = ((normal[3] << 4) | (normal[4] >> 4)) & 0xfe; + spread[5] = ((normal[4] << 3) | (normal[5] >> 5)) & 0xfe; + spread[6] = ((normal[5] << 2) | (normal[6] >> 6)) & 0xfe; + spread[7] = normal[6] << 1; + spread[8] = normal[7] & 0xfe; + spread[9] = ((normal[7] << 7) | (normal[8] >> 1)) & 0xfe; + spread[10] = ((normal[8] << 6) | (normal[9] >> 2)) & 0xfe; + spread[11] = ((normal[9] << 5) | (normal[10] >> 3)) & 0xfe; spread[12] = ((normal[10] << 4) | (normal[11] >> 4)) & 0xfe; spread[13] = ((normal[11] << 3) | (normal[12] >> 5)) & 0xfe; spread[14] = ((normal[12] << 2) | (normal[13] >> 6)) & 0xfe; @@ -120,26 +115,27 @@ des_key_spread(uint8_t *normal, uint8_t *spread) /** * */ -static int -des_encrypt(uint8_t *buffer, int len, cwc_t *cwc) -{ - uint8_t checksum = 0, *ptr, noPadBytes, padBytes[7]; +static int des_encrypt(uint8_t* buffer, int len, cwc_t* cwc) { + uint8_t checksum = 0, *ptr, noPadBytes, padBytes[7]; DES_cblock ivec; - int i; + int i; noPadBytes = (8 - ((len - 1) % 8)) % 8; - if (len + noPadBytes + 1 >= CWS_NETMSGSIZE-8) return -1; + if (len + noPadBytes + 1 >= CWS_NETMSGSIZE - 8) + return -1; uuid_random(padBytes, noPadBytes); - for (i = 0; i < noPadBytes; i++) buffer[len++] = padBytes[i]; - for (i = 2; i < len; i++) checksum ^= buffer[i]; + for (i = 0; i < noPadBytes; i++) + buffer[len++] = padBytes[i]; + for (i = 2; i < len; i++) + checksum ^= buffer[i]; buffer[len++] = checksum; - uuid_random((uint8_t *)ivec, 8); - memcpy(buffer+len, ivec, 8); + uuid_random((uint8_t*)ivec, 8); + memcpy(buffer + len, ivec, 8); for (i = 2; i < len; i += 8) { ptr = buffer + i; DES_ncbc_encrypt(ptr, ptr, 8, &cwc->cwc_k1, &ivec, 1); - DES_ecb_encrypt((DES_cblock *)ptr, (DES_cblock *)ptr, &cwc->cwc_k2, 0); - DES_ecb_encrypt((DES_cblock *)ptr, (DES_cblock *)ptr, &cwc->cwc_k1, 1); + DES_ecb_encrypt((DES_cblock*)ptr, (DES_cblock*)ptr, &cwc->cwc_k2, 0); + DES_ecb_encrypt((DES_cblock*)ptr, (DES_cblock*)ptr, &cwc->cwc_k1, 1); memcpy(ivec, ptr, 8); } return len + 8; @@ -148,55 +144,53 @@ des_encrypt(uint8_t *buffer, int len, cwc_t *cwc) /** * */ -static int -des_decrypt(uint8_t *buffer, int len, cwc_t *cwc) -{ +static int des_decrypt(uint8_t* buffer, int len, cwc_t* cwc) { DES_cblock ivec, nextIvec; - uint8_t *ptr, checksum = 0;; + uint8_t * ptr, checksum = 0; + ; int i; - if ((len-2) % 8 || (len-2) < 16) return -1; + if ((len - 2) % 8 || (len - 2) < 16) + return -1; len -= 8; - memcpy(nextIvec, buffer+len, 8); + memcpy(nextIvec, buffer + len, 8); for (i = 2; i < len; i += 8) { ptr = buffer + i; memcpy(ivec, nextIvec, 8); memcpy(nextIvec, ptr, 8); - DES_ecb_encrypt((DES_cblock *)ptr, (DES_cblock *)ptr, &cwc->cwc_k1, 0); - DES_ecb_encrypt((DES_cblock *)ptr, (DES_cblock *)ptr, &cwc->cwc_k2, 1); + DES_ecb_encrypt((DES_cblock*)ptr, (DES_cblock*)ptr, &cwc->cwc_k1, 0); + DES_ecb_encrypt((DES_cblock*)ptr, (DES_cblock*)ptr, &cwc->cwc_k2, 1); DES_ncbc_encrypt(ptr, ptr, 8, &cwc->cwc_k1, &ivec, 0); - } + } tvhlog_hexdump(cwc->cc_subsys, buffer, len); - for (i = 2; i < len; i++) checksum ^= buffer[i]; - if (checksum) return -1; + for (i = 2; i < len; i++) + checksum ^= buffer[i]; + if (checksum) + return -1; return len; } /** * */ -static void -des_make_login_key(cwc_t *cwc, uint8_t *k) -{ +static void des_make_login_key(cwc_t* cwc, uint8_t* k) { uint8_t des14[14], spread[16]; - int i; + int i; - for (i = 0; i < 14; i++) + for (i = 0; i < 14; i++) des14[i] = cwc->cwc_confedkey[i] ^ k[i]; des_key_spread(des14, spread); - DES_set_key_unchecked((DES_cblock *)spread, &cwc->cwc_k1); - DES_set_key_unchecked((DES_cblock *)(spread+8), &cwc->cwc_k2); + DES_set_key_unchecked((DES_cblock*)spread, &cwc->cwc_k1); + DES_set_key_unchecked((DES_cblock*)(spread + 8), &cwc->cwc_k2); } /** * */ -static void -des_make_session_key(cwc_t *cwc) -{ - uint8_t des14[14], spread[16], *k2 = (uint8_t *)cwc->cwc_password_salted; - int i, l = strlen(cwc->cwc_password_salted); +static void des_make_session_key(cwc_t* cwc) { + uint8_t des14[14], spread[16], *k2 = (uint8_t*)cwc->cwc_password_salted; + int i, l = strlen(cwc->cwc_password_salted); memcpy(des14, cwc->cwc_confedkey, 14); @@ -204,23 +198,26 @@ des_make_session_key(cwc_t *cwc) des14[i % 14] ^= k2[i]; des_key_spread(des14, spread); - DES_set_key_unchecked((DES_cblock *)spread, &cwc->cwc_k1); - DES_set_key_unchecked((DES_cblock *)(spread+8), &cwc->cwc_k2); + DES_set_key_unchecked((DES_cblock*)spread, &cwc->cwc_k1); + DES_set_key_unchecked((DES_cblock*)(spread + 8), &cwc->cwc_k2); } /** * Note, this function is called from multiple threads so beware of * the ID) */ -static int -cwc_send_msg(void *cc, const uint8_t *msg, size_t len, - int sid, int enq, uint16_t st_caid, uint32_t st_provider, - uint16_t *_seq) -{ - cwc_t *cwc = cc; - cc_message_t *cm; - uint8_t *buf; - int seq, ret; +static int cwc_send_msg(void* cc, + const uint8_t* msg, + size_t len, + int sid, + int enq, + uint16_t st_caid, + uint32_t st_provider, + uint16_t* _seq) { + cwc_t* cwc = cc; + cc_message_t* cm; + uint8_t* buf; + int seq, ret; if (len < 3) return -1; @@ -233,20 +230,20 @@ cwc_send_msg(void *cc, const uint8_t *msg, size_t len, seq = atomic_add(&cwc->cc_seq, 1); - buf = cm->cm_data; + buf = cm->cm_data; buf[0] = buf[1] = 0; - buf[2] = (seq >> 8) & 0xff; - buf[3] = seq & 0xff; - buf[4] = (sid >> 8) & 0xff; - buf[5] = sid & 0xff; - buf[6] = (st_caid >> 8) & 0xff; - buf[7] = st_caid & 0xff; - buf[8] = (st_provider >> 16) & 0xff; - buf[9] = (st_provider >> 8) & 0xff; - buf[10] = st_provider & 0xff; - buf[11] = (st_provider >> 24) & 0xff; // used for mgcamd - - memcpy(buf+12, msg, len); + buf[2] = (seq >> 8) & 0xff; + buf[3] = seq & 0xff; + buf[4] = (sid >> 8) & 0xff; + buf[5] = sid & 0xff; + buf[6] = (st_caid >> 8) & 0xff; + buf[7] = st_caid & 0xff; + buf[8] = (st_provider >> 16) & 0xff; + buf[9] = (st_provider >> 8) & 0xff; + buf[10] = st_provider & 0xff; + buf[11] = (st_provider >> 24) & 0xff; // used for mgcamd + + memcpy(buf + 12, msg, len); // adding packet header size len += 12; @@ -271,9 +268,7 @@ cwc_send_msg(void *cc, const uint8_t *msg, size_t len, /** * Card data command */ -static void -cwc_send_data_req(cwc_t *cwc) -{ +static void cwc_send_data_req(cwc_t* cwc) { uint8_t buf[3]; buf[0] = MSG_CARD_DATA_REQ; @@ -283,14 +278,11 @@ cwc_send_data_req(cwc_t *cwc) cwc_send_msg(cwc, buf, 3, 0, 0, 0, 1, NULL); } - /** * Send keep alive */ -static void -cwc_send_ka(void *cc) -{ - cwc_t *cwc = cc; +static void cwc_send_ka(void* cc) { + cwc_t* cwc = cc; uint8_t buf[3]; buf[0] = MSG_KEEPALIVE; @@ -303,41 +295,38 @@ cwc_send_ka(void *cc) /** * Handle reply to card data request */ -static int -cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len) -{ - int plen, i; +static int cwc_decode_card_data_reply(cwc_t* cwc, uint8_t* msg, int len) { + int plen, i; unsigned int nprov; - uint8_t **pid, **psa, *msg2; + uint8_t ** pid, **psa, *msg2; msg += 12; len -= 12; - if(len < 3) { + if (len < 3) { tvhinfo(cwc->cc_subsys, "%s: Invalid card data reply", cwc->cc_name); return -1; } plen = (msg[1] & 0xf) << 8 | msg[2]; - if(plen < 14) { + if (plen < 14) { tvhinfo(cwc->cc_subsys, "%s: Invalid card data reply (message)", cwc->cc_name); return -1; } nprov = msg[14]; - msg2 = msg + 15; + msg2 = msg + 15; plen -= 12; - if(plen < nprov * 11) { - tvhinfo(cwc->cc_subsys, "%s: Invalid card data reply (provider list)", - cwc->cc_name); + if (plen < nprov * 11) { + tvhinfo(cwc->cc_subsys, "%s: Invalid card data reply (provider list)", cwc->cc_name); return -1; } - pid = nprov ? alloca(nprov * sizeof(uint8_t *)) : NULL; - psa = nprov ? alloca(nprov * sizeof(uint8_t *)) : NULL; + pid = nprov ? alloca(nprov * sizeof(uint8_t*)) : NULL; + psa = nprov ? alloca(nprov * sizeof(uint8_t*)) : NULL; for (i = 0; i < nprov; i++) { pid[i] = msg2; @@ -345,9 +334,8 @@ cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len) msg2 += 11; } - caclient_set_status((caclient_t *)cwc, CACLIENT_STATUS_CONNECTED); - cc_new_card((cclient_t *)cwc, (msg[4] << 8) | msg[5], - 0, msg + 6, nprov, pid, psa, 0); + caclient_set_status((caclient_t*)cwc, CACLIENT_STATUS_CONNECTED); + cc_new_card((cclient_t*)cwc, (msg[4] << 8) | msg[5], 0, msg + 6, nprov, pid, psa, 0); return 0; } @@ -355,14 +343,11 @@ cwc_decode_card_data_reply(cwc_t *cwc, uint8_t *msg, int len) /** * Login command */ -static int -cwc_send_login(cwc_t *cwc) -{ +static int cwc_send_login(cwc_t* cwc) { uint8_t buf[CWS_NETMSGSIZE]; - size_t ul, pl; + size_t ul, pl; - if (cwc->cc_username == NULL || - cwc->cwc_password_salted == NULL) + if (cwc->cc_username == NULL || cwc->cwc_password_salted == NULL) return 1; ul = strlen(cwc->cc_username) + 1; @@ -374,7 +359,7 @@ cwc_send_login(cwc_t *cwc) buf[0] = MSG_CLIENT_2_SERVER_LOGIN; buf[1] = 0; buf[2] = ul + pl; - memcpy(buf + 3, cwc->cc_username, ul); + memcpy(buf + 3, cwc->cc_username, ul); memcpy(buf + 3 + ul, cwc->cwc_password_salted, pl); cwc_send_msg(cwc, buf, ul + pl + 3, TVHEADEND_PROTOCOL_ID, 0, 0, 0, NULL); @@ -386,12 +371,10 @@ cwc_send_login(cwc_t *cwc) * */ static void -handle_ecm_reply(cc_service_t *ct, cc_ecm_section_t *es, - uint8_t *msg, int len, int seq) -{ - cwc_t *cwc = ct->cs_client; +handle_ecm_reply(cc_service_t* ct, cc_ecm_section_t* es, uint8_t* msg, int len, int seq) { + cwc_t* cwc = ct->cs_client; uint32_t off; - int type; + int type; if (len < 19) { cc_ecm_reply(ct, es, DESCRAMBLER_NONE, NULL, NULL, seq); @@ -400,11 +383,10 @@ handle_ecm_reply(cc_service_t *ct, cc_ecm_section_t *es, if (len <= 22) { off = 8; } else if (len <= 40) { - off = 16; + off = 16; type = DESCRAMBLER_AES128_ECB; } else { - tvherror(cwc->cc_subsys, "%s: wrong ECM reply length %d", - cwc->cc_name, len); + tvherror(cwc->cc_subsys, "%s: wrong ECM reply length %d", cwc->cc_name, len); return; } cc_ecm_reply(ct, es, type, msg + 3, msg + 3 + off, seq); @@ -415,28 +397,25 @@ handle_ecm_reply(cc_service_t *ct, cc_ecm_section_t *es, * Handle running reply * cwc_mutex is held */ -static int -cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len) -{ - cc_service_t *ct; - cc_ecm_section_t *es; - uint16_t seq; - int plen; - short caid; - uint8_t *u8; - - switch(msgtype) { +static int cwc_running_reply(cwc_t* cwc, uint8_t msgtype, uint8_t* msg, int len) { + cc_service_t* ct; + cc_ecm_section_t* es; + uint16_t seq; + int plen; + short caid; + uint8_t* u8; + + switch (msgtype) { case 0x80: case 0x81: if (len < 12) { - tvherror(cwc->cc_subsys, "%s: wrong 0x%02X length %d", - cwc->cc_name, msgtype, len); + tvherror(cwc->cc_subsys, "%s: wrong 0x%02X length %d", cwc->cc_name, msgtype, len); return -1; } seq = (msg[2] << 8) | msg[3]; len -= 12; msg += 12; - es = cc_find_pending_section((cclient_t *)cwc, seq, &ct); + es = cc_find_pending_section((cclient_t*)cwc, seq, &ct); if (es) handle_ecm_reply(ct, es, msg, len, seq); break; @@ -462,19 +441,23 @@ cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len) return -1; } - caclient_set_status((caclient_t *)cwc, CACLIENT_STATUS_CONNECTED); - + caclient_set_status((caclient_t*)cwc, CACLIENT_STATUS_CONNECTED); + u8 = &msg[8]; if (caid_is_betacrypt(caid) || caid_is_irdeto(caid)) { - const char *n = caid2name(caid) ?: "Unknown"; - uint32_t provid = (u8[0] << 16) | (u8[1] << 8) | u8[0]; + const char* n = caid2name(caid) ?: "Unknown"; + uint32_t provid = (u8[0] << 16) | (u8[1] << 8) | u8[0]; if (provid != 0) { - tvhdebug(cwc->cc_subsys, "%s: Bad provider for %s-card [CAID:%04X Provider:0x%06X], using zero", - cwc->cc_name, n, caid, provid); + tvhdebug(cwc->cc_subsys, + "%s: Bad provider for %s-card [CAID:%04X Provider:0x%06X], using zero", + cwc->cc_name, + n, + caid, + provid); memset(u8, 0, 3); } } - cc_new_card((cclient_t *)cwc, caid, 0, NULL, 1, &u8, NULL, 1); + cc_new_card((cclient_t*)cwc, caid, 0, NULL, 1, &u8, NULL, 1); } } return 0; @@ -483,23 +466,19 @@ cwc_running_reply(cwc_t *cwc, uint8_t msgtype, uint8_t *msg, int len) /** * */ -static int -cwc_read_message0 - (cwc_t *cwc, const char *state, sbuf_t *rbuf, int *rsize, int timeout) -{ +static int cwc_read_message0(cwc_t* cwc, const char* state, sbuf_t* rbuf, int* rsize, int timeout) { int msglen; if (rbuf->sb_ptr < 2) return 0; msglen = (rbuf->sb_data[0] << 8) | rbuf->sb_data[1]; - if(rbuf->sb_ptr < 2 + msglen) + if (rbuf->sb_ptr < 2 + msglen) return 0; *rsize = msglen + 2; - if((msglen = des_decrypt(rbuf->sb_data, msglen + 2, cwc)) < 15) { - tvhinfo(cwc->cc_subsys, "%s: %s: Decrypt failed", - cwc->cc_name, state); + if ((msglen = des_decrypt(rbuf->sb_data, msglen + 2, cwc)) < 15) { + tvhinfo(cwc->cc_subsys, "%s: %s: Decrypt failed", cwc->cc_name, state); return -1; } @@ -512,40 +491,33 @@ cwc_read_message0 /** * */ -static int -cwc_read_message - (cwc_t *cwc, const char *state, uint8_t *buf, int len, int timeout) -{ +static int cwc_read_message(cwc_t* cwc, const char* state, uint8_t* buf, int len, int timeout) { int msglen, r; - if ((r = cc_read((cclient_t *)cwc, buf, 2, timeout))) { + if ((r = cc_read((cclient_t*)cwc, buf, 2, timeout))) { if (tvheadend_is_running()) - tvhinfo(cwc->cc_subsys, "%s: %s: Read error (header): %s", - cwc->cc_name, state, strerror(r)); + tvhinfo(cwc->cc_subsys, "%s: %s: Read error (header): %s", cwc->cc_name, state, strerror(r)); return -1; } msglen = (buf[0] << 8) | buf[1]; if (msglen > len) { if (tvheadend_is_running()) - tvhinfo(cwc->cc_subsys, "%s: %s: Invalid message size: %d", - cwc->cc_name, state, msglen); + tvhinfo(cwc->cc_subsys, "%s: %s: Invalid message size: %d", cwc->cc_name, state, msglen); return -1; } /* We expect the rest of the message to arrive fairly quick, so just wait 1 second here */ - if ((r = cc_read((cclient_t *)cwc, buf + 2, msglen, 1000))) { + if ((r = cc_read((cclient_t*)cwc, buf + 2, msglen, 1000))) { if (tvheadend_is_running()) - tvhinfo(cwc->cc_subsys, "%s: %s: Read error: %s", - cwc->cc_name, state, strerror(r)); + tvhinfo(cwc->cc_subsys, "%s: %s: Read error: %s", cwc->cc_name, state, strerror(r)); return -1; } if ((msglen = des_decrypt(buf, msglen + 2, cwc)) < 15) { - tvhinfo(cwc->cc_subsys, "%s: %s: Decrypt failed", - cwc->cc_name, state); + tvhinfo(cwc->cc_subsys, "%s: %s: Decrypt failed", cwc->cc_name, state); return -1; } @@ -558,19 +530,16 @@ cwc_read_message /** * */ -static int -cwc_init_session(void *cc) -{ - cwc_t *cwc = cc; +static int cwc_init_session(void* cc) { + cwc_t* cwc = cc; uint8_t buf[CWS_NETMSGSIZE]; - int r; + int r; /** * Get login key */ - if ((r = cc_read((cclient_t *)cwc, buf, 14, 5000))) { - tvhinfo(cwc->cc_subsys, "%s: No login key received: %s", - cwc->cc_name, strerror(r)); + if ((r = cc_read((cclient_t*)cwc, buf, 14, 5000))) { + tvhinfo(cwc->cc_subsys, "%s: No login key received: %s", cwc->cc_name, strerror(r)); return -1; } @@ -581,7 +550,7 @@ cwc_init_session(void *cc) */ if (cwc_send_login(cwc)) return -1; - + if (cwc_read_message(cwc, "Wait login response", buf, sizeof(buf), 5000) < 0) return -1; @@ -612,12 +581,10 @@ cwc_init_session(void *cc) /** * */ -static int -cwc_read(void *cc, sbuf_t *rbuf) -{ - cwc_t *cwc = cc; +static int cwc_read(void* cc, sbuf_t* rbuf) { + cwc_t* cwc = cc; const int ka_interval = cwc->cc_keepalive_interval * 2 * 1000; - int r, rsize; + int r, rsize; while (1) { r = cwc_read_message0(cwc, "DecoderLoop", rbuf, &rsize, ka_interval); @@ -639,14 +606,16 @@ cwc_read(void *cc, sbuf_t *rbuf) /** * */ -static int -cwc_send_ecm(void *cc, cc_service_t *ct, cc_ecm_section_t *es, - cc_card_data_t *pcard, const uint8_t *data, int len) -{ - mpegts_service_t *t = (mpegts_service_t *)ct->td_service; - uint16_t sid = service_id16(t); - uint16_t seq; - int r; +static int cwc_send_ecm(void* cc, + cc_service_t* ct, + cc_ecm_section_t* es, + cc_card_data_t* pcard, + const uint8_t* data, + int len) { + mpegts_service_t* t = (mpegts_service_t*)ct->td_service; + uint16_t sid = service_id16(t); + uint16_t seq; + int r; r = cwc_send_msg(cc, data, len, sid, 1, es->es_caid, es->es_provid, &seq); if (r == 0) @@ -657,16 +626,17 @@ cwc_send_ecm(void *cc, cc_service_t *ct, cc_ecm_section_t *es, /** * */ -static void -cwc_send_emm(void *cc, cc_service_t *ct, - cc_card_data_t *pcard, uint32_t provid, - const uint8_t *data, int len) -{ - mpegts_service_t *t; - uint16_t sid = 0; +static void cwc_send_emm(void* cc, + cc_service_t* ct, + cc_card_data_t* pcard, + uint32_t provid, + const uint8_t* data, + int len) { + mpegts_service_t* t; + uint16_t sid = 0; if (ct) { - t = (mpegts_service_t *)ct->td_service; + t = (mpegts_service_t*)ct->td_service; sid = service_id16(t); } @@ -676,44 +646,37 @@ cwc_send_emm(void *cc, cc_service_t *ct, /** * */ -static void -cwc_free(caclient_t *cac) -{ - cwc_t *cwc = (cwc_t *)cac; - char *salted = cwc->cwc_password_salted; +static void cwc_free(caclient_t* cac) { + cwc_t* cwc = (cwc_t*)cac; + char* salted = cwc->cwc_password_salted; cc_free(cac); - free((void *)salted); + free((void*)salted); } /** * */ -static int -nibble(char c) -{ - switch(c) { - case '0' ... '9': - return c - '0'; - case 'a' ... 'f': - return c - 'a' + 10; - case 'A' ... 'F': - return c - 'A' + 10; - default: - return 0; +static int nibble(char c) { + switch (c) { + case '0' ... '9': + return c - '0'; + case 'a' ... 'f': + return c - 'a' + 10; + case 'A' ... 'F': + return c - 'A' + 10; + default: + return 0; } } /** * */ -static void -cwc_conf_changed(caclient_t *cac) -{ - cwc_t *cwc = (cwc_t *)cac; +static void cwc_conf_changed(caclient_t* cac) { + cwc_t* cwc = (cwc_t*)cac; free(cwc->cwc_password_salted); - cwc->cwc_password_salted = - cwc->cc_password ? crypt_md5(cwc->cc_password, "$1$abcdefgh$") : NULL; + cwc->cwc_password_salted = cwc->cc_password ? crypt_md5(cwc->cc_password, "$1$abcdefgh$") : NULL; cc_conf_changed(cac); } @@ -721,19 +684,19 @@ cwc_conf_changed(caclient_t *cac) /** * */ -static int -caclient_cwc_class_deskey_set(void *o, const void *v) -{ - cwc_t *cwc = o; - const char *s = v ?: ""; - uint8_t key[14]; - int i, u, l; - - for(i = 0; i < ARRAY_SIZE(key); i++) { - while(*s != 0 && !isxdigit(*s)) s++; +static int caclient_cwc_class_deskey_set(void* o, const void* v) { + cwc_t* cwc = o; + const char* s = v ?: ""; + uint8_t key[14]; + int i, u, l; + + for (i = 0; i < ARRAY_SIZE(key); i++) { + while (*s != 0 && !isxdigit(*s)) + s++; u = *s ? nibble(*s++) : 0; - while(*s != 0 && !isxdigit(*s)) s++; - l = *s ? nibble(*s++) : 0; + while (*s != 0 && !isxdigit(*s)) + s++; + l = *s ? nibble(*s++) : 0; key[i] = (u << 4) | l; } i = memcmp(cwc->cwc_confedkey, key, ARRAY_SIZE(key)) != 0; @@ -741,74 +704,67 @@ caclient_cwc_class_deskey_set(void *o, const void *v) return i; } -static const void * -caclient_cwc_class_deskey_get(void *o) -{ - cwc_t *cwc = o; - snprintf(prop_sbuf, PROP_SBUF_LEN, - "%02x:%02x:%02x:%02x:%02x:%02x:%02x:" - "%02x:%02x:%02x:%02x:%02x:%02x:%02x", - cwc->cwc_confedkey[0x0], - cwc->cwc_confedkey[0x1], - cwc->cwc_confedkey[0x2], - cwc->cwc_confedkey[0x3], - cwc->cwc_confedkey[0x4], - cwc->cwc_confedkey[0x5], - cwc->cwc_confedkey[0x6], - cwc->cwc_confedkey[0x7], - cwc->cwc_confedkey[0x8], - cwc->cwc_confedkey[0x9], - cwc->cwc_confedkey[0xa], - cwc->cwc_confedkey[0xb], - cwc->cwc_confedkey[0xc], - cwc->cwc_confedkey[0xd]); +static const void* caclient_cwc_class_deskey_get(void* o) { + cwc_t* cwc = o; + snprintf(prop_sbuf, + PROP_SBUF_LEN, + "%02x:%02x:%02x:%02x:%02x:%02x:%02x:" + "%02x:%02x:%02x:%02x:%02x:%02x:%02x", + cwc->cwc_confedkey[0x0], + cwc->cwc_confedkey[0x1], + cwc->cwc_confedkey[0x2], + cwc->cwc_confedkey[0x3], + cwc->cwc_confedkey[0x4], + cwc->cwc_confedkey[0x5], + cwc->cwc_confedkey[0x6], + cwc->cwc_confedkey[0x7], + cwc->cwc_confedkey[0x8], + cwc->cwc_confedkey[0x9], + cwc->cwc_confedkey[0xa], + cwc->cwc_confedkey[0xb], + cwc->cwc_confedkey[0xc], + cwc->cwc_confedkey[0xd]); return &prop_sbuf_ptr; } -const idclass_t caclient_cwc_class = -{ - .ic_super = &caclient_cc_class, - .ic_class = "caclient_cwc", - .ic_caption = N_("Code Word Client (newcamd)"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "deskey", - .name = N_("DES key"), - .desc = N_("DES Key."), - .set = caclient_cwc_class_deskey_set, - .get = caclient_cwc_class_deskey_get, - .opts = PO_PASSWORD, - .def.s = "00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d", - .group = 2, - }, - { } - } -}; +const idclass_t caclient_cwc_class = {.ic_super = &caclient_cc_class, + .ic_class = "caclient_cwc", + .ic_caption = N_("Code Word Client (newcamd)"), + .ic_properties = (const property_t[]){{ + .type = PT_STR, + .id = "deskey", + .name = N_("DES key"), + .desc = N_("DES Key."), + .set = caclient_cwc_class_deskey_set, + .get = caclient_cwc_class_deskey_get, + .opts = PO_PASSWORD, + .def.s = "00:01:02:03:04:05:06:07:08:09:0a:0b:0c:0d", + .group = 2, + }, + {}}}; /* * */ -caclient_t *cwc_create(void) -{ - cwc_t *cwc = calloc(1, sizeof(*cwc)); +caclient_t* cwc_create(void) { + cwc_t* cwc = calloc(1, sizeof(*cwc)); cwc->cc_subsys = LS_CWC; cwc->cc_id = "newcamd"; tvh_mutex_init(&cwc->cc_mutex, NULL); tvh_cond_init(&cwc->cc_cond, 1); - cwc->cac_free = cwc_free; - cwc->cac_start = cc_service_start; - cwc->cac_conf_changed = cwc_conf_changed; - cwc->cac_caid_update = cc_caid_update; + cwc->cac_free = cwc_free; + cwc->cac_start = cc_service_start; + cwc->cac_conf_changed = cwc_conf_changed; + cwc->cac_caid_update = cc_caid_update; cwc->cc_keepalive_interval = CC_KEEPALIVE_INTERVAL; - cwc->cc_init_session = cwc_init_session; - cwc->cc_read = cwc_read; - cwc->cc_send_ecm = cwc_send_ecm; - cwc->cc_send_emm = cwc_send_emm; - cwc->cc_keepalive = cwc_send_ka; - return (caclient_t *)cwc; + cwc->cc_init_session = cwc_init_session; + cwc->cc_read = cwc_read; + cwc->cc_send_ecm = cwc_send_ecm; + cwc->cc_send_emm = cwc_send_emm; + cwc->cc_keepalive = cwc_send_ka; + return (caclient_t*)cwc; } /* @@ -825,123 +781,132 @@ caclient_t *cwc_create(void) */ static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */ - "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; + "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; /* to64 BUFFER VALUE NUM * Write NUM base64 characters of VALUE into BUFFER. */ -static void to64(char *s, unsigned long v, int n) -{ - while (--n >= 0) { - *s++ = itoa64[v&0x3f]; - v >>= 6; - } +static void to64(char* s, unsigned long v, int n) { + while (--n >= 0) { + *s++ = itoa64[v & 0x3f]; + v >>= 6; + } } /* crypt_md5 PASSWORD SALT * Poul-Henning Kamp's crypt(3)-alike using MD5. */ -static char * -crypt_md5(const char *pw, const char *salt) -{ - const char *magic = "$1$"; - /* This string is magic for this algorithm. Having - * it this way, we can get get better later on */ - char *p; - const char *sp,*ep; - unsigned char final[16]; - int sl,pl,i,j; - MD5_CTX ctx,ctx1; - unsigned long l; - - /* Refine the Salt first */ - sp = salt; - - /* If it starts with the magic string, then skip that */ - if(!strncmp(sp,magic,strlen(magic))) - sp += strlen(magic); - - /* It stops at the first '$', max 8 chars */ - for(ep=sp;*ep && *ep != '$' && ep < (sp+8);ep++) - continue; - - /* get the length of the true salt */ - sl = ep - sp; - - MD5_Init(&ctx); - - /* The password first, since that is what is most unknown */ - MD5_Update(&ctx,(unsigned char *)pw,strlen(pw)); - - /* Then our magic string */ - MD5_Update(&ctx,(unsigned char *)magic,strlen(magic)); - - /* Then the raw salt */ - MD5_Update(&ctx,(unsigned char *)sp,sl); - - /* Then just as many characters of the MD5_(pw,salt,pw) */ +static char* crypt_md5(const char* pw, const char* salt) { + const char* magic = "$1$"; + /* This string is magic for this algorithm. Having + * it this way, we can get get better later on */ + char* p; + const char * sp, *ep; + unsigned char final[16]; + int sl, pl, i, j; + MD5_CTX ctx, ctx1; + unsigned long l; + + /* Refine the Salt first */ + sp = salt; + + /* If it starts with the magic string, then skip that */ + if (!strncmp(sp, magic, strlen(magic))) + sp += strlen(magic); + + /* It stops at the first '$', max 8 chars */ + for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++) + continue; + + /* get the length of the true salt */ + sl = ep - sp; + + MD5_Init(&ctx); + + /* The password first, since that is what is most unknown */ + MD5_Update(&ctx, (unsigned char*)pw, strlen(pw)); + + /* Then our magic string */ + MD5_Update(&ctx, (unsigned char*)magic, strlen(magic)); + + /* Then the raw salt */ + MD5_Update(&ctx, (unsigned char*)sp, sl); + + /* Then just as many characters of the MD5_(pw,salt,pw) */ + MD5_Init(&ctx1); + MD5_Update(&ctx1, (unsigned char*)pw, strlen(pw)); + MD5_Update(&ctx1, (unsigned char*)sp, sl); + MD5_Update(&ctx1, (unsigned char*)pw, strlen(pw)); + MD5_Final(final, &ctx1); + for (pl = strlen(pw); pl > 0; pl -= 16) + MD5_Update(&ctx, (unsigned char*) final, pl > 16 ? 16 : pl); + + /* Don't leave anything around in vm they could use. */ + memset(final, 0, sizeof final); + + /* Then something really weird... */ + for (j = 0, i = strlen(pw); i; i >>= 1) + if (i & 1) + MD5_Update(&ctx, (unsigned char*) final + j, 1); + else + MD5_Update(&ctx, (unsigned char*)pw + j, 1); + + /* Now make the output string */ + char* passwd = malloc(120); + + strcpy(passwd, magic); + strncat(passwd, sp, sl); + strcat(passwd, "$"); + + MD5_Final(final, &ctx); + + /* + * and now, just to make sure things don't run too fast + * On a 60 Mhz Pentium this takes 34 msec, so you would + * need 30 seconds to build a 1000 entry dictionary... + */ + for (i = 0; i < 1000; i++) { MD5_Init(&ctx1); - MD5_Update(&ctx1,(unsigned char *)pw,strlen(pw)); - MD5_Update(&ctx1,(unsigned char *)sp,sl); - MD5_Update(&ctx1,(unsigned char *)pw,strlen(pw)); - MD5_Final(final,&ctx1); - for(pl = strlen(pw); pl > 0; pl -= 16) - MD5_Update(&ctx,(unsigned char *)final,pl>16 ? 16 : pl); - - /* Don't leave anything around in vm they could use. */ - memset(final,0,sizeof final); - - /* Then something really weird... */ - for (j=0,i = strlen(pw); i ; i >>= 1) - if(i&1) - MD5_Update(&ctx, (unsigned char *)final+j, 1); - else - MD5_Update(&ctx, (unsigned char *)pw+j, 1); - - /* Now make the output string */ - char *passwd = malloc(120); - - strcpy(passwd,magic); - strncat(passwd,sp,sl); - strcat(passwd,"$"); - - MD5_Final(final,&ctx); - - /* - * and now, just to make sure things don't run too fast - * On a 60 Mhz Pentium this takes 34 msec, so you would - * need 30 seconds to build a 1000 entry dictionary... - */ - for(i=0;i<1000;i++) { - MD5_Init(&ctx1); - if(i & 1) - MD5_Update(&ctx1,(unsigned char *)pw,strlen(pw)); - else - MD5_Update(&ctx1,(unsigned char *)final,16); - - if(i % 3) - MD5_Update(&ctx1,(unsigned char *)sp,sl); - - if(i % 7) - MD5_Update(&ctx1,(unsigned char *)pw,strlen(pw)); - - if(i & 1) - MD5_Update(&ctx1,(unsigned char *)final,16); - else - MD5_Update(&ctx1,(unsigned char *)pw,strlen(pw)); - MD5_Final(final,&ctx1); - } - - p = passwd + strlen(passwd); - - l = (final[ 0]<<16) | (final[ 6]<<8) | final[12]; to64(p,l,4); p += 4; - l = (final[ 1]<<16) | (final[ 7]<<8) | final[13]; to64(p,l,4); p += 4; - l = (final[ 2]<<16) | (final[ 8]<<8) | final[14]; to64(p,l,4); p += 4; - l = (final[ 3]<<16) | (final[ 9]<<8) | final[15]; to64(p,l,4); p += 4; - l = (final[ 4]<<16) | (final[10]<<8) | final[ 5]; to64(p,l,4); p += 4; - l = final[11] ; to64(p,l,2); p += 2; - *p = '\0'; - - /* Don't leave anything around in vm they could use. */ - memset(final,0,sizeof final); + if (i & 1) + MD5_Update(&ctx1, (unsigned char*)pw, strlen(pw)); + else + MD5_Update(&ctx1, (unsigned char*) final, 16); + + if (i % 3) + MD5_Update(&ctx1, (unsigned char*)sp, sl); + + if (i % 7) + MD5_Update(&ctx1, (unsigned char*)pw, strlen(pw)); + + if (i & 1) + MD5_Update(&ctx1, (unsigned char*) final, 16); + else + MD5_Update(&ctx1, (unsigned char*)pw, strlen(pw)); + MD5_Final(final, &ctx1); + } - return passwd; + p = passwd + strlen(passwd); + + l = (final[0] << 16) | (final[6] << 8) | final[12]; + to64(p, l, 4); + p += 4; + l = (final[1] << 16) | (final[7] << 8) | final[13]; + to64(p, l, 4); + p += 4; + l = (final[2] << 16) | (final[8] << 8) | final[14]; + to64(p, l, 4); + p += 4; + l = (final[3] << 16) | (final[9] << 8) | final[15]; + to64(p, l, 4); + p += 4; + l = (final[4] << 16) | (final[10] << 8) | final[5]; + to64(p, l, 4); + p += 4; + l = final[11]; + to64(p, l, 2); + p += 2; + *p = '\0'; + + /* Don't leave anything around in vm they could use. */ + memset(final, 0, sizeof final); + + return passwd; } diff --git a/src/descrambler/descrambler.c b/src/descrambler/descrambler.c index df7be5826..9e1508cb4 100644 --- a/src/descrambler/descrambler.c +++ b/src/descrambler/descrambler.c @@ -30,24 +30,25 @@ #include "streaming.h" #if 0 -#define DEBUG2 1 +#define DEBUG2 1 #define debug2(fmt, ...) tvhtrace(LS_DESCRAMBLER, fmt, ##__VA_ARGS__) #else #undef DEBUG2 -#define debug2(fmt, ...) do { } while(0) +#define debug2(fmt, ...) \ + do { \ + } while (0) #endif - -#define ECM_PARITY_DEFAULT 0 -#define ECM_PARITY_80EVEN_81ODD 1 -#define ECM_PARITY_81EVEN_80ODD 2 +#define ECM_PARITY_DEFAULT 0 +#define ECM_PARITY_80EVEN_81ODD 1 +#define ECM_PARITY_81EVEN_80ODD 2 typedef struct th_descrambler_data { TAILQ_ENTRY(th_descrambler_data) dd_link; - int64_t dd_timestamp; - sbuf_t dd_sbuf; - th_descrambler_key_t *dd_key; - uint8_t dd_key_changed; + int64_t dd_timestamp; + sbuf_t dd_sbuf; + th_descrambler_key_t* dd_key; + uint8_t dd_key_changed; } th_descrambler_data_t; typedef struct th_descrambler_hint { @@ -57,27 +58,25 @@ typedef struct th_descrambler_hint { uint32_t dh_interval; uint32_t dh_paritycheck; uint32_t dh_ecmparity; - uint32_t dh_constcw: 1; - uint32_t dh_quickecm: 1; - uint32_t dh_multipid: 1; + uint32_t dh_constcw : 1; + uint32_t dh_quickecm : 1; + uint32_t dh_multipid : 1; } th_descrambler_hint_t; TAILQ_HEAD(th_descrambler_queue, th_descrambler_data); -static TAILQ_HEAD( , th_descrambler_hint) ca_hints; +static TAILQ_HEAD(, th_descrambler_hint) ca_hints; static int ca_hints_quickecm; /* * */ -static inline int extractpid(const uint8_t *tsb) -{ +static inline int extractpid(const uint8_t* tsb) { return (tsb[1] & 0x1f) << 8 | tsb[2]; } #if DEBUG2 -static inline const char *keystr(const uint8_t *tsb) -{ +static inline const char* keystr(const uint8_t* tsb) { uint8_t b = tsb[3]; if (b & 0x80) return (b & 0x40) ? "odd" : "even"; @@ -89,12 +88,10 @@ static inline const char *keystr(const uint8_t *tsb) * */ static void -descrambler_data_destroy(th_descrambler_runtime_t *dr, th_descrambler_data_t *dd, int skip) -{ +descrambler_data_destroy(th_descrambler_runtime_t* dr, th_descrambler_data_t* dd, int skip) { if (dd) { if (skip && dr->dr_skip) - ts_skip_packet2((mpegts_service_t *)dr->dr_service, - dd->dd_sbuf.sb_data, dd->dd_sbuf.sb_ptr); + ts_skip_packet2((mpegts_service_t*)dr->dr_service, dd->dd_sbuf.sb_data, dd->dd_sbuf.sb_ptr); dr->dr_queue_total -= dd->dd_sbuf.sb_ptr; TAILQ_REMOVE(&dr->dr_queue, dd, dd_link); sbuf_free(&dd->dd_sbuf); @@ -106,12 +103,10 @@ descrambler_data_destroy(th_descrambler_runtime_t *dr, th_descrambler_data_t *dd } } -static void -descrambler_data_append(th_descrambler_runtime_t *dr, const uint8_t *tsb, int len) -{ - th_descrambler_data_t *dd; - const uint8_t *tsb0; - uint16_t pid1, pid2; +static void descrambler_data_append(th_descrambler_runtime_t* dr, const uint8_t* tsb, int len) { + th_descrambler_data_t* dd; + const uint8_t* tsb0; + uint16_t pid1, pid2; if (len == 0) return; @@ -126,50 +121,66 @@ descrambler_data_append(th_descrambler_runtime_t *dr, const uint8_t *tsb, int le if (dd && monocmpfastsec(dd->dd_timestamp, mclk()) && (tsb0[3] & 0xc0) == (tsb[3] & 0xc0) && /* key match */ pid1 == pid2) { - debug2("%p: data append %d, timestamp %ld, %s[%d]", dr, len, dd->dd_timestamp, keystr(tsb0), extractpid(tsb0)); + debug2("%p: data append %d, timestamp %ld, %s[%d]", + dr, + len, + dd->dd_timestamp, + keystr(tsb0), + extractpid(tsb0)); sbuf_append(&dd->dd_sbuf, tsb, len); dr->dr_queue_total += len; return; } } - dd = malloc(sizeof(*dd)); - dd->dd_key = NULL; + dd = malloc(sizeof(*dd)); + dd->dd_key = NULL; dd->dd_timestamp = mclk(); - debug2("%p: data append2 %d, timestamp %ld, %s[%d]", dr, len, dd->dd_timestamp, keystr(tsb), extractpid(tsb)); + debug2("%p: data append2 %d, timestamp %ld, %s[%d]", + dr, + len, + dd->dd_timestamp, + keystr(tsb), + extractpid(tsb)); sbuf_init(&dd->dd_sbuf); sbuf_append(&dd->dd_sbuf, tsb, len); TAILQ_INSERT_TAIL(&dr->dr_queue, dd, dd_link); dr->dr_queue_total += len; } -static void -descrambler_data_add_key(th_descrambler_runtime_t *dr, th_descrambler_key_t *tk, int change, int head) -{ - th_descrambler_data_t *dd; +static void descrambler_data_add_key(th_descrambler_runtime_t* dr, + th_descrambler_key_t* tk, + int change, + int head) { + th_descrambler_data_t* dd; - dd = calloc(1, sizeof(*dd)); - dd->dd_timestamp = mclk(); - dd->dd_key = tk; + dd = calloc(1, sizeof(*dd)); + dd->dd_timestamp = mclk(); + dd->dd_key = tk; dd->dd_key_changed = change; - debug2("%p: data %s key %d, timestamp %ld", dr, head ? "insert" : "append", tk->key_pid, dd->dd_timestamp); + debug2("%p: data %s key %d, timestamp %ld", + dr, + head ? "insert" : "append", + tk->key_pid, + dd->dd_timestamp); if (head) TAILQ_INSERT_HEAD(&dr->dr_queue, dd, dd_link); else TAILQ_INSERT_TAIL(&dr->dr_queue, dd, dd_link); } -static void -descrambler_data_cut(th_descrambler_runtime_t *dr, int len) -{ - th_descrambler_data_t *dd; +static void descrambler_data_cut(th_descrambler_runtime_t* dr, int len) { + th_descrambler_data_t* dd; while (len > 0) { - TAILQ_FOREACH(dd, &dr->dr_queue, dd_link) - if (dd && dd->dd_sbuf.sb_data) break; - if (dd == NULL) return; + TAILQ_FOREACH (dd, &dr->dr_queue, dd_link) + if (dd && dd->dd_sbuf.sb_data) + break; + if (dd == NULL) + return; if (dr->dr_skip) - ts_skip_packet2((mpegts_service_t *)dr->dr_service, - dd->dd_sbuf.sb_data, MIN(len, dd->dd_sbuf.sb_ptr)); + ts_skip_packet2((mpegts_service_t*)dr->dr_service, + dd->dd_sbuf.sb_data, + MIN(len, dd->dd_sbuf.sb_ptr)); if (len < dd->dd_sbuf.sb_ptr) { sbuf_cut(&dd->dd_sbuf, len); dr->dr_queue_total -= len; @@ -180,24 +191,25 @@ descrambler_data_cut(th_descrambler_runtime_t *dr, int len) } } -static int -descrambler_data_key_check(th_descrambler_runtime_t *dr, uint8_t key, int len) -{ - th_descrambler_data_t *dd; - int off = 0, l; - uint_fast8_t ki; +static int descrambler_data_key_check(th_descrambler_runtime_t* dr, uint8_t key, int len) { + th_descrambler_data_t* dd; + int off = 0, l; + uint_fast8_t ki; if ((dd = TAILQ_FIRST(&dr->dr_queue)) == NULL) return len; while (len > 0) { while (dd && dd->dd_sbuf.sb_data == NULL) dd = TAILQ_NEXT(dd, dd_link); - if (dd == NULL) break; + if (dd == NULL) + break; l = dd->dd_sbuf.sb_ptr; for (off = 0; off < l && len > 0; off += 188, l -= 188) { ki = dd->dd_sbuf.sb_data[off + 3]; - if (ki == 0) continue; - if ((ki & 0xc0) != key) return -1; + if (ki == 0) + continue; + if ((ki & 0xc0) != key) + return -1; len -= 188; } dd = TAILQ_NEXT(dd, dd_link); @@ -206,16 +218,15 @@ descrambler_data_key_check(th_descrambler_runtime_t *dr, uint8_t key, int len) } static int -descrambler_data_analyze(th_descrambler_runtime_t *dr, - th_descrambler_data_t *dd, uint8_t ki) -{ - th_descrambler_data_t *dd2; - const uint8_t *tsb0; - int packets = 0, blocks = 0; +descrambler_data_analyze(th_descrambler_runtime_t* dr, th_descrambler_data_t* dd, uint8_t ki) { + th_descrambler_data_t* dd2; + const uint8_t* tsb0; + int packets = 0, blocks = 0; for (dd2 = TAILQ_NEXT(dd, dd_link); dd2; dd2 = TAILQ_NEXT(dd2, dd_link)) { tsb0 = dd->dd_sbuf.sb_data; - if (tsb0 == NULL || dd->dd_sbuf.sb_ptr == 0) continue; + if (tsb0 == NULL || dd->dd_sbuf.sb_ptr == 0) + continue; if ((tsb0[3] & 0x80) != 0 && (tsb0[3] & 0x40) == (ki & 0x40)) { packets += dd2->dd_sbuf.sb_ptr; if (packets >= dr->dr_paritycheck) @@ -232,42 +243,32 @@ descrambler_data_analyze(th_descrambler_runtime_t *dr, /* * */ -static void -descrambler_destroy_ecmsec(descrambler_ecmsec_t *des) -{ +static void descrambler_destroy_ecmsec(descrambler_ecmsec_t* des) { LIST_REMOVE(des, link); free(des->last_data); if (atomic_dec(&des->refcnt, 1) == 0) free(des); } -static void -descrambler_destroy_all_ecmsecs(descrambler_section_t *ds) -{ - descrambler_ecmsec_t *des; +static void descrambler_destroy_all_ecmsecs(descrambler_section_t* ds) { + descrambler_ecmsec_t* des; while ((des = LIST_FIRST(&ds->ecmsecs)) != NULL) descrambler_destroy_ecmsec(des); } -static void -descrambler_destroy_section ( descrambler_section_t *ds, int emm ) -{ +static void descrambler_destroy_section(descrambler_section_t* ds, int emm) { ds->callback(ds->opaque, -1, NULL, 0, emm); descrambler_destroy_all_ecmsecs(ds); free(ds); } -static void -descrambler_destroy_table_( descrambler_table_t *dt ) -{ +static void descrambler_destroy_table_(descrambler_table_t* dt) { mpegts_table_destroy(dt->table); free(dt); } -static void -descrambler_destroy_table( descrambler_table_t *dt, int emm ) -{ - descrambler_section_t *ds; +static void descrambler_destroy_table(descrambler_table_t* dt, int emm) { + descrambler_section_t* ds; while ((ds = TAILQ_FIRST(&dt->sections)) != NULL) { TAILQ_REMOVE(&dt->sections, ds, link); descrambler_destroy_section(ds, emm); @@ -279,58 +280,60 @@ descrambler_destroy_table( descrambler_table_t *dt, int emm ) * */ static struct strtab ecmparitytab[] = { - { "default", ECM_PARITY_DEFAULT }, - { "standard", ECM_PARITY_80EVEN_81ODD }, - { "inverted", ECM_PARITY_81EVEN_80ODD }, + {"default", ECM_PARITY_DEFAULT}, + {"standard", ECM_PARITY_80EVEN_81ODD}, + {"inverted", ECM_PARITY_81EVEN_80ODD}, }; /* * */ -static void -descrambler_load_hints(htsmsg_t *m) -{ +static void descrambler_load_hints(htsmsg_t* m) { th_descrambler_hint_t hint, *dhint; - htsmsg_t *e; - htsmsg_field_t *f; - const char *s; + htsmsg_t* e; + htsmsg_field_t* f; + const char* s; HTSMSG_FOREACH(f, m) { - if (!(e = htsmsg_field_get_map(f))) continue; - if ((s = htsmsg_get_str(e, "caid")) == NULL) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; + if ((s = htsmsg_get_str(e, "caid")) == NULL) + continue; memset(&hint, 0, sizeof(hint)); hint.dh_caid = strtol(s, NULL, 16); hint.dh_mask = 0xffff; if ((s = htsmsg_get_str(e, "mask")) != NULL) hint.dh_mask = strtol(s, NULL, 16); - hint.dh_constcw = htsmsg_get_bool_or_default(e, "constcw", 0); - hint.dh_quickecm = htsmsg_get_bool_or_default(e, "quickecm", 0); - hint.dh_multipid = htsmsg_get_bool_or_default(e, "multipid", 0); - hint.dh_interval = htsmsg_get_s32_or_default(e, "interval", 10000); + hint.dh_constcw = htsmsg_get_bool_or_default(e, "constcw", 0); + hint.dh_quickecm = htsmsg_get_bool_or_default(e, "quickecm", 0); + hint.dh_multipid = htsmsg_get_bool_or_default(e, "multipid", 0); + hint.dh_interval = htsmsg_get_s32_or_default(e, "interval", 10000); hint.dh_paritycheck = htsmsg_get_s32_or_default(e, "paritycheck", 20); - hint.dh_ecmparity = str2val_def(htsmsg_get_str(e, "ecmparity"), ecmparitytab, ECM_PARITY_DEFAULT); - tvhinfo(LS_DESCRAMBLER, "adding CAID %04X/%04X as%s%s%s interval %ums pc %d ep %s (%s)", - hint.dh_caid, hint.dh_mask, - hint.dh_constcw ? " ConstCW" : "", - hint.dh_quickecm ? " QuickECM" : "", - hint.dh_multipid ? " MultiPID" : "", - hint.dh_interval, - hint.dh_paritycheck, - val2str(hint.dh_ecmparity, ecmparitytab), - htsmsg_get_str(e, "name") ?: "unknown"); - dhint = malloc(sizeof(*dhint)); + hint.dh_ecmparity = + str2val_def(htsmsg_get_str(e, "ecmparity"), ecmparitytab, ECM_PARITY_DEFAULT); + tvhinfo(LS_DESCRAMBLER, + "adding CAID %04X/%04X as%s%s%s interval %ums pc %d ep %s (%s)", + hint.dh_caid, + hint.dh_mask, + hint.dh_constcw ? " ConstCW" : "", + hint.dh_quickecm ? " QuickECM" : "", + hint.dh_multipid ? " MultiPID" : "", + hint.dh_interval, + hint.dh_paritycheck, + val2str(hint.dh_ecmparity, ecmparitytab), + htsmsg_get_str(e, "name") ?: "unknown"); + dhint = malloc(sizeof(*dhint)); *dhint = hint; TAILQ_INSERT_TAIL(&ca_hints, dhint, dh_link); - if (hint.dh_quickecm) ca_hints_quickecm++; + if (hint.dh_quickecm) + ca_hints_quickecm++; } } /* * */ -void -descrambler_init ( void ) -{ +void descrambler_init(void) { htsmsg_t *c, *m; TAILQ_INIT(&ca_hints); @@ -346,10 +349,8 @@ descrambler_init ( void ) } } -void -descrambler_done ( void ) -{ - th_descrambler_hint_t *hint; +void descrambler_done(void) { + th_descrambler_hint_t* hint; caclient_done(); while ((hint = TAILQ_FIRST(&ca_hints)) != NULL) { @@ -361,21 +362,22 @@ descrambler_done ( void ) /* * Decide, if we should work in "quick ECM" mode */ -static int -descrambler_quick_ecm ( mpegts_service_t *t, int pid ) -{ - elementary_stream_t *st; - th_descrambler_hint_t *hint; - caid_t *ca; +static int descrambler_quick_ecm(mpegts_service_t* t, int pid) { + elementary_stream_t* st; + th_descrambler_hint_t* hint; + caid_t* ca; if (!ca_hints_quickecm) return 0; - TAILQ_FOREACH(st, &t->s_components.set_filter, es_filter_link) { - if (st->es_pid != pid) continue; - TAILQ_FOREACH(hint, &ca_hints, dh_link) { - if (!hint->dh_quickecm) continue; - LIST_FOREACH(ca, &st->es_caids, link) { - if (ca->use == 0) continue; + TAILQ_FOREACH (st, &t->s_components.set_filter, es_filter_link) { + if (st->es_pid != pid) + continue; + TAILQ_FOREACH (hint, &ca_hints, dh_link) { + if (!hint->dh_quickecm) + continue; + LIST_FOREACH (ca, &st->es_caids, link) { + if (ca->use == 0) + continue; if (hint->dh_caid == (ca->caid & hint->dh_mask)) return 1; } @@ -389,16 +391,14 @@ descrambler_quick_ecm ( mpegts_service_t *t, int pid ) * a) start a new service * b) restart a running service with possible caid changes */ -void -descrambler_service_start ( service_t *t ) -{ - th_descrambler_runtime_t *dr; - th_descrambler_key_t *tk; - th_descrambler_hint_t *hint; - elementary_stream_t *st; - caid_t *ca; - int i, count, constcw = 0, multipid = 0, interval = 10000, paritycheck = 20; - int ecmparity = ECM_PARITY_DEFAULT; +void descrambler_service_start(service_t* t) { + th_descrambler_runtime_t* dr; + th_descrambler_key_t* tk; + th_descrambler_hint_t* hint; + elementary_stream_t* st; + caid_t* ca; + int i, count, constcw = 0, multipid = 0, interval = 10000, paritycheck = 20; + int ecmparity = ECM_PARITY_DEFAULT; if (t->s_scrambled_pass) return; @@ -406,15 +406,20 @@ descrambler_service_start ( service_t *t ) if (!t->s_dvb_forcecaid) { count = 0; - TAILQ_FOREACH(st, &t->s_components.set_filter, es_filter_link) - LIST_FOREACH(ca, &st->es_caids, link) { - if (ca->use == 0) continue; - TAILQ_FOREACH(hint, &ca_hints, dh_link) { + TAILQ_FOREACH (st, &t->s_components.set_filter, es_filter_link) + LIST_FOREACH (ca, &st->es_caids, link) { + if (ca->use == 0) + continue; + TAILQ_FOREACH (hint, &ca_hints, dh_link) { if (hint->dh_caid == (ca->caid & hint->dh_mask)) { - if (hint->dh_constcw) constcw = 1; - if (hint->dh_multipid) multipid = 1; - if (hint->dh_interval) interval = hint->dh_interval; - if (hint->dh_paritycheck) paritycheck = hint->dh_paritycheck; + if (hint->dh_constcw) + constcw = 1; + if (hint->dh_multipid) + multipid = 1; + if (hint->dh_interval) + interval = hint->dh_interval; + if (hint->dh_paritycheck) + paritycheck = hint->dh_paritycheck; if (hint->dh_ecmparity != ECM_PARITY_DEFAULT) ecmparity = hint->dh_ecmparity; } @@ -428,40 +433,43 @@ descrambler_service_start ( service_t *t ) } else { - TAILQ_FOREACH(hint, &ca_hints, dh_link) { + TAILQ_FOREACH (hint, &ca_hints, dh_link) { if (hint->dh_caid == (t->s_dvb_forcecaid & hint->dh_mask)) { - if (hint->dh_constcw) constcw = 1; - if (hint->dh_multipid) multipid = 1; - if (hint->dh_interval) interval = hint->dh_interval; + if (hint->dh_constcw) + constcw = 1; + if (hint->dh_multipid) + multipid = 1; + if (hint->dh_interval) + interval = hint->dh_interval; } } - } tvh_mutex_lock(&t->s_stream_mutex); - ((mpegts_service_t *)t)->s_dvb_mux->mm_descrambler_flush = 0; + ((mpegts_service_t*)t)->s_dvb_mux->mm_descrambler_flush = 0; if (t->s_descramble == NULL) { t->s_descramble = dr = calloc(1, sizeof(th_descrambler_runtime_t)); - dr->dr_service = t; + dr->dr_service = t; TAILQ_INIT(&dr->dr_queue); for (i = 0; i < DESCRAMBLER_MAX_KEYS; i++) { - tk = &dr->dr_keys[i]; - tk->key_index = 0xff; + tk = &dr->dr_keys[i]; + tk->key_index = 0xff; tk->key_interval = tk->key_initial_interval = ms2mono(interval); tvhcsa_init(&tk->key_csa); - if (!multipid) break; + if (!multipid) + break; } - dr->dr_paritycheck = MINMAX(paritycheck, 1, 200) * 188; + dr->dr_paritycheck = MINMAX(paritycheck, 1, 200) * 188; dr->dr_initial_paritycheck = MINMAX(paritycheck, 4, 200) * 188; - dr->dr_ecm_key_margin = ms2mono(interval) / 5; - dr->dr_key_const = constcw; - dr->dr_key_multipid = multipid; - dr->dr_ecm_parity = ecmparity ?: ECM_PARITY_80EVEN_81ODD; + dr->dr_ecm_key_margin = ms2mono(interval) / 5; + dr->dr_key_const = constcw; + dr->dr_key_multipid = multipid; + dr->dr_ecm_parity = ecmparity ?: ECM_PARITY_80EVEN_81ODD; if (constcw) tvhtrace(LS_DESCRAMBLER, "using constcw for \"%s\"", t->s_nicename); if (multipid) tvhtrace(LS_DESCRAMBLER, "using multipid for \"%s\"", t->s_nicename); - dr->dr_skip = 0; + dr->dr_skip = 0; dr->dr_force_skip = 0; if (t->s_dvb_forcecaid == 0xffff) dr->dr_descramble = descrambler_pass; @@ -472,23 +480,21 @@ descrambler_service_start ( service_t *t ) caclient_start(t); } -void -descrambler_service_stop ( service_t *t ) -{ - th_descrambler_t *td; - th_descrambler_runtime_t *dr; - th_descrambler_key_t *tk; - th_descrambler_data_t *dd; - void *p; - int i; +void descrambler_service_stop(service_t* t) { + th_descrambler_t* td; + th_descrambler_runtime_t* dr; + th_descrambler_key_t* tk; + th_descrambler_data_t* dd; + void* p; + int i; while ((td = LIST_FIRST(&t->s_descramblers)) != NULL) td->td_stop(td); tvh_mutex_lock(&t->s_stream_mutex); - dr = t->s_descramble; - t->s_descramble = NULL; - t->s_descrambler = NULL; - p = t->s_descramble_info; + dr = t->s_descramble; + t->s_descramble = NULL; + t->s_descrambler = NULL; + p = t->s_descramble_info; t->s_descramble_info = NULL; tvh_mutex_unlock(&t->s_stream_mutex); free(p); @@ -496,7 +502,8 @@ descrambler_service_stop ( service_t *t ) for (i = 0; i < DESCRAMBLER_MAX_KEYS; i++) { tk = &dr->dr_keys[i]; tvhcsa_destroy(&tk->key_csa); - if (!dr->dr_key_multipid) break; + if (!dr->dr_key_multipid) + break; } while ((dd = TAILQ_FIRST(&dr->dr_queue)) != NULL) descrambler_data_destroy(dr, dd, 0); @@ -504,22 +511,18 @@ descrambler_service_stop ( service_t *t ) } } -void -descrambler_caid_changed ( service_t *t ) -{ - th_descrambler_t *td; +void descrambler_caid_changed(service_t* t) { + th_descrambler_t* td; - LIST_FOREACH(td, &t->s_descramblers, td_service_link) { + LIST_FOREACH (td, &t->s_descramblers, td_service_link) { if (td->td_caid_change) td->td_caid_change(td); } } -static void -descrambler_notify_deliver( mpegts_service_t *t, descramble_info_t *di ) -{ - streaming_message_t *sm; - int r; +static void descrambler_notify_deliver(mpegts_service_t* t, descramble_info_t* di) { + streaming_message_t* sm; + int r; lock_assert(&t->s_stream_mutex); if (!t->s_descramble_info) { @@ -534,15 +537,13 @@ descrambler_notify_deliver( mpegts_service_t *t, descramble_info_t *di ) memcpy(t->s_descramble_info, di, sizeof(*di)); sm = streaming_msg_create_data(SMT_DESCRAMBLE_INFO, di); - streaming_service_deliver((service_t *)t, sm); + streaming_service_deliver((service_t*)t, sm); } /* it's called inside s_stream_mutex lock! */ -static void -descrambler_notify_nokey( th_descrambler_runtime_t *dr ) -{ - mpegts_service_t *t = (mpegts_service_t *)dr->dr_service; - descramble_info_t *di; +static void descrambler_notify_nokey(th_descrambler_runtime_t* dr) { + mpegts_service_t* t = (mpegts_service_t*)dr->dr_service; + descramble_info_t* di; tvhdebug(LS_DESCRAMBLER, "no key for service='%s'", t->s_dvb_svcname); @@ -552,22 +553,33 @@ descrambler_notify_nokey( th_descrambler_runtime_t *dr ) descrambler_notify_deliver(t, di); } -void -descrambler_notify( th_descrambler_t *td, - uint16_t caid, uint32_t provid, - const char *cardsystem, uint16_t pid, uint32_t ecmtime, - uint16_t hops, const char *reader, const char *from, - const char *protocol ) -{ - mpegts_service_t *t = (mpegts_service_t *)td->td_service; - descramble_info_t *di; - - tvhdebug(LS_DESCRAMBLER, "info - service='%s' caid=%04X(%s) " - "provid=%06X ecmtime=%d hops=%d " - "reader='%s' from='%s' protocol='%s'%s", - t->s_dvb_svcname, caid, cardsystem, provid, - ecmtime, hops, reader, from, protocol, - t->s_descrambler != td ? " (inactive)" : ""); +void descrambler_notify(th_descrambler_t* td, + uint16_t caid, + uint32_t provid, + const char* cardsystem, + uint16_t pid, + uint32_t ecmtime, + uint16_t hops, + const char* reader, + const char* from, + const char* protocol) { + mpegts_service_t* t = (mpegts_service_t*)td->td_service; + descramble_info_t* di; + + tvhdebug(LS_DESCRAMBLER, + "info - service='%s' caid=%04X(%s) " + "provid=%06X ecmtime=%d hops=%d " + "reader='%s' from='%s' protocol='%s'%s", + t->s_dvb_svcname, + caid, + cardsystem, + provid, + ecmtime, + hops, + reader, + from, + protocol, + t->s_descrambler != td ? " (inactive)" : ""); if (t->s_descrambler != td) return; @@ -589,22 +601,18 @@ descrambler_notify( th_descrambler_t *td, tvh_mutex_unlock(&t->s_stream_mutex); } -int -descrambler_resolved( service_t *t, th_descrambler_t *ignore ) -{ - th_descrambler_t *td; +int descrambler_resolved(service_t* t, th_descrambler_t* ignore) { + th_descrambler_t* td; - LIST_FOREACH(td, &t->s_descramblers, td_service_link) + LIST_FOREACH (td, &t->s_descramblers, td_service_link) if (td != ignore && td->td_keystate == DS_RESOLVED) return 1; return 0; } -int -descrambler_multi_pid ( th_descrambler_t *td ) -{ - service_t *t = td->td_service; - th_descrambler_runtime_t *dr; +int descrambler_multi_pid(th_descrambler_t* td) { + service_t* t = td->td_service; + th_descrambler_runtime_t* dr; if (t == NULL || (dr = t->s_descramble) == NULL) return 0; @@ -612,35 +620,34 @@ descrambler_multi_pid ( th_descrambler_t *td ) } static struct strtab keystatetab[] = { - { "INIT", DS_INIT }, - { "READY", DS_READY }, - { "RESOLVED", DS_RESOLVED }, - { "FORBIDDEN", DS_FORBIDDEN }, - { "FATAL", DS_FATAL }, - { "IDLE", DS_IDLE }, + {"INIT", DS_INIT}, + {"READY", DS_READY}, + {"RESOLVED", DS_RESOLVED}, + {"FORBIDDEN", DS_FORBIDDEN}, + {"FATAL", DS_FATAL}, + {"IDLE", DS_IDLE}, }; -const char * -descrambler_keystate2str( th_descrambler_keystate_t keystate ) -{ +const char* descrambler_keystate2str(th_descrambler_keystate_t keystate) { return val2str(keystate, keystatetab) ?: "INVALID"; } -void -descrambler_change_keystate( th_descrambler_t *td, th_descrambler_keystate_t keystate, int lock ) -{ - service_t *t = td->td_service; - th_descrambler_runtime_t *dr; - int count = 0, fatal = 0, failed = 0, resolved = 0; +void descrambler_change_keystate(th_descrambler_t* td, + th_descrambler_keystate_t keystate, + int lock) { + service_t* t = td->td_service; + th_descrambler_runtime_t* dr; + int count = 0, fatal = 0, failed = 0, resolved = 0; if (td->td_keystate == keystate) return; - tvhtrace(LS_DESCRAMBLER, "%s: key state changed from %s to %s for \"%s\"", - td->td_nicename, - descrambler_keystate2str(td->td_keystate), - descrambler_keystate2str(keystate), - t->s_nicename); + tvhtrace(LS_DESCRAMBLER, + "%s: key state changed from %s to %s for \"%s\"", + td->td_nicename, + descrambler_keystate2str(td->td_keystate), + descrambler_keystate2str(keystate), + t->s_nicename); td->td_keystate = keystate; if (t == NULL || (dr = t->s_descramble) == NULL) return; @@ -648,52 +655,63 @@ descrambler_change_keystate( th_descrambler_t *td, th_descrambler_keystate_t key if (lock) tvh_mutex_lock(&t->s_stream_mutex); count = failed = resolved = 0; - LIST_FOREACH(td, &t->s_descramblers, td_service_link) { + LIST_FOREACH (td, &t->s_descramblers, td_service_link) { count++; switch (td->td_keystate) { - case DS_FATAL: fatal++; break; - case DS_FORBIDDEN: failed++; break; - case DS_RESOLVED : resolved++; break; - default: break; + case DS_FATAL: + fatal++; + break; + case DS_FORBIDDEN: + failed++; + break; + case DS_RESOLVED: + resolved++; + break; + default: + break; } } - dr->dr_ca_count = count; + dr->dr_ca_count = count; dr->dr_ca_resolved = resolved; - dr->dr_ca_failed = failed; - dr->dr_ca_fatal = fatal; - tvhtrace(LS_DESCRAMBLER, "service \"%s\": %d descramblers (%d ok %d failed %d fatal)", - t->s_nicename, count, resolved, failed, fatal); + dr->dr_ca_failed = failed; + dr->dr_ca_fatal = fatal; + tvhtrace(LS_DESCRAMBLER, + "service \"%s\": %d descramblers (%d ok %d failed %d fatal)", + t->s_nicename, + count, + resolved, + failed, + fatal); if (lock) tvh_mutex_unlock(&t->s_stream_mutex); } static struct strtab keytypetab[] = { - { "NONE", DESCRAMBLER_NONE }, - { "CSA", DESCRAMBLER_CSA_CBC }, - { "DES", DESCRAMBLER_DES_NCB }, - { "AES EBC", DESCRAMBLER_AES_ECB }, - { "AES128 EBC", DESCRAMBLER_AES128_ECB }, + {"NONE", DESCRAMBLER_NONE}, + {"CSA", DESCRAMBLER_CSA_CBC}, + {"DES", DESCRAMBLER_DES_NCB}, + {"AES EBC", DESCRAMBLER_AES_ECB}, + {"AES128 EBC", DESCRAMBLER_AES128_ECB}, }; -const char * -descrambler_keytype2str( th_descrambler_keystate_t keytype ) -{ +const char* descrambler_keytype2str(th_descrambler_keystate_t keytype) { return val2str(keytype, keytypetab) ?: "INVALID"; } -void -descrambler_keys ( th_descrambler_t *td, int type, uint16_t pid, - const uint8_t *even, const uint8_t *odd ) -{ - static uint8_t empty[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - service_t *t = td->td_service; - th_descrambler_runtime_t *dr; - th_descrambler_key_t *tk; - th_descrambler_t *td2; - char pidname[16]; - const char *ktype; - uint16_t pid2; - int j, changed = 0, insert = 0; +void descrambler_keys(th_descrambler_t* td, + int type, + uint16_t pid, + const uint8_t* even, + const uint8_t* odd) { + static uint8_t empty[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + service_t* t = td->td_service; + th_descrambler_runtime_t* dr; + th_descrambler_key_t* tk; + th_descrambler_t* td2; + char pidname[16]; + const char* ktype; + uint16_t pid2; + int j, changed = 0, insert = 0; if (t == NULL || (dr = t->s_descramble) == NULL) { descrambler_change_keystate(td, DS_FORBIDDEN, 1); @@ -704,7 +722,7 @@ descrambler_keys ( th_descrambler_t *td, int type, uint16_t pid, if (pid == 0 && dr->dr_key_multipid) { for (j = 0; j < DESCRAMBLER_MAX_KEYS; j++) { - tk = &dr->dr_keys[j]; + tk = &dr->dr_keys[j]; pid2 = tk->key_pid; if (pid2) { tvh_mutex_unlock(&t->s_stream_mutex); @@ -719,9 +737,10 @@ descrambler_keys ( th_descrambler_t *td, int type, uint16_t pid, pid = 0; for (j = 0; j < DESCRAMBLER_MAX_KEYS; j++) { - tk = &dr->dr_keys[j]; + tk = &dr->dr_keys[j]; pid2 = tk->key_pid; - if (pid2 == 0 || pid2 == pid) break; + if (pid2 == 0 || pid2 == pid) + break; } if (j >= DESCRAMBLER_MAX_KEYS) { @@ -735,38 +754,43 @@ descrambler_keys ( th_descrambler_t *td, int type, uint16_t pid, snprintf(pidname, sizeof(pidname), "[%d]", pid); ktype = descrambler_keytype2str(type); - if (tvhcsa_set_type(&tk->key_csa, (mpegts_service_t *)t, type) < 0) { + if (tvhcsa_set_type(&tk->key_csa, (mpegts_service_t*)t, type) < 0) { if (tk->key_type_overwritten) goto end; if (type == DESCRAMBLER_CSA_CBC && tk->key_csa.csa_type == DESCRAMBLER_DES_NCB) { tvhwarn(LS_DESCRAMBLER, - "Keep key%s type %s (requested %s) for service \"%s\", check your caclient", - pidname, descrambler_keytype2str(tk->key_csa.csa_type), ktype, - ((mpegts_service_t *)t)->s_dvb_svcname); + "Keep key%s type %s (requested %s) for service \"%s\", check your caclient", + pidname, + descrambler_keytype2str(tk->key_csa.csa_type), + ktype, + ((mpegts_service_t*)t)->s_dvb_svcname); goto cont; } tk->key_type_overwritten = 1; tvhwarn(LS_DESCRAMBLER, - "Overwrite key%s type from %s to %s for service \"%s\"", - pidname, descrambler_keytype2str(tk->key_csa.csa_type), - ktype, ((mpegts_service_t *)t)->s_dvb_svcname); + "Overwrite key%s type from %s to %s for service \"%s\"", + pidname, + descrambler_keytype2str(tk->key_csa.csa_type), + ktype, + ((mpegts_service_t*)t)->s_dvb_svcname); tvhcsa_destroy(&tk->key_csa); tvhcsa_init(&tk->key_csa); - if (tvhcsa_set_type(&tk->key_csa, (mpegts_service_t *)t, type) < 0) + if (tvhcsa_set_type(&tk->key_csa, (mpegts_service_t*)t, type) < 0) goto end; tk->key_valid = 0; } cont: - LIST_FOREACH(td2, &t->s_descramblers, td_service_link) + LIST_FOREACH (td2, &t->s_descramblers, td_service_link) if (td2 != td && td2->td_keystate == DS_RESOLVED) { tvhdebug(LS_DESCRAMBLER, - "Already has a key[%d] from %s for service \"%s\", " - "ignoring key from \"%s\"%s", - tk->key_pid, td2->td_nicename, - ((mpegts_service_t *)td2->td_service)->s_dvb_svcname, - td->td_nicename, - dr->dr_key_const ? " (const)" : ""); + "Already has a key[%d] from %s for service \"%s\", " + "ignoring key from \"%s\"%s", + tk->key_pid, + td2->td_nicename, + ((mpegts_service_t*)td2->td_service)->s_dvb_svcname, + td->td_nicename, + dr->dr_key_const ? " (const)" : ""); descrambler_change_keystate(td, DS_IDLE, 0); if (td->td_ecm_idle) { tvh_mutex_unlock(&t->s_stream_mutex); @@ -780,15 +804,15 @@ cont: memcpy(tk->key_data[0], even, tk->key_csa.csa_keylen); tk->key_pid = pid; changed |= 1; - if (tk->key_timestamp[0] == 0 || - descrambler_data_key_check(dr, 0x80, dr->dr_queue_total) >= 0) + if (tk->key_timestamp[0] == 0 || descrambler_data_key_check(dr, 0x80, dr->dr_queue_total) >= 0) insert |= 1; tk->key_timestamp[0] = mclk(); if (dr->dr_ecm_start[0] < dr->dr_ecm_start[1]) { dr->dr_ecm_start[0] = dr->dr_ecm_start[1]; tvhdebug(LS_DESCRAMBLER, - "Both keys received, marking ECM start for even key%s for service \"%s\"", - pidname, ((mpegts_service_t *)t)->s_dvb_svcname); + "Both keys received, marking ECM start for even key%s for service \"%s\"", + pidname, + ((mpegts_service_t*)t)->s_dvb_svcname); } } else { even = empty; @@ -797,15 +821,15 @@ cont: memcpy(tk->key_data[1], odd, tk->key_csa.csa_keylen); tk->key_pid = pid; changed |= 2; - if (tk->key_timestamp[1] == 0 || - descrambler_data_key_check(dr, 0xc0, dr->dr_queue_total) >= 0) + if (tk->key_timestamp[1] == 0 || descrambler_data_key_check(dr, 0xc0, dr->dr_queue_total) >= 0) insert |= 2; tk->key_timestamp[1] = mclk(); if (dr->dr_ecm_start[1] < dr->dr_ecm_start[0]) { dr->dr_ecm_start[1] = dr->dr_ecm_start[0]; tvhdebug(LS_DESCRAMBLER, - "Both keys received, marking ECM start for odd key%s for service \"%s\"", - pidname, ((mpegts_service_t *)t)->s_dvb_svcname); + "Both keys received, marking ECM start for odd key%s for service \"%s\"", + pidname, + ((mpegts_service_t*)t)->s_dvb_svcname); } } else { odd = empty; @@ -815,82 +839,140 @@ cont: descrambler_data_add_key(dr, tk, changed, insert); if (td->td_keystate != DS_RESOLVED) tvhdebug(LS_DESCRAMBLER, - "Obtained %s keys%s from %s for service \"%s\"%s", - ktype, pidname, td->td_nicename, - ((mpegts_service_t *)t)->s_dvb_svcname, - dr->dr_key_const ? " (const)" : ""); + "Obtained %s keys%s from %s for service \"%s\"%s", + ktype, + pidname, + td->td_nicename, + ((mpegts_service_t*)t)->s_dvb_svcname, + dr->dr_key_const ? " (const)" : ""); if (tk->key_csa.csa_keylen == 8) { - tvhtrace(LS_DESCRAMBLER, "Obtained %s keys%s " - "%02X%02X%02X%02X%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X%02X%02X" - " pid %04X from %s for service \"%s\"", - ktype, pidname, - even[0], even[1], even[2], even[3], even[4], even[5], even[6], even[7], - odd[0], odd[1], odd[2], odd[3], odd[4], odd[5], odd[6], odd[7], - pid, td->td_nicename, - ((mpegts_service_t *)t)->s_dvb_svcname); + tvhtrace(LS_DESCRAMBLER, + "Obtained %s keys%s " + "%02X%02X%02X%02X%02X%02X%02X%02X:%02X%02X%02X%02X%02X%02X%02X%02X" + " pid %04X from %s for service \"%s\"", + ktype, + pidname, + even[0], + even[1], + even[2], + even[3], + even[4], + even[5], + even[6], + even[7], + odd[0], + odd[1], + odd[2], + odd[3], + odd[4], + odd[5], + odd[6], + odd[7], + pid, + td->td_nicename, + ((mpegts_service_t*)t)->s_dvb_svcname); } else if (tk->key_csa.csa_keylen == 16) { - tvhtrace(LS_DESCRAMBLER, "Obtained %s keys%s " - "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X:" - "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" - " pid %04X from %s for service \"%s\"", - ktype, pidname, - even[0], even[1], even[2], even[3], even[4], even[5], even[6], even[7], - even[8], even[9], even[10], even[11], even[12], even[13], even[14], even[15], - odd[0], odd[1], odd[2], odd[3], odd[4], odd[5], odd[6], odd[7], - odd[8], odd[9], odd[10], odd[11], odd[12], odd[13], odd[14], odd[15], - pid, td->td_nicename, - ((mpegts_service_t *)t)->s_dvb_svcname); + tvhtrace(LS_DESCRAMBLER, + "Obtained %s keys%s " + "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X:" + "%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X" + " pid %04X from %s for service \"%s\"", + ktype, + pidname, + even[0], + even[1], + even[2], + even[3], + even[4], + even[5], + even[6], + even[7], + even[8], + even[9], + even[10], + even[11], + even[12], + even[13], + even[14], + even[15], + odd[0], + odd[1], + odd[2], + odd[3], + odd[4], + odd[5], + odd[6], + odd[7], + odd[8], + odd[9], + odd[10], + odd[11], + odd[12], + odd[13], + odd[14], + odd[15], + pid, + td->td_nicename, + ((mpegts_service_t*)t)->s_dvb_svcname); } else { - tvhtrace(LS_DESCRAMBLER, "Unknown keys%s pid %04X from %s for for service \"%s\"", - pidname, pid, td->td_nicename, ((mpegts_service_t *)t)->s_dvb_svcname); + tvhtrace(LS_DESCRAMBLER, + "Unknown keys%s pid %04X from %s for for service \"%s\"", + pidname, + pid, + td->td_nicename, + ((mpegts_service_t*)t)->s_dvb_svcname); } dr->dr_ecm_last_key_time = mclk(); descrambler_change_keystate(td, DS_RESOLVED, 0); td->td_service->s_descrambler = td; } else { tvhdebug(LS_DESCRAMBLER, - "Empty %s keys%s received from %s for service \"%s\"%s", - ktype, pidname, td->td_nicename, - ((mpegts_service_t *)t)->s_dvb_svcname, - dr->dr_key_const ? " (const)" : ""); + "Empty %s keys%s received from %s for service \"%s\"%s", + ktype, + pidname, + td->td_nicename, + ((mpegts_service_t*)t)->s_dvb_svcname, + dr->dr_key_const ? " (const)" : ""); } end: tvh_mutex_unlock(&t->s_stream_mutex); } -void -descrambler_flush_table_data( service_t *t ) -{ - mpegts_service_t *ms = (mpegts_service_t *)t; - mpegts_mux_t *mux = ms->s_dvb_mux; - descrambler_table_t *dt; - descrambler_section_t *ds; +void descrambler_flush_table_data(service_t* t) { + mpegts_service_t* ms = (mpegts_service_t*)t; + mpegts_mux_t* mux = ms->s_dvb_mux; + descrambler_table_t* dt; + descrambler_section_t* ds; if (mux == NULL) return; tvhtrace(LS_DESCRAMBLER, "flush table data for service \"%s\"", ms->s_dvb_svcname); tvh_mutex_lock(&mux->mm_descrambler_lock); - TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) { + TAILQ_FOREACH (dt, &mux->mm_descrambler_tables, link) { if (dt->table == NULL || dt->table->mt_service != ms) continue; - TAILQ_FOREACH(ds, &dt->sections, link) + TAILQ_FOREACH (ds, &dt->sections, link) descrambler_destroy_all_ecmsecs(ds); } tvh_mutex_unlock(&mux->mm_descrambler_lock); } -static inline void -key_update( service_t *t, th_descrambler_key_t *tk, uint8_t key, int64_t timestamp ) -{ +static inline void +key_update(service_t* t, th_descrambler_key_t* tk, uint8_t key, int64_t timestamp) { /* set the even (0) or odd (0x40) key index */ tk->key_index = key & 0x40; if (tk->key_start) { /* don't change key interval for fast rolling keys */ if (tk->key_initial_interval > 2000000) { - tk->key_interval = tk->key_start + sec2mono(50) < timestamp ? - tk->key_initial_interval : MAX(5000000, timestamp - tk->key_start); - tvhtrace(LS_DESCRAMBLER, "update key[%d] interval for \"%s\" to %ldms", tk->key_pid, t->s_nicename, (long)(tk->key_interval / 1000)); + tk->key_interval = tk->key_start + sec2mono(50) < timestamp + ? tk->key_initial_interval + : MAX(5000000, timestamp - tk->key_start); + tvhtrace(LS_DESCRAMBLER, + "update key[%d] interval for \"%s\" to %ldms", + tk->key_pid, + t->s_nicename, + (long)(tk->key_interval / 1000)); } tk->key_start = timestamp; } else { @@ -900,69 +982,59 @@ key_update( service_t *t, th_descrambler_key_t *tk, uint8_t key, int64_t timesta } static inline int -key_changed ( th_descrambler_runtime_t *dr, th_descrambler_key_t *tk, uint8_t ki, int64_t timestamp ) -{ - return tk->key_index != (ki & 0x40) && - tk->key_start + dr->dr_ecm_key_margin < timestamp; +key_changed(th_descrambler_runtime_t* dr, th_descrambler_key_t* tk, uint8_t ki, int64_t timestamp) { + return tk->key_index != (ki & 0x40) && tk->key_start + dr->dr_ecm_key_margin < timestamp; } -static inline int -key_valid ( th_descrambler_key_t *tk, uint8_t ki ) -{ +static inline int key_valid(th_descrambler_key_t* tk, uint8_t ki) { /* 0x40 (for even) or 0x80 (for odd) */ uint8_t mask = ((ki & 0x40) + 0x40); return tk && (tk->key_valid & mask); } static inline int -key_late( th_descrambler_runtime_t *dr, th_descrambler_key_t *tk, uint8_t ki, int64_t timestamp ) -{ +key_late(th_descrambler_runtime_t* dr, th_descrambler_key_t* tk, uint8_t ki, int64_t timestamp) { uint8_t kidx = (ki & 0x40) >> 6; /* constcw - do not handle keys */ if (dr->dr_key_const) return 0; /* required key is older than previous? */ - if (tk->key_timestamp[kidx] < tk->key_timestamp[kidx^1]) { + if (tk->key_timestamp[kidx] < tk->key_timestamp[kidx ^ 1]) { /* but don't take in account the keys modified just now */ - if (tk->key_timestamp[kidx^1] + ms2mono(350) < timestamp) + if (tk->key_timestamp[kidx ^ 1] + ms2mono(350) < timestamp) goto late; } /* ECM was sent, but no new key was received */ if (dr->dr_ecm_last_key_time + dr->dr_ecm_key_margin < tk->key_start && (!dr->dr_quick_ecm || dr->dr_ecm_start[kidx] + ms2mono(10) < tk->key_start)) { -late: + late: tk->key_valid &= ~((ki & 0x40) + 0x40); return 1; } return 0; } -static inline int -key_started( th_descrambler_runtime_t *dr, uint8_t ki ) -{ +static inline int key_started(th_descrambler_runtime_t* dr, uint8_t ki) { uint8_t kidx = (ki & 0x40) >> 6; return mclk() - dr->dr_ecm_start[kidx] < dr->dr_ecm_key_margin * 2; } -static void -old_key_flush ( th_descrambler_runtime_t *dr, service_t *t ) -{ - th_descrambler_key_t *tk = dr->dr_key_last; +static void old_key_flush(th_descrambler_runtime_t* dr, service_t* t) { + th_descrambler_key_t* tk = dr->dr_key_last; if (tk) { debug2("%p: key[%d] flush1", dr, tk->key_pid); - tk->key_csa.csa_flush(&tk->key_csa, (mpegts_service_t *)t); + tk->key_csa.csa_flush(&tk->key_csa, (mpegts_service_t*)t); dr->dr_key_last = NULL; } } static void -key_flush( th_descrambler_runtime_t *dr, th_descrambler_key_t *tk, uint8_t changed, service_t *t ) -{ +key_flush(th_descrambler_runtime_t* dr, th_descrambler_key_t* tk, uint8_t changed, service_t* t) { if (!changed) return; debug2("%p: key[%d] flush2", dr, tk->key_pid); - tk->key_csa.csa_flush(&tk->key_csa, (mpegts_service_t *)t); + tk->key_csa.csa_flush(&tk->key_csa, (mpegts_service_t*)t); /* update the keys */ if (changed & 1) { debug2("%p: even key[%d] set for decoder", dr, tk->key_pid); @@ -976,13 +1048,10 @@ key_flush( th_descrambler_runtime_t *dr, th_descrambler_key_t *tk, uint8_t chang } } -static th_descrambler_key_t * -key_find_struct( th_descrambler_runtime_t *dr, - const uint8_t *tsb, - service_t *t ) -{ - th_descrambler_key_t *tk; - int i, pid = extractpid(tsb); +static th_descrambler_key_t* +key_find_struct(th_descrambler_runtime_t* dr, const uint8_t* tsb, service_t* t) { + th_descrambler_key_t* tk; + int i, pid = extractpid(tsb); if (dr->dr_key_last && dr->dr_key_last->key_pid == pid) return dr->dr_key_last; for (i = 0; i < DESCRAMBLER_MAX_KEYS; i++) { @@ -997,18 +1066,16 @@ key_find_struct( th_descrambler_runtime_t *dr, return NULL; } -static int -ecm_reset( service_t *t, th_descrambler_runtime_t *dr ) -{ - th_descrambler_t *td; - th_descrambler_key_t *tk; - int ret = 0, i; +static int ecm_reset(service_t* t, th_descrambler_runtime_t* dr) { + th_descrambler_t* td; + th_descrambler_key_t* tk; + int ret = 0, i; /* reset the reader ECM state */ - LIST_FOREACH(td, &t->s_descramblers, td_service_link) { + LIST_FOREACH (td, &t->s_descramblers, td_service_link) { if (!td->td_ecm_reset(td)) { for (i = 0; i < DESCRAMBLER_MAX_KEYS; i++) { - tk = &dr->dr_keys[i]; + tk = &dr->dr_keys[i]; tk->key_valid = 0; if (tk->key_pid == 0) break; @@ -1019,38 +1086,28 @@ ecm_reset( service_t *t, th_descrambler_runtime_t *dr ) return ret; } -int -descrambler_pass ( service_t *t, - elementary_stream_t *st, - const uint8_t *tsb, - int len ) -{ +int descrambler_pass(service_t* t, elementary_stream_t* st, const uint8_t* tsb, int len) { if ((tsb[3] & 0x80) == 0) - ts_recv_packet0((mpegts_service_t *)t, st, tsb, len); + ts_recv_packet0((mpegts_service_t*)t, st, tsb, len); return 1; } -int -descrambler_descramble ( service_t *t, - elementary_stream_t *st, - const uint8_t *tsb, - int len ) -{ - th_descrambler_runtime_t *dr = t->s_descramble; - th_descrambler_key_t *tk; - th_descrambler_data_t *dd, *dd_next; - int len2, len3, r, flush_data, update_tk; - uint32_t dbuflen; - const uint8_t *tsb2; - int64_t now; - uint_fast8_t ki; - sbuf_t *sb; +int descrambler_descramble(service_t* t, elementary_stream_t* st, const uint8_t* tsb, int len) { + th_descrambler_runtime_t* dr = t->s_descramble; + th_descrambler_key_t* tk; + th_descrambler_data_t * dd, *dd_next; + int len2, len3, r, flush_data, update_tk; + uint32_t dbuflen; + const uint8_t* tsb2; + int64_t now; + uint_fast8_t ki; + sbuf_t* sb; lock_assert(&t->s_stream_mutex); if (dr == NULL) { if ((tsb[3] & 0x80) == 0) { - ts_recv_packet0((mpegts_service_t *)t, st, tsb, len); + ts_recv_packet0((mpegts_service_t*)t, st, tsb, len); return 1; } return -1; @@ -1063,31 +1120,31 @@ descrambler_descramble ( service_t *t, tk = &dr->dr_keys[0]; } else { tk = (tsb[3] & 0x80) != 0 ? key_find_struct(dr, tsb, t) : dr->dr_key_last; - } + } if (dr->dr_queue_total == 0 && (tsb[3] & 0x80) == 0) { if (tk && tk->key_csa.csa_type != DESCRAMBLER_NONE) { debug2("%p: descramble0 %d, %s[%d]", dr, len, keystr(tsb), extractpid(tsb)); - tk->key_csa.csa_descramble(&tk->key_csa, (mpegts_service_t *)t, tsb, len); + tk->key_csa.csa_descramble(&tk->key_csa, (mpegts_service_t*)t, tsb, len); dr->dr_key_last = tk; } else { old_key_flush(dr, t); debug2("%p: direct0 %d, %s[%d]", dr, len, keystr(tsb), extractpid(tsb)); - ts_recv_packet0((mpegts_service_t *)t, st, tsb, len); + ts_recv_packet0((mpegts_service_t*)t, st, tsb, len); } return 1; } - update_tk = 0; + update_tk = 0; flush_data = 0; if (dr->dr_ca_resolved > 0) { /* process the queued TS packets or key updates */ for (dd = TAILQ_FIRST(&dr->dr_queue); dd; dd = dd_next) { dd_next = TAILQ_NEXT(dd, dd_link); - sb = &dd->dd_sbuf; - tsb2 = sb->sb_data; - len2 = sb->sb_ptr; + sb = &dd->dd_sbuf; + tsb2 = sb->sb_data; + len2 = sb->sb_ptr; if (dd->dd_key) { key_flush(dr, dd->dd_key, dd->dd_key_changed, t); dd->dd_key = NULL; @@ -1096,37 +1153,45 @@ descrambler_descramble ( service_t *t, goto dd_destroy; if ((tsb2[3] & 0x80) == 0) { if (tk == NULL) { - tk = dr->dr_key_last; + tk = dr->dr_key_last; update_tk = 1; } if (tk) { debug2("%p: descramble1 %d, %s[%d]", dr, len2, keystr(tsb2), extractpid(tsb2)); - tk->key_csa.csa_descramble(&tk->key_csa, (mpegts_service_t *)t, tsb2, len2); + tk->key_csa.csa_descramble(&tk->key_csa, (mpegts_service_t*)t, tsb2, len2); dr->dr_key_last = tk; } else { debug2("%p: direct1 %d, %s[%d]", dr, len2, keystr(tsb2), extractpid(tsb2)); - ts_recv_packet2((mpegts_service_t *)t, tsb2, len2); + ts_recv_packet2((mpegts_service_t*)t, tsb2, len2); } goto dd_destroy; } if (dr->dr_key_multipid) { update_tk = 1; - tk = key_find_struct(dr, tsb2, t); + tk = key_find_struct(dr, tsb2, t); if (tk == NULL) { - if (t->s_start_time + 3000000 < mclk() && - tvhlog_limit(&dr->dr_loglimit_key, 10)) - tvhwarn(LS_DESCRAMBLER, "%s stream key[%d] is not available", - ((mpegts_service_t *)t)->s_dvb_svcname, extractpid(tsb2)); + if (t->s_start_time + 3000000 < mclk() && tvhlog_limit(&dr->dr_loglimit_key, 10)) + tvhwarn(LS_DESCRAMBLER, + "%s stream key[%d] is not available", + ((mpegts_service_t*)t)->s_dvb_svcname, + extractpid(tsb2)); goto next; } } now = mclk(); #ifdef DEBUG2 { - int64_t t1, t2; - t1 = dd->dd_timestamp; - t2 = tk->key_interval - tk->key_interval / 5; - debug2("%p: timestamp %ld thres %ld now %ld (interval %ldms) %s[%d]", dr, t1, now - t2, (now - t1) / 1000, t2 / 1000, keystr(tsb2), extractpid(tsb2)); + int64_t t1, t2; + t1 = dd->dd_timestamp; + t2 = tk->key_interval - tk->key_interval / 5; + debug2("%p: timestamp %ld thres %ld now %ld (interval %ldms) %s[%d]", + dr, + t1, + now - t2, + (now - t1) / 1000, + t2 / 1000, + keystr(tsb2), + extractpid(tsb2)); } #endif if (dd->dd_timestamp < now - (tk->key_interval - tk->key_interval / 5)) { @@ -1148,9 +1213,11 @@ descrambler_descramble ( service_t *t, goto end; } else if (r == 2) goto doit; - tvhtrace(LS_DESCRAMBLER, "stream key[%d] changed to %s for service \"%s\"", - tk->key_pid, (ki & 0x40) ? "odd" : "even", - ((mpegts_service_t *)t)->s_dvb_svcname); + tvhtrace(LS_DESCRAMBLER, + "stream key[%d] changed to %s for service \"%s\"", + tk->key_pid, + (ki & 0x40) ? "odd" : "even", + ((mpegts_service_t*)t)->s_dvb_svcname); if (key_late(dr, tk, ki, dd->dd_timestamp)) { descrambler_notify_nokey(dr); tvh_mutex_unlock(&t->s_stream_mutex); @@ -1165,15 +1232,15 @@ descrambler_descramble ( service_t *t, key_update(t, tk, ki, dd->dd_timestamp); } } -doit: + doit: len3 = mpegts_word_count(tsb2, len2, 0xFF0000C0); debug2("%p: descramble2 %d, %s[%d]", dr, len3, keystr(tsb2), extractpid(tsb2)); - tk->key_csa.csa_descramble(&tk->key_csa, (mpegts_service_t *)t, tsb2, len3); + tk->key_csa.csa_descramble(&tk->key_csa, (mpegts_service_t*)t, tsb2, len3); dr->dr_key_last = tk; } if (len2 == 0) service_reset_streaming_status_flags(t, TSS_NO_ACCESS); -dd_destroy: + dd_destroy: descrambler_data_destroy(dr, dd, 0); } @@ -1181,7 +1248,7 @@ dd_destroy: tk = key_find_struct(dr, tsb, t); if (tk == NULL) { if ((tsb[3] & 0x80) == 0) { - ts_recv_packet0((mpegts_service_t *)t, st, tsb, len); + ts_recv_packet0((mpegts_service_t*)t, st, tsb, len); return 1; } goto next; @@ -1193,9 +1260,11 @@ dd_destroy: if ((ki & 0x80) != 0x00) { if (key_valid(tk, ki) == 0) { if (!key_started(dr, ki) && tvhlog_limit(&dr->dr_loglimit_key, 10)) - tvhwarn(LS_DESCRAMBLER, "%s %s stream key[%d] is not valid", - ((mpegts_service_t *)t)->s_dvb_svcname, - (ki & 0x40) ? "odd" : "even", extractpid(tsb)); + tvhwarn(LS_DESCRAMBLER, + "%s %s stream key[%d] is not valid", + ((mpegts_service_t*)t)->s_dvb_svcname, + (ki & 0x40) ? "odd" : "even", + extractpid(tsb)); goto next; } if (key_changed(dr, tk, ki, mclk())) { @@ -1206,7 +1275,7 @@ dd_destroy: } dr->dr_skip = 1; debug2("%p: descramble3 %d, %s[%d]", dr, len, keystr(tsb), extractpid(tsb)); - tk->key_csa.csa_descramble(&tk->key_csa, (mpegts_service_t *)t, tsb, len); + tk->key_csa.csa_descramble(&tk->key_csa, (mpegts_service_t*)t, tsb, len); dr->dr_key_last = tk; service_reset_streaming_status_flags(t, TSS_NO_ACCESS); return 1; @@ -1223,7 +1292,8 @@ next: if ((ki & 0x80) != 0x00) { if (dr->dr_key_multipid) { tk = key_find_struct(dr, tsb, t); - if (tk == NULL) goto queue; + if (tk == NULL) + goto queue; } else { tk = &dr->dr_keys[0]; } @@ -1231,9 +1301,11 @@ next: /* do not use the first TS packet to decide - it may be wrong */ while (dr->dr_queue_total > dr->dr_initial_paritycheck) { if (descrambler_data_key_check(dr, ki & 0xc0, dr->dr_initial_paritycheck) == 0) { - tvhtrace(LS_DESCRAMBLER, "initial stream key[%d] set to %s for service \"%s\"", - tk->key_pid, (ki & 0x40) ? "odd" : "even", - ((mpegts_service_t *)t)->s_dvb_svcname); + tvhtrace(LS_DESCRAMBLER, + "initial stream key[%d] set to %s for service \"%s\"", + tk->key_pid, + (ki & 0x40) ? "odd" : "even", + ((mpegts_service_t*)t)->s_dvb_svcname); key_update(t, tk, ki, mclk()); break; } else { @@ -1241,13 +1313,15 @@ next: } } } else if (key_changed(dr, tk, ki, mclk())) { - tvhtrace(LS_DESCRAMBLER, "stream key[%d] changed to %s for service \"%s\"", - tk->key_pid, (ki & 0x40) ? "odd" : "even", - ((mpegts_service_t *)t)->s_dvb_svcname); + tvhtrace(LS_DESCRAMBLER, + "stream key[%d] changed to %s for service \"%s\"", + tk->key_pid, + (ki & 0x40) ? "odd" : "even", + ((mpegts_service_t*)t)->s_dvb_svcname); key_update(t, tk, ki, mclk()); } } -queue: + queue: if (dr->dr_ca_count != dr->dr_ca_failed) { /* * Fill a temporary buffer until the keys are known to make @@ -1258,11 +1332,13 @@ queue: descrambler_data_cut(dr, MAX((dbuflen / 10) * 188, len)); if (dr->dr_last_err + sec2mono(10) < mclk()) { dr->dr_last_err = mclk(); - tvherror(LS_DESCRAMBLER, "cannot decode packets for service \"%s\"", - ((mpegts_service_t *)t)->s_dvb_svcname); + tvherror(LS_DESCRAMBLER, + "cannot decode packets for service \"%s\"", + ((mpegts_service_t*)t)->s_dvb_svcname); } else { - tvhtrace(LS_DESCRAMBLER, "cannot decode packets for service \"%s\"", - ((mpegts_service_t *)t)->s_dvb_svcname); + tvhtrace(LS_DESCRAMBLER, + "cannot decode packets for service \"%s\"", + ((mpegts_service_t*)t)->s_dvb_svcname); } } descrambler_data_append(dr, tsb, len); @@ -1270,7 +1346,7 @@ queue: } } else { if (dr->dr_skip || dr->dr_ca_count == 0) - ts_skip_packet2((mpegts_service_t *)t, tsb, len); + ts_skip_packet2((mpegts_service_t*)t, tsb, len); service_set_streaming_status_flags(t, TSS_NO_ACCESS); } if (flush_data) @@ -1287,43 +1363,40 @@ end: } static int -descrambler_table_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - descrambler_table_t *dt = mt->mt_opaque; - descrambler_section_t *ds; - descrambler_ecmsec_t *des; - th_descrambler_runtime_t *dr; - th_descrambler_key_t *tk; - LIST_HEAD(,descrambler_ecmsec) sections; - int emm = (mt->mt_flags & MT_FAST) == 0; - mpegts_service_t *t; - int64_t clk, clk2, clk3; - uint8_t ki; - int i, j; - caid_t *ca; - elementary_stream_t *st; +descrambler_table_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + descrambler_table_t* dt = mt->mt_opaque; + descrambler_section_t* ds; + descrambler_ecmsec_t* des; + th_descrambler_runtime_t* dr; + th_descrambler_key_t* tk; + LIST_HEAD(, descrambler_ecmsec) sections; + int emm = (mt->mt_flags & MT_FAST) == 0; + mpegts_service_t* t; + int64_t clk, clk2, clk3; + uint8_t ki; + int i, j; + caid_t* ca; + elementary_stream_t* st; if (len < 6) return 0; clk = mclk(); LIST_INIT(§ions); tvh_mutex_lock(&mt->mt_mux->mm_descrambler_lock); - TAILQ_FOREACH(ds, &dt->sections, link) { + TAILQ_FOREACH (ds, &dt->sections, link) { if (!emm) { - LIST_FOREACH(des, &ds->ecmsecs, link) + LIST_FOREACH (des, &ds->ecmsecs, link) if (des->number == ptr[4]) break; } else { des = LIST_FIRST(&ds->ecmsecs); } if (des == NULL) { - des = calloc(1, sizeof(*des)); + des = calloc(1, sizeof(*des)); des->number = emm ? 0 : ptr[4]; LIST_INSERT_HEAD(&ds->ecmsecs, des, link); } - if (des->last_data == NULL || len != des->last_data_len || - memcmp(des->last_data, ptr, len)) { + if (des->last_data == NULL || len != des->last_data_len || memcmp(des->last_data, ptr, len)) { free(des->last_data); des->last_data = malloc(len); if (des->last_data) { @@ -1338,12 +1411,12 @@ descrambler_table_callback } atomic_add(&des->refcnt, 1); des->callback = ds->callback; - des->opaque = ds->opaque; + des->opaque = ds->opaque; LIST_INSERT_HEAD(§ions, des, active_link); } tvh_mutex_unlock(&mt->mt_mux->mm_descrambler_lock); - LIST_FOREACH(des, §ions, active_link) { + LIST_FOREACH (des, §ions, active_link) { if (des->changed == 2) { des->callback(des->opaque, mt->mt_pid, ptr, len, emm); if (!emm) { /* ECM */ @@ -1354,55 +1427,113 @@ descrambler_table_callback if (dr) { if (!dr->dr_quick_ecm && !des->quick_ecm_called) { des->quick_ecm_called = 1; - dr->dr_quick_ecm = descrambler_quick_ecm(mt->mt_service, mt->mt_pid); + dr->dr_quick_ecm = descrambler_quick_ecm(mt->mt_service, mt->mt_pid); if (dr->dr_quick_ecm) - tvhdebug(LS_DESCRAMBLER, "quick ECM enabled for service '%s'", - t->s_dvb_svcname); + tvhdebug(LS_DESCRAMBLER, "quick ECM enabled for service '%s'", t->s_dvb_svcname); } if ((ptr[0] & 0xfe) == 0x80) { /* 0x80 = even, 0x81 = odd */ j = ptr[0] & 1; if (dr->dr_ecm_parity == ECM_PARITY_81EVEN_80ODD) j ^= 1; dr->dr_ecm_start[j] = clk; - ki = 1 << (j + 6); /* 0x40 = even, 0x80 = odd */ + ki = 1 << (j + 6); /* 0x40 = even, 0x80 = odd */ for (i = 0; i < DESCRAMBLER_MAX_KEYS; i++) { tk = &dr->dr_keys[i]; if (dr->dr_quick_ecm) tk->key_valid &= ~ki; - TAILQ_FOREACH(st, &mt->mt_service->s_components.set_filter, es_filter_link) { - if (st->es_pid != mt->mt_pid) continue; - LIST_FOREACH(ca, &st->es_caids, link) { - if (ca->use == 0) continue; - tk->key_csa.csa_ecm = (caid_is_videoguard(ca->caid) && (ptr[4] != 0 && (ptr[2] - ptr[4]) == 4)) ? 4 : 0; - tvhtrace(LS_DESCRAMBLER, "key ecm=%X (caid=%04X)", tk->key_csa.csa_ecm, ca->caid); + TAILQ_FOREACH (st, &mt->mt_service->s_components.set_filter, es_filter_link) { + if (st->es_pid != mt->mt_pid) + continue; + LIST_FOREACH (ca, &st->es_caids, link) { + if (ca->use == 0) + continue; + tk->key_csa.csa_ecm = + (caid_is_videoguard(ca->caid) && (ptr[4] != 0 && (ptr[2] - ptr[4]) == 4)) + ? 4 + : 0; + tvhtrace(LS_DESCRAMBLER, + "key ecm=%X (caid=%04X)", + tk->key_csa.csa_ecm, + ca->caid); } } - if (tk->key_pid == 0) break; + if (tk->key_pid == 0) + break; } } - tvhtrace(LS_DESCRAMBLER, "ECM message %02x:%02x (section %d, len %d, pid %d) for service \"%s\"", - ptr[0], ptr[1], des->number, len, mt->mt_pid, t->s_dvb_svcname); + tvhtrace(LS_DESCRAMBLER, + "ECM message %02x:%02x (section %d, len %d, pid %d) for service \"%s\"", + ptr[0], + ptr[1], + des->number, + len, + mt->mt_pid, + t->s_dvb_svcname); } tvh_mutex_unlock(&t->s_stream_mutex); } else - tvhtrace(LS_DESCRAMBLER, "Unknown fast table message %02x (section %d, len %d, pid %d)", - ptr[0], des->number, len, mt->mt_pid); + tvhtrace(LS_DESCRAMBLER, + "Unknown fast table message %02x (section %d, len %d, pid %d)", + ptr[0], + des->number, + len, + mt->mt_pid); } else if (tvhtrace_enabled()) { - const char *s; - if (mt->mt_pid == DVB_PAT_PID) s = "PAT"; - else if (mt->mt_pid == DVB_CAT_PID) s = "CAT"; - else s = "EMM"; + const char* s; + if (mt->mt_pid == DVB_PAT_PID) + s = "PAT"; + else if (mt->mt_pid == DVB_CAT_PID) + s = "CAT"; + else + s = "EMM"; if (len >= 18) - tvhtrace(LS_DESCRAMBLER_EMM, "%s message %02x:{%02x:%02x}:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x (len %d, pid %d)", - s, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], ptr[6], ptr[7], - ptr[8], ptr[9], ptr[10], ptr[11], ptr[12], ptr[13], ptr[14], ptr[15], - ptr[16], ptr[17], len, mt->mt_pid); + tvhtrace(LS_DESCRAMBLER_EMM, + "%s message " + "%02x:{%02x:%02x}:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:%" + "02x:%02x (len %d, pid %d)", + s, + ptr[0], + ptr[1], + ptr[2], + ptr[3], + ptr[4], + ptr[5], + ptr[6], + ptr[7], + ptr[8], + ptr[9], + ptr[10], + ptr[11], + ptr[12], + ptr[13], + ptr[14], + ptr[15], + ptr[16], + ptr[17], + len, + mt->mt_pid); else if (len >= 6) - tvhtrace(LS_DESCRAMBLER_EMM, "%s message %02x:{%02x:%02x}:%02x:%02x:%02x (len %d, pid %d)", - s, ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5], len, mt->mt_pid); + tvhtrace(LS_DESCRAMBLER_EMM, + "%s message %02x:{%02x:%02x}:%02x:%02x:%02x (len %d, pid %d)", + s, + ptr[0], + ptr[1], + ptr[2], + ptr[3], + ptr[4], + ptr[5], + len, + mt->mt_pid); else if (len >= 4) - tvhtrace(LS_DESCRAMBLER_EMM, "%s message %02x:{%02x:%02x}:%02x (len %d, pid %d)", - s, ptr[0], ptr[1], ptr[2], ptr[3], len, mt->mt_pid); + tvhtrace(LS_DESCRAMBLER_EMM, + "%s message %02x:{%02x:%02x}:%02x (len %d, pid %d)", + s, + ptr[0], + ptr[1], + ptr[2], + ptr[3], + len, + mt->mt_pid); } } else if (des->changed == 1 && !emm) { if ((t = mt->mt_service) != NULL) { @@ -1415,9 +1546,11 @@ descrambler_table_callback clk3 = tk->key_timestamp[j]; if (clk3 > 0 && clk3 >= clk2 && clk3 + ms2mono(200) <= clk) { tk->key_timestamp[j] = clk; - tvhtrace(LS_DESCRAMBLER, "ECM: %s key[%d] for service \"%s\" still valid", - j == 0 ? "Even" : "Odd", - tk->key_pid, t->s_dvb_svcname); + tvhtrace(LS_DESCRAMBLER, + "ECM: %s key[%d] for service \"%s\" still valid", + j == 0 ? "Even" : "Odd", + tk->key_pid, + t->s_dvb_svcname); } } } @@ -1435,25 +1568,25 @@ descrambler_table_callback return 0; } -static int -descrambler_open_pid_( mpegts_mux_t *mux, void *opaque, int pid, - descrambler_section_callback_t callback, - service_t *service ) -{ - descrambler_table_t *dt; - descrambler_section_t *ds; - int flags; +static int descrambler_open_pid_(mpegts_mux_t* mux, + void* opaque, + int pid, + descrambler_section_callback_t callback, + service_t* service) { + descrambler_table_t* dt; + descrambler_section_t* ds; + int flags; if (mux == NULL) return 0; if (mux->mm_descrambler_flush) return 0; - flags = (pid >> 16) & MT_FAST; - pid &= 0x1fff; - TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) { + flags = (pid >> 16) & MT_FAST; + pid &= 0x1fff; + TAILQ_FOREACH (dt, &mux->mm_descrambler_tables, link) { if (dt->table->mt_pid != pid || (dt->table->mt_flags & MT_FAST) != flags) continue; - TAILQ_FOREACH(ds, &dt->sections, link) { + TAILQ_FOREACH (ds, &dt->sections, link) { if (ds->opaque == opaque) return 0; } @@ -1462,28 +1595,40 @@ descrambler_open_pid_( mpegts_mux_t *mux, void *opaque, int pid, if (!dt) { dt = calloc(1, sizeof(*dt)); TAILQ_INIT(&dt->sections); - dt->table = mpegts_table_add(mux, 0, 0, descrambler_table_callback, - dt, (flags & MT_FAST) ? "ecm" : "emm", - LS_TBL_CSA, MT_FULL | MT_DEFER | flags, pid, - MPS_WEIGHT_CA); + dt->table = mpegts_table_add(mux, + 0, + 0, + descrambler_table_callback, + dt, + (flags & MT_FAST) ? "ecm" : "emm", + LS_TBL_CSA, + MT_FULL | MT_DEFER | flags, + pid, + MPS_WEIGHT_CA); if (dt->table) - dt->table->mt_service = (mpegts_service_t *)service; + dt->table->mt_service = (mpegts_service_t*)service; TAILQ_INSERT_TAIL(&mux->mm_descrambler_tables, dt, link); } - ds = calloc(1, sizeof(*ds)); - ds->callback = callback; - ds->opaque = opaque; + ds = calloc(1, sizeof(*ds)); + ds->callback = callback; + ds->opaque = opaque; LIST_INIT(&ds->ecmsecs); TAILQ_INSERT_TAIL(&dt->sections, ds, link); - tvhtrace(LS_DESCRAMBLER, "mux %p open pid %04X (%i) (flags 0x%04x) for %p", mux, pid, pid, flags, opaque); + tvhtrace(LS_DESCRAMBLER, + "mux %p open pid %04X (%i) (flags 0x%04x) for %p", + mux, + pid, + pid, + flags, + opaque); return 1; } -int -descrambler_open_pid( mpegts_mux_t *mux, void *opaque, int pid, - descrambler_section_callback_t callback, - service_t *service ) -{ +int descrambler_open_pid(mpegts_mux_t* mux, + void* opaque, + int pid, + descrambler_section_callback_t callback, + service_t* service) { int res; tvh_mutex_lock(&mux->mm_descrambler_lock); @@ -1492,21 +1637,19 @@ descrambler_open_pid( mpegts_mux_t *mux, void *opaque, int pid, return res; } -static int -descrambler_close_pid_( mpegts_mux_t *mux, void *opaque, int pid ) -{ - descrambler_table_t *dt; - descrambler_section_t *ds; - int flags; +static int descrambler_close_pid_(mpegts_mux_t* mux, void* opaque, int pid) { + descrambler_table_t* dt; + descrambler_section_t* ds; + int flags; if (mux == NULL) return 0; - flags = (pid >> 16) & MT_FAST; - pid &= 0x1fff; - TAILQ_FOREACH(dt, &mux->mm_descrambler_tables, link) { + flags = (pid >> 16) & MT_FAST; + pid &= 0x1fff; + TAILQ_FOREACH (dt, &mux->mm_descrambler_tables, link) { if (dt->table->mt_pid != pid || (dt->table->mt_flags & MT_FAST) != flags) continue; - TAILQ_FOREACH(ds, &dt->sections, link) { + TAILQ_FOREACH (ds, &dt->sections, link) { if (ds->opaque == opaque) { TAILQ_REMOVE(&dt->sections, ds, link); descrambler_destroy_section(ds, (flags & MT_FAST) == 0); @@ -1514,7 +1657,13 @@ descrambler_close_pid_( mpegts_mux_t *mux, void *opaque, int pid ) TAILQ_REMOVE(&mux->mm_descrambler_tables, dt, link); descrambler_destroy_table_(dt); } - tvhtrace(LS_DESCRAMBLER, "mux %p close pid %04X (%i) (flags 0x%04x) for %p", mux, pid, pid, flags, opaque); + tvhtrace(LS_DESCRAMBLER, + "mux %p close pid %04X (%i) (flags 0x%04x) for %p", + mux, + pid, + pid, + flags, + opaque); return 1; } } @@ -1522,9 +1671,7 @@ descrambler_close_pid_( mpegts_mux_t *mux, void *opaque, int pid ) return 0; } -int -descrambler_close_pid( mpegts_mux_t *mux, void *opaque, int pid ) -{ +int descrambler_close_pid(mpegts_mux_t* mux, void* opaque, int pid) { int res; tvh_mutex_lock(&mux->mm_descrambler_lock); @@ -1533,11 +1680,9 @@ descrambler_close_pid( mpegts_mux_t *mux, void *opaque, int pid ) return res; } -void -descrambler_flush_tables( mpegts_mux_t *mux ) -{ - descrambler_table_t *dt; - descrambler_emm_t *emm; +void descrambler_flush_tables(mpegts_mux_t* mux) { + descrambler_table_t* dt; + descrambler_emm_t* emm; if (mux == NULL) return; @@ -1556,19 +1701,23 @@ descrambler_flush_tables( mpegts_mux_t *mux ) tvh_mutex_unlock(&mux->mm_descrambler_lock); } -static void descrambler_cat_entry - ( void *_mux, uint16_t caid, uint32_t prov, uint16_t pid ) -{ - mpegts_mux_t *mux = _mux; - descrambler_emm_t *emm; +static void descrambler_cat_entry(void* _mux, uint16_t caid, uint32_t prov, uint16_t pid) { + mpegts_mux_t* mux = _mux; + descrambler_emm_t* emm; caclient_caid_update(mux, caid, prov, pid, 1); tvh_mutex_lock(&mux->mm_descrambler_lock); - TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link) + TAILQ_FOREACH (emm, &mux->mm_descrambler_emms, link) if (emm->caid == caid && emm->prov == prov) { emm->to_be_removed = 0; if (emm->pid == EMM_PID_UNKNOWN) { - tvhtrace(LS_DESCRAMBLER, "attach emm caid %04X (%i) prov %06X (%i) pid %04X (%i)", - caid, caid, prov, prov, pid, pid); + tvhtrace(LS_DESCRAMBLER, + "attach emm caid %04X (%i) prov %06X (%i) pid %04X (%i)", + caid, + caid, + prov, + prov, + pid, + pid); emm->pid = pid; descrambler_open_pid_(mux, emm->opaque, pid, emm->callback, NULL); break; // Only open a PID once @@ -1577,23 +1726,28 @@ static void descrambler_cat_entry tvh_mutex_unlock(&mux->mm_descrambler_lock); } -static void descrambler_cat_clean( mpegts_mux_t *mux ) -{ - descrambler_emm_t *emm; - TAILQ_HEAD(,descrambler_emm) removing; +static void descrambler_cat_clean(mpegts_mux_t* mux) { + descrambler_emm_t* emm; + TAILQ_HEAD(, descrambler_emm) removing; uint16_t caid = 0, pid = 0; uint32_t prov; TAILQ_INIT(&removing); tvh_mutex_lock(&mux->mm_descrambler_lock); - TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link) + TAILQ_FOREACH (emm, &mux->mm_descrambler_emms, link) if (emm->to_be_removed) { if (emm->pid != EMM_PID_UNKNOWN) { caid = emm->caid; prov = emm->prov; pid = emm->pid; - tvhtrace(LS_DESCRAMBLER, "close emm caid %04X (%i) prov %06X (%i) pid %04X (%i)", - caid, caid, prov, prov, pid, pid); + tvhtrace(LS_DESCRAMBLER, + "close emm caid %04X (%i) prov %06X (%i) pid %04X (%i)", + caid, + caid, + prov, + prov, + pid, + pid); descrambler_close_pid_(mux, emm->opaque, pid); } TAILQ_REMOVE(&mux->mm_descrambler_emms, emm, link); @@ -1608,50 +1762,48 @@ static void descrambler_cat_clean( mpegts_mux_t *mux ) } } -void -descrambler_cat_data( mpegts_mux_t *mux, const uint8_t *data, int len ) -{ - descrambler_emm_t *emm; +void descrambler_cat_data(mpegts_mux_t* mux, const uint8_t* data, int len) { + descrambler_emm_t* emm; tvhtrace(LS_DESCRAMBLER, "CAT data (len %d)", len); tvhlog_hexdump(LS_DESCRAMBLER, data, len); caclient_cat_update(mux, data, len); tvh_mutex_lock(&mux->mm_descrambler_lock); - TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link) + TAILQ_FOREACH (emm, &mux->mm_descrambler_emms, link) emm->to_be_removed = 1; tvh_mutex_unlock(&mux->mm_descrambler_lock); dvb_cat_decode(data, len, descrambler_cat_entry, mux); descrambler_cat_clean(mux); } -int -descrambler_open_emm( mpegts_mux_t *mux, void *opaque, - int caid, int prov, - descrambler_section_callback_t callback ) -{ - descrambler_emm_t *emm; - caid_t *c; - int pid = EMM_PID_UNKNOWN; +int descrambler_open_emm(mpegts_mux_t* mux, + void* opaque, + int caid, + int prov, + descrambler_section_callback_t callback) { + descrambler_emm_t* emm; + caid_t* c; + int pid = EMM_PID_UNKNOWN; if (mux == NULL) return 0; tvh_mutex_lock(&mux->mm_descrambler_lock); if (mux->mm_descrambler_flush) goto unlock; - TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link) { + TAILQ_FOREACH (emm, &mux->mm_descrambler_emms, link) { if (emm->caid == caid && emm->prov == prov && emm->opaque == opaque) { -unlock: + unlock: tvh_mutex_unlock(&mux->mm_descrambler_lock); return 0; } } - emm = calloc(1, sizeof(*emm)); + emm = calloc(1, sizeof(*emm)); emm->caid = caid; emm->prov = prov; emm->pid = EMM_PID_UNKNOWN; emm->opaque = opaque; emm->callback = callback; - LIST_FOREACH(c, &mux->mm_descrambler_caids, link) { + LIST_FOREACH (c, &mux->mm_descrambler_caids, link) { if (c->caid == caid && c->providerid == prov) { emm->pid = pid = c->pid; break; @@ -1660,24 +1812,25 @@ unlock: TAILQ_INSERT_TAIL(&mux->mm_descrambler_emms, emm, link); if (pid != EMM_PID_UNKNOWN) { tvhtrace(LS_DESCRAMBLER, - "attach emm caid %04X (%i) pid %04X (%i) - direct", - caid, caid, pid, pid); + "attach emm caid %04X (%i) pid %04X (%i) - direct", + caid, + caid, + pid, + pid); descrambler_open_pid_(mux, opaque, pid, callback, NULL); } tvh_mutex_unlock(&mux->mm_descrambler_lock); return 1; } -int -descrambler_close_emm( mpegts_mux_t *mux, void *opaque, int caid, int prov ) -{ - descrambler_emm_t *emm; - int pid; +int descrambler_close_emm(mpegts_mux_t* mux, void* opaque, int caid, int prov) { + descrambler_emm_t* emm; + int pid; if (mux == NULL) return 0; tvh_mutex_lock(&mux->mm_descrambler_lock); - TAILQ_FOREACH(emm, &mux->mm_descrambler_emms, link) + TAILQ_FOREACH (emm, &mux->mm_descrambler_emms, link) if (emm->caid == caid && emm->prov == prov && emm->opaque == opaque) break; if (!emm) { @@ -1685,12 +1838,18 @@ descrambler_close_emm( mpegts_mux_t *mux, void *opaque, int caid, int prov ) return 0; } TAILQ_REMOVE(&mux->mm_descrambler_emms, emm, link); - pid = emm->pid; + pid = emm->pid; if (pid != EMM_PID_UNKNOWN) { caid = emm->caid; prov = emm->prov; - tvhtrace(LS_DESCRAMBLER, "close emm caid %04X (%i) prov %06X (%i) pid %04X (%i) - direct", - caid, caid, prov, prov, pid, pid); + tvhtrace(LS_DESCRAMBLER, + "close emm caid %04X (%i) prov %06X (%i) pid %04X (%i) - direct", + caid, + caid, + prov, + prov, + pid, + pid); descrambler_close_pid_(mux, opaque, pid); } tvh_mutex_unlock(&mux->mm_descrambler_lock); diff --git a/src/descrambler/descrambler.h b/src/descrambler/descrambler.h index ac5ff312c..02b9832e8 100644 --- a/src/descrambler/descrambler.h +++ b/src/descrambler/descrambler.h @@ -31,23 +31,23 @@ struct mpegts_table; struct mpegts_mux; struct th_descrambler_data; -#define DESCRAMBLER_NONE 0 +#define DESCRAMBLER_NONE 0 /* 64-bit keys */ -#define DESCRAMBLER_CSA_CBC 1 -#define DESCRAMBLER_DES_NCB 2 /* no block cipher mode! */ -#define DESCRAMBLER_AES_ECB 3 +#define DESCRAMBLER_CSA_CBC 1 +#define DESCRAMBLER_DES_NCB 2 /* no block cipher mode! */ +#define DESCRAMBLER_AES_ECB 3 /* 128-bit keys */ -#define DESCRAMBLER_AES128_ECB 16 +#define DESCRAMBLER_AES128_ECB 16 #define DESCRAMBLER_KEY_SIZE(type) ((type >= DESCRAMBLER_AES128_ECB) ? 16 : 8) typedef enum { - DS_INIT, - DS_READY, - DS_RESOLVED, - DS_FORBIDDEN, - DS_FATAL, - DS_IDLE + DS_INIT, + DS_READY, + DS_RESOLVED, + DS_FORBIDDEN, + DS_FATAL, + DS_IDLE } th_descrambler_keystate_t; /** @@ -58,64 +58,67 @@ typedef enum { typedef struct th_descrambler { LIST_ENTRY(th_descrambler) td_service_link; - char *td_nicename; + char* td_nicename; th_descrambler_keystate_t td_keystate; - struct service *td_service; + struct service* td_service; - void (*td_stop) (struct th_descrambler *d); - void (*td_caid_change)(struct th_descrambler *d); - int (*td_ecm_reset) (struct th_descrambler *d); - void (*td_ecm_idle) (struct th_descrambler *d); + void (*td_stop)(struct th_descrambler* d); + void (*td_caid_change)(struct th_descrambler* d); + int (*td_ecm_reset)(struct th_descrambler* d); + void (*td_ecm_idle)(struct th_descrambler* d); } th_descrambler_t; typedef struct th_descrambler_key { - uint8_t key_data[2][16]; /* 0 = even, 1 = odd, max 16-byte key */ - tvhcsa_t key_csa; - uint16_t key_pid; /* keys are assigned to this pid (when multipid is set) */ - uint64_t key_interval; - uint64_t key_initial_interval; - int64_t key_start; - int64_t key_timestamp[2]; - uint8_t key_index; - uint8_t key_valid; - uint8_t key_type_overwritten; + uint8_t key_data[2][16]; /* 0 = even, 1 = odd, max 16-byte key */ + tvhcsa_t key_csa; + uint16_t key_pid; /* keys are assigned to this pid (when multipid is set) */ + uint64_t key_interval; + uint64_t key_initial_interval; + int64_t key_start; + int64_t key_timestamp[2]; + uint8_t key_index; + uint8_t key_valid; + uint8_t key_type_overwritten; tvhlog_limit_t key_loglimit; } th_descrambler_key_t; typedef struct th_descrambler_runtime { - th_descrambler_t *dr_descrambler; - struct service *dr_service; - int (*dr_descramble)(struct service *t, struct elementary_stream *st, - const uint8_t *tsb, int len); - int dr_ca_count; - int dr_ca_resolved; - int dr_ca_failed; - int dr_ca_fatal; - int dr_ecm_parity; - uint32_t dr_external:1; - uint32_t dr_skip:1; - uint32_t dr_quick_ecm:1; - uint32_t dr_key_const:1; - uint32_t dr_key_multipid:1; - int64_t dr_ecm_start[2]; - int64_t dr_ecm_last_key_time; - int64_t dr_ecm_key_margin; - int64_t dr_last_err; - int64_t dr_force_skip; - th_descrambler_key_t dr_keys[DESCRAMBLER_MAX_KEYS]; - th_descrambler_key_t *dr_key_last; + th_descrambler_t* dr_descrambler; + struct service* dr_service; + int ( + *dr_descramble)(struct service* t, struct elementary_stream* st, const uint8_t* tsb, int len); + int dr_ca_count; + int dr_ca_resolved; + int dr_ca_failed; + int dr_ca_fatal; + int dr_ecm_parity; + uint32_t dr_external : 1; + uint32_t dr_skip : 1; + uint32_t dr_quick_ecm : 1; + uint32_t dr_key_const : 1; + uint32_t dr_key_multipid : 1; + int64_t dr_ecm_start[2]; + int64_t dr_ecm_last_key_time; + int64_t dr_ecm_key_margin; + int64_t dr_last_err; + int64_t dr_force_skip; + th_descrambler_key_t dr_keys[DESCRAMBLER_MAX_KEYS]; + th_descrambler_key_t* dr_key_last; TAILQ_HEAD(, th_descrambler_data) dr_queue; - uint32_t dr_queue_total; - uint32_t dr_paritycheck; - uint32_t dr_initial_paritycheck; + uint32_t dr_queue_total; + uint32_t dr_paritycheck; + uint32_t dr_initial_paritycheck; tvhlog_limit_t dr_loglimit_key; } th_descrambler_runtime_t; -typedef void (*descrambler_section_callback_t) - (void *opaque, int pid, const uint8_t *section, int section_len, int emm); +typedef void (*descrambler_section_callback_t)(void* opaque, + int pid, + const uint8_t* section, + int section_len, + int emm); /** * Track required PIDs @@ -123,27 +126,27 @@ typedef void (*descrambler_section_callback_t) typedef struct descrambler_ecmsec { LIST_ENTRY(descrambler_ecmsec) link; LIST_ENTRY(descrambler_ecmsec) active_link; - int refcnt; - uint8_t changed; - uint8_t number; - uint8_t quick_ecm_called; - uint8_t *last_data; - int last_data_len; + int refcnt; + uint8_t changed; + uint8_t number; + uint8_t quick_ecm_called; + uint8_t* last_data; + int last_data_len; descrambler_section_callback_t callback; - void *opaque; + void* opaque; } descrambler_ecmsec_t; typedef struct descrambler_section { TAILQ_ENTRY(descrambler_section) link; descrambler_section_callback_t callback; - void *opaque; + void* opaque; LIST_HEAD(, descrambler_ecmsec) ecmsecs; } descrambler_section_t; typedef struct descrambler_table { TAILQ_ENTRY(descrambler_table) link; - struct mpegts_table *table; - TAILQ_HEAD(,descrambler_section) sections; + struct mpegts_table* table; + TAILQ_HEAD(, descrambler_section) sections; } descrambler_table_t; /** @@ -164,58 +167,69 @@ typedef struct caid { /** * List of EMM subscribers */ -#define EMM_PID_UNKNOWN ((uint16_t)-1) +#define EMM_PID_UNKNOWN ((uint16_t) - 1) typedef struct descrambler_emm { TAILQ_ENTRY(descrambler_emm) link; - uint16_t caid; - uint32_t prov; - uint16_t pid; - unsigned int to_be_removed:1; + uint16_t caid; + uint32_t prov; + uint16_t pid; + unsigned int to_be_removed : 1; descrambler_section_callback_t callback; - void *opaque; + void* opaque; } descrambler_emm_t; LIST_HEAD(caid_list, caid); #define DESCRAMBLER_ECM_PID(pid) ((pid) | (MT_FAST << 16)) -void descrambler_init ( void ); -void descrambler_done ( void ); -void descrambler_change_keystate ( th_descrambler_t *t, th_descrambler_keystate_t state, int lock ); -const char *descrambler_keystate2str( th_descrambler_keystate_t keystate ); -const char *descrambler_keytype2str( th_descrambler_keystate_t keytype ); -void descrambler_service_start ( struct service *t ); -void descrambler_service_stop ( struct service *t ); -void descrambler_caid_changed ( struct service *t ); -int descrambler_resolved ( struct service *t, th_descrambler_t *ignore ); -int descrambler_multi_pid ( th_descrambler_t *t ); -void descrambler_keys ( th_descrambler_t *t, int type, uint16_t pid, - const uint8_t *even, const uint8_t *odd ); -void descrambler_notify ( th_descrambler_t *t, - uint16_t caid, uint32_t provid, - const char *cardsystem, uint16_t pid, uint32_t ecmtime, - uint16_t hops, const char *reader, const char *from, - const char *protocol ); -int descrambler_pass ( struct service *t, struct elementary_stream *st, - const uint8_t *tsb, int len ); -int descrambler_descramble ( struct service *t, - struct elementary_stream *st, - const uint8_t *tsb, int len ); -void descrambler_flush_table_data( struct service *t ); -int descrambler_open_pid ( struct mpegts_mux *mux, void *opaque, int pid, - descrambler_section_callback_t callback, - struct service *service ); -int descrambler_close_pid ( struct mpegts_mux *mux, void *opaque, int pid ); -void descrambler_flush_tables ( struct mpegts_mux *mux ); -void descrambler_cat_data ( struct mpegts_mux *mux, const uint8_t *data, int len ); -int descrambler_open_emm ( struct mpegts_mux *mux, void *opaque, - int caid, int provid, - descrambler_section_callback_t callback ); -int descrambler_close_emm ( struct mpegts_mux *mux, void *opaque, - int caid, int provid ); +void descrambler_init(void); +void descrambler_done(void); +void descrambler_change_keystate(th_descrambler_t* t, th_descrambler_keystate_t state, int lock); +const char* descrambler_keystate2str(th_descrambler_keystate_t keystate); +const char* descrambler_keytype2str(th_descrambler_keystate_t keytype); +void descrambler_service_start(struct service* t); +void descrambler_service_stop(struct service* t); +void descrambler_caid_changed(struct service* t); +int descrambler_resolved(struct service* t, th_descrambler_t* ignore); +int descrambler_multi_pid(th_descrambler_t* t); +void descrambler_keys(th_descrambler_t* t, + int type, + uint16_t pid, + const uint8_t* even, + const uint8_t* odd); +void descrambler_notify(th_descrambler_t* t, + uint16_t caid, + uint32_t provid, + const char* cardsystem, + uint16_t pid, + uint32_t ecmtime, + uint16_t hops, + const char* reader, + const char* from, + const char* protocol); +int descrambler_pass(struct service* t, struct elementary_stream* st, const uint8_t* tsb, int len); +int descrambler_descramble(struct service* t, + struct elementary_stream* st, + const uint8_t* tsb, + int len); +void descrambler_flush_table_data(struct service* t); +int descrambler_open_pid(struct mpegts_mux* mux, + void* opaque, + int pid, + descrambler_section_callback_t callback, + struct service* service); +int descrambler_close_pid(struct mpegts_mux* mux, void* opaque, int pid); +void descrambler_flush_tables(struct mpegts_mux* mux); +void descrambler_cat_data(struct mpegts_mux* mux, const uint8_t* data, int len); +int descrambler_open_emm(struct mpegts_mux* mux, + void* opaque, + int caid, + int provid, + descrambler_section_callback_t callback); +int descrambler_close_emm(struct mpegts_mux* mux, void* opaque, int caid, int provid); #endif /* __TVH_DESCRAMBLER_H__ */ diff --git a/src/descrambler/dvbcam.c b/src/descrambler/dvbcam.c index 3fefecf12..c13571176 100644 --- a/src/descrambler/dvbcam.c +++ b/src/descrambler/dvbcam.c @@ -31,57 +31,55 @@ #if ENABLE_LINUXDVB_CA -#define DVBCAM_SEL_ALL 0 -#define DVBCAM_SEL_FIRST 1 -#define DVBCAM_SEL_LAST 2 +#define DVBCAM_SEL_ALL 0 +#define DVBCAM_SEL_FIRST 1 +#define DVBCAM_SEL_LAST 2 typedef struct dvbcam_active_cam { TAILQ_ENTRY(dvbcam_active_cam) global_link; - uint16_t caids[32]; - int caids_count; - linuxdvb_ca_t *ca; - uint8_t slot; - int active_programs; - int allocated_programs; + uint16_t caids[32]; + int caids_count; + linuxdvb_ca_t* ca; + uint8_t slot; + int active_programs; + int allocated_programs; } dvbcam_active_cam_t; typedef struct dvbcam_active_service { th_descrambler_t; TAILQ_ENTRY(dvbcam_active_service) global_link; - LIST_ENTRY(dvbcam_active_service) dvbcam_link; - uint8_t *last_pmt; - int last_pmt_len; - uint16_t caid_list[32]; - dvbcam_active_cam_t *ac; - mpegts_apids_t ecm_pids; - uint8_t *cat_data; - int cat_data_len; - mpegts_apids_t cat_pids; + LIST_ENTRY(dvbcam_active_service) dvbcam_link; + uint8_t* last_pmt; + int last_pmt_len; + uint16_t caid_list[32]; + dvbcam_active_cam_t* ac; + mpegts_apids_t ecm_pids; + uint8_t* cat_data; + int cat_data_len; + mpegts_apids_t cat_pids; #if ENABLE_DDCI - linuxdvb_ddci_t *lddci; + linuxdvb_ddci_t* lddci; #endif } dvbcam_active_service_t; typedef struct dvbcam { caclient_t; - LIST_HEAD(,dvbcam_active_service) services; - int limit; - int multi; - int caid_select; + LIST_HEAD(, dvbcam_active_service) services; + int limit; + int multi; + int caid_select; uint16_t caid_list[32]; } dvbcam_t; -static TAILQ_HEAD(,dvbcam_active_service) dvbcam_active_services; -static TAILQ_HEAD(,dvbcam_active_cam) dvbcam_active_cams; +static TAILQ_HEAD(, dvbcam_active_service) dvbcam_active_services; +static TAILQ_HEAD(, dvbcam_active_cam) dvbcam_active_cams; static tvh_mutex_t dvbcam_mutex; /* * */ -static void -dvbcam_status_update0(caclient_t *cac) -{ +static void dvbcam_status_update0(caclient_t* cac) { int status = CACLIENT_STATUS_NONE; tvh_mutex_lock(&dvbcam_mutex); @@ -94,9 +92,7 @@ dvbcam_status_update0(caclient_t *cac) /* * */ -static void -dvbcam_status_update(void) -{ +static void dvbcam_status_update(void) { caclient_foreach(dvbcam_status_update0); } @@ -107,11 +103,9 @@ dvbcam_status_update(void) /* * */ -static int -dvbcam_service_check_caid(dvbcam_active_service_t *as, uint16_t caid) -{ +static int dvbcam_service_check_caid(dvbcam_active_service_t* as, uint16_t caid) { uint16_t caid1; - int i; + int i; for (i = 0; i < ARRAY_SIZE(as->caid_list); i++) { caid1 = as->caid_list[i]; @@ -123,37 +117,33 @@ dvbcam_service_check_caid(dvbcam_active_service_t *as, uint16_t caid) return 0; } -static void -dvbcam_unregister_ddci(dvbcam_active_cam_t *ac, dvbcam_active_service_t *as) -{ - linuxdvb_ddci_t *lddci; +static void dvbcam_unregister_ddci(dvbcam_active_cam_t* ac, dvbcam_active_service_t* as) { + linuxdvb_ddci_t* lddci; if (ac == NULL) return; lddci = as->lddci; if (lddci) { - th_descrambler_t *td = (th_descrambler_t *)as; - service_t *t = td->td_service; - th_descrambler_runtime_t *dr = t->s_descramble; + th_descrambler_t* td = (th_descrambler_t*)as; + service_t* t = td->td_service; + th_descrambler_runtime_t* dr = t->s_descramble; /* unassign the service from the DD CI CAM */ as->lddci = NULL; linuxdvb_ddci_unassign(lddci, t); if (dr) { dr->dr_descrambler = NULL; - dr->dr_descramble = NULL; + dr->dr_descramble = NULL; } } } -int -dvbcam_is_ddci(struct service *t) -{ - th_descrambler_runtime_t *dr = t->s_descramble; - int ret = 0; +int dvbcam_is_ddci(struct service* t) { + th_descrambler_runtime_t* dr = t->s_descramble; + int ret = 0; if (dr) { - dvbcam_active_service_t *as = (dvbcam_active_service_t *)dr->dr_descrambler; + dvbcam_active_service_t* as = (dvbcam_active_service_t*)dr->dr_descrambler; if (as && as->ac) ret = as->lddci != NULL; } @@ -164,18 +154,15 @@ dvbcam_is_ddci(struct service *t) /* * */ -void -dvbcam_register_cam(linuxdvb_ca_t * lca, uint16_t * caids, - int caids_count) -{ +void dvbcam_register_cam(linuxdvb_ca_t* lca, uint16_t* caids, int caids_count) { dvbcam_active_cam_t *ac, *ac_first; - int registered = 0, call_update = 0; + int registered = 0, call_update = 0; tvhtrace(LS_DVBCAM, "register cam %p caids_count %u", lca->lca_name, caids_count); tvh_mutex_lock(&dvbcam_mutex); - TAILQ_FOREACH(ac, &dvbcam_active_cams, global_link) { + TAILQ_FOREACH (ac, &dvbcam_active_cams, global_link) { if (ac->ca == lca) { registered = 1; break; @@ -203,18 +190,15 @@ reterr: if (call_update) dvbcam_status_update(); - } /* * */ -void -dvbcam_unregister_cam(linuxdvb_ca_t *lca) -{ - dvbcam_active_cam_t *ac, *ac_next; - dvbcam_active_service_t *as; - int call_update; +void dvbcam_unregister_cam(linuxdvb_ca_t* lca) { + dvbcam_active_cam_t * ac, *ac_next; + dvbcam_active_service_t* as; + int call_update; tvhtrace(LS_DVBCAM, "unregister cam %s", lca->lca_name); @@ -226,7 +210,7 @@ dvbcam_unregister_cam(linuxdvb_ca_t *lca) if (ac->ca == lca) { TAILQ_REMOVE(&dvbcam_active_cams, ac, global_link); /* remove pointer to this CAM in all active services */ - TAILQ_FOREACH(as, &dvbcam_active_services, global_link) + TAILQ_FOREACH (as, &dvbcam_active_services, global_link) if (as->ac == ac) { #if ENABLE_DDCI dvbcam_unregister_ddci(ac, as); @@ -248,13 +232,11 @@ dvbcam_unregister_cam(linuxdvb_ca_t *lca) /* * */ -static int -dvbcam_ca_lookup(dvbcam_active_cam_t *ac, mpegts_input_t *input, uint16_t caid) -{ +static int dvbcam_ca_lookup(dvbcam_active_cam_t* ac, mpegts_input_t* input, uint16_t caid) { extern const idclass_t linuxdvb_frontend_class; - linuxdvb_frontend_t *lfe = NULL; - linuxdvb_transport_t *lcat; - int i; + linuxdvb_frontend_t* lfe = NULL; + linuxdvb_transport_t* lcat; + int i; if (ac->ca == NULL) return 0; @@ -266,8 +248,8 @@ dvbcam_ca_lookup(dvbcam_active_cam_t *ac, mpegts_input_t *input, uint16_t caid) #if ENABLE_DDCI if (!lcat->lddci) #endif - if (lfe == NULL || lcat->lcat_adapter != lfe->lfe_adapter) - return 0; + if (lfe == NULL || lcat->lcat_adapter != lfe->lfe_adapter) + return 0; for (i = 0; i < ac->caids_count; i++) if (ac->caids[i] == caid) @@ -279,21 +261,19 @@ dvbcam_ca_lookup(dvbcam_active_cam_t *ac, mpegts_input_t *input, uint16_t caid) /* * */ -void -dvbcam_pmt_data(mpegts_service_t *s, const uint8_t *ptr, int len) -{ - dvbcam_active_cam_t *ac; - dvbcam_active_service_t *as; - int bcmd, is_update = 0, r; - uint8_t *capmt; - size_t capmt_len; +void dvbcam_pmt_data(mpegts_service_t* s, const uint8_t* ptr, int len) { + dvbcam_active_cam_t* ac; + dvbcam_active_service_t* as; + int bcmd, is_update = 0, r; + uint8_t* capmt; + size_t capmt_len; tvh_mutex_lock(&s->s_stream_mutex); tvh_mutex_lock(&dvbcam_mutex); /* find this service in the list of active services */ - TAILQ_FOREACH(as, &dvbcam_active_services, global_link) - if (as->td_service == (service_t *)s) + TAILQ_FOREACH (as, &dvbcam_active_services, global_link) + if (as->td_service == (service_t*)s) break; if (as == NULL) { @@ -331,11 +311,15 @@ dvbcam_pmt_data(mpegts_service_t *s, const uint8_t *ptr, int len) ac->active_programs++; } - r = en50221_capmt_build(s, bcmd, - service_id16(s), - ac->caids, ac->caids_count, - as->last_pmt, as->last_pmt_len, - &capmt, &capmt_len); + r = en50221_capmt_build(s, + bcmd, + service_id16(s), + ac->caids, + ac->caids_count, + as->last_pmt, + as->last_pmt_len, + &capmt, + &capmt_len); if (r >= 0) { linuxdvb_ca_enqueue_capmt(ac->ca, capmt, capmt_len, 1); free(capmt); @@ -347,26 +331,28 @@ done: tvh_mutex_unlock(&s->s_stream_mutex); } -static void -dvbcam_service_destroy(th_descrambler_t *td) -{ - dvbcam_active_service_t *as = (dvbcam_active_service_t *)td; - dvbcam_active_cam_t *ac; - mpegts_service_t *s; - int do_active_programs = 0, r; - uint8_t *capmt; - size_t capmt_len; +static void dvbcam_service_destroy(th_descrambler_t* td) { + dvbcam_active_service_t* as = (dvbcam_active_service_t*)td; + dvbcam_active_cam_t* ac; + mpegts_service_t* s; + int do_active_programs = 0, r; + uint8_t* capmt; + size_t capmt_len; tvh_mutex_lock(&dvbcam_mutex); ac = as->ac; if (as->last_pmt) { if (ac) { - s = (mpegts_service_t *)td->td_service; - r = en50221_capmt_build(s, EN50221_CAPMT_BUILD_DELETE, - service_id16(s), - ac->caids, ac->caids_count, - as->last_pmt, as->last_pmt_len, - &capmt, &capmt_len); + s = (mpegts_service_t*)td->td_service; + r = en50221_capmt_build(s, + EN50221_CAPMT_BUILD_DELETE, + service_id16(s), + ac->caids, + ac->caids_count, + as->last_pmt, + as->last_pmt_len, + &capmt, + &capmt_len); if (r >= 0) { linuxdvb_ca_enqueue_capmt(ac->ca, capmt, capmt_len, 0); free(capmt); @@ -385,7 +371,7 @@ dvbcam_service_destroy(th_descrambler_t *td) LIST_REMOVE(as, dvbcam_link); LIST_REMOVE(td, td_service_link); TAILQ_REMOVE(&dvbcam_active_services, as, global_link); - TAILQ_FOREACH(ac, &dvbcam_active_cams, global_link) { + TAILQ_FOREACH (ac, &dvbcam_active_cams, global_link) { if (as->ac == ac) { if (do_active_programs) ac->active_programs--; @@ -403,10 +389,9 @@ dvbcam_service_destroy(th_descrambler_t *td) #if ENABLE_DDCI static int -dvbcam_descramble_ddci(service_t *t, elementary_stream_t *st, const uint8_t *tsb, int len) -{ - th_descrambler_runtime_t *dr = ((mpegts_service_t *)t)->s_descramble; - dvbcam_active_service_t *as = (dvbcam_active_service_t *)dr->dr_descrambler; +dvbcam_descramble_ddci(service_t* t, elementary_stream_t* st, const uint8_t* tsb, int len) { + th_descrambler_runtime_t* dr = ((mpegts_service_t*)t)->s_descramble; + dvbcam_active_service_t* as = (dvbcam_active_service_t*)dr->dr_descrambler; if (as->ac != NULL) linuxdvb_ddci_put(as->ac->ca->lca_transport->lddci, t, tsb, len); @@ -420,25 +405,23 @@ dvbcam_descramble_ddci(service_t *t, elementary_stream_t *st, const uint8_t *tsb * a) start a new service * b) restart a running service with possible caid changes */ -static void -dvbcam_service_start(caclient_t *cac, service_t *t) -{ - dvbcam_t *dc = (dvbcam_t *)cac; - dvbcam_active_service_t *as; - dvbcam_active_cam_t *ac = NULL; - th_descrambler_t *td; - elementary_stream_t *st; - th_descrambler_runtime_t *dr; - caid_t *c = NULL; - char buf[128]; - int i, j; +static void dvbcam_service_start(caclient_t* cac, service_t* t) { + dvbcam_t* dc = (dvbcam_t*)cac; + dvbcam_active_service_t* as; + dvbcam_active_cam_t* ac = NULL; + th_descrambler_t* td; + elementary_stream_t* st; + th_descrambler_runtime_t* dr; + caid_t* c = NULL; + char buf[128]; + int i, j; #if ENABLE_DDCI - mpegts_input_t *mi; - mpegts_mux_t *mm; - mpegts_apids_t ecm_pids; - mpegts_apids_t ecm_to_open; - mpegts_apids_t ecm_to_close; - linuxdvb_transport_t *lcat; + mpegts_input_t* mi; + mpegts_mux_t* mm; + mpegts_apids_t ecm_pids; + mpegts_apids_t ecm_to_open; + mpegts_apids_t ecm_to_close; + linuxdvb_transport_t* lcat; #endif if (!cac->cac_enabled) @@ -456,7 +439,7 @@ dvbcam_service_start(caclient_t *cac, service_t *t) tvh_mutex_lock(&dvbcam_mutex); /* is there already a CAM associated to the service? */ - TAILQ_FOREACH(as, &dvbcam_active_services, global_link) { + TAILQ_FOREACH (as, &dvbcam_active_services, global_link) { if (as->td_service == t) { ac = as->ac; goto update_pid; @@ -485,27 +468,33 @@ dvbcam_service_start(caclient_t *cac, service_t *t) if (i > 0) break; } - TAILQ_FOREACH(st, &t->s_components.set_all, es_link) { - if (st->es_type != SCT_CA) continue; - LIST_FOREACH(c, &st->es_caids, link) { - if (!c->use) continue; - if (t->s_dvb_forcecaid && t->s_dvb_forcecaid != c->caid) continue; - if (dc->caid_list[0] && dc->caid_list[i] != c->caid) continue; - TAILQ_FOREACH(ac, &dvbcam_active_cams, global_link) { - if (dvbcam_ca_lookup(ac, - ((mpegts_service_t *)t)->s_dvb_active_input, - c->caid)) { + TAILQ_FOREACH (st, &t->s_components.set_all, es_link) { + if (st->es_type != SCT_CA) + continue; + LIST_FOREACH (c, &st->es_caids, link) { + if (!c->use) + continue; + if (t->s_dvb_forcecaid && t->s_dvb_forcecaid != c->caid) + continue; + if (dc->caid_list[0] && dc->caid_list[i] != c->caid) + continue; + TAILQ_FOREACH (ac, &dvbcam_active_cams, global_link) { + if (dvbcam_ca_lookup(ac, ((mpegts_service_t*)t)->s_dvb_active_input, c->caid)) { /* limit the concurrent service decoders per CAM */ if (dc->limit > 0 && ac->allocated_programs >= dc->limit) continue; #if ENABLE_DDCI lcat = ac->ca->lca_transport; - if (lcat->lddci && linuxdvb_ddci_do_not_assign(lcat->lddci, t, - dc->multi)) + if (lcat->lddci && linuxdvb_ddci_do_not_assign(lcat->lddci, t, dc->multi)) continue; #endif - tvhtrace(LS_DVBCAM, "%s/%p: match CAID %04X PID %d (%04X)", - ac->ca->lca_name, t, c->caid, c->pid, c->pid); + tvhtrace(LS_DVBCAM, + "%s/%p: match CAID %04X PID %d (%04X)", + ac->ca->lca_name, + t, + c->caid, + c->pid, + c->pid); goto end_of_search_for_cam; } } @@ -524,12 +513,10 @@ end_of_search_for_cam: as->ac = ac; - if (dc->caid_select == DVBCAM_SEL_FIRST || - t->s_dvb_forcecaid) { + if (dc->caid_select == DVBCAM_SEL_FIRST || t->s_dvb_forcecaid) { as->caid_list[0] = c->caid; as->caid_list[1] = 0; - tvhtrace(LS_DVBCAM, "%s/%p: first CAID %04X selected", - ac->ca->lca_name, t, as->caid_list[0]); + tvhtrace(LS_DVBCAM, "%s/%p: first CAID %04X selected", ac->ca->lca_name, t, as->caid_list[0]); } else { for (i = j = 0; i < ARRAY_SIZE(dc->caid_list); i++) { if (dc->caid_list[0]) { @@ -539,22 +526,22 @@ end_of_search_for_cam: if (i > 0) break; } - TAILQ_FOREACH(st, &t->s_components.set_filter, es_link) { - if (st->es_type != SCT_CA) continue; - LIST_FOREACH(c, &st->es_caids, link) { + TAILQ_FOREACH (st, &t->s_components.set_filter, es_link) { + if (st->es_type != SCT_CA) + continue; + LIST_FOREACH (c, &st->es_caids, link) { if (i >= ARRAY_SIZE(as->caid_list)) { - tvherror(LS_DVBCAM, "%s/%p: CAID service list overflow", - ac->ca->lca_name, t); + tvherror(LS_DVBCAM, "%s/%p: CAID service list overflow", ac->ca->lca_name, t); break; } - if (!c->use) continue; - if (dc->caid_list[0] && c->caid != dc->caid_list[i]) continue; - if (!dvbcam_ca_lookup(ac, - ((mpegts_service_t *)t)->s_dvb_active_input, - c->caid)) continue; + if (!c->use) + continue; + if (dc->caid_list[0] && c->caid != dc->caid_list[i]) + continue; + if (!dvbcam_ca_lookup(ac, ((mpegts_service_t*)t)->s_dvb_active_input, c->caid)) + continue; if (dc->caid_select != DVBCAM_SEL_LAST) - tvhtrace(LS_DVBCAM, "%s/%p: add CAID %04X to selection", - ac->ca->lca_name, t, c->caid); + tvhtrace(LS_DVBCAM, "%s/%p: add CAID %04X to selection", ac->ca->lca_name, t, c->caid); as->caid_list[j++] = c->caid; } } @@ -562,32 +549,35 @@ end_of_search_for_cam: if (j < ARRAY_SIZE(as->caid_list)) as->caid_list[j] = 0; if (dc->caid_select == DVBCAM_SEL_LAST && j > 0) { - as->caid_list[0] = as->caid_list[j-1]; + as->caid_list[0] = as->caid_list[j - 1]; as->caid_list[1] = 0; - tvhtrace(LS_DVBCAM, "%s/%p: last CAID %04X selected", - ac->ca->lca_name, t, as->caid_list[0]); + tvhtrace(LS_DVBCAM, "%s/%p: last CAID %04X selected", ac->ca->lca_name, t, as->caid_list[0]); } } mpegts_pid_init(&as->ecm_pids); mpegts_pid_init(&as->cat_pids); - td = (th_descrambler_t *)as; - snprintf(buf, sizeof(buf), "dvbcam-%i-%i-%04X", - ac->ca->lca_adapnum, ac->ca->lca_slotnum, (int)as->caid_list[0]); - td->td_nicename = strdup(buf); - td->td_service = t; - td->td_stop = dvbcam_service_destroy; - dr = t->s_descramble; + td = (th_descrambler_t*)as; + snprintf(buf, + sizeof(buf), + "dvbcam-%i-%i-%04X", + ac->ca->lca_adapnum, + ac->ca->lca_slotnum, + (int)as->caid_list[0]); + td->td_nicename = strdup(buf); + td->td_service = t; + td->td_stop = dvbcam_service_destroy; + dr = t->s_descramble; dr->dr_descrambler = td; - dr->dr_descramble = descrambler_pass; + dr->dr_descramble = descrambler_pass; #if ENABLE_DDCI lcat = ac->ca->lca_transport; if (lcat->lddci) { /* assign the service to the DD CI CAM */ linuxdvb_ddci_assign(lcat->lddci, t); dr->dr_descramble = dvbcam_descramble_ddci; - as->lddci = lcat->lddci; + as->lddci = lcat->lddci; } #endif descrambler_change_keystate(td, DS_READY, 0); @@ -600,14 +590,21 @@ end_of_search_for_cam: update_pid: #if ENABLE_DDCI /* open selected ECM PIDs */ - TAILQ_FOREACH(st, &t->s_components.set_all, es_link) { - if (st->es_type != SCT_CA) continue; - LIST_FOREACH(c, &st->es_caids, link) { - if (!c->use) continue; + TAILQ_FOREACH (st, &t->s_components.set_all, es_link) { + if (st->es_type != SCT_CA) + continue; + LIST_FOREACH (c, &st->es_caids, link) { + if (!c->use) + continue; if (dvbcam_service_check_caid(as, c->caid)) { mpegts_pid_add(&ecm_pids, st->es_pid, 0); - tvhtrace(LS_DVBCAM, "%s/%p: add ECM PID %d (%04X) for CAID %04X", - ac->ca->lca_name, t, st->es_pid, st->es_pid, c->caid); + tvhtrace(LS_DVBCAM, + "%s/%p: add ECM PID %d (%04X) for CAID %04X", + ac->ca->lca_name, + t, + st->es_pid, + st->es_pid, + c->caid); } } } @@ -620,17 +617,21 @@ update_pid: #if ENABLE_DDCI if (as && as->lddci) { - mm = ((mpegts_service_t *)t)->s_dvb_mux; + mm = ((mpegts_service_t*)t)->s_dvb_mux; mi = mm->mm_active ? mm->mm_active->mmi_input : NULL; if (mi) { tvh_mutex_lock(&mi->mi_output_lock); tvh_mutex_lock(&t->s_stream_mutex); - mpegts_input_open_pid(mi, mm, DVB_CAT_PID, MPS_SERVICE | MPS_NOPOSTDEMUX, - MPS_WEIGHT_CAT, t, 0); - ((mpegts_service_t *)t)->s_cat_opened = 1; + mpegts_input_open_pid(mi, + mm, + DVB_CAT_PID, + MPS_SERVICE | MPS_NOPOSTDEMUX, + MPS_WEIGHT_CAT, + t, + 0); + ((mpegts_service_t*)t)->s_cat_opened = 1; for (i = 0; i < ecm_to_open.count; i++) - mpegts_input_open_pid(mi, mm, ecm_to_open.pids[i].pid, MPS_SERVICE, - MPS_WEIGHT_CA, t, 0); + mpegts_input_open_pid(mi, mm, ecm_to_open.pids[i].pid, MPS_SERVICE, MPS_WEIGHT_CA, t, 0); for (i = 0; i < ecm_to_close.count; i++) mpegts_input_close_pid(mi, mm, ecm_to_close.pids[i].pid, MPS_SERVICE, t); tvh_mutex_unlock(&t->s_stream_mutex); @@ -652,37 +653,31 @@ end: /* * */ -static void -dvbcam_free(caclient_t *cac) -{ -} +static void dvbcam_free(caclient_t* cac) {} /* * */ typedef struct __cat_update { - mpegts_service_t *service; - mpegts_apids_t to_open; - mpegts_apids_t to_close; + mpegts_service_t* service; + mpegts_apids_t to_open; + mpegts_apids_t to_close; } __cat_update_t; typedef struct __cat_entry { - mpegts_apids_t *pids; - mpegts_service_t *service; + mpegts_apids_t* pids; + mpegts_service_t* service; } __cat_entry_t; /* * */ #if ENABLE_DDCI -static void dvbcam_cat_entry - ( void *_aux, uint16_t caid, uint32_t prov, uint16_t pid ) -{ - __cat_entry_t *aux = _aux; +static void dvbcam_cat_entry(void* _aux, uint16_t caid, uint32_t prov, uint16_t pid) { + __cat_entry_t* aux = _aux; if (!mpegts_pid_rexists(aux->pids, pid)) { mpegts_pid_add(aux->pids, pid, 0); - tvhtrace(LS_DVBCAM, "%p: add EMM PID %d (%04X) for CAID %04X", - aux->service, pid, pid, caid); + tvhtrace(LS_DVBCAM, "%p: add EMM PID %d (%04X) for CAID %04X", aux->service, pid, pid, caid); } } #endif @@ -690,16 +685,14 @@ static void dvbcam_cat_entry /* * */ -static void -dvbcam_cat_update(caclient_t *cac, mpegts_mux_t *mux, const uint8_t *data, int len) -{ +static void dvbcam_cat_update(caclient_t* cac, mpegts_mux_t* mux, const uint8_t* data, int len) { #if ENABLE_DDCI - __cat_update_t services[32], *sp; - int i, services_count; - dvbcam_active_service_t *as; - mpegts_apids_t pids; - mpegts_input_t *mi; - __cat_entry_t cat_aux; + __cat_update_t services[32], *sp; + int i, services_count; + dvbcam_active_service_t* as; + mpegts_apids_t pids; + mpegts_input_t* mi; + __cat_entry_t cat_aux; if (len <= 0) return; @@ -707,24 +700,26 @@ dvbcam_cat_update(caclient_t *cac, mpegts_mux_t *mux, const uint8_t *data, int l services_count = 0; tvh_mutex_lock(&dvbcam_mutex); /* look for CAID in all services */ - TAILQ_FOREACH(as, &dvbcam_active_services, global_link) { - if (!as->lddci) continue; - if (as->caid_list[0] == 0) continue; - if (((mpegts_service_t *)as->td_service)->s_dvb_mux != mux) continue; - if (len == as->cat_data_len && - memcmp(data, as->cat_data, len) == 0) + TAILQ_FOREACH (as, &dvbcam_active_services, global_link) { + if (!as->lddci) + continue; + if (as->caid_list[0] == 0) + continue; + if (((mpegts_service_t*)as->td_service)->s_dvb_mux != mux) + continue; + if (len == as->cat_data_len && memcmp(data, as->cat_data, len) == 0) continue; free(as->cat_data); as->cat_data = malloc(len); memcpy(as->cat_data, data, len); as->cat_data_len = len; if (services_count < ARRAY_SIZE(services)) { - sp = &services[services_count++]; - sp->service = (mpegts_service_t *)as->td_service; + sp = &services[services_count++]; + sp->service = (mpegts_service_t*)as->td_service; mpegts_pid_init(&sp->to_open); mpegts_pid_init(&sp->to_close); mpegts_pid_init(&pids); - cat_aux.pids = &pids; + cat_aux.pids = &pids; cat_aux.service = sp->service; dvb_cat_decode(data, len, dvbcam_cat_entry, &cat_aux); mpegts_pid_compare(&pids, &as->cat_pids, &sp->to_open, &sp->to_close); @@ -743,11 +738,15 @@ dvbcam_cat_update(caclient_t *cac, mpegts_mux_t *mux, const uint8_t *data, int l sp = &services[i]; tvh_mutex_lock(&sp->service->s_stream_mutex); for (i = 0; i < sp->to_open.count; i++) - mpegts_input_open_pid(mi, mux, sp->to_open.pids[i].pid, MPS_SERVICE, - MPS_WEIGHT_CAT, sp->service, 0); + mpegts_input_open_pid(mi, + mux, + sp->to_open.pids[i].pid, + MPS_SERVICE, + MPS_WEIGHT_CAT, + sp->service, + 0); for (i = 0; i < sp->to_close.count; i++) - mpegts_input_close_pid(mi, mux, sp->to_close.pids[i].pid, MPS_SERVICE, - sp->service); + mpegts_input_close_pid(mi, mux, sp->to_close.pids[i].pid, MPS_SERVICE, sp->service); tvh_mutex_unlock(&sp->service->s_stream_mutex); mpegts_pid_done(&sp->to_open); mpegts_pid_done(&sp->to_close); @@ -762,36 +761,30 @@ dvbcam_cat_update(caclient_t *cac, mpegts_mux_t *mux, const uint8_t *data, int l /** * */ -static void -dvbcam_conf_changed(caclient_t *cac) -{ -} +static void dvbcam_conf_changed(caclient_t* cac) {} /* * */ -static htsmsg_t * -caclient_dvbcam_class_caid_selection_list ( void *o, const char *lang ) -{ +static htsmsg_t* caclient_dvbcam_class_caid_selection_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("All CAIDs"), DVBCAM_SEL_ALL }, - { N_("First hit"), DVBCAM_SEL_FIRST }, - { N_("Last hit"), DVBCAM_SEL_LAST }, + {N_("All CAIDs"), DVBCAM_SEL_ALL}, + {N_("First hit"), DVBCAM_SEL_FIRST}, + {N_("Last hit"), DVBCAM_SEL_LAST}, }; return strtab2htsmsg(tab, 1, lang); } -static int -caclient_dvbcam_class_caid_list_set( void *obj, const void *p ) -{ - dvbcam_t *dc = obj; - htsmsg_t *list = htsmsg_csv_2_list((const char *)p, ','); - const char *s; - htsmsg_field_t *f; - uint16_t caid_list[ARRAY_SIZE(dc->caid_list)]; - int caid, idx, index = 0, change = 0; +static int caclient_dvbcam_class_caid_list_set(void* obj, const void* p) { + dvbcam_t* dc = obj; + htsmsg_t* list = htsmsg_csv_2_list((const char*)p, ','); + const char* s; + htsmsg_field_t* f; + uint16_t caid_list[ARRAY_SIZE(dc->caid_list)]; + int caid, idx, index = 0, change = 0; - for (idx = 0; dc->caid_list[idx] && idx < ARRAY_SIZE(dc->caid_list); idx++); + for (idx = 0; dc->caid_list[idx] && idx < ARRAY_SIZE(dc->caid_list); idx++) + ; if (list == NULL) return 0; @@ -818,19 +811,16 @@ caclient_dvbcam_class_caid_list_set( void *obj, const void *p ) return change || index != idx; } -static const void * -caclient_dvbcam_class_caid_list_get( void *obj ) -{ - dvbcam_t *dc = obj; - size_t l = 0; - int index; +static const void* caclient_dvbcam_class_caid_list_get(void* obj) { + dvbcam_t* dc = obj; + size_t l = 0; + int index; prop_sbuf[0] = '\0'; for (index = 0; index < ARRAY_SIZE(dc->caid_list); index++) { if (dc->caid_list[index] == 0) break; - tvh_strlcatf(prop_sbuf, PROP_SBUF_LEN, l, "%s%04X", - index > 0 ? "," : "", dc->caid_list[index]); + tvh_strlcatf(prop_sbuf, PROP_SBUF_LEN, l, "%s%04X", index > 0 ? "," : "", dc->caid_list[index]); } return &prop_sbuf_ptr; } @@ -838,83 +828,74 @@ caclient_dvbcam_class_caid_list_get( void *obj ) /* * */ -const idclass_t caclient_dvbcam_class = -{ - .ic_super = &caclient_class, - .ic_class = "caclient_dvbcam", - .ic_caption = N_("Linux DVB CAM Client"), - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - { - .name = N_("Common Interface Settings"), - .number = 2, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "limit", - .name = N_("Service limit"), - .desc = N_("Limit of concurrent descrambled services (per one CAM)."), - .off = offsetof(dvbcam_t, limit), - .group = 2, - }, - { - .type = PT_INT, - .id = "caid_select", - .name = N_("CAID selection"), - .desc = N_("Selection method for CAID."), - .list = caclient_dvbcam_class_caid_selection_list, - .off = offsetof(dvbcam_t, caid_select), - .opts = PO_DOC_NLIST, - .group = 2, - }, - { - .type = PT_STR, - .id = "caid_list", - .name = N_("CAID filter list"), - .desc = N_("A list of allowed CAIDs (hexa format, comma separated). " - "E.g. '0D00,0F00,0100'."), - .set = caclient_dvbcam_class_caid_list_set, - .get = caclient_dvbcam_class_caid_list_get, - .group = 2, - }, - { - .type = PT_BOOL, - .id = "multi", - .name = N_("CAM can decode multiple channels"), - .desc = N_("To enable MCD and MTD for this CAM."), - .off = offsetof(dvbcam_t, multi), - .group = 2, - }, - {} - } -}; +const idclass_t caclient_dvbcam_class = {.ic_super = &caclient_class, + .ic_class = "caclient_dvbcam", + .ic_caption = N_("Linux DVB CAM Client"), + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + { + .name = N_("Common Interface Settings"), + .number = 2, + }, + {}}, + .ic_properties = (const property_t[]){ + { + .type = PT_INT, + .id = "limit", + .name = N_("Service limit"), + .desc = N_("Limit of concurrent descrambled services (per one CAM)."), + .off = offsetof(dvbcam_t, limit), + .group = 2, + }, + { + .type = PT_INT, + .id = "caid_select", + .name = N_("CAID selection"), + .desc = N_("Selection method for CAID."), + .list = caclient_dvbcam_class_caid_selection_list, + .off = offsetof(dvbcam_t, caid_select), + .opts = PO_DOC_NLIST, + .group = 2, + }, + { + .type = PT_STR, + .id = "caid_list", + .name = N_("CAID filter list"), + .desc = N_("A list of allowed CAIDs (hexa format, comma separated). " + "E.g. '0D00,0F00,0100'."), + .set = caclient_dvbcam_class_caid_list_set, + .get = caclient_dvbcam_class_caid_list_get, + .group = 2, + }, + { + .type = PT_BOOL, + .id = "multi", + .name = N_("CAM can decode multiple channels"), + .desc = N_("To enable MCD and MTD for this CAM."), + .off = offsetof(dvbcam_t, multi), + .group = 2, + }, + {}}}; /* * */ -caclient_t *dvbcam_create(void) -{ - dvbcam_t *dc = calloc(1, sizeof(*dc)); +caclient_t* dvbcam_create(void) { + dvbcam_t* dc = calloc(1, sizeof(*dc)); dc->cac_free = dvbcam_free; dc->cac_start = dvbcam_service_start; dc->cac_conf_changed = dvbcam_conf_changed; dc->cac_cat_update = dvbcam_cat_update; - return (caclient_t *)dc; + return (caclient_t*)dc; } /* * */ -void -dvbcam_init(void) -{ +void dvbcam_init(void) { tvh_mutex_init(&dvbcam_mutex, NULL); TAILQ_INIT(&dvbcam_active_services); TAILQ_INIT(&dvbcam_active_cams); diff --git a/src/descrambler/dvbcam.h b/src/descrambler/dvbcam.h index 09107338e..d3d66bd8f 100644 --- a/src/descrambler/dvbcam.h +++ b/src/descrambler/dvbcam.h @@ -28,16 +28,18 @@ struct elementary_stream; struct linuxdvb_ca; void dvbcam_init(void); -void dvbcam_register_cam(struct linuxdvb_ca *lca, uint16_t * caids, int num_caids); -void dvbcam_unregister_cam(struct linuxdvb_ca *lca); -void dvbcam_pmt_data(struct mpegts_service *s, const uint8_t *ptr, int len); +void dvbcam_register_cam(struct linuxdvb_ca* lca, uint16_t* caids, int num_caids); +void dvbcam_unregister_cam(struct linuxdvb_ca* lca); +void dvbcam_pmt_data(struct mpegts_service* s, const uint8_t* ptr, int len); #endif #if ENABLE_LINUXDVB_CA && ENABLE_DDCI -int dvbcam_is_ddci(struct service *t); +int dvbcam_is_ddci(struct service* t); #else -static inline int dvbcam_is_ddci(struct service *t) { return 0; } +static inline int dvbcam_is_ddci(struct service* t) { + return 0; +} #endif #endif /* __DVBCAM_H__ */ diff --git a/src/descrambler/emm_reass.c b/src/descrambler/emm_reass.c index 34a716b98..6df7f856f 100644 --- a/src/descrambler/emm_reass.c +++ b/src/descrambler/emm_reass.c @@ -20,8 +20,8 @@ #include "emm_reass.h" #include "descrambler/caid.h" -#define EMM_CACHE_SIZE (1<<5) -#define EMM_CACHE_MASK (EMM_CACHE_SIZE-1) +#define EMM_CACHE_SIZE (1 << 5) +#define EMM_CACHE_MASK (EMM_CACHE_SIZE - 1) #define PROVIDERS_FOREACH(ra, i, ep) \ for (i = 0, ep = (ra)->providers; i < (ra)->providers_count; i++, ep++) @@ -29,9 +29,7 @@ /** * */ -static void -emm_cache_insert(emm_reass_t *ra, uint32_t crc) -{ +static void emm_cache_insert(emm_reass_t* ra, uint32_t crc) { /* evict the oldest entry */ ra->emm_cache[ra->emm_cache_write++] = crc; ra->emm_cache_write &= EMM_CACHE_MASK; @@ -39,9 +37,7 @@ emm_cache_insert(emm_reass_t *ra, uint32_t crc) ra->emm_cache_count++; } -static int -emm_cache_lookup(emm_reass_t *ra, uint32_t crc) -{ +static int emm_cache_lookup(emm_reass_t* ra, uint32_t crc) { int i, off; off = ra->emm_cache_write - ra->emm_cache_count; @@ -58,20 +54,17 @@ emm_cache_lookup(emm_reass_t *ra, uint32_t crc) * conax emm handler */ static void -emm_conax - (emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ - emm_provider_t *ep; - int i, match = 0; +emm_conax(emm_reass_t* ra, const uint8_t* data, int len, void* mux, emm_send_t send, void* aux) { + emm_provider_t* ep; + int i, match = 0; if (data[0] == 0x82) { if (len >= 10) { PROVIDERS_FOREACH(ra, i, ep) - if (memcmp(&data[3], &ep->sa[1], 7) == 0) { - match = 1; - break; - } + if (memcmp(&data[3], &ep->sa[1], 7) == 0) { + match = 1; + break; + } } } if (match) @@ -83,19 +76,16 @@ emm_conax * inspired by opensasc-ng, https://opensvn.csie.org/traccgi/opensascng/ */ static void -emm_irdeto - (emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ - int i, emm_mode, emm_len, match = 0; - emm_provider_t *ep; - char prov[4]; +emm_irdeto(emm_reass_t* ra, const uint8_t* data, int len, void* mux, emm_send_t send, void* aux) { + int i, emm_mode, emm_len, match = 0; + emm_provider_t* ep; + char prov[4]; if (len < 4) return; emm_mode = data[3] >> 3; - emm_len = data[3] & 0x07; + emm_len = data[3] & 0x07; if (4 + emm_len > len || emm_len > 3) return; @@ -103,8 +93,8 @@ emm_irdeto if (emm_mode & 0x10) { // try to match card match = emm_mode == ra->ua[4] && - (!emm_len || // zero length - !memcmp(&data[4], &ra->ua[5], emm_len)); // exact match + (!emm_len || // zero length + !memcmp(&data[4], &ra->ua[5], emm_len)); // exact match } else { if (emm_len && !memcmp(&data[4], &ra->ua[5], emm_len)) { match = 1; @@ -115,11 +105,12 @@ emm_irdeto prov[1] = ep->id >> 16; prov[2] = ep->id >> 8; prov[3] = ep->id; - match = emm_mode == prov[0] && - (!emm_len || // zero length - !memcmp(&data[4], prov + 1, emm_len)); + match = emm_mode == prov[0] && + (!emm_len || // zero length + !memcmp(&data[4], prov + 1, emm_len)); // exact match - if (match) break; + if (match) + break; } } } @@ -128,34 +119,30 @@ emm_irdeto send(aux, data, len, mux); } - /** * seca emm handler * inspired by opensasc-ng, https://opensvn.csie.org/traccgi/opensascng/ */ static void -emm_seca - (emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ - int i, match = 0; - emm_provider_t *ep; +emm_seca(emm_reass_t* ra, const uint8_t* data, int len, void* mux, emm_send_t send, void* aux) { + int i, match = 0; + emm_provider_t* ep; if (len < 1) return; - if (data[0] == 0x82) { // unique emm + if (data[0] == 0x82) { // unique emm if (len >= 9) match = memcmp(&data[3], &ra->ua[2], 6) == 0; - } else if (data[0] == 0x84) { // shared emm + } else if (data[0] == 0x84) { // shared emm if (len >= 8) { PROVIDERS_FOREACH(ra, i, ep) - if (memcmp(&data[5], &ep->sa[5], 3) == 0) { - match = 1; - break; - } + if (memcmp(&data[5], &ep->sa[5], 3) == 0) { + match = 1; + break; + } } - } else if (data[0] == 0x83) { // global emm -> seca3 + } else if (data[0] == 0x83) { // global emm -> seca3 match = 1; } @@ -167,42 +154,44 @@ emm_seca * viaccess emm handler * inspired by opensasc-ng, https://opensvn.csie.org/traccgi/opensascng/ */ -static -const uint8_t * nano_start(const uint8_t * data, int len) -{ +static const uint8_t* nano_start(const uint8_t* data, int len) { int l; - switch(data[0]) { - case 0x88: l = 8; break; - case 0x8e: l = 7; break; - case 0x8c: - case 0x8d: l = 3; break; - case 0x80: - case 0x81: l = 4; break; - default: return NULL; + switch (data[0]) { + case 0x88: + l = 8; + break; + case 0x8e: + l = 7; + break; + case 0x8c: + case 0x8d: + l = 3; + break; + case 0x80: + case 0x81: + l = 4; + break; + default: + return NULL; } return l < len ? data + l : NULL; } -static -const uint8_t * nano_checknano90fromnano(const uint8_t * data, int len) -{ - if(data && len > 4 && data[0]==0x90 && data[1]==0x03) return data; +static const uint8_t* nano_checknano90fromnano(const uint8_t* data, int len) { + if (data && len > 4 && data[0] == 0x90 && data[1] == 0x03) + return data; return NULL; } -static -const uint8_t * nano_checknano90(const uint8_t * data, int len) -{ - const uint8_t *start = nano_start(data, len); +static const uint8_t* nano_checknano90(const uint8_t* data, int len) { + const uint8_t* start = nano_start(data, len); if (start) return nano_checknano90fromnano(start, len - (start - data)); return NULL; } -static -int sort_nanos(uint8_t *dest, const uint8_t *src, int len) -{ +static int sort_nanos(uint8_t* dest, const uint8_t* src, int len) { int w = 0, c = -1; while (1) { @@ -215,8 +204,7 @@ int sort_nanos(uint8_t *dest, const uint8_t *src, int len) return -1; memcpy(dest + w, src + j, l); w += l; - } - else if (src[j] > c && src[j] < n) { + } else if (src[j] > c && src[j] < n) { n = src[j]; } j += l; @@ -229,24 +217,21 @@ int sort_nanos(uint8_t *dest, const uint8_t *src, int len) return 0; } -static int via_provider_id(const uint8_t * data, int len) -{ - const uint8_t * tmp; +static int via_provider_id(const uint8_t* data, int len) { + const uint8_t* tmp; tmp = nano_checknano90(data, len); - if (!tmp) return 0; - return (tmp[2] << 16) | (tmp[3] << 8) | (tmp[4]&0xf0); + if (!tmp) + return 0; + return (tmp[2] << 16) | (tmp[3] << 8) | (tmp[4] & 0xf0); } #define EP_VIACCESS(ep, idx) (ep)->u.viacess[idx] static void -emm_viaccess - (emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ - int i, idx = 0, olen = len, match = 0; - emm_provider_t *ep; - uint32_t id; +emm_viaccess(emm_reass_t* ra, const uint8_t* data, int len, void* mux, emm_send_t send, void* aux) { + int i, idx = 0, olen = len, match = 0; + emm_provider_t* ep; + uint32_t id; if (len < 3) return; @@ -261,16 +246,18 @@ emm_viaccess /* Match provider id */ id = via_provider_id(data, len); - if (!id) return; + if (!id) + return; PROVIDERS_FOREACH(ra, i, ep) - if (ep->id == id) { - match = 1; - break; - } - if (!match) return; + if (ep->id == id) { + match = 1; + break; + } + if (!match) + return; - idx = data[0] - 0x8c; + idx = data[0] - 0x8c; EP_VIACCESS(ep, idx).shared_len = 0; free(EP_VIACCESS(ep, idx).shared_emm); if ((EP_VIACCESS(ep, idx).shared_emm = (uint8_t*)malloc(len)) != NULL) { @@ -281,50 +268,55 @@ emm_viaccess } else if (data[0] == 0x8e) { /* Match SA and provider in shared */ PROVIDERS_FOREACH(ra, i, ep) { - if (memcmp(&data[3], &ep->sa[4], 3)) continue; - if ((data[6]&2)) continue; + if (memcmp(&data[3], &ep->sa[4], 3)) + continue; + if ((data[6] & 2)) + continue; for (idx = 0; idx < 2; idx++) - if (EP_VIACCESS(ep, idx).shared_emm && - EP_VIACCESS(ep, idx).shared_mux == mux) { - id = via_provider_id(EP_VIACCESS(ep, idx).shared_emm, - EP_VIACCESS(ep, idx).shared_len); + if (EP_VIACCESS(ep, idx).shared_emm && EP_VIACCESS(ep, idx).shared_mux == mux) { + id = via_provider_id(EP_VIACCESS(ep, idx).shared_emm, EP_VIACCESS(ep, idx).shared_len); if (id == ep->id) { match = 1; break; } } - if (match) break; + if (match) + break; } if (match) { - uint8_t *tmp, *ass2; - const uint8_t *ass; - uint32_t crc; - int l; + uint8_t * tmp, *ass2; + const uint8_t* ass; + uint32_t crc; + int l; tmp = alloca(len + EP_VIACCESS(ep, idx).shared_len); ass = nano_start(data, len); - if (ass == NULL) return; + if (ass == NULL) + return; len -= (ass - data); - if((data[6] & 2) == 0) { + if ((data[6] & 2) == 0) { int addrlen = len - 8; - len=0; - tmp[len++] = 0x9e; - tmp[len++] = addrlen; - memcpy(&tmp[len], &ass[0], addrlen); len += addrlen; + len = 0; + tmp[len++] = 0x9e; + tmp[len++] = addrlen; + memcpy(&tmp[len], &ass[0], addrlen); + len += addrlen; tmp[len++] = 0xf0; tmp[len++] = 0x08; - memcpy(&tmp[len],&ass[addrlen],8); len += 8; + memcpy(&tmp[len], &ass[addrlen], 8); + len += 8; } else { memcpy(tmp, ass, len); } - ass = nano_start(EP_VIACCESS(ep, idx).shared_emm, - EP_VIACCESS(ep, idx).shared_len); - if (ass == NULL) return; + ass = nano_start(EP_VIACCESS(ep, idx).shared_emm, EP_VIACCESS(ep, idx).shared_len); + if (ass == NULL) + return; l = EP_VIACCESS(ep, idx).shared_len - (ass - EP_VIACCESS(ep, idx).shared_emm); - memcpy(&tmp[len], ass, l); len += l; + memcpy(&tmp[len], ass, l); + len += l; - ass2 = (uint8_t*) alloca(len+7); - if(ass2 == NULL) + ass2 = (uint8_t*)alloca(len + 7); + if (ass2 == NULL) return; memcpy(ass2, data, 7); @@ -337,19 +329,28 @@ emm_viaccess /* Set SCT len */ len += 4; - ass2[1] = (len>>8) | 0x70; + ass2[1] = (len >> 8) | 0x70; ass2[2] = len & 0xff; len += 3; crc = tvh_crc32(ass2, len, 0xffffffff); if (!emm_cache_lookup(ra, crc)) { tvhdebug(ra->subsys, - "Send EMM " - "%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x" - "...%02x.%02x.%02x.%02x", - ass2[0], ass2[1], ass2[2], ass2[3], - ass2[4], ass2[5], ass2[6], ass2[7], - ass2[len-4], ass2[len-3], ass2[len-2], ass2[len-1]); + "Send EMM " + "%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x" + "...%02x.%02x.%02x.%02x", + ass2[0], + ass2[1], + ass2[2], + ass2[3], + ass2[4], + ass2[5], + ass2[6], + ass2[7], + ass2[len - 4], + ass2[len - 3], + ass2[len - 2], + ass2[len - 1]); send(aux, ass2, len, mux); emm_cache_insert(ra, crc); } @@ -361,12 +362,9 @@ emm_viaccess * dre emm handler */ static void -emm_dre - (emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ - int i, match = 0; - emm_provider_t *ep; +emm_dre(emm_reass_t* ra, const uint8_t* data, int len, void* mux, emm_send_t send, void* aux) { + int i, match = 0; + emm_provider_t* ep; if (len < 1) return; @@ -377,11 +375,11 @@ emm_dre } else if (data[0] == 0x86) { if (len >= 44) { PROVIDERS_FOREACH(ra, i, ep) - if (memcmp(&data[40], &ep->sa[4], 4) == 0) { - /* if (memcmp(&data[3], &ep->sa[4], 1) == 0) { */ - match = 1; - break; - } + if (memcmp(&data[40], &ep->sa[4], 4) == 0) { + /* if (memcmp(&data[3], &ep->sa[4], 1) == 0) { */ + match = 1; + break; + } } } @@ -390,14 +388,11 @@ emm_dre } static void -emm_nagra - (emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ - int match = 0; +emm_nagra(emm_reass_t* ra, const uint8_t* data, int len, void* mux, emm_send_t send, void* aux) { + int match = 0; uint8_t hexserial[4]; - if (data[0] == 0x83) { // unique|shared + if (data[0] == 0x83) { // unique|shared if (len >= 8) { hexserial[0] = data[5]; hexserial[1] = data[4]; @@ -415,11 +410,8 @@ emm_nagra } static void -emm_nds - (emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ - int i, match = 0, serial_count; +emm_nds(emm_reass_t* ra, const uint8_t* data, int len, void* mux, emm_send_t send, void* aux) { + int i, match = 0, serial_count; uint8_t emmtype; if (len < 4) @@ -437,7 +429,7 @@ emm_nds } } } - } else if (emmtype == 0) { // global + } else if (emmtype == 0) { // global match = 1; } @@ -448,14 +440,15 @@ emm_nds /** * streamguard emm handler */ -static void -emm_streamguard - (emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ - //todo - int i, match = 0; - emm_provider_t *ep; +static void emm_streamguard(emm_reass_t* ra, + const uint8_t* data, + int len, + void* mux, + emm_send_t send, + void* aux) { + // todo + int i, match = 0; + emm_provider_t* ep; if (len < 1) return; @@ -467,11 +460,11 @@ emm_streamguard } else if (data[0] == 0x86) { if (len >= 44) { PROVIDERS_FOREACH(ra, i, ep) - if (memcmp(&data[40], &ep->sa[4], 4) == 0) { - /* if (memcmp(&data[3], &cwc->cwc_providers[i].sa[4], 1) == 0) { */ - match = 1; - break; - } + if (memcmp(&data[40], &ep->sa[4], 4) == 0) { + /* if (memcmp(&data[3], &cwc->cwc_providers[i].sa[4], 1) == 0) { */ + match = 1; + break; + } } } @@ -481,66 +474,68 @@ emm_streamguard #define RA_CRYPTOWORKS(ra) (ra)->u.cryptoworks -static void -emm_cryptoworks - (emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ +static void emm_cryptoworks(emm_reass_t* ra, + const uint8_t* data, + int len, + void* mux, + emm_send_t send, + void* aux) { int match = 0; if (len < 1) return; switch (data[0]) { - case 0x82: /* unique */ - match = len >= 10 && memcmp(data + 5, ra->ua + 3, 5) == 0; - break; - case 0x84: /* emm-sh */ - if (len >= 12 && memcmp(data + 5, ra->ua + 3, 4) == 0) { - if (RA_CRYPTOWORKS(ra).shared_emm) { + case 0x82: /* unique */ + match = len >= 10 && memcmp(data + 5, ra->ua + 3, 5) == 0; + break; + case 0x84: /* emm-sh */ + if (len >= 12 && memcmp(data + 5, ra->ua + 3, 4) == 0) { + if (RA_CRYPTOWORKS(ra).shared_emm) { + free(RA_CRYPTOWORKS(ra).shared_emm); + RA_CRYPTOWORKS(ra).shared_len = 0; + } + if ((RA_CRYPTOWORKS(ra).shared_emm = malloc(len)) != NULL) { + RA_CRYPTOWORKS(ra).shared_len = len; + memcpy(RA_CRYPTOWORKS(ra).shared_emm, data, len); + RA_CRYPTOWORKS(ra).shared_mux = mux; + } + } + break; + case 0x86: /* emm-sb */ + if (len < 5) + return; + if (RA_CRYPTOWORKS(ra).shared_emm && RA_CRYPTOWORKS(ra).shared_mux == mux) { + /* python: EMM_SH[0:12] + EMM_SB[5:-1] + EMM_SH[12:-1] */ + uint32_t elen = len - 5 + RA_CRYPTOWORKS(ra).shared_len - 12; + uint8_t* tmp = malloc(elen); + uint8_t* composed = tmp ? malloc(elen + 12) : NULL; + if (composed) { + memcpy(tmp, data + 5, len - 5); + memcpy(tmp + len - 5, + RA_CRYPTOWORKS(ra).shared_emm + 12, + RA_CRYPTOWORKS(ra).shared_len - 12); + memcpy(composed, RA_CRYPTOWORKS(ra).shared_emm, 12); + sort_nanos(composed + 12, tmp, elen); + composed[1] = ((elen + 9) >> 8) | 0x70; + composed[2] = (elen + 9) & 0xff; + send(aux, composed, elen + 12, mux); + free(composed); + free(tmp); + } else if (tmp) + free(tmp); + free(RA_CRYPTOWORKS(ra).shared_emm); + RA_CRYPTOWORKS(ra).shared_emm = NULL; RA_CRYPTOWORKS(ra).shared_len = 0; } - if ((RA_CRYPTOWORKS(ra).shared_emm = malloc(len)) != NULL) { - RA_CRYPTOWORKS(ra).shared_len = len; - memcpy(RA_CRYPTOWORKS(ra).shared_emm, data, len); - RA_CRYPTOWORKS(ra).shared_mux = mux; - } - } - break; - case 0x86: /* emm-sb */ - if (len < 5) - return; - if (RA_CRYPTOWORKS(ra).shared_emm && RA_CRYPTOWORKS(ra).shared_mux == mux) { - /* python: EMM_SH[0:12] + EMM_SB[5:-1] + EMM_SH[12:-1] */ - uint32_t elen = len - 5 + RA_CRYPTOWORKS(ra).shared_len - 12; - uint8_t *tmp = malloc(elen); - uint8_t *composed = tmp ? malloc(elen + 12) : NULL; - if (composed) { - memcpy(tmp, data + 5, len - 5); - memcpy(tmp + len - 5, RA_CRYPTOWORKS(ra).shared_emm + 12, - RA_CRYPTOWORKS(ra).shared_len - 12); - memcpy(composed, RA_CRYPTOWORKS(ra).shared_emm, 12); - sort_nanos(composed + 12, tmp, elen); - composed[1] = ((elen + 9) >> 8) | 0x70; - composed[2] = (elen + 9) & 0xff; - send(aux, composed, elen + 12, mux); - free(composed); - free(tmp); - } else if (tmp) - free(tmp); - - free(RA_CRYPTOWORKS(ra).shared_emm); - RA_CRYPTOWORKS(ra).shared_emm = NULL; - RA_CRYPTOWORKS(ra).shared_len = 0; - } - break; - case 0x88: /* global */ - case 0x89: /* global */ - match = 1; - break; - default: - break; + break; + case 0x88: /* global */ + case 0x89: /* global */ + match = 1; + break; + default: + break; } if (match) @@ -548,25 +543,22 @@ emm_cryptoworks } static void -emm_bulcrypt - (emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ +emm_bulcrypt(emm_reass_t* ra, const uint8_t* data, int len, void* mux, emm_send_t send, void* aux) { int match = 0; if (len < 1) return; switch (data[0]) { - case 0x82: /* unique - bulcrypt (1 card) */ - case 0x8a: /* unique - polaris (1 card) */ - case 0x85: /* unique - bulcrypt (4 cards) */ - case 0x8b: /* unique - polaris (4 cards) */ - match = len >= 10 && memcmp(data + 3, ra->ua + 2, 3) == 0; - break; - case 0x84: /* shared - (1024 cards) */ - match = len >= 10 && memcmp(data + 3, ra->ua + 2, 2) == 0; - break; + case 0x82: /* unique - bulcrypt (1 card) */ + case 0x8a: /* unique - polaris (1 card) */ + case 0x85: /* unique - bulcrypt (4 cards) */ + case 0x8b: /* unique - polaris (4 cards) */ + match = len >= 10 && memcmp(data + 3, ra->ua + 2, 3) == 0; + break; + case 0x84: /* shared - (1024 cards) */ + match = len >= 10 && memcmp(data + 3, ra->ua + 2, 2) == 0; + break; } if (match) @@ -574,67 +566,85 @@ emm_bulcrypt } static void -emm_griffin - (emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ - emm_provider_t *ep; - int i; +emm_griffin(emm_reass_t* ra, const uint8_t* data, int len, void* mux, emm_send_t send, void* aux) { + emm_provider_t* ep; + int i; if (len < 1) return; switch (data[0]) { - case 0x82: - case 0x83: - PROVIDERS_FOREACH(ra, i, ep) + case 0x82: + case 0x83: + PROVIDERS_FOREACH(ra, i, ep) if (memcmp(&data[3], &ep->sa[0], 4) == 0) { send(aux, data, len, mux); break; } - break; + break; } } -void -emm_filter(emm_reass_t *ra, const uint8_t *data, int len, void *mux, - emm_send_t send, void *aux) -{ +void emm_filter(emm_reass_t* ra, + const uint8_t* data, + int len, + void* mux, + emm_send_t send, + void* aux) { tvhtrace(ra->subsys, "emm filter : %s - len %d mux %p", caid2name(ra->caid), len, mux); tvhlog_hexdump(ra->subsys, data, len); if (ra->do_emm) ra->do_emm(ra, data, len, mux, send, aux); } -void -emm_reass_init(emm_reass_t *ra, int subsys, uint16_t caid) -{ +void emm_reass_init(emm_reass_t* ra, int subsys, uint16_t caid) { memset(ra, 0, sizeof(*ra)); ra->subsys = subsys; - ra->caid = caid; - ra->type = detect_card_type(caid); + ra->caid = caid; + ra->type = detect_card_type(caid); switch (ra->type) { - case CARD_CONAX: ra->do_emm = emm_conax; break; - case CARD_BETACRYPT: /* really? */ - case CARD_IRDETO: ra->do_emm = emm_irdeto; break; - case CARD_SECA: ra->do_emm = emm_seca; break; - case CARD_VIACCESS: ra->do_emm = emm_viaccess; break; - case CARD_DRE: ra->do_emm = emm_dre; break; - case CARD_NAGRA: ra->do_emm = emm_nagra; break; - case CARD_NDS: ra->do_emm = emm_nds; break; - case CARD_CRYPTOWORKS: ra->do_emm = emm_cryptoworks; break; - case CARD_BULCRYPT: ra->do_emm = emm_bulcrypt; break; - case CARD_STREAMGUARD: ra->do_emm = emm_streamguard; break; - case CARD_GRIFFIN: ra->do_emm = emm_griffin; break; - default: break; + case CARD_CONAX: + ra->do_emm = emm_conax; + break; + case CARD_BETACRYPT: /* really? */ + case CARD_IRDETO: + ra->do_emm = emm_irdeto; + break; + case CARD_SECA: + ra->do_emm = emm_seca; + break; + case CARD_VIACCESS: + ra->do_emm = emm_viaccess; + break; + case CARD_DRE: + ra->do_emm = emm_dre; + break; + case CARD_NAGRA: + ra->do_emm = emm_nagra; + break; + case CARD_NDS: + ra->do_emm = emm_nds; + break; + case CARD_CRYPTOWORKS: + ra->do_emm = emm_cryptoworks; + break; + case CARD_BULCRYPT: + ra->do_emm = emm_bulcrypt; + break; + case CARD_STREAMGUARD: + ra->do_emm = emm_streamguard; + break; + case CARD_GRIFFIN: + ra->do_emm = emm_griffin; + break; + default: + break; } } -void -emm_reass_done(emm_reass_t *ra) -{ - emm_provider_t *ep; - int i; +void emm_reass_done(emm_reass_t* ra) { + emm_provider_t* ep; + int i; PROVIDERS_FOREACH(ra, i, ep) { if (ra->type == CARD_VIACCESS) { @@ -667,18 +677,20 @@ emm_reass_done(emm_reass_t *ra) int tvhlog_level = TVHLOG_OPT_ALL; -uint32_t tvh_crc32(const uint8_t *data, size_t datalen, uint32_t crc) -{ +uint32_t tvh_crc32(const uint8_t* data, size_t datalen, uint32_t crc) { /* just for debugging purposes, not real crc32 */ while (datalen-- > 0) crc += *data++; return crc; } -void tvhlogv (const char *file, int line, - int notify, int severity, - const char *subsys, const char *fmt, va_list *args ) -{ +void tvhlogv(const char* file, + int line, + int notify, + int severity, + const char* subsys, + const char* fmt, + va_list* args) { fprintf(stderr, "LOG[%s]: ", subsys); if (args) { vfprintf(stderr, fmt, *args); @@ -688,10 +700,13 @@ void tvhlogv (const char *file, int line, } } -void _tvhlog (const char *file, int line, - int notify, int severity, - const char *subsys, const char *fmt, ...) -{ +void _tvhlog(const char* file, + int line, + int notify, + int severity, + const char* subsys, + const char* fmt, + ...) { va_list args; va_start(args, fmt); tvhlogv(file, line, notify, severity, subsys, fmt, &args); @@ -699,13 +714,14 @@ void _tvhlog (const char *file, int line, } #define HEXDUMP_WIDTH 16 -void -_tvhlog_hexdump(const char *file, int line, - int notify, int severity, - const char *subsys, - const uint8_t *data, ssize_t len ) -{ - int i, c; +void _tvhlog_hexdump(const char* file, + int line, + int notify, + int severity, + const char* subsys, + const uint8_t* data, + ssize_t len) { + int i, c; char str[1024]; /* Assume that severify was validated before call */ @@ -731,7 +747,7 @@ _tvhlog_hexdump(const char *file, int line, } str[c] = '\0'; tvhlogv(file, line, notify, severity, subsys, str, NULL); - len -= HEXDUMP_WIDTH; + len -= HEXDUMP_WIDTH; data += HEXDUMP_WIDTH; } } @@ -742,30 +758,26 @@ _tvhlog_hexdump(const char *file, int line, * Hexa strings can be joined 01020a or delimited by any character 01:02:0A. */ -#define CAID 0x0500 -#define PROVID 0x040820 -#define UA "00:00:00:00:00:00:00" -#define SA "00:00:00:00:A1:A2:A3" - -static char *emms[] = { - "8C 70 0C 90 03 04 08 21 A9 05 46 8B 46 BA 04", - "8D 70 0C 90 03 04 08 21 A9 05 46 8D 46 BC 04", - "8E 70 2C A1 A2 A3 00 00 00 00 00 00 00 00 00 00" - "60 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF" - "FF 5F FF FF FE 7F FF 02 B1 FC 60 FA 8A 36 86", - "8E 70 2C A1 A2 A3 00 00 00 00 00 00 00 00 00 00" - "60 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF" - "FF 5F FF FF FE 7F FF 02 B1 FC 60 FA 8A 36 86", - NULL -}; +#define CAID 0x0500 +#define PROVID 0x040820 +#define UA "00:00:00:00:00:00:00" +#define SA "00:00:00:00:A1:A2:A3" + +static char* emms[] = {"8C 70 0C 90 03 04 08 21 A9 05 46 8B 46 BA 04", + "8D 70 0C 90 03 04 08 21 A9 05 46 8D 46 BC 04", + "8E 70 2C A1 A2 A3 00 00 00 00 00 00 00 00 00 00" + "60 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF" + "FF 5F FF FF FE 7F FF 02 B1 FC 60 FA 8A 36 86", + "8E 70 2C A1 A2 A3 00 00 00 00 00 00 00 00 00 00" + "60 00 00 00 00 00 00 00 00 00 00 00 00 01 FF FF" + "FF 5F FF FF FE 7F FF 02 B1 FC 60 FA 8A 36 86", + NULL}; /* * END OF USER DATA */ -static int -decode_hexa(uint8_t *dst, int len, const char *src) -{ +static int decode_hexa(uint8_t* dst, int len, const char* src) { int res = 0, i; while (1) { @@ -790,40 +802,51 @@ decode_hexa(uint8_t *dst, int len, const char *src) return res; } -static void -emm_result(void *aux, const uint8_t *radata, int ralen, void *mux) -{ +static void emm_result(void* aux, const uint8_t* radata, int ralen, void* mux) { tvhlog_hexdump("emm-*send*", radata, ralen); } -int main(int argc, char *argv[]) -{ - uint8_t emm[1024]; +int main(int argc, char* argv[]) { + uint8_t emm[1024]; emm_reass_t ra; - char **p; - uint8_t *sa; - int l; + char** p; + uint8_t* sa; + int l; emm_reass_init(&ra, CAID); decode_hexa(ra.ua, sizeof(ra.ua), UA); ra.providers_count = 1; - ra.providers = calloc(ra.providers_count, sizeof(emm_provider_t)); - ra.providers->id = PROVID; + ra.providers = calloc(ra.providers_count, sizeof(emm_provider_t)); + ra.providers->id = PROVID; decode_hexa(ra.providers->sa, sizeof(ra.providers->sa), SA); tvhinfo("config", "CAID = %04x", CAID); tvhinfo("config", "PROVID = %06x", PROVID); - tvhinfo("config", "UA = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - ra.ua[0], ra.ua[1], ra.ua[2], ra.ua[3], - ra.ua[4], ra.ua[5], ra.ua[6], ra.ua[7]); + tvhinfo("config", + "UA = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + ra.ua[0], + ra.ua[1], + ra.ua[2], + ra.ua[3], + ra.ua[4], + ra.ua[5], + ra.ua[6], + ra.ua[7]); sa = ra.providers->sa; - tvhinfo("config", "SA = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", - sa[0], sa[1], sa[2], sa[3], - sa[4], sa[5], sa[6], sa[7]); + tvhinfo("config", + "SA = %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x", + sa[0], + sa[1], + sa[2], + sa[3], + sa[4], + sa[5], + sa[6], + sa[7]); for (p = emms; *p; p++) { l = decode_hexa(emm, sizeof(emm), *p); - emm_filter(&ra, emm, l, (void *)1, emm_result, NULL); + emm_filter(&ra, emm, l, (void*)1, emm_result, NULL); } emm_reass_done(&ra); diff --git a/src/descrambler/emm_reass.h b/src/descrambler/emm_reass.h index 5a5e92a30..082ddc3a1 100644 --- a/src/descrambler/emm_reass.h +++ b/src/descrambler/emm_reass.h @@ -23,56 +23,63 @@ #include "descrambler/caid.h" typedef struct emm_provider emm_provider_t; -typedef struct emm_reass emm_reass_t; +typedef struct emm_reass emm_reass_t; struct emm_provider { uint32_t id; - uint8_t sa[8]; + uint8_t sa[8]; union { struct { - void *shared_mux; - uint8_t *shared_emm; - int shared_len; + void* shared_mux; + uint8_t* shared_emm; + int shared_len; } viacess[2]; } u; }; -#define EMM_CACHE_SIZE (1<<5) -#define EMM_CACHE_MASK (EMM_CACHE_SIZE-1) +#define EMM_CACHE_SIZE (1 << 5) +#define EMM_CACHE_MASK (EMM_CACHE_SIZE - 1) -typedef void (*emm_send_t) - (void *aux, const uint8_t *radata, int ralen, void *mux); +typedef void (*emm_send_t)(void* aux, const uint8_t* radata, int ralen, void* mux); struct emm_reass { int subsys; - uint16_t caid; + uint16_t caid; card_type_t type; - int providers_count; - emm_provider_t *providers; - uint8_t ua[8]; + int providers_count; + emm_provider_t* providers; + uint8_t ua[8]; - int emm_cache_write; - int emm_cache_count; + int emm_cache_write; + int emm_cache_count; uint32_t emm_cache[EMM_CACHE_SIZE]; union { struct { - void *shared_mux; - uint8_t *shared_emm; - int shared_len; + void* shared_mux; + uint8_t* shared_emm; + int shared_len; } cryptoworks; } u; - void (*do_emm)(emm_reass_t *ra, const uint8_t *data, int len, - void *mux, emm_send_t send, void *aux); + void (*do_emm)(emm_reass_t* ra, + const uint8_t* data, + int len, + void* mux, + emm_send_t send, + void* aux); }; -void emm_filter(emm_reass_t *ra, const uint8_t *data, int len, - void *mux, emm_send_t send, void *aux); -emm_provider_t *emm_find_provider(emm_reass_t *ra, uint32_t provid); -void emm_reass_init(emm_reass_t *ra, int subsys, uint16_t caid); -void emm_reass_done(emm_reass_t *ra); +void emm_filter(emm_reass_t* ra, + const uint8_t* data, + int len, + void* mux, + emm_send_t send, + void* aux); +emm_provider_t* emm_find_provider(emm_reass_t* ra, uint32_t provid); +void emm_reass_init(emm_reass_t* ra, int subsys, uint16_t caid); +void emm_reass_done(emm_reass_t* ra); #endif /* __TVH_EMM_REASS_H__ */ diff --git a/src/descrambler/tsdebugcw.c b/src/descrambler/tsdebugcw.c index 679c4e3c7..3f1568a0b 100644 --- a/src/descrambler/tsdebugcw.c +++ b/src/descrambler/tsdebugcw.c @@ -28,37 +28,33 @@ typedef struct tsdebugcw_service { th_descrambler_t; - int tdcw_type; - uint16_t tdcw_pid; - uint8_t tdcw_key_even[16]; /* DES or AES key */ - uint8_t tdcw_key_odd [16]; /* DES or AES key */ + int tdcw_type; + uint16_t tdcw_pid; + uint8_t tdcw_key_even[16]; /* DES or AES key */ + uint8_t tdcw_key_odd[16]; /* DES or AES key */ } tsdebugcw_service_t; typedef struct tsdebugcw_request { TAILQ_ENTRY(tsdebugcw_request) link; - tsdebugcw_service_t *ct; + tsdebugcw_service_t* ct; } tsdebugcw_request_t; tvh_mutex_t tsdebugcw_mutex; -TAILQ_HEAD(,tsdebugcw_request) tsdebugcw_requests; +TAILQ_HEAD(, tsdebugcw_request) tsdebugcw_requests; /* * */ -static int -tsdebugcw_ecm_reset(th_descrambler_t *th) -{ +static int tsdebugcw_ecm_reset(th_descrambler_t* th) { return 1; } /** * s_stream_mutex is held */ -static void -tsdebugcw_service_destroy(th_descrambler_t *td) -{ - tsdebugcw_service_t *ct = (tsdebugcw_service_t *)td; +static void tsdebugcw_service_destroy(th_descrambler_t* td) { + tsdebugcw_service_t* ct = (tsdebugcw_service_t*)td; tsdebugcw_request_t *ctr, *ctrnext; tvh_mutex_lock(&tsdebugcw_mutex); @@ -79,61 +75,57 @@ tsdebugcw_service_destroy(th_descrambler_t *td) /** * global_lock is held. Not that we care about that, but either way, it is. */ -void -tsdebugcw_service_start(service_t *t) -{ - tsdebugcw_service_t *ct; - th_descrambler_t *td; - char buf[128]; +void tsdebugcw_service_start(service_t* t) { + tsdebugcw_service_t* ct; + th_descrambler_t* td; + char buf[128]; extern const idclass_t mpegts_service_class; if (!idnode_is_instance(&t->s_id, &mpegts_service_class)) return; - LIST_FOREACH(td, &t->s_descramblers, td_service_link) + LIST_FOREACH (td, &t->s_descramblers, td_service_link) if (td->td_stop == tsdebugcw_service_destroy) break; if (td) return; - ct = calloc(1, sizeof(tsdebugcw_service_t)); - td = (th_descrambler_t *)ct; + ct = calloc(1, sizeof(tsdebugcw_service_t)); + td = (th_descrambler_t*)ct; snprintf(buf, sizeof(buf), "tsdebugcw"); - td->td_nicename = strdup(buf); - td->td_service = t; - td->td_stop = tsdebugcw_service_destroy; - td->td_ecm_reset = tsdebugcw_ecm_reset; + td->td_nicename = strdup(buf); + td->td_service = t; + td->td_stop = tsdebugcw_service_destroy; + td->td_ecm_reset = tsdebugcw_ecm_reset; tvh_mutex_lock(&t->s_stream_mutex); LIST_INSERT_HEAD(&t->s_descramblers, td, td_service_link); - descrambler_change_keystate((th_descrambler_t *)td, DS_READY, 0); + descrambler_change_keystate((th_descrambler_t*)td, DS_READY, 0); tvh_mutex_unlock(&t->s_stream_mutex); } /* * */ -void -tsdebugcw_new_keys(service_t *t, int type, uint16_t pid, uint8_t *odd, uint8_t *even) -{ - static char empty[16] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - th_descrambler_t *td; - tsdebugcw_service_t *ct; - tsdebugcw_request_t *ctr; - int keylen = DESCRAMBLER_KEY_SIZE(type); - - LIST_FOREACH(td, &t->s_descramblers, td_service_link) +void tsdebugcw_new_keys(service_t* t, int type, uint16_t pid, uint8_t* odd, uint8_t* even) { + static char empty[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; + th_descrambler_t* td; + tsdebugcw_service_t* ct; + tsdebugcw_request_t* ctr; + int keylen = DESCRAMBLER_KEY_SIZE(type); + + LIST_FOREACH (td, &t->s_descramblers, td_service_link) if (td->td_stop == tsdebugcw_service_destroy) break; if (!td) return; - ct = (tsdebugcw_service_t *)td; + ct = (tsdebugcw_service_t*)td; ct->tdcw_type = type; - ct->tdcw_pid = pid; + ct->tdcw_pid = pid; if (odd && memcmp(empty, odd, keylen)) memcpy(ct->tdcw_key_odd, odd, keylen); if (even && memcmp(empty, even, keylen)) memcpy(ct->tdcw_key_even, even, keylen); - ctr = malloc(sizeof(*ctr)); + ctr = malloc(sizeof(*ctr)); ctr->ct = ct; tvh_mutex_lock(&tsdebugcw_mutex); TAILQ_INSERT_TAIL(&tsdebugcw_requests, ctr, link); @@ -143,11 +135,9 @@ tsdebugcw_new_keys(service_t *t, int type, uint16_t pid, uint8_t *odd, uint8_t * /* * */ -void -tsdebugcw_go(void) -{ - tsdebugcw_request_t *ctr; - tsdebugcw_service_t *ct; +void tsdebugcw_go(void) { + tsdebugcw_request_t* ctr; + tsdebugcw_service_t* ct; while (1) { tvh_mutex_lock(&tsdebugcw_mutex); @@ -155,11 +145,14 @@ tsdebugcw_go(void) if (ctr) TAILQ_REMOVE(&tsdebugcw_requests, ctr, link); tvh_mutex_unlock(&tsdebugcw_mutex); - if (!ctr) break; + if (!ctr) + break; ct = ctr->ct; - descrambler_keys((th_descrambler_t *)ct, - ct->tdcw_type, ct->tdcw_pid, - ct->tdcw_key_odd, ct->tdcw_key_even); + descrambler_keys((th_descrambler_t*)ct, + ct->tdcw_type, + ct->tdcw_pid, + ct->tdcw_key_odd, + ct->tdcw_key_even); free(ctr); } } @@ -167,9 +160,7 @@ tsdebugcw_go(void) /* * */ -void -tsdebugcw_init(void) -{ +void tsdebugcw_init(void) { tvh_mutex_init(&tsdebugcw_mutex, NULL); TAILQ_INIT(&tsdebugcw_requests); } diff --git a/src/descrambler/tvhcsa.c b/src/descrambler/tvhcsa.c index 2c75f8969..1fc942083 100644 --- a/src/descrambler/tvhcsa.c +++ b/src/descrambler/tvhcsa.c @@ -33,21 +33,16 @@ #include "descrambler/algo/libdesdec.h" #if ENABLE_DVBCSA -static int dvbcsa_dl_scanned; +static int dvbcsa_dl_scanned; static dvbcsa_dl_bs_key_set_type dvbcsa_dl_bs_key_set_ecm; #endif -static void -tvhcsa_empty_flush - ( tvhcsa_t *csa, struct mpegts_service *s ) -{ +static void tvhcsa_empty_flush(tvhcsa_t* csa, struct mpegts_service* s) { /* empty - no queue */ } static void -tvhcsa_aes_ecb_descramble - ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb, int len ) -{ +tvhcsa_aes_ecb_descramble(tvhcsa_t* csa, struct mpegts_service* s, const uint8_t* tsb, int len) { const uint8_t *tsb2, *end2; for (tsb2 = tsb, end2 = tsb + len; tsb2 < end2; tsb2 += 188) @@ -56,9 +51,7 @@ tvhcsa_aes_ecb_descramble } static void -tvhcsa_aes128_ecb_descramble - ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb, int len ) -{ +tvhcsa_aes128_ecb_descramble(tvhcsa_t* csa, struct mpegts_service* s, const uint8_t* tsb, int len) { const uint8_t *tsb2, *end2; for (tsb2 = tsb, end2 = tsb + len; tsb2 < end2; tsb2 += 188) @@ -67,9 +60,7 @@ tvhcsa_aes128_ecb_descramble } static void -tvhcsa_des_ncb_descramble - ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb, int len ) -{ +tvhcsa_des_ncb_descramble(tvhcsa_t* csa, struct mpegts_service* s, const uint8_t* tsb, int len) { const uint8_t *tsb2, *end2; for (tsb2 = tsb, end2 = tsb + len; tsb2 < end2; tsb2 += 188) @@ -77,20 +68,23 @@ tvhcsa_des_ncb_descramble ts_recv_packet2(s, tsb, len); } -static void -tvhcsa_csa_cbc_flush - ( tvhcsa_t *csa, struct mpegts_service *s ) -{ +static void tvhcsa_csa_cbc_flush(tvhcsa_t* csa, struct mpegts_service* s) { #if ENABLE_DVBCSA - tvhtrace(LS_CSA, "%p: CSA flush - descramble packets for service \"%s\" MAX=%d even=%d odd=%d fill=%d", - csa,((mpegts_service_t *)s)->s_dvb_svcname, csa->csa_cluster_size,csa->csa_fill_even,csa->csa_fill_odd,csa->csa_fill); - - if(csa->csa_fill_even) { + tvhtrace(LS_CSA, + "%p: CSA flush - descramble packets for service \"%s\" MAX=%d even=%d odd=%d fill=%d", + csa, + ((mpegts_service_t*)s)->s_dvb_svcname, + csa->csa_cluster_size, + csa->csa_fill_even, + csa->csa_fill_odd, + csa->csa_fill); + + if (csa->csa_fill_even) { csa->csa_tsbbatch_even[csa->csa_fill_even].data = NULL; dvbcsa_bs_decrypt(csa->csa_key_even, csa->csa_tsbbatch_even, 184); csa->csa_fill_even = 0; } - if(csa->csa_fill_odd) { + if (csa->csa_fill_odd) { csa->csa_tsbbatch_odd[csa->csa_fill_odd].data = NULL; dvbcsa_bs_decrypt(csa->csa_key_odd, csa->csa_tsbbatch_odd, 184); csa->csa_fill_odd = 0; @@ -105,64 +99,68 @@ tvhcsa_csa_cbc_flush #endif } -static void -tvhcsa_csa_cbc_descramble - ( tvhcsa_t *csa, struct mpegts_service *s, const uint8_t *tsb, int tsb_len ) -{ - const uint8_t *tsb_end = tsb + tsb_len; +static void tvhcsa_csa_cbc_descramble(tvhcsa_t* csa, + struct mpegts_service* s, + const uint8_t* tsb, + int tsb_len) { + const uint8_t* tsb_end = tsb + tsb_len; assert(csa->csa_fill >= 0 && csa->csa_fill < csa->csa_fill_size); #if ENABLE_DVBCSA - uint8_t *pkt; - int_fast8_t ev_od; + uint8_t* pkt; + int_fast8_t ev_od; int_fast16_t len; int_fast16_t offset; - for ( ; tsb < tsb_end; tsb += 188) { - - pkt = csa->csa_tsbcluster + csa->csa_fill * 188; - memcpy(pkt, tsb, 188); - csa->csa_fill++; - - do { // handle this packet - if((pkt[3] & 0x80) == 0) // clear or reserved (0x40) - break; - ev_od = pkt[3] & 0x40; - pkt[3] &= 0x3f; // consider it decrypted now - if(pkt[3] & 0x20) { // incomplete packet - if(!(pkt[3] & 0x10)) // no payload - but why scrambled??? - break; - offset = 4 + pkt[4] + 1; - if (offset >= 188){ // invalid offset (residue handling?) - if (tvhlog_limit(&csa->tvhcsa_loglimit, 30)) - tvhtrace(LS_CSA, "invalid payload offset in packet for service \"%s\" (offset=%d pkt[3]=0x%02x pkt[4]=0x%02x)", - ((mpegts_service_t *)s)->s_dvb_svcname, (int)offset, pkt[3], pkt[4]); - break; // no more processing - } - len = 188 - offset; - } else { - len = 184; - offset = 4; - } - if(ev_od == 0) { - csa->csa_tsbbatch_even[csa->csa_fill_even].data = pkt + offset; - csa->csa_tsbbatch_even[csa->csa_fill_even].len = len; - csa->csa_fill_even++; - if(csa->csa_fill_even == csa->csa_cluster_size) - tvhcsa_csa_cbc_flush(csa, s); - } else { - csa->csa_tsbbatch_odd[csa->csa_fill_odd].data = pkt + offset; - csa->csa_tsbbatch_odd[csa->csa_fill_odd].len = len; - csa->csa_fill_odd++; - if(csa->csa_fill_odd == csa->csa_cluster_size) - tvhcsa_csa_cbc_flush(csa, s); - } - } while(0); - - if(csa->csa_fill == csa->csa_fill_size ) - tvhcsa_csa_cbc_flush(csa, s); - + for (; tsb < tsb_end; tsb += 188) { + + pkt = csa->csa_tsbcluster + csa->csa_fill * 188; + memcpy(pkt, tsb, 188); + csa->csa_fill++; + + do { // handle this packet + if ((pkt[3] & 0x80) == 0) // clear or reserved (0x40) + break; + ev_od = pkt[3] & 0x40; + pkt[3] &= 0x3f; // consider it decrypted now + if (pkt[3] & 0x20) { // incomplete packet + if (!(pkt[3] & 0x10)) // no payload - but why scrambled??? + break; + offset = 4 + pkt[4] + 1; + if (offset >= 188) { // invalid offset (residue handling?) + if (tvhlog_limit(&csa->tvhcsa_loglimit, 30)) + tvhtrace(LS_CSA, + "invalid payload offset in packet for service \"%s\" (offset=%d pkt[3]=0x%02x " + "pkt[4]=0x%02x)", + ((mpegts_service_t*)s)->s_dvb_svcname, + (int)offset, + pkt[3], + pkt[4]); + break; // no more processing + } + len = 188 - offset; + } else { + len = 184; + offset = 4; + } + if (ev_od == 0) { + csa->csa_tsbbatch_even[csa->csa_fill_even].data = pkt + offset; + csa->csa_tsbbatch_even[csa->csa_fill_even].len = len; + csa->csa_fill_even++; + if (csa->csa_fill_even == csa->csa_cluster_size) + tvhcsa_csa_cbc_flush(csa, s); + } else { + csa->csa_tsbbatch_odd[csa->csa_fill_odd].data = pkt + offset; + csa->csa_tsbbatch_odd[csa->csa_fill_odd].len = len; + csa->csa_fill_odd++; + if (csa->csa_fill_odd == csa->csa_cluster_size) + tvhcsa_csa_cbc_flush(csa, s); + } + } while (0); + + if (csa->csa_fill == csa->csa_fill_size) + tvhcsa_csa_cbc_flush(csa, s); } #else @@ -170,130 +168,127 @@ tvhcsa_csa_cbc_descramble #endif } -int -tvhcsa_set_type( tvhcsa_t *csa, struct mpegts_service *s, int type ) -{ +int tvhcsa_set_type(tvhcsa_t* csa, struct mpegts_service* s, int type) { if (csa->csa_type == type) return 0; if (csa->csa_descramble) return -1; switch (type) { - case DESCRAMBLER_CSA_CBC: - csa->csa_descramble = tvhcsa_csa_cbc_descramble; - csa->csa_flush = tvhcsa_csa_cbc_flush; - csa->csa_keylen = 8; + case DESCRAMBLER_CSA_CBC: + csa->csa_descramble = tvhcsa_csa_cbc_descramble; + csa->csa_flush = tvhcsa_csa_cbc_flush; + csa->csa_keylen = 8; #if ENABLE_DVBCSA - csa->csa_cluster_size = dvbcsa_bs_batch_size(); + csa->csa_cluster_size = dvbcsa_bs_batch_size(); #else - csa->csa_cluster_size = 0; + csa->csa_cluster_size = 0; #endif - csa->csa_fill_size = 3 * csa->csa_cluster_size; - tvhtrace(LS_CSA, "%p: service \"%s\" using CSA batch size = %d for decryption", - csa, ((mpegts_service_t *)s)->s_dvb_svcname, csa->csa_cluster_size ); - - csa->csa_tsbcluster = malloc(csa->csa_fill_size * 188); + csa->csa_fill_size = 3 * csa->csa_cluster_size; + tvhtrace(LS_CSA, + "%p: service \"%s\" using CSA batch size = %d for decryption", + csa, + ((mpegts_service_t*)s)->s_dvb_svcname, + csa->csa_cluster_size); + + csa->csa_tsbcluster = malloc(csa->csa_fill_size * 188); #if ENABLE_DVBCSA - csa->csa_tsbbatch_even = malloc((csa->csa_cluster_size + 1) * - sizeof(struct dvbcsa_bs_batch_s)); - csa->csa_tsbbatch_odd = malloc((csa->csa_cluster_size + 1) * - sizeof(struct dvbcsa_bs_batch_s)); - csa->csa_key_even = dvbcsa_bs_key_alloc(); - csa->csa_key_odd = dvbcsa_bs_key_alloc(); + csa->csa_tsbbatch_even = + malloc((csa->csa_cluster_size + 1) * sizeof(struct dvbcsa_bs_batch_s)); + csa->csa_tsbbatch_odd = + malloc((csa->csa_cluster_size + 1) * sizeof(struct dvbcsa_bs_batch_s)); + csa->csa_key_even = dvbcsa_bs_key_alloc(); + csa->csa_key_odd = dvbcsa_bs_key_alloc(); #endif - break; - case DESCRAMBLER_DES_NCB: - csa->csa_priv = des_get_priv_struct(); - csa->csa_descramble = tvhcsa_des_ncb_descramble; - csa->csa_flush = tvhcsa_empty_flush; - csa->csa_keylen = 8; - break; - case DESCRAMBLER_AES_ECB: - csa->csa_priv = aes_get_priv_struct(); - csa->csa_descramble = tvhcsa_aes_ecb_descramble; - csa->csa_flush = tvhcsa_empty_flush; - csa->csa_keylen = 8; - break; - case DESCRAMBLER_AES128_ECB: - csa->csa_priv = aes128_get_priv_struct(); - csa->csa_descramble = tvhcsa_aes128_ecb_descramble; - csa->csa_flush = tvhcsa_empty_flush; - csa->csa_keylen = 16; - break; - default: - assert(0); + break; + case DESCRAMBLER_DES_NCB: + csa->csa_priv = des_get_priv_struct(); + csa->csa_descramble = tvhcsa_des_ncb_descramble; + csa->csa_flush = tvhcsa_empty_flush; + csa->csa_keylen = 8; + break; + case DESCRAMBLER_AES_ECB: + csa->csa_priv = aes_get_priv_struct(); + csa->csa_descramble = tvhcsa_aes_ecb_descramble; + csa->csa_flush = tvhcsa_empty_flush; + csa->csa_keylen = 8; + break; + case DESCRAMBLER_AES128_ECB: + csa->csa_priv = aes128_get_priv_struct(); + csa->csa_descramble = tvhcsa_aes128_ecb_descramble; + csa->csa_flush = tvhcsa_empty_flush; + csa->csa_keylen = 16; + break; + default: + assert(0); } csa->csa_type = type; return 0; } - -void tvhcsa_set_key_even( tvhcsa_t *csa, const uint8_t *even ) -{ +void tvhcsa_set_key_even(tvhcsa_t* csa, const uint8_t* even) { switch (csa->csa_type) { - case DESCRAMBLER_CSA_CBC: + case DESCRAMBLER_CSA_CBC: #if ENABLE_DVBCSA - dvbcsa_bs_key_set_wrap(csa->csa_ecm, even, csa->csa_key_even); + dvbcsa_bs_key_set_wrap(csa->csa_ecm, even, csa->csa_key_even); #endif - break; - case DESCRAMBLER_DES_NCB: - des_set_even_control_word(csa->csa_priv, even); - break; - case DESCRAMBLER_AES_ECB: - aes_set_even_control_word(csa->csa_priv, even); - break; - case DESCRAMBLER_AES128_ECB: - aes128_set_even_control_word(csa->csa_priv, even); - break; - assert(0); + break; + case DESCRAMBLER_DES_NCB: + des_set_even_control_word(csa->csa_priv, even); + break; + case DESCRAMBLER_AES_ECB: + aes_set_even_control_word(csa->csa_priv, even); + break; + case DESCRAMBLER_AES128_ECB: + aes128_set_even_control_word(csa->csa_priv, even); + break; + assert(0); } } -void tvhcsa_set_key_odd( tvhcsa_t *csa, const uint8_t *odd ) -{ +void tvhcsa_set_key_odd(tvhcsa_t* csa, const uint8_t* odd) { assert(csa->csa_type); switch (csa->csa_type) { - case DESCRAMBLER_CSA_CBC: + case DESCRAMBLER_CSA_CBC: #if ENABLE_DVBCSA - dvbcsa_bs_key_set_wrap(csa->csa_ecm, odd, csa->csa_key_odd); + dvbcsa_bs_key_set_wrap(csa->csa_ecm, odd, csa->csa_key_odd); #endif - break; - case DESCRAMBLER_DES_NCB: - des_set_odd_control_word(csa->csa_priv, odd); - break; - case DESCRAMBLER_AES_ECB: - aes_set_odd_control_word(csa->csa_priv, odd); - break; - case DESCRAMBLER_AES128_ECB: - aes128_set_odd_control_word(csa->csa_priv, odd); - break; - default: - assert(0); + break; + case DESCRAMBLER_DES_NCB: + des_set_odd_control_word(csa->csa_priv, odd); + break; + case DESCRAMBLER_AES_ECB: + aes_set_odd_control_word(csa->csa_priv, odd); + break; + case DESCRAMBLER_AES128_ECB: + aes128_set_odd_control_word(csa->csa_priv, odd); + break; + default: + assert(0); } } -void -tvhcsa_init ( tvhcsa_t *csa ) -{ +void tvhcsa_init(tvhcsa_t* csa) { #if ENABLE_DVBCSA - if (!dvbcsa_dl_scanned) - { + if (!dvbcsa_dl_scanned) { dvbcsa_dl_scanned++; #if defined RTLD_DEFAULT - dvbcsa_dl_bs_key_set_ecm = (dvbcsa_dl_bs_key_set_type) dlsym(RTLD_DEFAULT, "dvbcsa_bs_key_set_ecm"); - tvhinfo(LS_DESCRAMBLER, "dvbcsa_bs_key_set_ecm() function%s detected in libdvbcsa", dvbcsa_dl_bs_key_set_ecm ? "" : " not"); + dvbcsa_dl_bs_key_set_ecm = + (dvbcsa_dl_bs_key_set_type)dlsym(RTLD_DEFAULT, "dvbcsa_bs_key_set_ecm"); + tvhinfo(LS_DESCRAMBLER, + "dvbcsa_bs_key_set_ecm() function%s detected in libdvbcsa", + dvbcsa_dl_bs_key_set_ecm ? "" : " not"); #else - dvbcsa_dl_bs_key_set_ecm = (dvbcsa_dl_bs_key_set_type) NULL; - tvhinfo(LS_DESCRAMBLER, "can not detect dvbcsa_bs_key_set_ecm() function: RTLD_DEFAULT not defined on this system"); + dvbcsa_dl_bs_key_set_ecm = (dvbcsa_dl_bs_key_set_type)NULL; + tvhinfo(LS_DESCRAMBLER, + "can not detect dvbcsa_bs_key_set_ecm() function: RTLD_DEFAULT not defined on this system"); #endif } #endif - csa->csa_type = 0; - csa->csa_keylen = 0; + csa->csa_type = 0; + csa->csa_keylen = 0; } -void -tvhcsa_destroy ( tvhcsa_t *csa ) -{ +void tvhcsa_destroy(tvhcsa_t* csa) { #if ENABLE_DVBCSA if (csa->csa_key_odd) dvbcsa_bs_key_free(csa->csa_key_odd); @@ -308,28 +303,28 @@ tvhcsa_destroy ( tvhcsa_t *csa ) free(csa->csa_tsbcluster); if (csa->csa_priv) { switch (csa->csa_type) { - case DESCRAMBLER_CSA_CBC: - break; - case DESCRAMBLER_DES_NCB: - des_free_priv_struct(csa->csa_priv); - break; - case DESCRAMBLER_AES_ECB: - aes_free_priv_struct(csa->csa_priv); - break; - case DESCRAMBLER_AES128_ECB: - aes128_free_priv_struct(csa->csa_priv); - break; - default: - assert(0); + case DESCRAMBLER_CSA_CBC: + break; + case DESCRAMBLER_DES_NCB: + des_free_priv_struct(csa->csa_priv); + break; + case DESCRAMBLER_AES_ECB: + aes_free_priv_struct(csa->csa_priv); + break; + case DESCRAMBLER_AES128_ECB: + aes128_free_priv_struct(csa->csa_priv); + break; + default: + assert(0); } } memset(csa, 0, sizeof(*csa)); } #if ENABLE_DVBCSA -void -dvbcsa_bs_key_set_wrap(const unsigned char ecm, const dvbcsa_cw_t cw, struct dvbcsa_bs_key_s *key) -{ +void dvbcsa_bs_key_set_wrap(const unsigned char ecm, + const dvbcsa_cw_t cw, + struct dvbcsa_bs_key_s* key) { if (dvbcsa_dl_bs_key_set_ecm) dvbcsa_dl_bs_key_set_ecm(ecm, cw, key); else diff --git a/src/descrambler/tvhcsa.h b/src/descrambler/tvhcsa.h index 17020f9fe..73331e14a 100644 --- a/src/descrambler/tvhcsa.h +++ b/src/descrambler/tvhcsa.h @@ -29,65 +29,67 @@ struct elementary_stream; #endif #include "tvhlog.h" -typedef struct tvhcsa -{ +typedef struct tvhcsa { /** * CSA */ - int csa_type; /*< see DESCRAMBLER_* defines */ - int csa_keylen; - void (*csa_descramble) - ( struct tvhcsa *csa, struct mpegts_service *s, - const uint8_t *tsb, int len ); - void (*csa_flush) - ( struct tvhcsa *csa, struct mpegts_service *s ); + int csa_type; /*< see DESCRAMBLER_* defines */ + int csa_keylen; + void (*csa_descramble)(struct tvhcsa* csa, struct mpegts_service* s, const uint8_t* tsb, int len); + void (*csa_flush)(struct tvhcsa* csa, struct mpegts_service* s); int csa_cluster_size; - uint8_t *csa_tsbcluster; + uint8_t* csa_tsbcluster; int csa_fill; int csa_fill_size; uint8_t csa_ecm; #if ENABLE_DVBCSA - struct dvbcsa_bs_batch_s *csa_tsbbatch_even; - struct dvbcsa_bs_batch_s *csa_tsbbatch_odd; - int csa_fill_even; - int csa_fill_odd; + struct dvbcsa_bs_batch_s* csa_tsbbatch_even; + struct dvbcsa_bs_batch_s* csa_tsbbatch_odd; + int csa_fill_even; + int csa_fill_odd; - struct dvbcsa_bs_key_s *csa_key_even; - struct dvbcsa_bs_key_s *csa_key_odd; + struct dvbcsa_bs_key_s* csa_key_even; + struct dvbcsa_bs_key_s* csa_key_odd; #endif - void *csa_priv; + void* csa_priv; tvhlog_limit_t tvhcsa_loglimit; } tvhcsa_t; #if ENABLE_TVHCSA -int tvhcsa_set_type( tvhcsa_t *csa, struct mpegts_service *s, int type ); +int tvhcsa_set_type(tvhcsa_t* csa, struct mpegts_service* s, int type); -void tvhcsa_set_key_even( tvhcsa_t *csa, const uint8_t *even ); -void tvhcsa_set_key_odd ( tvhcsa_t *csa, const uint8_t *odd ); +void tvhcsa_set_key_even(tvhcsa_t* csa, const uint8_t* even); +void tvhcsa_set_key_odd(tvhcsa_t* csa, const uint8_t* odd); -void tvhcsa_init ( tvhcsa_t *csa ); -void tvhcsa_destroy ( tvhcsa_t *csa ); +void tvhcsa_init(tvhcsa_t* csa); +void tvhcsa_destroy(tvhcsa_t* csa); #else -static inline int tvhcsa_set_type( tvhcsa_t *csa, struct mpegts_service *s, int type ) { return -1; } +static inline int tvhcsa_set_type(tvhcsa_t* csa, struct mpegts_service* s, int type) { + return -1; +} -static inline void tvhcsa_set_key_even( tvhcsa_t *csa, const uint8_t *even ) { }; -static inline void tvhcsa_set_key_odd ( tvhcsa_t *csa, const uint8_t *odd ) { }; +static inline void tvhcsa_set_key_even(tvhcsa_t* csa, const uint8_t* even) {}; +static inline void tvhcsa_set_key_odd(tvhcsa_t* csa, const uint8_t* odd) {}; -static inline void tvhcsa_init ( tvhcsa_t *csa ) { }; -static inline void tvhcsa_destroy ( tvhcsa_t *csa ) { }; +static inline void tvhcsa_init(tvhcsa_t* csa) {}; +static inline void tvhcsa_destroy(tvhcsa_t* csa) {}; #endif #if ENABLE_DVBCSA -typedef void* (*dvbcsa_dl_bs_key_set_type)(const unsigned char ecm, const dvbcsa_cw_t cw, struct dvbcsa_bs_key_s *key); -void dvbcsa_bs_key_set_wrap(const unsigned char ecm, const dvbcsa_cw_t cw, struct dvbcsa_bs_key_s *key); +typedef void* (*dvbcsa_dl_bs_key_set_type)(const unsigned char ecm, + const dvbcsa_cw_t cw, + struct dvbcsa_bs_key_s* key); +void dvbcsa_bs_key_set_wrap(const unsigned char ecm, + const dvbcsa_cw_t cw, + struct dvbcsa_bs_key_s* key); #endif #endif /* __TVH_CSA_H__ */ diff --git a/src/docs.c b/src/docs.c index 684a9fad5..9a11793dd 100644 --- a/src/docs.c +++ b/src/docs.c @@ -5,6 +5,6 @@ #define DOCINCPREF "\xff\x02" #define ITEMSINCPREF "\xff\x03" #define MDINCLUDE "\xff\x04" -#define N_(s) s +#define N_(s) s #include "docs_inc.c" diff --git a/src/docs.h b/src/docs.h index d9581878d..91c812384 100644 --- a/src/docs.h +++ b/src/docs.h @@ -20,11 +20,10 @@ #define __TVH_DOCS_H__ struct tvh_doc_page { - const char *name; - const char **strings; + const char* name; + const char** strings; }; extern const struct tvh_doc_page tvh_doc_markdown_pages[]; #endif /* __TVH_DOCS_H__ */ - diff --git a/src/download.c b/src/download.c index 5f2b6a958..877b01be0 100644 --- a/src/download.c +++ b/src/download.c @@ -28,29 +28,25 @@ /* * */ -static int -download_file(download_t *dn, const char *filename) -{ - int fd, res; +static int download_file(download_t* dn, const char* filename) { + int fd, res; struct stat st; - char *data, *last_url; - ssize_t r; - off_t off; + char * data, *last_url; + ssize_t r; + off_t off; fd = tvh_open(filename, O_RDONLY, 0); if (fd < 0) { - tvherror(dn->subsys, "unable to open file '%s': %s", - filename, strerror(errno)); + tvherror(dn->subsys, "unable to open file '%s': %s", filename, strerror(errno)); return -1; } if (fstat(fd, &st) || st.st_size == 0) { - tvherror(dn->subsys, "unable to stat file '%s': %s", - filename, strerror(errno)); + tvherror(dn->subsys, "unable to stat file '%s': %s", filename, strerror(errno)); close(fd); return -1; } - data = malloc(st.st_size+1); - off = 0; + data = malloc(st.st_size + 1); + off = 0; do { r = read(fd, data + off, st.st_size - off); if (r < 0) { @@ -64,7 +60,7 @@ download_file(download_t *dn, const char *filename) if (off == st.st_size) { data[off] = '\0'; - last_url = strrchr(filename, '/'); + last_url = strrchr(filename, '/'); if (last_url) last_url++; res = dn->process(dn->aux, last_url, NULL, data, off); @@ -78,33 +74,29 @@ download_file(download_t *dn, const char *filename) /* * */ -static void -download_fetch_done(void *aux) -{ - http_client_t *hc = aux; - download_t *dm = hc->hc_aux; +static void download_fetch_done(void* aux) { + http_client_t* hc = aux; + download_t* dm = hc->hc_aux; if (dm->http_client) { dm->http_client = NULL; - http_client_close((http_client_t *)aux); + http_client_close((http_client_t*)aux); } } /* * */ -static int -download_fetch_complete(http_client_t *hc) -{ - download_t *dn = hc->hc_aux; - const char *last_url = NULL; - url_t u; +static int download_fetch_complete(http_client_t* hc) { + download_t* dn = hc->hc_aux; + const char* last_url = NULL; + url_t u; switch (hc->hc_code) { - case HTTP_STATUS_MOVED: - case HTTP_STATUS_FOUND: - case HTTP_STATUS_SEE_OTHER: - case HTTP_STATUS_NOT_MODIFIED: - return 0; + case HTTP_STATUS_MOVED: + case HTTP_STATUS_FOUND: + case HTTP_STATUS_SEE_OTHER: + case HTTP_STATUS_NOT_MODIFIED: + return 0; } urlinit(&u); @@ -122,8 +114,11 @@ download_fetch_complete(http_client_t *hc) if (hc->hc_code == HTTP_STATUS_OK && hc->hc_result == 0 && hc->hc_data_size > 0) dn->process(dn->aux, last_url, hc->hc_url, hc->hc_data, hc->hc_data_size); else - tvherror(dn->subsys, "unable to fetch data from url [%d-%d/%zd]", - hc->hc_code, hc->hc_result, hc->hc_data_size); + tvherror(dn->subsys, + "unable to fetch data from url [%d-%d/%zd]", + hc->hc_code, + hc->hc_result, + hc->hc_data_size); /* note: http_client_close must be called outside http_client callbacks */ mtimer_arm_rel(&dn->fetch_timer, download_fetch_done, hc, 0); @@ -138,14 +133,12 @@ out: /* * */ -static void -download_pipe_close(download_t *dn) -{ +static void download_pipe_close(download_t* dn) { if (dn->pipe_fd >= 0) { close(dn->pipe_fd); if (dn->pipe_pid) kill(-(dn->pipe_pid), SIGKILL); /* kill whole process group */ - dn->pipe_fd = -1; + dn->pipe_fd = -1; dn->pipe_pid = 0; } sbuf_free(&dn->pipe_sbuf); @@ -154,18 +147,16 @@ download_pipe_close(download_t *dn) /* * */ -static void -download_pipe_read(void *aux) -{ - download_t *dn = aux; - ssize_t len; - char *s, *p; +static void download_pipe_read(void* aux) { + download_t* dn = aux; + ssize_t len; + char * s, *p; if (dn->pipe_fd < 0 || dn->pipe_pid == 0) return; while (1) { - if (dn->pipe_sbuf.sb_ptr > 50*1024*1024) { + if (dn->pipe_sbuf.sb_ptr > 50 * 1024 * 1024) { errno = EMSGSIZE; goto failed; } @@ -180,13 +171,13 @@ download_pipe_read(void *aux) if (p) p++; sbuf_append(&dn->pipe_sbuf, "", 1); - dn->process(dn->aux, p, NULL, (char *)dn->pipe_sbuf.sb_data, (size_t)dn->pipe_sbuf.sb_ptr); + dn->process(dn->aux, p, NULL, (char*)dn->pipe_sbuf.sb_data, (size_t)dn->pipe_sbuf.sb_ptr); download_pipe_close(dn); return; } else if (len < 0) { if (ERRNO_AGAIN(errno)) break; -failed: + failed: tvherror(dn->subsys, "pipe: read failed: %d", errno); download_pipe_close(dn); return; @@ -199,11 +190,9 @@ failed: /* * */ -static int -download_pipe(download_t *dn, const char *args) -{ - char **argv = NULL; - int r; +static int download_pipe(download_t* dn, const char* args) { + char** argv = NULL; + int r; download_pipe_close(dn); mtimer_disarm(&dn->pipe_read_timer); @@ -220,7 +209,7 @@ download_pipe(download_t *dn, const char *args) spawn_free_args(argv); if (r < 0) { - dn->pipe_fd = -1; + dn->pipe_fd = -1; dn->pipe_pid = 0; tvherror(dn->subsys, "pipe: cannot start (%s)", args); return -1; @@ -235,12 +224,10 @@ download_pipe(download_t *dn, const char *args) /* * */ -static void -download_fetch(void *aux) -{ - download_t *dn = aux; - http_client_t *hc; - url_t u; +static void download_fetch(void* aux) { + download_t* dn = aux; + http_client_t* hc; + url_t u; urlinit(&u); @@ -248,7 +235,7 @@ download_fetch(void *aux) goto done; if (strncmp(dn->url, "file://", 7) == 0) { - char *f = tvh_strdupa(dn->url + 7); + char* f = tvh_strdupa(dn->url + 7); http_deescape(f); download_file(dn, f); goto done; @@ -274,8 +261,8 @@ download_fetch(void *aux) goto stop; } hc->hc_handle_location = 1; - hc->hc_data_limit = 1024*1024; - hc->hc_data_complete = download_fetch_complete; + hc->hc_data_limit = 1024 * 1024; + hc->hc_data_complete = download_fetch_complete; http_client_register(hc); http_client_ssl_peer_verify(hc, dn->ssl_peer_verify); if (http_client_simple(hc, &u) < 0) { @@ -297,11 +284,9 @@ done: /* * */ -void -download_init( download_t *dn, int subsys ) -{ +void download_init(download_t* dn, int subsys) { memset(dn, 0, sizeof(*dn)); - dn->subsys = subsys; + dn->subsys = subsys; dn->pipe_fd = -1; sbuf_init(&dn->pipe_sbuf); } @@ -309,9 +294,7 @@ download_init( download_t *dn, int subsys ) /* * */ -void -download_start( download_t *dn, const char *url, void *aux ) -{ +void download_start(download_t* dn, const char* url, void* aux) { if (dn->http_client) { http_client_close(dn->http_client); dn->http_client = NULL; @@ -327,9 +310,7 @@ download_start( download_t *dn, const char *url, void *aux ) /* * */ -void -download_done( download_t *dn ) -{ +void download_done(download_t* dn) { if (dn->http_client) { http_client_close(dn->http_client); dn->http_client = NULL; @@ -337,5 +318,6 @@ download_done( download_t *dn ) download_pipe_close(dn); mtimer_disarm(&dn->fetch_timer); mtimer_disarm(&dn->pipe_read_timer); - free(dn->url); dn->url = NULL; + free(dn->url); + dn->url = NULL; } diff --git a/src/download.h b/src/download.h index 9f1f1dd9c..a917ab297 100644 --- a/src/download.h +++ b/src/download.h @@ -25,14 +25,13 @@ typedef struct download { int subsys; - char *url; - void *aux; + char* url; + void* aux; int ssl_peer_verify; - int (*process)(void *aux, const char *last_url, const char *host_url, - char *data, size_t len); - void (*stop)(void *aux); + int (*process)(void* aux, const char* last_url, const char* host_url, char* data, size_t len); + void (*stop)(void* aux); /* internal members */ - http_client_t *http_client; + http_client_t* http_client; mtimer_t fetch_timer; mtimer_t pipe_read_timer; sbuf_t pipe_sbuf; @@ -40,8 +39,8 @@ typedef struct download { pid_t pipe_pid; } download_t; -void download_init ( download_t *dn, int subsys ); -void download_start( download_t *dn, const char *url, void *aux ); -void download_done ( download_t *dn ); +void download_init(download_t* dn, int subsys); +void download_start(download_t* dn, const char* url, void* aux); +void download_done(download_t* dn); #endif /* __DOWNLOAD__ */ diff --git a/src/dvr/dvr.h b/src/dvr/dvr.h index 05cceabfc..94e54749d 100644 --- a/src/dvr/dvr.h +++ b/src/dvr/dvr.h @@ -45,21 +45,21 @@ LIST_HEAD(dvr_vfs_list, dvr_vfs); /** * */ -#define DVR_MAX_DATA_ERRORS (10000) +#define DVR_MAX_DATA_ERRORS (10000) -#define DVR_FILESIZE_UPDATE (1<<0) -#define DVR_FILESIZE_TOTAL (1<<1) +#define DVR_FILESIZE_UPDATE (1 << 0) +#define DVR_FILESIZE_TOTAL (1 << 1) -#define DVR_FINISHED_ALL (1<<0) -#define DVR_FINISHED_SUCCESS (1<<1) -#define DVR_FINISHED_FAILED (1<<2) -#define DVR_FINISHED_REMOVED_SUCCESS (1<<3) /* Removed recording, was succesful before */ -#define DVR_FINISHED_REMOVED_FAILED (1<<4) /* Removed recording, was failed before */ +#define DVR_FINISHED_ALL (1 << 0) +#define DVR_FINISHED_SUCCESS (1 << 1) +#define DVR_FINISHED_FAILED (1 << 2) +#define DVR_FINISHED_REMOVED_SUCCESS (1 << 3) /* Removed recording, was succesful before */ +#define DVR_FINISHED_REMOVED_FAILED (1 << 4) /* Removed recording, was failed before */ typedef struct dvr_vfs { LIST_ENTRY(dvr_vfs) link; tvh_fsid_t fsid; - uint64_t used_size; + uint64_t used_size; } dvr_vfs_t; typedef struct dvr_config { @@ -68,60 +68,60 @@ typedef struct dvr_config { LIST_ENTRY(dvr_config) config_link; LIST_ENTRY(dvr_config) profile_link; - int dvr_enabled; - int dvr_valid; - char *dvr_config_name; - char *dvr_comment; - profile_t *dvr_profile; - char *dvr_storage; - int dvr_pri; - int dvr_clone; - int dvr_complex_scheduling; - uint32_t dvr_rerecord_errors; - uint32_t dvr_retention_days; - uint32_t dvr_removal_days; - uint32_t dvr_removal_after_playback; - uint32_t dvr_autorec_max_count; - uint32_t dvr_autorec_max_sched_count; - char *dvr_charset; - char *dvr_charset_id; - char *dvr_preproc; - char *dvr_postproc; - char *dvr_postremove; - uint32_t dvr_warm_time; - uint32_t dvr_extra_time_pre; - uint32_t dvr_extra_time_post; - uint32_t dvr_update_window; - int dvr_running; - uint32_t dvr_cleanup_threshold_free; - uint32_t dvr_cleanup_threshold_used; - int dvr_fetch_artwork; - int dvr_fetch_artwork_allow_unknown; - char *dvr_fetch_artwork_options; + int dvr_enabled; + int dvr_valid; + char* dvr_config_name; + char* dvr_comment; + profile_t* dvr_profile; + char* dvr_storage; + int dvr_pri; + int dvr_clone; + int dvr_complex_scheduling; + uint32_t dvr_rerecord_errors; + uint32_t dvr_retention_days; + uint32_t dvr_removal_days; + uint32_t dvr_removal_after_playback; + uint32_t dvr_autorec_max_count; + uint32_t dvr_autorec_max_sched_count; + char* dvr_charset; + char* dvr_charset_id; + char* dvr_preproc; + char* dvr_postproc; + char* dvr_postremove; + uint32_t dvr_warm_time; + uint32_t dvr_extra_time_pre; + uint32_t dvr_extra_time_post; + uint32_t dvr_update_window; + int dvr_running; + uint32_t dvr_cleanup_threshold_free; + uint32_t dvr_cleanup_threshold_used; + int dvr_fetch_artwork; + int dvr_fetch_artwork_allow_unknown; + char* dvr_fetch_artwork_options; muxer_config_t dvr_muxcnf; - char *dvr_pathname; - int dvr_pathname_changed; - - int dvr_dir_per_day; - int dvr_channel_dir; - int dvr_channel_in_title; - int dvr_omit_title; - int dvr_date_in_title; - int dvr_time_in_title; - int dvr_whitespace_in_title; - int dvr_title_dir; - int dvr_episode_in_title; - int dvr_clean_title; - int dvr_tag_files; - int dvr_skip_commercials; - int dvr_subtitle_in_title; - int dvr_windows_compatible_filenames; - char *dvr_format_tvmovies_subdir; - char *dvr_format_tvshows_subdir; - - struct dvr_entry_list dvr_entries; + char* dvr_pathname; + int dvr_pathname_changed; + + int dvr_dir_per_day; + int dvr_channel_dir; + int dvr_channel_in_title; + int dvr_omit_title; + int dvr_date_in_title; + int dvr_time_in_title; + int dvr_whitespace_in_title; + int dvr_title_dir; + int dvr_episode_in_title; + int dvr_clean_title; + int dvr_tag_files; + int dvr_skip_commercials; + int dvr_subtitle_in_title; + int dvr_windows_compatible_filenames; + char* dvr_format_tvmovies_subdir; + char* dvr_format_tvshows_subdir; + + struct dvr_entry_list dvr_entries; struct dvr_autorec_entry_list dvr_autorec_entries; struct dvr_timerec_entry_list dvr_timerec_entries; @@ -142,15 +142,14 @@ typedef enum { } dvr_prio_t; typedef enum { - DVR_SCHEDULED, /* Scheduled for recording (in the future) */ + DVR_SCHEDULED, /* Scheduled for recording (in the future) */ DVR_RECORDING, - DVR_COMPLETED, /* If recording failed, de->de_error is set to - a string */ + DVR_COMPLETED, /* If recording failed, de->de_error is set to + a string */ DVR_NOSTATE, DVR_MISSED_TIME, } dvr_entry_sched_state_t; - typedef enum { DVR_RS_PENDING, DVR_RS_WAIT_PROGRAM_START, @@ -170,15 +169,15 @@ typedef enum { DVR_RET_REM_1WEEK = 7, DVR_RET_REM_2WEEK = 14, DVR_RET_REM_3WEEK = 21, - DVR_RET_REM_1MONTH = (30+1), - DVR_RET_REM_2MONTH = (60+2), - DVR_RET_REM_3MONTH = (90+2), - DVR_RET_REM_6MONTH = (180+3), - DVR_RET_REM_1YEAR = (365+1), - DVR_RET_REM_2YEARS = (2*365+1), - DVR_RET_REM_3YEARS = (3*365+1), - DVR_RET_ONREMOVE = INT32_MAX-1, /* For retention only */ - DVR_REM_SPACE = INT32_MAX-1, /* For removal only */ + DVR_RET_REM_1MONTH = (30 + 1), + DVR_RET_REM_2MONTH = (60 + 2), + DVR_RET_REM_3MONTH = (90 + 2), + DVR_RET_REM_6MONTH = (180 + 3), + DVR_RET_REM_1YEAR = (365 + 1), + DVR_RET_REM_2YEARS = (2 * 365 + 1), + DVR_RET_REM_3YEARS = (3 * 365 + 1), + DVR_RET_ONREMOVE = INT32_MAX - 1, /* For retention only */ + DVR_REM_SPACE = INT32_MAX - 1, /* For removal only */ DVR_RET_REM_FOREVER = INT32_MAX } dvr_retention_removal_t; @@ -186,10 +185,9 @@ typedef struct dvr_entry { idnode_t de_id; - int de_refcnt; /* Modification is protected under global_lock */ + int de_refcnt; /* Modification is protected under global_lock */ int de_in_unsubscribe; - /** * Upon dvr_entry_remove() this fields will be invalidated (and pointers * NULLed) @@ -197,10 +195,10 @@ typedef struct dvr_entry { LIST_ENTRY(dvr_entry) de_global_link; - channel_t *de_channel; + channel_t* de_channel; LIST_ENTRY(dvr_entry) de_channel_link; - char *de_channel_name; + char* de_channel_name; gtimer_t de_timer; gtimer_t de_watched_timer; @@ -210,12 +208,12 @@ typedef struct dvr_entry { * These meta fields will stay valid as long as reference count > 0 */ - dvr_config_t *de_config; + dvr_config_t* de_config; LIST_ENTRY(dvr_entry) de_config_link; - int de_enabled; - time_t de_create; ///< Time entry was created - time_t de_watched; ///< Time entry was last watched + int de_enabled; + time_t de_create; ///< Time entry was created + time_t de_watched; ///< Time entry was last watched time_t de_start; time_t de_stop; @@ -228,34 +226,35 @@ typedef struct dvr_entry { time_t de_running_pause; int de_running_change; - char *de_owner; - char *de_creator; - char *de_comment; - char *de_uri; /* Programme unique ID */ - char *de_image; /* Programme Image */ - char *de_fanart_image; /* Programme fanart image */ - htsmsg_t *de_files; /* List of all used files */ - char *de_directory; /* Can be set for autorec entries, will override any - directory setting from the configuration */ - lang_str_t *de_title; /* Title in UTF-8 (from EPG) */ - lang_str_t *de_subtitle; /* Subtitle in UTF-8 (from EPG) */ - lang_str_t *de_summary; /* Summary in UTF-8 (from EPG) */ - lang_str_t *de_desc; /* Description in UTF-8 (from EPG) */ - uint32_t de_content_type; /* Content type (from EPG) (only code) */ - uint16_t de_copyright_year; /* Copyright year (from EPG) */ - uint16_t de_dvb_eid; - uint16_t de_age_rating; /* Age rating (from EPG) */ - //Depending how old the recording is, the current rating label system - //may have changed, so keep an absolute copy of the values at - //the time of recording rather than pointing to a rating label - //object that may no longer exist many years later. - char *de_rating_label_saved; /* Saved rating label for once the recording has been completed*/ - char *de_rating_icon_saved; /* Saved rating icon full path (not image cache) for once the recording has been completed*/ - ratinglabel_t *de_rating_label; /* 'Live' rating label object */ - - int de_pri; - int de_dont_reschedule; - int de_dont_rerecord; + char* de_owner; + char* de_creator; + char* de_comment; + char* de_uri; /* Programme unique ID */ + char* de_image; /* Programme Image */ + char* de_fanart_image; /* Programme fanart image */ + htsmsg_t* de_files; /* List of all used files */ + char* de_directory; /* Can be set for autorec entries, will override any + directory setting from the configuration */ + lang_str_t* de_title; /* Title in UTF-8 (from EPG) */ + lang_str_t* de_subtitle; /* Subtitle in UTF-8 (from EPG) */ + lang_str_t* de_summary; /* Summary in UTF-8 (from EPG) */ + lang_str_t* de_desc; /* Description in UTF-8 (from EPG) */ + uint32_t de_content_type; /* Content type (from EPG) (only code) */ + uint16_t de_copyright_year; /* Copyright year (from EPG) */ + uint16_t de_dvb_eid; + uint16_t de_age_rating; /* Age rating (from EPG) */ + // Depending how old the recording is, the current rating label system + // may have changed, so keep an absolute copy of the values at + // the time of recording rather than pointing to a rating label + // object that may no longer exist many years later. + char* de_rating_label_saved; /* Saved rating label for once the recording has been completed*/ + char* de_rating_icon_saved; /* Saved rating icon full path (not image cache) for once the + recording has been completed*/ + ratinglabel_t* de_rating_label; /* 'Live' rating label object */ + + int de_pri; + int de_dont_reschedule; + int de_dont_rerecord; uint32_t de_file_removed; uint32_t de_retention; uint32_t de_removal; @@ -266,7 +265,7 @@ typedef struct dvr_entry { * EPG information / links */ LIST_ENTRY(dvr_entry) de_bcast_link; - epg_broadcast_t *de_bcast; + epg_broadcast_t* de_bcast; epg_episode_num_t de_epnum; /** @@ -294,36 +293,35 @@ typedef struct dvr_entry { */ uint32_t de_last_error; - /** * Autorec linkage */ LIST_ENTRY(dvr_entry) de_autorec_link; - struct dvr_autorec_entry *de_autorec; + struct dvr_autorec_entry* de_autorec; /** * Timerec linkage */ - struct dvr_timerec_entry *de_timerec; + struct dvr_timerec_entry* de_timerec; /** * Parent/child */ - struct dvr_entry *de_parent; - struct dvr_entry *de_child; + struct dvr_entry* de_parent; + struct dvr_entry* de_child; /** * Fields for recording */ pthread_t de_thread; - int de_thread_shutdown; + int de_thread_shutdown; - th_subscription_t *de_s; + th_subscription_t* de_s; /** * Stream worker chain */ - profile_chain_t *de_chain; + profile_chain_t* de_chain; /** * Entry change notification timer @@ -337,34 +335,36 @@ typedef struct dvr_entry { } dvr_entry_t; -#define DVR_CH_NAME(e) \ - ((e)->de_channel == NULL ? (e)->de_channel_name : channel_get_name((e)->de_channel, channel_blank_name)) +#define DVR_CH_NAME(e) \ + ((e)->de_channel == NULL ? (e)->de_channel_name \ + : channel_get_name((e)->de_channel, channel_blank_name)) typedef enum { - DVR_AUTOREC_RECORD_ALL = 0, - DVR_AUTOREC_RECORD_UNIQUE = 14, /// Unique episode in EPG/XMLTV, typically used for movies/series, and not useful for news or sport. - DVR_AUTOREC_RECORD_DIFFERENT_EPISODE_NUMBER = 1, - DVR_AUTOREC_RECORD_DIFFERENT_SUBTITLE = 2, - DVR_AUTOREC_RECORD_DIFFERENT_DESCRIPTION = 3, - DVR_AUTOREC_RECORD_ONCE_PER_MONTH = 12, - DVR_AUTOREC_RECORD_ONCE_PER_WEEK = 4, - DVR_AUTOREC_RECORD_ONCE_PER_DAY = 5, + DVR_AUTOREC_RECORD_ALL = 0, + DVR_AUTOREC_RECORD_UNIQUE = 14, /// Unique episode in EPG/XMLTV, typically used for movies/series, + /// and not useful for news or sport. + DVR_AUTOREC_RECORD_DIFFERENT_EPISODE_NUMBER = 1, + DVR_AUTOREC_RECORD_DIFFERENT_SUBTITLE = 2, + DVR_AUTOREC_RECORD_DIFFERENT_DESCRIPTION = 3, + DVR_AUTOREC_RECORD_ONCE_PER_MONTH = 12, + DVR_AUTOREC_RECORD_ONCE_PER_WEEK = 4, + DVR_AUTOREC_RECORD_ONCE_PER_DAY = 5, DVR_AUTOREC_LRECORD_DIFFERENT_EPISODE_NUMBER = 6, - DVR_AUTOREC_LRECORD_DIFFERENT_TITLE = 7, - DVR_AUTOREC_LRECORD_DIFFERENT_SUBTITLE = 8, - DVR_AUTOREC_LRECORD_DIFFERENT_DESCRIPTION = 9, - DVR_AUTOREC_LRECORD_ONCE_PER_MONTH = 13, - DVR_AUTOREC_LRECORD_ONCE_PER_WEEK = 10, - DVR_AUTOREC_LRECORD_ONCE_PER_DAY = 11, - DVR_AUTOREC_RECORD_DVR_PROFILE = 15, + DVR_AUTOREC_LRECORD_DIFFERENT_TITLE = 7, + DVR_AUTOREC_LRECORD_DIFFERENT_SUBTITLE = 8, + DVR_AUTOREC_LRECORD_DIFFERENT_DESCRIPTION = 9, + DVR_AUTOREC_LRECORD_ONCE_PER_MONTH = 13, + DVR_AUTOREC_LRECORD_ONCE_PER_WEEK = 10, + DVR_AUTOREC_LRECORD_ONCE_PER_DAY = 11, + DVR_AUTOREC_RECORD_DVR_PROFILE = 15, /* first free value == 16 */ } dvr_autorec_dedup_t; typedef enum { - DVR_AUTOREC_BTYPE_ALL = 0, + DVR_AUTOREC_BTYPE_ALL = 0, DVR_AUTOREC_BTYPE_NEW_OR_UNKNOWN = 1, - DVR_AUTOREC_BTYPE_REPEAT = 2, - DVR_AUTOREC_BTYPE_NEW = 3, + DVR_AUTOREC_BTYPE_REPEAT = 2, + DVR_AUTOREC_BTYPE_NEW = 3, } dvr_autorec_btype_t; /** @@ -375,55 +375,55 @@ typedef struct dvr_autorec_entry { TAILQ_ENTRY(dvr_autorec_entry) dae_link; - char *dae_name; - char *dae_directory; - dvr_config_t *dae_config; + char* dae_name; + char* dae_directory; + dvr_config_t* dae_config; LIST_ENTRY(dvr_autorec_entry) dae_config_link; - int dae_enabled; - int dae_error; - char *dae_owner; - char *dae_creator; - char *dae_comment; + int dae_enabled; + int dae_error; + char* dae_owner; + char* dae_creator; + char* dae_comment; - char *dae_title; + char* dae_title; tvh_regex_t dae_title_regex; - int dae_fulltext; + int dae_fulltext; uint32_t dae_content_type; /* These categories (mainly from xmltv) such as Cooking, Dog racing, Movie. * This allows user to easily do filtering such as '"Movie" "Martial arts"' * or '"Children" "Animated" "Movie"' */ - char *dae_cat1; /** Simple single category from drop-down selection boxes */ - char *dae_cat2; /** Simple single category from drop-down selection boxes */ - char *dae_cat3; /** Simple single category from drop-down selection boxes */ - uint16_t dae_star_rating; /** Minimum star rating: we use u16 instead of u8 since no PT_U8 type */ + char* dae_cat1; /** Simple single category from drop-down selection boxes */ + char* dae_cat2; /** Simple single category from drop-down selection boxes */ + char* dae_cat3; /** Simple single category from drop-down selection boxes */ + uint16_t dae_star_rating; /** Minimum star rating: we use u16 instead of u8 since no PT_U8 type */ int dae_start; /* Minutes from midnight */ int dae_start_window; /* Minutes (duration) */ uint32_t dae_weekdays; - channel_t *dae_channel; + channel_t* dae_channel; LIST_ENTRY(dvr_autorec_entry) dae_channel_link; - channel_tag_t *dae_channel_tag; + channel_tag_t* dae_channel_tag; LIST_ENTRY(dvr_autorec_entry) dae_channel_tag_link; int dae_pri; struct dvr_entry_list dae_spawns; - const char *dae_serieslink_uri; + const char* dae_serieslink_uri; epg_episode_num_t dae_epnum; - int dae_minduration; - int dae_maxduration; - int dae_minyear; - int dae_maxyear; - int dae_minseason; - int dae_maxseason; + int dae_minduration; + int dae_maxduration; + int dae_minyear; + int dae_maxyear; + int dae_minseason; + int dae_maxseason; uint32_t dae_retention; uint32_t dae_removal; uint32_t dae_btype; @@ -447,29 +447,29 @@ typedef struct dvr_timerec_entry { TAILQ_ENTRY(dvr_timerec_entry) dte_link; - char *dte_name; - char *dte_directory; - dvr_config_t *dte_config; + char* dte_name; + char* dte_directory; + dvr_config_t* dte_config; LIST_ENTRY(dvr_timerec_entry) dte_config_link; - int dte_enabled; - char *dte_owner; - char *dte_creator; - char *dte_comment; + int dte_enabled; + char* dte_owner; + char* dte_creator; + char* dte_comment; - char *dte_title; + char* dte_title; - int dte_start; /* Minutes from midnight */ - int dte_stop; /* Minutes from midnight */ + int dte_start; /* Minutes from midnight */ + int dte_stop; /* Minutes from midnight */ uint32_t dte_weekdays; - channel_t *dte_channel; + channel_t* dte_channel; LIST_ENTRY(dvr_timerec_entry) dte_channel_link; int dte_pri; - dvr_entry_t *dte_spawn; + dvr_entry_t* dte_spawn; uint32_t dte_retention; uint32_t dte_removal; @@ -486,39 +486,41 @@ extern const idclass_t dvr_entry_class; extern const idclass_t dvr_autorec_entry_class; extern const idclass_t dvr_timerec_entry_class; -extern struct dvr_vfs_list dvrvfs_list; +extern struct dvr_vfs_list dvrvfs_list; extern struct dvr_config_list dvrconfigs; -extern struct dvr_entry_list dvrentries; +extern struct dvr_entry_list dvrentries; /** * Prototypes */ -static inline int dvr_config_is_valid(dvr_config_t *cfg) - { return cfg->dvr_valid; } +static inline int dvr_config_is_valid(dvr_config_t* cfg) { + return cfg->dvr_valid; +} -static inline int dvr_config_is_default(dvr_config_t *cfg) - { return tvh_str_default(cfg->dvr_config_name, NULL) == NULL; } +static inline int dvr_config_is_default(dvr_config_t* cfg) { + return tvh_str_default(cfg->dvr_config_name, NULL) == NULL; +} -dvr_config_t *dvr_config_find_by_name(const char *name); +dvr_config_t* dvr_config_find_by_name(const char* name); -dvr_config_t *dvr_config_find_by_name_default(const char *name); +dvr_config_t* dvr_config_find_by_name_default(const char* name); -dvr_config_t *dvr_config_find_by_list(htsmsg_t *list, const char *name); +dvr_config_t* dvr_config_find_by_list(htsmsg_t* list, const char* name); -dvr_config_t *dvr_config_create(const char *name, const char *uuid, htsmsg_t *conf); +dvr_config_t* dvr_config_create(const char* name, const char* uuid, htsmsg_t* conf); -static inline dvr_config_t *dvr_config_find_by_uuid(const char *uuid) - { return (dvr_config_t*)idnode_find(uuid, &dvr_config_class, NULL); } +static inline dvr_config_t* dvr_config_find_by_uuid(const char* uuid) { + return (dvr_config_t*)idnode_find(uuid, &dvr_config_class, NULL); +} -void dvr_config_delete(const char *name); +void dvr_config_delete(const char* name); -void dvr_config_changed(dvr_config_t *cfg); +void dvr_config_changed(dvr_config_t* cfg); -void dvr_config_destroy_by_profile(profile_t *pro, int delconf); +void dvr_config_destroy_by_profile(profile_t* pro, int delconf); -static inline uint32_t dvr_retention_cleanup(uint32_t val) -{ +static inline uint32_t dvr_retention_cleanup(uint32_t val) { return val > DVR_RET_REM_FOREVER ? DVR_RET_REM_FOREVER : val; } @@ -526,206 +528,216 @@ static inline uint32_t dvr_retention_cleanup(uint32_t val) * */ -uint32_t dvr_usage_count(access_t *aa); +uint32_t dvr_usage_count(access_t* aa); -static inline int dvr_entry_is_editable(dvr_entry_t *de) - { return de->de_sched_state == DVR_SCHEDULED; } +static inline int dvr_entry_is_editable(dvr_entry_t* de) { + return de->de_sched_state == DVR_SCHEDULED; +} -static inline int dvr_entry_is_valid(dvr_entry_t *de) - { return de->de_refcnt > 0; } +static inline int dvr_entry_is_valid(dvr_entry_t* de) { + return de->de_refcnt > 0; +} /// Does the user want fanart lookup for this entry? -int dvr_entry_allow_fanart_lookup(const dvr_entry_t *de); +int dvr_entry_allow_fanart_lookup(const dvr_entry_t* de); -static inline int dvr_entry_is_completed_ok(dvr_entry_t *de) - { assert(de->de_sched_state == DVR_COMPLETED); - return de->de_last_error == SM_CODE_OK || - de->de_last_error == SM_CODE_FORCE_OK || - de->de_last_error == SM_CODE_PREVIOUSLY_RECORDED; } +static inline int dvr_entry_is_completed_ok(dvr_entry_t* de) { + assert(de->de_sched_state == DVR_COMPLETED); + return de->de_last_error == SM_CODE_OK || de->de_last_error == SM_CODE_FORCE_OK || + de->de_last_error == SM_CODE_PREVIOUSLY_RECORDED; +} -char *dvr_entry_get_retention_string ( dvr_entry_t *de ); +char* dvr_entry_get_retention_string(dvr_entry_t* de); -char *dvr_entry_get_removal_string ( dvr_entry_t *de ); +char* dvr_entry_get_removal_string(dvr_entry_t* de); -uint32_t dvr_entry_get_retention_days( dvr_entry_t *de ); +uint32_t dvr_entry_get_retention_days(dvr_entry_t* de); -uint32_t dvr_entry_get_removal_days( dvr_entry_t *de ); +uint32_t dvr_entry_get_removal_days(dvr_entry_t* de); -uint32_t dvr_entry_get_rerecord_errors( dvr_entry_t *de ); +uint32_t dvr_entry_get_rerecord_errors(dvr_entry_t* de); -int dvr_entry_get_epg_running( dvr_entry_t *de ); +int dvr_entry_get_epg_running(dvr_entry_t* de); -time_t dvr_entry_get_start_time( dvr_entry_t *de, int warm ); +time_t dvr_entry_get_start_time(dvr_entry_t* de, int warm); -time_t dvr_entry_get_stop_time( dvr_entry_t *de ); +time_t dvr_entry_get_stop_time(dvr_entry_t* de); -time_t dvr_entry_get_extra_time_post( dvr_entry_t *de ); +time_t dvr_entry_get_extra_time_post(dvr_entry_t* de); -time_t dvr_entry_get_extra_time_pre( dvr_entry_t *de ); +time_t dvr_entry_get_extra_time_pre(dvr_entry_t* de); void dvr_entry_init(void); void dvr_entry_done(void); -void dvr_entry_destroy_by_config(dvr_config_t *cfg, int delconf); +void dvr_entry_destroy_by_config(dvr_config_t* cfg, int delconf); -int dvr_entry_set_state(dvr_entry_t *de, dvr_entry_sched_state_t state, - dvr_rs_state_t rec_state, int error_code); +int dvr_entry_set_state(dvr_entry_t* de, + dvr_entry_sched_state_t state, + dvr_rs_state_t rec_state, + int error_code); -int dvr_entry_set_playcount(dvr_entry_t *de, uint32_t playcount); -int dvr_entry_incr_playcount(dvr_entry_t *de); +int dvr_entry_set_playcount(dvr_entry_t* de, uint32_t playcount); +int dvr_entry_incr_playcount(dvr_entry_t* de); -const char *dvr_entry_status(dvr_entry_t *de); +const char* dvr_entry_status(dvr_entry_t* de); -const char *dvr_entry_schedstatus(dvr_entry_t *de); +const char* dvr_entry_schedstatus(dvr_entry_t* de); -void dvr_entry_create_by_autorec(int enabled, epg_broadcast_t *e, dvr_autorec_entry_t *dae); +void dvr_entry_create_by_autorec(int enabled, epg_broadcast_t* e, dvr_autorec_entry_t* dae); -void dvr_entry_created(dvr_entry_t *de); +void dvr_entry_created(dvr_entry_t* de); -dvr_entry_t * -dvr_entry_clone ( dvr_entry_t *de ); +dvr_entry_t* dvr_entry_clone(dvr_entry_t* de); -dvr_entry_t * -dvr_entry_create ( const char *uuid, htsmsg_t *conf, int clone ); +dvr_entry_t* dvr_entry_create(const char* uuid, htsmsg_t* conf, int clone); -dvr_entry_t * -dvr_entry_create_from_htsmsg( htsmsg_t *conf, epg_broadcast_t *e ); +dvr_entry_t* dvr_entry_create_from_htsmsg(htsmsg_t* conf, epg_broadcast_t* e); -dvr_entry_t * -dvr_entry_update( dvr_entry_t *de, int enabled, - const char *dvr_config_uuid, channel_t *ch, - const char *title, const char *subtitle, - const char *summary, const char *desc, const char *lang, - time_t start, time_t stop, - time_t start_extra, time_t stop_extra, - dvr_prio_t pri, int retention, int removal, - int playcount, int playposition, int age_rating, - ratinglabel_t *rating_label); +dvr_entry_t* dvr_entry_update(dvr_entry_t* de, + int enabled, + const char* dvr_config_uuid, + channel_t* ch, + const char* title, + const char* subtitle, + const char* summary, + const char* desc, + const char* lang, + time_t start, + time_t stop, + time_t start_extra, + time_t stop_extra, + dvr_prio_t pri, + int retention, + int removal, + int playcount, + int playposition, + int age_rating, + ratinglabel_t* rating_label); -void dvr_destroy_by_channel(channel_t *ch, int delconf); +void dvr_destroy_by_channel(channel_t* ch, int delconf); -void dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf, int clone); +void dvr_stop_recording(dvr_entry_t* de, int stopcode, int saveconf, int clone); -int dvr_rec_subscribe(dvr_entry_t *de); +int dvr_rec_subscribe(dvr_entry_t* de); -void dvr_rec_unsubscribe(dvr_entry_t *de); +void dvr_rec_unsubscribe(dvr_entry_t* de); -void dvr_rec_migrate(dvr_entry_t *de_old, dvr_entry_t *de_new); +void dvr_rec_migrate(dvr_entry_t* de_old, dvr_entry_t* de_new); -void dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e); +void dvr_event_replaced(epg_broadcast_t* e, epg_broadcast_t* new_e); -void dvr_event_removed(epg_broadcast_t *e); +void dvr_event_removed(epg_broadcast_t* e); -void dvr_event_updated(epg_broadcast_t *e); +void dvr_event_updated(epg_broadcast_t* e); -void dvr_event_running(epg_broadcast_t *e, epg_running_t running); -int dvr_entry_assign_broadcast(dvr_entry_t *de, epg_broadcast_t *bcast); +void dvr_event_running(epg_broadcast_t* e, epg_running_t running); +int dvr_entry_assign_broadcast(dvr_entry_t* de, epg_broadcast_t* bcast); -dvr_entry_t *dvr_entry_find_by_id(int id); +dvr_entry_t* dvr_entry_find_by_id(int id); -static inline dvr_entry_t *dvr_entry_find_by_uuid(const char *uuid) - { return (dvr_entry_t*)idnode_find(uuid, &dvr_entry_class, NULL); } +static inline dvr_entry_t* dvr_entry_find_by_uuid(const char* uuid) { + return (dvr_entry_t*)idnode_find(uuid, &dvr_entry_class, NULL); +} -dvr_entry_t *dvr_entry_find_by_event_fuzzy(epg_broadcast_t *e); +dvr_entry_t* dvr_entry_find_by_event_fuzzy(epg_broadcast_t* e); -const char *dvr_get_filename(dvr_entry_t *de); +const char* dvr_get_filename(dvr_entry_t* de); -int64_t dvr_get_filesize(dvr_entry_t *de, int flags); +int64_t dvr_get_filesize(dvr_entry_t* de, int flags); -int64_t dvr_entry_claenup(dvr_entry_t *de, int64_t requiredBytes); +int64_t dvr_entry_claenup(dvr_entry_t* de, int64_t requiredBytes); -void dvr_entry_set_rerecord(dvr_entry_t *de, int cmd); +void dvr_entry_set_rerecord(dvr_entry_t* de, int cmd); -void dvr_entry_move(dvr_entry_t *de, int to_failed); +void dvr_entry_move(dvr_entry_t* de, int to_failed); -dvr_entry_t *dvr_entry_stop(dvr_entry_t *de); +dvr_entry_t* dvr_entry_stop(dvr_entry_t* de); -dvr_entry_t *dvr_entry_cancel(dvr_entry_t *de, int rerecord); +dvr_entry_t* dvr_entry_cancel(dvr_entry_t* de, int rerecord); -void dvr_entry_dec_ref(dvr_entry_t *de); +void dvr_entry_dec_ref(dvr_entry_t* de); -int dvr_entry_delete(dvr_entry_t *de); +int dvr_entry_delete(dvr_entry_t* de); -void dvr_entry_cancel_delete(dvr_entry_t *de, int rerecord); +void dvr_entry_cancel_delete(dvr_entry_t* de, int rerecord); -void dvr_entry_cancel_remove(dvr_entry_t *de, int rerecord); +void dvr_entry_cancel_remove(dvr_entry_t* de, int rerecord); -void dvr_entry_set_prevrec(dvr_entry_t *de, int cmd); +void dvr_entry_set_prevrec(dvr_entry_t* de, int cmd); -int dvr_entry_file_moved(const char *src, const char *dst); +int dvr_entry_file_moved(const char* src, const char* dst); -void dvr_entry_destroy(dvr_entry_t *de, int delconf); +void dvr_entry_destroy(dvr_entry_t* de, int delconf); -htsmsg_t *dvr_entry_class_mc_list (void *o, const char *lang); -htsmsg_t *dvr_entry_class_pri_list(void *o, const char *lang); -htsmsg_t *dvr_entry_class_config_name_list(void *o, const char *lang); -htsmsg_t *dvr_entry_class_duration_list(void *o, const char *not_set, int max, int step, const char *lang); -htsmsg_t *dvr_entry_class_retention_list ( void *o, const char *lang ); -htsmsg_t *dvr_entry_class_removal_list ( void *o, const char *lang ); +htsmsg_t* dvr_entry_class_mc_list(void* o, const char* lang); +htsmsg_t* dvr_entry_class_pri_list(void* o, const char* lang); +htsmsg_t* dvr_entry_class_config_name_list(void* o, const char* lang); +htsmsg_t* +dvr_entry_class_duration_list(void* o, const char* not_set, int max, int step, const char* lang); +htsmsg_t* dvr_entry_class_retention_list(void* o, const char* lang); +htsmsg_t* dvr_entry_class_removal_list(void* o, const char* lang); -int dvr_entry_is_upcoming(dvr_entry_t *entry); -int dvr_entry_is_upcoming_nodup(dvr_entry_t *entry); -int dvr_entry_is_finished(dvr_entry_t *entry, int flags); -int dvr_entry_verify(dvr_entry_t *de, access_t *a, int readonly); +int dvr_entry_is_upcoming(dvr_entry_t* entry); +int dvr_entry_is_upcoming_nodup(dvr_entry_t* entry); +int dvr_entry_is_finished(dvr_entry_t* entry, int flags); +int dvr_entry_verify(dvr_entry_t* de, access_t* a, int readonly); -void dvr_entry_changed(dvr_entry_t *de); +void dvr_entry_changed(dvr_entry_t* de); -void dvr_spawn_cmd(dvr_entry_t *de, const char *cmd, const char *filename, int pre); +void dvr_spawn_cmd(dvr_entry_t* de, const char* cmd, const char* filename, int pre); /// Spawn a fetch of artwork for the entry. -void dvr_spawn_fetch_artwork(dvr_entry_t *de); +void dvr_spawn_fetch_artwork(dvr_entry_t* de); -void dvr_vfs_refresh_entry(dvr_entry_t *de); -void dvr_vfs_remove_entry(dvr_entry_t *de); -int64_t dvr_vfs_update_filename(const char *filename, htsmsg_t *fdata); -int dvr_vfs_rec_start_check(dvr_config_t *cfg); +void dvr_vfs_refresh_entry(dvr_entry_t* de); +void dvr_vfs_remove_entry(dvr_entry_t* de); +int64_t dvr_vfs_update_filename(const char* filename, htsmsg_t* fdata); +int dvr_vfs_rec_start_check(dvr_config_t* cfg); void dvr_disk_space_boot(void); void dvr_disk_space_init(void); void dvr_disk_space_done(void); -int dvr_get_disk_space(int64_t *bfree, int64_t *bused, int64_t *btotal); +int dvr_get_disk_space(int64_t* bfree, int64_t* bused, int64_t* btotal); /** * */ -dvr_autorec_entry_t * -dvr_autorec_create(const char *uuid, htsmsg_t *conf); - -dvr_autorec_entry_t * -dvr_autorec_create_htsp(htsmsg_t *conf); +dvr_autorec_entry_t* dvr_autorec_create(const char* uuid, htsmsg_t* conf); -void dvr_autorec_update_htsp(dvr_autorec_entry_t *dae, htsmsg_t *conf); +dvr_autorec_entry_t* dvr_autorec_create_htsp(htsmsg_t* conf); -dvr_autorec_entry_t * -dvr_autorec_add_series_link(const char *dvr_config_name, - epg_broadcast_t *event, - const char *owner, const char *creator, - const char *comment); +void dvr_autorec_update_htsp(dvr_autorec_entry_t* dae, htsmsg_t* conf); -void dvr_autorec_changed(dvr_autorec_entry_t *dae, int purge); +dvr_autorec_entry_t* dvr_autorec_add_series_link(const char* dvr_config_name, + epg_broadcast_t* event, + const char* owner, + const char* creator, + const char* comment); -static inline dvr_autorec_entry_t * -dvr_autorec_find_by_uuid(const char *uuid) - { return (dvr_autorec_entry_t*)idnode_find(uuid, &dvr_autorec_entry_class, NULL); } +void dvr_autorec_changed(dvr_autorec_entry_t* dae, int purge); +static inline dvr_autorec_entry_t* dvr_autorec_find_by_uuid(const char* uuid) { + return (dvr_autorec_entry_t*)idnode_find(uuid, &dvr_autorec_entry_class, NULL); +} -htsmsg_t * dvr_autorec_entry_class_time_list(void *o, const char *null); -htsmsg_t * dvr_autorec_entry_class_weekdays_get(uint32_t weekdays); -htsmsg_t * dvr_autorec_entry_class_weekdays_list (void *o, const char *list); -char * dvr_autorec_entry_class_weekdays_rend(uint32_t weekdays, const char *lang); -const char *dvr_entry_get_image(const dvr_entry_t *o); -const char *dvr_entry_get_fanart_image(const dvr_entry_t *o); +htsmsg_t* dvr_autorec_entry_class_time_list(void* o, const char* null); +htsmsg_t* dvr_autorec_entry_class_weekdays_get(uint32_t weekdays); +htsmsg_t* dvr_autorec_entry_class_weekdays_list(void* o, const char* list); +char* dvr_autorec_entry_class_weekdays_rend(uint32_t weekdays, const char* lang); +const char* dvr_entry_get_image(const dvr_entry_t* o); +const char* dvr_entry_get_fanart_image(const dvr_entry_t* o); -void dvr_autorec_check_event(epg_broadcast_t *e); +void dvr_autorec_check_event(epg_broadcast_t* e); -void autorec_destroy_by_config(dvr_config_t *cfg, int delconf); +void autorec_destroy_by_config(dvr_config_t* cfg, int delconf); -void autorec_destroy_by_channel(channel_t *ch, int delconf); +void autorec_destroy_by_channel(channel_t* ch, int delconf); -void autorec_destroy_by_channel_tag(channel_tag_t *ct, int delconf); +void autorec_destroy_by_channel_tag(channel_tag_t* ct, int delconf); -void autorec_destroy_by_id(const char *id, int delconf); +void autorec_destroy_by_id(const char* id, int delconf); void dvr_autorec_init(void); @@ -736,15 +748,13 @@ void dvr_autorec_update(void); void dvr_autorec_async_reschedule(void); /* @return 1 if the event 'e' is matched by the autorec rule 'dae' */ -int dvr_autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e); +int dvr_autorec_cmp(dvr_autorec_entry_t* dae, epg_broadcast_t* e); /* Purge any autorec timers that are obsolete since they no longer match any events. */ void dvr_autorec_purge_obsolete_timers(void); /* @return 1 if entry is an autorec and can be purged since it no longer matches its event. */ -int dvr_autorec_entry_can_be_purged(const dvr_entry_t *de); +int dvr_autorec_entry_can_be_purged(const dvr_entry_t* de); -static inline int - dvr_autorec_entry_verify(dvr_autorec_entry_t *dae, access_t *a, int readonly) -{ +static inline int dvr_autorec_entry_verify(dvr_autorec_entry_t* dae, access_t* a, int readonly) { if (readonly && !access_verify2(a, ACCESS_ALL_RECORDER)) return 0; if (!access_verify2(a, ACCESS_ALL_RW_RECORDER)) @@ -754,42 +764,39 @@ static inline int return 0; } -uint32_t dvr_autorec_get_retention_days( dvr_autorec_entry_t *dae ); +uint32_t dvr_autorec_get_retention_days(dvr_autorec_entry_t* dae); -uint32_t dvr_autorec_get_removal_days( dvr_autorec_entry_t *dae ); +uint32_t dvr_autorec_get_removal_days(dvr_autorec_entry_t* dae); -int dvr_autorec_get_extra_time_post( dvr_autorec_entry_t *dae ); +int dvr_autorec_get_extra_time_post(dvr_autorec_entry_t* dae); -int dvr_autorec_get_extra_time_pre( dvr_autorec_entry_t *dae ); +int dvr_autorec_get_extra_time_pre(dvr_autorec_entry_t* dae); -void dvr_autorec_completed( dvr_autorec_entry_t *dae, int error_code ); +void dvr_autorec_completed(dvr_autorec_entry_t* dae, int error_code); -uint32_t dvr_autorec_get_max_sched_count(dvr_autorec_entry_t *dae); +uint32_t dvr_autorec_get_max_sched_count(dvr_autorec_entry_t* dae); /** * */ -dvr_timerec_entry_t * -dvr_timerec_create(const char *uuid, htsmsg_t *conf); - -dvr_timerec_entry_t* -dvr_timerec_create_htsp(htsmsg_t *conf); +dvr_timerec_entry_t* dvr_timerec_create(const char* uuid, htsmsg_t* conf); -void dvr_timerec_update_htsp(dvr_timerec_entry_t *dte, htsmsg_t *conf); +dvr_timerec_entry_t* dvr_timerec_create_htsp(htsmsg_t* conf); -static inline dvr_timerec_entry_t * -dvr_timerec_find_by_uuid(const char *uuid) - { return (dvr_timerec_entry_t*)idnode_find(uuid, &dvr_timerec_entry_class, NULL); } +void dvr_timerec_update_htsp(dvr_timerec_entry_t* dte, htsmsg_t* conf); +static inline dvr_timerec_entry_t* dvr_timerec_find_by_uuid(const char* uuid) { + return (dvr_timerec_entry_t*)idnode_find(uuid, &dvr_timerec_entry_class, NULL); +} -void dvr_timerec_check(dvr_timerec_entry_t *dae); +void dvr_timerec_check(dvr_timerec_entry_t* dae); -void timerec_destroy_by_config(dvr_config_t *cfg, int delconf); +void timerec_destroy_by_config(dvr_config_t* cfg, int delconf); -void timerec_destroy_by_channel(channel_t *ch, int delconf); +void timerec_destroy_by_channel(channel_t* ch, int delconf); -void timerec_destroy_by_id(const char *id, int delconf); +void timerec_destroy_by_id(const char* id, int delconf); void dvr_timerec_init(void); @@ -797,9 +804,7 @@ void dvr_timerec_done(void); void dvr_timerec_update(void); -static inline int dvr_timerec_entry_verify - (dvr_timerec_entry_t *dte, access_t *a, int readonly) -{ +static inline int dvr_timerec_entry_verify(dvr_timerec_entry_t* dte, access_t* a, int readonly) { if (readonly && !access_verify2(a, ACCESS_ALL_RECORDER)) return 0; if (!access_verify2(a, ACCESS_ALL_RW_RECORDER)) @@ -809,18 +814,18 @@ static inline int dvr_timerec_entry_verify return 0; } -uint32_t dvr_timerec_get_retention_days( dvr_timerec_entry_t *dte ); +uint32_t dvr_timerec_get_retention_days(dvr_timerec_entry_t* dte); -uint32_t dvr_timerec_get_removal_days( dvr_timerec_entry_t *dte ); +uint32_t dvr_timerec_get_removal_days(dvr_timerec_entry_t* dte); /** * Inotify support */ -void dvr_inotify_init ( void ); -void dvr_inotify_done ( void ); -void dvr_inotify_add ( dvr_entry_t *de ); -void dvr_inotify_del ( dvr_entry_t *de ); -int dvr_inotify_count( void ); +void dvr_inotify_init(void); +void dvr_inotify_done(void); +void dvr_inotify_add(dvr_entry_t* de); +void dvr_inotify_del(dvr_entry_t* de); +int dvr_inotify_count(void); /** * Cutpoints support @@ -830,49 +835,46 @@ typedef struct dvr_cutpoint { TAILQ_ENTRY(dvr_cutpoint) dc_link; uint64_t dc_start_ms; uint64_t dc_end_ms; - enum { - DVR_CP_CUT, - DVR_CP_MUTE, - DVR_CP_SCENE, - DVR_CP_COMM - } dc_type; + enum { DVR_CP_CUT, DVR_CP_MUTE, DVR_CP_SCENE, DVR_CP_COMM } dc_type; } dvr_cutpoint_t; -typedef TAILQ_HEAD(,dvr_cutpoint) dvr_cutpoint_list_t; +typedef TAILQ_HEAD(, dvr_cutpoint) dvr_cutpoint_list_t; -dvr_cutpoint_list_t *dvr_get_cutpoint_list (dvr_entry_t *de); -void dvr_cutpoint_list_destroy (dvr_cutpoint_list_t *list); +dvr_cutpoint_list_t* dvr_get_cutpoint_list(dvr_entry_t* de); +void dvr_cutpoint_list_destroy(dvr_cutpoint_list_t* list); /** * */ -const char *dvr_entry_sched_state2str(dvr_entry_sched_state_t s); -const char *dvr_entry_rs_state2str(dvr_rs_state_t s); +const char* dvr_entry_sched_state2str(dvr_entry_sched_state_t s); +const char* dvr_entry_rs_state2str(dvr_rs_state_t s); -void dvr_entry_trace_(const char *file, int line, - dvr_entry_t *de, const char *fmt, ...); +void dvr_entry_trace_(const char* file, int line, dvr_entry_t* de, const char* fmt, ...); -void dvr_entry_trace_time2_(const char *file, int line, - dvr_entry_t *de, - const char *t1name, time_t t1, - const char *t2name, time_t t2, - const char *fmt, ...); +void dvr_entry_trace_time2_(const char* file, + int line, + dvr_entry_t* de, + const char* t1name, + time_t t1, + const char* t2name, + time_t t2, + const char* fmt, + ...); -#define dvr_entry_trace(de, fmt, ...) \ - do { \ - if (tvhtrace_enabled()) \ +#define dvr_entry_trace(de, fmt, ...) \ + do { \ + if (tvhtrace_enabled()) \ dvr_entry_trace_(__FILE__, __LINE__, de, fmt, ##__VA_ARGS__); \ } while (0) #define dvr_entry_trace_time1(de, t1name, t1, fmt, ...) \ dvr_entry_trace_time2(de, t1name, t1, NULL, 0, fmt, ##__VA_ARGS__) -#define dvr_entry_trace_time2(de, t1name, t1, t2name, t2, fmt, ...) \ - do { \ - if (tvhtrace_enabled()) \ - dvr_entry_trace_time2_(__FILE__, __LINE__, de, t1name, t1, \ - t2name, t2, fmt, ##__VA_ARGS__); \ +#define dvr_entry_trace_time2(de, t1name, t1, t2name, t2, fmt, ...) \ + do { \ + if (tvhtrace_enabled()) \ + dvr_entry_trace_time2_(__FILE__, __LINE__, de, t1name, t1, t2name, t2, fmt, ##__VA_ARGS__); \ } while (0) /** diff --git a/src/dvr/dvr_autorec.c b/src/dvr/dvr_autorec.c index 59f5108f0..1c0e74c73 100644 --- a/src/dvr/dvr_autorec.c +++ b/src/dvr/dvr_autorec.c @@ -27,8 +27,7 @@ struct dvr_autorec_entry_queue autorec_entries; -static void autorec_regfree(dvr_autorec_entry_t *dae) -{ +static void autorec_regfree(dvr_autorec_entry_t* dae) { if (dae->dae_title) { regex_free(&dae->dae_title_regex); free(dae->dae_title); @@ -39,8 +38,7 @@ static void autorec_regfree(dvr_autorec_entry_t *dae) /* * */ -static uint32_t dvr_autorec_get_max_count(dvr_autorec_entry_t *dae) -{ +static uint32_t dvr_autorec_get_max_count(dvr_autorec_entry_t* dae) { uint32_t max_count = dae->dae_max_count; if (max_count == 0) max_count = dae->dae_config ? dae->dae_config->dvr_autorec_max_count : 0; @@ -50,8 +48,7 @@ static uint32_t dvr_autorec_get_max_count(dvr_autorec_entry_t *dae) /* * */ -uint32_t dvr_autorec_get_max_sched_count(dvr_autorec_entry_t *dae) -{ +uint32_t dvr_autorec_get_max_sched_count(dvr_autorec_entry_t* dae) { uint32_t max_count = dae->dae_max_sched_count; if (max_count == 0) max_count = dae->dae_config ? dae->dae_config->dvr_autorec_max_sched_count : 0; @@ -61,21 +58,20 @@ uint32_t dvr_autorec_get_max_sched_count(dvr_autorec_entry_t *dae) /** * Unlink - and remove any unstarted */ -static epg_broadcast_t ** -dvr_autorec_purge_spawns(dvr_autorec_entry_t *dae, int del, int disabled) -{ - dvr_entry_t *de; +static epg_broadcast_t** dvr_autorec_purge_spawns(dvr_autorec_entry_t* dae, int del, int disabled) { + dvr_entry_t* de; epg_broadcast_t **bcast = NULL, **nbcast; - int i = 0, size = 0; + int i = 0, size = 0; - while((de = LIST_FIRST(&dae->dae_spawns)) != NULL) { + while ((de = LIST_FIRST(&dae->dae_spawns)) != NULL) { LIST_REMOVE(de, de_autorec_link); de->de_autorec = NULL; - if (!del) continue; + if (!del) + continue; if (de->de_sched_state == DVR_SCHEDULED) { if (disabled && !de->de_enabled && de->de_bcast) { if (i >= size - 1) { - nbcast = realloc(bcast, (size + 16) * sizeof(epg_broadcast_t *)); + nbcast = realloc(bcast, (size + 16) * sizeof(epg_broadcast_t*)); if (nbcast != NULL) { bcast = nbcast; size += 16; @@ -94,14 +90,11 @@ dvr_autorec_purge_spawns(dvr_autorec_entry_t *dae, int del, int disabled) return bcast; } - /** * If autorec entry no longer matches autorec rule then it can be purged. * @return 1 if it can be purged */ -int -dvr_autorec_entry_can_be_purged(const dvr_entry_t *de) -{ +int dvr_autorec_entry_can_be_purged(const dvr_entry_t* de) { /* Not an autorec so ignore */ if (!de->de_autorec) return 0; @@ -122,21 +115,20 @@ dvr_autorec_entry_can_be_purged(const dvr_entry_t *de) * Purge any dvr_entry for autorec entries that * no longer match the current schedule. */ -void -dvr_autorec_purge_obsolete_timers(void) -{ - dvr_entry_t *de; - int num_purged = 0; +void dvr_autorec_purge_obsolete_timers(void) { + dvr_entry_t* de; + int num_purged = 0; - LIST_FOREACH(de, &dvrentries, de_global_link) { + LIST_FOREACH (de, &dvrentries, de_global_link) { if (dvr_autorec_entry_can_be_purged(de)) { char ubuf[UUID_HEX_SIZE]; char t1buf[32], t2buf[32]; - tvhinfo(LS_DVR, "Entry %s can be purged for \"%s\" start %s stop %s", - idnode_uuid_as_str(&de->de_id, ubuf), - lang_str_get(de->de_title, NULL), - gmtime2local(de->de_start, t1buf, sizeof(t1buf)), - gmtime2local(de->de_stop, t2buf, sizeof(t2buf))); + tvhinfo(LS_DVR, + "Entry %s can be purged for \"%s\" start %s stop %s", + idnode_uuid_as_str(&de->de_id, ubuf), + lang_str_get(de->de_title, NULL), + gmtime2local(de->de_start, t1buf, sizeof(t1buf)), + gmtime2local(de->de_stop, t2buf, sizeof(t2buf))); dvr_entry_assign_broadcast(de, NULL); dvr_entry_destroy(de, 1); @@ -147,27 +139,28 @@ dvr_autorec_purge_obsolete_timers(void) tvhinfo(LS_DVR, "Purged %d autorec entries that no longer match schedule", num_purged); } - /** * Handle maxcount */ -void -dvr_autorec_completed(dvr_autorec_entry_t *dae, int error_code) -{ - uint32_t count, total = 0; +void dvr_autorec_completed(dvr_autorec_entry_t* dae, int error_code) { + uint32_t count, total = 0; dvr_entry_t *de, *de_prev; - uint32_t max_count; - char ubuf[UUID_HEX_SIZE]; + uint32_t max_count; + char ubuf[UUID_HEX_SIZE]; - if (dae == NULL) return; + if (dae == NULL) + return; max_count = dvr_autorec_get_max_count(dae); - if (max_count <= 0) return; + if (max_count <= 0) + return; while (1) { - count = 0; + count = 0; de_prev = NULL; - LIST_FOREACH(de, &dae->dae_spawns, de_autorec_link) { - if (de->de_sched_state != DVR_COMPLETED) continue; - if (dvr_get_filesize(de, 0) < 0) continue; + LIST_FOREACH (de, &dae->dae_spawns, de_autorec_link) { + if (de->de_sched_state != DVR_COMPLETED) + continue; + if (dvr_get_filesize(de, 0) < 0) + continue; if (de_prev == NULL || de_prev->de_start > de->de_start) de_prev = de; count++; @@ -177,8 +170,12 @@ dvr_autorec_completed(dvr_autorec_entry_t *dae, int error_code) if (count <= max_count) break; if (de_prev) { - tvhinfo(LS_DVR, "autorec %s removing recordings %s (allowed count %u total %u)", - dae->dae_name, idnode_uuid_as_str(&de_prev->de_id, ubuf), max_count, total); + tvhinfo(LS_DVR, + "autorec %s removing recordings %s (allowed count %u total %u)", + dae->dae_name, + idnode_uuid_as_str(&de_prev->de_id, ubuf), + max_count, + total); dvr_entry_cancel_remove(de_prev, 0); } } @@ -187,41 +184,34 @@ dvr_autorec_completed(dvr_autorec_entry_t *dae, int error_code) /** * return 1 if the event 'e' is matched by the autorec rule 'dae' */ -int -dvr_autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e) -{ - idnode_list_mapping_t *ilm; - dvr_config_t *cfg; - double duration; - - if (!e) return 0; - if (!e->channel) return 0; - if(dae->dae_enabled == 0 || dae->dae_weekdays == 0) +int dvr_autorec_cmp(dvr_autorec_entry_t* dae, epg_broadcast_t* e) { + idnode_list_mapping_t* ilm; + dvr_config_t* cfg; + double duration; + + if (!e) + return 0; + if (!e->channel) + return 0; + if (dae->dae_enabled == 0 || dae->dae_weekdays == 0) return 0; - if(dae->dae_channel == NULL && - dae->dae_channel_tag == NULL && - dae->dae_content_type == 0 && - (dae->dae_title == NULL || - dae->dae_title[0] == '\0') && - (dae->dae_cat1 == NULL || *dae->dae_cat1 == 0) && - (dae->dae_cat2 == NULL || *dae->dae_cat2 == 0) && - (dae->dae_cat3 == NULL || *dae->dae_cat3 == 0) && - dae->dae_minduration <= 0 && - (dae->dae_maxduration <= 0 || dae->dae_maxduration > 24 * 3600) && - dae->dae_minyear <= 0 && - dae->dae_maxyear <= 0 && - dae->dae_minseason <= 0 && - dae->dae_maxseason <= 0 && - dae->dae_serieslink_uri == NULL) + if (dae->dae_channel == NULL && dae->dae_channel_tag == NULL && dae->dae_content_type == 0 && + (dae->dae_title == NULL || dae->dae_title[0] == '\0') && + (dae->dae_cat1 == NULL || *dae->dae_cat1 == 0) && + (dae->dae_cat2 == NULL || *dae->dae_cat2 == 0) && + (dae->dae_cat3 == NULL || *dae->dae_cat3 == 0) && dae->dae_minduration <= 0 && + (dae->dae_maxduration <= 0 || dae->dae_maxduration > 24 * 3600) && dae->dae_minyear <= 0 && + dae->dae_maxyear <= 0 && dae->dae_minseason <= 0 && dae->dae_maxseason <= 0 && + dae->dae_serieslink_uri == NULL) return 0; // Avoid super wildcard match - if(dae->dae_serieslink_uri) { - if (!e->serieslink || - strcmp(dae->dae_serieslink_uri ?: "", e->serieslink->uri)) return 0; + if (dae->dae_serieslink_uri) { + if (!e->serieslink || strcmp(dae->dae_serieslink_uri ?: "", e->serieslink->uri)) + return 0; } - if(dae->dae_btype != DVR_AUTOREC_BTYPE_ALL) { + if (dae->dae_btype != DVR_AUTOREC_BTYPE_ALL) { if (dae->dae_btype == DVR_AUTOREC_BTYPE_NEW_OR_UNKNOWN && e->is_repeat) return 0; else if (dae->dae_btype == DVR_AUTOREC_BTYPE_NEW && !e->is_new) @@ -233,23 +223,22 @@ dvr_autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e) /* Note: ignore channel test if we allow quality unlocking */ if ((cfg = dae->dae_config) == NULL) return 0; - if(dae->dae_channel != NULL) { - if (dae->dae_channel != e->channel && - dae->dae_channel->ch_enabled) + if (dae->dae_channel != NULL) { + if (dae->dae_channel != e->channel && dae->dae_channel->ch_enabled) return 0; if (!dae->dae_channel->ch_enabled) return 0; } - if(dae->dae_channel_tag != NULL) { - LIST_FOREACH(ilm, &dae->dae_channel_tag->ct_ctms, ilm_in1_link) - if((channel_t *)ilm->ilm_in2 == e->channel) - break; - if(ilm == NULL) + if (dae->dae_channel_tag != NULL) { + LIST_FOREACH (ilm, &dae->dae_channel_tag->ct_ctms, ilm_in1_link) + if ((channel_t*)ilm->ilm_in2 == e->channel) + break; + if (ilm == NULL) return 0; } - if(dae->dae_content_type != 0) { + if (dae->dae_content_type != 0) { epg_genre_t ct; memset(&ct, 0, sizeof(ct)); ct.code = dae->dae_content_type; @@ -258,55 +247,53 @@ dvr_autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e) } if (e->category) { - if (dae->dae_cat1 && *dae->dae_cat1 && - !string_list_contains_string(e->category, dae->dae_cat1)) + if (dae->dae_cat1 && *dae->dae_cat1 && !string_list_contains_string(e->category, dae->dae_cat1)) return 0; - if (dae->dae_cat2 && *dae->dae_cat2 && - !string_list_contains_string(e->category, dae->dae_cat2)) + if (dae->dae_cat2 && *dae->dae_cat2 && !string_list_contains_string(e->category, dae->dae_cat2)) return 0; - if (dae->dae_cat3 && *dae->dae_cat3 && - !string_list_contains_string(e->category, dae->dae_cat3)) + if (dae->dae_cat3 && *dae->dae_cat3 && !string_list_contains_string(e->category, dae->dae_cat3)) return 0; - } else if ((dae->dae_cat1 && *dae->dae_cat1) || - (dae->dae_cat2 && *dae->dae_cat2) || - (dae->dae_cat3 && *dae->dae_cat3)) { + } else if ((dae->dae_cat1 && *dae->dae_cat1) || (dae->dae_cat2 && *dae->dae_cat2) || + (dae->dae_cat3 && *dae->dae_cat3)) { /* No category in event but autorec has category, so no match. */ return 0; } - if(dae->dae_start >= 0 && dae->dae_start_window >= 0 && - dae->dae_start < 24*60 && dae->dae_start_window < 24*60) { + if (dae->dae_start >= 0 && dae->dae_start_window >= 0 && dae->dae_start < 24 * 60 && + dae->dae_start_window < 24 * 60) { struct tm a_time, ev_time; - time_t ta, te, tad; + time_t ta, te, tad; localtime_r(&e->start, &a_time); - ev_time = a_time; - a_time.tm_min = dae->dae_start % 60; + ev_time = a_time; + a_time.tm_min = dae->dae_start % 60; a_time.tm_hour = dae->dae_start / 60; - ta = mktime(&a_time); - te = mktime(&ev_time); - if(dae->dae_start > dae->dae_start_window) { + ta = mktime(&a_time); + te = mktime(&ev_time); + if (dae->dae_start > dae->dae_start_window) { ta -= 24 * 3600; /* 24 hours */ tad = ((24 * 60) - dae->dae_start + dae->dae_start_window) * 60; - if(ta > te || te > ta + tad) { + if (ta > te || te > ta + tad) { ta += 24 * 3600; - if(ta > te || te > ta + tad) + if (ta > te || te > ta + tad) return 0; } } else { tad = (dae->dae_start_window - dae->dae_start) * 60; - if(ta > te || te > ta + tad) + if (ta > te || te > ta + tad) return 0; } } - duration = difftime(e->stop,e->start); + duration = difftime(e->stop, e->start); - if(dae->dae_minduration > 0) { - if(duration < dae->dae_minduration) return 0; + if (dae->dae_minduration > 0) { + if (duration < dae->dae_minduration) + return 0; } - if(dae->dae_maxduration > 0) { - if(duration > dae->dae_maxduration) return 0; + if (dae->dae_maxduration > 0) { + if (duration > dae->dae_maxduration) + return 0; } /* Only do year/season checks when programme guide has these values available. @@ -314,26 +301,30 @@ dvr_autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e) * no season (or season=0) and many people still want them to be picked up by * default. */ - if(e->copyright_year && dae->dae_minyear > 0) { - if(e->copyright_year < dae->dae_minyear) return 0; + if (e->copyright_year && dae->dae_minyear > 0) { + if (e->copyright_year < dae->dae_minyear) + return 0; } - if(e->copyright_year && dae->dae_maxyear > 0) { - if(e->copyright_year > dae->dae_maxyear) return 0; + if (e->copyright_year && dae->dae_maxyear > 0) { + if (e->copyright_year > dae->dae_maxyear) + return 0; } - if(e->epnum.s_num && dae->dae_minseason > 0) { - if(e->epnum.s_num < dae->dae_minseason) return 0; + if (e->epnum.s_num && dae->dae_minseason > 0) { + if (e->epnum.s_num < dae->dae_minseason) + return 0; } - if(e->epnum.s_num && dae->dae_maxseason > 0) { - if(e->epnum.s_num > dae->dae_maxseason) return 0; + if (e->epnum.s_num && dae->dae_maxseason > 0) { + if (e->epnum.s_num > dae->dae_maxseason) + return 0; } - if(dae->dae_weekdays != 0x7f) { + if (dae->dae_weekdays != 0x7f) { struct tm tm; localtime_r(&e->start, &tm); - if(!((1 << ((tm.tm_wday ?: 7) - 1)) & dae->dae_weekdays)) + if (!((1 << ((tm.tm_wday ?: 7) - 1)) & dae->dae_weekdays)) return 0; } @@ -348,35 +339,44 @@ dvr_autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e) return 0; /* Do not check title if the event is from the serieslink group */ - if((dae->dae_serieslink_uri == NULL || dae->dae_serieslink_uri[0] == '\0') && - dae->dae_title != NULL && dae->dae_title[0] != '\0') { - lang_str_ele_t *ls; + if ((dae->dae_serieslink_uri == NULL || dae->dae_serieslink_uri[0] == '\0') && + dae->dae_title != NULL && dae->dae_title[0] != '\0') { + lang_str_ele_t* ls; if (!dae->dae_fulltext) { - if(!e->title) return 0; - RB_FOREACH(ls, e->title, link) - if (!regex_match(&dae->dae_title_regex, ls->str)) break; + if (!e->title) + return 0; + RB_FOREACH (ls, e->title, link) + if (!regex_match(&dae->dae_title_regex, ls->str)) + break; } else { ls = NULL; if (e->title) - RB_FOREACH(ls, e->title, link) - if (!regex_match(&dae->dae_title_regex, ls->str)) break; + RB_FOREACH (ls, e->title, link) + if (!regex_match(&dae->dae_title_regex, ls->str)) + break; if (!ls && e->subtitle) - RB_FOREACH(ls, e->subtitle, link) - if (!regex_match(&dae->dae_title_regex, ls->str)) break; + RB_FOREACH (ls, e->subtitle, link) + if (!regex_match(&dae->dae_title_regex, ls->str)) + break; if (!ls && e->summary) - RB_FOREACH(ls, e->summary, link) - if (!regex_match(&dae->dae_title_regex, ls->str)) break; + RB_FOREACH (ls, e->summary, link) + if (!regex_match(&dae->dae_title_regex, ls->str)) + break; if (!ls && e->description) - RB_FOREACH(ls, e->description, link) - if (!regex_match(&dae->dae_title_regex, ls->str)) break; + RB_FOREACH (ls, e->description, link) + if (!regex_match(&dae->dae_title_regex, ls->str)) + break; if (!ls && e->credits_cached) - RB_FOREACH(ls, e->credits_cached, link) - if (!regex_match(&dae->dae_title_regex, ls->str)) break; + RB_FOREACH (ls, e->credits_cached, link) + if (!regex_match(&dae->dae_title_regex, ls->str)) + break; if (!ls && e->keyword_cached) - RB_FOREACH(ls, e->keyword_cached, link) - if (!regex_match(&dae->dae_title_regex, ls->str)) break; + RB_FOREACH (ls, e->keyword_cached, link) + if (!regex_match(&dae->dae_title_regex, ls->str)) + break; } - if (!ls) return 0; + if (!ls) + return 0; } return 1; @@ -385,10 +385,8 @@ dvr_autorec_cmp(dvr_autorec_entry_t *dae, epg_broadcast_t *e) /** * */ -dvr_autorec_entry_t * -dvr_autorec_create(const char *uuid, htsmsg_t *conf) -{ - dvr_autorec_entry_t *dae; +dvr_autorec_entry_t* dvr_autorec_create(const char* uuid, htsmsg_t* conf) { + dvr_autorec_entry_t* dae; dae = calloc(1, sizeof(*dae)); @@ -399,15 +397,16 @@ dvr_autorec_create(const char *uuid, htsmsg_t *conf) return NULL; } - dvr_config_t *c = dvr_config_find_by_uuid(htsmsg_get_str(conf, "config_name")); - if (c && c->dvr_autorec_dedup) dae->dae_record = c->dvr_autorec_dedup; - dae->dae_weekdays = 0x7f; - dae->dae_pri = DVR_PRIO_DEFAULT; - dae->dae_start = -1; + dvr_config_t* c = dvr_config_find_by_uuid(htsmsg_get_str(conf, "config_name")); + if (c && c->dvr_autorec_dedup) + dae->dae_record = c->dvr_autorec_dedup; + dae->dae_weekdays = 0x7f; + dae->dae_pri = DVR_PRIO_DEFAULT; + dae->dae_start = -1; dae->dae_start_window = -1; - dae->dae_enabled = 1; - dae->dae_record = DVR_AUTOREC_RECORD_DVR_PROFILE; - dae->dae_config = dvr_config_find_by_name_default(NULL); + dae->dae_enabled = 1; + dae->dae_record = DVR_AUTOREC_RECORD_DVR_PROFILE; + dae->dae_config = dvr_config_find_by_name_default(NULL); LIST_INSERT_HEAD(&dae->dae_config->dvr_autorec_entries, dae, dae_config_link); TAILQ_INSERT_TAIL(&autorec_entries, dae, dae_link); @@ -419,11 +418,8 @@ dvr_autorec_create(const char *uuid, htsmsg_t *conf) return dae; } - -dvr_autorec_entry_t* -dvr_autorec_create_htsp(htsmsg_t *conf) -{ - dvr_autorec_entry_t *dae; +dvr_autorec_entry_t* dvr_autorec_create_htsp(htsmsg_t* conf) { + dvr_autorec_entry_t* dae; dae = dvr_autorec_create(NULL, conf); htsmsg_destroy(conf); @@ -437,37 +433,36 @@ dvr_autorec_create_htsp(htsmsg_t *conf) return dae; } -void -dvr_autorec_update_htsp(dvr_autorec_entry_t *dae, htsmsg_t *conf) -{ +void dvr_autorec_update_htsp(dvr_autorec_entry_t* dae, htsmsg_t* conf) { idnode_update(&dae->dae_id, conf); idnode_changed(&dae->dae_id); - tvhinfo(LS_DVR, "autorec \"%s\" on \"%s\": Updated", dae->dae_title ? dae->dae_title : "", + tvhinfo(LS_DVR, + "autorec \"%s\" on \"%s\": Updated", + dae->dae_title ? dae->dae_title : "", (dae->dae_channel && dae->dae_channel->ch_name) ? dae->dae_channel->ch_name : "any channel"); } /** * */ -dvr_autorec_entry_t * -dvr_autorec_add_series_link(const char *dvr_config_name, - epg_broadcast_t *event, - const char *owner, const char *creator, - const char *comment) -{ - dvr_autorec_entry_t *dae; - htsmsg_t *conf; - const char *chname; - char *title; - const char *name; +dvr_autorec_entry_t* dvr_autorec_add_series_link(const char* dvr_config_name, + epg_broadcast_t* event, + const char* owner, + const char* creator, + const char* comment) { + dvr_autorec_entry_t* dae; + htsmsg_t* conf; + const char* chname; + char* title; + const char* name; if (!event) return NULL; chname = channel_get_name(event->channel, NULL); if (!chname) return NULL; - conf = htsmsg_create_map(); + conf = htsmsg_create_map(); title = regexp_escape(epg_broadcast_get_title(event, NULL)); - name = epg_broadcast_get_title(event, NULL); + name = epg_broadcast_get_title(event, NULL); htsmsg_add_u32(conf, "enabled", 1); htsmsg_add_str(conf, "title", title); htsmsg_add_str(conf, "name", name); @@ -491,9 +486,7 @@ dvr_autorec_add_series_link(const char *dvr_config_name, /** * */ -static void -autorec_entry_destroy(dvr_autorec_entry_t *dae, int delconf) -{ +static void autorec_entry_destroy(dvr_autorec_entry_t* dae, int delconf) { char ubuf[UUID_HEX_SIZE]; idnode_save_check(&dae->dae_id, delconf); @@ -508,7 +501,7 @@ autorec_entry_destroy(dvr_autorec_entry_t *dae, int delconf) TAILQ_REMOVE(&autorec_entries, dae, dae_link); idnode_unlink(&dae->dae_id); - if(dae->dae_config) + if (dae->dae_config) LIST_REMOVE(dae, dae_config_link); free(dae->dae_name); @@ -522,10 +515,10 @@ autorec_entry_destroy(dvr_autorec_entry_t *dae, int delconf) autorec_regfree(dae); - if(dae->dae_channel != NULL) + if (dae->dae_channel != NULL) LIST_REMOVE(dae, dae_channel_link); - if(dae->dae_channel_tag != NULL) + if (dae->dae_channel_tag != NULL) LIST_REMOVE(dae, dae_channel_tag_link); free(dae); @@ -535,10 +528,8 @@ autorec_entry_destroy(dvr_autorec_entry_t *dae, int delconf) * DVR Autorec Entry Class definition * **************************************************************************/ -static void -dvr_autorec_entry_class_changed(idnode_t *self) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)self; +static void dvr_autorec_entry_class_changed(idnode_t* self) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)self; if (dae->dae_error) dae->dae_enabled = 0; @@ -547,30 +538,24 @@ dvr_autorec_entry_class_changed(idnode_t *self) htsp_autorec_entry_update(dae); } -static htsmsg_t * -dvr_autorec_entry_class_save(idnode_t *self, char *filename, size_t fsize) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)self; - htsmsg_t *m = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* dvr_autorec_entry_class_save(idnode_t* self, char* filename, size_t fsize) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)self; + htsmsg_t* m = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(&dae->dae_id, m); if (filename) snprintf(filename, fsize, "dvr/autorec/%s", idnode_uuid_as_str(&dae->dae_id, ubuf)); return m; } -static void -dvr_autorec_entry_class_delete(idnode_t *self) -{ - autorec_entry_destroy((dvr_autorec_entry_t *)self, 1); +static void dvr_autorec_entry_class_delete(idnode_t* self) { + autorec_entry_destroy((dvr_autorec_entry_t*)self, 1); } -static int -dvr_autorec_entry_class_perm(idnode_t *self, access_t *a, htsmsg_t *msg_to_write) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)self; +static int dvr_autorec_entry_class_perm(idnode_t* self, access_t* a, htsmsg_t* msg_to_write) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)self; - if (access_verify2(a, ACCESS_OR|ACCESS_ADMIN|ACCESS_RECORDER)) + if (access_verify2(a, ACCESS_OR | ACCESS_ADMIN | ACCESS_RECORDER)) return -1; if (!access_verify2(a, ACCESS_ADMIN)) return 0; @@ -580,11 +565,9 @@ dvr_autorec_entry_class_perm(idnode_t *self, access_t *a, htsmsg_t *msg_to_write } static void -dvr_autorec_entry_class_get_title - (idnode_t *self, const char *lang, char *dst, size_t dstsize) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)self; - const char *s = ""; +dvr_autorec_entry_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)self; + const char* s = ""; if (dae->dae_name && dae->dae_name[0] != '\0') s = dae->dae_name; else if (dae->dae_comment && dae->dae_comment[0] != '\0') @@ -592,12 +575,11 @@ dvr_autorec_entry_class_get_title snprintf(dst, dstsize, "%s", s); } -static int -dvr_autorec_entry_class_channel_set(void *o, const void *v) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; - channel_t *ch = v ? channel_find_by_uuid(v) : NULL; - if (ch == NULL) ch = v ? channel_find_by_name(v) : NULL; +static int dvr_autorec_entry_class_channel_set(void* o, const void* v) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; + channel_t* ch = v ? channel_find_by_uuid(v) : NULL; + if (ch == NULL) + ch = v ? channel_find_by_name(v) : NULL; if (ch == NULL) { if (dae->dae_channel) { LIST_REMOVE(dae, dae_channel_link); @@ -605,8 +587,7 @@ dvr_autorec_entry_class_channel_set(void *o, const void *v) return 1; } } else if (dae->dae_channel != ch) { - if (dae->dae_id.in_access && - !channel_access(ch, dae->dae_id.in_access, 1)) + if (dae->dae_id.in_access && !channel_access(ch, dae->dae_id.in_access, 1)) return 0; if (dae->dae_channel) LIST_REMOVE(dae, dae_channel_link); @@ -617,10 +598,8 @@ dvr_autorec_entry_class_channel_set(void *o, const void *v) return 0; } -static const void * -dvr_autorec_entry_class_channel_get(void *o) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static const void* dvr_autorec_entry_class_channel_get(void* o) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; if (dae->dae_channel) idnode_uuid_as_str(&dae->dae_channel->ch_id, prop_sbuf); else @@ -628,20 +607,16 @@ dvr_autorec_entry_class_channel_get(void *o) return &prop_sbuf_ptr; } -static char * -dvr_autorec_entry_class_channel_rend(void *o, const char *lang) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static char* dvr_autorec_entry_class_channel_rend(void* o, const char* lang) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; if (dae->dae_channel) return strdup(channel_get_name(dae->dae_channel, tvh_gettext_lang(lang, channel_blank_name))); return NULL; } -static int -dvr_autorec_entry_class_title_set(void *o, const void *v) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; - const char *title = v ?: ""; +static int dvr_autorec_entry_class_title_set(void* o, const void* v) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; + const char* title = v ?: ""; if (strcmp(title, dae->dae_title ?: "")) { if (dae->dae_title) autorec_regfree(dae); @@ -655,12 +630,11 @@ dvr_autorec_entry_class_title_set(void *o, const void *v) return 0; } -static int -dvr_autorec_entry_class_tag_set(void *o, const void *v) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; - channel_tag_t *tag = v ? channel_tag_find_by_uuid(v) : NULL; - if (tag == NULL) tag = v ? channel_tag_find_by_name(v, 0) : NULL; +static int dvr_autorec_entry_class_tag_set(void* o, const void* v) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; + channel_tag_t* tag = v ? channel_tag_find_by_uuid(v) : NULL; + if (tag == NULL) + tag = v ? channel_tag_find_by_name(v, 0) : NULL; if (tag == NULL && dae->dae_channel_tag) { LIST_REMOVE(dae, dae_channel_tag_link); dae->dae_channel_tag = NULL; @@ -675,10 +649,8 @@ dvr_autorec_entry_class_tag_set(void *o, const void *v) return 0; } -static const void * -dvr_autorec_entry_class_tag_get(void *o) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static const void* dvr_autorec_entry_class_tag_get(void* o) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; if (dae->dae_channel_tag) idnode_uuid_as_str(&dae->dae_channel_tag->ct_id, prop_sbuf); else @@ -686,24 +658,20 @@ dvr_autorec_entry_class_tag_get(void *o) return &prop_sbuf_ptr; } -static char * -dvr_autorec_entry_class_tag_rend(void *o, const char *lang) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static char* dvr_autorec_entry_class_tag_rend(void* o, const char* lang) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; if (dae->dae_channel_tag) return strdup(dae->dae_channel_tag->ct_name); return NULL; } -static int -dvr_autorec_entry_class_time_set(void *o, const void *v, int *tm) -{ - const char *s = v; - int t; +static int dvr_autorec_entry_class_time_set(void* o, const void* v, int* tm) { + const char* s = v; + int t; - if(s == NULL || s[0] == '\0' || !isdigit(s[0])) + if (s == NULL || s[0] == '\0' || !isdigit(s[0])) t = -1; - else if(strchr(s, ':') != NULL) + else if (strchr(s, ':') != NULL) // formatted time string - convert t = (atoi(s) * 60) + atoi(s + 3); else { @@ -718,23 +686,17 @@ dvr_autorec_entry_class_time_set(void *o, const void *v, int *tm) return 0; } -static int -dvr_autorec_entry_class_start_set(void *o, const void *v) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static int dvr_autorec_entry_class_start_set(void* o, const void* v) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; return dvr_autorec_entry_class_time_set(o, v, &dae->dae_start); } -static int -dvr_autorec_entry_class_start_window_set(void *o, const void *v) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static int dvr_autorec_entry_class_start_window_set(void* o, const void* v) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; return dvr_autorec_entry_class_time_set(o, v, &dae->dae_start_window); } -static const void * -dvr_autorec_entry_class_time_get(void *o, int tm) -{ +static const void* dvr_autorec_entry_class_time_get(void* o, int tm) { if (tm >= 0) snprintf(prop_sbuf, PROP_SBUF_LEN, "%02d:%02d", tm / 60, tm % 60); else @@ -742,68 +704,53 @@ dvr_autorec_entry_class_time_get(void *o, int tm) return &prop_sbuf_ptr; } -static const void * -dvr_autorec_entry_class_start_get(void *o) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static const void* dvr_autorec_entry_class_start_get(void* o) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; return dvr_autorec_entry_class_time_get(o, dae->dae_start); } -static const void * -dvr_autorec_entry_class_start_window_get(void *o) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static const void* dvr_autorec_entry_class_start_window_get(void* o) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; return dvr_autorec_entry_class_time_get(o, dae->dae_start_window); } -htsmsg_t * -dvr_autorec_entry_class_time_list(void *o, const char *null) -{ - int i; - htsmsg_t *l = htsmsg_create_list(); - char buf[16]; +htsmsg_t* dvr_autorec_entry_class_time_list(void* o, const char* null) { + int i; + htsmsg_t* l = htsmsg_create_list(); + char buf[16]; htsmsg_add_str(l, NULL, null); - for (i = 0; i < 24*60; i += 10) { + for (i = 0; i < 24 * 60; i += 10) { snprintf(buf, sizeof(buf), "%02d:%02d", i / 60, (i % 60)); htsmsg_add_str(l, NULL, buf); } return l; } -static htsmsg_t * -dvr_autorec_entry_class_time_list_(void *o, const char *lang) -{ - const char *msg = N_("Any"); +static htsmsg_t* dvr_autorec_entry_class_time_list_(void* o, const char* lang) { + const char* msg = N_("Any"); return dvr_autorec_entry_class_time_list(o, tvh_gettext_lang(lang, msg)); } -static htsmsg_t * -dvr_autorec_entry_class_extra_list(void *o, const char *lang) -{ - const char *msg = N_("Not set (use channel or DVR configuration)"); - return dvr_entry_class_duration_list(o, tvh_gettext_lang(lang, msg), 4*60, 1, lang); +static htsmsg_t* dvr_autorec_entry_class_extra_list(void* o, const char* lang) { + const char* msg = N_("Not set (use channel or DVR configuration)"); + return dvr_entry_class_duration_list(o, tvh_gettext_lang(lang, msg), 4 * 60, 1, lang); } -static htsmsg_t * -dvr_autorec_entry_class_minduration_list(void *o, const char *lang) -{ - const char *msg = N_("Any"); - return dvr_entry_class_duration_list(o, tvh_gettext_lang(lang, msg), 24*60, 60, lang); +static htsmsg_t* dvr_autorec_entry_class_minduration_list(void* o, const char* lang) { + const char* msg = N_("Any"); + return dvr_entry_class_duration_list(o, tvh_gettext_lang(lang, msg), 24 * 60, 60, lang); } -static htsmsg_t * -dvr_autorec_entry_class_maxduration_list(void *o, const char *lang) -{ - const char *msg = N_("Any"); - return dvr_entry_class_duration_list(o, tvh_gettext_lang(lang, msg), 24*60, 60, lang); +static htsmsg_t* dvr_autorec_entry_class_maxduration_list(void* o, const char* lang) { + const char* msg = N_("Any"); + return dvr_entry_class_duration_list(o, tvh_gettext_lang(lang, msg), 24 * 60, 60, lang); } -static int -dvr_autorec_entry_class_config_name_set(void *o, const void *v) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; - dvr_config_t *cfg = v ? dvr_config_find_by_uuid(v) : NULL; - if (cfg == NULL) cfg = v ? dvr_config_find_by_name_default(v): NULL; +static int dvr_autorec_entry_class_config_name_set(void* o, const void* v) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; + dvr_config_t* cfg = v ? dvr_config_find_by_uuid(v) : NULL; + if (cfg == NULL) + cfg = v ? dvr_config_find_by_name_default(v) : NULL; if (cfg == NULL && dae->dae_config) { dae->dae_config = NULL; LIST_REMOVE(dae, dae_config_link); @@ -818,10 +765,8 @@ dvr_autorec_entry_class_config_name_set(void *o, const void *v) return 0; } -static const void * -dvr_autorec_entry_class_config_name_get(void *o) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static const void* dvr_autorec_entry_class_config_name_get(void* o) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; if (dae->dae_config) idnode_uuid_as_str(&dae->dae_config->dvr_id, prop_sbuf); else @@ -829,25 +774,21 @@ dvr_autorec_entry_class_config_name_get(void *o) return &prop_sbuf_ptr; } -static char * -dvr_autorec_entry_class_config_name_rend(void *o, const char *lang) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static char* dvr_autorec_entry_class_config_name_rend(void* o, const char* lang) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; if (dae->dae_config) return strdup(dae->dae_config->dvr_config_name); return NULL; } -static int -dvr_autorec_entry_class_weekdays_set(void *o, const void *v) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; - htsmsg_field_t *f; - uint32_t u32, bits = 0; +static int dvr_autorec_entry_class_weekdays_set(void* o, const void* v) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; + htsmsg_field_t* f; + uint32_t u32, bits = 0; - HTSMSG_FOREACH(f, (htsmsg_t *)v) - if (!htsmsg_field_get_u32(f, &u32) && u32 > 0 && u32 < 8) - bits |= (1 << (u32 - 1)); + HTSMSG_FOREACH(f, (htsmsg_t*)v) + if (!htsmsg_field_get_u32(f, &u32) && u32 > 0 && u32 < 8) + bits |= (1 << (u32 - 1)); if (bits != dae->dae_weekdays) { dae->dae_weekdays = bits; @@ -856,52 +797,42 @@ dvr_autorec_entry_class_weekdays_set(void *o, const void *v) return 0; } -htsmsg_t * -dvr_autorec_entry_class_weekdays_get(uint32_t weekdays) -{ - htsmsg_t *m = htsmsg_create_list(); - int i; +htsmsg_t* dvr_autorec_entry_class_weekdays_get(uint32_t weekdays) { + htsmsg_t* m = htsmsg_create_list(); + int i; for (i = 0; i < 7; i++) if (weekdays & (1 << i)) htsmsg_add_u32(m, NULL, i + 1); return m; } -static htsmsg_t * -dvr_autorec_entry_class_weekdays_default(void) -{ +static htsmsg_t* dvr_autorec_entry_class_weekdays_default(void) { return dvr_autorec_entry_class_weekdays_get(0x7f); } -static const void * -dvr_autorec_entry_class_weekdays_get_(void *o) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static const void* dvr_autorec_entry_class_weekdays_get_(void* o) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; return dvr_autorec_entry_class_weekdays_get(dae->dae_weekdays); } static const struct strtab dvr_autorec_entry_class_weekdays_tab[] = { - { N_("Mon"), 1 }, - { N_("Tue"), 2 }, - { N_("Wed"), 3 }, - { N_("Thu"), 4 }, - { N_("Fri"), 5 }, - { N_("Sat"), 6 }, - { N_("Sun"), 7 }, + {N_("Mon"), 1}, + {N_("Tue"), 2}, + {N_("Wed"), 3}, + {N_("Thu"), 4}, + {N_("Fri"), 5}, + {N_("Sat"), 6}, + {N_("Sun"), 7}, }; -htsmsg_t * -dvr_autorec_entry_class_weekdays_list ( void *o, const char *lang ) -{ +htsmsg_t* dvr_autorec_entry_class_weekdays_list(void* o, const char* lang) { return strtab2htsmsg(dvr_autorec_entry_class_weekdays_tab, 1, lang); } -char * -dvr_autorec_entry_class_weekdays_rend(uint32_t weekdays, const char *lang) -{ - char buf[32]; +char* dvr_autorec_entry_class_weekdays_rend(uint32_t weekdays, const char* lang) { + char buf[32]; size_t l; - int i; + int i; if (weekdays == 0x7f) snprintf(buf, sizeof(buf), "%s", tvh_gettext_lang(lang, N_("Every day"))); else if (weekdays == 0) @@ -911,37 +842,33 @@ dvr_autorec_entry_class_weekdays_rend(uint32_t weekdays, const char *lang) for (i = 0; i < 7; i++) if (weekdays & (1 << i)) { l = strlen(buf); - snprintf(buf + l, sizeof(buf) - l, ",%s", - tvh_gettext_lang(lang, val2str(i + 1, dvr_autorec_entry_class_weekdays_tab))); + snprintf(buf + l, + sizeof(buf) - l, + ",%s", + tvh_gettext_lang(lang, val2str(i + 1, dvr_autorec_entry_class_weekdays_tab))); } } return strdup(buf + 1); } -static char * -dvr_autorec_entry_class_weekdays_rend_(void *o, const char *lang) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; +static char* dvr_autorec_entry_class_weekdays_rend_(void* o, const char* lang) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; return dvr_autorec_entry_class_weekdays_rend(dae->dae_weekdays, lang); } /** Validate star rating is in range */ -static int -dvr_autorec_entry_class_star_rating_set(void *o, const void *v) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; - const uint16_t *val = (uint16_t*)v; +static int dvr_autorec_entry_class_star_rating_set(void* o, const void* v) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; + const uint16_t* val = (uint16_t*)v; if (*val > 100) return 0; dae->dae_star_rating = *val; return 1; } -static htsmsg_t * -dvr_autorec_entry_class_star_rating_list ( void *o, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_list(); - htsmsg_t *e = htsmsg_create_map(); +static htsmsg_t* dvr_autorec_entry_class_star_rating_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_list(); + htsmsg_t* e = htsmsg_create_map(); /* No htsmsg_add_u16 so use htsmsg_add_u32 instead */ htsmsg_add_u32(e, "key", 0); /* Instead of "Any" we use "No rating needed" since "Any" could @@ -956,7 +883,7 @@ dvr_autorec_entry_class_star_rating_list ( void *o, const char *lang ) * likely to want to record something with a high rating than scroll * through the list to find programmes with a poor rating. */ - for (i = 100; i > 0 ; i-=5) { + for (i = 100; i > 0; i -= 5) { e = htsmsg_create_map(); htsmsg_add_u32(e, "key", i); htsmsg_add_u32(e, "val", i); @@ -966,11 +893,9 @@ dvr_autorec_entry_class_star_rating_list ( void *o, const char *lang ) } /** Generate a year list to make it easier to select min/max year */ -static htsmsg_t * -dvr_autorec_entry_class_year_list ( void *o, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_list(); - htsmsg_t *e = htsmsg_create_map(); +static htsmsg_t* dvr_autorec_entry_class_year_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_list(); + htsmsg_t* e = htsmsg_create_map(); htsmsg_add_u32(e, "key", 0); htsmsg_add_str(e, "val", tvh_gettext_lang(lang, N_("Any"))); htsmsg_add_msg(m, NULL, e); @@ -979,7 +904,7 @@ dvr_autorec_entry_class_year_list ( void *o, const char *lang ) /* We create the list from highest to lowest since you're more * likely to want to record something recent. */ - for (i = 2025; i > 1900 ; i-=5) { + for (i = 2025; i > 1900; i -= 5) { e = htsmsg_create_map(); htsmsg_add_u32(e, "key", i); htsmsg_add_u32(e, "val", i); @@ -988,87 +913,57 @@ dvr_autorec_entry_class_year_list ( void *o, const char *lang ) return m; } -static htsmsg_t * -dvr_autorec_entry_class_content_type_list(void *o, const char *lang) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "epg/content_type/list"); +static htsmsg_t* dvr_autorec_entry_class_content_type_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "epg/content_type/list"); return m; } -static htsmsg_t * -dvr_autorec_entry_class_dedup_list ( void *o, const char *lang ) -{ +static htsmsg_t* dvr_autorec_entry_class_dedup_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Use DVR configuration"), - DVR_AUTOREC_RECORD_DVR_PROFILE }, - { N_("Record all"), - DVR_AUTOREC_RECORD_ALL }, - { N_("All: Record if EPG/XMLTV indicates it is a unique programme"), - DVR_AUTOREC_RECORD_UNIQUE }, - { N_("All: Record if different episode number"), - DVR_AUTOREC_RECORD_DIFFERENT_EPISODE_NUMBER }, - { N_("All: Record if different subtitle"), - DVR_AUTOREC_RECORD_DIFFERENT_SUBTITLE }, - { N_("All: Record if different description"), - DVR_AUTOREC_RECORD_DIFFERENT_DESCRIPTION }, - { N_("All: Record once per month"), - DVR_AUTOREC_RECORD_ONCE_PER_MONTH }, - { N_("All: Record once per week"), - DVR_AUTOREC_RECORD_ONCE_PER_WEEK }, - { N_("All: Record once per day"), - DVR_AUTOREC_RECORD_ONCE_PER_DAY }, - { N_("Local: Record if different episode number"), - DVR_AUTOREC_LRECORD_DIFFERENT_EPISODE_NUMBER }, - { N_("Local: Record if different title"), - DVR_AUTOREC_LRECORD_DIFFERENT_TITLE }, - { N_("Local: Record if different subtitle"), - DVR_AUTOREC_LRECORD_DIFFERENT_SUBTITLE }, - { N_("Local: Record if different description"), - DVR_AUTOREC_LRECORD_DIFFERENT_DESCRIPTION }, - { N_("Local: Record once per month"), - DVR_AUTOREC_LRECORD_ONCE_PER_MONTH }, - { N_("Local: Record once per week"), - DVR_AUTOREC_LRECORD_ONCE_PER_WEEK }, - { N_("Local: Record once per day"), - DVR_AUTOREC_LRECORD_ONCE_PER_DAY }, + {N_("Use DVR configuration"), DVR_AUTOREC_RECORD_DVR_PROFILE}, + {N_("Record all"), DVR_AUTOREC_RECORD_ALL}, + {N_("All: Record if EPG/XMLTV indicates it is a unique programme"), + DVR_AUTOREC_RECORD_UNIQUE}, + {N_("All: Record if different episode number"), DVR_AUTOREC_RECORD_DIFFERENT_EPISODE_NUMBER}, + {N_("All: Record if different subtitle"), DVR_AUTOREC_RECORD_DIFFERENT_SUBTITLE}, + {N_("All: Record if different description"), DVR_AUTOREC_RECORD_DIFFERENT_DESCRIPTION}, + {N_("All: Record once per month"), DVR_AUTOREC_RECORD_ONCE_PER_MONTH}, + {N_("All: Record once per week"), DVR_AUTOREC_RECORD_ONCE_PER_WEEK}, + {N_("All: Record once per day"), DVR_AUTOREC_RECORD_ONCE_PER_DAY}, + {N_("Local: Record if different episode number"), + DVR_AUTOREC_LRECORD_DIFFERENT_EPISODE_NUMBER}, + {N_("Local: Record if different title"), DVR_AUTOREC_LRECORD_DIFFERENT_TITLE}, + {N_("Local: Record if different subtitle"), DVR_AUTOREC_LRECORD_DIFFERENT_SUBTITLE}, + {N_("Local: Record if different description"), DVR_AUTOREC_LRECORD_DIFFERENT_DESCRIPTION}, + {N_("Local: Record once per month"), DVR_AUTOREC_LRECORD_ONCE_PER_MONTH}, + {N_("Local: Record once per week"), DVR_AUTOREC_LRECORD_ONCE_PER_WEEK}, + {N_("Local: Record once per day"), DVR_AUTOREC_LRECORD_ONCE_PER_DAY}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -dvr_autorec_entry_class_btype_list ( void *o, const char *lang ) -{ +static htsmsg_t* dvr_autorec_entry_class_btype_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Any"), - DVR_AUTOREC_BTYPE_ALL }, - { N_("New / premiere / unknown"), - DVR_AUTOREC_BTYPE_NEW_OR_UNKNOWN }, - { N_("New / premiere"), - DVR_AUTOREC_BTYPE_NEW }, - { N_("Repeated"), - DVR_AUTOREC_BTYPE_REPEAT }, + {N_("Any"), DVR_AUTOREC_BTYPE_ALL}, + {N_("New / premiere / unknown"), DVR_AUTOREC_BTYPE_NEW_OR_UNKNOWN}, + {N_("New / premiere"), DVR_AUTOREC_BTYPE_NEW}, + {N_("Repeated"), DVR_AUTOREC_BTYPE_REPEAT}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -dvr_autorec_entry_category_list ( void *o, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "channelcategory/list"); +static htsmsg_t* dvr_autorec_entry_category_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "channelcategory/list"); return m; } - -static uint32_t -dvr_autorec_entry_class_owner_opts(void *o, uint32_t opts) -{ - dvr_autorec_entry_t *dae = (dvr_autorec_entry_t *)o; - if (dae && dae->dae_id.in_access && - !access_verify2(dae->dae_id.in_access, ACCESS_ADMIN)) +static uint32_t dvr_autorec_entry_class_owner_opts(void* o, uint32_t opts) { + dvr_autorec_entry_t* dae = (dvr_autorec_entry_t*)o; + if (dae && dae->dae_id.in_access && !access_verify2(dae->dae_id.in_access, ACCESS_ADMIN)) return PO_ADVANCED; return PO_RDONLY | PO_ADVANCED; } @@ -1080,392 +975,375 @@ PROP_DOC(duplicate_handling) * to select several. So abstract the properties away since they * are nearly identical for each entry. */ -#define CATEGORY_SELECTION_PROP(NUM) \ - .type = PT_STR, \ - .id = "cat" #NUM, \ - .name = N_("Category " #NUM " (selection)"), \ - .desc = N_("The category of the program to look for. The xmltv "\ - "providers often supply detailed categories such as "\ - "Sitcom, Movie, Track/field, etc. " \ - "This let you select from categories for current programmes. " \ - "It is then combined (AND) with other fields to limit to " \ - "programmes that match all categories. " \ - "If this selection list is empty then it means your provider does not " \ - "supply programme categories." \ - ), \ - .off = offsetof(dvr_autorec_entry_t, dae_cat ## NUM), \ - .opts = PO_EXPERT, \ - .list = dvr_autorec_entry_category_list - - -const idclass_t dvr_autorec_entry_class = { - .ic_class = "dvrautorec", - .ic_caption = N_("DVR - Auto-recording (Autorecs)"), - .ic_event = "dvrautorec", - .ic_doc = tvh_doc_dvrautorec_class, - .ic_changed = dvr_autorec_entry_class_changed, - .ic_save = dvr_autorec_entry_class_save, - .ic_get_title = dvr_autorec_entry_class_get_title, - .ic_delete = dvr_autorec_entry_class_delete, - .ic_perm = dvr_autorec_entry_class_perm, - .ic_properties = (const property_t[]) { - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable auto-rec rule."), - .def.i = 1, - .off = offsetof(dvr_autorec_entry_t, dae_enabled), - }, - { - .type = PT_STR, - .id = "name", - .name = N_("Name"), - .desc = N_("The name of the the rule."), - .off = offsetof(dvr_autorec_entry_t, dae_name), - }, - { - .type = PT_STR, - .id = "directory", - .name = N_("Directory"), - .desc = N_("When specified, this setting overrides the " - "subdirectory rules (except the base directory) " - "defined in the DVR configuration and puts all " - "recordings done by this entry into the " - "subdirectory named here. See Help for more info."), - .off = offsetof(dvr_autorec_entry_t, dae_directory), - .opts = PO_EXPERT, - }, - { - .type = PT_STR, - .id = "title", - .name = N_("Title (regexp)"), - .desc = N_("The title of the program to look for. Note that " - "this accepts case-insensitive regular expressions."), - .set = dvr_autorec_entry_class_title_set, - .off = offsetof(dvr_autorec_entry_t, dae_title), - }, - /* We provide a small number of selection drop-downs. This is to - * make it easier for users to see what categories are available and - * make it easy to record for example '"Movie" "Martial arts" "Western"' - * without user needing a regex, and allowing them to easily see what - * categories they have available. - */ - { - CATEGORY_SELECTION_PROP(1) - }, - { - CATEGORY_SELECTION_PROP(2) - }, - { - CATEGORY_SELECTION_PROP(3) - }, - { - .type = PT_BOOL, - .id = "fulltext", - .name = N_("Full-text"), - .desc = N_("When the fulltext is checked, the title pattern is " - "matched against title, subtitle, summary and description."), - .off = offsetof(dvr_autorec_entry_t, dae_fulltext), - }, - { - .type = PT_STR, - .id = "channel", - .name = N_("Channel"), - .desc = N_("The channel on which this rule applies, i.e. the " - "channel you're aiming to record. You can leave " - "this field blank to apply the rule to all " - "channels."), - .set = dvr_autorec_entry_class_channel_set, - .get = dvr_autorec_entry_class_channel_get, - .rend = dvr_autorec_entry_class_channel_rend, - .list = channel_class_get_list, - }, - { - .type = PT_STR, - .id = "tag", - .name = N_("Channel tag"), - .desc = N_("A channel tag (e.g. a group of channels) to which " - "this rule applies."), - .set = dvr_autorec_entry_class_tag_set, - .get = dvr_autorec_entry_class_tag_get, - .rend = dvr_autorec_entry_class_tag_rend, - .list = channel_tag_class_get_list, - .opts = PO_ADVANCED - }, - { - .type = PT_U32, - .id = "btype", - .name = N_("Broadcast type"), - .desc = N_("Select type of broadcast."), - .def.i = DVR_AUTOREC_BTYPE_ALL, - .off = offsetof(dvr_autorec_entry_t, dae_btype), - .list = dvr_autorec_entry_class_btype_list, - .opts = PO_HIDDEN | PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "content_type", - .name = N_("Content type"), - .desc = N_("The content type (Movie/Drama, Sports, etc.) to " - "be used to filter matching events/programs."), - .list = dvr_autorec_entry_class_content_type_list, - .off = offsetof(dvr_autorec_entry_t, dae_content_type), - .opts = PO_ADVANCED, - }, - { - .type = PT_U16, - .id = "star_rating", - .name = N_("Star rating"), - .desc = N_("The minimum number of stars the broadcast should have - in " - "other words, only match programs that have at " - "least this rating."), - .set = dvr_autorec_entry_class_star_rating_set, - .list = dvr_autorec_entry_class_star_rating_list, - .off = offsetof(dvr_autorec_entry_t, dae_star_rating), - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "start", - .name = N_("Start after"), - .desc = N_("An event which starts between this \"start after\" " - "and \"start before\" will be matched (including " - "boundary values)."), - .def.s = N_("Any"), - .set = dvr_autorec_entry_class_start_set, - .get = dvr_autorec_entry_class_start_get, - .list = dvr_autorec_entry_class_time_list_, - .opts = PO_SORTKEY | PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "start_window", - .name = N_("Start before"), - .desc = N_("An event which starts between this \"start after\" " - "and \"start before\" will be matched (including " - "boundary values)."), - .def.s = N_("Any"), - .set = dvr_autorec_entry_class_start_window_set, - .get = dvr_autorec_entry_class_start_window_get, - .list = dvr_autorec_entry_class_time_list_, - .opts = PO_SORTKEY | PO_DOC_NLIST, - }, - { - .type = PT_TIME, - .id = "start_extra", - .name = N_("Extra start time"), - .desc = N_("Start recording earlier than the defined start " - "time by x minutes."), - .off = offsetof(dvr_autorec_entry_t, dae_start_extra), - .list = dvr_autorec_entry_class_extra_list, - .opts = PO_DURATION | PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_TIME, - .id = "stop_extra", - .name = N_("Extra stop time"), - .desc = N_("Continue recording for x minutes after scheduled " - "stop time"), - .off = offsetof(dvr_autorec_entry_t, dae_stop_extra), - .list = dvr_autorec_entry_class_extra_list, - .opts = PO_DURATION | PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .islist = 1, - .id = "weekdays", - .name = N_("Days of week"), - .desc = N_("Days of the week to which the rule should apply."), - .set = dvr_autorec_entry_class_weekdays_set, - .get = dvr_autorec_entry_class_weekdays_get_, - .list = dvr_autorec_entry_class_weekdays_list, - .rend = dvr_autorec_entry_class_weekdays_rend_, - .def.list = dvr_autorec_entry_class_weekdays_default, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_INT, - .id = "minduration", - .name = N_("Minimum duration"), - .desc = N_("The minimal duration of a matching event - in " - "other words, only match programs that are no " - "shorter than this duration."), - .list = dvr_autorec_entry_class_minduration_list, - .off = offsetof(dvr_autorec_entry_t, dae_minduration), - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_INT, - .id = "maxduration", - .name = N_("Maximum duration"), - .desc = N_("The maximal duration of a matching event - in " - "other words, only match programmes that are no " - "longer than this duration."), - .list = dvr_autorec_entry_class_maxduration_list, - .off = offsetof(dvr_autorec_entry_t, dae_maxduration), - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "minyear", - .name = N_("Minimum year"), - .desc = N_("The earliest year for the programme. Programmes must be equal to or later than this year."), - .list = dvr_autorec_entry_class_year_list, - .off = offsetof(dvr_autorec_entry_t, dae_minyear), - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "maxyear", - .name = N_("Maximum year"), - .desc = N_("The latest year for the programme. Programmes must be equal to or earlier than this year."), - .list = dvr_autorec_entry_class_year_list, - .off = offsetof(dvr_autorec_entry_t, dae_maxyear), - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_U16, - .id = "minseason", - .name = N_("Minimum season"), - .desc = N_("The earliest season for the programme. Programmes must be equal to or later than this season."), - .off = offsetof(dvr_autorec_entry_t, dae_minseason), - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_U16, - .id = "maxseason", - .name = N_("Maximum season"), - .desc = N_("The latest season for the programme. Programmes must be equal to or earlier than this season."), - .off = offsetof(dvr_autorec_entry_t, dae_maxseason), - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "pri", - .name = N_("Priority"), - .desc = N_("Priority of the recording. Higher priority entries " - "will take precedence and cancel lower-priority events. " - "The 'Not Set' value inherits the settings from " - "the assigned DVR configuration."), - .list = dvr_entry_class_pri_list, - .def.i = DVR_PRIO_DEFAULT, - .off = offsetof(dvr_autorec_entry_t, dae_pri), - .opts = PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "record", - .name = N_("Duplicate handling"), - .desc = N_("How to handle duplicate recordings. The 'Use DVR " - "Configuration' value (the default) inherits the " - "settings from the assigned DVR configuration"), - .def.i = DVR_AUTOREC_RECORD_DVR_PROFILE, - .doc = prop_doc_duplicate_handling, - .off = offsetof(dvr_autorec_entry_t, dae_record), - .list = dvr_autorec_entry_class_dedup_list, - .opts = PO_HIDDEN | PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "retention", - .name = N_("DVR log retention"), - .desc = N_("Number of days to retain information about recording."), - .def.i = DVR_RET_REM_DVRCONFIG, - .off = offsetof(dvr_autorec_entry_t, dae_retention), - .list = dvr_entry_class_retention_list, - .opts = PO_HIDDEN | PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "removal", - .name = N_("DVR file retention period"), - .desc = N_("Number of days to keep the recorded file."), - .def.i = DVR_RET_REM_DVRCONFIG, - .off = offsetof(dvr_autorec_entry_t, dae_removal), - .list = dvr_entry_class_removal_list, - .opts = PO_HIDDEN | PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "maxcount", - .name = N_("Maximum count (0=default)"), - .desc = N_("The maximum number of times this rule can be " - "triggered."), - .off = offsetof(dvr_autorec_entry_t, dae_max_count), - .opts = PO_HIDDEN | PO_EXPERT, - }, - { - .type = PT_U32, - .id = "maxsched", - .name = N_("Maximum schedules limit (0=default)"), - .desc = N_("The maximum number of recording entries this rule " - "can create."), - .off = offsetof(dvr_autorec_entry_t, dae_max_sched_count), - .opts = PO_HIDDEN | PO_EXPERT, - }, - { - .type = PT_STR, - .id = "config_name", - .name = N_("DVR configuration"), - .desc = N_("The DVR profile to be used/used by this rule."), - .set = dvr_autorec_entry_class_config_name_set, - .get = dvr_autorec_entry_class_config_name_get, - .rend = dvr_autorec_entry_class_config_name_rend, - .list = dvr_entry_class_config_name_list, - .opts = PO_ADVANCED - }, - { - .type = PT_STR, - .id = "serieslink", - .name = N_("Series link"), - .desc = N_("Series link ID."), - .off = offsetof(dvr_autorec_entry_t, dae_serieslink_uri), - .opts = PO_RDONLY | PO_ADVANCED, - }, - { - .type = PT_STR, - .id = "owner", - .name = N_("Owner"), - .desc = N_("Owner of the rule."), - .off = offsetof(dvr_autorec_entry_t, dae_owner), - .get_opts = dvr_autorec_entry_class_owner_opts, - }, - { - .type = PT_STR, - .id = "creator", - .name = N_("Creator"), - .desc = N_("The user who created the recording, or the " - "auto-recording source and IP address if scheduled " - "by a matching rule."), - .off = offsetof(dvr_autorec_entry_t, dae_creator), - .get_opts = dvr_autorec_entry_class_owner_opts, - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-form text field, enter whatever you like here."), - .off = offsetof(dvr_autorec_entry_t, dae_comment), - }, - {} - } -}; +#define CATEGORY_SELECTION_PROP(NUM) \ + .type = PT_STR, .id = "cat" #NUM, .name = N_("Category " #NUM " (selection)"), \ + .desc = N_("The category of the program to look for. The xmltv " \ + "providers often supply detailed categories such as " \ + "Sitcom, Movie, Track/field, etc. " \ + "This let you select from categories for current programmes. " \ + "It is then combined (AND) with other fields to limit to " \ + "programmes that match all categories. " \ + "If this selection list is empty then it means your provider does not " \ + "supply programme categories."), \ + .off = offsetof(dvr_autorec_entry_t, dae_cat##NUM), .opts = PO_EXPERT, \ + .list = dvr_autorec_entry_category_list + +const idclass_t dvr_autorec_entry_class = {.ic_class = "dvrautorec", + .ic_caption = N_("DVR - Auto-recording (Autorecs)"), + .ic_event = "dvrautorec", + .ic_doc = tvh_doc_dvrautorec_class, + .ic_changed = dvr_autorec_entry_class_changed, + .ic_save = dvr_autorec_entry_class_save, + .ic_get_title = dvr_autorec_entry_class_get_title, + .ic_delete = dvr_autorec_entry_class_delete, + .ic_perm = dvr_autorec_entry_class_perm, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable auto-rec rule."), + .def.i = 1, + .off = offsetof(dvr_autorec_entry_t, dae_enabled), + }, + { + .type = PT_STR, + .id = "name", + .name = N_("Name"), + .desc = N_("The name of the the rule."), + .off = offsetof(dvr_autorec_entry_t, dae_name), + }, + { + .type = PT_STR, + .id = "directory", + .name = N_("Directory"), + .desc = N_("When specified, this setting overrides the " + "subdirectory rules (except the base directory) " + "defined in the DVR configuration and puts all " + "recordings done by this entry into the " + "subdirectory named here. See Help for more info."), + .off = offsetof(dvr_autorec_entry_t, dae_directory), + .opts = PO_EXPERT, + }, + { + .type = PT_STR, + .id = "title", + .name = N_("Title (regexp)"), + .desc = N_("The title of the program to look for. Note that " + "this accepts case-insensitive regular expressions."), + .set = dvr_autorec_entry_class_title_set, + .off = offsetof(dvr_autorec_entry_t, dae_title), + }, + /* We provide a small number of selection drop-downs. This is to + * make it easier for users to see what categories are available and + * make it easy to record for example '"Movie" "Martial arts" "Western"' + * without user needing a regex, and allowing them to easily see what + * categories they have available. + */ + {CATEGORY_SELECTION_PROP(1)}, + {CATEGORY_SELECTION_PROP(2)}, + {CATEGORY_SELECTION_PROP(3)}, + { + .type = PT_BOOL, + .id = "fulltext", + .name = N_("Full-text"), + .desc = N_("When the fulltext is checked, the title pattern is " + "matched against title, subtitle, summary and description."), + .off = offsetof(dvr_autorec_entry_t, dae_fulltext), + }, + { + .type = PT_STR, + .id = "channel", + .name = N_("Channel"), + .desc = N_("The channel on which this rule applies, i.e. the " + "channel you're aiming to record. You can leave " + "this field blank to apply the rule to all " + "channels."), + .set = dvr_autorec_entry_class_channel_set, + .get = dvr_autorec_entry_class_channel_get, + .rend = dvr_autorec_entry_class_channel_rend, + .list = channel_class_get_list, + }, + {.type = PT_STR, + .id = "tag", + .name = N_("Channel tag"), + .desc = N_("A channel tag (e.g. a group of channels) to which " + "this rule applies."), + .set = dvr_autorec_entry_class_tag_set, + .get = dvr_autorec_entry_class_tag_get, + .rend = dvr_autorec_entry_class_tag_rend, + .list = channel_tag_class_get_list, + .opts = PO_ADVANCED}, + { + .type = PT_U32, + .id = "btype", + .name = N_("Broadcast type"), + .desc = N_("Select type of broadcast."), + .def.i = DVR_AUTOREC_BTYPE_ALL, + .off = offsetof(dvr_autorec_entry_t, dae_btype), + .list = dvr_autorec_entry_class_btype_list, + .opts = PO_HIDDEN | PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "content_type", + .name = N_("Content type"), + .desc = N_("The content type (Movie/Drama, Sports, etc.) to " + "be used to filter matching events/programs."), + .list = dvr_autorec_entry_class_content_type_list, + .off = offsetof(dvr_autorec_entry_t, dae_content_type), + .opts = PO_ADVANCED, + }, + { + .type = PT_U16, + .id = "star_rating", + .name = N_("Star rating"), + .desc = N_("The minimum number of stars the broadcast should have - in " + "other words, only match programs that have at " + "least this rating."), + .set = dvr_autorec_entry_class_star_rating_set, + .list = dvr_autorec_entry_class_star_rating_list, + .off = offsetof(dvr_autorec_entry_t, dae_star_rating), + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "start", + .name = N_("Start after"), + .desc = N_("An event which starts between this \"start after\" " + "and \"start before\" will be matched (including " + "boundary values)."), + .def.s = N_("Any"), + .set = dvr_autorec_entry_class_start_set, + .get = dvr_autorec_entry_class_start_get, + .list = dvr_autorec_entry_class_time_list_, + .opts = PO_SORTKEY | PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "start_window", + .name = N_("Start before"), + .desc = N_("An event which starts between this \"start after\" " + "and \"start before\" will be matched (including " + "boundary values)."), + .def.s = N_("Any"), + .set = dvr_autorec_entry_class_start_window_set, + .get = dvr_autorec_entry_class_start_window_get, + .list = dvr_autorec_entry_class_time_list_, + .opts = PO_SORTKEY | PO_DOC_NLIST, + }, + { + .type = PT_TIME, + .id = "start_extra", + .name = N_("Extra start time"), + .desc = N_("Start recording earlier than the defined start " + "time by x minutes."), + .off = offsetof(dvr_autorec_entry_t, dae_start_extra), + .list = dvr_autorec_entry_class_extra_list, + .opts = PO_DURATION | PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_TIME, + .id = "stop_extra", + .name = N_("Extra stop time"), + .desc = N_("Continue recording for x minutes after scheduled " + "stop time"), + .off = offsetof(dvr_autorec_entry_t, dae_stop_extra), + .list = dvr_autorec_entry_class_extra_list, + .opts = PO_DURATION | PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .islist = 1, + .id = "weekdays", + .name = N_("Days of week"), + .desc = N_("Days of the week to which the rule should apply."), + .set = dvr_autorec_entry_class_weekdays_set, + .get = dvr_autorec_entry_class_weekdays_get_, + .list = dvr_autorec_entry_class_weekdays_list, + .rend = dvr_autorec_entry_class_weekdays_rend_, + .def.list = dvr_autorec_entry_class_weekdays_default, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_INT, + .id = "minduration", + .name = N_("Minimum duration"), + .desc = N_("The minimal duration of a matching event - in " + "other words, only match programs that are no " + "shorter than this duration."), + .list = dvr_autorec_entry_class_minduration_list, + .off = offsetof(dvr_autorec_entry_t, dae_minduration), + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_INT, + .id = "maxduration", + .name = N_("Maximum duration"), + .desc = N_("The maximal duration of a matching event - in " + "other words, only match programmes that are no " + "longer than this duration."), + .list = dvr_autorec_entry_class_maxduration_list, + .off = offsetof(dvr_autorec_entry_t, dae_maxduration), + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "minyear", + .name = N_("Minimum year"), + .desc = N_("The earliest year for the programme. Programmes must be equal to or later " + "than this year."), + .list = dvr_autorec_entry_class_year_list, + .off = offsetof(dvr_autorec_entry_t, dae_minyear), + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "maxyear", + .name = N_("Maximum year"), + .desc = N_("The latest year for the programme. Programmes must be equal to or earlier " + "than this year."), + .list = dvr_autorec_entry_class_year_list, + .off = offsetof(dvr_autorec_entry_t, dae_maxyear), + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_U16, + .id = "minseason", + .name = N_("Minimum season"), + .desc = N_("The earliest season for the programme. Programmes must be equal to or " + "later than this season."), + .off = offsetof(dvr_autorec_entry_t, dae_minseason), + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_U16, + .id = "maxseason", + .name = N_("Maximum season"), + .desc = N_("The latest season for the programme. Programmes must be equal to or " + "earlier than this season."), + .off = offsetof(dvr_autorec_entry_t, dae_maxseason), + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "pri", + .name = N_("Priority"), + .desc = N_("Priority of the recording. Higher priority entries " + "will take precedence and cancel lower-priority events. " + "The 'Not Set' value inherits the settings from " + "the assigned DVR configuration."), + .list = dvr_entry_class_pri_list, + .def.i = DVR_PRIO_DEFAULT, + .off = offsetof(dvr_autorec_entry_t, dae_pri), + .opts = PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "record", + .name = N_("Duplicate handling"), + .desc = N_("How to handle duplicate recordings. The 'Use DVR " + "Configuration' value (the default) inherits the " + "settings from the assigned DVR configuration"), + .def.i = DVR_AUTOREC_RECORD_DVR_PROFILE, + .doc = prop_doc_duplicate_handling, + .off = offsetof(dvr_autorec_entry_t, dae_record), + .list = dvr_autorec_entry_class_dedup_list, + .opts = PO_HIDDEN | PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "retention", + .name = N_("DVR log retention"), + .desc = N_("Number of days to retain information about recording."), + .def.i = DVR_RET_REM_DVRCONFIG, + .off = offsetof(dvr_autorec_entry_t, dae_retention), + .list = dvr_entry_class_retention_list, + .opts = PO_HIDDEN | PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "removal", + .name = N_("DVR file retention period"), + .desc = N_("Number of days to keep the recorded file."), + .def.i = DVR_RET_REM_DVRCONFIG, + .off = offsetof(dvr_autorec_entry_t, dae_removal), + .list = dvr_entry_class_removal_list, + .opts = PO_HIDDEN | PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "maxcount", + .name = N_("Maximum count (0=default)"), + .desc = N_("The maximum number of times this rule can be " + "triggered."), + .off = offsetof(dvr_autorec_entry_t, dae_max_count), + .opts = PO_HIDDEN | PO_EXPERT, + }, + { + .type = PT_U32, + .id = "maxsched", + .name = N_("Maximum schedules limit (0=default)"), + .desc = N_("The maximum number of recording entries this rule " + "can create."), + .off = offsetof(dvr_autorec_entry_t, dae_max_sched_count), + .opts = PO_HIDDEN | PO_EXPERT, + }, + {.type = PT_STR, + .id = "config_name", + .name = N_("DVR configuration"), + .desc = N_("The DVR profile to be used/used by this rule."), + .set = dvr_autorec_entry_class_config_name_set, + .get = dvr_autorec_entry_class_config_name_get, + .rend = dvr_autorec_entry_class_config_name_rend, + .list = dvr_entry_class_config_name_list, + .opts = PO_ADVANCED}, + { + .type = PT_STR, + .id = "serieslink", + .name = N_("Series link"), + .desc = N_("Series link ID."), + .off = offsetof(dvr_autorec_entry_t, dae_serieslink_uri), + .opts = PO_RDONLY | PO_ADVANCED, + }, + { + .type = PT_STR, + .id = "owner", + .name = N_("Owner"), + .desc = N_("Owner of the rule."), + .off = offsetof(dvr_autorec_entry_t, dae_owner), + .get_opts = dvr_autorec_entry_class_owner_opts, + }, + { + .type = PT_STR, + .id = "creator", + .name = N_("Creator"), + .desc = N_("The user who created the recording, or the " + "auto-recording source and IP address if scheduled " + "by a matching rule."), + .off = offsetof(dvr_autorec_entry_t, dae_creator), + .get_opts = dvr_autorec_entry_class_owner_opts, + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-form text field, enter whatever you like here."), + .off = offsetof(dvr_autorec_entry_t, dae_comment), + }, + {}}}; /** * */ -void -dvr_autorec_init(void) -{ - htsmsg_t *l, *c; - htsmsg_field_t *f; +void dvr_autorec_init(void) { + htsmsg_t * l, *c; + htsmsg_field_t* f; TAILQ_INIT(&autorec_entries); idclass_register(&dvr_autorec_entry_class); - if((l = hts_settings_load("dvr/autorec")) != NULL) { + if ((l = hts_settings_load("dvr/autorec")) != NULL) { HTSMSG_FOREACH(f, l) { - if((c = htsmsg_get_map_by_field(f)) == NULL) + if ((c = htsmsg_get_map_by_field(f)) == NULL) continue; (void)dvr_autorec_create(htsmsg_field_name(f), c); } @@ -1473,10 +1351,8 @@ dvr_autorec_init(void) } } -void -dvr_autorec_done(void) -{ - dvr_autorec_entry_t *dae; +void dvr_autorec_done(void) { + dvr_autorec_entry_t* dae; tvh_mutex_lock(&global_lock); while ((dae = TAILQ_FIRST(&autorec_entries)) != NULL) @@ -1484,27 +1360,21 @@ dvr_autorec_done(void) tvh_mutex_unlock(&global_lock); } -void -dvr_autorec_update(void) -{ - dvr_autorec_entry_t *dae; - TAILQ_FOREACH(dae, &autorec_entries, dae_link) { +void dvr_autorec_update(void) { + dvr_autorec_entry_t* dae; + TAILQ_FOREACH (dae, &autorec_entries, dae_link) { dvr_autorec_changed(dae, 0); dvr_autorec_completed(dae, 0); } } -static void -dvr_autorec_async_reschedule_cb(void *ignored) -{ +static void dvr_autorec_async_reschedule_cb(void* ignored) { tvhdebug(LS_DVR, "dvr_autorec_async_reschedule_cb - begin"); dvr_autorec_update(); tvhdebug(LS_DVR, "dvr_autorec_async_reschedule_cb - end"); } -void -dvr_autorec_async_reschedule(void) -{ +void dvr_autorec_async_reschedule(void) { tvhtrace(LS_DVR, "dvr_autorec_async_reschedule"); static mtimer_t reschedule_timer; mtimer_disarm(&reschedule_timer); @@ -1513,22 +1383,19 @@ dvr_autorec_async_reschedule(void) * such as deleting numerous records due to disabling an autorec * rule. */ - mtimer_arm_rel(&reschedule_timer, dvr_autorec_async_reschedule_cb, NULL, - sec2mono(60)); + mtimer_arm_rel(&reschedule_timer, dvr_autorec_async_reschedule_cb, NULL, sec2mono(60)); } /** * */ -void -dvr_autorec_check_event(epg_broadcast_t *e) -{ - dvr_autorec_entry_t *dae; +void dvr_autorec_check_event(epg_broadcast_t* e) { + dvr_autorec_entry_t* dae; if (e->channel && !e->channel->ch_enabled) return; - TAILQ_FOREACH(dae, &autorec_entries, dae_link) - if(dvr_autorec_cmp(dae, e)) + TAILQ_FOREACH (dae, &autorec_entries, dae_link) + if (dvr_autorec_cmp(dae, e)) dvr_entry_create_by_autorec(1, e, dae); // Note: no longer updating event here as it will be done from EPG // anyway @@ -1537,23 +1404,23 @@ dvr_autorec_check_event(epg_broadcast_t *e) /** * */ -void -dvr_autorec_changed(dvr_autorec_entry_t *dae, int purge) -{ - channel_t *ch; +void dvr_autorec_changed(dvr_autorec_entry_t* dae, int purge) { + channel_t* ch; epg_broadcast_t *e, **disabled = NULL, **p; - int enabled; + int enabled; if (purge) disabled = dvr_autorec_purge_spawns(dae, 1, 1); CHANNEL_FOREACH(ch) { - if (!ch->ch_enabled) continue; - RB_FOREACH(e, &ch->ch_epg_schedule, sched_link) { - if(dvr_autorec_cmp(dae, e)) { + if (!ch->ch_enabled) + continue; + RB_FOREACH (e, &ch->ch_epg_schedule, sched_link) { + if (dvr_autorec_cmp(dae, e)) { enabled = 1; if (disabled) { - for (p = disabled; *p && *p != e; p++); + for (p = disabled; *p && *p != e; p++) + ; enabled = *p == NULL; } dvr_entry_create_by_autorec(enabled, e, dae); @@ -1564,28 +1431,23 @@ dvr_autorec_changed(dvr_autorec_entry_t *dae, int purge) free(disabled); } - /** * */ -void -autorec_destroy_by_channel(channel_t *ch, int delconf) -{ - dvr_autorec_entry_t *dae; +void autorec_destroy_by_channel(channel_t* ch, int delconf) { + dvr_autorec_entry_t* dae; - while((dae = LIST_FIRST(&ch->ch_autorecs)) != NULL) + while ((dae = LIST_FIRST(&ch->ch_autorecs)) != NULL) autorec_entry_destroy(dae, delconf); } /* * */ -void -autorec_destroy_by_channel_tag(channel_tag_t *ct, int delconf) -{ - dvr_autorec_entry_t *dae; +void autorec_destroy_by_channel_tag(channel_tag_t* ct, int delconf) { + dvr_autorec_entry_t* dae; - while((dae = LIST_FIRST(&ct->ct_autorecs)) != NULL) { + while ((dae = LIST_FIRST(&ct->ct_autorecs)) != NULL) { LIST_REMOVE(dae, dae_channel_tag_link); dae->dae_channel_tag = NULL; idnode_notify_changed(&dae->dae_id); @@ -1597,10 +1459,8 @@ autorec_destroy_by_channel_tag(channel_tag_t *ct, int delconf) /* * */ -void -autorec_destroy_by_id(const char *id, int delconf) -{ - dvr_autorec_entry_t *dae; +void autorec_destroy_by_id(const char* id, int delconf) { + dvr_autorec_entry_t* dae; dae = dvr_autorec_find_by_uuid(id); if (dae) @@ -1610,13 +1470,11 @@ autorec_destroy_by_id(const char *id, int delconf) /** * */ -void -autorec_destroy_by_config(dvr_config_t *kcfg, int delconf) -{ - dvr_autorec_entry_t *dae; - dvr_config_t *cfg = NULL; +void autorec_destroy_by_config(dvr_config_t* kcfg, int delconf) { + dvr_autorec_entry_t* dae; + dvr_config_t* cfg = NULL; - while((dae = LIST_FIRST(&kcfg->dvr_autorec_entries)) != NULL) { + while ((dae = LIST_FIRST(&kcfg->dvr_autorec_entries)) != NULL) { LIST_REMOVE(dae, dae_config_link); if (cfg == NULL && delconf) cfg = dvr_config_find_by_name_default(NULL); @@ -1628,17 +1486,14 @@ autorec_destroy_by_config(dvr_config_t *kcfg, int delconf) } } -static inline int extra_valid(time_t extra) -{ +static inline int extra_valid(time_t extra) { return extra != 0 && extra != (time_t)-1; } /** * */ -int -dvr_autorec_get_extra_time_pre( dvr_autorec_entry_t *dae ) -{ +int dvr_autorec_get_extra_time_pre(dvr_autorec_entry_t* dae) { time_t extra = dae->dae_start_extra; if (!extra_valid(extra)) { @@ -1653,9 +1508,7 @@ dvr_autorec_get_extra_time_pre( dvr_autorec_entry_t *dae ) /** * */ -int -dvr_autorec_get_extra_time_post( dvr_autorec_entry_t *dae ) -{ +int dvr_autorec_get_extra_time_post(dvr_autorec_entry_t* dae) { time_t extra = dae->dae_stop_extra; if (!extra_valid(extra)) { @@ -1670,9 +1523,7 @@ dvr_autorec_get_extra_time_post( dvr_autorec_entry_t *dae ) /** * */ -uint32_t -dvr_autorec_get_retention_days( dvr_autorec_entry_t *dae ) -{ +uint32_t dvr_autorec_get_retention_days(dvr_autorec_entry_t* dae) { if (dae->dae_retention > 0) { if (dae->dae_retention > DVR_RET_REM_FOREVER) return DVR_RET_REM_FOREVER; @@ -1685,9 +1536,7 @@ dvr_autorec_get_retention_days( dvr_autorec_entry_t *dae ) /** * */ -uint32_t -dvr_autorec_get_removal_days( dvr_autorec_entry_t *dae ) -{ +uint32_t dvr_autorec_get_removal_days(dvr_autorec_entry_t* dae) { if (dae->dae_removal > 0) { if (dae->dae_removal > DVR_RET_REM_FOREVER) return DVR_RET_REM_FOREVER; diff --git a/src/dvr/dvr_config.c b/src/dvr/dvr_config.c index 8160d351d..c6ea9caf7 100644 --- a/src/dvr/dvr_config.c +++ b/src/dvr/dvr_config.c @@ -36,23 +36,21 @@ int dvr_iov_max; struct dvr_config_list dvrconfigs; -static dvr_config_t *dvrdefaultconfig = NULL; +static dvr_config_t* dvrdefaultconfig = NULL; -static void dvr_config_destroy(dvr_config_t *cfg, int delconf); -static void dvr_update_pathname_from_booleans(dvr_config_t *cfg); +static void dvr_config_destroy(dvr_config_t* cfg, int delconf); +static void dvr_update_pathname_from_booleans(dvr_config_t* cfg); /** * find a dvr config by name, return NULL if not found */ -dvr_config_t * -dvr_config_find_by_name(const char *name) -{ - dvr_config_t *cfg; +dvr_config_t* dvr_config_find_by_name(const char* name) { + dvr_config_t* cfg; if (name == NULL) name = ""; - LIST_FOREACH(cfg, &dvrconfigs, config_link) + LIST_FOREACH (cfg, &dvrconfigs, config_link) if (cfg->dvr_enabled && !strcmp(name, cfg->dvr_config_name)) return cfg; @@ -62,10 +60,8 @@ dvr_config_find_by_name(const char *name) /** * find a dvr config by name, return the default config if not found */ -dvr_config_t * -dvr_config_find_by_name_default(const char *name) -{ - dvr_config_t *cfg; +dvr_config_t* dvr_config_find_by_name_default(const char* name) { + dvr_config_t* cfg; if (dvrdefaultconfig == NULL) dvrdefaultconfig = dvr_config_find_by_name(NULL); @@ -99,17 +95,15 @@ dvr_config_find_by_name_default(const char *name) * return the first config from list if name is not valid * return the default config if not found */ -dvr_config_t * -dvr_config_find_by_list(htsmsg_t *uuids, const char *name) -{ - dvr_config_t *cfg, *res = NULL; - htsmsg_field_t *f; - const char *uuid, *uuid2; - char ubuf[UUID_HEX_SIZE]; +dvr_config_t* dvr_config_find_by_list(htsmsg_t* uuids, const char* name) { + dvr_config_t * cfg, *res = NULL; + htsmsg_field_t* f; + const char * uuid, *uuid2; + char ubuf[UUID_HEX_SIZE]; cfg = dvr_config_find_by_uuid(name); if (!cfg) - cfg = dvr_config_find_by_name(name); + cfg = dvr_config_find_by_name(name); uuid = cfg ? idnode_uuid_as_str(&cfg->dvr_id, ubuf) : ""; if (uuids) { HTSMSG_FOREACH(f, uuids) { @@ -134,17 +128,15 @@ dvr_config_find_by_list(htsmsg_t *uuids, const char *name) /** * */ -static int -dvr_charset_update(dvr_config_t *cfg, const char *charset) -{ +static int dvr_charset_update(dvr_config_t* cfg, const char* charset) { const char *s, *id; - int change = strcmp(cfg->dvr_charset ?: "", charset ?: ""); + int change = strcmp(cfg->dvr_charset ?: "", charset ?: ""); free(cfg->dvr_charset); free(cfg->dvr_charset_id); - s = charset ? charset : intlconv_filesystem_charset(); - id = intlconv_charset_id(s, 1, 1); - cfg->dvr_charset = s ? strdup(s) : NULL; + s = charset ? charset : intlconv_filesystem_charset(); + id = intlconv_charset_id(s, 1, 1); + cfg->dvr_charset = s ? strdup(s) : NULL; cfg->dvr_charset_id = id ? strdup(id) : NULL; return change; } @@ -153,10 +145,8 @@ dvr_charset_update(dvr_config_t *cfg, const char *charset) * create a new named dvr config; the caller is responsible * to avoid duplicates */ -dvr_config_t * -dvr_config_create(const char *name, const char *uuid, htsmsg_t *conf) -{ - dvr_config_t *cfg; +dvr_config_t* dvr_config_create(const char* name, const char* uuid, htsmsg_t* conf) { + dvr_config_t* cfg; if (name == NULL) name = ""; @@ -174,26 +164,26 @@ dvr_config_create(const char *name, const char *uuid, htsmsg_t *conf) return NULL; } - cfg->dvr_enabled = 1; - cfg->dvr_config_name = strdup(name); - cfg->dvr_retention_days = DVR_RET_ONREMOVE; - cfg->dvr_removal_days = DVR_RET_REM_FOREVER; - cfg->dvr_clone = 1; - cfg->dvr_tag_files = 1; + cfg->dvr_enabled = 1; + cfg->dvr_config_name = strdup(name); + cfg->dvr_retention_days = DVR_RET_ONREMOVE; + cfg->dvr_removal_days = DVR_RET_REM_FOREVER; + cfg->dvr_clone = 1; + cfg->dvr_tag_files = 1; cfg->dvr_skip_commercials = 1; dvr_charset_update(cfg, intlconv_filesystem_charset()); - cfg->dvr_warm_time = 30; - cfg->dvr_update_window = 24 * 3600; - cfg->dvr_pathname = strdup("$t$n.$x"); + cfg->dvr_warm_time = 30; + cfg->dvr_update_window = 24 * 3600; + cfg->dvr_pathname = strdup("$t$n.$x"); cfg->dvr_cleanup_threshold_free = 1000; // keep 1000 MiB of free space on disk by default cfg->dvr_cleanup_threshold_used = 0; // disabled - cfg->dvr_autorec_max_count = 50; + cfg->dvr_autorec_max_count = 50; cfg->dvr_format_tvmovies_subdir = strdup("tvmovies"); - cfg->dvr_format_tvshows_subdir = strdup("tvshows"); - cfg->dvr_autorec_dedup = DVR_AUTOREC_RECORD_ALL; + cfg->dvr_format_tvshows_subdir = strdup("tvshows"); + cfg->dvr_autorec_dedup = DVR_AUTOREC_RECORD_ALL; /* Muxer config */ - cfg->dvr_muxcnf.m_cache = MC_CACHE_SYSTEM; + cfg->dvr_muxcnf.m_cache = MC_CACHE_SYSTEM; /* Default recording file and directory permissions */ @@ -234,9 +224,7 @@ dvr_config_create(const char *name, const char *uuid, htsmsg_t *conf) /** * destroy a dvr config */ -static void -dvr_config_destroy(dvr_config_t *cfg, int delconf) -{ +static void dvr_config_destroy(dvr_config_t* cfg, int delconf) { char ubuf[UUID_HEX_SIZE]; idnode_save_check(&cfg->dvr_id, delconf); @@ -274,18 +262,16 @@ dvr_config_destroy(dvr_config_t *cfg, int delconf) /** * */ -static void -dvr_config_storage_check(dvr_config_t *cfg) -{ - char recordings_dir[] = "/var/lib/tvheadend/recordings"; - char home_dir[PATH_MAX + sizeof("/Videos")]; - char dvr_dir[PATH_MAX]; - char buf[PATH_MAX]; - uid_t uid = getuid(); - char *xdg_dir; +static void dvr_config_storage_check(dvr_config_t* cfg) { + char recordings_dir[] = "/var/lib/tvheadend/recordings"; + char home_dir[PATH_MAX + sizeof("/Videos")]; + char dvr_dir[PATH_MAX]; + char buf[PATH_MAX]; + uid_t uid = getuid(); + char* xdg_dir; struct stat st; - if(cfg->dvr_storage != NULL && cfg->dvr_storage[0]) + if (cfg->dvr_storage != NULL && cfg->dvr_storage[0]) return; /* Try to figure out a good place to put them videos */ @@ -309,27 +295,26 @@ dvr_config_storage_check(dvr_config_t *cfg) if ((stat(recordings_dir, &st) == 0) && (st.st_uid == uid)) cfg->dvr_storage = strndup(recordings_dir, sizeof(recordings_dir)); - else if((stat(dvr_dir, &st) == 0) && S_ISDIR(st.st_mode)) - cfg->dvr_storage = strndup(dvr_dir, PATH_MAX); - else if(stat(home_dir, &st) == 0 && S_ISDIR(st.st_mode)) - cfg->dvr_storage = strndup(home_dir, sizeof(home_dir)); + else if ((stat(dvr_dir, &st) == 0) && S_ISDIR(st.st_mode)) + cfg->dvr_storage = strndup(dvr_dir, PATH_MAX); + else if (stat(home_dir, &st) == 0 && S_ISDIR(st.st_mode)) + cfg->dvr_storage = strndup(home_dir, sizeof(home_dir)); else - cfg->dvr_storage = strdup(getcwd(buf, sizeof(buf))); + cfg->dvr_storage = strdup(getcwd(buf, sizeof(buf))); tvhwarn(LS_DVR, - "Output directory for video recording is not yet configured " - "for DVR configuration \"%s\". " - "Defaulting to to \"%s\". " - "This can be changed from the web user interface.", - cfg->dvr_config_name, cfg->dvr_storage); + "Output directory for video recording is not yet configured " + "for DVR configuration \"%s\". " + "Defaulting to to \"%s\". " + "This can be changed from the web user interface.", + cfg->dvr_config_name, + cfg->dvr_storage); } /** * */ -static int -dvr_filename_index(dvr_config_t *cfg) -{ +static int dvr_filename_index(dvr_config_t* cfg) { char *str = cfg->dvr_pathname, *p; for (str = p = cfg->dvr_pathname; *p; p++) { @@ -345,11 +330,9 @@ dvr_filename_index(dvr_config_t *cfg) /** * */ -static int -dvr_match_fmtstr(dvr_config_t *cfg, const char *needle, int nodir) -{ - char *str = cfg->dvr_pathname, *p; - const char *x; +static int dvr_match_fmtstr(dvr_config_t* cfg, const char* needle, int nodir) { + char * str = cfg->dvr_pathname, *p; + const char* x; if (needle == NULL) return -1; @@ -378,12 +361,10 @@ dvr_match_fmtstr(dvr_config_t *cfg, const char *needle, int nodir) /** * */ -static void -dvr_insert_fmtstr(dvr_config_t *cfg, int idx, const char *str) -{ +static void dvr_insert_fmtstr(dvr_config_t* cfg, int idx, const char* str) { size_t t = strlen(cfg->dvr_pathname); size_t l = strlen(str); - char *n = malloc(t + l + 1); + char* n = malloc(t + l + 1); memcpy(n, cfg->dvr_pathname, idx); memcpy(n + idx, str, l); memcpy(n + idx + l, cfg->dvr_pathname + idx, t - idx); @@ -395,11 +376,9 @@ dvr_insert_fmtstr(dvr_config_t *cfg, int idx, const char *str) /** * */ -static void -dvr_insert_fmtstr_before_extension(dvr_config_t *cfg, const char *str) -{ +static void dvr_insert_fmtstr_before_extension(dvr_config_t* cfg, const char* str) { int idx = dvr_match_fmtstr(cfg, "$n", 1); - idx = idx < 0 ? dvr_match_fmtstr(cfg, "$x", 1) : idx; + idx = idx < 0 ? dvr_match_fmtstr(cfg, "$x", 1) : idx; if (idx < 0) { idx = strlen(cfg->dvr_pathname); } else { @@ -415,11 +394,9 @@ dvr_insert_fmtstr_before_extension(dvr_config_t *cfg, const char *str) /** * */ -static void -dvr_remove_fmtstr(dvr_config_t *cfg, int idx, int len) -{ - char *pathname = cfg->dvr_pathname; - size_t l = strlen(pathname); +static void dvr_remove_fmtstr(dvr_config_t* cfg, int idx, int len) { + char* pathname = cfg->dvr_pathname; + size_t l = strlen(pathname); memmove(pathname + idx, pathname + idx + len, l - idx - len); pathname[l - len] = '\0'; } @@ -427,9 +404,7 @@ dvr_remove_fmtstr(dvr_config_t *cfg, int idx, int len) /** * */ -static void -dvr_match_and_insert_or_remove(dvr_config_t *cfg, const char *str, int val, int idx) -{ +static void dvr_match_and_insert_or_remove(dvr_config_t* cfg, const char* str, int val, int idx) { int i = dvr_match_fmtstr(cfg, str, idx < 0 ? 1 : 0); if (val) { if (i < 0) { @@ -451,9 +426,7 @@ dvr_match_and_insert_or_remove(dvr_config_t *cfg, const char *str, int val, int /** * */ -static void -dvr_update_pathname_safe(dvr_config_t *cfg) -{ +static void dvr_update_pathname_safe(dvr_config_t* cfg) { if (cfg->dvr_pathname[0] == '\0') { free(cfg->dvr_pathname); cfg->dvr_pathname = strdup("$t$n.$x"); @@ -466,9 +439,7 @@ dvr_update_pathname_safe(dvr_config_t *cfg) /** * */ -static void -dvr_update_pathname_from_fmtstr(dvr_config_t *cfg) -{ +static void dvr_update_pathname_from_fmtstr(dvr_config_t* cfg) { if (cfg->dvr_pathname == NULL) return; @@ -490,9 +461,7 @@ dvr_update_pathname_from_fmtstr(dvr_config_t *cfg) /** * */ -static void -dvr_update_pathname_from_booleans(dvr_config_t *cfg) -{ +static void dvr_update_pathname_from_booleans(dvr_config_t* cfg) { int i; i = dvr_match_fmtstr(cfg, "$t", 1); @@ -513,9 +482,9 @@ dvr_update_pathname_from_booleans(dvr_config_t *cfg) dvr_match_and_insert_or_remove(cfg, "$-c", cfg->dvr_channel_in_title, -1); dvr_match_and_insert_or_remove(cfg, "$.s", cfg->dvr_subtitle_in_title, -1); - dvr_match_and_insert_or_remove(cfg, "%F", cfg->dvr_date_in_title, -1); - dvr_match_and_insert_or_remove(cfg, "%R", cfg->dvr_time_in_title, -1); - dvr_match_and_insert_or_remove(cfg, "$-e", cfg->dvr_episode_in_title, -1); + dvr_match_and_insert_or_remove(cfg, "%F", cfg->dvr_date_in_title, -1); + dvr_match_and_insert_or_remove(cfg, "%R", cfg->dvr_time_in_title, -1); + dvr_match_and_insert_or_remove(cfg, "$-e", cfg->dvr_episode_in_title, -1); dvr_update_pathname_safe(cfg); } @@ -523,10 +492,8 @@ dvr_update_pathname_from_booleans(dvr_config_t *cfg) /** * */ -void -dvr_config_delete(const char *name) -{ - dvr_config_t *cfg; +void dvr_config_delete(const char* name) { + dvr_config_t* cfg; cfg = dvr_config_find_by_name(name); if (!dvr_config_is_default(cfg)) @@ -538,9 +505,7 @@ dvr_config_delete(const char *name) /** * */ -void -dvr_config_changed(dvr_config_t *cfg) -{ +void dvr_config_changed(dvr_config_t* cfg) { if (dvr_config_is_default(cfg)) cfg->dvr_enabled = 1; cfg->dvr_valid = 1; @@ -557,50 +522,42 @@ dvr_config_changed(dvr_config_t *cfg) cfg->dvr_removal_days = DVR_RET_REM_FOREVER; if (cfg->dvr_retention_days > DVR_RET_REM_FOREVER) cfg->dvr_retention_days = DVR_RET_REM_FOREVER; - if (cfg->dvr_profile && !strcmp(profile_get_name(cfg->dvr_profile), "htsp")) // htsp is for streaming only + if (cfg->dvr_profile && + !strcmp(profile_get_name(cfg->dvr_profile), "htsp")) // htsp is for streaming only cfg->dvr_profile = profile_find_by_name("pass", NULL); } - /* ************************************************************************** * DVR Config Class definition * **************************************************************************/ -static void -dvr_config_class_changed(idnode_t *self) -{ - dvr_config_changed((dvr_config_t *)self); +static void dvr_config_class_changed(idnode_t* self) { + dvr_config_changed((dvr_config_t*)self); } -static htsmsg_t * -dvr_config_class_save(idnode_t *self, char *filename, size_t fsize) -{ - dvr_config_t *cfg = (dvr_config_t *)self; - htsmsg_t *m = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* dvr_config_class_save(idnode_t* self, char* filename, size_t fsize) { + dvr_config_t* cfg = (dvr_config_t*)self; + htsmsg_t* m = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(&cfg->dvr_id, m); if (filename) snprintf(filename, fsize, "dvr/config/%s", idnode_uuid_as_str(&cfg->dvr_id, ubuf)); return m; } -static void -dvr_config_class_delete(idnode_t *self) -{ - dvr_config_t *cfg = (dvr_config_t *)self; +static void dvr_config_class_delete(idnode_t* self) { + dvr_config_t* cfg = (dvr_config_t*)self; if (!dvr_config_is_default(cfg)) - dvr_config_destroy(cfg, 1); + dvr_config_destroy(cfg, 1); } -static int -dvr_config_class_perm(idnode_t *self, access_t *a, htsmsg_t *msg_to_write) -{ - dvr_config_t *cfg = (dvr_config_t *)self; - htsmsg_field_t *f; - const char *uuid, *my_uuid; - char ubuf[UUID_HEX_SIZE]; +static int dvr_config_class_perm(idnode_t* self, access_t* a, htsmsg_t* msg_to_write) { + dvr_config_t* cfg = (dvr_config_t*)self; + htsmsg_field_t* f; + const char * uuid, *my_uuid; + char ubuf[UUID_HEX_SIZE]; - if (access_verify2(a, ACCESS_OR|ACCESS_ADMIN|ACCESS_RECORDER)) + if (access_verify2(a, ACCESS_OR | ACCESS_ADMIN | ACCESS_RECORDER)) return -1; if (!access_verify2(a, ACCESS_ADMIN)) return 0; @@ -617,32 +574,26 @@ fine: return 0; } -static int -dvr_config_class_enabled_set(void *o, const void *v) -{ - dvr_config_t *cfg = (dvr_config_t *)o; +static int dvr_config_class_enabled_set(void* o, const void* v) { + dvr_config_t* cfg = (dvr_config_t*)o; if (dvr_config_is_default(cfg) && dvr_config_is_valid(cfg)) return 0; - if (cfg->dvr_enabled != *(int *)v) { - cfg->dvr_enabled = *(int *)v; + if (cfg->dvr_enabled != *(int*)v) { + cfg->dvr_enabled = *(int*)v; return 1; } return 0; } -static uint32_t -dvr_config_class_enabled_opts(void *o, uint32_t opts) -{ - dvr_config_t *cfg = (dvr_config_t *)o; +static uint32_t dvr_config_class_enabled_opts(void* o, uint32_t opts) { + dvr_config_t* cfg = (dvr_config_t*)o; if (cfg && dvr_config_is_default(cfg) && dvr_config_is_valid(cfg)) return PO_RDONLY; return 0; } -static int -dvr_config_class_name_set(void *o, const void *v) -{ - dvr_config_t *cfg = (dvr_config_t *)o; +static int dvr_config_class_name_set(void* o, const void* v) { + dvr_config_t* cfg = (dvr_config_t*)o; if (dvr_config_is_default(cfg) && dvr_config_is_valid(cfg)) return 0; if (strcmp(cfg->dvr_config_name, v ?: "")) { @@ -655,11 +606,9 @@ dvr_config_class_name_set(void *o, const void *v) return 0; } -static int -dvr_config_class_profile_set(void *o, const void *v) -{ - dvr_config_t *cfg = (dvr_config_t *)o; - profile_t *pro; +static int dvr_config_class_profile_set(void* o, const void* v) { + dvr_config_t* cfg = (dvr_config_t*)o; + profile_t* pro; pro = v ? profile_find_by_uuid(v) : NULL; pro = pro ?: profile_find_by_name(v, "pass"); @@ -679,10 +628,8 @@ dvr_config_class_profile_set(void *o, const void *v) return 0; } -static const void * -dvr_config_class_profile_get(void *o) -{ - dvr_config_t *cfg = (dvr_config_t *)o; +static const void* dvr_config_class_profile_get(void* o) { + dvr_config_t* cfg = (dvr_config_t*)o; if (cfg->dvr_profile) idnode_uuid_as_str(&cfg->dvr_profile->pro_id, prop_sbuf); else @@ -690,20 +637,16 @@ dvr_config_class_profile_get(void *o) return &prop_sbuf_ptr; } -static char * -dvr_config_class_profile_rend(void *o, const char *lang) -{ - dvr_config_t *cfg = (dvr_config_t *)o; +static char* dvr_config_class_profile_rend(void* o, const char* lang) { + dvr_config_t* cfg = (dvr_config_t*)o; if (cfg->dvr_profile) return strdup(profile_get_name(cfg->dvr_profile)); return NULL; } static void -dvr_config_class_get_title - (idnode_t *self, const char *lang, char *dst, size_t dstsize) -{ - dvr_config_t *cfg = (dvr_config_t *)self; +dvr_config_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + dvr_config_t* cfg = (dvr_config_t*)self; if (!dvr_config_is_default(cfg)) { snprintf(dst, dstsize, "%s", cfg->dvr_config_name); } else { @@ -711,66 +654,50 @@ dvr_config_class_get_title } } -static int -dvr_config_class_charset_set(void *o, const void *v) -{ - dvr_config_t *cfg = (dvr_config_t *)o; +static int dvr_config_class_charset_set(void* o, const void* v) { + dvr_config_t* cfg = (dvr_config_t*)o; return dvr_charset_update(cfg, v); } -static htsmsg_t * -dvr_config_class_charset_list(void *o, const char *lang) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "intlconv/charsets"); +static htsmsg_t* dvr_config_class_charset_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "intlconv/charsets"); return m; } -static htsmsg_t * -dvr_config_class_cache_list(void *o, const char *lang) -{ - static struct strtab tab[] = { - { N_("Unknown"), MC_CACHE_UNKNOWN }, - { N_("System"), MC_CACHE_SYSTEM }, - { N_("Don't keep"), MC_CACHE_DONTKEEP }, - { N_("Sync"), MC_CACHE_SYNC }, - { N_("Sync + Don't keep"), MC_CACHE_SYNCDONTKEEP } - }; +static htsmsg_t* dvr_config_class_cache_list(void* o, const char* lang) { + static struct strtab tab[] = {{N_("Unknown"), MC_CACHE_UNKNOWN}, + {N_("System"), MC_CACHE_SYSTEM}, + {N_("Don't keep"), MC_CACHE_DONTKEEP}, + {N_("Sync"), MC_CACHE_SYNC}, + {N_("Sync + Don't keep"), MC_CACHE_SYNCDONTKEEP}}; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -dvr_config_class_removal_list ( void *o, const char *lang ) -{ +static htsmsg_t* dvr_config_class_removal_list(void* o, const char* lang) { static const struct strtab_u32 tab[] = { - { N_("1 day"), DVR_RET_REM_1DAY }, - { N_("3 days"), DVR_RET_REM_3DAY }, - { N_("5 days"), DVR_RET_REM_5DAY }, - { N_("1 week"), DVR_RET_REM_1WEEK }, - { N_("2 weeks"), DVR_RET_REM_2WEEK }, - { N_("3 weeks"), DVR_RET_REM_3WEEK }, - { N_("1 month"), DVR_RET_REM_1MONTH }, - { N_("2 months"), DVR_RET_REM_2MONTH }, - { N_("3 months"), DVR_RET_REM_3MONTH }, - { N_("6 months"), DVR_RET_REM_6MONTH }, - { N_("1 year"), DVR_RET_REM_1YEAR }, - { N_("2 years"), DVR_RET_REM_2YEARS }, - { N_("3 years"), DVR_RET_REM_3YEARS }, - { N_("Maintained space"), DVR_REM_SPACE }, - { N_("Forever"), DVR_RET_REM_FOREVER }, + {N_("1 day"), DVR_RET_REM_1DAY}, + {N_("3 days"), DVR_RET_REM_3DAY}, + {N_("5 days"), DVR_RET_REM_5DAY}, + {N_("1 week"), DVR_RET_REM_1WEEK}, + {N_("2 weeks"), DVR_RET_REM_2WEEK}, + {N_("3 weeks"), DVR_RET_REM_3WEEK}, + {N_("1 month"), DVR_RET_REM_1MONTH}, + {N_("2 months"), DVR_RET_REM_2MONTH}, + {N_("3 months"), DVR_RET_REM_3MONTH}, + {N_("6 months"), DVR_RET_REM_6MONTH}, + {N_("1 year"), DVR_RET_REM_1YEAR}, + {N_("2 years"), DVR_RET_REM_2YEARS}, + {N_("3 years"), DVR_RET_REM_3YEARS}, + {N_("Maintained space"), DVR_REM_SPACE}, + {N_("Forever"), DVR_RET_REM_FOREVER}, }; return strtab2htsmsg_u32(tab, 1, lang); } -static htsmsg_t * -dvr_config_class_remove_after_playback_list ( void *o, const char *lang ) -{ - enum { - ONE_MINUTE = 60, - ONE_HOUR = ONE_MINUTE * 60, - ONE_DAY = ONE_HOUR * 24 - }; +static htsmsg_t* dvr_config_class_remove_after_playback_list(void* o, const char* lang) { + enum { ONE_MINUTE = 60, ONE_HOUR = ONE_MINUTE * 60, ONE_DAY = ONE_HOUR * 24 }; /* We want a few "soon" options (other than immediately) since that * gives the user time to restart the playback if they accidentally @@ -779,116 +706,96 @@ dvr_config_class_remove_after_playback_list ( void *o, const char *lang ) * undelete). */ static const struct strtab_u32 tab[] = { - { N_("Never"), 0 }, - { N_("Immediately"), 1 }, - { N_("1 minute"), ONE_MINUTE }, - { N_("10 minutes"), ONE_MINUTE * 10 }, - { N_("30 minutes"), ONE_MINUTE * 30 }, - { N_("1 hour"), ONE_HOUR }, - { N_("2 hours"), ONE_HOUR * 2 }, - { N_("4 hour"), ONE_HOUR * 4 }, - { N_("8 hour"), ONE_HOUR * 8 }, - { N_("12 hours"), ONE_HOUR * 12 }, - { N_("1 day"), ONE_DAY }, - { N_("2 days"), ONE_DAY * 2 }, - { N_("3 days"), ONE_DAY * 3 }, - { N_("5 days"), ONE_DAY * 5 }, - { N_("1 week"), ONE_DAY * 7 }, - { N_("2 weeks"), ONE_DAY * 14 }, - { N_("3 weeks"), ONE_DAY * 21 }, - { N_("1 month"), ONE_DAY * 31 }, /* Approximations based on RET_REM */ - { N_("2 months"), ONE_DAY * 62 }, - { N_("3 months"), ONE_DAY * 92 }, + {N_("Never"), 0}, + {N_("Immediately"), 1}, + {N_("1 minute"), ONE_MINUTE}, + {N_("10 minutes"), ONE_MINUTE * 10}, + {N_("30 minutes"), ONE_MINUTE * 30}, + {N_("1 hour"), ONE_HOUR}, + {N_("2 hours"), ONE_HOUR * 2}, + {N_("4 hour"), ONE_HOUR * 4}, + {N_("8 hour"), ONE_HOUR * 8}, + {N_("12 hours"), ONE_HOUR * 12}, + {N_("1 day"), ONE_DAY}, + {N_("2 days"), ONE_DAY * 2}, + {N_("3 days"), ONE_DAY * 3}, + {N_("5 days"), ONE_DAY * 5}, + {N_("1 week"), ONE_DAY * 7}, + {N_("2 weeks"), ONE_DAY * 14}, + {N_("3 weeks"), ONE_DAY * 21}, + {N_("1 month"), ONE_DAY * 31}, /* Approximations based on RET_REM */ + {N_("2 months"), ONE_DAY * 62}, + {N_("3 months"), ONE_DAY * 92}, }; return strtab2htsmsg_u32(tab, 1, lang); } - -static htsmsg_t * -dvr_config_class_retention_list ( void *o, const char *lang ) -{ +static htsmsg_t* dvr_config_class_retention_list(void* o, const char* lang) { static const struct strtab_u32 tab[] = { - { N_("1 day"), DVR_RET_REM_1DAY }, - { N_("3 days"), DVR_RET_REM_3DAY }, - { N_("5 days"), DVR_RET_REM_5DAY }, - { N_("1 week"), DVR_RET_REM_1WEEK }, - { N_("2 weeks"), DVR_RET_REM_2WEEK }, - { N_("3 weeks"), DVR_RET_REM_3WEEK }, - { N_("1 month"), DVR_RET_REM_1MONTH }, - { N_("2 months"), DVR_RET_REM_2MONTH }, - { N_("3 months"), DVR_RET_REM_3MONTH }, - { N_("6 months"), DVR_RET_REM_6MONTH }, - { N_("1 year"), DVR_RET_REM_1YEAR }, - { N_("2 years"), DVR_RET_REM_2YEARS }, - { N_("3 years"), DVR_RET_REM_3YEARS }, - { N_("On file removal"), DVR_RET_ONREMOVE }, - { N_("Forever"), DVR_RET_REM_FOREVER }, + {N_("1 day"), DVR_RET_REM_1DAY}, + {N_("3 days"), DVR_RET_REM_3DAY}, + {N_("5 days"), DVR_RET_REM_5DAY}, + {N_("1 week"), DVR_RET_REM_1WEEK}, + {N_("2 weeks"), DVR_RET_REM_2WEEK}, + {N_("3 weeks"), DVR_RET_REM_3WEEK}, + {N_("1 month"), DVR_RET_REM_1MONTH}, + {N_("2 months"), DVR_RET_REM_2MONTH}, + {N_("3 months"), DVR_RET_REM_3MONTH}, + {N_("6 months"), DVR_RET_REM_6MONTH}, + {N_("1 year"), DVR_RET_REM_1YEAR}, + {N_("2 years"), DVR_RET_REM_2YEARS}, + {N_("3 years"), DVR_RET_REM_3YEARS}, + {N_("On file removal"), DVR_RET_ONREMOVE}, + {N_("Forever"), DVR_RET_REM_FOREVER}, }; return strtab2htsmsg_u32(tab, 1, lang); } -static htsmsg_t * -dvr_config_class_extra_list(void *o, const char *lang) -{ +static htsmsg_t* dvr_config_class_extra_list(void* o, const char* lang) { return dvr_entry_class_duration_list(o, - tvh_gettext_lang(lang, N_("Not set (none or channel configuration)")), - 4*60, 1, lang); + tvh_gettext_lang(lang, N_("Not set (none or channel configuration)")), + 4 * 60, + 1, + lang); } -static htsmsg_t * -dvr_config_entry_class_update_window_list(void *o, const char *lang) -{ +static htsmsg_t* dvr_config_entry_class_update_window_list(void* o, const char* lang) { return dvr_entry_class_duration_list(o, - tvh_gettext_lang(lang, N_("Update disabled")), - 24*3600, 60, lang); + tvh_gettext_lang(lang, N_("Update disabled")), + 24 * 3600, + 60, + lang); } -static htsmsg_t * -dvr_autorec_entry_class_record_list ( void *o, const char *lang ) -{ +static htsmsg_t* dvr_autorec_entry_class_record_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Record all"), - DVR_AUTOREC_RECORD_ALL }, - { N_("All: Record if EPG/XMLTV indicates it is a unique programme"), - DVR_AUTOREC_RECORD_UNIQUE }, - { N_("All: Record if different episode number"), - DVR_AUTOREC_RECORD_DIFFERENT_EPISODE_NUMBER }, - { N_("All: Record if different subtitle"), - DVR_AUTOREC_RECORD_DIFFERENT_SUBTITLE }, - { N_("All: Record if different description"), - DVR_AUTOREC_RECORD_DIFFERENT_DESCRIPTION }, - { N_("All: Record once per month"), - DVR_AUTOREC_RECORD_ONCE_PER_MONTH }, - { N_("All: Record once per week"), - DVR_AUTOREC_RECORD_ONCE_PER_WEEK }, - { N_("All: Record once per day"), - DVR_AUTOREC_RECORD_ONCE_PER_DAY }, - { N_("Local: Record if different episode number"), - DVR_AUTOREC_LRECORD_DIFFERENT_EPISODE_NUMBER }, - { N_("Local: Record if different title"), - DVR_AUTOREC_LRECORD_DIFFERENT_TITLE }, - { N_("Local: Record if different subtitle"), - DVR_AUTOREC_LRECORD_DIFFERENT_SUBTITLE }, - { N_("Local: Record if different description"), - DVR_AUTOREC_LRECORD_DIFFERENT_DESCRIPTION }, - { N_("Local: Record once per month"), - DVR_AUTOREC_LRECORD_ONCE_PER_MONTH }, - { N_("Local: Record once per week"), - DVR_AUTOREC_LRECORD_ONCE_PER_WEEK }, - { N_("Local: Record once per day"), - DVR_AUTOREC_LRECORD_ONCE_PER_DAY }, + {N_("Record all"), DVR_AUTOREC_RECORD_ALL}, + {N_("All: Record if EPG/XMLTV indicates it is a unique programme"), + DVR_AUTOREC_RECORD_UNIQUE}, + {N_("All: Record if different episode number"), DVR_AUTOREC_RECORD_DIFFERENT_EPISODE_NUMBER}, + {N_("All: Record if different subtitle"), DVR_AUTOREC_RECORD_DIFFERENT_SUBTITLE}, + {N_("All: Record if different description"), DVR_AUTOREC_RECORD_DIFFERENT_DESCRIPTION}, + {N_("All: Record once per month"), DVR_AUTOREC_RECORD_ONCE_PER_MONTH}, + {N_("All: Record once per week"), DVR_AUTOREC_RECORD_ONCE_PER_WEEK}, + {N_("All: Record once per day"), DVR_AUTOREC_RECORD_ONCE_PER_DAY}, + {N_("Local: Record if different episode number"), + DVR_AUTOREC_LRECORD_DIFFERENT_EPISODE_NUMBER}, + {N_("Local: Record if different title"), DVR_AUTOREC_LRECORD_DIFFERENT_TITLE}, + {N_("Local: Record if different subtitle"), DVR_AUTOREC_LRECORD_DIFFERENT_SUBTITLE}, + {N_("Local: Record if different description"), DVR_AUTOREC_LRECORD_DIFFERENT_DESCRIPTION}, + {N_("Local: Record once per month"), DVR_AUTOREC_LRECORD_ONCE_PER_MONTH}, + {N_("Local: Record once per week"), DVR_AUTOREC_LRECORD_ONCE_PER_WEEK}, + {N_("Local: Record once per day"), DVR_AUTOREC_LRECORD_ONCE_PER_DAY}, }; return strtab2htsmsg(tab, 1, lang); } -static int -dvr_config_class_pathname_set(void *o, const void *v) -{ - dvr_config_t *cfg = (dvr_config_t *)o; - const char *s = v; +static int dvr_config_class_pathname_set(void* o, const void* v) { + dvr_config_t* cfg = (dvr_config_t*)o; + const char* s = v; if (strcmp(cfg->dvr_pathname ?: "", s ?: "")) { free(cfg->dvr_pathname); - cfg->dvr_pathname = s ? strdup(s) : NULL; + cfg->dvr_pathname = s ? strdup(s) : NULL; cfg->dvr_pathname_changed = 1; return 1; } @@ -909,641 +816,630 @@ PROP_DOC(dvrconfig_fanart) PROP_DOC(duplicate_handling) const idclass_t dvr_config_class = { - .ic_class = "dvrconfig", - .ic_caption = N_("DVR - Profiles"), - .ic_event = "dvrconfig", - .ic_doc = tvh_doc_dvrconfig_class, - .ic_changed = dvr_config_class_changed, - .ic_save = dvr_config_class_save, - .ic_get_title = dvr_config_class_get_title, - .ic_delete = dvr_config_class_delete, - .ic_perm = dvr_config_class_perm, - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - { - .name = N_("Filesystem Settings"), - .number = 2, - }, - { - .name = N_("Subdirectory Settings"), - .number = 3, - }, - { - .name = N_("Filename/Tagging Settings"), - .number = 4, - .column = 1, - }, - { - .name = "", - .number = 5, - .parent = 4, - .column = 2, - }, - { - .name = N_("EPG/Autorec Settings"), - .number = 6, - }, - { - .name = N_("Miscellaneous Settings"), - .number = 7, - }, - { - .name = N_("Artwork Settings"), - .number = 8, - .column = 1, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable profile."), - .set = dvr_config_class_enabled_set, - .off = offsetof(dvr_config_t, dvr_enabled), - .def.i = 1, - .group = 1, - .get_opts = dvr_config_class_enabled_opts, - }, - { - .type = PT_STR, - .id = "name", - .name = N_("Configuration name"), - .desc = N_("Name of the profile."), - .set = dvr_config_class_name_set, - .off = offsetof(dvr_config_t, dvr_config_name), - .def.s = "! New config", - .group = 1, - .get_opts = dvr_config_class_enabled_opts, - }, - { - .type = PT_STR, - .id = "profile", - .name = N_("Stream profile"), - .desc = N_("The stream profile the DVR profile will use for " - "recordings."), - .set = dvr_config_class_profile_set, - .get = dvr_config_class_profile_get, - .rend = dvr_config_class_profile_rend, - .list = profile_class_get_list, - .opts = PO_ADVANCED, - .group = 1, - }, - { - .type = PT_U32, - .id = "pri", - .name = N_("Priority"), - .desc = N_("Priority of the entry, higher-priority entries will " - "take precedence and cancel lower-priority events."), - .list = dvr_entry_class_pri_list, - .def.i = DVR_PRIO_NORMAL, - .off = offsetof(dvr_config_t, dvr_pri), - .opts = PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, - .group = 1, - }, - { - .type = PT_U32, - .id = "retention-days", - .name = N_("Recording info retention period"), - .desc = N_("Days to retain information about recordings. Once this period is exceeded, duplicate detection will not be possible."), - .off = offsetof(dvr_config_t, dvr_retention_days), - .def.u32 = DVR_RET_ONREMOVE, - .list = dvr_config_class_retention_list, - .opts = PO_EXPERT | PO_DOC_NLIST, - .group = 1, - }, - { - .type = PT_U32, - .id = "removal-days", - .name = N_("Recorded file(s) retention period"), - .desc = N_("Number of days to keep recorded files."), - .off = offsetof(dvr_config_t, dvr_removal_days), - .def.u32 = DVR_RET_REM_FOREVER, - .list = dvr_config_class_removal_list, - .opts = PO_DOC_NLIST, - .group = 1, - }, - { - .type = PT_U32, - .id = "remove-after-playback", - .name = N_("Automatically delete played recordings"), - .desc = N_("Number of minutes after playback has finished " - "before file should be automatically removed " - "(unless its retention is 'forever'). " - "Note that some clients may pre-cache playback " - "which means the recording will be marked as " - "played when the client has cached the data, " - "which may be before the end of the programme is " - "actually watched." - ), - .off = offsetof(dvr_config_t, dvr_removal_after_playback), - .def.u32 = 0, - .list = dvr_config_class_remove_after_playback_list, - .opts = PO_ADVANCED, - .group = 1, - }, - { - .type = PT_U32, - .id = "pre-extra-time", - .name = N_("Pre-recording padding"), - .desc = N_("Start recording earlier than the defined start " - "time by x minutes: for example, if a program is " - "to start at 13:00 and you set a padding of 5 " - "minutes it will start recording at 12:54:30 " - "(including a warm-up time of 30 seconds). If this " - "isn't specified, any pre-recording padding as set " - "in the channel or DVR entry will be used."), - .off = offsetof(dvr_config_t, dvr_extra_time_pre), - .list = dvr_config_class_extra_list, - .opts = PO_DOC_NLIST, - .group = 1, - }, - { - .type = PT_U32, - .id = "post-extra-time", - .name = N_("Post-recording padding"), - .desc = N_("Continue recording for x minutes after scheduled " - "stop time."), - .off = offsetof(dvr_config_t, dvr_extra_time_post), - .list = dvr_config_class_extra_list, - .opts = PO_DOC_NLIST, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "clone", - .name = N_("Clone scheduled entry on error"), - .desc = N_("If an error occurs clone the scheduled entry and " - "try to record again (if possible)."), - .off = offsetof(dvr_config_t, dvr_clone), - .opts = PO_ADVANCED, - .def.u32 = 1, - .group = 1, - }, - { - .type = PT_U32, - .id = "rerecord-errors", - .name = N_("Try re-scheduling recording if more errors than (0=off)"), - .desc = N_("If more than x errors occur during a recording " - "schedule a re-record (if possible)."), - .off = offsetof(dvr_config_t, dvr_rerecord_errors), - .opts = PO_ADVANCED, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "complex-scheduling", - .name = N_("For autorecs, attempt to find better time slots"), - .desc = N_("When scheduling an autorec, this option attempts " - "to schedule at the earliest time and on the 'best' " - "channel (such as channel with the most failover services). " - "This is useful when multiple timeshift " - "and repeat channels are available. Without this option " - "autorecs may get scheduled on timeshift channels " - "instead of on primary channels. " - "This scheduling " - "requires extra overhead so is disabled by default."), - .off = offsetof(dvr_config_t, dvr_complex_scheduling), - .opts = PO_ADVANCED, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "fetch-artwork", - .name = N_("Fetch artwork for new recordings."), - .desc = N_("Fetch additional artwork from installed providers. " - "Tvheadend has a 'tmdb' and `tvdb' provider which require " - "you to specify your authorized key in the options below."), - .off = offsetof(dvr_config_t, dvr_fetch_artwork), - .opts = PO_ADVANCED, - .group = 8, - }, - { - .type = PT_BOOL, - .id = "fetch-artwork-known-broadcasts-allow-unknown", - .name = N_("Fetch artwork for unidentifiable broadcasts."), - .desc = N_("Artwork fetching requires broadcasts to have good quality " - "information that uniquely identifies them, such as " - "year, season and episode. " - "Without this information, lookups will frequently fail " - "or return incorrect artwork. " - "The default is to only lookup fanart for broadcasts that " - "have high quality identifiable information." - ), - .off = offsetof(dvr_config_t, dvr_fetch_artwork_allow_unknown), - .opts = PO_ADVANCED, - .group = 8, - }, - { - .type = PT_STR, - .id = "fetch-artwork-options", - .name = N_("Additional command line options when fetching artwork for new recordings."), - .desc = N_("Some artwork providers require additional arguments such as " - "'--tmdb-key my_key_from_website'. These can be specified here. " - "See Help for full details."), - .off = offsetof(dvr_config_t, dvr_fetch_artwork_options), - .doc = prop_doc_dvrconfig_fanart, - .opts = PO_ADVANCED, - .group = 8, - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-form field, enter whatever you like here."), - .off = offsetof(dvr_config_t, dvr_comment), - .group = 1, - }, - { - .type = PT_STR, - .id = "storage", - .name = N_("Storage path"), - .desc = N_("Path where the recordings are stored. If " - "components of the path do not exist, " - "Tvheadend will try to create them."), - .off = offsetof(dvr_config_t, dvr_storage), - .group = 2, - }, - { - .type = PT_U32, - .id = "storage-mfree", - .name = N_("Maintain free storage space in MiB"), - .desc = N_("Keep x amount of storage space free."), - .off = offsetof(dvr_config_t, dvr_cleanup_threshold_free), - .def.i = 1000, - .opts = PO_ADVANCED, - .group = 2, - }, - { - .type = PT_U32, - .id = "storage-mused", - .name = N_("Maintain used storage space in MiB (0=disabled)"), - .desc = N_("Use x amount of storage space."), - .off = offsetof(dvr_config_t, dvr_cleanup_threshold_used), - .def.i = 0, - .opts = PO_EXPERT, - .group = 2, - }, - { - .type = PT_PERM, - .id = "directory-permissions", - .name = N_("Directory permissions (octal, e.g. 0775)"), - .desc = N_("Create directories using these permissions."), - .off = offsetof(dvr_config_t, dvr_muxcnf.m_directory_permissions), - .opts = PO_EXPERT, - .def.u32 = 0775, - .group = 2, - }, - { - .type = PT_PERM, - .id = "file-permissions", - .name = N_("File permissions (octal, e.g. 0664)"), - .desc = N_("Create files using these permissions."), - .off = offsetof(dvr_config_t, dvr_muxcnf.m_file_permissions), - .opts = PO_EXPERT, - .def.u32 = 0664, - .group = 2, - }, - { - .type = PT_STR, - .id = "charset", - .name = N_("Character set"), - .desc = N_("Use this character set when setting filenames."), - .off = offsetof(dvr_config_t, dvr_charset), - .set = dvr_config_class_charset_set, - .list = dvr_config_class_charset_list, - .opts = PO_EXPERT, - .def.s = "UTF-8", - .group = 2, - }, - { - .type = PT_STR, - .id = "pathname", - .name = N_("Format string/Pathname specification"), - .desc = N_("The string allows you to manually specify the " - "full path generation using predefined " - "modifiers. See Help for full details."), - .doc = prop_doc_pathname, - .set = dvr_config_class_pathname_set, - .off = offsetof(dvr_config_t, dvr_pathname), - .opts = PO_EXPERT, - .group = 2, - }, - { - .type = PT_INT, - .id = "cache", - .name = N_("Cache scheme"), - .desc = N_("The cache scheme to use/used to store recordings. " - "Leave as \"system\" unless you have a special use " - "case for one of the others. See Help for details."), - .doc = prop_doc_cache_scheme, - .off = offsetof(dvr_config_t, dvr_muxcnf.m_cache), - .def.i = MC_CACHE_DONTKEEP, - .list = dvr_config_class_cache_list, - .opts = PO_EXPERT | PO_DOC_NLIST, - .group = 2, - }, - { - .type = PT_BOOL, - .id = "day-dir", - .name = N_("Make subdirectories per day"), - .desc = N_("Create a new directory per day in the " - "recording system path. Folders will only be " - "created when something is recorded. The format " - "of the directory will be ISO standard YYYY-MM-DD."), - .off = offsetof(dvr_config_t, dvr_dir_per_day), - .opts = PO_EXPERT, - .group = 3, - }, - { - .type = PT_BOOL, - .id = "channel-dir", - .name = N_("Make subdirectories per channel"), - .desc = N_("Create a directory per channel when " - "storing recordings. If both this and the 'directory " - "per day' checkbox is enabled, the date-directory " - "will be the parent of the per-channel directory."), - .off = offsetof(dvr_config_t, dvr_channel_dir), - .opts = PO_EXPERT, - .group = 3, - }, - { - .type = PT_BOOL, - .id = "title-dir", - .name = N_("Make subdirectories per title"), - .desc = N_("Create a directory per title when " - "storing recordings. If the day/channel directory " - "checkboxes are also enabled, those directories " - "will be parents of this directory."), - .off = offsetof(dvr_config_t, dvr_title_dir), - .opts = PO_EXPERT, - .group = 3, - }, - { - .type = PT_STR, - .id = "format-tvmovies-subdir", - .name = N_("Subdirectory for tvmovies for $q format specifier"), - .desc = N_("Subdirectory to use for tvmovies when using the $q specifier. " - "This can contain any alphanumeric " - "characters (A-Za-z0-9). Other characters may be supported depending " - "on your OS and filesystem." - ), - .off = offsetof(dvr_config_t, dvr_format_tvmovies_subdir), - .def.s = "tvmovies", - .opts = PO_EXPERT, - .group = 3, - }, - { - .type = PT_STR, - .id = "format-tvshows-subdir", - .name = N_("Subdirectory for tvshows for $q format specifier"), - .desc = N_("Subdirectory to use for tvshows when using the $q specifier. " - "This can contain any alphanumeric " - "characters (A-Za-z0-9). Other characters may be supported depending " - "on your OS and filesystem." - ), - .off = offsetof(dvr_config_t, dvr_format_tvshows_subdir), - .def.s = "tvshows", - .opts = PO_EXPERT, - .group = 3, - }, - { - .type = PT_BOOL, - .id = "channel-in-title", - .name = N_("Include channel name in filename"), - .desc = N_("Include the name of the channel in " - "the event title. This applies to both the title " - "stored in the file and to the filename itself."), - .off = offsetof(dvr_config_t, dvr_channel_in_title), - .opts = PO_ADVANCED, - .group = 4, - }, - { - .type = PT_BOOL, - .id = "date-in-title", - .name = N_("Include date in filename"), - .desc = N_("Include the date for the recording in " - "the event title. This applies to both the title " - "stored in the file and to the filename itself."), - .off = offsetof(dvr_config_t, dvr_date_in_title), - .opts = PO_ADVANCED, - .group = 4, - }, - { - .type = PT_BOOL, - .id = "time-in-title", - .name = N_("Include time in filename"), - .desc = N_("Include the time for the recording in " - "the event title. This applies to both the title " - "stored in the file and to the filename itself."), - .off = offsetof(dvr_config_t, dvr_time_in_title), - .opts = PO_ADVANCED, - .group = 4, - }, - { - .type = PT_BOOL, - .id = "episode-in-title", - .name = N_("Include episode in filename"), - .desc = N_("Include the season and episode in the " - "title (if available)."), - .off = offsetof(dvr_config_t, dvr_episode_in_title), - .opts = PO_EXPERT, - .group = 4, - }, - { - .type = PT_BOOL, - .id = "subtitle-in-title", - .name = N_("Include subtitle in filename"), - .desc = N_("Include the episode subtitle in the " - "title (if available)."), - .off = offsetof(dvr_config_t, dvr_subtitle_in_title), - .opts = PO_EXPERT, - .group = 4, - }, - { - .type = PT_BOOL, - .id = "omit-title", - .name = N_("Don't include title in filename"), - .desc = N_("Don't include the title in the filename."), - .off = offsetof(dvr_config_t, dvr_omit_title), - .opts = PO_EXPERT, - .group = 5, - }, - { - .type = PT_BOOL, - .id = "clean-title", - .name = N_("Remove all unsafe characters from filename"), - .desc = N_("All characters that could possibly " - "cause problems for filenaming will be replaced " - "with an underscore. See Help for details."), - .doc = prop_doc_dvrconfig_unsafe, - .off = offsetof(dvr_config_t, dvr_clean_title), - .opts = PO_EXPERT, - .group = 5, - }, - { - .type = PT_BOOL, - .id = "whitespace-in-title", - .name = N_("Replace whitespace in title with '-'"), - .desc = N_("Replaces all whitespace in the title with '-'."), - .doc = prop_doc_dvrconfig_whitespace, - .off = offsetof(dvr_config_t, dvr_whitespace_in_title), - .opts = PO_EXPERT, - .group = 5, - }, - { - .type = PT_BOOL, - .id = "windows-compatible-filenames", - .name = N_("Use Windows-compatible filenames"), - .desc = N_("Characters not supported in Windows filenames " - "(e.g. for an SMB/CIFS share) will be stripped out " - "or converted."), - .doc = prop_doc_dvrconfig_windows, - .off = offsetof(dvr_config_t, dvr_windows_compatible_filenames), - .opts = PO_ADVANCED, - .group = 5, - }, - { - .type = PT_BOOL, - .id = "tag-files", - .name = N_("Tag files with metadata"), - .desc = N_("Create tags in recordings using media containers " - "that support metadata (if possible)."), - .off = offsetof(dvr_config_t, dvr_tag_files), - .opts = PO_ADVANCED, - .def.i = 1, - .group = 5, - }, - { - .type = PT_U32, - .id = "epg-update-window", - .name = N_("EPG update window"), - .desc = N_("Maximum allowed difference between event start time when " - "the EPG event is changed in seconds."), - .off = offsetof(dvr_config_t, dvr_update_window), - .list = dvr_config_entry_class_update_window_list, - .def.u32 = 24*3600, - .opts = PO_EXPERT | PO_DOC_NLIST, - .group = 6, - }, - { - .type = PT_BOOL, - .id = "epg-running", - .name = N_("Use EPG running state"), - .desc = N_("Use EITp/f to decide event start/stop. This is " - "also known as \"Accurate Recording\". See Help " - "for details."), - .doc = prop_doc_runningstate, - .off = offsetof(dvr_config_t, dvr_running), - .opts = PO_ADVANCED, - .def.u32 = 1, - .group = 6, - }, - { - .type = PT_U32, - .id = "autorec-maxcount", - .name = N_("Autorec maximum count (0=unlimited)"), - .desc = N_("The maximum number of entries that can be matched."), - .off = offsetof(dvr_config_t, dvr_autorec_max_count), - .opts = PO_ADVANCED, - .def.i = 50, - .group = 6, - }, - { - .type = PT_U32, - .id = "autorec-maxsched", - .name = N_("Autorec maximum schedules limit (0=unlimited)"), - .desc = N_("The maximum number of recordings that can be scheduled."), - .off = offsetof(dvr_config_t, dvr_autorec_max_sched_count), - .opts = PO_ADVANCED, - .group = 6, - }, - { - .type = PT_U32, - .id = "record", - .name = N_("Duplicate handling"), - .desc = N_("How to handle duplicate recordings."), - .def.i = DVR_AUTOREC_RECORD_ALL, - .doc = prop_doc_duplicate_handling, - .off = offsetof(dvr_config_t, dvr_autorec_dedup), - .list = dvr_autorec_entry_class_record_list, - .opts = PO_ADVANCED | PO_DOC_NLIST | PO_HIDDEN, - .group = 6, - }, - { - .type = PT_BOOL, - .id = "skip-commercials", - .name = N_("Skip commercials"), - .desc = N_("Commercials will be dropped from the " - "recordings. Commercial detection works using EITp/f " - "(EPG running state) and for the Swedish channel TV4 " - "(using teletext info)."), - .off = offsetof(dvr_config_t, dvr_skip_commercials), - .opts = PO_ADVANCED, - .def.i = 1, - .group = 6, - }, - { - .type = PT_STR, - .id = "preproc", - .name = N_("Pre-processor command"), - .desc = N_("Script/program to run when a recording starts " - "(service is subscribed but no filename available)."), - .doc = prop_doc_preprocessor, - .off = offsetof(dvr_config_t, dvr_preproc), - .opts = PO_EXPERT, - .group = 7, - }, - { - .type = PT_STR, - .id = "postproc", - .name = N_("Post-processor command"), - .desc = N_("Script/program to run when a recording completes."), - .doc = prop_doc_postprocessor, - .off = offsetof(dvr_config_t, dvr_postproc), - .opts = PO_ADVANCED, - .group = 7, - }, - { - .type = PT_STR, - .id = "postremove", - .name = N_("Post-remove command"), - .desc = N_("Script/program to run when a recording gets removed."), - .doc = prop_doc_postremove, - .off = offsetof(dvr_config_t, dvr_postremove), - .opts = PO_EXPERT, - .group = 7, - }, - { - .type = PT_U32, - .id = "warm-time", - .name = N_("Extra warming up time (seconds)"), - .desc = N_("Additional time (in seconds) in which to get " - "the tuner ready for recording. This is useful for " - "those with tuners that take some time to tune " - "and/or send garbage data at the beginning. "), - .off = offsetof(dvr_config_t, dvr_warm_time), - .opts = PO_EXPERT, - .group = 7, - .def.u32 = 30 - }, - {} - }, + .ic_class = "dvrconfig", + .ic_caption = N_("DVR - Profiles"), + .ic_event = "dvrconfig", + .ic_doc = tvh_doc_dvrconfig_class, + .ic_changed = dvr_config_class_changed, + .ic_save = dvr_config_class_save, + .ic_get_title = dvr_config_class_get_title, + .ic_delete = dvr_config_class_delete, + .ic_perm = dvr_config_class_perm, + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + { + .name = N_("Filesystem Settings"), + .number = 2, + }, + { + .name = N_("Subdirectory Settings"), + .number = 3, + }, + { + .name = N_("Filename/Tagging Settings"), + .number = 4, + .column = 1, + }, + { + .name = "", + .number = 5, + .parent = 4, + .column = 2, + }, + { + .name = N_("EPG/Autorec Settings"), + .number = 6, + }, + { + .name = N_("Miscellaneous Settings"), + .number = 7, + }, + { + .name = N_("Artwork Settings"), + .number = 8, + .column = 1, + }, + {}}, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable profile."), + .set = dvr_config_class_enabled_set, + .off = offsetof(dvr_config_t, dvr_enabled), + .def.i = 1, + .group = 1, + .get_opts = dvr_config_class_enabled_opts, + }, + { + .type = PT_STR, + .id = "name", + .name = N_("Configuration name"), + .desc = N_("Name of the profile."), + .set = dvr_config_class_name_set, + .off = offsetof(dvr_config_t, dvr_config_name), + .def.s = "! New config", + .group = 1, + .get_opts = dvr_config_class_enabled_opts, + }, + { + .type = PT_STR, + .id = "profile", + .name = N_("Stream profile"), + .desc = N_("The stream profile the DVR profile will use for " + "recordings."), + .set = dvr_config_class_profile_set, + .get = dvr_config_class_profile_get, + .rend = dvr_config_class_profile_rend, + .list = profile_class_get_list, + .opts = PO_ADVANCED, + .group = 1, + }, + { + .type = PT_U32, + .id = "pri", + .name = N_("Priority"), + .desc = N_("Priority of the entry, higher-priority entries will " + "take precedence and cancel lower-priority events."), + .list = dvr_entry_class_pri_list, + .def.i = DVR_PRIO_NORMAL, + .off = offsetof(dvr_config_t, dvr_pri), + .opts = PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, + .group = 1, + }, + { + .type = PT_U32, + .id = "retention-days", + .name = N_("Recording info retention period"), + .desc = N_("Days to retain information about recordings. Once this period is exceeded, " + "duplicate detection will not be possible."), + .off = offsetof(dvr_config_t, dvr_retention_days), + .def.u32 = DVR_RET_ONREMOVE, + .list = dvr_config_class_retention_list, + .opts = PO_EXPERT | PO_DOC_NLIST, + .group = 1, + }, + { + .type = PT_U32, + .id = "removal-days", + .name = N_("Recorded file(s) retention period"), + .desc = N_("Number of days to keep recorded files."), + .off = offsetof(dvr_config_t, dvr_removal_days), + .def.u32 = DVR_RET_REM_FOREVER, + .list = dvr_config_class_removal_list, + .opts = PO_DOC_NLIST, + .group = 1, + }, + { + .type = PT_U32, + .id = "remove-after-playback", + .name = N_("Automatically delete played recordings"), + .desc = N_("Number of minutes after playback has finished " + "before file should be automatically removed " + "(unless its retention is 'forever'). " + "Note that some clients may pre-cache playback " + "which means the recording will be marked as " + "played when the client has cached the data, " + "which may be before the end of the programme is " + "actually watched."), + .off = offsetof(dvr_config_t, dvr_removal_after_playback), + .def.u32 = 0, + .list = dvr_config_class_remove_after_playback_list, + .opts = PO_ADVANCED, + .group = 1, + }, + { + .type = PT_U32, + .id = "pre-extra-time", + .name = N_("Pre-recording padding"), + .desc = N_("Start recording earlier than the defined start " + "time by x minutes: for example, if a program is " + "to start at 13:00 and you set a padding of 5 " + "minutes it will start recording at 12:54:30 " + "(including a warm-up time of 30 seconds). If this " + "isn't specified, any pre-recording padding as set " + "in the channel or DVR entry will be used."), + .off = offsetof(dvr_config_t, dvr_extra_time_pre), + .list = dvr_config_class_extra_list, + .opts = PO_DOC_NLIST, + .group = 1, + }, + { + .type = PT_U32, + .id = "post-extra-time", + .name = N_("Post-recording padding"), + .desc = N_("Continue recording for x minutes after scheduled " + "stop time."), + .off = offsetof(dvr_config_t, dvr_extra_time_post), + .list = dvr_config_class_extra_list, + .opts = PO_DOC_NLIST, + .group = 1, + }, + { + .type = PT_BOOL, + .id = "clone", + .name = N_("Clone scheduled entry on error"), + .desc = N_("If an error occurs clone the scheduled entry and " + "try to record again (if possible)."), + .off = offsetof(dvr_config_t, dvr_clone), + .opts = PO_ADVANCED, + .def.u32 = 1, + .group = 1, + }, + { + .type = PT_U32, + .id = "rerecord-errors", + .name = N_("Try re-scheduling recording if more errors than (0=off)"), + .desc = N_("If more than x errors occur during a recording " + "schedule a re-record (if possible)."), + .off = offsetof(dvr_config_t, dvr_rerecord_errors), + .opts = PO_ADVANCED, + .group = 1, + }, + { + .type = PT_BOOL, + .id = "complex-scheduling", + .name = N_("For autorecs, attempt to find better time slots"), + .desc = N_("When scheduling an autorec, this option attempts " + "to schedule at the earliest time and on the 'best' " + "channel (such as channel with the most failover services). " + "This is useful when multiple timeshift " + "and repeat channels are available. Without this option " + "autorecs may get scheduled on timeshift channels " + "instead of on primary channels. " + "This scheduling " + "requires extra overhead so is disabled by default."), + .off = offsetof(dvr_config_t, dvr_complex_scheduling), + .opts = PO_ADVANCED, + .group = 1, + }, + { + .type = PT_BOOL, + .id = "fetch-artwork", + .name = N_("Fetch artwork for new recordings."), + .desc = N_("Fetch additional artwork from installed providers. " + "Tvheadend has a 'tmdb' and `tvdb' provider which require " + "you to specify your authorized key in the options below."), + .off = offsetof(dvr_config_t, dvr_fetch_artwork), + .opts = PO_ADVANCED, + .group = 8, + }, + { + .type = PT_BOOL, + .id = "fetch-artwork-known-broadcasts-allow-unknown", + .name = N_("Fetch artwork for unidentifiable broadcasts."), + .desc = N_("Artwork fetching requires broadcasts to have good quality " + "information that uniquely identifies them, such as " + "year, season and episode. " + "Without this information, lookups will frequently fail " + "or return incorrect artwork. " + "The default is to only lookup fanart for broadcasts that " + "have high quality identifiable information."), + .off = offsetof(dvr_config_t, dvr_fetch_artwork_allow_unknown), + .opts = PO_ADVANCED, + .group = 8, + }, + { + .type = PT_STR, + .id = "fetch-artwork-options", + .name = N_("Additional command line options when fetching artwork for new recordings."), + .desc = N_("Some artwork providers require additional arguments such as " + "'--tmdb-key my_key_from_website'. These can be specified here. " + "See Help for full details."), + .off = offsetof(dvr_config_t, dvr_fetch_artwork_options), + .doc = prop_doc_dvrconfig_fanart, + .opts = PO_ADVANCED, + .group = 8, + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-form field, enter whatever you like here."), + .off = offsetof(dvr_config_t, dvr_comment), + .group = 1, + }, + { + .type = PT_STR, + .id = "storage", + .name = N_("Storage path"), + .desc = N_("Path where the recordings are stored. If " + "components of the path do not exist, " + "Tvheadend will try to create them."), + .off = offsetof(dvr_config_t, dvr_storage), + .group = 2, + }, + { + .type = PT_U32, + .id = "storage-mfree", + .name = N_("Maintain free storage space in MiB"), + .desc = N_("Keep x amount of storage space free."), + .off = offsetof(dvr_config_t, dvr_cleanup_threshold_free), + .def.i = 1000, + .opts = PO_ADVANCED, + .group = 2, + }, + { + .type = PT_U32, + .id = "storage-mused", + .name = N_("Maintain used storage space in MiB (0=disabled)"), + .desc = N_("Use x amount of storage space."), + .off = offsetof(dvr_config_t, dvr_cleanup_threshold_used), + .def.i = 0, + .opts = PO_EXPERT, + .group = 2, + }, + { + .type = PT_PERM, + .id = "directory-permissions", + .name = N_("Directory permissions (octal, e.g. 0775)"), + .desc = N_("Create directories using these permissions."), + .off = offsetof(dvr_config_t, dvr_muxcnf.m_directory_permissions), + .opts = PO_EXPERT, + .def.u32 = 0775, + .group = 2, + }, + { + .type = PT_PERM, + .id = "file-permissions", + .name = N_("File permissions (octal, e.g. 0664)"), + .desc = N_("Create files using these permissions."), + .off = offsetof(dvr_config_t, dvr_muxcnf.m_file_permissions), + .opts = PO_EXPERT, + .def.u32 = 0664, + .group = 2, + }, + { + .type = PT_STR, + .id = "charset", + .name = N_("Character set"), + .desc = N_("Use this character set when setting filenames."), + .off = offsetof(dvr_config_t, dvr_charset), + .set = dvr_config_class_charset_set, + .list = dvr_config_class_charset_list, + .opts = PO_EXPERT, + .def.s = "UTF-8", + .group = 2, + }, + { + .type = PT_STR, + .id = "pathname", + .name = N_("Format string/Pathname specification"), + .desc = N_("The string allows you to manually specify the " + "full path generation using predefined " + "modifiers. See Help for full details."), + .doc = prop_doc_pathname, + .set = dvr_config_class_pathname_set, + .off = offsetof(dvr_config_t, dvr_pathname), + .opts = PO_EXPERT, + .group = 2, + }, + { + .type = PT_INT, + .id = "cache", + .name = N_("Cache scheme"), + .desc = N_("The cache scheme to use/used to store recordings. " + "Leave as \"system\" unless you have a special use " + "case for one of the others. See Help for details."), + .doc = prop_doc_cache_scheme, + .off = offsetof(dvr_config_t, dvr_muxcnf.m_cache), + .def.i = MC_CACHE_DONTKEEP, + .list = dvr_config_class_cache_list, + .opts = PO_EXPERT | PO_DOC_NLIST, + .group = 2, + }, + { + .type = PT_BOOL, + .id = "day-dir", + .name = N_("Make subdirectories per day"), + .desc = N_("Create a new directory per day in the " + "recording system path. Folders will only be " + "created when something is recorded. The format " + "of the directory will be ISO standard YYYY-MM-DD."), + .off = offsetof(dvr_config_t, dvr_dir_per_day), + .opts = PO_EXPERT, + .group = 3, + }, + { + .type = PT_BOOL, + .id = "channel-dir", + .name = N_("Make subdirectories per channel"), + .desc = N_("Create a directory per channel when " + "storing recordings. If both this and the 'directory " + "per day' checkbox is enabled, the date-directory " + "will be the parent of the per-channel directory."), + .off = offsetof(dvr_config_t, dvr_channel_dir), + .opts = PO_EXPERT, + .group = 3, + }, + { + .type = PT_BOOL, + .id = "title-dir", + .name = N_("Make subdirectories per title"), + .desc = N_("Create a directory per title when " + "storing recordings. If the day/channel directory " + "checkboxes are also enabled, those directories " + "will be parents of this directory."), + .off = offsetof(dvr_config_t, dvr_title_dir), + .opts = PO_EXPERT, + .group = 3, + }, + { + .type = PT_STR, + .id = "format-tvmovies-subdir", + .name = N_("Subdirectory for tvmovies for $q format specifier"), + .desc = N_("Subdirectory to use for tvmovies when using the $q specifier. " + "This can contain any alphanumeric " + "characters (A-Za-z0-9). Other characters may be supported depending " + "on your OS and filesystem."), + .off = offsetof(dvr_config_t, dvr_format_tvmovies_subdir), + .def.s = "tvmovies", + .opts = PO_EXPERT, + .group = 3, + }, + { + .type = PT_STR, + .id = "format-tvshows-subdir", + .name = N_("Subdirectory for tvshows for $q format specifier"), + .desc = N_("Subdirectory to use for tvshows when using the $q specifier. " + "This can contain any alphanumeric " + "characters (A-Za-z0-9). Other characters may be supported depending " + "on your OS and filesystem."), + .off = offsetof(dvr_config_t, dvr_format_tvshows_subdir), + .def.s = "tvshows", + .opts = PO_EXPERT, + .group = 3, + }, + { + .type = PT_BOOL, + .id = "channel-in-title", + .name = N_("Include channel name in filename"), + .desc = N_("Include the name of the channel in " + "the event title. This applies to both the title " + "stored in the file and to the filename itself."), + .off = offsetof(dvr_config_t, dvr_channel_in_title), + .opts = PO_ADVANCED, + .group = 4, + }, + { + .type = PT_BOOL, + .id = "date-in-title", + .name = N_("Include date in filename"), + .desc = N_("Include the date for the recording in " + "the event title. This applies to both the title " + "stored in the file and to the filename itself."), + .off = offsetof(dvr_config_t, dvr_date_in_title), + .opts = PO_ADVANCED, + .group = 4, + }, + { + .type = PT_BOOL, + .id = "time-in-title", + .name = N_("Include time in filename"), + .desc = N_("Include the time for the recording in " + "the event title. This applies to both the title " + "stored in the file and to the filename itself."), + .off = offsetof(dvr_config_t, dvr_time_in_title), + .opts = PO_ADVANCED, + .group = 4, + }, + { + .type = PT_BOOL, + .id = "episode-in-title", + .name = N_("Include episode in filename"), + .desc = N_("Include the season and episode in the " + "title (if available)."), + .off = offsetof(dvr_config_t, dvr_episode_in_title), + .opts = PO_EXPERT, + .group = 4, + }, + { + .type = PT_BOOL, + .id = "subtitle-in-title", + .name = N_("Include subtitle in filename"), + .desc = N_("Include the episode subtitle in the " + "title (if available)."), + .off = offsetof(dvr_config_t, dvr_subtitle_in_title), + .opts = PO_EXPERT, + .group = 4, + }, + { + .type = PT_BOOL, + .id = "omit-title", + .name = N_("Don't include title in filename"), + .desc = N_("Don't include the title in the filename."), + .off = offsetof(dvr_config_t, dvr_omit_title), + .opts = PO_EXPERT, + .group = 5, + }, + { + .type = PT_BOOL, + .id = "clean-title", + .name = N_("Remove all unsafe characters from filename"), + .desc = N_("All characters that could possibly " + "cause problems for filenaming will be replaced " + "with an underscore. See Help for details."), + .doc = prop_doc_dvrconfig_unsafe, + .off = offsetof(dvr_config_t, dvr_clean_title), + .opts = PO_EXPERT, + .group = 5, + }, + { + .type = PT_BOOL, + .id = "whitespace-in-title", + .name = N_("Replace whitespace in title with '-'"), + .desc = N_("Replaces all whitespace in the title with '-'."), + .doc = prop_doc_dvrconfig_whitespace, + .off = offsetof(dvr_config_t, dvr_whitespace_in_title), + .opts = PO_EXPERT, + .group = 5, + }, + { + .type = PT_BOOL, + .id = "windows-compatible-filenames", + .name = N_("Use Windows-compatible filenames"), + .desc = N_("Characters not supported in Windows filenames " + "(e.g. for an SMB/CIFS share) will be stripped out " + "or converted."), + .doc = prop_doc_dvrconfig_windows, + .off = offsetof(dvr_config_t, dvr_windows_compatible_filenames), + .opts = PO_ADVANCED, + .group = 5, + }, + { + .type = PT_BOOL, + .id = "tag-files", + .name = N_("Tag files with metadata"), + .desc = N_("Create tags in recordings using media containers " + "that support metadata (if possible)."), + .off = offsetof(dvr_config_t, dvr_tag_files), + .opts = PO_ADVANCED, + .def.i = 1, + .group = 5, + }, + { + .type = PT_U32, + .id = "epg-update-window", + .name = N_("EPG update window"), + .desc = N_("Maximum allowed difference between event start time when " + "the EPG event is changed in seconds."), + .off = offsetof(dvr_config_t, dvr_update_window), + .list = dvr_config_entry_class_update_window_list, + .def.u32 = 24 * 3600, + .opts = PO_EXPERT | PO_DOC_NLIST, + .group = 6, + }, + { + .type = PT_BOOL, + .id = "epg-running", + .name = N_("Use EPG running state"), + .desc = N_("Use EITp/f to decide event start/stop. This is " + "also known as \"Accurate Recording\". See Help " + "for details."), + .doc = prop_doc_runningstate, + .off = offsetof(dvr_config_t, dvr_running), + .opts = PO_ADVANCED, + .def.u32 = 1, + .group = 6, + }, + { + .type = PT_U32, + .id = "autorec-maxcount", + .name = N_("Autorec maximum count (0=unlimited)"), + .desc = N_("The maximum number of entries that can be matched."), + .off = offsetof(dvr_config_t, dvr_autorec_max_count), + .opts = PO_ADVANCED, + .def.i = 50, + .group = 6, + }, + { + .type = PT_U32, + .id = "autorec-maxsched", + .name = N_("Autorec maximum schedules limit (0=unlimited)"), + .desc = N_("The maximum number of recordings that can be scheduled."), + .off = offsetof(dvr_config_t, dvr_autorec_max_sched_count), + .opts = PO_ADVANCED, + .group = 6, + }, + { + .type = PT_U32, + .id = "record", + .name = N_("Duplicate handling"), + .desc = N_("How to handle duplicate recordings."), + .def.i = DVR_AUTOREC_RECORD_ALL, + .doc = prop_doc_duplicate_handling, + .off = offsetof(dvr_config_t, dvr_autorec_dedup), + .list = dvr_autorec_entry_class_record_list, + .opts = PO_ADVANCED | PO_DOC_NLIST | PO_HIDDEN, + .group = 6, + }, + { + .type = PT_BOOL, + .id = "skip-commercials", + .name = N_("Skip commercials"), + .desc = N_("Commercials will be dropped from the " + "recordings. Commercial detection works using EITp/f " + "(EPG running state) and for the Swedish channel TV4 " + "(using teletext info)."), + .off = offsetof(dvr_config_t, dvr_skip_commercials), + .opts = PO_ADVANCED, + .def.i = 1, + .group = 6, + }, + { + .type = PT_STR, + .id = "preproc", + .name = N_("Pre-processor command"), + .desc = N_("Script/program to run when a recording starts " + "(service is subscribed but no filename available)."), + .doc = prop_doc_preprocessor, + .off = offsetof(dvr_config_t, dvr_preproc), + .opts = PO_EXPERT, + .group = 7, + }, + { + .type = PT_STR, + .id = "postproc", + .name = N_("Post-processor command"), + .desc = N_("Script/program to run when a recording completes."), + .doc = prop_doc_postprocessor, + .off = offsetof(dvr_config_t, dvr_postproc), + .opts = PO_ADVANCED, + .group = 7, + }, + { + .type = PT_STR, + .id = "postremove", + .name = N_("Post-remove command"), + .desc = N_("Script/program to run when a recording gets removed."), + .doc = prop_doc_postremove, + .off = offsetof(dvr_config_t, dvr_postremove), + .opts = PO_EXPERT, + .group = 7, + }, + {.type = PT_U32, + .id = "warm-time", + .name = N_("Extra warming up time (seconds)"), + .desc = N_("Additional time (in seconds) in which to get " + "the tuner ready for recording. This is useful for " + "those with tuners that take some time to tune " + "and/or send garbage data at the beginning. "), + .off = offsetof(dvr_config_t, dvr_warm_time), + .opts = PO_EXPERT, + .group = 7, + .def.u32 = 30}, + {}}, }; /** * */ -void -dvr_config_destroy_by_profile(profile_t *pro, int delconf) -{ - dvr_config_t *cfg; +void dvr_config_destroy_by_profile(profile_t* pro, int delconf) { + dvr_config_t* cfg; - while((cfg = LIST_FIRST(&pro->pro_dvr_configs)) != NULL) { + while ((cfg = LIST_FIRST(&pro->pro_dvr_configs)) != NULL) { LIST_REMOVE(cfg, profile_link); cfg->dvr_profile = profile_find_by_name(NULL, "pass"); } @@ -1552,15 +1448,13 @@ dvr_config_destroy_by_profile(profile_t *pro, int delconf) /** * */ -void -dvr_config_init(void) -{ - htsmsg_t *m, *l; - htsmsg_field_t *f; - dvr_config_t *cfg; +void dvr_config_init(void) { + htsmsg_t * m, *l; + htsmsg_field_t* f; + dvr_config_t* cfg; dvr_iov_max = sysconf(_SC_IOV_MAX); - if( dvr_iov_max == -1 ) + if (dvr_iov_max == -1) #ifdef IOV_MAX dvr_iov_max = IOV_MAX; #else @@ -1574,7 +1468,8 @@ dvr_config_init(void) if ((l = hts_settings_load("dvr/config")) != NULL) { HTSMSG_FOREACH(f, l) { - if ((m = htsmsg_get_map_by_field(f)) == NULL) continue; + if ((m = htsmsg_get_map_by_field(f)) == NULL) + continue; (void)dvr_config_create(NULL, htsmsg_field_name(f), m); } htsmsg_destroy(l); @@ -1585,13 +1480,11 @@ dvr_config_init(void) cfg = dvr_config_find_by_name_default(NULL); assert(cfg); - LIST_FOREACH(cfg, &dvrconfigs, config_link) + LIST_FOREACH (cfg, &dvrconfigs, config_link) dvr_config_storage_check(cfg); } -void -dvr_init(void) -{ +void dvr_init(void) { #if ENABLE_INOTIFY dvr_inotify_init(); #endif @@ -1616,10 +1509,8 @@ dvr_init(void) /** * */ -void -dvr_done(void) -{ - dvr_config_t *cfg; +void dvr_done(void) { + dvr_config_t* cfg; #if ENABLE_INOTIFY dvr_inotify_done(); diff --git a/src/dvr/dvr_cutpoints.c b/src/dvr/dvr_cutpoints.c index e3101deb1..581267d4b 100644 --- a/src/dvr/dvr_cutpoints.c +++ b/src/dvr/dvr_cutpoints.c @@ -59,11 +59,8 @@ * 1426.68 2160.16 3 * */ -static int -dvr_parse_edl - ( const char *line, dvr_cutpoint_t *cutpoint, float *frame ) -{ - int action = 0; +static int dvr_parse_edl(const char* line, dvr_cutpoint_t* cutpoint, float* frame) { + int action = 0; float start = 0.0f, end = 0.0f; /* Invalid line */ @@ -71,21 +68,20 @@ dvr_parse_edl return 1; /* Sanity Checks */ - if(start < 0 || end < 0 || end < start || start == end || - action < DVR_CP_CUT || action > DVR_CP_COMM) { + if (start < 0 || end < 0 || end < start || start == end || action < DVR_CP_CUT || + action > DVR_CP_COMM) { tvhwarn(LS_DVR, "Insane entry: start=%f, end=%f. Skipping.", start, end); return 1; } /* Set values */ - cutpoint->dc_start_ms = (int) (start * 1000.0f); - cutpoint->dc_end_ms = (int) (end * 1000.0f); + cutpoint->dc_start_ms = (int)(start * 1000.0f); + cutpoint->dc_end_ms = (int)(end * 1000.0f); cutpoint->dc_type = action; return 0; } - /** * Parse comskip data. * filename, in: full path to comskip file. @@ -101,34 +97,30 @@ dvr_parse_edl * 42417 54004 * */ -static int -dvr_parse_comskip - ( const char *line, dvr_cutpoint_t *cutpoint, float *frame_rate ) -{ +static int dvr_parse_comskip(const char* line, dvr_cutpoint_t* cutpoint, float* frame_rate) { int start = 0, end = 0; /* Header */ - if (sscanf(line, "FILE PROCESSING COMPLETE %*d FRAMES AT %f", - frame_rate) == 1) { + if (sscanf(line, "FILE PROCESSING COMPLETE %*d FRAMES AT %f", frame_rate) == 1) { *frame_rate /= (*frame_rate > 1000.0f ? 100.0f : 1.0f); return 1; // TODO: probably not nice this returns "error" } /* Invalid line */ - if(*frame_rate <= 0.0f || sscanf(line, "%d\t%d", &start, &end) != 2) + if (*frame_rate <= 0.0f || sscanf(line, "%d\t%d", &start, &end) != 2) return 1; /* Sanity Checks */ - if(start < 0 || end < 0 || end < start || start == end) { + if (start < 0 || end < 0 || end < start || start == end) { tvherror(LS_DVR, "Insane EDL entry: start=%d, end=%d. Skipping.", start, end); return 1; } /* Set values */ - cutpoint->dc_start_ms = (int) ((start * 1000) / *frame_rate); - cutpoint->dc_end_ms = (int) ((end * 1000) / *frame_rate); + cutpoint->dc_start_ms = (int)((start * 1000) / *frame_rate); + cutpoint->dc_end_ms = (int)((end * 1000) / *frame_rate); // Comskip don't have different actions, so use DVR_CP_COMM (Commercial skip) - cutpoint->dc_type = DVR_CP_COMM; + cutpoint->dc_type = DVR_CP_COMM; return 0; } @@ -136,25 +128,21 @@ dvr_parse_comskip /** * Wrapper for basic file processing */ -static int -dvr_parse_file - ( const char *path, dvr_cutpoint_list_t *cut_list, void *p ) -{ +static int dvr_parse_file(const char* path, dvr_cutpoint_list_t* cut_list, void* p) { int line_count = 0, valid_lines = -1; - int (*parse) (const char *line, dvr_cutpoint_t *cp, float *framerate) = p; - dvr_cutpoint_t *cp = NULL; - float frate = 0.0; - char line[DVR_MAX_CUTPOINT_LINE]; - FILE *file = tvh_fopen(path, "r"); + int (*parse)(const char* line, dvr_cutpoint_t* cp, float* framerate) = p; + dvr_cutpoint_t* cp = NULL; + float frate = 0.0; + char line[DVR_MAX_CUTPOINT_LINE]; + FILE* file = tvh_fopen(path, "r"); if (file == NULL) return -1; - while (line_count < DVR_MAX_READ_CUTFILE_LINES && - valid_lines < DVR_MAX_CUT_ENTRIES) { + while (line_count < DVR_MAX_READ_CUTFILE_LINES && valid_lines < DVR_MAX_CUT_ENTRIES) { /* Read line */ - if(fgets(line, DVR_MAX_CUTPOINT_LINE, file) == NULL) + if (fgets(line, DVR_MAX_CUTPOINT_LINE, file) == NULL) break; line_count++; @@ -171,7 +159,8 @@ dvr_parse_file } done: - if (cp) free(cp); + if (cp) + free(cp); fclose(file); return valid_lines; } @@ -186,32 +175,30 @@ done: * // TODO: possibly could be better with some sort of auto-detect */ static struct { - const char *ext; - int (*parse) (const char *path, dvr_cutpoint_list_t *, void *); - void *opaque; + const char* ext; + int (*parse)(const char* path, dvr_cutpoint_list_t*, void*); + void* opaque; } dvr_cutpoint_parsers[] = { - { - .ext = "txt", - .parse = dvr_parse_file, - .opaque = dvr_parse_comskip, - }, - { - .ext = "edl", - .parse = dvr_parse_file, - .opaque = dvr_parse_edl, - }, + { + .ext = "txt", + .parse = dvr_parse_file, + .opaque = dvr_parse_comskip, + }, + { + .ext = "edl", + .parse = dvr_parse_file, + .opaque = dvr_parse_edl, + }, }; /* * Return cutpoint data for a recording (if present). */ -dvr_cutpoint_list_t * -dvr_get_cutpoint_list (dvr_entry_t *de) -{ - int i; - char *path, *sptr; - const char *filename; - dvr_cutpoint_list_t *cuts; +dvr_cutpoint_list_t* dvr_get_cutpoint_list(dvr_entry_t* de) { + int i; + char * path, *sptr; + const char* filename; + dvr_cutpoint_list_t* cuts; /* Check this is a valid recording */ assert(de != NULL); @@ -239,15 +226,14 @@ dvr_get_cutpoint_list (dvr_entry_t *de) for (i = 0; i < ARRAY_SIZE(dvr_cutpoint_parsers); i++) { /* Add extension */ - strcpy(sptr+1, dvr_cutpoint_parsers[i].ext); + strcpy(sptr + 1, dvr_cutpoint_parsers[i].ext); /* Check file exists (and readable) */ if (access(path, R_OK)) continue; /* Try parsing */ - if (dvr_cutpoint_parsers[i].parse(path, cuts, - dvr_cutpoint_parsers[i].opaque) != -1) + if (dvr_cutpoint_parsers[i].parse(path, cuts, dvr_cutpoint_parsers[i].opaque) != -1) break; } @@ -263,11 +249,10 @@ dvr_get_cutpoint_list (dvr_entry_t *de) /* * Delete list */ -void -dvr_cutpoint_list_destroy (dvr_cutpoint_list_t *list) -{ - dvr_cutpoint_t *cp; - if(!list) return; +void dvr_cutpoint_list_destroy(dvr_cutpoint_list_t* list) { + dvr_cutpoint_t* cp; + if (!list) + return; while ((cp = TAILQ_FIRST(list))) { TAILQ_REMOVE(list, cp, dc_link); free(cp); @@ -278,11 +263,9 @@ dvr_cutpoint_list_destroy (dvr_cutpoint_list_t *list) /* * Delete cutpoint files */ -void -dvr_cutpoint_delete_files (const char *s) -{ +void dvr_cutpoint_delete_files(const char* s) { char *path, *dot; - int i; + int i; // TODO: harcoded 3 for max extension, plus 1 for . and one for termination path = alloca(strlen(s) + 5); @@ -301,8 +284,8 @@ dvr_cutpoint_delete_files (const char *s) continue; /* Delete File */ - tvhinfo(LS_DVR, "Erasing cutpoint file '%s'", (const char *)path); + tvhinfo(LS_DVR, "Erasing cutpoint file '%s'", (const char*)path); if (unlink(path)) - tvherror(LS_DVR, "unable to remove cutpoint file '%s'", (const char *)path); + tvherror(LS_DVR, "unable to remove cutpoint file '%s'", (const char*)path); } } diff --git a/src/dvr/dvr_db.c b/src/dvr/dvr_db.c index 5a625d329..8cf8f0733 100644 --- a/src/dvr/dvr_db.c +++ b/src/dvr/dvr_db.c @@ -34,129 +34,118 @@ #include "epggrab.h" //Needed to get the epggrab_conf.epgdb_processparentallabels flag. struct dvr_entry_list dvrentries; -static int dvr_in_init; +static int dvr_in_init; #if ENABLE_DBUS_1 static mtimer_t dvr_dbus_timer; #endif /// Periodically pre-fetch artwork for scheduled recordings. -static mtimer_t dvr_fanart_timer; -static string_list_t *dvr_fanart_to_prefetch; - -static void dvr_entry_deferred_destroy(dvr_entry_t *de); -static void dvr_entry_set_timer(dvr_entry_t *de); -static void dvr_timer_rerecord(void *aux); -static void dvr_timer_expire(void *aux); -static void dvr_timer_disarm(void *aux); -static void dvr_timer_remove_files(void *aux); -static void dvr_entry_start_recording(dvr_entry_t *de, int clone); -static void dvr_timer_start_recording(void *aux); -static void dvr_timer_stop_recording(void *aux); -static int dvr_entry_rerecord(dvr_entry_t *de); -static time_t dvr_entry_get_segment_stop_extra(dvr_entry_t *de); -static void dvr_entry_watched_timer_arm(dvr_entry_t* de); -static void dvr_entry_watched_timer_disarm(dvr_entry_t* de); - -static dvr_entry_t *_dvr_duplicate_event(dvr_entry_t *de); - -static const void *dvr_entry_class_rating_icon_url_get(void *o); +static mtimer_t dvr_fanart_timer; +static string_list_t* dvr_fanart_to_prefetch; + +static void dvr_entry_deferred_destroy(dvr_entry_t* de); +static void dvr_entry_set_timer(dvr_entry_t* de); +static void dvr_timer_rerecord(void* aux); +static void dvr_timer_expire(void* aux); +static void dvr_timer_disarm(void* aux); +static void dvr_timer_remove_files(void* aux); +static void dvr_entry_start_recording(dvr_entry_t* de, int clone); +static void dvr_timer_start_recording(void* aux); +static void dvr_timer_stop_recording(void* aux); +static int dvr_entry_rerecord(dvr_entry_t* de); +static time_t dvr_entry_get_segment_stop_extra(dvr_entry_t* de); +static void dvr_entry_watched_timer_arm(dvr_entry_t* de); +static void dvr_entry_watched_timer_disarm(dvr_entry_t* de); + +static dvr_entry_t* _dvr_duplicate_event(dvr_entry_t* de); + +static const void* dvr_entry_class_rating_icon_url_get(void* o); /* * */ -static struct strtab schedstatetab[] = { - { "SCHEDULED", DVR_SCHEDULED }, - { "RECORDING", DVR_RECORDING }, - { "COMPLETED", DVR_COMPLETED }, - { "NOSTATE", DVR_NOSTATE }, - { "MISSEDTM", DVR_MISSED_TIME } -}; - -const char * -dvr_entry_sched_state2str(dvr_entry_sched_state_t s) -{ +static struct strtab schedstatetab[] = {{"SCHEDULED", DVR_SCHEDULED}, + {"RECORDING", DVR_RECORDING}, + {"COMPLETED", DVR_COMPLETED}, + {"NOSTATE", DVR_NOSTATE}, + {"MISSEDTM", DVR_MISSED_TIME}}; + +const char* dvr_entry_sched_state2str(dvr_entry_sched_state_t s) { return val2str(s, schedstatetab) ?: "INVALID"; } -static struct strtab rsstatetab[] = { - { "PENDING", DVR_RS_PENDING }, - { "WAIT", DVR_RS_WAIT_PROGRAM_START }, - { "RUNNING", DVR_RS_RUNNING }, - { "COMMERCIAL", DVR_RS_COMMERCIAL }, - { "ERROR", DVR_RS_ERROR }, - { "EPGWAIT", DVR_RS_EPG_WAIT }, - { "FINISHED", DVR_RS_FINISHED } -}; +static struct strtab rsstatetab[] = {{"PENDING", DVR_RS_PENDING}, + {"WAIT", DVR_RS_WAIT_PROGRAM_START}, + {"RUNNING", DVR_RS_RUNNING}, + {"COMMERCIAL", DVR_RS_COMMERCIAL}, + {"ERROR", DVR_RS_ERROR}, + {"EPGWAIT", DVR_RS_EPG_WAIT}, + {"FINISHED", DVR_RS_FINISHED}}; -const char * -dvr_entry_rs_state2str(dvr_rs_state_t s) -{ +const char* dvr_entry_rs_state2str(dvr_rs_state_t s) { return val2str(s, rsstatetab) ?: "INVALID"; } -void -dvr_entry_trace_(const char *file, int line, dvr_entry_t *de, const char *fmt, ...) -{ - char buf[512], ubuf[UUID_HEX_SIZE]; +void dvr_entry_trace_(const char* file, int line, dvr_entry_t* de, const char* fmt, ...) { + char buf[512], ubuf[UUID_HEX_SIZE]; va_list args; va_start(args, fmt); - snprintf(buf, sizeof(buf), "entry %s - %s", - idnode_uuid_as_str(&de->de_id, ubuf), - fmt); + snprintf(buf, sizeof(buf), "entry %s - %s", idnode_uuid_as_str(&de->de_id, ubuf), fmt); tvhlogv(file, line, LOG_TRACE, LS_DVR, buf, &args); va_end(args); } -void -dvr_entry_trace_time2_(const char *file, int line, - dvr_entry_t *de, - const char *t1name, time_t t1, - const char *t2name, time_t t2, - const char *fmt, ...) -{ - char buf[512], ubuf[UUID_HEX_SIZE], t1buf[32], t2buf[32]; +void dvr_entry_trace_time2_(const char* file, + int line, + dvr_entry_t* de, + const char* t1name, + time_t t1, + const char* t2name, + time_t t2, + const char* fmt, + ...) { + char buf[512], ubuf[UUID_HEX_SIZE], t1buf[32], t2buf[32]; va_list args; va_start(args, fmt); - snprintf(buf, sizeof(buf), "entry %s%s%s%s%s%s%s%s%s - %s", - idnode_uuid_as_str(&de->de_id, ubuf), - t1name ? " " : "", - t1name ? t1name : "", - t1name ? " " : "", - t1name ? gmtime2local(t1, t1buf, sizeof(t1buf)) : "", - t2name ? " " : "", - t2name ? t2name : "", - t2name ? " " : "", - t2name ? gmtime2local(t2, t2buf, sizeof(t2buf)) : "", - fmt); + snprintf(buf, + sizeof(buf), + "entry %s%s%s%s%s%s%s%s%s - %s", + idnode_uuid_as_str(&de->de_id, ubuf), + t1name ? " " : "", + t1name ? t1name : "", + t1name ? " " : "", + t1name ? gmtime2local(t1, t1buf, sizeof(t1buf)) : "", + t2name ? " " : "", + t2name ? t2name : "", + t2name ? " " : "", + t2name ? gmtime2local(t2, t2buf, sizeof(t2buf)) : "", + fmt); tvhlogv(file, line, LOG_TRACE, LS_DVR, buf, &args); va_end(args); } -int dvr_entry_is_upcoming(dvr_entry_t *entry) -{ +int dvr_entry_is_upcoming(dvr_entry_t* entry) { dvr_entry_sched_state_t state = entry->de_sched_state; return state == DVR_RECORDING || state == DVR_SCHEDULED || state == DVR_NOSTATE; } -int dvr_entry_is_upcoming_nodup(dvr_entry_t *entry) -{ +int dvr_entry_is_upcoming_nodup(dvr_entry_t* entry) { dvr_entry_sched_state_t state = entry->de_sched_state; if (_dvr_duplicate_event(entry)) return 0; return state == DVR_RECORDING || state == DVR_SCHEDULED || state == DVR_NOSTATE; } -int dvr_entry_is_finished(dvr_entry_t *entry, int flags) -{ +int dvr_entry_is_finished(dvr_entry_t* entry, int flags) { if (dvr_entry_is_upcoming(entry)) return 0; if (!flags || (flags & DVR_FINISHED_ALL)) return 1; - int removed = entry->de_file_removed || /* Removed by tvheadend */ - (entry->de_sched_state != DVR_MISSED_TIME && - dvr_get_filesize(entry, 0) < 0); /* Removed externally? */ + int removed = entry->de_file_removed || /* Removed by tvheadend */ + (entry->de_sched_state != DVR_MISSED_TIME && + dvr_get_filesize(entry, 0) < 0); /* Removed externally? */ int success = entry->de_sched_state == DVR_COMPLETED; if (success) { @@ -180,11 +169,8 @@ int dvr_entry_is_finished(dvr_entry_t *entry, int flags) /* * */ -int -dvr_entry_verify(dvr_entry_t *de, access_t *a, int readonly) -{ - if (access_verify2(a, ACCESS_FAILED_RECORDER) && - dvr_entry_is_finished(de, DVR_FINISHED_FAILED)) +int dvr_entry_verify(dvr_entry_t* de, access_t* a, int readonly) { + if (access_verify2(a, ACCESS_FAILED_RECORDER) && dvr_entry_is_finished(de, DVR_FINISHED_FAILED)) return -1; if (readonly && !access_verify2(a, ACCESS_ALL_RECORDER)) @@ -201,9 +187,7 @@ dvr_entry_verify(dvr_entry_t *de, access_t *a, int readonly) /* * */ -void -dvr_entry_changed(dvr_entry_t *de) -{ +void dvr_entry_changed(dvr_entry_t* de) { idnode_changed(&de->de_id); htsp_dvr_entry_update(de); } @@ -211,25 +195,25 @@ dvr_entry_changed(dvr_entry_t *de) /* * */ -int -dvr_entry_set_state(dvr_entry_t *de, dvr_entry_sched_state_t state, - dvr_rs_state_t rec_state, int error_code) -{ +int dvr_entry_set_state(dvr_entry_t* de, + dvr_entry_sched_state_t state, + dvr_rs_state_t rec_state, + int error_code) { char id[16]; - if (de->de_sched_state != state || - de->de_rec_state != rec_state || + if (de->de_sched_state != state || de->de_rec_state != rec_state || de->de_last_error != error_code) { - dvr_entry_trace(de, "set state - state %s rec_state %s error '%s'", - dvr_entry_sched_state2str(state), - dvr_entry_rs_state2str(rec_state), - streaming_code2txt(error_code)); + dvr_entry_trace(de, + "set state - state %s rec_state %s error '%s'", + dvr_entry_sched_state2str(state), + dvr_entry_rs_state2str(rec_state), + streaming_code2txt(error_code)); if (de->de_bcast) { snprintf(id, sizeof(id), "%u", de->de_bcast->id); notify_delayed(id, "epg", "dvr_update"); } de->de_sched_state = state; - de->de_rec_state = rec_state; - de->de_last_error = error_code; + de->de_rec_state = rec_state; + de->de_last_error = error_code; idnode_notify_changed(&de->de_id); htsp_dvr_entry_update(de); return 1; @@ -240,9 +224,7 @@ dvr_entry_set_state(dvr_entry_t *de, dvr_entry_sched_state_t state, /* * */ -int -dvr_entry_assign_broadcast(dvr_entry_t *de, epg_broadcast_t *bcast) -{ +int dvr_entry_assign_broadcast(dvr_entry_t* de, epg_broadcast_t* bcast) { char id[16]; if (bcast != de->de_bcast) { if (de->de_bcast) { @@ -251,7 +233,7 @@ dvr_entry_assign_broadcast(dvr_entry_t *de, epg_broadcast_t *bcast) LIST_REMOVE(de, de_bcast_link); de->de_bcast->ops->putref((epg_object_t*)de->de_bcast); notify_delayed(id, "epg", "dvr_delete"); - de->de_bcast = NULL; + de->de_bcast = NULL; de->de_dvb_eid = 0; } if (bcast) { @@ -270,9 +252,7 @@ dvr_entry_assign_broadcast(dvr_entry_t *de, epg_broadcast_t *bcast) /* * */ -static void -dvr_entry_dont_rerecord(dvr_entry_t *de, int dont_rerecord) -{ +static void dvr_entry_dont_rerecord(dvr_entry_t* de, int dont_rerecord) { dont_rerecord = dont_rerecord ? 1 : 0; if (de->de_dont_rerecord ? 1 : 0 != dont_rerecord) { dvr_entry_trace(de, "don't rerecord change %d", dont_rerecord); @@ -285,9 +265,8 @@ dvr_entry_dont_rerecord(dvr_entry_t *de, int dont_rerecord) * */ static int -dvr_entry_change_parent_child(dvr_entry_t *parent, dvr_entry_t *child, void *origin, int save) -{ - dvr_entry_t *p; +dvr_entry_change_parent_child(dvr_entry_t* parent, dvr_entry_t* child, void* origin, int save) { + dvr_entry_t* p; if (parent == NULL && child == NULL) return 0; @@ -301,76 +280,75 @@ dvr_entry_change_parent_child(dvr_entry_t *parent, dvr_entry_t *child, void *ori } if (child == NULL) { if (parent->de_child) { - p = parent->de_child->de_parent; + p = parent->de_child->de_parent; parent->de_child->de_parent = NULL; - if (save && p && p != origin) idnode_changed(&p->de_id); + if (save && p && p != origin) + idnode_changed(&p->de_id); parent->de_child = NULL; - if (save && origin != parent) idnode_changed(&parent->de_id); + if (save && origin != parent) + idnode_changed(&parent->de_id); return 1; } return 0; } if (parent == NULL) { if (child->de_parent) { - p = child->de_parent->de_child; + p = child->de_parent->de_child; child->de_parent->de_child = NULL; - if (save && p && p != origin) idnode_changed(&p->de_id); + if (save && p && p != origin) + idnode_changed(&p->de_id); child->de_parent = NULL; - if (save && origin != child) idnode_changed(&child->de_id); + if (save && origin != child) + idnode_changed(&child->de_id); return 1; } return 0; } if (parent->de_child) { - p = parent->de_child->de_parent; + p = parent->de_child->de_parent; parent->de_child->de_parent = NULL; - if (save && p) idnode_changed(&p->de_id); + if (save && p) + idnode_changed(&p->de_id); } if (child->de_parent) { - p = child->de_parent->de_child; + p = child->de_parent->de_child; child->de_parent->de_child = NULL; - if (save && p) idnode_changed(&p->de_id); + if (save && p) + idnode_changed(&p->de_id); } parent->de_child = child; child->de_parent = parent; - if (save && origin != parent) idnode_changed(&parent->de_id); - if (save && origin != child) idnode_changed(&child->de_id); + if (save && origin != parent) + idnode_changed(&parent->de_id); + if (save && origin != child) + idnode_changed(&child->de_id); return 1; } /* * Start / stop time calculators */ -static inline int extra_valid(time_t extra) -{ +static inline int extra_valid(time_t extra) { return extra != 0 && extra != (time_t)-1; } -static uint32_t -dvr_entry_warm_time( dvr_entry_t *de ) -{ +static uint32_t dvr_entry_warm_time(dvr_entry_t* de) { return MIN(de->de_config->dvr_warm_time, 600); } -time_t -dvr_entry_get_start_time( dvr_entry_t *de, int warm ) -{ - int64_t b = (dvr_entry_get_extra_time_pre(de)) + - (warm ? dvr_entry_warm_time(de) : 0); +time_t dvr_entry_get_start_time(dvr_entry_t* de, int warm) { + int64_t b = (dvr_entry_get_extra_time_pre(de)) + (warm ? dvr_entry_warm_time(de) : 0); if (de->de_start < b) return 0; return de->de_start - b; } -time_t -dvr_entry_get_stop_time( dvr_entry_t *de ) -{ - return time_t_out_of_range((int64_t)de->de_stop + dvr_entry_get_segment_stop_extra(de) + dvr_entry_get_extra_time_post(de)); +time_t dvr_entry_get_stop_time(dvr_entry_t* de) { + return time_t_out_of_range((int64_t)de->de_stop + dvr_entry_get_segment_stop_extra(de) + + dvr_entry_get_extra_time_post(de)); } -time_t -dvr_entry_get_extra_time_pre( dvr_entry_t *de ) -{ +time_t dvr_entry_get_extra_time_pre(dvr_entry_t* de) { time_t extra = de->de_start_extra; if (de->de_timerec) @@ -381,12 +359,10 @@ dvr_entry_get_extra_time_pre( dvr_entry_t *de ) if (!extra_valid(extra)) extra = de->de_config->dvr_extra_time_pre; } - return MINMAX(extra, 0, 24*60) * 60; + return MINMAX(extra, 0, 24 * 60) * 60; } -time_t -dvr_entry_get_extra_time_post( dvr_entry_t *de ) -{ +time_t dvr_entry_get_extra_time_post(dvr_entry_t* de) { time_t extra = de->de_stop_extra; if (de->de_timerec) @@ -397,13 +373,11 @@ dvr_entry_get_extra_time_post( dvr_entry_t *de ) if (!extra_valid(extra)) extra = de->de_config->dvr_extra_time_post; } - return MINMAX(extra, 0, 24*60) * 60; + return MINMAX(extra, 0, 24 * 60) * 60; } -char * -dvr_entry_get_retention_string ( dvr_entry_t *de ) -{ - char buf[24]; +char* dvr_entry_get_retention_string(dvr_entry_t* de) { + char buf[24]; uint32_t retention = dvr_entry_get_retention_days(de); if (retention < DVR_RET_ONREMOVE) @@ -416,10 +390,8 @@ dvr_entry_get_retention_string ( dvr_entry_t *de ) return strdup(buf); } -char * -dvr_entry_get_removal_string ( dvr_entry_t *de ) -{ - char buf[24]; +char* dvr_entry_get_removal_string(dvr_entry_t* de) { + char buf[24]; uint32_t removal = dvr_entry_get_removal_days(de); if (removal < DVR_REM_SPACE) @@ -432,9 +404,7 @@ dvr_entry_get_removal_string ( dvr_entry_t *de ) return strdup(buf); } -uint32_t -dvr_entry_get_retention_days( dvr_entry_t *de ) -{ +uint32_t dvr_entry_get_retention_days(dvr_entry_t* de) { if (de->de_retention > 0) { if (de->de_retention > DVR_RET_REM_FOREVER) return DVR_RET_REM_FOREVER; @@ -444,9 +414,7 @@ dvr_entry_get_retention_days( dvr_entry_t *de ) return dvr_retention_cleanup(de->de_config->dvr_retention_days); } -uint32_t -dvr_entry_get_removal_days ( dvr_entry_t *de ) -{ +uint32_t dvr_entry_get_removal_days(dvr_entry_t* de) { if (de->de_removal > 0) { if (de->de_removal > DVR_RET_REM_FOREVER) return DVR_RET_REM_FOREVER; @@ -456,16 +424,12 @@ dvr_entry_get_removal_days ( dvr_entry_t *de ) return dvr_retention_cleanup(de->de_config->dvr_removal_days); } -uint32_t -dvr_entry_get_rerecord_errors( dvr_entry_t *de ) -{ +uint32_t dvr_entry_get_rerecord_errors(dvr_entry_t* de) { return de->de_config->dvr_rerecord_errors; } -int -dvr_entry_get_epg_running( dvr_entry_t *de ) -{ - channel_t *ch; +int dvr_entry_get_epg_running(dvr_entry_t* de) { + channel_t* ch; if (de->de_dvb_eid == 0) return 0; @@ -480,17 +444,15 @@ dvr_entry_get_epg_running( dvr_entry_t *de ) * DBUS next dvr start notifications */ #if ENABLE_DBUS_1 -static void -dvr_dbus_timer_cb( void *aux ) -{ - dvr_entry_t *de; - time_t result, start, max = 0; +static void dvr_dbus_timer_cb(void* aux) { + dvr_entry_t* de; + time_t result, start, max = 0; static time_t last_result = 0; lock_assert(&global_lock); /* find the maximum value */ - LIST_FOREACH(de, &dvrentries, de_global_link) { + LIST_FOREACH (de, &dvrentries, de_global_link) { if (de->de_sched_state != DVR_SCHEDULED) continue; start = dvr_entry_get_start_time(de, 1); @@ -499,7 +461,7 @@ dvr_dbus_timer_cb( void *aux ) } /* lower the maximum value */ result = max; - LIST_FOREACH(de, &dvrentries, de_global_link) { + LIST_FOREACH (de, &dvrentries, de_global_link) { if (de->de_sched_state != DVR_SCHEDULED) continue; start = dvr_entry_get_start_time(de, 1); @@ -517,13 +479,11 @@ dvr_dbus_timer_cb( void *aux ) /* * */ -static void -dvr_entry_retention_arm(dvr_entry_t *de, gti_callback_t *cb, time_t when) -{ +static void dvr_entry_retention_arm(dvr_entry_t* de, gti_callback_t* cb, time_t when) { uint32_t rerecord = dvr_entry_get_rerecord_errors(de); if (rerecord && (when - gclk()) > 3600) { when = gclk() + 3600; - cb = dvr_timer_rerecord; + cb = dvr_timer_rerecord; dvr_entry_trace_time1(de, "when", when, "retention arm - rerecord"); } else { dvr_entry_trace_time1(de, "when", when, "retention arm", "when"); @@ -535,11 +495,9 @@ dvr_entry_retention_arm(dvr_entry_t *de, gti_callback_t *cb, time_t when) * Returns 1 if the database entry should be deleted on file removal * NOTE: retention can be postponed when retention < removal */ -static int -dvr_entry_delete_retention_expired(dvr_entry_t *de) -{ +static int dvr_entry_delete_retention_expired(dvr_entry_t* de) { uint32_t retention = dvr_entry_get_retention_days(de); - time_t stop; + time_t stop; if (retention == DVR_RET_ONREMOVE) return 1; @@ -554,13 +512,11 @@ dvr_entry_delete_retention_expired(dvr_entry_t *de) /* * */ -static void -dvr_entry_retention_timer(dvr_entry_t *de) -{ - time_t stop = de->de_stop; - uint32_t removal = dvr_entry_get_removal_days(de); +static void dvr_entry_retention_timer(dvr_entry_t* de) { + time_t stop = de->de_stop; + uint32_t removal = dvr_entry_get_removal_days(de); uint32_t retention = dvr_entry_get_retention_days(de); - int save; + int save; if ((removal > 0 || retention == 0) && removal < DVR_REM_SPACE && dvr_get_filesize(de, 0) > 0) { stop = time_t_out_of_range((int64_t)de->de_stop + removal * (int64_t)86400); @@ -570,9 +526,10 @@ dvr_entry_retention_timer(dvr_entry_t *de) } save = 0; if (dvr_get_filename(de)) - save = dvr_entry_delete(de); // delete actual file - if (dvr_entry_delete_retention_expired(de)) { // in case retention was postponed (retention < removal) - dvr_entry_deferred_destroy(de); // also remove database entry + save = dvr_entry_delete(de); // delete actual file + if (dvr_entry_delete_retention_expired( + de)) { // in case retention was postponed (retention < removal) + dvr_entry_deferred_destroy(de); // also remove database entry return; } if (save) @@ -580,22 +537,22 @@ dvr_entry_retention_timer(dvr_entry_t *de) } if (retention < DVR_RET_ONREMOVE && - (dvr_get_filesize(de, 0) < 0 || removal == DVR_RET_REM_FOREVER)) { // we need the database entry for later file removal + (dvr_get_filesize(de, 0) < 0 || + removal == DVR_RET_REM_FOREVER)) { // we need the database entry for later file removal stop = time_t_out_of_range((int64_t)de->de_stop + retention * (int64_t)86400); dvr_entry_retention_arm(de, dvr_timer_expire, stop); - } - else { - dvr_entry_retention_arm(de, dvr_timer_disarm, - dvr_entry_get_rerecord_errors(de) ? INT_MAX : 0); // extend disarm to keep the rerecord logic running + } else { + dvr_entry_retention_arm(de, + dvr_timer_disarm, + dvr_entry_get_rerecord_errors(de) ? INT_MAX + : 0); // extend disarm to keep the rerecord logic running } } /* * No state */ -static void -dvr_entry_nostate(dvr_entry_t *de, int error_code) -{ +static void dvr_entry_nostate(dvr_entry_t* de, int error_code) { dvr_entry_set_state(de, DVR_NOSTATE, DVR_RS_FINISHED, error_code); dvr_entry_retention_timer(de); } @@ -603,10 +560,8 @@ dvr_entry_nostate(dvr_entry_t *de, int error_code) /* * Missed time */ -static void -dvr_entry_missed_time(dvr_entry_t *de, int error_code) -{ - dvr_autorec_entry_t *dae = de->de_autorec; +static void dvr_entry_missed_time(dvr_entry_t* de, int error_code) { + dvr_autorec_entry_t* dae = de->de_autorec; dvr_entry_set_state(de, DVR_MISSED_TIME, DVR_RS_FINISHED, error_code); dvr_entry_retention_timer(de); @@ -619,9 +574,7 @@ dvr_entry_missed_time(dvr_entry_t *de, int error_code) /* * Completed */ -static int -dvr_entry_completed(dvr_entry_t *de, int error_code) -{ +static int dvr_entry_completed(dvr_entry_t* de, int error_code) { int change; change = dvr_entry_set_state(de, DVR_COMPLETED, DVR_RS_FINISHED, error_code); #if ENABLE_INOTIFY @@ -636,102 +589,96 @@ dvr_entry_completed(dvr_entry_t *de, int error_code) /** * Return printable status for a dvr entry */ -const char * -dvr_entry_status(dvr_entry_t *de) -{ - switch(de->de_sched_state) { - case DVR_SCHEDULED: - return N_("Scheduled for recording"); - - case DVR_RECORDING: - - switch(de->de_rec_state) { - case DVR_RS_PENDING: - return N_("Waiting for stream"); - case DVR_RS_WAIT_PROGRAM_START: - return N_("Waiting for program start"); - case DVR_RS_RUNNING: - return N_("Running"); - case DVR_RS_COMMERCIAL: - return N_("Commercial break"); - case DVR_RS_ERROR: - return streaming_code2txt(de->de_last_error); - case DVR_RS_EPG_WAIT: - return N_("Waiting for EPG running flag"); - case DVR_RS_FINISHED: - return N_("Finished"); - default: - return N_("Invalid"); - } +const char* dvr_entry_status(dvr_entry_t* de) { + switch (de->de_sched_state) { + case DVR_SCHEDULED: + return N_("Scheduled for recording"); + + case DVR_RECORDING: + + switch (de->de_rec_state) { + case DVR_RS_PENDING: + return N_("Waiting for stream"); + case DVR_RS_WAIT_PROGRAM_START: + return N_("Waiting for program start"); + case DVR_RS_RUNNING: + return N_("Running"); + case DVR_RS_COMMERCIAL: + return N_("Commercial break"); + case DVR_RS_ERROR: + return streaming_code2txt(de->de_last_error); + case DVR_RS_EPG_WAIT: + return N_("Waiting for EPG running flag"); + case DVR_RS_FINISHED: + return N_("Finished"); + default: + return N_("Invalid"); + } - case DVR_COMPLETED: - switch(de->de_last_error) { - case SM_CODE_INVALID_TARGET: - return N_("File not created"); - case SM_CODE_USER_ACCESS: - case SM_CODE_USER_LIMIT: - case SM_CODE_NO_SPACE: - case SM_CODE_PREVIOUSLY_RECORDED: + case DVR_COMPLETED: + switch (de->de_last_error) { + case SM_CODE_INVALID_TARGET: + return N_("File not created"); + case SM_CODE_USER_ACCESS: + case SM_CODE_USER_LIMIT: + case SM_CODE_NO_SPACE: + case SM_CODE_PREVIOUSLY_RECORDED: + return streaming_code2txt(de->de_last_error); + default: + break; + } + if (dvr_get_filesize(de, 0) < 0 && !de->de_file_removed) + return N_("File missing"); + if (de->de_last_error != SM_CODE_FORCE_OK && + de->de_data_errors >= DVR_MAX_DATA_ERRORS) /* user configurable threshold? */ + return N_("Too many data errors"); + if (de->de_last_error) return streaming_code2txt(de->de_last_error); - default: - break; - } - if (dvr_get_filesize(de, 0) < 0 && !de->de_file_removed) - return N_("File missing"); - if(de->de_last_error != SM_CODE_FORCE_OK && - de->de_data_errors >= DVR_MAX_DATA_ERRORS) /* user configurable threshold? */ - return N_("Too many data errors"); - if(de->de_last_error) - return streaming_code2txt(de->de_last_error); - else - return N_("Completed OK"); + else + return N_("Completed OK"); - case DVR_MISSED_TIME: - if (de->de_last_error == SM_CODE_SVC_NOT_ENABLED || de->de_last_error == SM_CODE_NO_SPACE) - return streaming_code2txt(de->de_last_error); - return N_("Time missed"); + case DVR_MISSED_TIME: + if (de->de_last_error == SM_CODE_SVC_NOT_ENABLED || de->de_last_error == SM_CODE_NO_SPACE) + return streaming_code2txt(de->de_last_error); + return N_("Time missed"); - default: - return N_("Invalid"); + default: + return N_("Invalid"); } } - /** * */ -const char * -dvr_entry_schedstatus(dvr_entry_t *de) -{ - const char *s; - uint32_t rerecord; - - switch(de->de_sched_state) { - case DVR_SCHEDULED: - s = "scheduled"; - break; - case DVR_RECORDING: - s = de->de_last_error ? "recordingError" : "recording"; - break; - case DVR_COMPLETED: - s = "completed"; - if(!dvr_entry_is_completed_ok(de) || - (dvr_get_filesize(de, 0) < 0 && !de->de_file_removed)) +const char* dvr_entry_schedstatus(dvr_entry_t* de) { + const char* s; + uint32_t rerecord; + + switch (de->de_sched_state) { + case DVR_SCHEDULED: + s = "scheduled"; + break; + case DVR_RECORDING: + s = de->de_last_error ? "recordingError" : "recording"; + break; + case DVR_COMPLETED: + s = "completed"; + if (!dvr_entry_is_completed_ok(de) || (dvr_get_filesize(de, 0) < 0 && !de->de_file_removed)) + s = "completedError"; + rerecord = de->de_dont_rerecord ? 0 : dvr_entry_get_rerecord_errors(de); + if (rerecord && (de->de_errors || de->de_data_errors > rerecord)) + s = "completedRerecord"; + break; + case DVR_MISSED_TIME: s = "completedError"; - rerecord = de->de_dont_rerecord ? 0 : dvr_entry_get_rerecord_errors(de); - if(rerecord && (de->de_errors || de->de_data_errors > rerecord)) - s = "completedRerecord"; - break; - case DVR_MISSED_TIME: - s = "completedError"; - if (de->de_last_error == SM_CODE_SVC_NOT_ENABLED) - s = "completedWarning"; - rerecord = de->de_dont_rerecord ? 0 : dvr_entry_get_rerecord_errors(de); - if(rerecord) - s = "completedRerecord"; - break; - default: - s = "unknown"; + if (de->de_last_error == SM_CODE_SVC_NOT_ENABLED) + s = "completedWarning"; + rerecord = de->de_dont_rerecord ? 0 : dvr_entry_get_rerecord_errors(de); + if (rerecord) + s = "completedRerecord"; + break; + default: + s = "unknown"; } return s; } @@ -739,13 +686,11 @@ dvr_entry_schedstatus(dvr_entry_t *de) /** * */ -uint32_t -dvr_usage_count(access_t *aa) -{ - dvr_entry_t *de; - uint32_t used = 0; +uint32_t dvr_usage_count(access_t* aa) { + dvr_entry_t* de; + uint32_t used = 0; - LIST_FOREACH(de, &dvrentries, de_global_link) { + LIST_FOREACH (de, &dvrentries, de_global_link) { if (de->de_sched_state != DVR_RECORDING) continue; if (de->de_owner && de->de_owner[0]) { @@ -759,9 +704,7 @@ dvr_usage_count(access_t *aa) return used; } -int -dvr_entry_allow_fanart_lookup(const dvr_entry_t *de) -{ +int dvr_entry_allow_fanart_lookup(const dvr_entry_t* de) { char ubuf[UUID_HEX_SIZE]; /* User doesn't want us to fetch artwork? */ @@ -769,8 +712,7 @@ dvr_entry_allow_fanart_lookup(const dvr_entry_t *de) return 0; /* Entry already have artwork? So nothing to do */ - if (de->de_image && *de->de_image && - de->de_fanart_image && *de->de_fanart_image) + if (de->de_image && *de->de_image && de->de_fanart_image && *de->de_fanart_image) return 0; /* Allow any artwork even if we can't identify episode? */ @@ -781,11 +723,11 @@ dvr_entry_allow_fanart_lookup(const dvr_entry_t *de) * bad artwork. Good episodes have a season/episode (assume * episode) or year (assume movie). */ - if (!de->de_epnum.s_num && !de->de_epnum.e_num && - !de->de_copyright_year) { - tvhdebug(LS_DVR, "Ignoring fanart for entry without good data for %s \"%s\"", - lang_str_get(de->de_title, NULL), - idnode_uuid_as_str(&de->de_id, ubuf)); + if (!de->de_epnum.s_num && !de->de_epnum.e_num && !de->de_copyright_year) { + tvhdebug(LS_DVR, + "Ignoring fanart for entry without good data for %s \"%s\"", + lang_str_get(de->de_title, NULL), + idnode_uuid_as_str(&de->de_id, ubuf)); return 0; } @@ -798,23 +740,18 @@ dvr_entry_allow_fanart_lookup(const dvr_entry_t *de) /// have limits on how frequently artwork can be fetched. /// It doesn't matter if the entry gets deleted before we /// perform the check. -static void -dvr_entry_fanart_add_to_prefetch(const dvr_entry_t *de) -{ +static void dvr_entry_fanart_add_to_prefetch(const dvr_entry_t* de) { char ubuf[UUID_HEX_SIZE]; if (!dvr_entry_allow_fanart_lookup(de)) return; - string_list_insert(dvr_fanart_to_prefetch, - idnode_uuid_as_str(&de->de_id, ubuf)); + string_list_insert(dvr_fanart_to_prefetch, idnode_uuid_as_str(&de->de_id, ubuf)); } -static void -dvr_entry_fanart_prefetch_cb(void *aux) -{ - char *id; - dvr_entry_t *de; +static void dvr_entry_fanart_prefetch_cb(void* aux) { + char* id; + dvr_entry_t* de; lock_assert(&global_lock); @@ -843,12 +780,13 @@ dvr_entry_fanart_prefetch_cb(void *aux) // Re-arm timer with a slight random factor to avoid queries at same // time every hour. - mtimer_arm_rel(&dvr_fanart_timer, dvr_entry_fanart_prefetch_cb, NULL, sec2mono(3600 + random() % 900)); + mtimer_arm_rel(&dvr_fanart_timer, + dvr_entry_fanart_prefetch_cb, + NULL, + sec2mono(3600 + random() % 900)); } -void -dvr_entry_set_timer(dvr_entry_t *de) -{ +void dvr_entry_set_timer(dvr_entry_t* de) { time_t now = gclk(), start, stop; if (dvr_in_init) @@ -862,7 +800,7 @@ dvr_entry_set_timer(dvr_entry_t *de) if (now >= stop || de->de_dont_reschedule) { /* EPG thinks that the program is running */ - if(de->de_running_start > de->de_running_stop && !de->de_dont_reschedule) { + if (de->de_running_start > de->de_running_stop && !de->de_dont_reschedule) { stop = now + 10; if (de->de_sched_state == DVR_RECORDING) { dvr_entry_trace_time1(de, "stop", stop, "set timer - running+"); @@ -876,21 +814,21 @@ dvr_entry_set_timer(dvr_entry_t *de) } /* Files are missing and job was completed */ - if(htsmsg_is_empty(de->de_files) && !de->de_dont_reschedule) + if (htsmsg_is_empty(de->de_files) && !de->de_dont_reschedule) dvr_entry_missed_time(de, de->de_last_error); else dvr_entry_completed(de, de->de_last_error); - if(dvr_entry_rerecord(de)) + if (dvr_entry_rerecord(de)) return; - } else if (de->de_sched_state == DVR_RECORDING) { + } else if (de->de_sched_state == DVR_RECORDING) { if (!de->de_enabled) { dvr_stop_recording(de, SM_CODE_ABORTED, 1, 0); return; } -recording: + recording: dvr_entry_trace_time1(de, "stop", stop, "set timer - arm"); gtimer_arm_absn(&de->de_timer, dvr_timer_stop_recording, de, stop); @@ -909,22 +847,23 @@ recording: dvr_entry_trace(de, "set timer - nostate"); dvr_entry_nostate(de, de->de_last_error); - } } - /** * Get episode name */ -static char * -dvr_entry_get_episode(epg_broadcast_t *bcast, char *buf, int len) -{ +static char* dvr_entry_get_episode(epg_broadcast_t* bcast, char* buf, int len) { if (!bcast) return NULL; if (epg_broadcast_epnumber_format(bcast, - buf, len, NULL, - _("Season %d"), ".", _("Episode %d"), "/%d")) + buf, + len, + NULL, + _("Season %d"), + ".", + _("Episode %d"), + "/%d")) return buf; return NULL; } @@ -933,10 +872,9 @@ dvr_entry_get_episode(epg_broadcast_t *bcast, char *buf, int len) * Find dvr entry using 'fuzzy' search */ static int -dvr_entry_fuzzy_match(dvr_entry_t *de, epg_broadcast_t *e, uint16_t eid, int64_t time_window) -{ - time_t t1, t2; - const char *title1, *title2; +dvr_entry_fuzzy_match(dvr_entry_t* de, epg_broadcast_t* e, uint16_t eid, int64_t time_window) { + time_t t1, t2; + const char * title1, *title2; epg_episode_num_t epnum; /* Wrong length (+/-20%) */ @@ -978,10 +916,9 @@ dvr_entry_fuzzy_match(dvr_entry_t *de, epg_broadcast_t *e, uint16_t eid, int64_t * or "Season A.Episode Y" * or some combination. */ -static int extract_season_episode(epg_episode_num_t *epnum, const char *text) -{ - uint32_t s = 0, sc = 0, e = 0, ec = 0; - const char *ch = text; +static int extract_season_episode(epg_episode_num_t* epnum, const char* text) { + uint32_t s = 0, sc = 0, e = 0, ec = 0; + const char* ch = text; memset(epnum, 0, sizeof(*epnum)); @@ -990,7 +927,8 @@ static int extract_season_episode(epg_episode_num_t *epnum, const char *text) goto _episode; ch += 6; - for (; *ch == ' '; ch++); + for (; *ch == ' '; ch++) + ; for (; isdigit(*ch); ch++) s = (s * 10) + (*ch - '0'); if (*ch == '/') { @@ -1008,7 +946,8 @@ _episode: if (strncasecmp(ch, "Episode", 7)) return 0; ch += 7; - for (; *ch == ' '; ch++); + for (; *ch == ' '; ch++) + ; for (; isdigit(*ch); ch++) e = (e * 10) + (*ch - '0'); if (*ch == '/') { @@ -1033,22 +972,19 @@ _episode: /** * Create the event from config */ -dvr_entry_t * -dvr_entry_create(const char *uuid, htsmsg_t *conf, int clone) -{ +dvr_entry_t* dvr_entry_create(const char* uuid, htsmsg_t* conf, int clone) { dvr_entry_t *de, *de2; - int64_t start, stop, create, watched, now; - htsmsg_t *m; - char ubuf[UUID_HEX_SIZE], ubuf2[UUID_HEX_SIZE]; - const char *s; + int64_t start, stop, create, watched, now; + htsmsg_t* m; + char ubuf[UUID_HEX_SIZE], ubuf2[UUID_HEX_SIZE]; + const char* s; if (conf) { if (htsmsg_get_s64(conf, "start", &start)) return NULL; if (htsmsg_get_s64(conf, "stop", &stop)) return NULL; - if ((htsmsg_get_str(conf, "channel")) == NULL && - (htsmsg_get_str(conf, "channelname")) == NULL) + if ((htsmsg_get_str(conf, "channel")) == NULL && (htsmsg_get_str(conf, "channelname")) == NULL) return NULL; } @@ -1062,7 +998,7 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf, int clone) } de->de_enabled = 1; - de->de_config = dvr_config_find_by_name_default(NULL); + de->de_config = dvr_config_find_by_name_default(NULL); if (de->de_config) LIST_INSERT_HEAD(&de->de_config->dvr_entries, de, de_config_link); de->de_pri = DVR_PRIO_DEFAULT; @@ -1071,21 +1007,21 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf, int clone) /* Time the node was created. */ if (!htsmsg_get_s64(conf, "create", &create)) { - de->de_create = create; + de->de_create = create; } else { - /* Old dvr entry without a create time, so fake one. For - * entries that are older than a day, assume these are old - * (tvh4.2) recordings, so use the start time as the create - * time. This will allow user to order records by create time - * and get something reasonable. For all new records however, we - * use now since they will be written to disk. - */ - now = gclk(); - if (now > start && start < now - 86400) - create = start; - else - create = now; - de->de_create = create; + /* Old dvr entry without a create time, so fake one. For + * entries that are older than a day, assume these are old + * (tvh4.2) recordings, so use the start time as the create + * time. This will allow user to order records by create time + * and get something reasonable. For all new records however, we + * use now since they will be written to disk. + */ + now = gclk(); + if (now > start && start < now - 86400) + create = start; + else + create = now; + de->de_create = create; } if (!htsmsg_get_s64(conf, "watched", &watched)) { de->de_watched = watched; @@ -1124,29 +1060,32 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf, int clone) * otherwise the destroy will abort. */ if (_dvr_duplicate_event(de)) { - tvhtrace(LS_DVR, "Entry was duplicate for %s \"%s\" on \"%s\" start time %"PRId64", " - "scheduled for recording by \"%s\"", - idnode_uuid_as_str(&de->de_id, ubuf), - lang_str_get(de->de_title, NULL), DVR_CH_NAME(de), - (int64_t)de->de_start, de->de_creator ?: ""); - dvr_entry_destroy(de, 1); - return NULL; + tvhtrace(LS_DVR, + "Entry was duplicate for %s \"%s\" on \"%s\" start time %" PRId64 ", " + "scheduled for recording by \"%s\"", + idnode_uuid_as_str(&de->de_id, ubuf), + lang_str_get(de->de_title, NULL), + DVR_CH_NAME(de), + (int64_t)de->de_start, + de->de_creator ?: ""); + dvr_entry_destroy(de, 1); + return NULL; } if (de->de_channel && !de->de_dont_reschedule && !clone) { - LIST_FOREACH(de2, &de->de_channel->ch_dvrs, de_channel_link) - if(de2 != de && - de2->de_config == de->de_config && - de2->de_start == de->de_start && - de2->de_sched_state != DVR_COMPLETED && - de2->de_sched_state != DVR_MISSED_TIME && - strcmp(de2->de_owner ?: "", de->de_owner ?: "") == 0) { - tvhinfo(LS_DVR, "delete entry %s \"%s\" on \"%s\" start time %"PRId64", " - "scheduled for recording by \"%s\" (duplicate with %s)", - idnode_uuid_as_str(&de->de_id, ubuf), - lang_str_get(de->de_title, NULL), DVR_CH_NAME(de), - (int64_t)de2->de_start, de->de_creator ?: "", - idnode_uuid_as_str(&de2->de_id, ubuf2)); + LIST_FOREACH (de2, &de->de_channel->ch_dvrs, de_channel_link) + if (de2 != de && de2->de_config == de->de_config && de2->de_start == de->de_start && + de2->de_sched_state != DVR_COMPLETED && de2->de_sched_state != DVR_MISSED_TIME && + strcmp(de2->de_owner ?: "", de->de_owner ?: "") == 0) { + tvhinfo(LS_DVR, + "delete entry %s \"%s\" on \"%s\" start time %" PRId64 ", " + "scheduled for recording by \"%s\" (duplicate with %s)", + idnode_uuid_as_str(&de->de_id, ubuf), + lang_str_get(de->de_title, NULL), + DVR_CH_NAME(de), + (int64_t)de2->de_start, + de->de_creator ?: "", + idnode_uuid_as_str(&de2->de_id, ubuf2)); dvr_entry_destroy(de, 1); return NULL; } @@ -1168,16 +1107,14 @@ dvr_entry_create(const char *uuid, htsmsg_t *conf, int clone) /** * Create the event */ -dvr_entry_t * -dvr_entry_create_from_htsmsg(htsmsg_t *conf, epg_broadcast_t *e) -{ - dvr_entry_t *de; - char tbuf[64], *s; - struct tm tm; - time_t t; - char ubuf[UUID_HEX_SIZE]; - epg_genre_t *genre; - int summary_used = 0; +dvr_entry_t* dvr_entry_create_from_htsmsg(htsmsg_t* conf, epg_broadcast_t* e) { + dvr_entry_t* de; + char tbuf[64], *s; + struct tm tm; + time_t t; + char ubuf[UUID_HEX_SIZE]; + epg_genre_t* genre; + int summary_used = 0; if (e) { htsmsg_add_u32(conf, "broadcast", e->id); @@ -1210,20 +1147,21 @@ dvr_entry_create_from_htsmsg(htsmsg_t *conf, epg_broadcast_t *e) genre = LIST_FIRST(&e->genre); if (genre) htsmsg_add_u32(conf, "content_type", genre->code / 16); - if(e->age_rating) + if (e->age_rating) htsmsg_add_u32(conf, "age_rating", e->age_rating); - //Only process these fields if rating labels are enabled. - if(epggrab_conf.epgdb_processparentallabels){ - if(e->rating_label){ + // Only process these fields if rating labels are enabled. + if (epggrab_conf.epgdb_processparentallabels) { + if (e->rating_label) { htsmsg_set_uuid(conf, "rating_label_uuid", &e->rating_label->rl_id.in_uuid); - if(e->rating_label->rl_icon){ - htsmsg_add_str(conf, "rating_icon_saved", imagecache_get_propstr(e->rating_label->rl_icon, tbuf, sizeof(tbuf))); + if (e->rating_label->rl_icon) { + htsmsg_add_str(conf, + "rating_icon_saved", + imagecache_get_propstr(e->rating_label->rl_icon, tbuf, sizeof(tbuf))); } } - }//END rating labels enabled. - + } // END rating labels enabled. } de = dvr_entry_create(NULL, conf, 0); @@ -1236,13 +1174,16 @@ dvr_entry_create_from_htsmsg(htsmsg_t *conf, epg_broadcast_t *e) if (strftime(tbuf, sizeof(tbuf), "%F %T", &tm) <= 0) *tbuf = 0; - tvhinfo(LS_DVR, "entry %s \"%s\" on \"%s\" starting at %s, " - "with broadcast id \"%s\", " - "scheduled for recording by \"%s\"", - idnode_uuid_as_str(&de->de_id, ubuf), - lang_str_get(de->de_title, NULL), DVR_CH_NAME(de), tbuf, - de->de_uri ? de->de_uri : "", - de->de_creator ?: ""); + tvhinfo(LS_DVR, + "entry %s \"%s\" on \"%s\" starting at %s, " + "with broadcast id \"%s\", " + "scheduled for recording by \"%s\"", + idnode_uuid_as_str(&de->de_id, ubuf), + lang_str_get(de->de_title, NULL), + DVR_CH_NAME(de), + tbuf, + de->de_uri ? de->de_uri : "", + de->de_creator ?: ""); idnode_changed(&de->de_id); return de; @@ -1251,12 +1192,11 @@ dvr_entry_create_from_htsmsg(htsmsg_t *conf, epg_broadcast_t *e) /** * Return the event for the last segment. */ -static epg_broadcast_t *dvr_entry_get_segment_last( dvr_entry_t *de ) -{ - time_t start, stop, maximum_stop_time; - int max_progs_to_check; +static epg_broadcast_t* dvr_entry_get_segment_last(dvr_entry_t* de) { + time_t start, stop, maximum_stop_time; + int max_progs_to_check; epg_broadcast_t *e, *next, *ret; - epg_set_t *eplink1, *eplink2; + epg_set_t * eplink1, *eplink2; if (!de) return NULL; @@ -1269,9 +1209,7 @@ static epg_broadcast_t *dvr_entry_get_segment_last( dvr_entry_t *de ) eplink1 = e->episodelink; /* If not a segmented programme then no segment extra time */ - if (eplink1 == NULL || - strncmp(eplink1->uri, "crid://", 7) || - !strstr(eplink1->uri, "#")) + if (eplink1 == NULL || strncmp(eplink1->uri, "crid://", 7) || !strstr(eplink1->uri, "#")) return 0; /* This URI is a CRID (from EIT) which contains an IMI so the @@ -1292,20 +1230,15 @@ static epg_broadcast_t *dvr_entry_get_segment_last( dvr_entry_t *de ) * We also put a couple of safety checks on the number of programmes * we check in case broadcast data is bad. */ - enum - { - THREE_HOURS = 3 * 60 * 60, - MAX_STOP_TIME = 9 * 60 * 60 - }; + enum { THREE_HOURS = 3 * 60 * 60, MAX_STOP_TIME = 9 * 60 * 60 }; - ret = NULL; - start = e->start; - stop = e->stop; - maximum_stop_time = start + MAX_STOP_TIME; + ret = NULL; + start = e->start; + stop = e->stop; + maximum_stop_time = start + MAX_STOP_TIME; max_progs_to_check = 10; for (next = epg_broadcast_get_next(e); - --max_progs_to_check && stop < maximum_stop_time && - next && next->start < stop + THREE_HOURS; + --max_progs_to_check && stop < maximum_stop_time && next && next->start < stop + THREE_HOURS; next = epg_broadcast_get_next(next)) { eplink2 = next->episodelink; if (eplink2 && eplink1 == eplink2) { @@ -1324,10 +1257,9 @@ static epg_broadcast_t *dvr_entry_get_segment_last( dvr_entry_t *de ) * Determine stop time for the broadcast taking in * to account segmented programmes via EIT. */ -static time_t dvr_entry_get_segment_stop_extra( dvr_entry_t *de ) -{ - time_t segment_stop_extra; - epg_broadcast_t *e; +static time_t dvr_entry_get_segment_stop_extra(dvr_entry_t* de) { + time_t segment_stop_extra; + epg_broadcast_t* e; if (!de) return 0; @@ -1343,11 +1275,15 @@ static time_t dvr_entry_get_segment_stop_extra( dvr_entry_t *de ) segment_stop_extra = e->stop - de->de_bcast->stop; if (segment_stop_extra != de->de_segment_stop_extra) { - tvhinfo(LS_DVR, "Increasing stop for \"%s\" on \"%s\" \"%s\" by %"PRId64 - " seconds at start %"PRId64" and original stop %"PRId64, - lang_str_get(e->title, NULL), DVR_CH_NAME(de), e->episodelink->uri, - (int64_t)segment_stop_extra, (int64_t)de->de_bcast->start, - (int64_t)de->de_bcast->stop); + tvhinfo(LS_DVR, + "Increasing stop for \"%s\" on \"%s\" \"%s\" by %" PRId64 " seconds at start %" PRId64 + " and original stop %" PRId64, + lang_str_get(e->title, NULL), + DVR_CH_NAME(de), + e->episodelink->uri, + (int64_t)segment_stop_extra, + (int64_t)de->de_bcast->start, + (int64_t)de->de_bcast->stop); de->de_segment_stop_extra = segment_stop_extra; } @@ -1357,11 +1293,9 @@ static time_t dvr_entry_get_segment_stop_extra( dvr_entry_t *de ) /** * Clone existing DVR entry and stop the previous */ -dvr_entry_t * -dvr_entry_clone(dvr_entry_t *de) -{ - htsmsg_t *conf = htsmsg_create_map(); - dvr_entry_t *n; +dvr_entry_t* dvr_entry_clone(dvr_entry_t* de) { + htsmsg_t* conf = htsmsg_create_map(); + dvr_entry_t* n; lock_assert(&global_lock); @@ -1370,7 +1304,7 @@ dvr_entry_clone(dvr_entry_t *de) htsmsg_destroy(conf); if (n) { - if(de->de_sched_state == DVR_RECORDING) { + if (de->de_sched_state == DVR_RECORDING) { dvr_stop_recording(de, SM_CODE_SOURCE_RECONFIGURED, 1, 1); dvr_rec_migrate(de, n); n->de_start = gclk(); @@ -1387,17 +1321,15 @@ dvr_entry_clone(dvr_entry_t *de) /** * */ -static int -dvr_entry_rerecord(dvr_entry_t *de) -{ - uint32_t rerecord; +static int dvr_entry_rerecord(dvr_entry_t* de) { + uint32_t rerecord; epg_broadcast_t *e, *ev; - dvr_entry_t *de2; - char buf[512]; - int64_t fsize1, fsize2; - time_t pre; - uint32_t warm; - htsmsg_t *conf; + dvr_entry_t* de2; + char buf[512]; + int64_t fsize1, fsize2; + time_t pre; + uint32_t warm; + htsmsg_t* conf; if (dvr_in_init || de->de_dont_rerecord) return 0; @@ -1405,8 +1337,7 @@ dvr_entry_rerecord(dvr_entry_t *de) if (rerecord == 0) return 0; if ((de2 = de->de_parent) != NULL) { - if (de->de_sched_state == DVR_COMPLETED && - de->de_errors == 0 && + if (de->de_sched_state == DVR_COMPLETED && de->de_errors == 0 && de->de_data_errors < de2->de_data_errors) { fsize1 = dvr_get_filesize(de, DVR_FILESIZE_TOTAL); fsize2 = dvr_get_filesize(de2, DVR_FILESIZE_TOTAL); @@ -1417,14 +1348,14 @@ dvr_entry_rerecord(dvr_entry_t *de) } } else if (de->de_sched_state == DVR_COMPLETED) { if (dvr_get_filesize(de, 0) < 0) { -delete_me: + delete_me: dvr_entry_cancel_delete(de, 0); dvr_entry_rerecord(de2); return 1; } -not_so_good: + not_so_good: de->de_retention = DVR_RET_ONREMOVE; - de->de_removal = DVR_RET_REM_1DAY; + de->de_removal = DVR_RET_REM_1DAY; dvr_entry_change_parent_child(de->de_parent, NULL, NULL, 1); dvr_entry_completed(de, SM_CODE_WEAK_STREAM); return 0; @@ -1438,23 +1369,22 @@ not_so_good: return 0; if (de->de_channel == NULL) return 0; - if (de->de_sched_state == DVR_SCHEDULED || - de->de_sched_state == DVR_RECORDING) + if (de->de_sched_state == DVR_SCHEDULED || de->de_sched_state == DVR_RECORDING) return 0; - if (de->de_sched_state == DVR_COMPLETED && - de->de_last_error == SM_CODE_WEAK_STREAM) + if (de->de_sched_state == DVR_COMPLETED && de->de_last_error == SM_CODE_WEAK_STREAM) return 0; /* rerecord if - DVR_NOSTATE, DVR_MISSED_TIME */ - if (de->de_sched_state == DVR_COMPLETED && - rerecord > de->de_data_errors && de->de_errors <= 0) + if (de->de_sched_state == DVR_COMPLETED && rerecord > de->de_data_errors && de->de_errors <= 0) return 0; - e = NULL; - pre = dvr_entry_get_extra_time_pre(de); + e = NULL; + pre = dvr_entry_get_extra_time_pre(de); warm = dvr_entry_warm_time(de); - RB_FOREACH(ev, &de->de_channel->ch_epg_schedule, sched_link) { - if (de->de_bcast == ev) continue; - if (ev->start - pre - warm < gclk()) continue; + RB_FOREACH (ev, &de->de_channel->ch_epg_schedule, sched_link) { + if (de->de_bcast == ev) + continue; + if (ev->start - pre - warm < gclk()) + continue; if (dvr_entry_fuzzy_match(de, ev, 0, INT64_MAX)) if (!e || e->start > ev->start) e = ev; @@ -1463,13 +1393,16 @@ not_so_good: if (e == NULL) return 0; - dvr_entry_trace_time2(de, "start", e->start, "stop", e->stop, - "rerecord event %s on %s", - epg_broadcast_get_title(e, NULL), - channel_get_name(e->channel, channel_blank_name)); - - snprintf(buf, sizeof(buf), _("Re-record%s%s"), - de->de_comment ? ": " : "", de->de_comment ?: ""); + dvr_entry_trace_time2(de, + "start", + e->start, + "stop", + e->stop, + "rerecord event %s on %s", + epg_broadcast_get_title(e, NULL), + channel_get_name(e->channel, channel_blank_name)); + + snprintf(buf, sizeof(buf), _("Re-record%s%s"), de->de_comment ? ": " : "", de->de_comment ?: ""); conf = htsmsg_create_map(); htsmsg_add_uuid(conf, "config_name", &de->de_config->dvr_id.in_uuid); htsmsg_add_s64(conf, "start_extra", de->de_start_extra); @@ -1498,30 +1431,25 @@ not_so_good: /** * */ -typedef int (*_dvr_duplicate_fcn_t)(dvr_entry_t *de, dvr_entry_t *de2, void **aux); +typedef int (*_dvr_duplicate_fcn_t)(dvr_entry_t* de, dvr_entry_t* de2, void** aux); -static int _dvr_duplicate_epnum(dvr_entry_t *de, dvr_entry_t *de2, void **aux) -{ - return ! epg_episode_number_cmp(&(de->de_epnum), &(de2->de_epnum)) ; +static int _dvr_duplicate_epnum(dvr_entry_t* de, dvr_entry_t* de2, void** aux) { + return !epg_episode_number_cmp(&(de->de_epnum), &(de2->de_epnum)); } -static int _dvr_duplicate_title(dvr_entry_t *de, dvr_entry_t *de2, void **aux) -{ +static int _dvr_duplicate_title(dvr_entry_t* de, dvr_entry_t* de2, void** aux) { return !lang_str_compare(de->de_title, de2->de_title); } -static int _dvr_duplicate_subtitle(dvr_entry_t *de, dvr_entry_t *de2, void **aux) -{ +static int _dvr_duplicate_subtitle(dvr_entry_t* de, dvr_entry_t* de2, void** aux) { return !lang_str_compare(de->de_subtitle, de2->de_subtitle); } -static int _dvr_duplicate_desc(dvr_entry_t *de, dvr_entry_t *de2, void **aux) -{ +static int _dvr_duplicate_desc(dvr_entry_t* de, dvr_entry_t* de2, void** aux) { return !lang_str_compare(de->de_desc, de2->de_desc); } -static int _dvr_duplicate_per_month(dvr_entry_t *de, dvr_entry_t *de2, void **aux) -{ +static int _dvr_duplicate_per_month(dvr_entry_t* de, dvr_entry_t* de2, void** aux) { struct tm *de1_start = *aux, de2_start; if (de1_start == NULL) { de1_start = calloc(1, sizeof(*de1_start)); @@ -1529,29 +1457,25 @@ static int _dvr_duplicate_per_month(dvr_entry_t *de, dvr_entry_t *de2, void **au *aux = de1_start; } localtime_r(&de2->de_start, &de2_start); - return de1_start->tm_year == de2_start.tm_year && - de1_start->tm_mon == de2_start.tm_mon; + return de1_start->tm_year == de2_start.tm_year && de1_start->tm_mon == de2_start.tm_mon; } -static int _dvr_duplicate_per_week(dvr_entry_t *de, dvr_entry_t *de2, void **aux) -{ +static int _dvr_duplicate_per_week(dvr_entry_t* de, dvr_entry_t* de2, void** aux) { struct tm *de1_start = *aux, de2_start; if (de1_start == NULL) { de1_start = calloc(1, sizeof(*de1_start)); localtime_r(&de->de_start, de1_start); de1_start->tm_mday -= (de1_start->tm_wday + 6) % 7; // week = mon-sun - mktime(de1_start); // adjusts de_start + mktime(de1_start); // adjusts de_start *aux = de1_start; } localtime_r(&de2->de_start, &de2_start); de2_start.tm_mday -= (de2_start.tm_wday + 6) % 7; // week = mon-sun - mktime(&de2_start); // adjusts de2_start - return de1_start->tm_year == de2_start.tm_year && - de1_start->tm_yday == de2_start.tm_yday; + mktime(&de2_start); // adjusts de2_start + return de1_start->tm_year == de2_start.tm_year && de1_start->tm_yday == de2_start.tm_yday; } -static int _dvr_duplicate_per_day(dvr_entry_t *de, dvr_entry_t *de2, void **aux) -{ +static int _dvr_duplicate_per_day(dvr_entry_t* de, dvr_entry_t* de2, void** aux) { struct tm *de1_start = *aux, de2_start; if (de1_start == NULL) { de1_start = calloc(1, sizeof(*de1_start)); @@ -1559,25 +1483,24 @@ static int _dvr_duplicate_per_day(dvr_entry_t *de, dvr_entry_t *de2, void **aux) *aux = de1_start; } localtime_r(&de2->de_start, &de2_start); - return de1_start->tm_year == de2_start.tm_year && - de1_start->tm_yday == de2_start.tm_yday; + return de1_start->tm_year == de2_start.tm_year && de1_start->tm_yday == de2_start.tm_yday; } /// Does the de have a crid programid? -static int is_uri_crid(const dvr_entry_t *de) -{ - return de && de->de_uri && !strncmp(de->de_uri, "crid://", 7); +static int is_uri_crid(const dvr_entry_t* de) { + return de && de->de_uri && !strncmp(de->de_uri, "crid://", 7); } /// Is the uri in the de one that is suitable for de-dup. See Issue /// #4652 for details. /// @return NULL if no id suitable, else the id that can be used for dedup. -static const char *_dvr_duplicate_get_dedup_program_id(const dvr_entry_t *de) -{ - if (!de) return 0; +static const char* _dvr_duplicate_get_dedup_program_id(const dvr_entry_t* de) { + if (!de) + return 0; - const char *ep_uri = de->de_uri; - if (!ep_uri) return NULL; + const char* ep_uri = de->de_uri; + if (!ep_uri) + return NULL; /* Only want to dedup on crid (unique broadcast id) or dd-progid * (unique xmltvid). @@ -1585,49 +1508,54 @@ static const char *_dvr_duplicate_get_dedup_program_id(const dvr_entry_t *de) /* It's a crid? If so, we can use the id as the unique indicator */ if (is_uri_crid(de)) - return ep_uri + 7; /* +7 to skip past crid:// */ + return ep_uri + 7; /* +7 to skip past crid:// */ if (!strncmp(ep_uri, "ddprogid://", 11)) { /* Unfortunately, we prepend the grabber to the id, which can be "xmltv" * or "/usr/bin/tv_grab_combiner"! Since the ddprogid can't contain / * we can just return the last component. */ - const char *last = strrchr(ep_uri, '/'); + const char* last = strrchr(ep_uri, '/'); /* "Can't" happen since by definition ddprogid:// must contain a slash */ - if (!last) return ep_uri; + if (!last) + return ep_uri; /* Return the bit after the last slash. */ - return last+1; /* +1 to skip '/' */ + return last + 1; /* +1 to skip '/' */ } /* Must be an internal tvh:// id or some other id we consider not unique */ return NULL; } /// @return 1 if dup. -static int _dvr_duplicate_unique_match(dvr_entry_t *de1, dvr_entry_t *de2, void **aux) -{ +static int _dvr_duplicate_unique_match(dvr_entry_t* de1, dvr_entry_t* de2, void** aux) { enum { NOT_DUP = 0, DUP = 1 }; /* We should always have entries so if something is wrong it is a dup */ - if (!de1 || !de2) return DUP; + if (!de1 || !de2) + return DUP; - const char *progid1 = _dvr_duplicate_get_dedup_program_id(de1); - const char *progid2 = _dvr_duplicate_get_dedup_program_id(de2); - if (progid1 && progid2 && !strcmp(progid1, progid2)) return DUP; + const char* progid1 = _dvr_duplicate_get_dedup_program_id(de1); + const char* progid2 = _dvr_duplicate_get_dedup_program_id(de2); + if (progid1 && progid2 && !strcmp(progid1, progid2)) + return DUP; - const lang_str_t *title1 = de1->de_title; - const lang_str_t *title2 = de2->de_title; + const lang_str_t* title1 = de1->de_title; + const lang_str_t* title2 = de2->de_title; - if (!title1 || !title2) return NOT_DUP; + if (!title1 || !title2) + return NOT_DUP; /* Titles not equal? Can't be a dup then */ - if (lang_str_compare(de1->de_title, de2->de_title)) return NOT_DUP; + if (lang_str_compare(de1->de_title, de2->de_title)) + return NOT_DUP; /* We want to dup match only if both season * AND episode are present since OTA often have just "Ep 1" without * giving the season. */ - if (de1->de_epnum.s_num && de1->de_epnum.e_num && - de2->de_epnum.s_num && de2->de_epnum.e_num) - return de1->de_epnum.s_num == de2->de_epnum.s_num && de1->de_epnum.e_num == de2->de_epnum.e_num ? DUP : NOT_DUP; + if (de1->de_epnum.s_num && de1->de_epnum.e_num && de2->de_epnum.s_num && de2->de_epnum.e_num) + return de1->de_epnum.s_num == de2->de_epnum.s_num && de1->de_epnum.e_num == de2->de_epnum.e_num + ? DUP + : NOT_DUP; /* If we don't have Season & Episode, then we will try matching just * season and just episode (if available). This is because if OTA @@ -1665,10 +1593,10 @@ static int _dvr_duplicate_unique_match(dvr_entry_t *de1, dvr_entry_t *de2, void * crid can be checked. */ - const int is_uri_crid1 = is_uri_crid(de1); - const int is_uri_crid2 = is_uri_crid(de2); - const int is_both_crid = is_uri_crid1 && is_uri_crid2; - int is_same_authority = 1; + const int is_uri_crid1 = is_uri_crid(de1); + const int is_uri_crid2 = is_uri_crid(de2); + const int is_both_crid = is_uri_crid1 && is_uri_crid2; + int is_same_authority = 1; if (is_both_crid) { /* If both entries have a crid (OTA) then check if they are from * the same authority. This is the bit before the final slash. @@ -1680,19 +1608,18 @@ static int _dvr_duplicate_unique_match(dvr_entry_t *de1, dvr_entry_t *de2, void * to include the slash itself. */ if (progid1 && progid2) { - const char *slash = strchr(progid1, '/'); + const char* slash = strchr(progid1, '/'); const ssize_t num_char = slash ? slash + 1 - progid1 : 0; - is_same_authority = !strncmp(progid1, progid2, num_char); + is_same_authority = !strncmp(progid1, progid2, num_char); } else { is_same_authority = 0; } } - const int do_progid_check = - (!is_uri_crid1 && !is_uri_crid2) || /* e.g., xmltv */ - (is_both_crid && is_same_authority) || /* e.g, OTA on same broadcaster */ - (is_uri_crid1 && !is_uri_crid2) || /* e.g., OTA vs xmltv channel */ - (!is_uri_crid1 && is_uri_crid2); + const int do_progid_check = (!is_uri_crid1 && !is_uri_crid2) || /* e.g., xmltv */ + (is_both_crid && is_same_authority) || /* e.g, OTA on same broadcaster */ + (is_uri_crid1 && !is_uri_crid2) || /* e.g., OTA vs xmltv channel */ + (!is_uri_crid1 && is_uri_crid2); /* And we can finally here do 'different programme id' * check. Programme id identical check is done first, but non-identical @@ -1725,28 +1652,27 @@ static int _dvr_duplicate_unique_match(dvr_entry_t *de1, dvr_entry_t *de2, void /** * */ -static dvr_entry_t *_dvr_duplicate_event(dvr_entry_t *de) -{ +static dvr_entry_t* _dvr_duplicate_event(dvr_entry_t* de) { static _dvr_duplicate_fcn_t fcns[] = { - [DVR_AUTOREC_RECORD_UNIQUE] = _dvr_duplicate_unique_match, - [DVR_AUTOREC_RECORD_DIFFERENT_EPISODE_NUMBER] = _dvr_duplicate_epnum, - [DVR_AUTOREC_LRECORD_DIFFERENT_EPISODE_NUMBER] = _dvr_duplicate_epnum, - [DVR_AUTOREC_LRECORD_DIFFERENT_TITLE] = _dvr_duplicate_title, - [DVR_AUTOREC_RECORD_DIFFERENT_SUBTITLE] = _dvr_duplicate_subtitle, - [DVR_AUTOREC_LRECORD_DIFFERENT_SUBTITLE] = _dvr_duplicate_subtitle, - [DVR_AUTOREC_RECORD_DIFFERENT_DESCRIPTION] = _dvr_duplicate_desc, - [DVR_AUTOREC_LRECORD_DIFFERENT_DESCRIPTION] = _dvr_duplicate_desc, - [DVR_AUTOREC_RECORD_ONCE_PER_MONTH] = _dvr_duplicate_per_month, - [DVR_AUTOREC_LRECORD_ONCE_PER_MONTH] = _dvr_duplicate_per_month, - [DVR_AUTOREC_RECORD_ONCE_PER_WEEK] = _dvr_duplicate_per_week, - [DVR_AUTOREC_LRECORD_ONCE_PER_WEEK] = _dvr_duplicate_per_week, - [DVR_AUTOREC_RECORD_ONCE_PER_DAY] = _dvr_duplicate_per_day, - [DVR_AUTOREC_LRECORD_ONCE_PER_DAY] = _dvr_duplicate_per_day, + [DVR_AUTOREC_RECORD_UNIQUE] = _dvr_duplicate_unique_match, + [DVR_AUTOREC_RECORD_DIFFERENT_EPISODE_NUMBER] = _dvr_duplicate_epnum, + [DVR_AUTOREC_LRECORD_DIFFERENT_EPISODE_NUMBER] = _dvr_duplicate_epnum, + [DVR_AUTOREC_LRECORD_DIFFERENT_TITLE] = _dvr_duplicate_title, + [DVR_AUTOREC_RECORD_DIFFERENT_SUBTITLE] = _dvr_duplicate_subtitle, + [DVR_AUTOREC_LRECORD_DIFFERENT_SUBTITLE] = _dvr_duplicate_subtitle, + [DVR_AUTOREC_RECORD_DIFFERENT_DESCRIPTION] = _dvr_duplicate_desc, + [DVR_AUTOREC_LRECORD_DIFFERENT_DESCRIPTION] = _dvr_duplicate_desc, + [DVR_AUTOREC_RECORD_ONCE_PER_MONTH] = _dvr_duplicate_per_month, + [DVR_AUTOREC_LRECORD_ONCE_PER_MONTH] = _dvr_duplicate_per_month, + [DVR_AUTOREC_RECORD_ONCE_PER_WEEK] = _dvr_duplicate_per_week, + [DVR_AUTOREC_LRECORD_ONCE_PER_WEEK] = _dvr_duplicate_per_week, + [DVR_AUTOREC_RECORD_ONCE_PER_DAY] = _dvr_duplicate_per_day, + [DVR_AUTOREC_LRECORD_ONCE_PER_DAY] = _dvr_duplicate_per_day, }; - dvr_entry_t *de2; - _dvr_duplicate_fcn_t match; - int record; - void *aux; + dvr_entry_t* de2; + _dvr_duplicate_fcn_t match; + int record; + void* aux; if (!de->de_autorec) return NULL; @@ -1791,7 +1717,7 @@ static dvr_entry_t *_dvr_duplicate_event(dvr_entry_t *de) break; case DVR_AUTOREC_LRECORD_DIFFERENT_TITLE: break; - default: + default: abort(); } @@ -1800,14 +1726,14 @@ static dvr_entry_t *_dvr_duplicate_event(dvr_entry_t *de) assert(match); - if (record < DVR_AUTOREC_LRECORD_DIFFERENT_EPISODE_NUMBER || record == DVR_AUTOREC_RECORD_UNIQUE) { - LIST_FOREACH(de2, &dvrentries, de_global_link) { + if (record < DVR_AUTOREC_LRECORD_DIFFERENT_EPISODE_NUMBER || + record == DVR_AUTOREC_RECORD_UNIQUE) { + LIST_FOREACH (de2, &dvrentries, de_global_link) { if (de == de2) continue; // check for valid states - if (de2->de_sched_state == DVR_NOSTATE || - de2->de_sched_state == DVR_MISSED_TIME) + if (de2->de_sched_state == DVR_NOSTATE || de2->de_sched_state == DVR_MISSED_TIME) continue; // only earlier recordings qualify as master @@ -1822,9 +1748,9 @@ static dvr_entry_t *_dvr_duplicate_event(dvr_entry_t *de) if (dvr_entry_is_finished(de2, DVR_FINISHED_FAILED | DVR_FINISHED_REMOVED_FAILED)) continue; - // some channels add "New:" to the title of the first showing, so title match with repeats will fail. - // if we are going on to check CRIDs, ignore any title mismatch - // otherwise if titles are not defined or do not match, don't dedup + // some channels add "New:" to the title of the first showing, so title match with repeats + // will fail. if we are going on to check CRIDs, ignore any title mismatch otherwise if titles + // are not defined or do not match, don't dedup if (record != DVR_AUTOREC_RECORD_UNIQUE && lang_str_compare(de->de_title, de2->de_title)) continue; @@ -1834,13 +1760,12 @@ static dvr_entry_t *_dvr_duplicate_event(dvr_entry_t *de) } } } else { - LIST_FOREACH(de2, &de->de_autorec->dae_spawns, de_autorec_link) { + LIST_FOREACH (de2, &de->de_autorec->dae_spawns, de_autorec_link) { if (de == de2) continue; // check for valid states - if (de2->de_sched_state == DVR_NOSTATE || - de2->de_sched_state == DVR_MISSED_TIME) + if (de2->de_sched_state == DVR_NOSTATE || de2->de_sched_state == DVR_MISSED_TIME) continue; // only earlier recordings qualify as master @@ -1871,27 +1796,29 @@ static dvr_entry_t *_dvr_duplicate_event(dvr_entry_t *de) } /*** Return non-zero if the broadcast new_bcast is better for recording than the one for old_de. */ -static int -dvr_is_better_recording_timeslot(const epg_broadcast_t *new_bcast, const dvr_entry_t *old_de) -{ +static int dvr_is_better_recording_timeslot(const epg_broadcast_t* new_bcast, + const dvr_entry_t* old_de) { /* If programme is recording (or completed) then it is the "best", * even if a better schedule is found after recording starts. */ if (old_de && old_de->de_sched_state != DVR_SCHEDULED) return 0; - if (!old_de || !old_de->de_bcast) return 1; /* Old broadcast should always exist */ - int old_services = 0; - int new_services = 0; - int64_t old_chnumber, new_chnumber; - const idnode_list_mapping_t *ilm; - const epg_broadcast_t *old_bcast = old_de->de_bcast; - const channel_t *old_channel = old_bcast->channel; - const channel_t *new_channel = new_bcast->channel; + if (!old_de || !old_de->de_bcast) + return 1; /* Old broadcast should always exist */ + int old_services = 0; + int new_services = 0; + int64_t old_chnumber, new_chnumber; + const idnode_list_mapping_t* ilm; + const epg_broadcast_t* old_bcast = old_de->de_bcast; + const channel_t* old_channel = old_bcast->channel; + const channel_t* new_channel = new_bcast->channel; /* Sanity check. */ - if (!new_channel) return 0; - if (!old_channel) return 1; + if (!new_channel) + return 0; + if (!old_channel) + return 1; /* Always prefer a recording that has the correct service profile * (UHD, FHD, HD, SD). Someone mentioned (#1846) that some channels can @@ -1901,9 +1828,9 @@ dvr_is_better_recording_timeslot(const epg_broadcast_t *new_bcast, const dvr_ent */ if (old_de->de_config && old_de->de_config->dvr_profile && old_de->de_config->dvr_profile->pro_svfilter != PROFILE_SVF_NONE) { - const int svf = old_de->de_config->dvr_profile->pro_svfilter; - int old_has_svf = channel_has_correct_service_filter(old_channel, svf); - int new_has_svf = channel_has_correct_service_filter(new_channel, svf); + const int svf = old_de->de_config->dvr_profile->pro_svfilter; + int old_has_svf = channel_has_correct_service_filter(old_channel, svf); + int new_has_svf = channel_has_correct_service_filter(new_channel, svf); if (old_has_svf && !new_has_svf) return 0; @@ -1955,7 +1882,7 @@ dvr_is_better_recording_timeslot(const epg_broadcast_t *new_bcast, const dvr_ent * get 50 minutes. */ if (new_bcast->start != old_bcast->start) { - if (new_bcast->start > old_bcast->start && gclk() > old_bcast->start) { + if (new_bcast->start > old_bcast->start && gclk() > old_bcast->start) { return 1; } else if (new_bcast->start < old_bcast->start && gclk() > new_bcast->start) { return 0; @@ -1975,10 +1902,10 @@ dvr_is_better_recording_timeslot(const epg_broadcast_t *new_bcast, const dvr_ent * services we assume it's a better choice since we have more fallbacks * if a tune fails. */ - LIST_FOREACH(ilm, &old_channel->ch_services, ilm_in2_link) { + LIST_FOREACH (ilm, &old_channel->ch_services, ilm_in2_link) { ++old_services; } - LIST_FOREACH(ilm, &new_channel->ch_services, ilm_in2_link) { + LIST_FOREACH (ilm, &new_channel->ch_services, ilm_in2_link) { ++new_services; } if (new_services > old_services) @@ -2008,19 +1935,18 @@ dvr_is_better_recording_timeslot(const epg_broadcast_t *new_bcast, const dvr_ent /** * */ -void -dvr_entry_create_by_autorec(int enabled, epg_broadcast_t *e, dvr_autorec_entry_t *dae) -{ - char buf[512]; - char t1buf[32], t2buf[32]; - const char *s; +void dvr_entry_create_by_autorec(int enabled, epg_broadcast_t* e, dvr_autorec_entry_t* dae) { + char buf[512]; + char t1buf[32], t2buf[32]; + const char* s; dvr_entry_t *de, *replace = NULL; - uint32_t count = 0, max_count; - htsmsg_t *conf; + uint32_t count = 0, max_count; + htsmsg_t* conf; /* Identical duplicate detection - NOTE: Semantic duplicate detection is deferred to the start time of recording and then done using _dvr_duplicate_event by dvr_timer_start_recording. */ - LIST_FOREACH(de, &dvrentries, de_global_link) { + NOTE: Semantic duplicate detection is deferred to the start time of recording and then done + using _dvr_duplicate_event by dvr_timer_start_recording. */ + LIST_FOREACH (de, &dvrentries, de_global_link) { if (de->de_bcast == e || epg_episode_match(de->de_bcast, e)) if (strcmp(dae->dae_owner ?: "", de->de_owner ?: "") == 0) { /* See if our new broadcast is better than our existing schedule, @@ -2069,27 +1995,33 @@ dvr_entry_create_by_autorec(int enabled, epg_broadcast_t *e, dvr_autorec_entry_t * so that our max schedules check will be correct. */ if (replace) { - tvhinfo(LS_DVR, "Autorecord \"%s\" Replacing existing dvr recording entry of \"%s\" on %s @ start %s with recording on %s @ start %s", - dae->dae_name, lang_str_get(e->title, NULL), - DVR_CH_NAME(replace), - gmtime2local(replace->de_bcast->start, t1buf, sizeof t1buf), - e->channel ? channel_get_name(e->channel, channel_blank_name) : channel_blank_name, - gmtime2local(e->start, t2buf, sizeof t2buf)); + tvhinfo(LS_DVR, + "Autorecord \"%s\" Replacing existing dvr recording entry of \"%s\" on %s @ start %s with " + "recording on %s @ start %s", + dae->dae_name, + lang_str_get(e->title, NULL), + DVR_CH_NAME(replace), + gmtime2local(replace->de_bcast->start, t1buf, sizeof t1buf), + e->channel ? channel_get_name(e->channel, channel_blank_name) : channel_blank_name, + gmtime2local(e->start, t2buf, sizeof t2buf)); dvr_entry_delete(replace); dvr_entry_destroy(replace, 1); } /* Handle max schedules limit for autorrecord */ - if ((max_count = dvr_autorec_get_max_sched_count(dae)) > 0){ + if ((max_count = dvr_autorec_get_max_sched_count(dae)) > 0) { count = 0; - LIST_FOREACH(de, &dae->dae_spawns, de_autorec_link) - if ((de->de_sched_state == DVR_SCHEDULED) || - (de->de_sched_state == DVR_RECORDING)) count++; + LIST_FOREACH (de, &dae->dae_spawns, de_autorec_link) + if ((de->de_sched_state == DVR_SCHEDULED) || (de->de_sched_state == DVR_RECORDING)) + count++; /* We drop this to a debug since on a reschedule numerous emitted */ if (count >= max_count) { - tvhdebug(LS_DVR, "Autorecord \"%s\": Not scheduling \"%s\" because of autorecord max schedules limit reached", - dae->dae_name, lang_str_get(e->title, NULL)); + tvhdebug(LS_DVR, + "Autorecord \"%s\": Not scheduling \"%s\" because of autorecord max schedules limit " + "reached", + dae->dae_name, + lang_str_get(e->title, NULL)); return; } } @@ -2120,12 +2052,10 @@ dvr_entry_create_by_autorec(int enabled, epg_broadcast_t *e, dvr_autorec_entry_t /** * */ -void -dvr_entry_dec_ref(dvr_entry_t *de) -{ +void dvr_entry_dec_ref(dvr_entry_t* de) { lock_assert(&global_lock); - if(de->de_refcnt > 1) { + if (de->de_refcnt > 1) { de->de_refcnt--; return; } @@ -2134,15 +2064,15 @@ dvr_entry_dec_ref(dvr_entry_t *de) idnode_unlink(&de->de_id); - if(de->de_autorec != NULL) + if (de->de_autorec != NULL) LIST_REMOVE(de, de_autorec_link); if (de->de_timerec) { de->de_timerec->dte_spawn = NULL; - de->de_timerec = NULL; + de->de_timerec = NULL; } - if(de->de_config != NULL) + if (de->de_config != NULL) LIST_REMOVE(de, de_config_link); htsmsg_destroy(de->de_files); @@ -2150,10 +2080,14 @@ dvr_entry_dec_ref(dvr_entry_t *de) free(de->de_owner); free(de->de_creator); free(de->de_comment); - if (de->de_title) lang_str_destroy(de->de_title); - if (de->de_subtitle) lang_str_destroy(de->de_subtitle); - if (de->de_summary) lang_str_destroy(de->de_summary); - if (de->de_desc) lang_str_destroy(de->de_desc); + if (de->de_title) + lang_str_destroy(de->de_title); + if (de->de_subtitle) + lang_str_destroy(de->de_subtitle); + if (de->de_summary) + lang_str_destroy(de->de_summary); + if (de->de_desc) + lang_str_destroy(de->de_desc); dvr_entry_assign_broadcast(de, NULL); free(de->de_channel_name); free(de->de_epnum.text); @@ -2167,9 +2101,7 @@ dvr_entry_dec_ref(dvr_entry_t *de) /** * */ -void -dvr_entry_destroy(dvr_entry_t *de, int delconf) -{ +void dvr_entry_destroy(dvr_entry_t* de, int delconf) { char ubuf[UUID_HEX_SIZE]; idnode_save_check(&de->de_id, delconf); @@ -2211,32 +2143,27 @@ dvr_entry_destroy(dvr_entry_t *de, int delconf) * lee-way in case of slow hardware. */ if (!de->de_create || gclk() - de->de_create > 10) - dvr_autorec_async_reschedule(); + dvr_autorec_async_reschedule(); dvr_entry_dec_ref(de); } /** * */ -static void _deferred_destroy_cb(void *aux) -{ +static void _deferred_destroy_cb(void* aux) { dvr_entry_destroy(aux, 1); } -static void -dvr_entry_deferred_destroy(dvr_entry_t *de) -{ +static void dvr_entry_deferred_destroy(dvr_entry_t* de) { mtimer_arm_rel(&de->de_deferred_timer, _deferred_destroy_cb, de, 0); } /** * */ -void -dvr_entry_destroy_by_config(dvr_config_t *cfg, int delconf) -{ - dvr_entry_t *de; - dvr_config_t *def = NULL; +void dvr_entry_destroy_by_config(dvr_config_t* cfg, int delconf) { + dvr_entry_t* de; + dvr_config_t* def = NULL; while ((de = LIST_FIRST(&cfg->dvr_entries)) != NULL) { LIST_REMOVE(de, de_config_link); @@ -2253,25 +2180,19 @@ dvr_entry_destroy_by_config(dvr_config_t *cfg, int delconf) /** * */ -static void -dvr_timer_rerecord(void *aux) -{ - dvr_entry_t *de = aux; +static void dvr_timer_rerecord(void* aux) { + dvr_entry_t* de = aux; if (dvr_entry_rerecord(de)) return; dvr_entry_retention_timer(de); } - /** * */ -static void -dvr_timer_expire(void *aux) -{ - dvr_entry_t *de = aux; - tvhinfo(LS_DVR, "Watched timer expiring \"%s\"", - lang_str_get(de->de_title, NULL)); +static void dvr_timer_expire(void* aux) { + dvr_entry_t* de = aux; + tvhinfo(LS_DVR, "Watched timer expiring \"%s\"", lang_str_get(de->de_title, NULL)); /* Force the watched timer to be reset. This ensures it * cannot be re-triggered on a restart of tvheadend. */ @@ -2281,25 +2202,20 @@ dvr_timer_expire(void *aux) dvr_entry_cancel_remove(de, 1); } -static void -dvr_entry_watched_timer_cb(void *aux) -{ +static void dvr_entry_watched_timer_cb(void* aux) { tvhtrace(LS_DVR, "Entry watched cb"); dvr_timer_expire(aux); } -static void -dvr_entry_watched_timer_arm(dvr_entry_t* de) -{ - if (!de || !de->de_watched || - dvr_entry_get_removal_days(de) == DVR_RET_REM_FOREVER || +static void dvr_entry_watched_timer_arm(dvr_entry_t* de) { + if (!de || !de->de_watched || dvr_entry_get_removal_days(de) == DVR_RET_REM_FOREVER || !de->de_config || !de->de_config->dvr_removal_after_playback) return; - char t1buf[32]; + char t1buf[32]; const time_t now = gclk(); - char ubuf[UUID_HEX_SIZE]; - time_t when = de->de_watched + de->de_config->dvr_removal_after_playback; + char ubuf[UUID_HEX_SIZE]; + time_t when = de->de_watched + de->de_config->dvr_removal_after_playback; /* We could just call the cb ourselves, but we'll set a timer if * the event is in the past so that we are always async. @@ -2308,17 +2224,16 @@ dvr_entry_watched_timer_arm(dvr_entry_t* de) */ if (when < now) when = now; - tvhinfo(LS_DVR, "Arming watched timer to delete \"%s\" %s @ %s (now+%"PRId64")", - lang_str_get(de->de_title, NULL), - idnode_uuid_as_str(&de->de_id, ubuf), - gmtime2local(when, t1buf, sizeof t1buf), - (int64_t)when-now); + tvhinfo(LS_DVR, + "Arming watched timer to delete \"%s\" %s @ %s (now+%" PRId64 ")", + lang_str_get(de->de_title, NULL), + idnode_uuid_as_str(&de->de_id, ubuf), + gmtime2local(when, t1buf, sizeof t1buf), + (int64_t)when - now); gtimer_arm_absn(&de->de_watched_timer, dvr_entry_watched_timer_cb, de, when); } -static void -dvr_entry_watched_timer_disarm(dvr_entry_t* de) -{ +static void dvr_entry_watched_timer_disarm(dvr_entry_t* de) { if (de) { dvr_entry_trace(de, "watched timer - disarm"); de->de_watched = 0; @@ -2328,9 +2243,7 @@ dvr_entry_watched_timer_disarm(dvr_entry_t* de) /// Check if user wants played entries to be automatically deleted /// If so, arm the timers. -static void -dvr_entry_watched_set_watched(dvr_entry_t* de) -{ +static void dvr_entry_watched_set_watched(dvr_entry_t* de) { if (!de) return; @@ -2345,10 +2258,8 @@ dvr_entry_watched_set_watched(dvr_entry_t* de) /** * */ -static void -dvr_timer_disarm(void *aux) -{ - dvr_entry_t *de = aux; +static void dvr_timer_disarm(void* aux) { + dvr_entry_t* de = aux; dvr_entry_trace(de, "retention timer - disarm"); gtimer_disarm(&de->de_timer); } @@ -2356,10 +2267,8 @@ dvr_timer_disarm(void *aux) /** * */ -static void -dvr_timer_remove_files(void *aux) -{ - dvr_entry_t *de = aux; +static void dvr_timer_remove_files(void* aux) { + dvr_entry_t* de = aux; dvr_entry_retention_timer(de); } @@ -2367,33 +2276,32 @@ dvr_timer_remove_files(void *aux) * */ -#define DVR_UPDATED_ENABLED (1<<0) -#define DVR_UPDATED_CHANNEL (1<<1) -#define DVR_UPDATED_STOP (1<<2) -#define DVR_UPDATED_STOP_EXTRA (1<<3) -#define DVR_UPDATED_START (1<<4) -#define DVR_UPDATED_START_EXTRA (1<<5) -#define DVR_UPDATED_TITLE (1<<6) -#define DVR_UPDATED_SUBTITLE (1<<7) -#define DVR_UPDATED_SUMMARY (1<<8) -#define DVR_UPDATED_DESCRIPTION (1<<9) -#define DVR_UPDATED_PRIO (1<<10) -#define DVR_UPDATED_GENRE (1<<11) -#define DVR_UPDATED_RETENTION (1<<12) -#define DVR_UPDATED_REMOVAL (1<<13) -#define DVR_UPDATED_EID (1<<14) -#define DVR_UPDATED_BROADCAST (1<<15) -#define DVR_UPDATED_EPISODE (1<<16) -#define DVR_UPDATED_CONFIG (1<<17) -#define DVR_UPDATED_PLAYPOS (1<<18) -#define DVR_UPDATED_PLAYCOUNT (1<<19) -#define DVR_UPDATED_AGE_RATING (1<<20) - -static char *dvr_updated_str(char *buf, size_t buflen, int flags) -{ - static const char *x = "ecoOsStumdpgrviBEC"; - const char *p = x; - char *w = buf, *end = buf + buflen; +#define DVR_UPDATED_ENABLED (1 << 0) +#define DVR_UPDATED_CHANNEL (1 << 1) +#define DVR_UPDATED_STOP (1 << 2) +#define DVR_UPDATED_STOP_EXTRA (1 << 3) +#define DVR_UPDATED_START (1 << 4) +#define DVR_UPDATED_START_EXTRA (1 << 5) +#define DVR_UPDATED_TITLE (1 << 6) +#define DVR_UPDATED_SUBTITLE (1 << 7) +#define DVR_UPDATED_SUMMARY (1 << 8) +#define DVR_UPDATED_DESCRIPTION (1 << 9) +#define DVR_UPDATED_PRIO (1 << 10) +#define DVR_UPDATED_GENRE (1 << 11) +#define DVR_UPDATED_RETENTION (1 << 12) +#define DVR_UPDATED_REMOVAL (1 << 13) +#define DVR_UPDATED_EID (1 << 14) +#define DVR_UPDATED_BROADCAST (1 << 15) +#define DVR_UPDATED_EPISODE (1 << 16) +#define DVR_UPDATED_CONFIG (1 << 17) +#define DVR_UPDATED_PLAYPOS (1 << 18) +#define DVR_UPDATED_PLAYCOUNT (1 << 19) +#define DVR_UPDATED_AGE_RATING (1 << 20) + +static char* dvr_updated_str(char* buf, size_t buflen, int flags) { + static const char* x = "ecoOsStumdpgrviBEC"; + const char* p = x; + char * w = buf, *end = buf + buflen; for (p = x; *p && flags && w != end; p++, flags >>= 1) if (flags & 1) @@ -2401,45 +2309,51 @@ static char *dvr_updated_str(char *buf, size_t buflen, int flags) if (w == end) *(w - 1) = '\0'; else - *w ='\0'; + *w = '\0'; return buf; } -int -dvr_entry_set_playcount(dvr_entry_t *de, uint32_t playcount) -{ +int dvr_entry_set_playcount(dvr_entry_t* de, uint32_t playcount) { if (de->de_playcount == playcount) return 0; de->de_playcount = playcount; if (de->de_playcount) dvr_entry_watched_set_watched(de); - else /* Not watched, so disarm timer */ + else /* Not watched, so disarm timer */ dvr_entry_watched_timer_disarm(de); return 1; } -int -dvr_entry_incr_playcount(dvr_entry_t *de) -{ +int dvr_entry_incr_playcount(dvr_entry_t* de) { return dvr_entry_set_playcount(de, de->de_playcount + 1); } /** * */ -static dvr_entry_t *_dvr_entry_update - ( dvr_entry_t *de, int enabled, const char *dvr_config_uuid, - epg_broadcast_t *e, channel_t *ch, - const char *title, const char *subtitle, - const char *summary, const char *desc, - const char *lang, time_t start, time_t stop, - time_t start_extra, time_t stop_extra, - dvr_prio_t pri, int retention, int removal, - int playcount, int playposition, int age_rating, - ratinglabel_t *rating_label) -{ - char buf[40]; - int save = 0, updated = 0; +static dvr_entry_t* _dvr_entry_update(dvr_entry_t* de, + int enabled, + const char* dvr_config_uuid, + epg_broadcast_t* e, + channel_t* ch, + const char* title, + const char* subtitle, + const char* summary, + const char* desc, + const char* lang, + time_t start, + time_t stop, + time_t start_extra, + time_t stop_extra, + dvr_prio_t pri, + int retention, + int removal, + int playcount, + int playposition, + int age_rating, + ratinglabel_t* rating_label) { + char buf[40]; + int save = 0, updated = 0; epg_episode_num_t epnum; if (enabled >= 0) { @@ -2465,7 +2379,7 @@ static dvr_entry_t *_dvr_entry_update de->de_stop_extra = stop_extra; save |= DVR_UPDATED_STOP_EXTRA; } - if (save & (DVR_UPDATED_STOP|DVR_UPDATED_STOP_EXTRA|DVR_UPDATED_ENABLED)) { + if (save & (DVR_UPDATED_STOP | DVR_UPDATED_STOP_EXTRA | DVR_UPDATED_ENABLED)) { updated = 1; dvr_entry_set_timer(de); } @@ -2602,7 +2516,7 @@ static dvr_entry_t *_dvr_entry_update /* Genre */ if (e) { - epg_genre_t *g = LIST_FIRST(&e->genre); + epg_genre_t* g = LIST_FIRST(&e->genre); if (g && (g->code / 16) != de->de_content_type) { de->de_content_type = g->code / 16; save |= DVR_UPDATED_GENRE; @@ -2633,15 +2547,19 @@ dosave: if (save) { dvr_entry_changed(de); if (tvhlog_limit(&de->de_update_limit, 60)) { - tvhinfo(LS_DVR, "\"%s\" on \"%s\": Updated%s (%s)", - lang_str_get(de->de_title, NULL), DVR_CH_NAME(de), - updated ? " Timer" : "", - dvr_updated_str(buf, sizeof(buf), save)); + tvhinfo(LS_DVR, + "\"%s\" on \"%s\": Updated%s (%s)", + lang_str_get(de->de_title, NULL), + DVR_CH_NAME(de), + updated ? " Timer" : "", + dvr_updated_str(buf, sizeof(buf), save)); } else { - tvhtrace(LS_DVR, "\"%s\" on \"%s\": Updated%s (%s)", - lang_str_get(de->de_title, NULL), DVR_CH_NAME(de), - updated ? " Timer" : "", - dvr_updated_str(buf, sizeof(buf), save)); + tvhtrace(LS_DVR, + "\"%s\" on \"%s\": Updated%s (%s)", + lang_str_get(de->de_title, NULL), + DVR_CH_NAME(de), + updated ? " Timer" : "", + dvr_updated_str(buf, sizeof(buf), save)); } /* The updates could mean the autorec rule no longer matches the event, * so we have to destroy the de and the conf and let the autorec rule @@ -2653,9 +2571,9 @@ dosave: * it. */ if (dvr_autorec_entry_can_be_purged(de)) { - dvr_entry_assign_broadcast(de, NULL); - dvr_entry_destroy(de, 1); - de = NULL; + dvr_entry_assign_broadcast(de, NULL); + dvr_entry_destroy(de, 1); + de = NULL; } } @@ -2665,40 +2583,64 @@ dosave: /** * */ -dvr_entry_t * -dvr_entry_update - ( dvr_entry_t *de, int enabled, - const char *dvr_config_uuid, channel_t *ch, - const char *title, const char *subtitle, - const char *summary, const char *desc, const char *lang, - time_t start, time_t stop, - time_t start_extra, time_t stop_extra, - dvr_prio_t pri, int retention, int removal, int playcount, int playposition, - int age_rating, ratinglabel_t *rating_label ) -{ - return _dvr_entry_update(de, enabled, dvr_config_uuid, - NULL, ch, title, subtitle, summary, desc, lang, - start, stop, start_extra, stop_extra, - pri, retention, removal, playcount, playposition, - age_rating, rating_label); +dvr_entry_t* dvr_entry_update(dvr_entry_t* de, + int enabled, + const char* dvr_config_uuid, + channel_t* ch, + const char* title, + const char* subtitle, + const char* summary, + const char* desc, + const char* lang, + time_t start, + time_t stop, + time_t start_extra, + time_t stop_extra, + dvr_prio_t pri, + int retention, + int removal, + int playcount, + int playposition, + int age_rating, + ratinglabel_t* rating_label) { + return _dvr_entry_update(de, + enabled, + dvr_config_uuid, + NULL, + ch, + title, + subtitle, + summary, + desc, + lang, + start, + stop, + start_extra, + stop_extra, + pri, + retention, + removal, + playcount, + playposition, + age_rating, + rating_label); } /** * Used to notify the DVR that an event has been replaced in the EPG */ -void -dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e) -{ - dvr_entry_t *de, *de_next; - channel_t *ch = e->channel; - epg_broadcast_t *e2; - char t1buf[32], t2buf[32]; +void dvr_event_replaced(epg_broadcast_t* e, epg_broadcast_t* new_e) { + dvr_entry_t * de, *de_next; + channel_t* ch = e->channel; + epg_broadcast_t* e2; + char t1buf[32], t2buf[32]; assert(e != NULL); assert(new_e != NULL); /* Ignore */ - if (ch == NULL || e == new_e) return; + if (ch == NULL || e == new_e) + return; /* Existing entry */ for (de = LIST_FIRST(&ch->ch_dvrs); de; de = de_next) { @@ -2707,10 +2649,14 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e) if (de->de_bcast != e) continue; - dvr_entry_trace_time2(de, "start", e->start, "stop", e->stop, - "event replaced %s on %s", - epg_broadcast_get_title(e, NULL), - channel_get_name(ch, channel_blank_name)); + dvr_entry_trace_time2(de, + "start", + e->start, + "stop", + e->stop, + "event replaced %s on %s", + epg_broadcast_get_title(e, NULL), + channel_get_name(ch, channel_blank_name)); /* Ignore - already in progress */ if (de->de_sched_state != DVR_SCHEDULED) @@ -2722,24 +2668,42 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e) dvr_entry_assign_broadcast(de, NULL); dvr_entry_destroy(de, 1); - /* Find match */ + /* Find match */ } else { - RB_FOREACH(e2, &ch->ch_epg_schedule, sched_link) { - if (dvr_entry_fuzzy_match(de, e2, e2->dvb_eid, - de->de_config->dvr_update_window)) { - tvhtrace(LS_DVR, " replacement event %s on %s @ start %s stop %s", - epg_broadcast_get_title(e2, NULL), - channel_get_name(ch, channel_blank_name), - gmtime2local(e2->start, t1buf, sizeof(t1buf)), - gmtime2local(e2->stop, t2buf, sizeof(t2buf))); - _dvr_entry_update(de, -1, NULL, e2, NULL, NULL, NULL, NULL, NULL, - NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0, -1, -1, 0, NULL); + RB_FOREACH (e2, &ch->ch_epg_schedule, sched_link) { + if (dvr_entry_fuzzy_match(de, e2, e2->dvb_eid, de->de_config->dvr_update_window)) { + tvhtrace(LS_DVR, + " replacement event %s on %s @ start %s stop %s", + epg_broadcast_get_title(e2, NULL), + channel_get_name(ch, channel_blank_name), + gmtime2local(e2->start, t1buf, sizeof(t1buf)), + gmtime2local(e2->stop, t2buf, sizeof(t2buf))); + _dvr_entry_update(de, + -1, + NULL, + e2, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + 0, + 0, + DVR_PRIO_NOTSET, + 0, + 0, + -1, + -1, + 0, + NULL); return; } } dvr_entry_assign_broadcast(de, NULL); - } } } @@ -2747,14 +2711,12 @@ dvr_event_replaced(epg_broadcast_t *e, epg_broadcast_t *new_e) /** * Used to notify the DVR that an event has been removed */ -void -dvr_event_removed(epg_broadcast_t *e) -{ - dvr_entry_t *de; +void dvr_event_removed(epg_broadcast_t* e) { + dvr_entry_t* de; if (e->channel == NULL) return; - LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) { + LIST_FOREACH (de, &e->channel->ch_dvrs, de_channel_link) { if (de->de_bcast != e) continue; dvr_entry_assign_broadcast(de, NULL); @@ -2765,29 +2727,72 @@ dvr_event_removed(epg_broadcast_t *e) /** * Event was updated in epg */ -void dvr_event_updated(epg_broadcast_t *e) -{ - dvr_entry_t *de; +void dvr_event_updated(epg_broadcast_t* e) { + dvr_entry_t* de; if (e->channel == NULL) return; - LIST_FOREACH(de, &e->dvr_entries, de_bcast_link) { + LIST_FOREACH (de, &e->dvr_entries, de_bcast_link) { assert(de->de_bcast == e); - if (de->de_sched_state != DVR_SCHEDULED) continue; - _dvr_entry_update(de, -1, NULL, e, NULL, NULL, NULL, NULL, NULL, - NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0, -1, -1, 0, NULL); - } - LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) { - if (de->de_sched_state != DVR_SCHEDULED) continue; - if (de->de_bcast) continue; - if (dvr_entry_fuzzy_match(de, e, e->dvb_eid, - de->de_config->dvr_update_window)) { - dvr_entry_trace_time2(de, "start", e->start, "stop", e->stop, - "link to event %s on %s", - epg_broadcast_get_title(e, NULL), - channel_get_name(e->channel, channel_blank_name)); - _dvr_entry_update(de, -1, NULL, e, NULL, NULL, NULL, NULL, NULL, - NULL, 0, 0, 0, 0, DVR_PRIO_NOTSET, 0, 0, -1, -1, 0, NULL); + if (de->de_sched_state != DVR_SCHEDULED) + continue; + _dvr_entry_update(de, + -1, + NULL, + e, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + 0, + 0, + DVR_PRIO_NOTSET, + 0, + 0, + -1, + -1, + 0, + NULL); + } + LIST_FOREACH (de, &e->channel->ch_dvrs, de_channel_link) { + if (de->de_sched_state != DVR_SCHEDULED) + continue; + if (de->de_bcast) + continue; + if (dvr_entry_fuzzy_match(de, e, e->dvb_eid, de->de_config->dvr_update_window)) { + dvr_entry_trace_time2(de, + "start", + e->start, + "stop", + e->stop, + "link to event %s on %s", + epg_broadcast_get_title(e, NULL), + channel_get_name(e->channel, channel_blank_name)); + _dvr_entry_update(de, + -1, + NULL, + e, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + 0, + 0, + 0, + 0, + DVR_PRIO_NOTSET, + 0, + 0, + -1, + -1, + 0, + NULL); } } } @@ -2795,48 +2800,51 @@ void dvr_event_updated(epg_broadcast_t *e) /** * Event running status is updated */ -void dvr_event_running(epg_broadcast_t *e, epg_running_t running) -{ - dvr_entry_t *de; - epg_broadcast_t *e2; - const char *srcname; - char ubuf[UUID_HEX_SIZE]; +void dvr_event_running(epg_broadcast_t* e, epg_running_t running) { + dvr_entry_t* de; + epg_broadcast_t* e2; + const char* srcname; + char ubuf[UUID_HEX_SIZE]; if (e->dvb_eid == 0 || e->channel == NULL) return; - tvhtrace(LS_DVR, "dvr event running check for %s on %s running %d", - epg_broadcast_get_title(e, NULL), - channel_get_name(e->channel, channel_blank_name), - running); - LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) { + tvhtrace(LS_DVR, + "dvr event running check for %s on %s running %d", + epg_broadcast_get_title(e, NULL), + channel_get_name(e->channel, channel_blank_name), + running); + LIST_FOREACH (de, &e->channel->ch_dvrs, de_channel_link) { if (running == EPG_RUNNING_NOW && de->de_dvb_eid == e->dvb_eid) { if (de->de_running_pause) { - tvhdebug(LS_DVR, "dvr entry %s event %s on %s - EPG unpause", - idnode_uuid_as_str(&de->de_id, ubuf), - epg_broadcast_get_title(e, NULL), - channel_get_name(e->channel, channel_blank_name)); + tvhdebug(LS_DVR, + "dvr entry %s event %s on %s - EPG unpause", + idnode_uuid_as_str(&de->de_id, ubuf), + epg_broadcast_get_title(e, NULL), + channel_get_name(e->channel, channel_blank_name)); atomic_set_time_t(&de->de_running_pause, 0); atomic_add(&de->de_running_change, 1); } if (!de->de_running_start) { - tvhdebug(LS_DVR, "dvr entry %s event %s on %s - EPG marking start", - idnode_uuid_as_str(&de->de_id, ubuf), - epg_broadcast_get_title(e, NULL), - channel_get_name(e->channel, channel_blank_name)); + tvhdebug(LS_DVR, + "dvr entry %s event %s on %s - EPG marking start", + idnode_uuid_as_str(&de->de_id, ubuf), + epg_broadcast_get_title(e, NULL), + channel_get_name(e->channel, channel_blank_name)); atomic_set_time_t(&de->de_running_start, gclk()); atomic_add(&de->de_running_change, 1); } if (dvr_entry_get_start_time(de, 1) > gclk()) { - tvhdebug(LS_DVR, "dvr entry %s event %s on %s - EPG start", - idnode_uuid_as_str(&de->de_id, ubuf), - epg_broadcast_get_title(e, NULL), - channel_get_name(e->channel, channel_blank_name)); + tvhdebug(LS_DVR, + "dvr entry %s event %s on %s - EPG start", + idnode_uuid_as_str(&de->de_id, ubuf), + epg_broadcast_get_title(e, NULL), + channel_get_name(e->channel, channel_blank_name)); atomic_set_time_t(&de->de_start, gclk()); atomic_add(&de->de_running_change, 1); dvr_entry_set_timer(de); } } else if ((running == EPG_RUNNING_STOP && de->de_dvb_eid == e->dvb_eid) || - running == EPG_RUNNING_NOW) { + running == EPG_RUNNING_NOW) { /* Don't stop recording if we are a segmented programme since * (by definition) the first segment will be marked as stop long * before the second segment is marked as started. Otherwise if we @@ -2846,7 +2854,7 @@ void dvr_event_running(epg_broadcast_t *e, epg_running_t running) */ if (de->de_segment_stop_extra) { e2 = dvr_entry_get_segment_last(de); - for ( ; e2; e2 = epg_broadcast_get_prev(e2)) + for (; e2; e2 = epg_broadcast_get_prev(e2)) if (e == e2) break; if (e2) @@ -2861,31 +2869,35 @@ void dvr_event_running(epg_broadcast_t *e, epg_running_t running) continue; srcname = de->de_dvb_eid == e->dvb_eid ? "event" : "other running event"; - if (!de->de_running_stop || - de->de_running_start > de->de_running_stop) { + if (!de->de_running_stop || de->de_running_start > de->de_running_stop) { atomic_add(&de->de_running_change, 1); - tvhdebug(LS_DVR, "dvr entry %s %s %s on %s - EPG marking stop", - idnode_uuid_as_str(&de->de_id, ubuf), srcname, - epg_broadcast_get_title(e, NULL), - channel_get_name(de->de_channel, channel_blank_name)); + tvhdebug(LS_DVR, + "dvr entry %s %s %s on %s - EPG marking stop", + idnode_uuid_as_str(&de->de_id, ubuf), + srcname, + epg_broadcast_get_title(e, NULL), + channel_get_name(de->de_channel, channel_blank_name)); } atomic_set_time_t(&de->de_running_stop, gclk()); atomic_set_time_t(&de->de_running_pause, 0); if (de->de_sched_state == DVR_RECORDING && de->de_running_start) { if (dvr_entry_get_epg_running(de)) { - tvhdebug(LS_DVR, "dvr entry %s %s %s on %s - EPG stop", - idnode_uuid_as_str(&de->de_id, ubuf), srcname, - epg_broadcast_get_title(e, NULL), - channel_get_name(de->de_channel, channel_blank_name)); + tvhdebug(LS_DVR, + "dvr entry %s %s %s on %s - EPG stop", + idnode_uuid_as_str(&de->de_id, ubuf), + srcname, + epg_broadcast_get_title(e, NULL), + channel_get_name(de->de_channel, channel_blank_name)); dvr_stop_recording(de, SM_CODE_OK, 0, 0); } } } else if (running == EPG_RUNNING_PAUSE && de->de_dvb_eid == e->dvb_eid) { if (!de->de_running_pause) { - tvhdebug(LS_DVR, "dvr entry %s event %s on %s - EPG pause", - idnode_uuid_as_str(&de->de_id, ubuf), - epg_broadcast_get_title(e, NULL), - channel_get_name(e->channel, channel_blank_name)); + tvhdebug(LS_DVR, + "dvr entry %s event %s on %s - EPG pause", + idnode_uuid_as_str(&de->de_id, ubuf), + epg_broadcast_get_title(e, NULL), + channel_get_name(e->channel, channel_blank_name)); atomic_set_time_t(&de->de_running_pause, gclk()); atomic_add(&de->de_running_change, 1); } @@ -2896,11 +2908,9 @@ void dvr_event_running(epg_broadcast_t *e, epg_running_t running) /** * */ -void -dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf, int clone) -{ - dvr_rs_state_t rec_state = de->de_rec_state; - dvr_autorec_entry_t *dae = de->de_autorec; +void dvr_stop_recording(dvr_entry_t* de, int stopcode, int saveconf, int clone) { + dvr_rs_state_t rec_state = de->de_rec_state; + dvr_autorec_entry_t* dae = de->de_autorec; if (!clone) dvr_rec_unsubscribe(de); @@ -2908,17 +2918,18 @@ dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf, int clone) de->de_dont_reschedule = 1; if (stopcode != SM_CODE_INVALID_TARGET && - (rec_state == DVR_RS_PENDING || - rec_state == DVR_RS_WAIT_PROGRAM_START || - htsmsg_is_empty(de->de_files))) + (rec_state == DVR_RS_PENDING || rec_state == DVR_RS_WAIT_PROGRAM_START || + htsmsg_is_empty(de->de_files))) dvr_entry_missed_time(de, stopcode); else dvr_entry_completed(de, stopcode); - tvhinfo(LS_DVR, "\"%s\" on \"%s\": " - "End of program: %s", - lang_str_get(de->de_title, NULL), DVR_CH_NAME(de), - dvr_entry_status(de)); + tvhinfo(LS_DVR, + "\"%s\" on \"%s\": " + "End of program: %s", + lang_str_get(de->de_title, NULL), + DVR_CH_NAME(de), + dvr_entry_status(de)); if (dvr_entry_rerecord(de)) return; @@ -2933,28 +2944,36 @@ dvr_stop_recording(dvr_entry_t *de, int stopcode, int saveconf, int clone) dvr_autorec_changed(de->de_autorec, 0); } - /** * */ -static void -dvr_timer_stop_recording(void *aux) -{ - dvr_entry_t *de = aux; - if(de->de_sched_state != DVR_RECORDING) +static void dvr_timer_stop_recording(void* aux) { + dvr_entry_t* de = aux; + if (de->de_sched_state != DVR_RECORDING) return; dvr_entry_trace_time2(de, - "rstart", de->de_running_start, - "rstop", de->de_running_stop, - "stop recording timer called"); + "rstart", + de->de_running_start, + "rstop", + de->de_running_stop, + "stop recording timer called"); /* EPG thinks that the program is running */ if (de->de_segment_stop_extra) { const time_t stop = dvr_entry_get_stop_time(de); - dvr_entry_trace_time2(de, "running start", de->de_running_start, "running stop", de->de_running_stop, "forcing stop"); - dvr_entry_trace_time1(de, "stop", stop, "forcing stop - segment extra %"PRId64, (int64_t)de->de_segment_stop_extra); + dvr_entry_trace_time2(de, + "running start", + de->de_running_start, + "running stop", + de->de_running_stop, + "forcing stop"); + dvr_entry_trace_time1(de, + "stop", + stop, + "forcing stop - segment extra %" PRId64, + (int64_t)de->de_segment_stop_extra); /* no-op. We fall through to the final dvr_stop_recording below. - * This path is here purely to get a log. - */ + * This path is here purely to get a log. + */ } else if (de->de_running_start > de->de_running_stop) { gtimer_arm_rel(&de->de_timer, dvr_timer_stop_recording, de, 10); return; @@ -2962,16 +2981,12 @@ dvr_timer_stop_recording(void *aux) dvr_stop_recording(aux, SM_CODE_OK, 1, 0); } - - /** * */ -static void -dvr_entry_start_recording(dvr_entry_t *de, int clone) -{ +static void dvr_entry_start_recording(dvr_entry_t* de, int clone) { time_t stop; - int r; + int r; if (!de->de_enabled) { dvr_entry_missed_time(de, SM_CODE_SVC_NOT_ENABLED); @@ -2980,24 +2995,25 @@ dvr_entry_start_recording(dvr_entry_t *de, int clone) dvr_entry_set_state(de, DVR_RECORDING, DVR_RS_PENDING, SM_CODE_OK); - tvhinfo(LS_DVR, "\"%s\" on \"%s\" recorder starting", - lang_str_get(de->de_title, NULL), DVR_CH_NAME(de)); + tvhinfo(LS_DVR, + "\"%s\" on \"%s\" recorder starting", + lang_str_get(de->de_title, NULL), + DVR_CH_NAME(de)); /* * The running flag is updated only on the event change. When the DVR * entry is added too late, the running timers might not be updated. */ if (de->de_bcast && de->de_running_start == 0 && de->de_running_stop == 0) { - epg_broadcast_t *ebc = epg_broadcast_get_prev(de->de_bcast); - if (de->de_bcast->running != EPG_RUNNING_NOTSET || - (ebc && ebc->running != EPG_RUNNING_NOTSET)) + epg_broadcast_t* ebc = epg_broadcast_get_prev(de->de_bcast); + if (de->de_bcast->running != EPG_RUNNING_NOTSET || (ebc && ebc->running != EPG_RUNNING_NOTSET)) de->de_running_stop = gclk(); } if (!clone && (r = dvr_rec_subscribe(de)) < 0) { - dvr_entry_completed(de, r == -EPERM ? SM_CODE_USER_ACCESS : - (r == -EOVERFLOW ? SM_CODE_USER_LIMIT : - SM_CODE_BAD_SOURCE)); + dvr_entry_completed(de, + r == -EPERM ? SM_CODE_USER_ACCESS + : (r == -EOVERFLOW ? SM_CODE_USER_LIMIT : SM_CODE_BAD_SOURCE)); return; } @@ -3011,21 +3027,18 @@ dvr_entry_start_recording(dvr_entry_t *de, int clone) * further segments enter the EIT window. */ de->de_segment_stop_extra = 0; - stop = dvr_entry_get_stop_time(de); + stop = dvr_entry_get_stop_time(de); dvr_entry_trace_time2(de, "original stop", de->de_stop, "stop", stop, "stop timer set"); gtimer_arm_absn(&de->de_timer, dvr_timer_stop_recording, de, stop); } - /** * */ -static void -dvr_timer_start_recording(void *aux) -{ - dvr_entry_t *de = aux; +static void dvr_timer_start_recording(void* aux) { + dvr_entry_t* de = aux; if (de->de_channel == NULL || !de->de_channel->ch_enabled) { dvr_entry_set_state(de, DVR_NOSTATE, DVR_RS_PENDING, de->de_last_error); @@ -3041,30 +3054,24 @@ dvr_timer_start_recording(void *aux) dvr_entry_start_recording(de, 0); } - /** * */ -dvr_entry_t * -dvr_entry_find_by_id(int id) -{ - dvr_entry_t *de; - LIST_FOREACH(de, &dvrentries, de_global_link) - if(idnode_get_short_uuid(&de->de_id) == id) +dvr_entry_t* dvr_entry_find_by_id(int id) { + dvr_entry_t* de; + LIST_FOREACH (de, &dvrentries, de_global_link) + if (idnode_get_short_uuid(&de->de_id) == id) break; return de; } - /** * Unconditionally remove an entry */ -static void -dvr_entry_purge(dvr_entry_t *de, int delconf) -{ +static void dvr_entry_purge(dvr_entry_t* de, int delconf) { int dont_reschedule; - if(de->de_sched_state == DVR_RECORDING) { + if (de->de_sched_state == DVR_RECORDING) { dont_reschedule = de->de_dont_reschedule; dvr_stop_recording(de, SM_CODE_SOURCE_DELETED, delconf, 0); if (!delconf) @@ -3072,15 +3079,12 @@ dvr_entry_purge(dvr_entry_t *de, int delconf) } } - /* ************************************************************************** * DVR Entry Class definition * **************************************************************************/ -static void -dvr_entry_class_changed(idnode_t *self) -{ - dvr_entry_t *de = (dvr_entry_t *)self; +static void dvr_entry_class_changed(idnode_t* self) { + dvr_entry_t* de = (dvr_entry_t*)self; if (de->de_in_unsubscribe) return; if (dvr_entry_is_valid(de)) @@ -3088,15 +3092,13 @@ dvr_entry_class_changed(idnode_t *self) htsp_dvr_entry_update(de); } -static htsmsg_t * -dvr_entry_class_save(idnode_t *self, char *filename, size_t fsize) -{ - dvr_entry_t *de = (dvr_entry_t *)self; - htsmsg_t *m = htsmsg_create_map(), *e, *l, *c, *info; - htsmsg_field_t *f; - char ubuf[UUID_HEX_SIZE]; - const char *filename2; - int64_t s64; +static htsmsg_t* dvr_entry_class_save(idnode_t* self, char* filename, size_t fsize) { + dvr_entry_t* de = (dvr_entry_t*)self; + htsmsg_t * m = htsmsg_create_map(), *e, *l, *c, *info; + htsmsg_field_t* f; + char ubuf[UUID_HEX_SIZE]; + const char* filename2; + int64_t s64; idnode_save(&de->de_id, m); if ((e = epg_episode_epnum_serialize(&de->de_epnum)) != NULL) @@ -3104,23 +3106,23 @@ dvr_entry_class_save(idnode_t *self, char *filename, size_t fsize) if (de->de_files) { l = htsmsg_create_list(); HTSMSG_FOREACH(f, de->de_files) - if ((e = htsmsg_field_get_map(f)) != NULL) { - filename2 = htsmsg_get_str(e, "filename"); - info = htsmsg_get_list(e, "info"); - if (filename2) { - c = htsmsg_create_map(); - htsmsg_add_str(c, "filename", filename2); - if (info) - htsmsg_add_msg(c, "info", htsmsg_copy(info)); - if (!htsmsg_get_s64(e, "start", &s64)) - htsmsg_add_s64(c, "start", s64); - if (!htsmsg_get_s64(e, "stop", &s64)) - htsmsg_add_s64(c, "stop", s64); - if (!htsmsg_get_s64(e, "size", &s64)) - htsmsg_add_s64(c, "size", s64); - htsmsg_add_msg(l, NULL, c); - } + if ((e = htsmsg_field_get_map(f)) != NULL) { + filename2 = htsmsg_get_str(e, "filename"); + info = htsmsg_get_list(e, "info"); + if (filename2) { + c = htsmsg_create_map(); + htsmsg_add_str(c, "filename", filename2); + if (info) + htsmsg_add_msg(c, "info", htsmsg_copy(info)); + if (!htsmsg_get_s64(e, "start", &s64)) + htsmsg_add_s64(c, "start", s64); + if (!htsmsg_get_s64(e, "stop", &s64)) + htsmsg_add_s64(c, "stop", s64); + if (!htsmsg_get_s64(e, "size", &s64)) + htsmsg_add_s64(c, "size", s64); + htsmsg_add_msg(l, NULL, c); } + } htsmsg_add_msg(m, "files", l); } if (filename) @@ -3128,19 +3130,15 @@ dvr_entry_class_save(idnode_t *self, char *filename, size_t fsize) return m; } -static void -dvr_entry_class_delete(idnode_t *self) -{ - dvr_entry_t *de = (dvr_entry_t *)self; +static void dvr_entry_class_delete(idnode_t* self) { + dvr_entry_t* de = (dvr_entry_t*)self; dvr_entry_cancel_delete(de, 0); } -static int -dvr_entry_class_perm(idnode_t *self, access_t *a, htsmsg_t *msg_to_write) -{ - dvr_entry_t *de = (dvr_entry_t *)self; +static int dvr_entry_class_perm(idnode_t* self, access_t* a, htsmsg_t* msg_to_write) { + dvr_entry_t* de = (dvr_entry_t*)self; - if (access_verify2(a, ACCESS_OR|ACCESS_ADMIN|ACCESS_RECORDER)) + if (access_verify2(a, ACCESS_OR | ACCESS_ADMIN | ACCESS_RECORDER)) return -1; if (!access_verify2(a, ACCESS_ADMIN)) return 0; @@ -3149,12 +3147,9 @@ dvr_entry_class_perm(idnode_t *self, access_t *a, htsmsg_t *msg_to_write) return 0; } -static void -dvr_entry_class_get_title - (idnode_t *self, const char *lang, char *dst, size_t dstsize) -{ - dvr_entry_t *de = (dvr_entry_t *)self; - const char *s; +static void dvr_entry_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + dvr_entry_t* de = (dvr_entry_t*)self; + const char* s; s = lang_str_get(de->de_title, lang); if (tvh_str_default(s, NULL) == NULL) { s = lang ? lang_str_get(de->de_title, NULL) : NULL; @@ -3167,9 +3162,7 @@ dvr_entry_class_get_title snprintf(dst, dstsize, "%s", s); } -static int -dvr_entry_class_time_set(dvr_entry_t *de, time_t *v, time_t nv) -{ +static int dvr_entry_class_time_set(dvr_entry_t* de, time_t* v, time_t nv) { if (!dvr_entry_is_editable(de)) return 0; if (nv != *v) { @@ -3179,9 +3172,7 @@ dvr_entry_class_time_set(dvr_entry_t *de, time_t *v, time_t nv) return 0; } -static int -dvr_entry_class_int_set(dvr_entry_t *de, int *v, int nv) -{ +static int dvr_entry_class_int_set(dvr_entry_t* de, int* v, int nv) { if (!dvr_entry_is_editable(de)) return 0; if (nv != *v) { @@ -3191,69 +3182,52 @@ dvr_entry_class_int_set(dvr_entry_t *de, int *v, int nv) return 0; } -static int -dvr_entry_class_create_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - return dvr_entry_class_time_set(de, &de->de_create, *(time_t *)v); +static int dvr_entry_class_create_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + return dvr_entry_class_time_set(de, &de->de_create, *(time_t*)v); } -static int -dvr_entry_class_start_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - return dvr_entry_class_time_set(de, &de->de_start, *(time_t *)v); +static int dvr_entry_class_start_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + return dvr_entry_class_time_set(de, &de->de_start, *(time_t*)v); } -static uint32_t -dvr_entry_class_start_opts(void *o, uint32_t opts) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static uint32_t dvr_entry_class_start_opts(void* o, uint32_t opts) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de && !dvr_entry_is_editable(de)) return PO_RDONLY; return 0; } -static uint32_t -dvr_entry_class_config_name_opts(void *o, uint32_t opts) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static uint32_t dvr_entry_class_config_name_opts(void* o, uint32_t opts) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de && !dvr_entry_is_editable(de)) return PO_RDONLY | PO_ADVANCED; return PO_ADVANCED; } -static uint32_t -dvr_entry_class_owner_opts(void *o, uint32_t opts) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - if (de && de->de_id.in_access && - !access_verify2(de->de_id.in_access, ACCESS_ADMIN)) +static uint32_t dvr_entry_class_owner_opts(void* o, uint32_t opts) { + dvr_entry_t* de = (dvr_entry_t*)o; + if (de && de->de_id.in_access && !access_verify2(de->de_id.in_access, ACCESS_ADMIN)) return PO_ADVANCED; return PO_RDONLY | PO_ADVANCED; } -static uint32_t -dvr_entry_class_start_extra_opts(void *o, uint32_t opts) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static uint32_t dvr_entry_class_start_extra_opts(void* o, uint32_t opts) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de && !dvr_entry_is_editable(de)) return PO_RDONLY | PO_DURATION | PO_ADVANCED; return PO_DURATION | PO_ADVANCED | PO_DOC_NLIST; } -static int -dvr_entry_class_start_extra_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - return dvr_entry_class_time_set(de, &de->de_start_extra, *(time_t *)v); +static int dvr_entry_class_start_extra_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + return dvr_entry_class_time_set(de, &de->de_start_extra, *(time_t*)v); } -static int -dvr_entry_class_stop_set(void *o, const void *_v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - time_t v = *(time_t *)_v; +static int dvr_entry_class_stop_set(void* o, const void* _v) { + dvr_entry_t* de = (dvr_entry_t*)o; + time_t v = *(time_t*)_v; if (!dvr_entry_is_editable(de)) { if (v < gclk()) @@ -3268,11 +3242,9 @@ dvr_entry_class_stop_set(void *o, const void *_v) return 0; } -static int -dvr_entry_class_config_name_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - dvr_config_t *cfg; +static int dvr_entry_class_config_name_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + dvr_config_t* cfg; if (!dvr_entry_is_editable(de)) return 0; @@ -3295,10 +3267,8 @@ dvr_entry_class_config_name_set(void *o, const void *v) return 0; } -static const void * -dvr_entry_class_config_name_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_config_name_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_config) idnode_uuid_as_str(&de->de_config->dvr_id, prop_sbuf); else @@ -3306,42 +3276,34 @@ dvr_entry_class_config_name_get(void *o) return &prop_sbuf_ptr; } -htsmsg_t * -dvr_entry_class_config_name_list(void *o, const char *lang) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_t *p = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "idnode/load"); +htsmsg_t* dvr_entry_class_config_name_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_t* p = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "idnode/load"); htsmsg_add_str(m, "event", "dvrconfig"); - htsmsg_add_u32(p, "enum", 1); + htsmsg_add_u32(p, "enum", 1); htsmsg_add_str(p, "class", dvr_config_class.ic_class); htsmsg_add_msg(m, "params", p); return m; } -static char * -dvr_entry_class_config_name_rend(void *o, const char *lang) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static char* dvr_entry_class_config_name_rend(void* o, const char* lang) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_config) return strdup(de->de_config->dvr_config_name); return NULL; } -static const void * -dvr_entry_class_filename_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - prop_ptr = dvr_get_filename(de) ?: ""; +static const void* dvr_entry_class_filename_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; + prop_ptr = dvr_get_filename(de) ?: ""; return &prop_ptr; } -static int -dvr_entry_class_channel_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - channel_t *ch; +static int dvr_entry_class_channel_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + channel_t* ch; if (!dvr_entry_is_editable(de)) return 0; @@ -3351,28 +3313,25 @@ dvr_entry_class_channel_set(void *o, const void *v) LIST_REMOVE(de, de_channel_link); free(de->de_channel_name); de->de_channel_name = NULL; - de->de_channel = NULL; + de->de_channel = NULL; return 1; } } else if (de->de_channel != ch) { - if (de->de_id.in_access && - !channel_access(ch, de->de_id.in_access, 1)) + if (de->de_id.in_access && !channel_access(ch, de->de_id.in_access, 1)) return 0; if (de->de_channel) LIST_REMOVE(de, de_channel_link); free(de->de_channel_name); de->de_channel_name = strdup(channel_get_name(ch, "")); - de->de_channel = ch; + de->de_channel = ch; LIST_INSERT_HEAD(&ch->ch_dvrs, de, de_channel_link); return 1; } return 0; } -static const void * -dvr_entry_class_channel_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_channel_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_channel) idnode_uuid_as_str(&de->de_channel->ch_id, prop_sbuf); else @@ -3380,21 +3339,17 @@ dvr_entry_class_channel_get(void *o) return &prop_sbuf_ptr; } -static char * -dvr_entry_class_channel_rend(void *o, const char *lang) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static char* dvr_entry_class_channel_rend(void* o, const char* lang) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_channel) return strdup(channel_get_name(de->de_channel, tvh_gettext_lang(lang, channel_blank_name))); return NULL; } -static int -dvr_entry_class_channel_name_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - channel_t *ch; - char ubuf[UUID_HEX_SIZE]; +static int dvr_entry_class_channel_name_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + channel_t* ch; + char ubuf[UUID_HEX_SIZE]; if (!dvr_entry_is_editable(de)) return 0; if (!strcmp(de->de_channel_name ?: "", v ?: "")) @@ -3409,10 +3364,8 @@ dvr_entry_class_channel_name_set(void *o, const void *v) } } -static const void * -dvr_entry_class_channel_name_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_channel_name_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_channel) prop_ptr = channel_get_name(de->de_channel, channel_blank_name); else @@ -3420,14 +3373,12 @@ dvr_entry_class_channel_name_get(void *o) return &prop_ptr; } -static int -dvr_entry_class_rating_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - ratinglabel_t *rl = NULL; +static int dvr_entry_class_rating_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + ratinglabel_t* rl = NULL; - //If RL processing is not enabled, return a null and exit. - if(!epggrab_conf.epgdb_processparentallabels){ + // If RL processing is not enabled, return a null and exit. + if (!epggrab_conf.epgdb_processparentallabels) { de->de_rating_label = NULL; return 0; } @@ -3435,49 +3386,47 @@ dvr_entry_class_rating_set(void *o, const void *v) if (!dvr_entry_is_editable(de)) return 0; - //If the entry is in the past, don't link to the RL object. - if (de->de_stop < gclk()){ + // If the entry is in the past, don't link to the RL object. + if (de->de_stop < gclk()) { de->de_rating_label = NULL; return 0; } rl = v ? ratinglabel_find_from_uuid(v) : NULL; - //If the rating label is found. - if(rl){ - //Set the rating label pointer in the DVR entry object + // If the rating label is found. + if (rl) { + // Set the rating label pointer in the DVR entry object de->de_rating_label = rl; - //Save the label and icon values - if(de->de_rating_label_saved){ - free(de->de_rating_label_saved); + // Save the label and icon values + if (de->de_rating_label_saved) { + free(de->de_rating_label_saved); } - if(rl->rl_display_label){ - de->de_rating_label_saved = strdup(rl->rl_display_label); + if (rl->rl_display_label) { + de->de_rating_label_saved = strdup(rl->rl_display_label); } - if(de->de_rating_icon_saved){ - free(de->de_rating_icon_saved); + if (de->de_rating_icon_saved) { + free(de->de_rating_icon_saved); } - if(rl->rl_icon){ - de->de_rating_icon_saved = strdup(rl->rl_icon); + if (rl->rl_icon) { + de->de_rating_icon_saved = strdup(rl->rl_icon); } return 1; - }//END we got an RL object. + } // END we got an RL object. return 0; } -//Return the UUID string for this rating label of this entry. -//If RL is not enabled, this function must return an empty string, -//returning NULL will cause a crash. -static const void * -dvr_entry_class_rating_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +// Return the UUID string for this rating label of this entry. +// If RL is not enabled, this function must return an empty string, +// returning NULL will cause a crash. +static const void* dvr_entry_class_rating_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_rating_label) idnode_uuid_as_str(&de->de_rating_label->rl_id, prop_sbuf); else @@ -3485,83 +3434,76 @@ dvr_entry_class_rating_get(void *o) return &prop_sbuf_ptr; } -static int -dvr_entry_class_pri_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - int pri = *(int *)v; +static int dvr_entry_class_pri_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + int pri = *(int*)v; if (pri == DVR_PRIO_NOTSET || pri < 0 || pri > DVR_PRIO_DEFAULT) pri = DVR_PRIO_DEFAULT; return dvr_entry_class_int_set(de, &de->de_pri, pri); } -htsmsg_t * -dvr_entry_class_pri_list ( void *o, const char *lang ) -{ +htsmsg_t* dvr_entry_class_pri_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Default"), DVR_PRIO_DEFAULT }, - { N_("Important"), DVR_PRIO_IMPORTANT }, - { N_("High"), DVR_PRIO_HIGH, }, - { N_("Normal"), DVR_PRIO_NORMAL }, - { N_("Low"), DVR_PRIO_LOW }, - { N_("Unimportant"), DVR_PRIO_UNIMPORTANT }, + {N_("Default"), DVR_PRIO_DEFAULT}, + {N_("Important"), DVR_PRIO_IMPORTANT}, + { + N_("High"), + DVR_PRIO_HIGH, + }, + {N_("Normal"), DVR_PRIO_NORMAL}, + {N_("Low"), DVR_PRIO_LOW}, + {N_("Unimportant"), DVR_PRIO_UNIMPORTANT}, }; return strtab2htsmsg(tab, 1, lang); } -htsmsg_t * -dvr_entry_class_retention_list ( void *o, const char *lang ) -{ +htsmsg_t* dvr_entry_class_retention_list(void* o, const char* lang) { static const struct strtab_u32 tab[] = { - { N_("DVR configuration"), DVR_RET_REM_DVRCONFIG }, - { N_("1 day"), DVR_RET_REM_1DAY }, - { N_("3 days"), DVR_RET_REM_3DAY }, - { N_("5 days"), DVR_RET_REM_5DAY }, - { N_("1 week"), DVR_RET_REM_1WEEK }, - { N_("2 weeks"), DVR_RET_REM_2WEEK }, - { N_("3 weeks"), DVR_RET_REM_3WEEK }, - { N_("1 month"), DVR_RET_REM_1MONTH }, - { N_("2 months"), DVR_RET_REM_2MONTH }, - { N_("3 months"), DVR_RET_REM_3MONTH }, - { N_("6 months"), DVR_RET_REM_6MONTH }, - { N_("1 year"), DVR_RET_REM_1YEAR }, - { N_("2 years"), DVR_RET_REM_2YEARS }, - { N_("3 years"), DVR_RET_REM_3YEARS }, - { N_("On file removal"), DVR_RET_ONREMOVE }, - { N_("Forever"), DVR_RET_REM_FOREVER }, + {N_("DVR configuration"), DVR_RET_REM_DVRCONFIG}, + {N_("1 day"), DVR_RET_REM_1DAY}, + {N_("3 days"), DVR_RET_REM_3DAY}, + {N_("5 days"), DVR_RET_REM_5DAY}, + {N_("1 week"), DVR_RET_REM_1WEEK}, + {N_("2 weeks"), DVR_RET_REM_2WEEK}, + {N_("3 weeks"), DVR_RET_REM_3WEEK}, + {N_("1 month"), DVR_RET_REM_1MONTH}, + {N_("2 months"), DVR_RET_REM_2MONTH}, + {N_("3 months"), DVR_RET_REM_3MONTH}, + {N_("6 months"), DVR_RET_REM_6MONTH}, + {N_("1 year"), DVR_RET_REM_1YEAR}, + {N_("2 years"), DVR_RET_REM_2YEARS}, + {N_("3 years"), DVR_RET_REM_3YEARS}, + {N_("On file removal"), DVR_RET_ONREMOVE}, + {N_("Forever"), DVR_RET_REM_FOREVER}, }; return strtab2htsmsg_u32(tab, 1, lang); } -htsmsg_t * -dvr_entry_class_removal_list ( void *o, const char *lang ) -{ +htsmsg_t* dvr_entry_class_removal_list(void* o, const char* lang) { static const struct strtab_u32 tab[] = { - { N_("DVR configuration"), DVR_RET_REM_DVRCONFIG }, - { N_("1 day"), DVR_RET_REM_1DAY }, - { N_("3 days"), DVR_RET_REM_3DAY }, - { N_("5 days"), DVR_RET_REM_5DAY }, - { N_("1 week"), DVR_RET_REM_1WEEK }, - { N_("2 weeks"), DVR_RET_REM_2WEEK }, - { N_("3 weeks"), DVR_RET_REM_3WEEK }, - { N_("1 month"), DVR_RET_REM_1MONTH }, - { N_("2 months"), DVR_RET_REM_2MONTH }, - { N_("3 months"), DVR_RET_REM_3MONTH }, - { N_("6 months"), DVR_RET_REM_6MONTH }, - { N_("1 year"), DVR_RET_REM_1YEAR }, - { N_("2 years"), DVR_RET_REM_2YEARS }, - { N_("3 years"), DVR_RET_REM_3YEARS }, - { N_("Maintained space"), DVR_REM_SPACE }, - { N_("Forever"), DVR_RET_REM_FOREVER }, + {N_("DVR configuration"), DVR_RET_REM_DVRCONFIG}, + {N_("1 day"), DVR_RET_REM_1DAY}, + {N_("3 days"), DVR_RET_REM_3DAY}, + {N_("5 days"), DVR_RET_REM_5DAY}, + {N_("1 week"), DVR_RET_REM_1WEEK}, + {N_("2 weeks"), DVR_RET_REM_2WEEK}, + {N_("3 weeks"), DVR_RET_REM_3WEEK}, + {N_("1 month"), DVR_RET_REM_1MONTH}, + {N_("2 months"), DVR_RET_REM_2MONTH}, + {N_("3 months"), DVR_RET_REM_3MONTH}, + {N_("6 months"), DVR_RET_REM_6MONTH}, + {N_("1 year"), DVR_RET_REM_1YEAR}, + {N_("2 years"), DVR_RET_REM_2YEARS}, + {N_("3 years"), DVR_RET_REM_3YEARS}, + {N_("Maintained space"), DVR_REM_SPACE}, + {N_("Forever"), DVR_RET_REM_FOREVER}, }; return strtab2htsmsg_u32(tab, 1, lang); } -static int -dvr_entry_class_autorec_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - dvr_autorec_entry_t *dae; +static int dvr_entry_class_autorec_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + dvr_autorec_entry_t* dae; if (!dvr_entry_is_editable(de)) return 0; dae = v ? dvr_autorec_find_by_uuid(v) : NULL; @@ -3579,10 +3521,8 @@ dvr_entry_class_autorec_set(void *o, const void *v) return 0; } -static const void * -dvr_entry_class_autorec_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_autorec_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_autorec) idnode_uuid_as_str(&de->de_autorec->dae_id, prop_sbuf); else @@ -3590,35 +3530,33 @@ dvr_entry_class_autorec_get(void *o) return &prop_sbuf_ptr; } -static const void * -dvr_entry_class_autorec_caption_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - dvr_autorec_entry_t *dae = de->de_autorec; +static const void* dvr_entry_class_autorec_caption_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; + dvr_autorec_entry_t* dae = de->de_autorec; if (dae) { const int comment = !strempty(dae->dae_comment); - snprintf(prop_sbuf, PROP_SBUF_LEN, "%s%s%s%s", - dae->dae_name ?: "", - comment ? " (" : "", - comment ? dae->dae_comment : "", - comment ? ")" : ""); + snprintf(prop_sbuf, + PROP_SBUF_LEN, + "%s%s%s%s", + dae->dae_name ?: "", + comment ? " (" : "", + comment ? dae->dae_comment : "", + comment ? ")" : ""); } else prop_sbuf[0] = '\0'; return &prop_sbuf_ptr; } -static int -dvr_entry_class_timerec_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - dvr_timerec_entry_t *dte; +static int dvr_entry_class_timerec_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + dvr_timerec_entry_t* dte; if (!dvr_entry_is_editable(de)) return 0; dte = v ? dvr_timerec_find_by_uuid(v) : NULL; if (dte == NULL) { if (de->de_timerec) { de->de_timerec->dte_spawn = NULL; - de->de_timerec = NULL; + de->de_timerec = NULL; return 1; } } else if (de->de_timerec != dte) { @@ -3629,10 +3567,8 @@ dvr_entry_class_timerec_set(void *o, const void *v) return 0; } -static const void * -dvr_entry_class_timerec_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_timerec_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_timerec) idnode_uuid_as_str(&de->de_timerec->dte_id, prop_sbuf); else @@ -3640,36 +3576,32 @@ dvr_entry_class_timerec_get(void *o) return &prop_sbuf_ptr; } -static const void * -dvr_entry_class_timerec_caption_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - dvr_timerec_entry_t *dte = de->de_timerec; +static const void* dvr_entry_class_timerec_caption_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; + dvr_timerec_entry_t* dte = de->de_timerec; if (dte) { - snprintf(prop_sbuf, PROP_SBUF_LEN, "%s%s%s%s", - dte->dte_name ?: "", - dte->dte_comment ? " (" : "", - dte->dte_comment, - dte->dte_comment ? ")" : ""); + snprintf(prop_sbuf, + PROP_SBUF_LEN, + "%s%s%s%s", + dte->dte_name ?: "", + dte->dte_comment ? " (" : "", + dte->dte_comment, + dte->dte_comment ? ")" : ""); } else prop_sbuf[0] = '\0'; return &prop_sbuf_ptr; } -static int -dvr_entry_class_parent_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o, *de2; +static int dvr_entry_class_parent_set(void* o, const void* v) { + dvr_entry_t *de = (dvr_entry_t*)o, *de2; if (!dvr_entry_is_editable(de)) return 0; de2 = v ? dvr_entry_find_by_uuid(v) : NULL; return dvr_entry_change_parent_child(de2, de, de, 1); } -static const void * -dvr_entry_class_parent_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_parent_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_parent) idnode_uuid_as_str(&de->de_parent->de_id, prop_sbuf); else @@ -3677,20 +3609,16 @@ dvr_entry_class_parent_get(void *o) return &prop_sbuf_ptr; } -static int -dvr_entry_class_child_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o, *de2; +static int dvr_entry_class_child_set(void* o, const void* v) { + dvr_entry_t *de = (dvr_entry_t*)o, *de2; if (!dvr_entry_is_editable(de)) return 0; de2 = v ? dvr_entry_find_by_uuid(v) : NULL; return dvr_entry_change_parent_child(de, de2, de, 1); } -static const void * -dvr_entry_class_child_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_child_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_child) idnode_uuid_as_str(&de->de_child->de_id, prop_sbuf); else @@ -3698,23 +3626,19 @@ dvr_entry_class_child_get(void *o) return &prop_sbuf_ptr; } -static int -dvr_entry_class_broadcast_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - uint32_t id = *(uint32_t *)v; - epg_broadcast_t *bcast; +static int dvr_entry_class_broadcast_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + uint32_t id = *(uint32_t*)v; + epg_broadcast_t* bcast; if (!dvr_entry_is_editable(de)) return 0; bcast = epg_broadcast_find_by_id(id); return dvr_entry_assign_broadcast(de, bcast); } -static const void * -dvr_entry_class_broadcast_get(void *o) -{ +static const void* dvr_entry_class_broadcast_get(void* o) { static uint32_t id; - dvr_entry_t *de = (dvr_entry_t *)o; + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_bcast) id = de->de_bcast->id; else @@ -3722,13 +3646,11 @@ dvr_entry_class_broadcast_get(void *o) return &id; } -static int -dvr_entry_class_disp_title_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - const char *lang = idnode_lang(&de->de_id); - const char *s = ""; - v = tvh_str_default(v, "UnknownTitle"); +static int dvr_entry_class_disp_title_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + const char* lang = idnode_lang(&de->de_id); + const char* s = ""; + v = tvh_str_default(v, "UnknownTitle"); if (de->de_title) s = lang_str_get(de->de_title, lang); if (strcmp(s, v)) { @@ -3738,10 +3660,8 @@ dvr_entry_class_disp_title_set(void *o, const void *v) return 0; } -static const void * -dvr_entry_class_disp_title_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_disp_title_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_title) prop_ptr = lang_str_get(de->de_title, idnode_lang(o)); else @@ -3751,13 +3671,11 @@ dvr_entry_class_disp_title_get(void *o) return &prop_ptr; } -static int -dvr_entry_class_disp_subtitle_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - const char *lang = idnode_lang(o); - const char *s = ""; - v = tvh_str_default(v, "UnknownSubtitle"); +static int dvr_entry_class_disp_subtitle_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + const char* lang = idnode_lang(o); + const char* s = ""; + v = tvh_str_default(v, "UnknownSubtitle"); if (de->de_subtitle) s = lang_str_get(de->de_subtitle, lang); if (strcmp(s, v)) { @@ -3767,10 +3685,8 @@ dvr_entry_class_disp_subtitle_set(void *o, const void *v) return 0; } -static const void * -dvr_entry_class_disp_subtitle_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_disp_subtitle_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_subtitle) prop_ptr = lang_str_get(de->de_subtitle, idnode_lang(o)); else @@ -3780,13 +3696,11 @@ dvr_entry_class_disp_subtitle_get(void *o) return &prop_ptr; } -static int -dvr_entry_class_disp_summary_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - const char *lang = idnode_lang(o); - const char *s = ""; - v = tvh_str_default(v, "UnknownSummary"); +static int dvr_entry_class_disp_summary_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + const char* lang = idnode_lang(o); + const char* s = ""; + v = tvh_str_default(v, "UnknownSummary"); if (de->de_subtitle) s = lang_str_get(de->de_summary, lang); if (strcmp(s, v)) { @@ -3796,10 +3710,8 @@ dvr_entry_class_disp_summary_set(void *o, const void *v) return 0; } -static const void * -dvr_entry_class_disp_summary_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_disp_summary_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_summary) prop_ptr = lang_str_get(de->de_summary, idnode_lang(o)); else @@ -3809,10 +3721,8 @@ dvr_entry_class_disp_summary_get(void *o) return &prop_ptr; } -static const void * -dvr_entry_class_disp_description_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_disp_description_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; if (de->de_desc) prop_ptr = lang_str_get(de->de_desc, idnode_lang(o)); else @@ -3822,11 +3732,9 @@ dvr_entry_class_disp_description_get(void *o) return &prop_ptr; } -static const void * -dvr_entry_class_disp_extratext_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - prop_ptr = NULL; +static const void* dvr_entry_class_disp_extratext_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; + prop_ptr = NULL; if (de->de_subtitle) prop_ptr = lang_str_get(de->de_subtitle, idnode_lang(o)); if (prop_ptr == NULL) @@ -3838,12 +3746,10 @@ dvr_entry_class_disp_extratext_get(void *o) return &prop_ptr; } -static int -dvr_entry_class_disp_extratext_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - const char *lang = idnode_lang(o); - v = tvh_str_default(v, "?????"); +static int dvr_entry_class_disp_extratext_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; + const char* lang = idnode_lang(o); + v = tvh_str_default(v, "?????"); if (lang_str_get(de->de_subtitle, lang)) return lang_str_set(&de->de_subtitle, v, lang); @@ -3856,13 +3762,11 @@ dvr_entry_class_disp_extratext_set(void *o, const void *v) return lang_str_set(&de->de_subtitle, v, lang); } -static int -dvr_entry_class_disp_episode_set(void *o, const void *v) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static int dvr_entry_class_disp_episode_set(void* o, const void* v) { + dvr_entry_t* de = (dvr_entry_t*)o; epg_episode_num_t epnum; - if (!extract_season_episode(&epnum, (const char *)v)) - epnum.text = (char *)v; + if (!extract_season_episode(&epnum, (const char*)v)) + epnum.text = (char*)v; if (epg_episode_number_cmpfull(&de->de_epnum, &epnum)) { free(de->de_epnum.text); de->de_epnum = epnum; @@ -3873,18 +3777,15 @@ dvr_entry_class_disp_episode_set(void *o, const void *v) return 0; } -static const void * -dvr_entry_class_disp_episode_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - const char *lang; - char buf1[32], buf2[32]; +static const void* dvr_entry_class_disp_episode_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; + const char* lang; + char buf1[32], buf2[32]; if (de->de_epnum.e_num || de->de_epnum.s_num) { lang = idnode_lang(o); snprintf(buf1, sizeof(buf1), "%s %%d", tvh_gettext_lang(lang, N_("Season"))); snprintf(buf2, sizeof(buf2), "%s %%d", tvh_gettext_lang(lang, N_("Episode"))); - epg_episode_num_format(&de->de_epnum, prop_sbuf, PROP_SBUF_LEN, NULL, - buf1, ".", buf2, "/%d"); + epg_episode_num_format(&de->de_epnum, prop_sbuf, PROP_SBUF_LEN, NULL, buf1, ".", buf2, "/%d"); return &prop_sbuf_ptr; } else if (de->de_epnum.text) { prop_ptr = de->de_epnum.text; @@ -3894,25 +3795,19 @@ dvr_entry_class_disp_episode_get(void *o) return &prop_ptr; } -static const void * -dvr_entry_class_url_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - char ubuf[UUID_HEX_SIZE]; +static const void* dvr_entry_class_url_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; + char ubuf[UUID_HEX_SIZE]; prop_sbuf[0] = '\0'; - if (de->de_sched_state == DVR_COMPLETED || - de->de_sched_state == DVR_RECORDING) + if (de->de_sched_state == DVR_COMPLETED || de->de_sched_state == DVR_RECORDING) snprintf(prop_sbuf, PROP_SBUF_LEN, "dvrfile/%s", idnode_uuid_as_str(&de->de_id, ubuf)); return &prop_sbuf_ptr; } -static const void * -dvr_entry_class_filesize_get(void *o) -{ +static const void* dvr_entry_class_filesize_get(void* o) { static int64_t size; - dvr_entry_t *de = (dvr_entry_t *)o; - if (de->de_sched_state == DVR_COMPLETED || - de->de_sched_state == DVR_RECORDING) { + dvr_entry_t* de = (dvr_entry_t*)o; + if (de->de_sched_state == DVR_COMPLETED || de->de_sched_state == DVR_RECORDING) { size = dvr_get_filesize(de, DVR_FILESIZE_UPDATE); if (size < 0) size = 0; @@ -3921,32 +3816,26 @@ dvr_entry_class_filesize_get(void *o) return &size; } -static const void * -dvr_entry_class_start_real_get(void *o) -{ +static const void* dvr_entry_class_start_real_get(void* o) { static time_t tm; - dvr_entry_t *de = (dvr_entry_t *)o; - tm = dvr_entry_get_start_time(de, 1); + dvr_entry_t* de = (dvr_entry_t*)o; + tm = dvr_entry_get_start_time(de, 1); return &tm; } -static const void * -dvr_entry_class_stop_real_get(void *o) -{ +static const void* dvr_entry_class_stop_real_get(void* o) { static time_t tm; - dvr_entry_t *de = (dvr_entry_t *)o; - tm = dvr_entry_get_stop_time(de); + dvr_entry_t* de = (dvr_entry_t*)o; + tm = dvr_entry_get_stop_time(de); return &tm; } -static const void * -dvr_entry_class_duration_get(void *o) -{ +static const void* dvr_entry_class_duration_get(void* o) { static time_t tm; - time_t start, stop; - dvr_entry_t *de = (dvr_entry_t *)o; - start = dvr_entry_get_start_time(de, 0); - stop = dvr_entry_get_stop_time(de); + time_t start, stop; + dvr_entry_t* de = (dvr_entry_t*)o; + start = dvr_entry_get_start_time(de, 0); + stop = dvr_entry_get_stop_time(de); if (stop > start) tm = stop - start; else @@ -3954,27 +3843,21 @@ dvr_entry_class_duration_get(void *o) return &tm; } -static const void * -dvr_entry_class_status_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_status_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; strlcpy(prop_sbuf, dvr_entry_status(de), PROP_SBUF_LEN); return &prop_sbuf_ptr; } -static const void * -dvr_entry_class_sched_status_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; +static const void* dvr_entry_class_sched_status_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; strlcpy(prop_sbuf, dvr_entry_schedstatus(de), PROP_SBUF_LEN); return &prop_sbuf_ptr; } -static const void * -dvr_entry_class_channel_icon_url_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - channel_t *ch = de->de_channel; +static const void* dvr_entry_class_channel_icon_url_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; + channel_t* ch = de->de_channel; if (ch == NULL) { prop_ptr = ""; } else { @@ -3983,9 +3866,7 @@ dvr_entry_class_channel_icon_url_get(void *o) return &prop_ptr; } -const char * -dvr_entry_get_image(const dvr_entry_t *de) -{ +const char* dvr_entry_get_image(const dvr_entry_t* de) { if (de && de->de_bcast && de->de_bcast->image) return de->de_bcast->image; if (de && de->de_image) @@ -3993,109 +3874,84 @@ dvr_entry_get_image(const dvr_entry_t *de) return NULL; } -const char * -dvr_entry_get_fanart_image(const dvr_entry_t *de) -{ +const char* dvr_entry_get_fanart_image(const dvr_entry_t* de) { return de->de_fanart_image; } -static const void * -dvr_entry_class_image_get0(dvr_entry_t *de, const char *image) -{ +static const void* dvr_entry_class_image_get0(dvr_entry_t* de, const char* image) { prop_ptr = imagecache_get_propstr(image, prop_sbuf, PROP_SBUF_LEN); if (prop_ptr == NULL) prop_ptr = ""; return &prop_ptr; } -static const void * -dvr_entry_class_image_get(void *o) -{ +static const void* dvr_entry_class_image_get(void* o) { return dvr_entry_class_image_get0(o, dvr_entry_get_image(o)); } -static void -dvr_entry_class_image_notify(void *o, const char *lang) -{ +static void dvr_entry_class_image_notify(void* o, const char* lang) { (void)imagecache_get_id(dvr_entry_get_image(o)); } -static const void * -dvr_entry_class_fanart_image_get(void *o) -{ +static const void* dvr_entry_class_fanart_image_get(void* o) { return dvr_entry_class_image_get0(o, dvr_entry_get_fanart_image(o)); } -static void -dvr_entry_class_fanart_image_notify(void *o, const char *lang) -{ +static void dvr_entry_class_fanart_image_notify(void* o, const char* lang) { (void)imagecache_get_id(dvr_entry_get_fanart_image(o)); } -static const void * -dvr_entry_class_rating_icon_url_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - ratinglabel_t *rl = de->de_rating_label; +static const void* dvr_entry_class_rating_icon_url_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; + ratinglabel_t* rl = de->de_rating_label; if ((rl == NULL) || (de->de_sched_state > DVR_SCHEDULED)) { - //See if there is a saved icon and if so return the imagecache path for that icon. + // See if there is a saved icon and if so return the imagecache path for that icon. prop_ptr = ""; - if(de->de_rating_icon_saved){ - prop_ptr = de->de_rating_icon_saved; - prop_ptr = imagecache_get_propstr(prop_ptr, prop_sbuf, PROP_SBUF_LEN); + if (de->de_rating_icon_saved) { + prop_ptr = de->de_rating_icon_saved; + prop_ptr = imagecache_get_propstr(prop_ptr, prop_sbuf, PROP_SBUF_LEN); } } else { - //Get the icon from the live RL object. - return ratinglabel_class_get_icon (rl); + // Get the icon from the live RL object. + return ratinglabel_class_get_icon(rl); } return &prop_ptr; } -static const void * -dvr_entry_class_rating_label_get(void *o) -{ - dvr_entry_t *de = (dvr_entry_t *)o; - ratinglabel_t *rl = de->de_rating_label; +static const void* dvr_entry_class_rating_label_get(void* o) { + dvr_entry_t* de = (dvr_entry_t*)o; + ratinglabel_t* rl = de->de_rating_label; if (rl == NULL) { prop_ptr = ""; - if(de->de_rating_label_saved){ - prop_ptr = de->de_rating_label_saved; + if (de->de_rating_label_saved) { + prop_ptr = de->de_rating_label_saved; } } else { - if(de->de_sched_state == DVR_SCHEDULED){ + if (de->de_sched_state == DVR_SCHEDULED) { prop_ptr = rl->rl_display_label; - } - else - { + } else { prop_ptr = de->de_rating_label_saved; } - } return &prop_ptr; } -static const void * -dvr_entry_class_duplicate_get(void *o) -{ +static const void* dvr_entry_class_duplicate_get(void* o) { static time_t null = 0; - dvr_entry_t *de = (dvr_entry_t *)o; - de = _dvr_duplicate_event(de); + dvr_entry_t* de = (dvr_entry_t*)o; + de = _dvr_duplicate_event(de); return de ? &de->de_start : &null; } -static const void * -dvr_entry_class_first_aired_get(void *o) -{ - static time_t null = 0; - const dvr_entry_t *de = (const dvr_entry_t *)o; +static const void* dvr_entry_class_first_aired_get(void* o) { + static time_t null = 0; + const dvr_entry_t* de = (const dvr_entry_t*)o; return de && de->de_bcast ? &de->de_bcast->first_aired : &null; } -static const void * -dvr_entry_class_category_get(void *o) -{ - const dvr_entry_t *de = (dvr_entry_t *)o; - htsmsg_t *l; +static const void* dvr_entry_class_category_get(void* o) { + const dvr_entry_t* de = (dvr_entry_t*)o; + htsmsg_t* l; if (de->de_bcast && de->de_bcast->category) { l = string_list_to_htsmsg(de->de_bcast->category); } else { @@ -4104,11 +3960,9 @@ dvr_entry_class_category_get(void *o) return l; } -static const void * -dvr_entry_class_credits_get(void *o) -{ - const dvr_entry_t *de = (dvr_entry_t *)o; - htsmsg_t *l; +static const void* dvr_entry_class_credits_get(void* o) { + const dvr_entry_t* de = (dvr_entry_t*)o; + htsmsg_t* l; if (de->de_bcast && de->de_bcast->credits) { l = htsmsg_copy(de->de_bcast->credits); } else { @@ -4117,11 +3971,9 @@ dvr_entry_class_credits_get(void *o) return l; } -static const void * -dvr_entry_class_keyword_get(void *o) -{ - const dvr_entry_t *de = (dvr_entry_t *)o; - htsmsg_t *l; +static const void* dvr_entry_class_keyword_get(void* o) { + const dvr_entry_t* de = (dvr_entry_t*)o; + htsmsg_t* l; if (de->de_bcast && de->de_bcast->keyword) { l = string_list_to_htsmsg(de->de_bcast->keyword); } else { @@ -4130,34 +3982,31 @@ dvr_entry_class_keyword_get(void *o) return l; } -static const void * -dvr_entry_class_genre_get(void *o) -{ - const dvr_entry_t *de = (dvr_entry_t *)o; - htsmsg_t *l = htsmsg_create_list(); +static const void* dvr_entry_class_genre_get(void* o) { + const dvr_entry_t* de = (dvr_entry_t*)o; + htsmsg_t* l = htsmsg_create_list(); if (de && de->de_bcast) { - epg_genre_t *eg; - LIST_FOREACH(eg, &de->de_bcast->genre, link) { + epg_genre_t* eg; + LIST_FOREACH (eg, &de->de_bcast->genre, link) { htsmsg_add_u32(l, NULL, eg->code); } } return l; } -htsmsg_t * -dvr_entry_class_duration_list(void *o, const char *not_set, int max, int step, const char *lang) -{ - int i; - htsmsg_t *e, *l = htsmsg_create_list(); - const char *hrs = tvh_gettext_lang(lang, N_("hrs")); - const char *min = tvh_gettext_lang(lang, N_("min")); - const char *mins = tvh_gettext_lang(lang, N_("mins")); - char buf[32]; +htsmsg_t* +dvr_entry_class_duration_list(void* o, const char* not_set, int max, int step, const char* lang) { + int i; + htsmsg_t * e, *l = htsmsg_create_list(); + const char* hrs = tvh_gettext_lang(lang, N_("hrs")); + const char* min = tvh_gettext_lang(lang, N_("min")); + const char* mins = tvh_gettext_lang(lang, N_("mins")); + char buf[32]; e = htsmsg_create_map(); htsmsg_add_u32(e, "key", 0); htsmsg_add_str(e, "val", not_set); htsmsg_add_msg(l, NULL, e); - for (i = 1; i <= 120; i++) { + for (i = 1; i <= 120; i++) { snprintf(buf, sizeof(buf), "%d %s", i, i > 1 ? mins : min); e = htsmsg_create_map(); htsmsg_add_u32(e, "key", i * step); @@ -4177,19 +4026,15 @@ dvr_entry_class_duration_list(void *o, const char *not_set, int max, int step, c return l; } -static htsmsg_t * -dvr_entry_class_extra_list(void *o, const char *lang) -{ - const char *msg = N_("Not set (use channel or DVR configuration)"); - return dvr_entry_class_duration_list(o, tvh_gettext_lang(lang, msg), 4*60, 1, lang); +static htsmsg_t* dvr_entry_class_extra_list(void* o, const char* lang) { + const char* msg = N_("Not set (use channel or DVR configuration)"); + return dvr_entry_class_duration_list(o, tvh_gettext_lang(lang, msg), 4 * 60, 1, lang); } -static htsmsg_t * -dvr_entry_class_content_type_list(void *o, const char *lang) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "epg/content_type/list"); +static htsmsg_t* dvr_entry_class_content_type_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "epg/content_type/list"); return m; } @@ -4198,641 +4043,627 @@ PROP_DOC(dvr_status) PROP_DOC(dvr_start_extra) PROP_DOC(dvr_stop_extra) -const idclass_t dvr_entry_class = { - .ic_class = "dvrentry", - .ic_caption = N_("Digital Video Recorder"), - .ic_event = "dvrentry", - .ic_doc = tvh_doc_dvrentry_class, - .ic_changed = dvr_entry_class_changed, - .ic_save = dvr_entry_class_save, - .ic_get_title = dvr_entry_class_get_title, - .ic_delete = dvr_entry_class_delete, - .ic_perm = dvr_entry_class_perm, - .ic_properties = (const property_t[]) { - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable the entry."), - .off = offsetof(dvr_entry_t, de_enabled), - }, - { - .type = PT_TIME, - .id = "create", - .name = N_("Time the entry was created"), - .desc = N_("The create time of the entry describing the recording."), - .set = dvr_entry_class_create_set, - .off = offsetof(dvr_entry_t, de_create), - .opts = PO_HIDDEN | PO_RDONLY | PO_NOUI, - }, - { - .type = PT_TIME, - .id = "watched", - .name = N_("Time the entry was last watched"), - .desc = N_("Time the entry was last watched."), - .off = offsetof(dvr_entry_t, de_watched), - .opts = PO_RDONLY, - }, - { - .type = PT_TIME, - .id = "start", - .name = N_("Start time"), - .desc = N_("The start time of the recording."), - .set = dvr_entry_class_start_set, - .off = offsetof(dvr_entry_t, de_start), - .get_opts = dvr_entry_class_start_opts, - }, - { - .type = PT_TIME, - .id = "start_extra", - .name = N_("Pre-recording padding"), - .desc = N_("Start recording earlier than the " - "EPG/timer-defined start time by x minutes."), - .doc = prop_doc_dvr_start_extra, - .off = offsetof(dvr_entry_t, de_start_extra), - .set = dvr_entry_class_start_extra_set, - .list = dvr_entry_class_extra_list, - .get_opts = dvr_entry_class_start_extra_opts, - }, - { - .type = PT_TIME, - .id = "start_real", - .name = N_("Scheduled start time"), - .desc = N_("The scheduled start time, including any padding."), - .get = dvr_entry_class_start_real_get, - .opts = PO_RDONLY | PO_NOSAVE, - }, - { - .type = PT_TIME, - .id = "stop", - .name = N_("Stop time"), - .desc = N_("The time the entry stops/stopped being recorded."), - .set = dvr_entry_class_stop_set, - .off = offsetof(dvr_entry_t, de_stop), - }, - { - .type = PT_TIME, - .id = "stop_extra", - .name = N_("Post-recording padding"), - .desc = N_("Continue recording for x minutes after scheduled " - "stop time."), - .doc = prop_doc_dvr_stop_extra, - .off = offsetof(dvr_entry_t, de_stop_extra), - .list = dvr_entry_class_extra_list, - .opts = PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_TIME, - .id = "stop_real", - .name = N_("Scheduled stop time"), - .desc = N_("The scheduled stop time, including any padding."), - .get = dvr_entry_class_stop_real_get, - .opts = PO_RDONLY | PO_NOSAVE, - }, - { - .type = PT_TIME, - .id = "duration", - .name = N_("Scheduled Duration"), - .desc = N_("The total scheduled duration."), - .get = dvr_entry_class_duration_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_DURATION, - }, - { - .type = PT_STR, - .id = "channel", - .name = N_("Channel"), - .desc = N_("The channel name the entry will record from."), - .set = dvr_entry_class_channel_set, - .get = dvr_entry_class_channel_get, - .rend = dvr_entry_class_channel_rend, - .list = channel_class_get_list, - .get_opts = dvr_entry_class_start_opts, - }, - { - .type = PT_STR, - .id = "channel_icon", - .name = N_("Channel icon"), - .desc = N_("Channel icon URL."), - .get = dvr_entry_class_channel_icon_url_get, - .opts = PO_HIDDEN | PO_RDONLY | PO_NOSAVE | PO_NOUI, - }, - { - .type = PT_STR, - .id = "channelname", - .name = N_("Channel name"), - .desc = N_("Name of channel the entry recorded from."), - .get = dvr_entry_class_channel_name_get, - .set = dvr_entry_class_channel_name_set, - .off = offsetof(dvr_entry_t, de_channel_name), - .opts = PO_HIDDEN | PO_RDONLY, - }, - { - .type = PT_STR, - .id = "image", /* Name chosen to be compatible with api_epg */ - .name = N_("Episode image"), - .desc = N_("Episode image."), - .get = dvr_entry_class_image_get, - .notify = dvr_entry_class_image_notify, - .off = offsetof(dvr_entry_t, de_image), - .opts = PO_HIDDEN, - }, - { - .type = PT_STR, - .id = "fanart_image", - .name = N_("Fanart image"), - .desc = N_("Fanart image."), - .get = dvr_entry_class_fanart_image_get, - .notify = dvr_entry_class_fanart_image_notify, - .off = offsetof(dvr_entry_t, de_fanart_image), - .opts = PO_HIDDEN, - }, - { - .type = PT_LANGSTR, - .id = "title", - .name = N_("Title"), - .desc = N_("Title of the program."), - .off = offsetof(dvr_entry_t, de_title), - .opts = PO_RDONLY, - }, - { - .type = PT_STR, - .id = "disp_title", - .name = N_("Title"), - .desc = N_("Title of the program (display only)."), - .get = dvr_entry_class_disp_title_get, - .set = dvr_entry_class_disp_title_set, - .opts = PO_NOSAVE, - }, - { - .type = PT_LANGSTR, - .id = "subtitle", - .name = N_("Subtitle"), - .desc = N_("Subtitle of the program (if any)."), - .off = offsetof(dvr_entry_t, de_subtitle), - .opts = PO_RDONLY, - }, - { - .type = PT_STR, - .id = "disp_subtitle", - .name = N_("Subtitle"), - .desc = N_("Subtitle of the program (if any) (display only)."), - .get = dvr_entry_class_disp_subtitle_get, - .set = dvr_entry_class_disp_subtitle_set, - .opts = PO_NOSAVE, - }, - { - .type = PT_LANGSTR, - .id = "summary", - .name = N_("Summary"), - .desc = N_("Summary of the program (if any)."), - .off = offsetof(dvr_entry_t, de_summary), - .opts = PO_RDONLY, - }, - { - .type = PT_STR, - .id = "disp_summary", - .name = N_("Summary"), - .desc = N_("Summary of the program (if any) (display only)."), - .get = dvr_entry_class_disp_summary_get, - .set = dvr_entry_class_disp_summary_set, - .opts = PO_NOSAVE, - }, - { - .type = PT_LANGSTR, - .id = "description", - .name = N_("Description"), - .desc = N_("Program synopsis."), - .off = offsetof(dvr_entry_t, de_desc), - .opts = PO_RDONLY, - }, - { - .type = PT_STR, - .id = "disp_description", - .name = N_("Description"), - .desc = N_("Program synopsis (display only)."), - .get = dvr_entry_class_disp_description_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN, - }, - { - .type = PT_STR, - .id = "disp_extratext", - .name = N_("Extra text"), - .desc = N_("Subtitle, summary or description of the program (if any)."), - .get = dvr_entry_class_disp_extratext_get, - .set = dvr_entry_class_disp_extratext_set, - .opts = PO_NOSAVE, - }, - { - .type = PT_INT, - .id = "pri", - .name = N_("Priority"), - .desc = N_("Priority of the recording. Higher priority entries " - "will take precedence and cancel lower-priority events. " - "The 'Not Set' value inherits the settings from " - "the assigned DVR configuration."), - .off = offsetof(dvr_entry_t, de_pri), - .def.i = DVR_PRIO_DEFAULT, - .set = dvr_entry_class_pri_set, - .list = dvr_entry_class_pri_list, - .opts = PO_SORTKEY | PO_DOC_NLIST | PO_ADVANCED, - }, - { - .type = PT_U32, - .id = "retention", - .name = N_("DVR log retention"), - .desc = N_("Number of days to retain entry information."), - .off = offsetof(dvr_entry_t, de_retention), - .def.i = DVR_RET_REM_DVRCONFIG, - .list = dvr_entry_class_retention_list, - .opts = PO_HIDDEN | PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "removal", - .name = N_("DVR file retention period"), - .desc = N_("Number of days to keep the file."), - .off = offsetof(dvr_entry_t, de_removal), - .def.i = DVR_RET_REM_DVRCONFIG, - .list = dvr_entry_class_removal_list, - .opts = PO_HIDDEN | PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "playposition", - .name = N_("Last played position"), - .desc = N_("Last played position when the recording isn't fully watched yet."), - .off = offsetof(dvr_entry_t, de_playposition), - .def.i = 0, - .opts = PO_HIDDEN | PO_NOUI | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "playcount", - .name = N_("Recording play count"), - .desc = N_("Number of times this recording was played."), - .off = offsetof(dvr_entry_t, de_playcount), - .def.i = 0, - .opts = PO_HIDDEN | PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "config_name", - .name = N_("DVR configuration"), - .desc = N_("The DVR profile to be used/used by the recording."), - .set = dvr_entry_class_config_name_set, - .get = dvr_entry_class_config_name_get, - .list = dvr_entry_class_config_name_list, - .rend = dvr_entry_class_config_name_rend, - .get_opts = dvr_entry_class_config_name_opts, - }, - { - .type = PT_STR, - .id = "owner", - .name = N_("Owner"), - .desc = N_("Owner of the entry."), - .off = offsetof(dvr_entry_t, de_owner), - .list = user_get_userlist, - .get_opts = dvr_entry_class_owner_opts, - .opts = PO_SORTKEY, - }, - { - .type = PT_STR, - .id = "creator", - .name = N_("Creator"), - .desc = N_("The user who created the recording, or the " - "auto-recording source and IP address if scheduled " - "by a matching rule."), - .off = offsetof(dvr_entry_t, de_creator), - .get_opts = dvr_entry_class_owner_opts, - .opts = PO_SORTKEY, - }, - { - .type = PT_STR, - .id = "filename", - .name = N_("Filename"), - .desc = N_("Filename used by the entry."), - .get = dvr_entry_class_filename_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, - }, - { - .type = PT_STR, - .id = "directory", - .name = N_("Directory"), - .desc = N_("Directory used by the entry."), - .off = offsetof(dvr_entry_t, de_directory), - .opts = PO_RDONLY | PO_NOUI, - }, - { - .type = PT_U32, - .id = "errorcode", - .name = N_("Error code"), - .desc = N_("Error code of entry."), - .off = offsetof(dvr_entry_t, de_last_error), - .opts = PO_RDONLY | PO_NOUI, - }, - { - .type = PT_U32, - .id = "errors", - .name = N_("Errors"), - .desc = N_("Number of errors that occurred during recording."), - .off = offsetof(dvr_entry_t, de_errors), - .opts = PO_RDONLY | PO_ADVANCED, - }, - { - .type = PT_U32, - .id = "data_errors", - .name = N_("Data errors"), - .desc = N_("Number of errors that occurred during recording " - "(Transport errors)."), - .off = offsetof(dvr_entry_t, de_data_errors), - .opts = PO_RDONLY | PO_ADVANCED, - }, - { - .type = PT_U16, - .id = "dvb_eid", - .name = N_("DVB EPG ID"), - .desc = N_("The EPG ID used by the entry."), - .off = offsetof(dvr_entry_t, de_dvb_eid), - .opts = PO_RDONLY | PO_EXPERT, - }, - { - .type = PT_BOOL, - .id = "noresched", - .name = N_("Don't reschedule"), - .desc = N_("Don't re-schedule if recording fails."), - .off = offsetof(dvr_entry_t, de_dont_reschedule), - .opts = PO_HIDDEN | PO_NOUI, - }, - { - .type = PT_BOOL, - .id = "norerecord", - .name = N_("Don't re-record"), - .desc = N_("Don't re-record if recording fails."), - .off = offsetof(dvr_entry_t, de_dont_rerecord), - .opts = PO_HIDDEN | PO_ADVANCED, - }, - { - .type = PT_U32, - .id = "fileremoved", - .name = N_("File removed"), - .desc = N_("The recorded file was removed intentionally"), - .off = offsetof(dvr_entry_t, de_file_removed), - .opts = PO_HIDDEN | PO_NOUI, - }, - { - .type = PT_STR, - .id = "uri", - .name = N_("Program unique ID (from grabber)"), - .desc = N_("Program unique ID (from grabber), such as MV101010101.0000"), - .off = offsetof(dvr_entry_t, de_uri), - .opts = PO_RDONLY | PO_EXPERT - }, - { - .type = PT_STR, - .id = "autorec", - .name = N_("Auto record"), - .desc = N_("Automatically record."), - .set = dvr_entry_class_autorec_set, - .get = dvr_entry_class_autorec_get, - .opts = PO_RDONLY | PO_NOUI, - }, - { - .type = PT_STR, - .id = "autorec_caption", - .name = N_("Auto record caption"), - .desc = N_("Automatic recording caption."), - .get = dvr_entry_class_autorec_caption_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_NOUI, - }, - { - .type = PT_STR, - .id = "timerec", - .name = N_("Auto time record"), - .desc = N_("Timer-based automatic recording."), - .set = dvr_entry_class_timerec_set, - .get = dvr_entry_class_timerec_get, - .opts = PO_RDONLY | PO_EXPERT, - }, - { - .type = PT_STR, - .id = "timerec_caption", - .name = N_("Time record caption"), - .desc = N_("Timer-based automatic record caption."), - .get = dvr_entry_class_timerec_caption_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_NOUI, - }, - { - .type = PT_STR, - .id = "parent", - .name = N_("Parent entry"), - .desc = N_("Parent entry."), - .set = dvr_entry_class_parent_set, - .get = dvr_entry_class_parent_get, - .opts = PO_RDONLY | PO_NOUI, - }, - { - .type = PT_STR, - .id = "child", - .name = N_("Slave entry"), - .desc = N_("Slave entry."), - .set = dvr_entry_class_child_set, - .get = dvr_entry_class_child_get, - .opts = PO_RDONLY | PO_NOUI, - }, - { - .type = PT_U32, - .id = "content_type", - .name = N_("Content type"), - .desc = N_("Content type."), - .list = dvr_entry_class_content_type_list, - .off = offsetof(dvr_entry_t, de_content_type), - .opts = PO_RDONLY | PO_SORTKEY, - }, - { - .type = PT_U16, - .id = "copyright_year", - .name = N_("Copyright year"), - .desc = N_("The copyright year of the program."), - .off = offsetof(dvr_entry_t, de_copyright_year), - .opts = PO_RDONLY | PO_EXPERT, - }, - { - .type = PT_U32, - .id = "broadcast", - .name = N_("Broadcast"), - .desc = N_("Broadcast."), - .set = dvr_entry_class_broadcast_set, - .get = dvr_entry_class_broadcast_get, - /* Has to be available to UI for "show duplicate" from dvr upcoming */ - .opts = PO_RDONLY | PO_HIDDEN, - }, - { - .type = PT_STR, - .id = "episode_disp", - .name = N_("Episode"), - .desc = N_("Episode number/ID."), - .set = dvr_entry_class_disp_episode_set, - .get = dvr_entry_class_disp_episode_get, - .opts = PO_HIDDEN | PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "url", - .name = N_("URL"), - .desc = N_("URL."), - .get = dvr_entry_class_url_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, - }, - { - .type = PT_S64, - .id = "filesize", - .name = N_("File size"), - .desc = N_("Recording file size."), - .get = dvr_entry_class_filesize_get, - .opts = PO_RDONLY | PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "status", - .name = N_("Status"), - .doc = prop_doc_dvr_status, - .desc = N_("The recording/entry status."), - .get = dvr_entry_class_status_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_LOCALE, - }, - { - .type = PT_STR, - .id = "sched_status", - .name = N_("Schedule status"), - .desc = N_("Schedule status."), - .get = dvr_entry_class_sched_status_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_NOUI, - }, - { - .type = PT_TIME, - .id = "duplicate", - .name = N_("Rerun of"), - .desc = N_("Name (or date) of program the entry is a rerun of."), - .get = dvr_entry_class_duplicate_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_ADVANCED, - }, - { - .type = PT_TIME, - .id = "first_aired", - .name = N_("First aired"), - .desc = N_("Time when the program was first aired"), - .get = dvr_entry_class_first_aired_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_ADVANCED, - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-form text field, enter whatever you like here."), - .off = offsetof(dvr_entry_t, de_comment), - }, - { - .type = PT_STR, - .islist = 1, - .id = "category", - .name = N_("Category"), - .desc = N_("Extra categories, typically from xmltv"), - .get = dvr_entry_class_category_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI - }, - { - .type = PT_STR, - .islist = 1, - .id = "credits", - .name = N_("Credits"), - .desc = N_("Credits such as cast members"), - .get = dvr_entry_class_credits_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI - }, - { - .type = PT_STR, - .islist = 1, - .id = "keyword", - .name = N_("Keyword"), - .desc = N_("Extra keywords, typically from xmltv"), - .get = dvr_entry_class_keyword_get, - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI - }, - { - .type = PT_STR, - .islist = 1, - .id = "genre", - .name = N_("Genre"), - .desc = N_("Genre of program"), - .get = dvr_entry_class_genre_get, - .opts = PO_RDONLY | PO_NOSAVE, - }, - { - .type = PT_U16, - .id = "age_rating", - .name = N_("Age Rating"), - .desc = N_("The age rating of the program."), - .off = offsetof(dvr_entry_t, de_age_rating), - .opts = PO_RDONLY | PO_EXPERT, - }, - { - .type = PT_STR, - .id = "rating_label_saved", - .name = N_("Saved Rating Label"), - .desc = N_("Saved parental rating for once recording is complete."), - .off = offsetof(dvr_entry_t, de_rating_label_saved), - .opts = PO_RDONLY | PO_NOUI, - }, - { - .type = PT_STR, - .id = "rating_icon_saved", - .name = N_("Saved Rating Icon Path"), - .desc = N_("Saved parental rating icon for once recording is complete."), - .off = offsetof(dvr_entry_t, de_rating_icon_saved), - .opts = PO_RDONLY | PO_NOUI, - }, - //This needs to go after the 'saved' properties because loading the RL object - //can refresh the 'saved' objects for scheduled entries. - { - .type = PT_STR, - .id = "rating_label_uuid", - .name = N_("Rating Label UUID"), - .desc = N_("Parental rating label UUID."), - .set = dvr_entry_class_rating_set, - .get = dvr_entry_class_rating_get, - .opts = PO_RDONLY | PO_NOUI, - }, - //This needs to go after the RL object is loaded because the - //getter needs the object in order to get the imagecache icon path. - { - .type = PT_STR, - .id = "rating_icon", - .name = N_("Rating Icon"), - .desc = N_("Rating Icon URL."), - .get = dvr_entry_class_rating_icon_url_get, - .opts = PO_HIDDEN | PO_RDONLY | PO_NOSAVE | PO_NOUI, - }, - { - .type = PT_STR, - .id = "rating_label", - .name = N_("Rating Label"), - .desc = N_("Rating Label."), - .get = dvr_entry_class_rating_label_get, - .opts = PO_HIDDEN | PO_RDONLY | PO_NOSAVE, - }, - {} - } -}; +const idclass_t dvr_entry_class = {.ic_class = "dvrentry", + .ic_caption = N_("Digital Video Recorder"), + .ic_event = "dvrentry", + .ic_doc = tvh_doc_dvrentry_class, + .ic_changed = dvr_entry_class_changed, + .ic_save = dvr_entry_class_save, + .ic_get_title = dvr_entry_class_get_title, + .ic_delete = dvr_entry_class_delete, + .ic_perm = dvr_entry_class_perm, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable the entry."), + .off = offsetof(dvr_entry_t, de_enabled), + }, + { + .type = PT_TIME, + .id = "create", + .name = N_("Time the entry was created"), + .desc = N_("The create time of the entry describing the recording."), + .set = dvr_entry_class_create_set, + .off = offsetof(dvr_entry_t, de_create), + .opts = PO_HIDDEN | PO_RDONLY | PO_NOUI, + }, + { + .type = PT_TIME, + .id = "watched", + .name = N_("Time the entry was last watched"), + .desc = N_("Time the entry was last watched."), + .off = offsetof(dvr_entry_t, de_watched), + .opts = PO_RDONLY, + }, + { + .type = PT_TIME, + .id = "start", + .name = N_("Start time"), + .desc = N_("The start time of the recording."), + .set = dvr_entry_class_start_set, + .off = offsetof(dvr_entry_t, de_start), + .get_opts = dvr_entry_class_start_opts, + }, + { + .type = PT_TIME, + .id = "start_extra", + .name = N_("Pre-recording padding"), + .desc = N_("Start recording earlier than the " + "EPG/timer-defined start time by x minutes."), + .doc = prop_doc_dvr_start_extra, + .off = offsetof(dvr_entry_t, de_start_extra), + .set = dvr_entry_class_start_extra_set, + .list = dvr_entry_class_extra_list, + .get_opts = dvr_entry_class_start_extra_opts, + }, + { + .type = PT_TIME, + .id = "start_real", + .name = N_("Scheduled start time"), + .desc = N_("The scheduled start time, including any padding."), + .get = dvr_entry_class_start_real_get, + .opts = PO_RDONLY | PO_NOSAVE, + }, + { + .type = PT_TIME, + .id = "stop", + .name = N_("Stop time"), + .desc = N_("The time the entry stops/stopped being recorded."), + .set = dvr_entry_class_stop_set, + .off = offsetof(dvr_entry_t, de_stop), + }, + { + .type = PT_TIME, + .id = "stop_extra", + .name = N_("Post-recording padding"), + .desc = N_("Continue recording for x minutes after scheduled " + "stop time."), + .doc = prop_doc_dvr_stop_extra, + .off = offsetof(dvr_entry_t, de_stop_extra), + .list = dvr_entry_class_extra_list, + .opts = PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_TIME, + .id = "stop_real", + .name = N_("Scheduled stop time"), + .desc = N_("The scheduled stop time, including any padding."), + .get = dvr_entry_class_stop_real_get, + .opts = PO_RDONLY | PO_NOSAVE, + }, + { + .type = PT_TIME, + .id = "duration", + .name = N_("Scheduled Duration"), + .desc = N_("The total scheduled duration."), + .get = dvr_entry_class_duration_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_DURATION, + }, + { + .type = PT_STR, + .id = "channel", + .name = N_("Channel"), + .desc = N_("The channel name the entry will record from."), + .set = dvr_entry_class_channel_set, + .get = dvr_entry_class_channel_get, + .rend = dvr_entry_class_channel_rend, + .list = channel_class_get_list, + .get_opts = dvr_entry_class_start_opts, + }, + { + .type = PT_STR, + .id = "channel_icon", + .name = N_("Channel icon"), + .desc = N_("Channel icon URL."), + .get = dvr_entry_class_channel_icon_url_get, + .opts = PO_HIDDEN | PO_RDONLY | PO_NOSAVE | PO_NOUI, + }, + { + .type = PT_STR, + .id = "channelname", + .name = N_("Channel name"), + .desc = N_("Name of channel the entry recorded from."), + .get = dvr_entry_class_channel_name_get, + .set = dvr_entry_class_channel_name_set, + .off = offsetof(dvr_entry_t, de_channel_name), + .opts = PO_HIDDEN | PO_RDONLY, + }, + { + .type = PT_STR, + .id = "image", /* Name chosen to be compatible with api_epg */ + .name = N_("Episode image"), + .desc = N_("Episode image."), + .get = dvr_entry_class_image_get, + .notify = dvr_entry_class_image_notify, + .off = offsetof(dvr_entry_t, de_image), + .opts = PO_HIDDEN, + }, + { + .type = PT_STR, + .id = "fanart_image", + .name = N_("Fanart image"), + .desc = N_("Fanart image."), + .get = dvr_entry_class_fanart_image_get, + .notify = dvr_entry_class_fanart_image_notify, + .off = offsetof(dvr_entry_t, de_fanart_image), + .opts = PO_HIDDEN, + }, + { + .type = PT_LANGSTR, + .id = "title", + .name = N_("Title"), + .desc = N_("Title of the program."), + .off = offsetof(dvr_entry_t, de_title), + .opts = PO_RDONLY, + }, + { + .type = PT_STR, + .id = "disp_title", + .name = N_("Title"), + .desc = N_("Title of the program (display only)."), + .get = dvr_entry_class_disp_title_get, + .set = dvr_entry_class_disp_title_set, + .opts = PO_NOSAVE, + }, + { + .type = PT_LANGSTR, + .id = "subtitle", + .name = N_("Subtitle"), + .desc = N_("Subtitle of the program (if any)."), + .off = offsetof(dvr_entry_t, de_subtitle), + .opts = PO_RDONLY, + }, + { + .type = PT_STR, + .id = "disp_subtitle", + .name = N_("Subtitle"), + .desc = N_("Subtitle of the program (if any) (display only)."), + .get = dvr_entry_class_disp_subtitle_get, + .set = dvr_entry_class_disp_subtitle_set, + .opts = PO_NOSAVE, + }, + { + .type = PT_LANGSTR, + .id = "summary", + .name = N_("Summary"), + .desc = N_("Summary of the program (if any)."), + .off = offsetof(dvr_entry_t, de_summary), + .opts = PO_RDONLY, + }, + { + .type = PT_STR, + .id = "disp_summary", + .name = N_("Summary"), + .desc = N_("Summary of the program (if any) (display only)."), + .get = dvr_entry_class_disp_summary_get, + .set = dvr_entry_class_disp_summary_set, + .opts = PO_NOSAVE, + }, + { + .type = PT_LANGSTR, + .id = "description", + .name = N_("Description"), + .desc = N_("Program synopsis."), + .off = offsetof(dvr_entry_t, de_desc), + .opts = PO_RDONLY, + }, + { + .type = PT_STR, + .id = "disp_description", + .name = N_("Description"), + .desc = N_("Program synopsis (display only)."), + .get = dvr_entry_class_disp_description_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN, + }, + { + .type = PT_STR, + .id = "disp_extratext", + .name = N_("Extra text"), + .desc = N_("Subtitle, summary or description of the program (if any)."), + .get = dvr_entry_class_disp_extratext_get, + .set = dvr_entry_class_disp_extratext_set, + .opts = PO_NOSAVE, + }, + { + .type = PT_INT, + .id = "pri", + .name = N_("Priority"), + .desc = N_("Priority of the recording. Higher priority entries " + "will take precedence and cancel lower-priority events. " + "The 'Not Set' value inherits the settings from " + "the assigned DVR configuration."), + .off = offsetof(dvr_entry_t, de_pri), + .def.i = DVR_PRIO_DEFAULT, + .set = dvr_entry_class_pri_set, + .list = dvr_entry_class_pri_list, + .opts = PO_SORTKEY | PO_DOC_NLIST | PO_ADVANCED, + }, + { + .type = PT_U32, + .id = "retention", + .name = N_("DVR log retention"), + .desc = N_("Number of days to retain entry information."), + .off = offsetof(dvr_entry_t, de_retention), + .def.i = DVR_RET_REM_DVRCONFIG, + .list = dvr_entry_class_retention_list, + .opts = PO_HIDDEN | PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "removal", + .name = N_("DVR file retention period"), + .desc = N_("Number of days to keep the file."), + .off = offsetof(dvr_entry_t, de_removal), + .def.i = DVR_RET_REM_DVRCONFIG, + .list = dvr_entry_class_removal_list, + .opts = PO_HIDDEN | PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "playposition", + .name = N_("Last played position"), + .desc = N_("Last played position when the recording isn't fully watched yet."), + .off = offsetof(dvr_entry_t, de_playposition), + .def.i = 0, + .opts = PO_HIDDEN | PO_NOUI | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "playcount", + .name = N_("Recording play count"), + .desc = N_("Number of times this recording was played."), + .off = offsetof(dvr_entry_t, de_playcount), + .def.i = 0, + .opts = PO_HIDDEN | PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "config_name", + .name = N_("DVR configuration"), + .desc = N_("The DVR profile to be used/used by the recording."), + .set = dvr_entry_class_config_name_set, + .get = dvr_entry_class_config_name_get, + .list = dvr_entry_class_config_name_list, + .rend = dvr_entry_class_config_name_rend, + .get_opts = dvr_entry_class_config_name_opts, + }, + { + .type = PT_STR, + .id = "owner", + .name = N_("Owner"), + .desc = N_("Owner of the entry."), + .off = offsetof(dvr_entry_t, de_owner), + .list = user_get_userlist, + .get_opts = dvr_entry_class_owner_opts, + .opts = PO_SORTKEY, + }, + { + .type = PT_STR, + .id = "creator", + .name = N_("Creator"), + .desc = N_("The user who created the recording, or the " + "auto-recording source and IP address if scheduled " + "by a matching rule."), + .off = offsetof(dvr_entry_t, de_creator), + .get_opts = dvr_entry_class_owner_opts, + .opts = PO_SORTKEY, + }, + { + .type = PT_STR, + .id = "filename", + .name = N_("Filename"), + .desc = N_("Filename used by the entry."), + .get = dvr_entry_class_filename_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, + }, + { + .type = PT_STR, + .id = "directory", + .name = N_("Directory"), + .desc = N_("Directory used by the entry."), + .off = offsetof(dvr_entry_t, de_directory), + .opts = PO_RDONLY | PO_NOUI, + }, + { + .type = PT_U32, + .id = "errorcode", + .name = N_("Error code"), + .desc = N_("Error code of entry."), + .off = offsetof(dvr_entry_t, de_last_error), + .opts = PO_RDONLY | PO_NOUI, + }, + { + .type = PT_U32, + .id = "errors", + .name = N_("Errors"), + .desc = N_("Number of errors that occurred during recording."), + .off = offsetof(dvr_entry_t, de_errors), + .opts = PO_RDONLY | PO_ADVANCED, + }, + { + .type = PT_U32, + .id = "data_errors", + .name = N_("Data errors"), + .desc = N_("Number of errors that occurred during recording " + "(Transport errors)."), + .off = offsetof(dvr_entry_t, de_data_errors), + .opts = PO_RDONLY | PO_ADVANCED, + }, + { + .type = PT_U16, + .id = "dvb_eid", + .name = N_("DVB EPG ID"), + .desc = N_("The EPG ID used by the entry."), + .off = offsetof(dvr_entry_t, de_dvb_eid), + .opts = PO_RDONLY | PO_EXPERT, + }, + { + .type = PT_BOOL, + .id = "noresched", + .name = N_("Don't reschedule"), + .desc = N_("Don't re-schedule if recording fails."), + .off = offsetof(dvr_entry_t, de_dont_reschedule), + .opts = PO_HIDDEN | PO_NOUI, + }, + { + .type = PT_BOOL, + .id = "norerecord", + .name = N_("Don't re-record"), + .desc = N_("Don't re-record if recording fails."), + .off = offsetof(dvr_entry_t, de_dont_rerecord), + .opts = PO_HIDDEN | PO_ADVANCED, + }, + { + .type = PT_U32, + .id = "fileremoved", + .name = N_("File removed"), + .desc = N_("The recorded file was removed intentionally"), + .off = offsetof(dvr_entry_t, de_file_removed), + .opts = PO_HIDDEN | PO_NOUI, + }, + {.type = PT_STR, + .id = "uri", + .name = N_("Program unique ID (from grabber)"), + .desc = N_("Program unique ID (from grabber), such as MV101010101.0000"), + .off = offsetof(dvr_entry_t, de_uri), + .opts = PO_RDONLY | PO_EXPERT}, + { + .type = PT_STR, + .id = "autorec", + .name = N_("Auto record"), + .desc = N_("Automatically record."), + .set = dvr_entry_class_autorec_set, + .get = dvr_entry_class_autorec_get, + .opts = PO_RDONLY | PO_NOUI, + }, + { + .type = PT_STR, + .id = "autorec_caption", + .name = N_("Auto record caption"), + .desc = N_("Automatic recording caption."), + .get = dvr_entry_class_autorec_caption_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_NOUI, + }, + { + .type = PT_STR, + .id = "timerec", + .name = N_("Auto time record"), + .desc = N_("Timer-based automatic recording."), + .set = dvr_entry_class_timerec_set, + .get = dvr_entry_class_timerec_get, + .opts = PO_RDONLY | PO_EXPERT, + }, + { + .type = PT_STR, + .id = "timerec_caption", + .name = N_("Time record caption"), + .desc = N_("Timer-based automatic record caption."), + .get = dvr_entry_class_timerec_caption_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_NOUI, + }, + { + .type = PT_STR, + .id = "parent", + .name = N_("Parent entry"), + .desc = N_("Parent entry."), + .set = dvr_entry_class_parent_set, + .get = dvr_entry_class_parent_get, + .opts = PO_RDONLY | PO_NOUI, + }, + { + .type = PT_STR, + .id = "child", + .name = N_("Slave entry"), + .desc = N_("Slave entry."), + .set = dvr_entry_class_child_set, + .get = dvr_entry_class_child_get, + .opts = PO_RDONLY | PO_NOUI, + }, + { + .type = PT_U32, + .id = "content_type", + .name = N_("Content type"), + .desc = N_("Content type."), + .list = dvr_entry_class_content_type_list, + .off = offsetof(dvr_entry_t, de_content_type), + .opts = PO_RDONLY | PO_SORTKEY, + }, + { + .type = PT_U16, + .id = "copyright_year", + .name = N_("Copyright year"), + .desc = N_("The copyright year of the program."), + .off = offsetof(dvr_entry_t, de_copyright_year), + .opts = PO_RDONLY | PO_EXPERT, + }, + { + .type = PT_U32, + .id = "broadcast", + .name = N_("Broadcast"), + .desc = N_("Broadcast."), + .set = dvr_entry_class_broadcast_set, + .get = dvr_entry_class_broadcast_get, + /* Has to be available to UI for "show duplicate" from dvr upcoming */ + .opts = PO_RDONLY | PO_HIDDEN, + }, + { + .type = PT_STR, + .id = "episode_disp", + .name = N_("Episode"), + .desc = N_("Episode number/ID."), + .set = dvr_entry_class_disp_episode_set, + .get = dvr_entry_class_disp_episode_get, + .opts = PO_HIDDEN | PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "url", + .name = N_("URL"), + .desc = N_("URL."), + .get = dvr_entry_class_url_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, + }, + { + .type = PT_S64, + .id = "filesize", + .name = N_("File size"), + .desc = N_("Recording file size."), + .get = dvr_entry_class_filesize_get, + .opts = PO_RDONLY | PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "status", + .name = N_("Status"), + .doc = prop_doc_dvr_status, + .desc = N_("The recording/entry status."), + .get = dvr_entry_class_status_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_LOCALE, + }, + { + .type = PT_STR, + .id = "sched_status", + .name = N_("Schedule status"), + .desc = N_("Schedule status."), + .get = dvr_entry_class_sched_status_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_NOUI, + }, + { + .type = PT_TIME, + .id = "duplicate", + .name = N_("Rerun of"), + .desc = N_("Name (or date) of program the entry is a rerun of."), + .get = dvr_entry_class_duplicate_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_ADVANCED, + }, + { + .type = PT_TIME, + .id = "first_aired", + .name = N_("First aired"), + .desc = N_("Time when the program was first aired"), + .get = dvr_entry_class_first_aired_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_ADVANCED, + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-form text field, enter whatever you like here."), + .off = offsetof(dvr_entry_t, de_comment), + }, + {.type = PT_STR, + .islist = 1, + .id = "category", + .name = N_("Category"), + .desc = N_("Extra categories, typically from xmltv"), + .get = dvr_entry_class_category_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI}, + {.type = PT_STR, + .islist = 1, + .id = "credits", + .name = N_("Credits"), + .desc = N_("Credits such as cast members"), + .get = dvr_entry_class_credits_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI}, + {.type = PT_STR, + .islist = 1, + .id = "keyword", + .name = N_("Keyword"), + .desc = N_("Extra keywords, typically from xmltv"), + .get = dvr_entry_class_keyword_get, + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI}, + { + .type = PT_STR, + .islist = 1, + .id = "genre", + .name = N_("Genre"), + .desc = N_("Genre of program"), + .get = dvr_entry_class_genre_get, + .opts = PO_RDONLY | PO_NOSAVE, + }, + { + .type = PT_U16, + .id = "age_rating", + .name = N_("Age Rating"), + .desc = N_("The age rating of the program."), + .off = offsetof(dvr_entry_t, de_age_rating), + .opts = PO_RDONLY | PO_EXPERT, + }, + { + .type = PT_STR, + .id = "rating_label_saved", + .name = N_("Saved Rating Label"), + .desc = N_("Saved parental rating for once recording is complete."), + .off = offsetof(dvr_entry_t, de_rating_label_saved), + .opts = PO_RDONLY | PO_NOUI, + }, + { + .type = PT_STR, + .id = "rating_icon_saved", + .name = N_("Saved Rating Icon Path"), + .desc = N_("Saved parental rating icon for once recording is complete."), + .off = offsetof(dvr_entry_t, de_rating_icon_saved), + .opts = PO_RDONLY | PO_NOUI, + }, + // This needs to go after the 'saved' properties because loading the RL object + // can refresh the 'saved' objects for scheduled entries. + { + .type = PT_STR, + .id = "rating_label_uuid", + .name = N_("Rating Label UUID"), + .desc = N_("Parental rating label UUID."), + .set = dvr_entry_class_rating_set, + .get = dvr_entry_class_rating_get, + .opts = PO_RDONLY | PO_NOUI, + }, + // This needs to go after the RL object is loaded because the + // getter needs the object in order to get the imagecache icon path. + { + .type = PT_STR, + .id = "rating_icon", + .name = N_("Rating Icon"), + .desc = N_("Rating Icon URL."), + .get = dvr_entry_class_rating_icon_url_get, + .opts = PO_HIDDEN | PO_RDONLY | PO_NOSAVE | PO_NOUI, + }, + { + .type = PT_STR, + .id = "rating_label", + .name = N_("Rating Label"), + .desc = N_("Rating Label."), + .get = dvr_entry_class_rating_label_get, + .opts = PO_HIDDEN | PO_RDONLY | PO_NOSAVE, + }, + {}}}; /** * */ -void -dvr_destroy_by_channel(channel_t *ch, int delconf) -{ - dvr_entry_t *de; +void dvr_destroy_by_channel(channel_t* ch, int delconf) { + dvr_entry_t* de; - while((de = LIST_FIRST(&ch->ch_dvrs)) != NULL) { + while ((de = LIST_FIRST(&ch->ch_dvrs)) != NULL) { LIST_REMOVE(de, de_channel_link); de->de_channel = NULL; free(de->de_channel_name); @@ -4844,14 +4675,11 @@ dvr_destroy_by_channel(channel_t *ch, int delconf) /** * */ -const char * -dvr_get_filename(dvr_entry_t *de) -{ - htsmsg_field_t *f; - htsmsg_t *m; - const char *s; - if ((f = htsmsg_field_last(de->de_files)) != NULL && - (m = htsmsg_field_get_map(f)) != NULL && +const char* dvr_get_filename(dvr_entry_t* de) { + htsmsg_field_t* f; + htsmsg_t* m; + const char* s; + if ((f = htsmsg_field_last(de->de_files)) != NULL && (m = htsmsg_field_get_map(f)) != NULL && (s = htsmsg_get_str(m, "filename")) != NULL) return s; else @@ -4861,30 +4689,28 @@ dvr_get_filename(dvr_entry_t *de) /** * */ -int64_t -dvr_get_filesize(dvr_entry_t *de, int flags) -{ - htsmsg_field_t *f; - htsmsg_t *m; - const char *filename; - int first = 1; - int64_t res = 0, size; +int64_t dvr_get_filesize(dvr_entry_t* de, int flags) { + htsmsg_field_t* f; + htsmsg_t* m; + const char* filename; + int first = 1; + int64_t res = 0, size; if (de->de_files == NULL) return -1; HTSMSG_FOREACH(f, de->de_files) - if ((m = htsmsg_field_get_map(f)) != NULL) { - filename = htsmsg_get_str(m, "filename"); - if (flags & DVR_FILESIZE_UPDATE) - size = dvr_vfs_update_filename(filename, m); - else - size = htsmsg_get_s64_or_default(m, "size", -1); - if (filename && size >= 0) { - res = (flags & DVR_FILESIZE_TOTAL) ? (res + size) : size; - first = 0; - } + if ((m = htsmsg_field_get_map(f)) != NULL) { + filename = htsmsg_get_str(m, "filename"); + if (flags & DVR_FILESIZE_UPDATE) + size = dvr_vfs_update_filename(filename, m); + else + size = htsmsg_get_s64_or_default(m, "size", -1); + if (filename && size >= 0) { + res = (flags & DVR_FILESIZE_TOTAL) ? (res + size) : size; + first = 0; } + } return first ? -1 : res; } @@ -4892,18 +4718,16 @@ dvr_get_filesize(dvr_entry_t *de, int flags) /** * */ -int -dvr_entry_delete(dvr_entry_t *de) -{ - dvr_config_t *cfg = de->de_config; - htsmsg_t *m; - htsmsg_field_t *f; - time_t t; - struct tm tm; - const char *filename; - char *str1, *str2; - char tbuf[64], ubuf[UUID_HEX_SIZE], *rdir, *cmd; - int r, ret = 0; +int dvr_entry_delete(dvr_entry_t* de) { + dvr_config_t* cfg = de->de_config; + htsmsg_t* m; + htsmsg_field_t* f; + time_t t; + struct tm tm; + const char* filename; + char * str1, *str2; + char tbuf[64], ubuf[UUID_HEX_SIZE], *rdir, *cmd; + int r, ret = 0; t = dvr_entry_get_start_time(de, 1); localtime_r(&t, &tm); @@ -4912,32 +4736,38 @@ dvr_entry_delete(dvr_entry_t *de) str1 = dvr_entry_get_retention_string(de); str2 = dvr_entry_get_removal_string(de); - tvhinfo(LS_DVR, "delete entry %s \"%s\" on \"%s\" start time %s, " - "scheduled for recording by \"%s\", retention \"%s\" removal \"%s\"", - idnode_uuid_as_str(&de->de_id, ubuf), - lang_str_get(de->de_title, NULL), DVR_CH_NAME(de), tbuf, - de->de_creator ?: "", str1, str2); + tvhinfo(LS_DVR, + "delete entry %s \"%s\" on \"%s\" start time %s, " + "scheduled for recording by \"%s\", retention \"%s\" removal \"%s\"", + idnode_uuid_as_str(&de->de_id, ubuf), + lang_str_get(de->de_title, NULL), + DVR_CH_NAME(de), + tbuf, + de->de_creator ?: "", + str1, + str2); free(str2); free(str1); - if(!htsmsg_is_empty(de->de_files)) { + if (!htsmsg_is_empty(de->de_files)) { #if ENABLE_INOTIFY dvr_inotify_del(de); #endif rdir = NULL; - if(cfg->dvr_title_dir || cfg->dvr_channel_dir || cfg->dvr_dir_per_day || de->de_directory) + if (cfg->dvr_title_dir || cfg->dvr_channel_dir || cfg->dvr_dir_per_day || de->de_directory) rdir = cfg->dvr_storage; dvr_vfs_remove_entry(de); HTSMSG_FOREACH(f, de->de_files) { m = htsmsg_field_get_map(f); - if (m == NULL) continue; + if (m == NULL) + continue; filename = htsmsg_get_str(m, "filename"); - if (filename == NULL) continue; + if (filename == NULL) + continue; r = deferred_unlink(filename, rdir); - if(r && r != -ENOENT) - tvhwarn(LS_DVR, "Unable to remove file '%s' from disk -- %s", - filename, strerror(errno)); + if (r && r != -ENOENT) + tvhwarn(LS_DVR, "Unable to remove file '%s' from disk -- %s", filename, strerror(errno)); cmd = de->de_config->dvr_postremove; if (cmd && cmd[0]) @@ -4954,11 +4784,10 @@ dvr_entry_delete(dvr_entry_t *de) /** * */ -void -dvr_entry_set_rerecord(dvr_entry_t *de, int cmd) -{ +void dvr_entry_set_rerecord(dvr_entry_t* de, int cmd) { if (cmd < 0) { /* toggle */ - if (de->de_parent) return; + if (de->de_parent) + return; cmd = de->de_dont_rerecord ? 1 : 0; } if (cmd == 0 && !de->de_dont_rerecord) { @@ -4974,22 +4803,17 @@ dvr_entry_set_rerecord(dvr_entry_t *de, int cmd) /** * */ -void -dvr_entry_move(dvr_entry_t *de, int to_failed) -{ - if(de->de_sched_state == DVR_COMPLETED) - if (dvr_entry_completed(de, to_failed ? SM_CODE_USER_REQUEST : - SM_CODE_FORCE_OK)) +void dvr_entry_move(dvr_entry_t* de, int to_failed) { + if (de->de_sched_state == DVR_COMPLETED) + if (dvr_entry_completed(de, to_failed ? SM_CODE_USER_REQUEST : SM_CODE_FORCE_OK)) idnode_changed(&de->de_id); } /** * */ -dvr_entry_t * -dvr_entry_stop(dvr_entry_t *de) -{ - if(de->de_sched_state == DVR_RECORDING) { +dvr_entry_t* dvr_entry_stop(dvr_entry_t* de) { + if (de->de_sched_state == DVR_RECORDING) { dvr_stop_recording(de, SM_CODE_OK, 1, 0); return de; } @@ -5000,27 +4824,25 @@ dvr_entry_stop(dvr_entry_t *de) /** * Cancels an upcoming or active recording */ -dvr_entry_t * -dvr_entry_cancel(dvr_entry_t *de, int rerecord) -{ - dvr_entry_t *parent = de->de_parent; - - switch(de->de_sched_state) { - case DVR_RECORDING: - dvr_stop_recording(de, SM_CODE_ABORTED, 1, 0); - break; - /* Cancel is not valid for finished recordings */ - case DVR_COMPLETED: - case DVR_MISSED_TIME: - return de; - case DVR_SCHEDULED: - case DVR_NOSTATE: - dvr_entry_destroy(de, 1); - de = NULL; - break; +dvr_entry_t* dvr_entry_cancel(dvr_entry_t* de, int rerecord) { + dvr_entry_t* parent = de->de_parent; + + switch (de->de_sched_state) { + case DVR_RECORDING: + dvr_stop_recording(de, SM_CODE_ABORTED, 1, 0); + break; + /* Cancel is not valid for finished recordings */ + case DVR_COMPLETED: + case DVR_MISSED_TIME: + return de; + case DVR_SCHEDULED: + case DVR_NOSTATE: + dvr_entry_destroy(de, 1); + de = NULL; + break; - default: - abort(); + default: + abort(); } if (parent) { @@ -5036,9 +4858,7 @@ dvr_entry_cancel(dvr_entry_t *de, int rerecord) /* * Toggle/set/unset previously recorded state */ -void -dvr_entry_set_prevrec(dvr_entry_t *de, int cmd) -{ +void dvr_entry_set_prevrec(dvr_entry_t* de, int cmd) { if (de->de_sched_state == DVR_RECORDING) return; @@ -5050,13 +4870,13 @@ dvr_entry_set_prevrec(dvr_entry_t *de, int cmd) if (cmd) { de->de_dont_reschedule = 1; - de->de_dont_rerecord = 1; - de->de_file_removed = 1; + de->de_dont_rerecord = 1; + de->de_file_removed = 1; dvr_entry_completed(de, SM_CODE_PREVIOUSLY_RECORDED); } else { de->de_dont_reschedule = 0; - de->de_dont_rerecord = 0; - de->de_file_removed = 0; + de->de_dont_rerecord = 0; + de->de_file_removed = 0; dvr_entry_set_timer(de); } @@ -5064,10 +4884,12 @@ dvr_entry_set_prevrec(dvr_entry_t *de, int cmd) dvr_entry_changed(de); - tvhinfo(LS_DVR, "\"%s\" on \"%s\": " - "%sset as previously recorded", - lang_str_get(de->de_title, NULL), DVR_CH_NAME(de), - cmd ? "" : "un"); + tvhinfo(LS_DVR, + "\"%s\" on \"%s\": " + "%sset as previously recorded", + lang_str_get(de->de_title, NULL), + DVR_CH_NAME(de), + cmd ? "" : "un"); } /** @@ -5075,33 +4897,33 @@ dvr_entry_set_prevrec(dvr_entry_t *de, int cmd) * delete = 0 -> remove finished and active recordings (visible as removed) * delete = 1 -> delete finished and active recordings (not visible anymore) */ -static void -dvr_entry_cancel_delete_remove(dvr_entry_t *de, int rerecord, int _delete) -{ - dvr_entry_t *parent = de->de_parent; - dvr_autorec_entry_t *dae = de->de_autorec; - int save; - - switch(de->de_sched_state) { - case DVR_RECORDING: - dvr_stop_recording(de, SM_CODE_ABORTED, 1, 0); - case DVR_MISSED_TIME: - case DVR_COMPLETED: - save = dvr_entry_delete(de); /* Remove files */ - if (_delete || dvr_entry_delete_retention_expired(de)) /* In case retention was postponed (retention < removal) */ - dvr_entry_destroy(de, 1); /* Delete database */ - else if (save) { - dvr_entry_changed(de); - dvr_entry_retention_timer(de); /* As retention timer depends on file removal */ - } - break; - case DVR_SCHEDULED: - case DVR_NOSTATE: - dvr_entry_destroy(de, 1); - break; +static void dvr_entry_cancel_delete_remove(dvr_entry_t* de, int rerecord, int _delete) { + dvr_entry_t* parent = de->de_parent; + dvr_autorec_entry_t* dae = de->de_autorec; + int save; + + switch (de->de_sched_state) { + case DVR_RECORDING: + dvr_stop_recording(de, SM_CODE_ABORTED, 1, 0); + case DVR_MISSED_TIME: + case DVR_COMPLETED: + save = dvr_entry_delete(de); /* Remove files */ + if (_delete || + dvr_entry_delete_retention_expired( + de)) /* In case retention was postponed (retention < removal) */ + dvr_entry_destroy(de, 1); /* Delete database */ + else if (save) { + dvr_entry_changed(de); + dvr_entry_retention_timer(de); /* As retention timer depends on file removal */ + } + break; + case DVR_SCHEDULED: + case DVR_NOSTATE: + dvr_entry_destroy(de, 1); + break; - default: - abort(); + default: + abort(); } if (parent) { @@ -5122,9 +4944,7 @@ dvr_entry_cancel_delete_remove(dvr_entry_t *de, int rerecord, int _delete) * Finished recordings -> remove * The latter 2 will be visible as "removed recording" */ -void -dvr_entry_cancel_remove(dvr_entry_t *de, int rerecord) -{ +void dvr_entry_cancel_remove(dvr_entry_t* de, int rerecord) { dvr_entry_cancel_delete_remove(de, rerecord, 0); } @@ -5134,40 +4954,37 @@ dvr_entry_cancel_remove(dvr_entry_t *de, int rerecord) * Finished recordings -> delete * The latter 2 will NOT be visible as "removed recording" */ -void -dvr_entry_cancel_delete(dvr_entry_t *de, int rerecord) -{ +void dvr_entry_cancel_delete(dvr_entry_t* de, int rerecord) { dvr_entry_cancel_delete_remove(de, rerecord, 1); } /** * */ -int -dvr_entry_file_moved(const char *src, const char *dst) -{ - dvr_entry_t *de; - htsmsg_t *m; - htsmsg_field_t *f; - const char *filename; - int r = -1, chg; +int dvr_entry_file_moved(const char* src, const char* dst) { + dvr_entry_t* de; + htsmsg_t* m; + htsmsg_field_t* f; + const char* filename; + int r = -1, chg; if (!src || !dst || src[0] == '\0' || dst[0] == '\0' || access(dst, R_OK)) return r; tvh_mutex_lock(&global_lock); - LIST_FOREACH(de, &dvrentries, de_global_link) { - if (htsmsg_is_empty(de->de_files)) continue; + LIST_FOREACH (de, &dvrentries, de_global_link) { + if (htsmsg_is_empty(de->de_files)) + continue; chg = 0; HTSMSG_FOREACH(f, de->de_files) - if ((m = htsmsg_field_get_map(f)) != NULL) { - filename = htsmsg_get_str(m, "filename"); - if (filename && strcmp(filename, src) == 0) { - htsmsg_set_str(m, "filename", dst); - dvr_vfs_refresh_entry(de); - r = 0; - chg++; - } + if ((m = htsmsg_field_get_map(f)) != NULL) { + filename = htsmsg_get_str(m, "filename"); + if (filename && strcmp(filename, src) == 0) { + htsmsg_set_str(m, "filename", dst); + dvr_vfs_refresh_entry(de); + r = 0; + chg++; } + } if (chg) idnode_changed(&de->de_id); } @@ -5178,25 +4995,23 @@ dvr_entry_file_moved(const char *src, const char *dst) /** * */ -void -dvr_entry_init(void) -{ - htsmsg_t *l, *c, *rere; - htsmsg_field_t *f; - const char *parent, *child; - dvr_entry_t *de1, *de2; - - dvr_in_init = 1; +void dvr_entry_init(void) { + htsmsg_t * l, *c, *rere; + htsmsg_field_t* f; + const char * parent, *child; + dvr_entry_t * de1, *de2; + + dvr_in_init = 1; dvr_fanart_to_prefetch = string_list_create(); idclass_register(&dvr_entry_class); rere = htsmsg_create_map(); /* load config, but remove parent/child fields */ - if((l = hts_settings_load("dvr/log")) != NULL) { + if ((l = hts_settings_load("dvr/log")) != NULL) { HTSMSG_FOREACH(f, l) { - if((c = htsmsg_get_map_by_field(f)) == NULL) - continue; + if ((c = htsmsg_get_map_by_field(f)) == NULL) + continue; parent = htsmsg_get_str(c, "parent"); - child = htsmsg_get_str(c, "child"); + child = htsmsg_get_str(c, "child"); if (parent && parent[0]) htsmsg_set_str(rere, parent, htsmsg_field_name(f)); if (child && child[0]) @@ -5210,11 +5025,11 @@ dvr_entry_init(void) dvr_in_init = 0; /* process parent/child mapping */ HTSMSG_FOREACH(f, rere) { - if((child = htsmsg_field_get_str(f)) == NULL) + if ((child = htsmsg_field_get_str(f)) == NULL) continue; parent = htsmsg_field_name(f); - de1 = dvr_entry_find_by_uuid(parent); - de2 = dvr_entry_find_by_uuid(child); + de1 = dvr_entry_find_by_uuid(parent); + de2 = dvr_entry_find_by_uuid(child); dvr_entry_change_parent_child(de1, de2, NULL, 0); } htsmsg_destroy(rere); @@ -5229,10 +5044,8 @@ dvr_entry_init(void) mtimer_arm_rel(&dvr_fanart_timer, dvr_entry_fanart_prefetch_cb, NULL, sec2mono(3600)); } -void -dvr_entry_done(void) -{ - dvr_entry_t *de; +void dvr_entry_done(void) { + dvr_entry_t* de; lock_assert(&global_lock); while ((de = LIST_FIRST(&dvrentries)) != NULL) { if (de->de_sched_state == DVR_RECORDING) diff --git a/src/dvr/dvr_inotify.c b/src/dvr/dvr_inotify.c index 77ae87caf..6748c6ff2 100644 --- a/src/dvr/dvr_inotify.c +++ b/src/dvr/dvr_inotify.c @@ -28,43 +28,37 @@ /* inotify limits */ #define EVENT_SIZE (sizeof(struct inotify_event)) #define EVENT_BUF_LEN (5 * EVENT_SIZE + NAME_MAX) -#define EVENT_MASK IN_DELETE | IN_DELETE_SELF | \ - IN_MOVE_SELF | IN_MOVED_FROM | IN_MOVED_TO - -static int _inot_fd; -static RB_HEAD(,dvr_inotify_entry) _inot_tree; - -typedef struct dvr_inotify_filename -{ - dvr_entry_t *de; +#define EVENT_MASK IN_DELETE | IN_DELETE_SELF | IN_MOVE_SELF | IN_MOVED_FROM | IN_MOVED_TO + +static int _inot_fd; +static RB_HEAD(, dvr_inotify_entry) _inot_tree; + +typedef struct dvr_inotify_filename { + dvr_entry_t* de; LIST_ENTRY(dvr_inotify_filename) link; } dvr_inotify_filename_t; -typedef struct dvr_inotify_entry -{ +typedef struct dvr_inotify_entry { RB_ENTRY(dvr_inotify_entry) link; - char *path; - int fd; + char* path; + int fd; LIST_HEAD(, dvr_inotify_filename) entries; } dvr_inotify_entry_t; static SKEL_DECLARE(dvr_inotify_entry_skel, dvr_inotify_entry_t); -static void* _dvr_inotify_thread ( void *p ); +static void* _dvr_inotify_thread(void* p); -static int _str_cmp ( void *a, void *b ) -{ +static int _str_cmp(void* a, void* b) { return strcmp(((dvr_inotify_entry_t*)a)->path, ((dvr_inotify_entry_t*)b)->path); } - /** * Initialise threads */ pthread_t dvr_inotify_tid; -void dvr_inotify_init ( void ) -{ +void dvr_inotify_init(void) { atomic_set(&_inot_fd, inotify_init1(IN_CLOEXEC)); if (atomic_get(&_inot_fd) < 0) { tvherror(LS_DVR, "failed to initialise inotify (err=%s)", strerror(errno)); @@ -77,10 +71,10 @@ void dvr_inotify_init ( void ) /** * */ -void dvr_inotify_done ( void ) -{ +void dvr_inotify_done(void) { int fd = atomic_exchange(&_inot_fd, -1); - if (fd >= 0) blacklisted_close(fd); + if (fd >= 0) + blacklisted_close(fd); tvh_thread_kill(dvr_inotify_tid, SIGTERM); pthread_join(dvr_inotify_tid, NULL); SKEL_FREE(dvr_inotify_entry_skel); @@ -89,11 +83,10 @@ void dvr_inotify_done ( void ) /** * */ -static int dvr_inotify_exists ( dvr_inotify_entry_t *die, dvr_entry_t *de ) -{ - dvr_inotify_filename_t *dif; +static int dvr_inotify_exists(dvr_inotify_entry_t* die, dvr_entry_t* de) { + dvr_inotify_filename_t* dif; - LIST_FOREACH(dif, &die->entries, link) + LIST_FOREACH (dif, &die->entries, link) if (dif->de == de) return 1; return 0; @@ -102,13 +95,12 @@ static int dvr_inotify_exists ( dvr_inotify_entry_t *die, dvr_entry_t *de ) /** * Add an entry for monitoring */ -static void dvr_inotify_add_one ( dvr_entry_t *de, htsmsg_t *m ) -{ - dvr_inotify_filename_t *dif; - dvr_inotify_entry_t *e; - const char *filename; - char path[PATH_MAX]; - int fd = atomic_get(&_inot_fd); +static void dvr_inotify_add_one(dvr_entry_t* de, htsmsg_t* m) { + dvr_inotify_filename_t* dif; + dvr_inotify_entry_t* e; + const char* filename; + char path[PATH_MAX]; + int fd = atomic_get(&_inot_fd); filename = htsmsg_get_str(m, "filename"); if (filename == NULL || fd < 0) @@ -124,10 +116,10 @@ static void dvr_inotify_add_one ( dvr_entry_t *de, htsmsg_t *m ) SKEL_ALLOC(dvr_inotify_entry_skel); dvr_inotify_entry_skel->path = dirname(path); - + e = RB_INSERT_SORTED(&_inot_tree, dvr_inotify_entry_skel, link, _str_cmp); if (!e) { - e = dvr_inotify_entry_skel; + e = dvr_inotify_entry_skel; SKEL_USED(dvr_inotify_entry_skel); e->path = strdup(e->path); e->fd = inotify_add_watch(fd, e->path, EVENT_MASK); @@ -135,44 +127,39 @@ static void dvr_inotify_add_one ( dvr_entry_t *de, htsmsg_t *m ) if (!dvr_inotify_exists(e, de)) { - dif = malloc(sizeof(*dif)); + dif = malloc(sizeof(*dif)); dif->de = de; LIST_INSERT_HEAD(&e->entries, dif, link); if (e->fd < 0) { - tvherror(LS_DVR, "failed to add inotify watch to %s (err=%s)", - e->path, strerror(errno)); + tvherror(LS_DVR, "failed to add inotify watch to %s (err=%s)", e->path, strerror(errno)); dvr_inotify_del(de); } else { - tvhdebug(LS_DVR, "adding inotify watch to %s (fd=%d)", - e->path, e->fd); + tvhdebug(LS_DVR, "adding inotify watch to %s (fd=%d)", e->path, e->fd); } - } } -void dvr_inotify_add ( dvr_entry_t *de ) -{ - htsmsg_field_t *f; - htsmsg_t *m; +void dvr_inotify_add(dvr_entry_t* de) { + htsmsg_field_t* f; + htsmsg_t* m; if (atomic_get(&_inot_fd) < 0 || de->de_files == NULL) return; HTSMSG_FOREACH(f, de->de_files) - if ((m = htsmsg_field_get_map(f)) != NULL) - dvr_inotify_add_one(de, m); + if ((m = htsmsg_field_get_map(f)) != NULL) + dvr_inotify_add_one(de, m); } /* * Delete an entry from the monitor */ -void dvr_inotify_del ( dvr_entry_t *de ) -{ +void dvr_inotify_del(dvr_entry_t* de) { dvr_inotify_filename_t *f = NULL, *f_next; - dvr_inotify_entry_t *e, *e_next; - int fd; + dvr_inotify_entry_t * e, *e_next; + int fd; lock_assert(&global_lock); @@ -199,14 +186,13 @@ void dvr_inotify_del ( dvr_entry_t *de ) /* * return count of registered entries (for debugging) */ -int dvr_inotify_count ( void ) -{ - dvr_inotify_filename_t *f; - dvr_inotify_entry_t *e; - int count = 0; +int dvr_inotify_count(void) { + dvr_inotify_filename_t* f; + dvr_inotify_entry_t* e; + int count = 0; lock_assert(&global_lock); - RB_FOREACH(e, &_inot_tree, link) - LIST_FOREACH(f, &e->entries, link) + RB_FOREACH (e, &_inot_tree, link) + LIST_FOREACH (f, &e->entries, link) count++; return count; } @@ -214,12 +200,9 @@ int dvr_inotify_count ( void ) /* * Find inotify entry */ -static dvr_inotify_entry_t * -_dvr_inotify_find - ( int fd ) -{ - dvr_inotify_entry_t *e = NULL; - RB_FOREACH(e, &_inot_tree, link) +static dvr_inotify_entry_t* _dvr_inotify_find(int fd) { + dvr_inotify_entry_t* e = NULL; + RB_FOREACH (e, &_inot_tree, link) if (e->fd == fd) break; return e; @@ -228,62 +211,64 @@ _dvr_inotify_find /* * File moved */ -static void -_dvr_inotify_moved - ( int from_fd, const char *from, const char *to, int to_fd ) -{ - dvr_inotify_filename_t *dif; - dvr_inotify_entry_t *die; - dvr_entry_t *de; - char path[PATH_MAX]; - const char *filename; - htsmsg_t *m = NULL; - htsmsg_field_t *f = NULL; - char realdir[PATH_MAX]; - char new_path[PATH_MAX+PATH_MAX+1]; - char ubuf[UUID_HEX_SIZE]; - char *file, *dir = NULL; +static void _dvr_inotify_moved(int from_fd, const char* from, const char* to, int to_fd) { + dvr_inotify_filename_t* dif; + dvr_inotify_entry_t* die; + dvr_entry_t* de; + char path[PATH_MAX]; + const char* filename; + htsmsg_t* m = NULL; + htsmsg_field_t* f = NULL; + char realdir[PATH_MAX]; + char new_path[PATH_MAX + PATH_MAX + 1]; + char ubuf[UUID_HEX_SIZE]; + char * file, *dir = NULL; if (!(die = _dvr_inotify_find(from_fd))) return; snprintf(path, sizeof(path), "%s/%s", die->path, from); - tvhdebug(LS_DVR, "inotify: moved from_fd: %d path: \"%s\" to: \"%s\" to_fd: %d", from_fd, path, to?:"", to_fd); + tvhdebug(LS_DVR, + "inotify: moved from_fd: %d path: \"%s\" to: \"%s\" to_fd: %d", + from_fd, + path, + to ?: "", + to_fd); de = NULL; - LIST_FOREACH(dif, &die->entries, link) { + LIST_FOREACH (dif, &die->entries, link) { de = dif->de; if (de->de_files == NULL) continue; HTSMSG_FOREACH(f, de->de_files) - if ((m = htsmsg_field_get_map(f)) != NULL) { - filename = htsmsg_get_str(m, "filename"); - if (!filename) - continue; + if ((m = htsmsg_field_get_map(f)) != NULL) { + filename = htsmsg_get_str(m, "filename"); + if (!filename) + continue; - /* Simple case of names match */ - if (!strcmp(path, filename)) - break; + /* Simple case of names match */ + if (!strcmp(path, filename)) + break; - /* Otherwise get the real path (after symlinks) - * and compare that. - * - * This is made far more complicated since the - * file has already disappeared so we can't realpath - * on it, so we need to realpath on the directory - * it _was_ in, append the filename part and then - * compare against the realpath of the path we - * were given by inotify. - */ - dir = tvh_strdupa(filename); - dir = dirname(dir); - if (realpath(dir, realdir)) { - file = basename(tvh_strdupa(filename)); - snprintf(new_path, sizeof(new_path), "%s/%s", realdir, file); - if (!strcmp(path, new_path)) - break; - } + /* Otherwise get the real path (after symlinks) + * and compare that. + * + * This is made far more complicated since the + * file has already disappeared so we can't realpath + * on it, so we need to realpath on the directory + * it _was_ in, append the filename part and then + * compare against the realpath of the path we + * were given by inotify. + */ + dir = tvh_strdupa(filename); + dir = dirname(dir); + if (realpath(dir, realdir)) { + file = basename(tvh_strdupa(filename)); + snprintf(new_path, sizeof(new_path), "%s/%s", realdir, file); + if (!strcmp(path, new_path)) + break; } + } if (f) break; } @@ -306,7 +291,11 @@ _dvr_inotify_moved } } snprintf(new_path, sizeof(path), "%s/%s", die->path, to); - tvhdebug(LS_DVR, "inotify: moved from name: \"%s\" to: \"%s\" for \"%s\"", path, new_path, idnode_uuid_as_str(&de->de_id, ubuf)); + tvhdebug(LS_DVR, + "inotify: moved from name: \"%s\" to: \"%s\" for \"%s\"", + path, + new_path, + idnode_uuid_as_str(&de->de_id, ubuf)); htsmsg_set_str(m, "filename", new_path); idnode_changed(&de->de_id); } else { @@ -315,7 +304,7 @@ _dvr_inotify_moved dvr_inotify_del(de); } } - + dvr_vfs_refresh_entry(de); htsp_dvr_entry_update(de); idnode_notify_changed(&de->de_id); @@ -324,23 +313,17 @@ _dvr_inotify_moved /* * File deleted */ -static void -_dvr_inotify_delete - ( int fd, const char *path ) -{ +static void _dvr_inotify_delete(int fd, const char* path) { _dvr_inotify_moved(fd, path, NULL, -1); } /* * Directory moved */ -static void -_dvr_inotify_moved_all - ( int fd, const char *to ) -{ - dvr_inotify_filename_t *f; - dvr_inotify_entry_t *die; - dvr_entry_t *de; +static void _dvr_inotify_moved_all(int fd, const char* to) { + dvr_inotify_filename_t* f; + dvr_inotify_entry_t* die; + dvr_entry_t* de; if (!(die = _dvr_inotify_find(fd))) return; @@ -356,27 +339,23 @@ _dvr_inotify_moved_all /* * Directory deleted */ -static void -_dvr_inotify_delete_all - ( int fd ) -{ +static void _dvr_inotify_delete_all(int fd) { _dvr_inotify_moved_all(fd, NULL); } /* * Process events */ -void* _dvr_inotify_thread ( void *p ) -{ - int fd, i, len; - char buf[EVENT_BUF_LEN]; - const char *from; - int fromfd; - int cookie; - struct inotify_event *ev; - char from_prev[NAME_MAX + 1] = ""; - int fromfd_prev = 0; - int cookie_prev = 0; +void* _dvr_inotify_thread(void* p) { + int fd, i, len; + char buf[EVENT_BUF_LEN]; + const char* from; + int fromfd; + int cookie; + struct inotify_event* ev; + char from_prev[NAME_MAX + 1] = ""; + int fromfd_prev = 0; + int cookie_prev = 0; while (tvheadend_is_running()) { @@ -388,14 +367,14 @@ void* _dvr_inotify_thread ( void *p ) fd = atomic_get(&_inot_fd); if (fd < 0) break; - len = read(fd, buf, EVENT_BUF_LEN); + len = read(fd, buf, EVENT_BUF_LEN); if (len < 0) break; /* Process */ tvh_mutex_lock(&global_lock); while (i < len) { - ev = (struct inotify_event *)&buf[i]; + ev = (struct inotify_event*)&buf[i]; tvhtrace(LS_DVR_INOTIFY, "i=%d len=%d name=%s", i, len, ev->name); i += EVENT_SIZE + ev->len; if (i > len || i < 0) @@ -410,26 +389,32 @@ void* _dvr_inotify_thread ( void *p ) continue; } else if (ev->mask & IN_MOVED_TO) { - tvhtrace(LS_DVR_INOTIFY, "i=%d len=%d to_cookie=%d from_cookie=%d cookie_prev=%d", i, len, ev->cookie, cookie, cookie_prev); - if (from && ev->cookie == cookie) { - _dvr_inotify_moved(fromfd, from, ev->name, ev->wd); - from = NULL; - cookie = 0; - } else if (from_prev[0] != '\0' && ev->cookie == cookie_prev) { - _dvr_inotify_moved(fromfd_prev, from_prev, ev->name, ev->wd); - from_prev[0] = '\0'; - cookie_prev = 0; - } - - /* Removed */ + tvhtrace(LS_DVR_INOTIFY, + "i=%d len=%d to_cookie=%d from_cookie=%d cookie_prev=%d", + i, + len, + ev->cookie, + cookie, + cookie_prev); + if (from && ev->cookie == cookie) { + _dvr_inotify_moved(fromfd, from, ev->name, ev->wd); + from = NULL; + cookie = 0; + } else if (from_prev[0] != '\0' && ev->cookie == cookie_prev) { + _dvr_inotify_moved(fromfd_prev, from_prev, ev->name, ev->wd); + from_prev[0] = '\0'; + cookie_prev = 0; + } + + /* Removed */ } else if (ev->mask & IN_DELETE) { _dvr_inotify_delete(ev->wd, ev->name); - - /* Moved self */ + + /* Moved self */ } else if (ev->mask & IN_MOVE_SELF) { _dvr_inotify_moved_all(ev->wd, NULL); - - /* Removed self */ + + /* Removed self */ } else if (ev->mask & IN_DELETE_SELF) { _dvr_inotify_delete_all(ev->wd); } @@ -438,18 +423,23 @@ void* _dvr_inotify_thread ( void *p ) if (from_prev[0] != '\0') { _dvr_inotify_moved(fromfd_prev, from_prev, NULL, -1); from_prev[0] = '\0'; - cookie_prev = 0; + cookie_prev = 0; } // if unmatched "from", save in case matching "to" is coming in next read if (from) { strlcpy(from_prev, from, 255); fromfd_prev = fromfd; cookie_prev = cookie; - tvhdebug(LS_DVR_INOTIFY, "i=%d len=%d cookie_prev=%d from_prev=%s fd=%d EOR", i, len, cookie_prev, from_prev, fromfd_prev); + tvhdebug(LS_DVR_INOTIFY, + "i=%d len=%d cookie_prev=%d from_prev=%s fd=%d EOR", + i, + len, + cookie_prev, + from_prev, + fromfd_prev); } tvh_mutex_unlock(&global_lock); } return NULL; } - diff --git a/src/dvr/dvr_rec.c b/src/dvr/dvr_rec.c index 278fa1dea..4d3e7557b 100644 --- a/src/dvr/dvr_rec.c +++ b/src/dvr/dvr_rec.c @@ -37,23 +37,20 @@ /** * */ -static void *dvr_thread(void *aux); -static void dvr_thread_epilog(dvr_entry_t *de, const char *dvr_postproc); - +static void* dvr_thread(void* aux); +static void dvr_thread_epilog(dvr_entry_t* de, const char* dvr_postproc); static const int prio2weight[6] = { - [DVR_PRIO_IMPORTANT] = 500, - [DVR_PRIO_HIGH] = 400, - [DVR_PRIO_NORMAL] = 300, - [DVR_PRIO_LOW] = 200, - [DVR_PRIO_UNIMPORTANT] = 100, - [DVR_PRIO_NOTSET] = 300, /* DVR_PRIO_NORMAL */ + [DVR_PRIO_IMPORTANT] = 500, + [DVR_PRIO_HIGH] = 400, + [DVR_PRIO_NORMAL] = 300, + [DVR_PRIO_LOW] = 200, + [DVR_PRIO_UNIMPORTANT] = 100, + [DVR_PRIO_NOTSET] = 300, /* DVR_PRIO_NORMAL */ }; /// Spawn a fetch of artwork for the entry. -void -dvr_spawn_fetch_artwork(dvr_entry_t *de) -{ +void dvr_spawn_fetch_artwork(dvr_entry_t* de) { /* Don't want to use _SC_ARG_MAX since it will be a large number */ char buf[1024]; char ubuf[UUID_HEX_SIZE]; @@ -61,36 +58,36 @@ dvr_spawn_fetch_artwork(dvr_entry_t *de) if (!dvr_entry_allow_fanart_lookup(de)) return; - snprintf(buf, sizeof buf, "tvhmeta --uuid %s %s", - idnode_uuid_as_str(&de->de_id, ubuf), - de->de_config->dvr_fetch_artwork_options); + snprintf(buf, + sizeof buf, + "tvhmeta --uuid %s %s", + idnode_uuid_as_str(&de->de_id, ubuf), + de->de_config->dvr_fetch_artwork_options); dvr_spawn_cmd(de, buf, NULL, 1); } /** * */ -int -dvr_rec_subscribe(dvr_entry_t *de) -{ - char buf[100]; - int weight; - profile_t *pro; - profile_chain_t *prch = NULL; +int dvr_rec_subscribe(dvr_entry_t* de) { + char buf[100]; + int weight; + profile_t* pro; + profile_chain_t* prch = NULL; struct sockaddr_storage sa; - access_t *aa = NULL; - uint32_t rec_count, net_count; - int ret = 0, pri, c1, c2; - struct stat st; - int stat_ret; + access_t* aa = NULL; + uint32_t rec_count, net_count; + int ret = 0, pri, c1, c2; + struct stat st; + int stat_ret; assert(de->de_s == NULL); assert(de->de_chain == NULL); pri = de->de_pri; - if(pri == DVR_PRIO_NOTSET || pri == DVR_PRIO_DEFAULT) + if (pri == DVR_PRIO_NOTSET || pri == DVR_PRIO_DEFAULT) pri = de->de_config->dvr_pri; - if(pri < 0 || pri >= ARRAY_SIZE(prio2weight)) + if (pri < 0 || pri >= ARRAY_SIZE(prio2weight)) pri = DVR_PRIO_NORMAL; weight = prio2weight[pri]; @@ -99,11 +96,13 @@ dvr_rec_subscribe(dvr_entry_t *de) if (de->de_owner && de->de_owner[0] != '\0') { aa = access_get_by_username(de->de_owner); } else if (de->de_creator && de->de_creator[0] != '\0' && - tcp_get_ip_from_str(de->de_creator, &sa) != NULL) { + tcp_get_ip_from_str(de->de_creator, &sa) != NULL) { aa = access_get_by_addr(&sa); } else { - tvherror(LS_DVR, "unable to find access (owner '%s', creator '%s')", - de->de_owner, de->de_creator); + tvherror(LS_DVR, + "unable to find access (owner '%s', creator '%s')", + de->de_owner, + de->de_creator); ret = -EPERM; goto _return; } @@ -116,10 +115,15 @@ dvr_rec_subscribe(dvr_entry_t *de) c1 = aa->aa_conn_limit ? rec_count + net_count >= aa->aa_conn_limit : -1; c2 = aa->aa_conn_limit_dvr ? rec_count >= aa->aa_conn_limit_dvr : -1; if (c1 && c2) { - tvherror(LS_DVR, "multiple connections are not allowed for user '%s' from '%s' " - "(limit %u, dvr limit %u, active DVR %u, streaming %u)", - aa->aa_username ?: "", aa->aa_representative ?: "", - aa->aa_conn_limit, aa->aa_conn_limit_dvr, rec_count, net_count); + tvherror(LS_DVR, + "multiple connections are not allowed for user '%s' from '%s' " + "(limit %u, dvr limit %u, active DVR %u, streaming %u)", + aa->aa_username ?: "", + aa->aa_representative ?: "", + aa->aa_conn_limit, + aa->aa_conn_limit_dvr, + rec_count, + net_count); ret = -EOVERFLOW; goto _return; } @@ -127,43 +131,58 @@ dvr_rec_subscribe(dvr_entry_t *de) stat_ret = stat(de->de_config->dvr_storage, &st); - //If the stat() failed, show the error message. - if(stat_ret != 0) { - tvherror(LS_DVR, "Directory '%s' not accessible: %s", de->de_config->dvr_storage, strerror(errno)); + // If the stat() failed, show the error message. + if (stat_ret != 0) { + tvherror(LS_DVR, + "Directory '%s' not accessible: %s", + de->de_config->dvr_storage, + strerror(errno)); ret = -EIO; goto _return; } - //If the stat() worked, but the path is not a directory. - if(!S_ISDIR(st.st_mode) && stat_ret == 0) { + // If the stat() worked, but the path is not a directory. + if (!S_ISDIR(st.st_mode) && stat_ret == 0) { tvherror(LS_DVR, "'%s' is not a directory.", de->de_config->dvr_storage); ret = -EIO; goto _return; } - pro = de->de_config->dvr_profile; + pro = de->de_config->dvr_profile; prch = malloc(sizeof(*prch)); profile_chain_init(prch, pro, de->de_channel, 1); if (profile_chain_open(prch, &de->de_config->dvr_muxcnf, NULL, 0, 0)) { profile_chain_close(prch); - tvherror(LS_DVR, "unable to create new channel streaming chain '%s' for '%s', using default", - profile_get_name(pro), channel_get_name(de->de_channel, channel_blank_name)); + tvherror(LS_DVR, + "unable to create new channel streaming chain '%s' for '%s', using default", + profile_get_name(pro), + channel_get_name(de->de_channel, channel_blank_name)); pro = profile_find_by_name(NULL, NULL); profile_chain_init(prch, pro, de->de_channel, 1); if (profile_chain_open(prch, &de->de_config->dvr_muxcnf, NULL, 0, 0)) { - tvherror(LS_DVR, "unable to create channel streaming default chain '%s' for '%s'", - profile_get_name(pro), channel_get_name(de->de_channel, channel_blank_name)); + tvherror(LS_DVR, + "unable to create channel streaming default chain '%s' for '%s'", + profile_get_name(pro), + channel_get_name(de->de_channel, channel_blank_name)); ret = -EINVAL; goto _return; } } - de->de_s = subscription_create_from_channel(prch, NULL, weight, - buf, prch->prch_flags, - NULL, aa->aa_username ?: "", NULL, NULL); + de->de_s = subscription_create_from_channel(prch, + NULL, + weight, + buf, + prch->prch_flags, + NULL, + aa->aa_username ?: "", + NULL, + NULL); if (de->de_s == NULL) { - tvherror(LS_DVR, "unable to create new channel subcription for '%s' profile '%s'", - channel_get_name(de->de_channel, channel_blank_name), profile_get_name(pro)); + tvherror(LS_DVR, + "unable to create new channel subcription for '%s' profile '%s'", + channel_get_name(de->de_channel, channel_blank_name), + profile_get_name(pro)); ret = -EINVAL; goto _return; } @@ -191,11 +210,9 @@ _return: /** * */ -void -dvr_rec_unsubscribe(dvr_entry_t *de) -{ - profile_chain_t *prch = de->de_chain; - char *postproc = NULL; +void dvr_rec_unsubscribe(dvr_entry_t* de) { + profile_chain_t* prch = de->de_chain; + char* postproc = NULL; assert(de->de_s != NULL); assert(prch != NULL); @@ -206,7 +223,7 @@ dvr_rec_unsubscribe(dvr_entry_t *de) atomic_add(&de->de_thread_shutdown, 1); - pthread_join(de->de_thread, (void **)&postproc); + pthread_join(de->de_thread, (void**)&postproc); if (prch->prch_muxer) dvr_thread_epilog(de, postproc); @@ -228,16 +245,14 @@ dvr_rec_unsubscribe(dvr_entry_t *de) /** * */ -void -dvr_rec_migrate(dvr_entry_t *de_old, dvr_entry_t *de_new) -{ +void dvr_rec_migrate(dvr_entry_t* de_old, dvr_entry_t* de_new) { lock_assert(&global_lock); - de_new->de_s = de_old->de_s; - de_new->de_chain = de_old->de_chain; + de_new->de_s = de_old->de_s; + de_new->de_chain = de_old->de_chain; de_new->de_thread = de_old->de_thread; - de_old->de_s = NULL; - de_old->de_chain = NULL; + de_old->de_s = NULL; + de_old->de_chain = NULL; de_old->de_thread = 0; } @@ -245,17 +260,14 @@ dvr_rec_migrate(dvr_entry_t *de_old, dvr_entry_t *de_new) * Replace various chars with a dash * - dosubs specifies if user demanded substitutions are performed */ -static char * -cleanup_filename(dvr_config_t *cfg, char *s, int dosubs) -{ - int len = strlen(s); +static char* cleanup_filename(dvr_config_t* cfg, char* s, int dosubs) { + int len = strlen(s); char *s1, *p; s1 = intlconv_utf8safestr(cfg->dvr_charset_id, s, (len * 2) + 1); if (s1 == NULL) { tvherror(LS_DVR, "Unsupported charset %s using ASCII", cfg->dvr_charset); - s1 = intlconv_utf8safestr(intlconv_charset_id("ASCII", 1, 1), - s, len * 2); + s1 = intlconv_utf8safestr(intlconv_charset_id("ASCII", 1, 1), s, len * 2); if (s1 == NULL) return NULL; } @@ -266,7 +278,7 @@ cleanup_filename(dvr_config_t *cfg, char *s, int dosubs) if (s1[0] == '\\' && s1[1] == '.') s1[1] = '_'; - for (s = s1 ; *s; s++) { + for (s = s1; *s; s++) { if (*s == '\\') { s++; @@ -277,20 +289,14 @@ cleanup_filename(dvr_config_t *cfg, char *s, int dosubs) if (*s == '/') *s = '-'; - else if (cfg->dvr_whitespace_in_title && - (*s == ' ' || *s == '\t') && - dosubs) + else if (cfg->dvr_whitespace_in_title && (*s == ' ' || *s == '\t') && dosubs) *s = '-'; else if (cfg->dvr_clean_title && - ((*s < 32) || (*s > 122) || - (strchr("/:\\<>|*?\"", *s) != NULL)) && - dosubs) + ((*s < 32) || (*s > 122) || (strchr("/:\\<>|*?\"", *s) != NULL)) && dosubs) *s = '_'; - else if (cfg->dvr_windows_compatible_filenames && - (strchr("/:\\<>|*?\"", *s) != NULL) && - dosubs) + else if (cfg->dvr_windows_compatible_filenames && (strchr("/:\\<>|*?\"", *s) != NULL) && dosubs) *s = '_'; } @@ -311,9 +317,7 @@ cleanup_filename(dvr_config_t *cfg, char *s, int dosubs) /** * */ -static char * -dvr_clean_directory_separator(char *s, char *tmp, size_t tmplen) -{ +static char* dvr_clean_directory_separator(char* s, char* tmp, size_t tmplen) { char *p, *end; if (s != tmp) { @@ -328,7 +332,7 @@ dvr_clean_directory_separator(char *s, char *tmp, size_t tmplen) *p = *s; *p = '\0'; return tmp; - } else { + } else { for (; *s; s++) if (*s == '/') *s = '-'; @@ -338,9 +342,8 @@ dvr_clean_directory_separator(char *s, char *tmp, size_t tmplen) } } -static const char * -dvr_do_prefix(const char *id, const char *fmt, const char *s, char *tmp, size_t tmplen) -{ +static const char* +dvr_do_prefix(const char* id, const char* fmt, const char* s, char* tmp, size_t tmplen) { if (id[0] == '?') { id++; if (fmt && *fmt >= '0' && *fmt <= '9') { @@ -361,77 +364,67 @@ dvr_do_prefix(const char *id, const char *fmt, const char *s, char *tmp, size_t return dvr_clean_directory_separator(tmp, tmp, tmplen); } - -static const char * -dvr_sub_title(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return dvr_do_prefix(id, fmt, lang_str_get(((dvr_entry_t *)aux)->de_title, NULL), tmp, tmplen); +static const char* +dvr_sub_title(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + return dvr_do_prefix(id, fmt, lang_str_get(((dvr_entry_t*)aux)->de_title, NULL), tmp, tmplen); } -static const char * -dvr_sub_subtitle_or_summary(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - const dvr_entry_t *de = aux; - const char *s = lang_str_get(de->de_subtitle, NULL); - if (s == NULL) s = lang_str_get(de->de_summary, NULL); +static const char* dvr_sub_subtitle_or_summary(const char* id, + const char* fmt, + const void* aux, + char* tmp, + size_t tmplen) { + const dvr_entry_t* de = aux; + const char* s = lang_str_get(de->de_subtitle, NULL); + if (s == NULL) + s = lang_str_get(de->de_summary, NULL); return dvr_do_prefix(id, fmt, s, tmp, tmplen); } -static const char * -dvr_sub_subtitle(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return dvr_do_prefix(id, fmt, lang_str_get(((dvr_entry_t *)aux)->de_subtitle, NULL), tmp, tmplen); +static const char* +dvr_sub_subtitle(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + return dvr_do_prefix(id, fmt, lang_str_get(((dvr_entry_t*)aux)->de_subtitle, NULL), tmp, tmplen); } -static const char * -dvr_sub_summary(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return dvr_do_prefix(id, fmt, lang_str_get(((dvr_entry_t *)aux)->de_summary, NULL), tmp, tmplen); +static const char* +dvr_sub_summary(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + return dvr_do_prefix(id, fmt, lang_str_get(((dvr_entry_t*)aux)->de_summary, NULL), tmp, tmplen); } -static const char * -dvr_sub_description(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return dvr_do_prefix(id, fmt, lang_str_get(((dvr_entry_t *)aux)->de_desc, NULL), tmp, tmplen); +static const char* +dvr_sub_description(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + return dvr_do_prefix(id, fmt, lang_str_get(((dvr_entry_t*)aux)->de_desc, NULL), tmp, tmplen); } -static const char * -dvr_sub_uuid(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - const dvr_entry_t *de = aux; - char ubuf[UUID_HEX_SIZE]; +static const char* +dvr_sub_uuid(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + const dvr_entry_t* de = aux; + char ubuf[UUID_HEX_SIZE]; idnode_uuid_as_str(&de->de_id, ubuf); strlcpy(tmp, ubuf, tmplen); return tmp; } -static const char * -dvr_sub_episode(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - const dvr_entry_t *de = aux; - char buf[64]; +static const char* +dvr_sub_episode(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + const dvr_entry_t* de = aux; + char buf[64]; if (de->de_bcast == NULL) return ""; - epg_broadcast_epnumber_format(de->de_bcast, - buf, sizeof(buf), - NULL, "S%02d", NULL, "E%02d", NULL); + epg_broadcast_epnumber_format(de->de_bcast, buf, sizeof(buf), NULL, "S%02d", NULL, "E%02d", NULL); return dvr_do_prefix(id, fmt, buf, tmp, tmplen); } -static const char * -_dvr_get_tvmovies_subdir(const dvr_entry_t *de) -{ - dvr_config_t *config = de->de_config; +static const char* _dvr_get_tvmovies_subdir(const dvr_entry_t* de) { + dvr_config_t* config = de->de_config; if (config && !strempty(config->dvr_format_tvmovies_subdir)) return config->dvr_format_tvmovies_subdir; return "tvmovies"; } -static const char * -_dvr_get_tvshows_subdir(const dvr_entry_t *de) -{ - dvr_config_t *config = de->de_config; +static const char* _dvr_get_tvshows_subdir(const dvr_entry_t* de) { + dvr_config_t* config = de->de_config; if (config && !strempty(config->dvr_format_tvshows_subdir)) return config->dvr_format_tvshows_subdir; return "tvshows"; @@ -445,21 +438,24 @@ typedef enum { DVR_SF_WITH_PER_MOVIE_SUBDIR = 0x4 /*< X/X.ts - separate dir per-movie */ } dvr_sf_t; -static const char * -_dvr_sub_scraper_friendly(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen, dvr_sf_t subdir_type) -{ +static const char* _dvr_sub_scraper_friendly(const char* id, + const char* fmt, + const void* aux, + char* tmp, + size_t tmplen, + dvr_sf_t subdir_type) { /* Directory to use for no season/special season when using * per-season directories. Kodi "naming tv shows/Special Episodes". */ - static const char special_season_dir[] = "Season 0"; /* Deliberately not localized. */ - const dvr_entry_t *de = aux; - epg_broadcast_t *ebc = de->de_bcast; + static const char special_season_dir[] = "Season 0"; /* Deliberately not localized. */ + const dvr_entry_t* de = aux; + epg_broadcast_t* ebc = de->de_bcast; - *tmp = 0; - const char *title = lang_str_get(de->de_title, NULL); - const char *subtitle = lang_str_get(de->de_subtitle, NULL); - const char *summary = lang_str_get(de->de_summary, NULL); - const char *desc = lang_str_get(de->de_desc, NULL); + *tmp = 0; + const char* title = lang_str_get(de->de_title, NULL); + const char* subtitle = lang_str_get(de->de_subtitle, NULL); + const char* summary = lang_str_get(de->de_summary, NULL); + const char* desc = lang_str_get(de->de_desc, NULL); /* Pick summary as subtitle if appropriate */ if (summary) { @@ -480,16 +476,16 @@ _dvr_sub_scraper_friendly(const char *id, const char *fmt, const void *aux, char subtitle = NULL; } - const size_t title_buf_size = title ? strlen(title) + 1 : 0; - char *title_buf = title ? alloca(title_buf_size) : NULL; + const size_t title_buf_size = title ? strlen(title) + 1 : 0; + char* title_buf = title ? alloca(title_buf_size) : NULL; const size_t subtitle_buf_size = subtitle ? strlen(subtitle) + 1 : 0; - char *subtitle_buf = subtitle ? alloca(subtitle_buf_size) : NULL; + char* subtitle_buf = subtitle ? alloca(subtitle_buf_size) : NULL; /* Copy a cleaned version in to our buffers. * Since dvr_clean_directory_separator _can_ modify source if source!=dest * it means we have to remove our const when we call it. */ if (title) - dvr_clean_directory_separator((char*)title, title_buf, title_buf_size); + dvr_clean_directory_separator((char*)title, title_buf, title_buf_size); if (subtitle) dvr_clean_directory_separator((char*)subtitle, subtitle_buf, subtitle_buf_size); @@ -497,16 +493,15 @@ _dvr_sub_scraper_friendly(const char *id, const char *fmt, const void *aux, char /* Override options on the format tag. This is useful because my OTA * for the film channel doesn't have a genre. */ - if (fmt && *fmt == '1') /* Force to be a movie */ + if (fmt && *fmt == '1') /* Force to be a movie */ is_movie = 1; - else if (fmt && *fmt == '2') /* Force to be a series (not a movie) */ + else if (fmt && *fmt == '2') /* Force to be a series (not a movie) */ is_movie = 0; else { if (ebc && ebc->category) { /* We've parsed categories from xmltv. So check if it has the movie category. */ - is_movie = - string_list_contains_string(ebc->category, "movie") || - string_list_contains_string(ebc->category, "film"); + is_movie = string_list_contains_string(ebc->category, "movie") || + string_list_contains_string(ebc->category, "film"); } else { /* No xmltv categories parsed. So have to use less-accurate genre instead. */ @@ -519,12 +514,16 @@ _dvr_sub_scraper_friendly(const char *id, const char *fmt, const void *aux, char * otherwise we default to movie. */ if (ebc && (ebc->epnum.s_num || ebc->epnum.e_num)) - is_movie = 0; + is_movie = 0; } } } - tvhdebug(LS_DVR, "fmt = %s is_movie = %d content_type = %d", fmt ?: "", is_movie, de->de_content_type); + tvhdebug(LS_DVR, + "fmt = %s is_movie = %d content_type = %d", + fmt ?: "", + is_movie, + de->de_content_type); char *date_buf = NULL, *episode_buf = NULL, *season_dir = NULL; @@ -554,8 +553,7 @@ _dvr_sub_scraper_friendly(const char *id, const char *fmt, const void *aux, char if (ebc) { /* Get episode information */ episode_buf = alloca(512); - epg_broadcast_epnumber_format(ebc, episode_buf, 512, - NULL, "S%02d", NULL, "E%02d", NULL); + epg_broadcast_epnumber_format(ebc, episode_buf, 512, NULL, "S%02d", NULL, "E%02d", NULL); const time_t first_aired = ebc->first_aired; if (first_aired) { @@ -598,8 +596,10 @@ _dvr_sub_scraper_friendly(const char *id, const char *fmt, const void *aux, char if ((subdir_type & DVR_SF_WITH_GENRE_SUBDIR) == DVR_SF_WITH_GENRE_SUBDIR) tvh_strlcatf(tmp, tmplen, offset, "%s/", _dvr_get_tvmovies_subdir(de)); - /* For 'per movie subdir' we want "title (YYYY)/" or "title/" if no year but don't want "(YYYY)" (no title) */ - if ((subdir_type & DVR_SF_WITH_PER_MOVIE_SUBDIR) == DVR_SF_WITH_PER_MOVIE_SUBDIR && !strempty(title_buf)) { + /* For 'per movie subdir' we want "title (YYYY)/" or "title/" if no year but don't want "(YYYY)" + * (no title) */ + if ((subdir_type & DVR_SF_WITH_PER_MOVIE_SUBDIR) == DVR_SF_WITH_PER_MOVIE_SUBDIR && + !strempty(title_buf)) { tvh_strlcatf(tmp, tmplen, offset, "%s", title_buf); if (!strempty(date_buf)) tvh_strlcatf(tmp, tmplen, offset, " (%s)", date_buf); @@ -647,12 +647,17 @@ _dvr_sub_scraper_friendly(const char *id, const char *fmt, const void *aux, char * There seems to be disagreement between tools on whether it should be * "Season 1" (Emby, Kodi) or "Season 01" (Plex). */ - epg_broadcast_epnumber_format(ebc, season_dir, 256, - NULL, "Season %d", NULL, NULL, NULL); + epg_broadcast_epnumber_format(ebc, season_dir, 256, NULL, "Season %d", NULL, NULL, NULL); /* E.g., "Simpsons/Season 1/Simpsons", to which we'll later add " - S01E02" * Or "Simpsons/Season 0/Simpsons" for a tv special. */ - tvh_strlcatf(tmp, tmplen, offset, "%s/%s/%s", title_buf, strempty(season_dir) ? special_season_dir : season_dir, title_buf); + tvh_strlcatf(tmp, + tmplen, + offset, + "%s/%s/%s", + title_buf, + strempty(season_dir) ? special_season_dir : season_dir, + title_buf); } else if (!strempty(title_buf)) tvh_strlcatf(tmp, tmplen, offset, "%s/%s", title_buf, title_buf); if (!strempty(episode_buf)) @@ -666,42 +671,58 @@ _dvr_sub_scraper_friendly(const char *id, const char *fmt, const void *aux, char return tmp; } -static const char * -dvr_sub_scraper_friendly_with_genre_subdir(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ +static const char* dvr_sub_scraper_friendly_with_genre_subdir(const char* id, + const char* fmt, + const void* aux, + char* tmp, + size_t tmplen) { return _dvr_sub_scraper_friendly(id, fmt, aux, tmp, tmplen, DVR_SF_WITH_GENRE_SUBDIR); } -static const char * -dvr_sub_scraper_friendly_with_genre_subdir_full(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return _dvr_sub_scraper_friendly(id, fmt, aux, tmp, tmplen, DVR_SF_WITH_GENRE_SUBDIR | DVR_SF_WITH_PER_SEASON_SUBDIR | DVR_SF_WITH_PER_MOVIE_SUBDIR); +static const char* dvr_sub_scraper_friendly_with_genre_subdir_full(const char* id, + const char* fmt, + const void* aux, + char* tmp, + size_t tmplen) { + return _dvr_sub_scraper_friendly(id, + fmt, + aux, + tmp, + tmplen, + DVR_SF_WITH_GENRE_SUBDIR | DVR_SF_WITH_PER_SEASON_SUBDIR | DVR_SF_WITH_PER_MOVIE_SUBDIR); } -static const char * -dvr_sub_scraper_friendly_without_genre_subdir(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ +static const char* dvr_sub_scraper_friendly_without_genre_subdir(const char* id, + const char* fmt, + const void* aux, + char* tmp, + size_t tmplen) { return _dvr_sub_scraper_friendly(id, fmt, aux, tmp, tmplen, DVR_SF_WITHOUT_SUBDIR); } -static const char * -dvr_sub_scraper_friendly_without_genre_subdir_full(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return _dvr_sub_scraper_friendly(id, fmt, aux, tmp, tmplen, DVR_SF_WITHOUT_SUBDIR | DVR_SF_WITH_PER_SEASON_SUBDIR | DVR_SF_WITH_PER_MOVIE_SUBDIR); +static const char* dvr_sub_scraper_friendly_without_genre_subdir_full(const char* id, + const char* fmt, + const void* aux, + char* tmp, + size_t tmplen) { + return _dvr_sub_scraper_friendly(id, + fmt, + aux, + tmp, + tmplen, + DVR_SF_WITHOUT_SUBDIR | DVR_SF_WITH_PER_SEASON_SUBDIR | DVR_SF_WITH_PER_MOVIE_SUBDIR); } -static const char * -dvr_sub_channel(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return dvr_do_prefix(id, fmt, DVR_CH_NAME((dvr_entry_t *)aux), tmp, tmplen); +static const char* +dvr_sub_channel(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + return dvr_do_prefix(id, fmt, DVR_CH_NAME((dvr_entry_t*)aux), tmp, tmplen); } -static const char * -dvr_sub_genre(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - const dvr_entry_t *de = aux; - epg_genre_t *genre; - char buf[64]; +static const char* +dvr_sub_genre(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + const dvr_entry_t* de = aux; + epg_genre_t* genre; + char buf[64]; if (de->de_bcast == NULL) return ""; @@ -712,129 +733,122 @@ dvr_sub_genre(const char *id, const char *fmt, const void *aux, char *tmp, size_ return dvr_do_prefix(id, fmt, buf, tmp, tmplen); } -static const char * -dvr_sub_owner(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return dvr_do_prefix(id, fmt, ((dvr_entry_t *)aux)->de_owner, tmp, tmplen); +static const char* +dvr_sub_owner(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + return dvr_do_prefix(id, fmt, ((dvr_entry_t*)aux)->de_owner, tmp, tmplen); } -static const char * -dvr_sub_creator(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return dvr_do_prefix(id, fmt, ((dvr_entry_t *)aux)->de_creator, tmp, tmplen); +static const char* +dvr_sub_creator(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + return dvr_do_prefix(id, fmt, ((dvr_entry_t*)aux)->de_creator, tmp, tmplen); } -static const char * -dvr_sub_last_error(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return dvr_do_prefix(id, fmt, streaming_code2txt(((dvr_entry_t *)aux)->de_last_error), tmp, tmplen); +static const char* +dvr_sub_last_error(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + return dvr_do_prefix(id, + fmt, + streaming_code2txt(((dvr_entry_t*)aux)->de_last_error), + tmp, + tmplen); } -static const char * -dvr_sub_start(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ +static const char* +dvr_sub_start(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { char buf[16]; - snprintf(buf, sizeof(buf), "%"PRItime_t, (time_t)dvr_entry_get_start_time((dvr_entry_t *)aux, 0)); + snprintf(buf, sizeof(buf), "%" PRItime_t, (time_t)dvr_entry_get_start_time((dvr_entry_t*)aux, 0)); return dvr_do_prefix(id, fmt, buf, tmp, tmplen); } -static const char * -dvr_sub_errors(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ +static const char* +dvr_sub_errors(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { char buf[16]; - snprintf(buf, sizeof(buf), "%"PRIu32, (uint32_t)((dvr_entry_t *)aux)->de_errors); + snprintf(buf, sizeof(buf), "%" PRIu32, (uint32_t)((dvr_entry_t*)aux)->de_errors); return dvr_do_prefix(id, fmt, buf, tmp, tmplen); } -static const char * -dvr_sub_data_errors(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ +static const char* +dvr_sub_data_errors(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { char buf[16]; - snprintf(buf, sizeof(buf), "%"PRIu32, (uint32_t)((dvr_entry_t *)aux)->de_data_errors); + snprintf(buf, sizeof(buf), "%" PRIu32, (uint32_t)((dvr_entry_t*)aux)->de_data_errors); return dvr_do_prefix(id, fmt, buf, tmp, tmplen); } -static const char * -dvr_sub_stop(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ +static const char* +dvr_sub_stop(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { char buf[16]; - snprintf(buf, sizeof(buf), "%"PRItime_t, (time_t)dvr_entry_get_stop_time((dvr_entry_t *)aux)); + snprintf(buf, sizeof(buf), "%" PRItime_t, (time_t)dvr_entry_get_stop_time((dvr_entry_t*)aux)); return dvr_do_prefix(id, fmt, buf, tmp, tmplen); } -static const char * -dvr_sub_comment(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return dvr_do_prefix(id, fmt, ((dvr_entry_t *)aux)->de_comment, tmp, tmplen); +static const char* +dvr_sub_comment(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + return dvr_do_prefix(id, fmt, ((dvr_entry_t*)aux)->de_comment, tmp, tmplen); } -static htsstr_substitute_t dvr_subs_entry[] = { - { .id = "?t", .getval = dvr_sub_title }, - { .id = "? t", .getval = dvr_sub_title }, - { .id = "?-t", .getval = dvr_sub_title }, - { .id = "?_t", .getval = dvr_sub_title }, - { .id = "?.t", .getval = dvr_sub_title }, - { .id = "?,t", .getval = dvr_sub_title }, - { .id = "?;t", .getval = dvr_sub_title }, - { .id = "?s", .getval = dvr_sub_subtitle_or_summary }, - { .id = "? s", .getval = dvr_sub_subtitle_or_summary }, - { .id = "?-s", .getval = dvr_sub_subtitle_or_summary }, - { .id = "?_s", .getval = dvr_sub_subtitle_or_summary }, - { .id = "?.s", .getval = dvr_sub_subtitle_or_summary }, - { .id = "?,s", .getval = dvr_sub_subtitle_or_summary }, - { .id = "?;s", .getval = dvr_sub_subtitle_or_summary }, - { .id = "?u", .getval = dvr_sub_subtitle }, - { .id = "? u", .getval = dvr_sub_subtitle }, - { .id = "?-u", .getval = dvr_sub_subtitle }, - { .id = "?_u", .getval = dvr_sub_subtitle }, - { .id = "?.u", .getval = dvr_sub_subtitle }, - { .id = "?,u", .getval = dvr_sub_subtitle }, - { .id = "?;u", .getval = dvr_sub_subtitle }, - { .id = "?m", .getval = dvr_sub_summary }, - { .id = "? m", .getval = dvr_sub_summary }, - { .id = "?-m", .getval = dvr_sub_summary }, - { .id = "?_m", .getval = dvr_sub_summary }, - { .id = "?.m", .getval = dvr_sub_summary }, - { .id = "?,m", .getval = dvr_sub_summary }, - { .id = "?;m", .getval = dvr_sub_summary }, - { .id = "e", .getval = dvr_sub_episode }, - { .id = " e", .getval = dvr_sub_episode }, - { .id = "-e", .getval = dvr_sub_episode }, - { .id = "_e", .getval = dvr_sub_episode }, - { .id = ".e", .getval = dvr_sub_episode }, - { .id = ",e", .getval = dvr_sub_episode }, - { .id = ";e", .getval = dvr_sub_episode }, - { .id = "c", .getval = dvr_sub_channel }, - { .id = " c", .getval = dvr_sub_channel }, - { .id = "-c", .getval = dvr_sub_channel }, - { .id = "_c", .getval = dvr_sub_channel }, - { .id = ".c", .getval = dvr_sub_channel }, - { .id = ",c", .getval = dvr_sub_channel }, - { .id = ";c", .getval = dvr_sub_channel }, - { .id = "g", .getval = dvr_sub_genre }, - { .id = " g", .getval = dvr_sub_genre }, - { .id = "-g", .getval = dvr_sub_genre }, - { .id = "_g", .getval = dvr_sub_genre }, - { .id = ".g", .getval = dvr_sub_genre }, - { .id = ",g", .getval = dvr_sub_genre }, - { .id = ";g", .getval = dvr_sub_genre }, - { .id = "q", .getval = dvr_sub_scraper_friendly_with_genre_subdir }, - { .id = "1q", .getval = dvr_sub_scraper_friendly_with_genre_subdir }, - { .id = "2q", .getval = dvr_sub_scraper_friendly_with_genre_subdir }, - { .id = "3q", .getval = dvr_sub_scraper_friendly_with_genre_subdir_full }, - { .id = "Q", .getval = dvr_sub_scraper_friendly_without_genre_subdir }, - { .id = "1Q", .getval = dvr_sub_scraper_friendly_without_genre_subdir }, - { .id = "2Q", .getval = dvr_sub_scraper_friendly_without_genre_subdir }, - { .id = "3Q", .getval = dvr_sub_scraper_friendly_without_genre_subdir_full }, - { .id = NULL, .getval = NULL } -}; - -static const char * -dvr_sub_strftime(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ +static htsstr_substitute_t dvr_subs_entry[] = {{.id = "?t", .getval = dvr_sub_title}, + {.id = "? t", .getval = dvr_sub_title}, + {.id = "?-t", .getval = dvr_sub_title}, + {.id = "?_t", .getval = dvr_sub_title}, + {.id = "?.t", .getval = dvr_sub_title}, + {.id = "?,t", .getval = dvr_sub_title}, + {.id = "?;t", .getval = dvr_sub_title}, + {.id = "?s", .getval = dvr_sub_subtitle_or_summary}, + {.id = "? s", .getval = dvr_sub_subtitle_or_summary}, + {.id = "?-s", .getval = dvr_sub_subtitle_or_summary}, + {.id = "?_s", .getval = dvr_sub_subtitle_or_summary}, + {.id = "?.s", .getval = dvr_sub_subtitle_or_summary}, + {.id = "?,s", .getval = dvr_sub_subtitle_or_summary}, + {.id = "?;s", .getval = dvr_sub_subtitle_or_summary}, + {.id = "?u", .getval = dvr_sub_subtitle}, + {.id = "? u", .getval = dvr_sub_subtitle}, + {.id = "?-u", .getval = dvr_sub_subtitle}, + {.id = "?_u", .getval = dvr_sub_subtitle}, + {.id = "?.u", .getval = dvr_sub_subtitle}, + {.id = "?,u", .getval = dvr_sub_subtitle}, + {.id = "?;u", .getval = dvr_sub_subtitle}, + {.id = "?m", .getval = dvr_sub_summary}, + {.id = "? m", .getval = dvr_sub_summary}, + {.id = "?-m", .getval = dvr_sub_summary}, + {.id = "?_m", .getval = dvr_sub_summary}, + {.id = "?.m", .getval = dvr_sub_summary}, + {.id = "?,m", .getval = dvr_sub_summary}, + {.id = "?;m", .getval = dvr_sub_summary}, + {.id = "e", .getval = dvr_sub_episode}, + {.id = " e", .getval = dvr_sub_episode}, + {.id = "-e", .getval = dvr_sub_episode}, + {.id = "_e", .getval = dvr_sub_episode}, + {.id = ".e", .getval = dvr_sub_episode}, + {.id = ",e", .getval = dvr_sub_episode}, + {.id = ";e", .getval = dvr_sub_episode}, + {.id = "c", .getval = dvr_sub_channel}, + {.id = " c", .getval = dvr_sub_channel}, + {.id = "-c", .getval = dvr_sub_channel}, + {.id = "_c", .getval = dvr_sub_channel}, + {.id = ".c", .getval = dvr_sub_channel}, + {.id = ",c", .getval = dvr_sub_channel}, + {.id = ";c", .getval = dvr_sub_channel}, + {.id = "g", .getval = dvr_sub_genre}, + {.id = " g", .getval = dvr_sub_genre}, + {.id = "-g", .getval = dvr_sub_genre}, + {.id = "_g", .getval = dvr_sub_genre}, + {.id = ".g", .getval = dvr_sub_genre}, + {.id = ",g", .getval = dvr_sub_genre}, + {.id = ";g", .getval = dvr_sub_genre}, + {.id = "q", .getval = dvr_sub_scraper_friendly_with_genre_subdir}, + {.id = "1q", .getval = dvr_sub_scraper_friendly_with_genre_subdir}, + {.id = "2q", .getval = dvr_sub_scraper_friendly_with_genre_subdir}, + {.id = "3q", .getval = dvr_sub_scraper_friendly_with_genre_subdir_full}, + {.id = "Q", .getval = dvr_sub_scraper_friendly_without_genre_subdir}, + {.id = "1Q", .getval = dvr_sub_scraper_friendly_without_genre_subdir}, + {.id = "2Q", .getval = dvr_sub_scraper_friendly_without_genre_subdir}, + {.id = "3Q", .getval = dvr_sub_scraper_friendly_without_genre_subdir_full}, + {.id = NULL, .getval = NULL}}; + +static const char* +dvr_sub_strftime(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { char fid[8], *p; snprintf(fid, sizeof(fid), "%%%s", id); - strftime(tmp, tmplen, fid, (struct tm *)aux); + strftime(tmp, tmplen, fid, (struct tm*)aux); for (p = tmp; *p; p++) if (*p == ':') *p = '-'; @@ -842,134 +856,133 @@ dvr_sub_strftime(const char *id, const char *fmt, const void *aux, char *tmp, si } static htsstr_substitute_t dvr_subs_time[] = { - { .id = "a", .getval = dvr_sub_strftime }, /* The abbreviated name of the day of the week */ - { .id = "A", .getval = dvr_sub_strftime }, /* The full name of the day of the week */ - { .id = "b", .getval = dvr_sub_strftime }, /* The abbreviated month name */ - { .id = "B", .getval = dvr_sub_strftime }, /* The full month name */ - { .id = "c", .getval = dvr_sub_strftime }, /* The preferred date and time representation */ - { .id = "C", .getval = dvr_sub_strftime }, /* The century number (year/100) as a 2-digit integer */ - { .id = "d", .getval = dvr_sub_strftime }, /* The day of the month as a decimal number (range 01 to 31) */ - { .id = "D", .getval = dvr_sub_strftime }, /* Equivalent to %m/%d/%y */ - { .id = "e", .getval = dvr_sub_strftime }, /* The day of the month as a decimal number (range 01 to 31) */ - - { .id = "Ec", .getval = dvr_sub_strftime }, /* alternatives */ - { .id = "EC", .getval = dvr_sub_strftime }, - { .id = "Ex", .getval = dvr_sub_strftime }, - { .id = "EX", .getval = dvr_sub_strftime }, - { .id = "Ey", .getval = dvr_sub_strftime }, - { .id = "EY", .getval = dvr_sub_strftime }, - - { .id = "F", .getval = dvr_sub_strftime }, /* Equivalent to %m/%d/%y */ - { .id = "G", .getval = dvr_sub_strftime }, /* The ISO 8601 week-based year with century */ - { .id = "g", .getval = dvr_sub_strftime }, /* Like %G, but without century */ - { .id = "h", .getval = dvr_sub_strftime }, /* Equivalent to %b */ - { .id = "H", .getval = dvr_sub_strftime }, /* The hour (range 00 to 23) */ - { .id = "j", .getval = dvr_sub_strftime }, /* The day of the year (range 000 to 366) */ - { .id = "k", .getval = dvr_sub_strftime }, /* The hour (range 0 to 23) - with space */ - { .id = "l", .getval = dvr_sub_strftime }, /* The hour (range 1 to 12) - with space */ - { .id = "m", .getval = dvr_sub_strftime }, /* The month (range 01 to 12) */ - { .id = "M", .getval = dvr_sub_strftime }, /* The minute (range 00 to 59) */ - - { .id = "Od", .getval = dvr_sub_strftime }, /* alternatives */ - { .id = "Oe", .getval = dvr_sub_strftime }, - { .id = "OH", .getval = dvr_sub_strftime }, - { .id = "OI", .getval = dvr_sub_strftime }, - { .id = "Om", .getval = dvr_sub_strftime }, - { .id = "OM", .getval = dvr_sub_strftime }, - { .id = "OS", .getval = dvr_sub_strftime }, - { .id = "Ou", .getval = dvr_sub_strftime }, - { .id = "OU", .getval = dvr_sub_strftime }, - { .id = "OV", .getval = dvr_sub_strftime }, - { .id = "Ow", .getval = dvr_sub_strftime }, - { .id = "OW", .getval = dvr_sub_strftime }, - { .id = "Oy", .getval = dvr_sub_strftime }, - - { .id = "p", .getval = dvr_sub_strftime }, /* AM/PM */ - { .id = "P", .getval = dvr_sub_strftime }, /* am/pm */ - { .id = "r", .getval = dvr_sub_strftime }, /* a.m./p.m. */ - { .id = "R", .getval = dvr_sub_strftime }, /* %H:%M */ - { .id = "s", .getval = dvr_sub_strftime }, /* The number of seconds since the Epoch */ - { .id = "S", .getval = dvr_sub_strftime }, /* The seconds (range 00 to 60) */ - { .id = "T", .getval = dvr_sub_strftime }, /* %H:%M:%S */ - { .id = "u", .getval = dvr_sub_strftime }, /* The day of the week as a decimal, range 1 to 7, Monday being 1 */ - { .id = "U", .getval = dvr_sub_strftime }, /* The week number of the current year as a decimal number, range 00 to 53 (Sunday) */ - { .id = "V", .getval = dvr_sub_strftime }, /* The ISO 8601 week number (range 01 to 53) */ - { .id = "w", .getval = dvr_sub_strftime }, /* The day of the week as a decimal, range 0 to 6, Sunday being 0 */ - { .id = "W", .getval = dvr_sub_strftime }, /* The week number of the current year as a decimal number, range 00 to 53 (Monday) */ - { .id = "x", .getval = dvr_sub_strftime }, /* The preferred date representation */ - { .id = "X", .getval = dvr_sub_strftime }, /* The preferred time representation */ - { .id = "y", .getval = dvr_sub_strftime }, /* The year as a decimal number without a century (range 00 to 99) */ - { .id = "Y", .getval = dvr_sub_strftime }, /* The year as a decimal number including the century */ - { .id = "z", .getval = dvr_sub_strftime }, /* The +hhmm or -hhmm numeric timezone */ - { .id = "Z", .getval = dvr_sub_strftime }, /* The timezone name or abbreviation */ - - { .id = NULL, .getval = NULL } -}; - -static const char * -dvr_sub_str(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - return (const char *)aux; + {.id = "a", .getval = dvr_sub_strftime}, /* The abbreviated name of the day of the week */ + {.id = "A", .getval = dvr_sub_strftime}, /* The full name of the day of the week */ + {.id = "b", .getval = dvr_sub_strftime}, /* The abbreviated month name */ + {.id = "B", .getval = dvr_sub_strftime}, /* The full month name */ + {.id = "c", .getval = dvr_sub_strftime}, /* The preferred date and time representation */ + {.id = "C", + .getval = dvr_sub_strftime}, /* The century number (year/100) as a 2-digit integer */ + {.id = "d", + .getval = dvr_sub_strftime}, /* The day of the month as a decimal number (range 01 to 31) */ + {.id = "D", .getval = dvr_sub_strftime}, /* Equivalent to %m/%d/%y */ + {.id = "e", + .getval = dvr_sub_strftime}, /* The day of the month as a decimal number (range 01 to 31) */ + + {.id = "Ec", .getval = dvr_sub_strftime}, /* alternatives */ + {.id = "EC", .getval = dvr_sub_strftime}, + {.id = "Ex", .getval = dvr_sub_strftime}, + {.id = "EX", .getval = dvr_sub_strftime}, + {.id = "Ey", .getval = dvr_sub_strftime}, + {.id = "EY", .getval = dvr_sub_strftime}, + + {.id = "F", .getval = dvr_sub_strftime}, /* Equivalent to %m/%d/%y */ + {.id = "G", .getval = dvr_sub_strftime}, /* The ISO 8601 week-based year with century */ + {.id = "g", .getval = dvr_sub_strftime}, /* Like %G, but without century */ + {.id = "h", .getval = dvr_sub_strftime}, /* Equivalent to %b */ + {.id = "H", .getval = dvr_sub_strftime}, /* The hour (range 00 to 23) */ + {.id = "j", .getval = dvr_sub_strftime}, /* The day of the year (range 000 to 366) */ + {.id = "k", .getval = dvr_sub_strftime}, /* The hour (range 0 to 23) - with space */ + {.id = "l", .getval = dvr_sub_strftime}, /* The hour (range 1 to 12) - with space */ + {.id = "m", .getval = dvr_sub_strftime}, /* The month (range 01 to 12) */ + {.id = "M", .getval = dvr_sub_strftime}, /* The minute (range 00 to 59) */ + + {.id = "Od", .getval = dvr_sub_strftime}, /* alternatives */ + {.id = "Oe", .getval = dvr_sub_strftime}, + {.id = "OH", .getval = dvr_sub_strftime}, + {.id = "OI", .getval = dvr_sub_strftime}, + {.id = "Om", .getval = dvr_sub_strftime}, + {.id = "OM", .getval = dvr_sub_strftime}, + {.id = "OS", .getval = dvr_sub_strftime}, + {.id = "Ou", .getval = dvr_sub_strftime}, + {.id = "OU", .getval = dvr_sub_strftime}, + {.id = "OV", .getval = dvr_sub_strftime}, + {.id = "Ow", .getval = dvr_sub_strftime}, + {.id = "OW", .getval = dvr_sub_strftime}, + {.id = "Oy", .getval = dvr_sub_strftime}, + + {.id = "p", .getval = dvr_sub_strftime}, /* AM/PM */ + {.id = "P", .getval = dvr_sub_strftime}, /* am/pm */ + {.id = "r", .getval = dvr_sub_strftime}, /* a.m./p.m. */ + {.id = "R", .getval = dvr_sub_strftime}, /* %H:%M */ + {.id = "s", .getval = dvr_sub_strftime}, /* The number of seconds since the Epoch */ + {.id = "S", .getval = dvr_sub_strftime}, /* The seconds (range 00 to 60) */ + {.id = "T", .getval = dvr_sub_strftime}, /* %H:%M:%S */ + {.id = "u", + .getval = + dvr_sub_strftime}, /* The day of the week as a decimal, range 1 to 7, Monday being 1 */ + {.id = "U", .getval = dvr_sub_strftime}, /* The week number of the current year as a decimal + number, range 00 to 53 (Sunday) */ + {.id = "V", .getval = dvr_sub_strftime}, /* The ISO 8601 week number (range 01 to 53) */ + {.id = "w", + .getval = + dvr_sub_strftime}, /* The day of the week as a decimal, range 0 to 6, Sunday being 0 */ + {.id = "W", .getval = dvr_sub_strftime}, /* The week number of the current year as a decimal + number, range 00 to 53 (Monday) */ + {.id = "x", .getval = dvr_sub_strftime}, /* The preferred date representation */ + {.id = "X", .getval = dvr_sub_strftime}, /* The preferred time representation */ + {.id = "y", + .getval = + dvr_sub_strftime}, /* The year as a decimal number without a century (range 00 to 99) */ + {.id = "Y", + .getval = dvr_sub_strftime}, /* The year as a decimal number including the century */ + {.id = "z", .getval = dvr_sub_strftime}, /* The +hhmm or -hhmm numeric timezone */ + {.id = "Z", .getval = dvr_sub_strftime}, /* The timezone name or abbreviation */ + + {.id = NULL, .getval = NULL}}; + +static const char* +dvr_sub_str(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + return (const char*)aux; } -static const char * -dvr_sub_str_separator(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - strlcpy(tmp, (const char *)aux, tmplen); +static const char* +dvr_sub_str_separator(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + strlcpy(tmp, (const char*)aux, tmplen); return dvr_clean_directory_separator(tmp, tmp, tmplen); } -static htsstr_substitute_t dvr_subs_extension[] = { - { .id = "x", .getval = dvr_sub_str_separator }, - { .id = NULL, .getval = NULL } -}; - -static htsstr_substitute_t dvr_subs_tally[] = { - { .id = "n", .getval = dvr_sub_str_separator }, - { .id = NULL, .getval = NULL } -}; - -static htsstr_substitute_t dvr_subs_postproc_entry[] = { - { .id = "t", .getval = dvr_sub_title }, - { .id = "s", .getval = dvr_sub_subtitle_or_summary }, - { .id = "u", .getval = dvr_sub_subtitle }, - { .id = "U", .getval = dvr_sub_uuid }, - { .id = "m", .getval = dvr_sub_summary }, - { .id = "p", .getval = dvr_sub_episode }, - { .id = "d", .getval = dvr_sub_description }, - { .id = "g", .getval = dvr_sub_genre }, - { .id = "c", .getval = dvr_sub_channel }, - { .id = "e", .getval = dvr_sub_last_error }, - { .id = "C", .getval = dvr_sub_creator }, - { .id = "O", .getval = dvr_sub_owner }, - { .id = "S", .getval = dvr_sub_start }, - { .id = "E", .getval = dvr_sub_stop }, - { .id = "r", .getval = dvr_sub_errors }, - { .id = "R", .getval = dvr_sub_data_errors }, - { .id = "Z", .getval = dvr_sub_comment }, - { .id = NULL, .getval = NULL } -}; - -static const char * -dvr_sub_basename(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - strlcpy(tmp, (const char *)aux, tmplen); +static htsstr_substitute_t dvr_subs_extension[] = {{.id = "x", .getval = dvr_sub_str_separator}, + {.id = NULL, .getval = NULL}}; + +static htsstr_substitute_t dvr_subs_tally[] = {{.id = "n", .getval = dvr_sub_str_separator}, + {.id = NULL, .getval = NULL}}; + +static htsstr_substitute_t dvr_subs_postproc_entry[] = {{.id = "t", .getval = dvr_sub_title}, + {.id = "s", .getval = dvr_sub_subtitle_or_summary}, + {.id = "u", .getval = dvr_sub_subtitle}, + {.id = "U", .getval = dvr_sub_uuid}, + {.id = "m", .getval = dvr_sub_summary}, + {.id = "p", .getval = dvr_sub_episode}, + {.id = "d", .getval = dvr_sub_description}, + {.id = "g", .getval = dvr_sub_genre}, + {.id = "c", .getval = dvr_sub_channel}, + {.id = "e", .getval = dvr_sub_last_error}, + {.id = "C", .getval = dvr_sub_creator}, + {.id = "O", .getval = dvr_sub_owner}, + {.id = "S", .getval = dvr_sub_start}, + {.id = "E", .getval = dvr_sub_stop}, + {.id = "r", .getval = dvr_sub_errors}, + {.id = "R", .getval = dvr_sub_data_errors}, + {.id = "Z", .getval = dvr_sub_comment}, + {.id = NULL, .getval = NULL}}; + +static const char* +dvr_sub_basename(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + strlcpy(tmp, (const char*)aux, tmplen); return basename(tmp); } -static htsstr_substitute_t dvr_subs_postproc_filename[] = { - { .id = "f", .getval = dvr_sub_str }, - { .id = "b", .getval = dvr_sub_basename }, - { .id = NULL, .getval = NULL } -}; +static htsstr_substitute_t dvr_subs_postproc_filename[] = {{.id = "f", .getval = dvr_sub_str}, + {.id = "b", .getval = dvr_sub_basename}, + {.id = NULL, .getval = NULL}}; -static const char * -dvr_sub_basic_info(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - htsmsg_t *info = (htsmsg_t *)aux, *e; - htsmsg_field_t *f; - const char *s; - size_t l = 0; +static const char* +dvr_sub_basic_info(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + htsmsg_t * info = (htsmsg_t*)aux, *e; + htsmsg_field_t* f; + const char* s; + size_t l = 0; if (info) info = htsmsg_get_list(info, "info"); @@ -978,20 +991,18 @@ dvr_sub_basic_info(const char *id, const char *fmt, const void *aux, char *tmp, tmp[0] = '\0'; HTSMSG_FOREACH(f, info) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if ((s = htsmsg_get_str(e, "type")) != NULL) tvh_strlcatf(tmp, tmplen, l, "%s%s", l > 0 ? "," : "", s); } return tmp; } -static htsstr_substitute_t dvr_subs_postproc_info[] = { - { .id = "i", .getval = dvr_sub_basic_info }, - { .id = NULL, .getval = NULL } -}; +static htsstr_substitute_t dvr_subs_postproc_info[] = {{.id = "i", .getval = dvr_sub_basic_info}, + {.id = NULL, .getval = NULL}}; -static char *dvr_find_last_path_component(char *path) -{ +static char* dvr_find_last_path_component(char* path) { char *res, *p; for (p = path, res = NULL; *p; p++) { if (*p == '\\') { @@ -1004,8 +1015,7 @@ static char *dvr_find_last_path_component(char *path) return res; } -static char *dvr_find_next_path_component(char *path) -{ +static char* dvr_find_next_path_component(char* path) { char *res, *p; for (p = res = path; *p; p++) { if (*p == '\\') { @@ -1025,24 +1035,22 @@ static char *dvr_find_next_path_component(char *path) * - avoid duplicate filenames * */ -static int -pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) -{ - char filename[PATH_MAX]; - char path[PATH_MAX + 1]; - char ptmp[PATH_MAX]; - char number[16]; - char tmp[MAX(PATH_MAX, 512)]; - char *lastpath = NULL; - int tally = 0; - struct stat st; - char *s, *x, *fmtstr, *dirsep; - struct tm tm; - dvr_config_t *cfg; - htsmsg_t *m; - size_t l, j, k; - long max; - int dir_dosubs; +static int pvr_generate_filename(dvr_entry_t* de, const streaming_start_t* ss) { + char filename[PATH_MAX]; + char path[PATH_MAX + 1]; + char ptmp[PATH_MAX]; + char number[16]; + char tmp[MAX(PATH_MAX, 512)]; + char* lastpath = NULL; + int tally = 0; + struct stat st; + char * s, *x, *fmtstr, *dirsep; + struct tm tm; + dvr_config_t* cfg; + htsmsg_t* m; + size_t l, j, k; + long max; + int dir_dosubs; if (de == NULL) return -1; @@ -1051,9 +1059,8 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) if (tvh_str_default(cfg->dvr_storage, NULL) == NULL) return -1; - dir_dosubs = de->de_directory == NULL || - (de->de_directory[0] == '$' && - de->de_directory[1] == '$'); + dir_dosubs = + de->de_directory == NULL || (de->de_directory[0] == '$' && de->de_directory[1] == '$'); localtime_r(&de->de_start, &tm); @@ -1065,12 +1072,12 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) } /* Remove trailing slash */ - while (l > 0 && path[l-1] == '/') + while (l > 0 && path[l - 1] == '/') path[--l] = '\0'; if (l + 1 >= sizeof(path)) l--; path[l++] = '/'; - path[l] = '\0'; + path[l] = '\0'; fmtstr = cfg->dvr_pathname; while (*fmtstr == '/') @@ -1087,7 +1094,14 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) else strcpy(filename, path + l); if (dir_dosubs) { - htsstr_substitute(de->de_directory+2, ptmp, sizeof(ptmp), '$', dvr_subs_entry, de, tmp, sizeof(tmp)); + htsstr_substitute(de->de_directory + 2, + ptmp, + sizeof(ptmp), + '$', + dvr_subs_entry, + de, + tmp, + sizeof(tmp)); } else { strlcpy(ptmp, de->de_directory, sizeof(ptmp)); } @@ -1095,7 +1109,7 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) while (*s == '/') s++; j = strlen(s); - while (j > 0 && s[j-1] == '/') + while (j > 0 && s[j - 1] == '/') j--; s[j] = '\0'; snprintf(path + l, sizeof(path) - l, "%s", s); @@ -1103,14 +1117,27 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) } /* Substitute time formatters */ - htsstr_substitute(path + l, filename, sizeof(filename), '%', dvr_subs_time, &tm, tmp, sizeof(tmp)); + htsstr_substitute(path + l, + filename, + sizeof(filename), + '%', + dvr_subs_time, + &tm, + tmp, + sizeof(tmp)); /* Substitute extension */ - htsstr_substitute(filename, path + l, sizeof(path) - l, '$', dvr_subs_extension, - muxer_suffix(de->de_chain->prch_muxer, ss) ?: "", tmp, sizeof(tmp)); + htsstr_substitute(filename, + path + l, + sizeof(path) - l, + '$', + dvr_subs_extension, + muxer_suffix(de->de_chain->prch_muxer, ss) ?: "", + tmp, + sizeof(tmp)); /* Cleanup all directory names */ - x = path + l; + x = path + l; filename[j = 0] = '\0'; while (1) { dirsep = dvr_find_next_path_component(x); @@ -1134,14 +1161,13 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) dirsep++; } else { if (l > 0) { - assert(path[l-1] == '/'); - path[l-1] = '\0'; + assert(path[l - 1] == '/'); + path[l - 1] = '\0'; } dirsep = path + l; } htsstr_unescape_to(path, filename, sizeof(filename)); - if (makedirs(LS_DVR, filename, - cfg->dvr_muxcnf.m_directory_permissions, 0, -1, -1) != 0) + if (makedirs(LS_DVR, filename, cfg->dvr_muxcnf.m_directory_permissions, 0, -1, -1) != 0) return -1; max = pathconf(filename, _PC_NAME_MAX); if (max < 8) @@ -1167,16 +1193,16 @@ pvr_generate_filename(dvr_entry_t *de, const streaming_start_t *ss) l = strlen(number); k = strlen(filename + j); if (l + k > max) { - s = (char *)htsstr_substitute_find(filename + j, '$'); + s = (char*)htsstr_substitute_find(filename + j, '$'); if (s == NULL || s - (filename + j) < (l + k) - max) { -cut1: + cut1: l = j + (max - l); if (filename[l - 1] == '$') /* not optimal */ filename[l + 1] = '\0'; else filename[l] = '\0'; } else { - x = (char *)htsstr_escape_find(filename + j, s - (filename + j) - ((l + k) - max)); + x = (char*)htsstr_escape_find(filename + j, s - (filename + j) - ((l + k) - max)); if (x == NULL) goto cut1; k = strlen(s); @@ -1185,7 +1211,14 @@ cut1: } } - htsstr_substitute(filename + j, ptmp, sizeof(ptmp), '$', dvr_subs_tally, number, tmp, sizeof(tmp)); + htsstr_substitute(filename + j, + ptmp, + sizeof(ptmp), + '$', + dvr_subs_tally, + number, + tmp, + sizeof(tmp)); s = cleanup_filename(cfg, ptmp, 1); if (s == NULL) { free(lastpath); @@ -1207,8 +1240,7 @@ cut1: } if (stat(path, &st) == -1) { - tvhdebug(LS_DVR, "File \"%s\" -- %s -- Using for recording", - path, strerror(errno)); + tvhdebug(LS_DVR, "File \"%s\" -- %s -- Using for recording", path, strerror(errno)); break; } @@ -1232,9 +1264,7 @@ cut1: /** * */ -static void -dvr_rec_fatal_error(dvr_entry_t *de, const char *fmt, ...) -{ +static void dvr_rec_fatal_error(dvr_entry_t* de, const char* fmt, ...) { char msgbuf[256]; va_list ap; @@ -1243,16 +1273,16 @@ dvr_rec_fatal_error(dvr_entry_t *de, const char *fmt, ...) vsnprintf(msgbuf, sizeof(msgbuf), fmt, ap); va_end(ap); - tvherror(LS_DVR, "Recording error: \"%s\": %s", - dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL), msgbuf); + tvherror(LS_DVR, + "Recording error: \"%s\": %s", + dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL), + msgbuf); } /** * */ -static void -dvr_notify(dvr_entry_t *de) -{ +static void dvr_notify(dvr_entry_t* de) { if (de->de_last_notify + sec2mono(5) < mclk()) { idnode_notify_changed(&de->de_id); de->de_last_notify = mclk(); @@ -1263,9 +1293,7 @@ dvr_notify(dvr_entry_t *de) /** * */ -static void -dvr_rec_set_state(dvr_entry_t *de, dvr_rs_state_t newstate, int error) -{ +static void dvr_rec_set_state(dvr_entry_t* de, dvr_rs_state_t newstate, int error) { if (de->de_last_error != error && error) de->de_errors++; dvr_entry_set_state(de, de->de_sched_state, newstate, error); @@ -1274,20 +1302,18 @@ dvr_rec_set_state(dvr_entry_t *de, dvr_rs_state_t newstate, int error) /** * */ -static int -dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss) -{ - const source_info_t *si = &ss->ss_si; - streaming_start_t *ss_copy; - const streaming_start_component_t *ssc; - char res[14], asp[14], sr[6], ch[7]; - dvr_config_t *cfg = de->de_config; - profile_chain_t *prch = de->de_chain; - htsmsg_t *info, *e; - htsmsg_field_t *f; - muxer_t *muxer; - struct stat st; - int i; +static int dvr_rec_start(dvr_entry_t* de, const streaming_start_t* ss) { + const source_info_t* si = &ss->ss_si; + streaming_start_t* ss_copy; + const streaming_start_component_t* ssc; + char res[14], asp[14], sr[6], ch[7]; + dvr_config_t* cfg = de->de_config; + profile_chain_t* prch = de->de_chain; + htsmsg_t * info, *e; + htsmsg_field_t* f; + muxer_t* muxer; + struct stat st; + int i; if (!cfg) { dvr_rec_fatal_error(de, "Unable to determine config profile"); @@ -1317,17 +1343,17 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss) muxer = prch->prch_muxer; } - if(!muxer) { + if (!muxer) { dvr_rec_fatal_error(de, "Unable to create muxer"); return -1; } - if(pvr_generate_filename(de, ss) != 0) { + if (pvr_generate_filename(de, ss) != 0) { dvr_rec_fatal_error(de, "Unable to create file"); return -1; } - if(muxer_open_file(muxer, dvr_get_filename(de))) { + if (muxer_open_file(muxer, dvr_get_filename(de))) { dvr_rec_fatal_error(de, "Unable to open file"); return -1; } @@ -1336,87 +1362,85 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss) ss_copy = streaming_start_copy(ss); - if(muxer_init(muxer, ss_copy, lang_str_get(de->de_title, NULL))) { + if (muxer_init(muxer, ss_copy, lang_str_get(de->de_title, NULL))) { dvr_rec_fatal_error(de, "Unable to init file"); goto _err; } - if(cfg->dvr_tag_files) { - if(muxer_write_meta(muxer, de->de_bcast, de->de_comment)) { + if (cfg->dvr_tag_files) { + if (muxer_write_meta(muxer, de->de_bcast, de->de_comment)) { dvr_rec_fatal_error(de, "Unable to write meta data"); goto _err; } } - tvhinfo(LS_DVR, "%s from " - "adapter: \"%s\", " - "network: \"%s\", mux: \"%s\", provider: \"%s\", " - "service: \"%s\"", - - dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL), - si->si_adapter ?: "", - si->si_network ?: "", - si->si_mux ?: "", - si->si_provider ?: "", - si->si_service ?: ""); - + tvhinfo(LS_DVR, + "%s from " + "adapter: \"%s\", " + "network: \"%s\", mux: \"%s\", provider: \"%s\", " + "service: \"%s\"", + + dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL), + si->si_adapter ?: "", + si->si_network ?: "", + si->si_mux ?: "", + si->si_provider ?: "", + si->si_service ?: ""); tvhinfo(LS_DVR, - " # %-16s %-4s %-10s %-12s %-11s %-8s", - "type", - "lang", - "resolution", - "aspect ratio", - "sample rate", - "channels"); + " # %-16s %-4s %-10s %-12s %-11s %-8s", + "type", + "lang", + "resolution", + "aspect ratio", + "sample rate", + "channels"); info = htsmsg_create_list(); - for(i = 0; i < ss_copy->ss_num_components; i++) { + for (i = 0; i < ss_copy->ss_num_components; i++) { ssc = &ss_copy->ss_components[i]; - if(ssc->ssc_muxer_disabled) + if (ssc->ssc_muxer_disabled) continue; e = htsmsg_create_map(); htsmsg_add_str(e, "type", streaming_component_type2txt(ssc->es_type)); if (ssc->es_lang[0]) - htsmsg_add_str(e, "language", ssc->es_lang); + htsmsg_add_str(e, "language", ssc->es_lang); - if(SCT_ISAUDIO(ssc->es_type)) { + if (SCT_ISAUDIO(ssc->es_type)) { htsmsg_add_u32(e, "audio_type", ssc->es_audio_type); - if(ssc->es_audio_version) + if (ssc->es_audio_version) htsmsg_add_u32(e, "audio_version", ssc->es_audio_version); - if(ssc->es_sri < 16) - snprintf(sr, sizeof(sr), "%d", sri_to_rate(ssc->es_sri)); + if (ssc->es_sri < 16) + snprintf(sr, sizeof(sr), "%d", sri_to_rate(ssc->es_sri)); else - strcpy(sr, "?"); + strcpy(sr, "?"); - if(ssc->es_channels == 6) - snprintf(ch, sizeof(ch), "5.1"); - else if(ssc->es_channels == 0) - strcpy(ch, "?"); + if (ssc->es_channels == 6) + snprintf(ch, sizeof(ch), "5.1"); + else if (ssc->es_channels == 0) + strcpy(ch, "?"); else - snprintf(ch, sizeof(ch), "%d", ssc->es_channels); + snprintf(ch, sizeof(ch), "%d", ssc->es_channels); } else { sr[0] = ch[0] = 0; } - if(SCT_ISVIDEO(ssc->es_type)) { - if(ssc->es_width && ssc->es_height) - snprintf(res, sizeof(res), "%dx%d", - ssc->es_width, ssc->es_height); + if (SCT_ISVIDEO(ssc->es_type)) { + if (ssc->es_width && ssc->es_height) + snprintf(res, sizeof(res), "%dx%d", ssc->es_width, ssc->es_height); else - strcpy(res, "?"); + strcpy(res, "?"); - if(ssc->es_aspect_num && ssc->es_aspect_den) - snprintf(asp, sizeof(asp), "%d:%d", - ssc->es_aspect_num, ssc->es_aspect_den); + if (ssc->es_aspect_num && ssc->es_aspect_den) + snprintf(asp, sizeof(asp), "%d:%d", ssc->es_aspect_num, ssc->es_aspect_den); else - strcpy(asp, "?"); + strcpy(asp, "?"); - htsmsg_add_u32(e, "width", ssc->es_width); - htsmsg_add_u32(e, "height", ssc->es_height); - htsmsg_add_u32(e, "duration", ssc->es_frame_duration); + htsmsg_add_u32(e, "width", ssc->es_width); + htsmsg_add_u32(e, "height", ssc->es_height); + htsmsg_add_u32(e, "duration", ssc->es_frame_duration); htsmsg_add_u32(e, "aspect_num", ssc->es_aspect_num); htsmsg_add_u32(e, "aspect_den", ssc->es_aspect_den); } else { @@ -1425,27 +1449,26 @@ dvr_rec_start(dvr_entry_t *de, const streaming_start_t *ss) if (SCT_ISSUBTITLE(ssc->es_type)) { htsmsg_add_u32(e, "composition_id", ssc->es_composition_id); - htsmsg_add_u32(e, "ancillary_id", ssc->es_ancillary_id); + htsmsg_add_u32(e, "ancillary_id", ssc->es_ancillary_id); } tvhinfo(LS_DVR, - "%2d %-16s %-4s %-10s %-12s %-11s %-8s %s", - ssc->es_index, - streaming_component_type2txt(ssc->es_type), - ssc->es_lang, - res, - asp, - sr, - ch, - ssc->ssc_disabled ? "" : ""); + "%2d %-16s %-4s %-10s %-12s %-11s %-8s %s", + ssc->es_index, + streaming_component_type2txt(ssc->es_type), + ssc->es_lang, + res, + asp, + sr, + ch, + ssc->ssc_disabled ? "" : ""); htsmsg_add_msg(info, NULL, e); } streaming_start_unref(ss_copy); /* update the info field for a filename */ - if ((f = htsmsg_field_last(de->de_files)) != NULL && - (e = htsmsg_field_get_map(f)) != NULL) { + if ((f = htsmsg_field_last(de->de_files)) != NULL && (e = htsmsg_field_get_map(f)) != NULL) { htsmsg_set_msg(e, "info", info); htsmsg_set_s64(e, "start", gclk()); } else { @@ -1461,9 +1484,7 @@ _err: /** * */ -static inline int -dvr_thread_global_lock(dvr_entry_t *de, int *run) -{ +static inline int dvr_thread_global_lock(dvr_entry_t* de, int* run) { if (atomic_add(&de->de_thread_shutdown, 1) > 0) { *run = 0; return 0; @@ -1475,9 +1496,7 @@ dvr_thread_global_lock(dvr_entry_t *de, int *run) /** * */ -static inline void -dvr_thread_global_unlock(dvr_entry_t *de) -{ +static inline void dvr_thread_global_unlock(dvr_entry_t* de) { tvh_mutex_unlock(&global_lock); atomic_dec(&de->de_thread_shutdown, 1); } @@ -1485,9 +1504,7 @@ dvr_thread_global_unlock(dvr_entry_t *de) /** * */ -static void -dvr_streaming_restart(dvr_entry_t *de, int *run) -{ +static void dvr_streaming_restart(dvr_entry_t* de, int* run) { if (dvr_thread_global_lock(de, run)) { service_restart(de->de_s->ths_service); dvr_thread_global_unlock(de); @@ -1497,11 +1514,9 @@ dvr_streaming_restart(dvr_entry_t *de, int *run) /** * */ -static int -dvr_thread_pkt_stats(dvr_entry_t *de, th_pkt_t *pkt, int payload) -{ - th_subscription_t *ts; - int ret = 0; +static int dvr_thread_pkt_stats(dvr_entry_t* de, th_pkt_t* pkt, int payload) { + th_subscription_t* ts; + int ret = 0; if ((ts = de->de_s) != NULL) { if (pkt->pkt_err) { @@ -1517,12 +1532,10 @@ dvr_thread_pkt_stats(dvr_entry_t *de, th_pkt_t *pkt, int payload) /** * */ -static int -dvr_thread_mpegts_stats(dvr_entry_t *de, void *sm_data) -{ - th_subscription_t *ts; - pktbuf_t *pb = sm_data; - int ret = 0; +static int dvr_thread_mpegts_stats(dvr_entry_t* de, void* sm_data) { + th_subscription_t* ts; + pktbuf_t* pb = sm_data; + int ret = 0; if (pb) { if ((ts = de->de_s) != NULL) { @@ -1539,31 +1552,33 @@ dvr_thread_mpegts_stats(dvr_entry_t *de, void *sm_data) /** * */ -static int -dvr_thread_rec_start(dvr_entry_t **_de, streaming_start_t *ss, - int *run, int *started, int64_t *dts_offset, - const char *postproc) -{ - dvr_entry_t *de = *_de; - profile_chain_t *prch = de->de_chain; - int ret = 0; +static int dvr_thread_rec_start(dvr_entry_t** _de, + streaming_start_t* ss, + int* run, + int* started, + int64_t* dts_offset, + const char* postproc) { + dvr_entry_t* de = *_de; + profile_chain_t* prch = de->de_chain; + int ret = 0; if (*started) { if (muxer_reconfigure(prch->prch_muxer, ss) >= 0) return 1; - tvhwarn(LS_DVR, "Unable to reconfigure \"%s\"", - dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL)); + tvhwarn(LS_DVR, + "Unable to reconfigure \"%s\"", + dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL)); // Try to restart the recording if the muxer doesn't // support reconfiguration of the streams. if (!dvr_thread_global_lock(de, run)) { *dts_offset = PTS_UNSET; - *started = 0; + *started = 0; return 0; } dvr_thread_epilog(de, postproc); *dts_offset = PTS_UNSET; - *started = 0; + *started = 0; if (de->de_config->dvr_clone) *_de = dvr_entry_clone(de); dvr_thread_global_unlock(de); @@ -1578,14 +1593,18 @@ dvr_thread_rec_start(dvr_entry_t **_de, streaming_start_t *ss, /* Persist entry so we save the filename details to avoid orphan * files if we crash before the programme completes recording. */ - de->de_rating_label = NULL; //Forget the rating label pointer and only rely on the saved values from here on. + de->de_rating_label = + NULL; // Forget the rating label pointer and only rely on the saved values from here on. dvr_entry_changed(de); htsp_dvr_entry_update(de); - if(code == 0) { - ret = 1; + if (code == 0) { + ret = 1; *started = 1; } else - dvr_stop_recording(de, code == SM_CODE_NO_SPACE ? SM_CODE_NO_SPACE : SM_CODE_INVALID_TARGET, 1, 0); + dvr_stop_recording(de, + code == SM_CODE_NO_SPACE ? SM_CODE_NO_SPACE : SM_CODE_INVALID_TARGET, + 1, + 0); dvr_thread_global_unlock(de); } return ret; @@ -1594,14 +1613,9 @@ dvr_thread_rec_start(dvr_entry_t **_de, streaming_start_t *ss, /** * */ -static inline int -dts_pts_valid(th_pkt_t *pkt, int64_t dts_offset) -{ - if (pkt->pkt_dts == PTS_UNSET || - pkt->pkt_pts == PTS_UNSET || - dts_offset == PTS_UNSET || - pkt->pkt_dts < dts_offset || - pkt->pkt_pts < dts_offset) +static inline int dts_pts_valid(th_pkt_t* pkt, int64_t dts_offset) { + if (pkt->pkt_dts == PTS_UNSET || pkt->pkt_pts == PTS_UNSET || dts_offset == PTS_UNSET || + pkt->pkt_dts < dts_offset || pkt->pkt_pts < dts_offset) return 0; return 1; } @@ -1609,12 +1623,10 @@ dts_pts_valid(th_pkt_t *pkt, int64_t dts_offset) /** * */ -static int64_t -get_dts_ref(th_pkt_t *pkt, streaming_start_t *ss) -{ - const streaming_start_component_t *ssc; - int64_t audio = PTS_UNSET; - int i; +static int64_t get_dts_ref(th_pkt_t* pkt, streaming_start_t* ss) { + const streaming_start_component_t* ssc; + int64_t audio = PTS_UNSET; + int i; if (pkt->pkt_dts == PTS_UNSET) return PTS_UNSET; @@ -1633,42 +1645,42 @@ get_dts_ref(th_pkt_t *pkt, streaming_start_t *ss) /** * */ -static void * -dvr_thread(void *aux) -{ - dvr_entry_t *de = aux; - profile_chain_t *prch = de->de_chain; - streaming_queue_t *sq = &prch->prch_sq; +static void* dvr_thread(void* aux) { + dvr_entry_t* de = aux; + profile_chain_t* prch = de->de_chain; + streaming_queue_t* sq = &prch->prch_sq; struct streaming_message_queue backlog; - streaming_message_t *sm, *sm2; - th_pkt_t *pkt, *pkt2, *pkt3; - streaming_start_t *ss = NULL; - int run = 1, started = 0, muxing = 0, comm_skip, rs; - int epg_running = 0, old_epg_running, epg_pause = 0; - int commercial = COMMERCIAL_UNKNOWN; - int running_disabled; - int64_t packets = 0, dts_offset = PTS_UNSET; + streaming_message_t * sm, *sm2; + th_pkt_t * pkt, *pkt2, *pkt3; + streaming_start_t* ss = NULL; + int run = 1, started = 0, muxing = 0, comm_skip, rs; + int epg_running = 0, old_epg_running, epg_pause = 0; + int commercial = COMMERCIAL_UNKNOWN; + int running_disabled; + int64_t packets = 0, dts_offset = PTS_UNSET; time_t now, real_start, start_time = 0, running_start = 0, running_stop = 0; - char *postproc; - char ubuf[UUID_HEX_SIZE]; + char* postproc; + char ubuf[UUID_HEX_SIZE]; if (!dvr_thread_global_lock(de, &run)) return NULL; - comm_skip = de->de_config->dvr_skip_commercials; - postproc = de->de_config->dvr_postproc ? strdup(de->de_config->dvr_postproc) : NULL; + comm_skip = de->de_config->dvr_skip_commercials; + postproc = de->de_config->dvr_postproc ? strdup(de->de_config->dvr_postproc) : NULL; running_disabled = dvr_entry_get_epg_running(de) <= 0; - real_start = dvr_entry_get_start_time(de, 0); - tvhtrace(LS_DVR, "%s - recoding thread started for \"%s\"", - idnode_uuid_as_str(&de->de_id, ubuf), lang_str_get(de->de_title, NULL)); + real_start = dvr_entry_get_start_time(de, 0); + tvhtrace(LS_DVR, + "%s - recoding thread started for \"%s\"", + idnode_uuid_as_str(&de->de_id, ubuf), + lang_str_get(de->de_title, NULL)); if (!running_disabled && de->de_bcast) { now = gclk(); switch (de->de_bcast->running) { - case EPG_RUNNING_PAUSE: - atomic_set_time_t(&de->de_running_pause, now); - /* fall through */ - case EPG_RUNNING_NOW: - atomic_set_time_t(&de->de_running_start, now); - break; + case EPG_RUNNING_PAUSE: + atomic_set_time_t(&de->de_running_pause, now); + /* fall through */ + case EPG_RUNNING_NOW: + atomic_set_time_t(&de->de_running_start, now); + break; } } dvr_thread_global_unlock(de); @@ -1676,9 +1688,9 @@ dvr_thread(void *aux) TAILQ_INIT(&backlog); tvh_mutex_lock(&sq->sq_mutex); - while(run) { + while (run) { sm = TAILQ_FIRST(&sq->sq_queue); - if(sm == NULL) { + if (sm == NULL) { tvh_cond_wait(&sq->sq_cond, &sq->sq_mutex); continue; } @@ -1708,222 +1720,234 @@ dvr_thread(void *aux) } } if (epg_running != old_epg_running) - tvhtrace(LS_DVR, "%s - running flag changed from %d to %d", - idnode_uuid_as_str(&de->de_id, ubuf), old_epg_running, epg_running); + tvhtrace(LS_DVR, + "%s - running flag changed from %d to %d", + idnode_uuid_as_str(&de->de_id, ubuf), + old_epg_running, + epg_running); tvh_mutex_unlock(&sq->sq_mutex); - switch(sm->sm_type) { + switch (sm->sm_type) { - case SMT_PACKET: - pkt = sm->sm_data; + case SMT_PACKET: + pkt = sm->sm_data; - rs = DVR_RS_RUNNING; - if (!epg_running) - rs = DVR_RS_EPG_WAIT; - else if (pkt->pkt_commercial == COMMERCIAL_YES || epg_running == 2) - rs = DVR_RS_COMMERCIAL; - dvr_rec_set_state(de, rs, 0); + rs = DVR_RS_RUNNING; + if (!epg_running) + rs = DVR_RS_EPG_WAIT; + else if (pkt->pkt_commercial == COMMERCIAL_YES || epg_running == 2) + rs = DVR_RS_COMMERCIAL; + dvr_rec_set_state(de, rs, 0); - if ((rs == DVR_RS_COMMERCIAL && comm_skip) || !epg_running) { - if (ss && packets && running_start == 0) { - dvr_streaming_restart(de, &run); - packets = 0; - started = 0; + if ((rs == DVR_RS_COMMERCIAL && comm_skip) || !epg_running) { + if (ss && packets && running_start == 0) { + dvr_streaming_restart(de, &run); + packets = 0; + started = 0; + } + break; } - break; - } - - if (epg_pause != (epg_running == 2)) { - epg_pause = epg_running == 2; - if (muxing) muxer_add_marker(prch->prch_muxer); - } else if (commercial != pkt->pkt_commercial) { - commercial = pkt->pkt_commercial; - if (muxing) muxer_add_marker(prch->prch_muxer); - } else if (atomic_exchange(&de->de_running_change, 0)) { - if (muxing) muxer_add_marker(prch->prch_muxer); - } - if (ss == NULL) - break; + if (epg_pause != (epg_running == 2)) { + epg_pause = epg_running == 2; + if (muxing) + muxer_add_marker(prch->prch_muxer); + } else if (commercial != pkt->pkt_commercial) { + commercial = pkt->pkt_commercial; + if (muxing) + muxer_add_marker(prch->prch_muxer); + } else if (atomic_exchange(&de->de_running_change, 0)) { + if (muxing) + muxer_add_marker(prch->prch_muxer); + } - if (muxing == 0) { - if (!dvr_thread_rec_start(&de, ss, &run, &started, &dts_offset, postproc)) + if (ss == NULL) break; - tvhtrace(LS_DVR, "%s - muxing activated", idnode_uuid_as_str(&de->de_id, ubuf)); - } - muxing = 1; - while ((sm2 = TAILQ_FIRST(&backlog)) != NULL) { - TAILQ_REMOVE(&backlog, sm2, sm_link); - pkt2 = sm2->sm_data; - if (pkt2->pkt_dts != PTS_UNSET) { - if (dts_offset == PTS_UNSET) - dts_offset = get_dts_ref(pkt2, ss); - if (dts_pts_valid(pkt2, dts_offset)) { - pkt3 = pkt_copy_shallow(pkt2); - pkt3->pkt_dts -= dts_offset; - if (pkt3->pkt_pts != PTS_UNSET) - pkt3->pkt_pts -= dts_offset; - dvr_thread_pkt_stats(de, pkt3, 1); - muxer_write_pkt(prch->prch_muxer, sm2->sm_type, pkt3); - } else { - dvr_thread_pkt_stats(de, pkt2, 0); - } + if (muxing == 0) { + if (!dvr_thread_rec_start(&de, ss, &run, &started, &dts_offset, postproc)) + break; + tvhtrace(LS_DVR, "%s - muxing activated", idnode_uuid_as_str(&de->de_id, ubuf)); } - streaming_msg_free(sm2); - } - if (dts_offset == PTS_UNSET) - dts_offset = get_dts_ref(pkt, ss); - if (dts_pts_valid(pkt, dts_offset)) { - pkt3 = pkt_copy_shallow(pkt); - pkt3->pkt_dts -= dts_offset; - if (pkt3->pkt_pts != PTS_UNSET) - pkt3->pkt_pts -= dts_offset; - dvr_thread_pkt_stats(de, pkt3, 1); - muxer_write_pkt(prch->prch_muxer, sm->sm_type, pkt3); - } else { - dvr_thread_pkt_stats(de, pkt, 0); - } - dvr_notify(de); - packets++; - break; - - case SMT_MPEGTS: - rs = DVR_RS_RUNNING; - if (!epg_running) - rs = DVR_RS_EPG_WAIT; - else if (epg_running == 2) - rs = DVR_RS_COMMERCIAL; - dvr_rec_set_state(de, rs, 0); - - if (ss == NULL) - break; - if ((rs == DVR_RS_COMMERCIAL && comm_skip) || !epg_running) { - if (packets && running_start == 0) { - dvr_streaming_restart(de, &run); - packets = 0; - started = 0; + muxing = 1; + while ((sm2 = TAILQ_FIRST(&backlog)) != NULL) { + TAILQ_REMOVE(&backlog, sm2, sm_link); + pkt2 = sm2->sm_data; + if (pkt2->pkt_dts != PTS_UNSET) { + if (dts_offset == PTS_UNSET) + dts_offset = get_dts_ref(pkt2, ss); + if (dts_pts_valid(pkt2, dts_offset)) { + pkt3 = pkt_copy_shallow(pkt2); + pkt3->pkt_dts -= dts_offset; + if (pkt3->pkt_pts != PTS_UNSET) + pkt3->pkt_pts -= dts_offset; + dvr_thread_pkt_stats(de, pkt3, 1); + muxer_write_pkt(prch->prch_muxer, sm2->sm_type, pkt3); + } else { + dvr_thread_pkt_stats(de, pkt2, 0); + } + } + streaming_msg_free(sm2); + } + if (dts_offset == PTS_UNSET) + dts_offset = get_dts_ref(pkt, ss); + if (dts_pts_valid(pkt, dts_offset)) { + pkt3 = pkt_copy_shallow(pkt); + pkt3->pkt_dts -= dts_offset; + if (pkt3->pkt_pts != PTS_UNSET) + pkt3->pkt_pts -= dts_offset; + dvr_thread_pkt_stats(de, pkt3, 1); + muxer_write_pkt(prch->prch_muxer, sm->sm_type, pkt3); + } else { + dvr_thread_pkt_stats(de, pkt, 0); } + dvr_notify(de); + packets++; break; - } - if (epg_pause != (epg_running == 2)) { - epg_pause = epg_running == 2; - if (muxing) muxer_add_marker(prch->prch_muxer); - } else if (atomic_exchange(&de->de_running_change, 0)) { - if (muxing) muxer_add_marker(prch->prch_muxer); - } + case SMT_MPEGTS: + rs = DVR_RS_RUNNING; + if (!epg_running) + rs = DVR_RS_EPG_WAIT; + else if (epg_running == 2) + rs = DVR_RS_COMMERCIAL; + dvr_rec_set_state(de, rs, 0); - if (muxing == 0) { - if (!dvr_thread_rec_start(&de, ss, &run, &started, &dts_offset, postproc)) + if (ss == NULL) break; - tvhtrace(LS_DVR, "%s - muxing activated", idnode_uuid_as_str(&de->de_id, ubuf)); - } - muxing = 1; - while ((sm2 = TAILQ_FIRST(&backlog)) != NULL) { - TAILQ_REMOVE(&backlog, sm2, sm_link); - dvr_thread_mpegts_stats(de, sm2->sm_data); - muxer_write_pkt(prch->prch_muxer, sm2->sm_type, sm2->sm_data); - sm2->sm_data = NULL; - streaming_msg_free(sm2); - } - dvr_thread_mpegts_stats(de, sm->sm_data); - muxer_write_pkt(prch->prch_muxer, sm->sm_type, sm->sm_data); - sm->sm_data = NULL; - dvr_notify(de); - packets++; - break; - - case SMT_START: - start_time = gclk(); - packets = 0; - if (ss) - streaming_start_unref(ss); - ss = streaming_start_copy((streaming_start_t *)sm->sm_data); - break; - - case SMT_STOP: - if (sm->sm_code == SM_CODE_SOURCE_RECONFIGURED) { - // Subscription is restarting, wait for SMT_START - if (muxing) - tvhtrace(LS_DVR, "%s - source reconfigured", idnode_uuid_as_str(&de->de_id, ubuf)); - muxing = 0; // reconfigure muxer - - } else if(sm->sm_code == 0) { - // Recording is completed + if ((rs == DVR_RS_COMMERCIAL && comm_skip) || !epg_running) { + if (packets && running_start == 0) { + dvr_streaming_restart(de, &run); + packets = 0; + started = 0; + } + break; + } - dvr_entry_set_state(de, de->de_sched_state, de->de_rec_state, SM_CODE_OK); - tvhinfo(LS_DVR, "Recording completed: \"%s\"", - dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL)); + if (epg_pause != (epg_running == 2)) { + epg_pause = epg_running == 2; + if (muxing) + muxer_add_marker(prch->prch_muxer); + } else if (atomic_exchange(&de->de_running_change, 0)) { + if (muxing) + muxer_add_marker(prch->prch_muxer); + } - goto fin; + if (muxing == 0) { + if (!dvr_thread_rec_start(&de, ss, &run, &started, &dts_offset, postproc)) + break; + tvhtrace(LS_DVR, "%s - muxing activated", idnode_uuid_as_str(&de->de_id, ubuf)); + } - } else if (de->de_last_error != sm->sm_code) { - // Error during recording + muxing = 1; + while ((sm2 = TAILQ_FIRST(&backlog)) != NULL) { + TAILQ_REMOVE(&backlog, sm2, sm_link); + dvr_thread_mpegts_stats(de, sm2->sm_data); + muxer_write_pkt(prch->prch_muxer, sm2->sm_type, sm2->sm_data); + sm2->sm_data = NULL; + streaming_msg_free(sm2); + } + dvr_thread_mpegts_stats(de, sm->sm_data); + muxer_write_pkt(prch->prch_muxer, sm->sm_type, sm->sm_data); + sm->sm_data = NULL; + dvr_notify(de); + packets++; + break; - dvr_rec_set_state(de, DVR_RS_ERROR, sm->sm_code); - tvherror(LS_DVR, "Recording stopped: \"%s\": %s", - dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL), - streaming_code2txt(sm->sm_code)); + case SMT_START: + start_time = gclk(); + packets = 0; + if (ss) + streaming_start_unref(ss); + ss = streaming_start_copy((streaming_start_t*)sm->sm_data); + break; -fin: - streaming_queue_clear(&backlog); - if (!dvr_thread_global_lock(de, &run)) - break; - dvr_thread_epilog(de, postproc); - dvr_thread_global_unlock(de); - start_time = 0; - started = 0; - muxing = 0; - if (ss) { - streaming_start_unref(ss); - ss = NULL; + case SMT_STOP: + if (sm->sm_code == SM_CODE_SOURCE_RECONFIGURED) { + // Subscription is restarting, wait for SMT_START + if (muxing) + tvhtrace(LS_DVR, "%s - source reconfigured", idnode_uuid_as_str(&de->de_id, ubuf)); + muxing = 0; // reconfigure muxer + + } else if (sm->sm_code == 0) { + // Recording is completed + + dvr_entry_set_state(de, de->de_sched_state, de->de_rec_state, SM_CODE_OK); + tvhinfo(LS_DVR, + "Recording completed: \"%s\"", + dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL)); + + goto fin; + + } else if (de->de_last_error != sm->sm_code) { + // Error during recording + + dvr_rec_set_state(de, DVR_RS_ERROR, sm->sm_code); + tvherror(LS_DVR, + "Recording stopped: \"%s\": %s", + dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL), + streaming_code2txt(sm->sm_code)); + + fin: + streaming_queue_clear(&backlog); + if (!dvr_thread_global_lock(de, &run)) + break; + dvr_thread_epilog(de, postproc); + dvr_thread_global_unlock(de); + start_time = 0; + started = 0; + muxing = 0; + if (ss) { + streaming_start_unref(ss); + ss = NULL; + } } - } - break; + break; - case SMT_SERVICE_STATUS: - if (sm->sm_code & TSS_PACKETS) { + case SMT_SERVICE_STATUS: + if (sm->sm_code & TSS_PACKETS) { - } else if (sm->sm_code & TSS_ERRORS) { + } else if (sm->sm_code & TSS_ERRORS) { - int code = tss2errcode(sm->sm_code); + int code = tss2errcode(sm->sm_code); - if(de->de_last_error != code) { - dvr_rec_set_state(de, DVR_RS_ERROR, code); - tvherror(LS_DVR, "Streaming error: \"%s\": %s", - dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL), - streaming_code2txt(code)); - } - } - break; + if (de->de_last_error != code) { + dvr_rec_set_state(de, DVR_RS_ERROR, code); + tvherror(LS_DVR, + "Streaming error: \"%s\": %s", + dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL), + streaming_code2txt(code)); + } + } + break; - case SMT_NOSTART: + case SMT_NOSTART: - if (de->de_last_error != sm->sm_code) { - dvr_rec_set_state(de, DVR_RS_PENDING, sm->sm_code); + if (de->de_last_error != sm->sm_code) { + dvr_rec_set_state(de, DVR_RS_PENDING, sm->sm_code); - tvherror(LS_DVR, "Recording unable to start: \"%s\": %s", - dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL), - streaming_code2txt(sm->sm_code)); - } - break; + tvherror(LS_DVR, + "Recording unable to start: \"%s\": %s", + dvr_get_filename(de) ?: lang_str_get(de->de_title, NULL), + streaming_code2txt(sm->sm_code)); + } + break; - case SMT_GRACE: - case SMT_NOSTART_WARN: - case SMT_SPEED: - case SMT_SKIP: - case SMT_SIGNAL_STATUS: - case SMT_TIMESHIFT_STATUS: - case SMT_DESCRAMBLE_INFO: - break; + case SMT_GRACE: + case SMT_NOSTART_WARN: + case SMT_SPEED: + case SMT_SKIP: + case SMT_SIGNAL_STATUS: + case SMT_TIMESHIFT_STATUS: + case SMT_DESCRAMBLE_INFO: + break; - case SMT_EXIT: - run = 0; - break; + case SMT_EXIT: + run = 0; + break; } streaming_msg_free(sm); @@ -1942,18 +1966,15 @@ fin: /** * */ -void -dvr_spawn_cmd(dvr_entry_t *de, const char *cmd, const char *filename, int pre) -{ - char buf1[MAX(PATH_MAX, 2048)], *buf2; - char tmp[MAX(PATH_MAX, 512)]; - htsmsg_t *info = NULL, *e; - htsmsg_field_t *f; - char **args; +void dvr_spawn_cmd(dvr_entry_t* de, const char* cmd, const char* filename, int pre) { + char buf1[MAX(PATH_MAX, 2048)], *buf2; + char tmp[MAX(PATH_MAX, 512)]; + htsmsg_t * info = NULL, *e; + htsmsg_field_t* f; + char** args; if (!pre) { - if ((f = htsmsg_field_last(de->de_files)) != NULL && - (e = htsmsg_field_get_map(f)) != NULL) { + if ((f = htsmsg_field_last(de->de_files)) != NULL && (e = htsmsg_field_get_map(f)) != NULL) { if (filename == NULL) { filename = htsmsg_get_str(e, "filename"); if (filename == NULL) @@ -1970,16 +1991,30 @@ dvr_spawn_cmd(dvr_entry_t *de, const char *cmd, const char *filename, int pre) buf2 = tvh_strdupa(buf1); /* Substitute filename formatters */ if (!pre) { - htsstr_substitute(buf2, buf1, sizeof(buf1), '%', dvr_subs_postproc_filename, filename, tmp, sizeof(tmp)); + htsstr_substitute(buf2, + buf1, + sizeof(buf1), + '%', + dvr_subs_postproc_filename, + filename, + tmp, + sizeof(tmp)); buf2 = tvh_strdupa(buf1); } /* Substitute info formatters */ if (info) - htsstr_substitute(buf2, buf1, sizeof(buf1), '%', dvr_subs_postproc_info, info, tmp, sizeof(tmp)); + htsstr_substitute(buf2, + buf1, + sizeof(buf1), + '%', + dvr_subs_postproc_info, + info, + tmp, + sizeof(tmp)); args = htsstr_argsplit(buf1); - if(args[0]) - spawnv(args[0], (void *)args, NULL, 1, 1); + if (args[0]) + spawnv(args[0], (void*)args, NULL, 1, 1); htsstr_argsplit_free(args); } @@ -1987,12 +2022,10 @@ dvr_spawn_cmd(dvr_entry_t *de, const char *cmd, const char *filename, int pre) /** * */ -static void -dvr_thread_epilog(dvr_entry_t *de, const char *dvr_postproc) -{ - profile_chain_t *prch = de->de_chain; - htsmsg_t *e; - htsmsg_field_t *f; +static void dvr_thread_epilog(dvr_entry_t* de, const char* dvr_postproc) { + profile_chain_t* prch = de->de_chain; + htsmsg_t* e; + htsmsg_field_t* f; lock_assert(&global_lock); @@ -2003,11 +2036,10 @@ dvr_thread_epilog(dvr_entry_t *de, const char *dvr_postproc) muxer_destroy(prch->prch_muxer); prch->prch_muxer = NULL; - if ((f = htsmsg_field_last(de->de_files)) != NULL && - (e = htsmsg_field_get_map(f)) != NULL) + if ((f = htsmsg_field_last(de->de_files)) != NULL && (e = htsmsg_field_get_map(f)) != NULL) htsmsg_set_s64(e, "stop", gclk()); - if(dvr_postproc && dvr_postproc[0]) + if (dvr_postproc && dvr_postproc[0]) dvr_spawn_cmd(de, dvr_postproc, NULL, 0); idnode_changed(&de->de_id); diff --git a/src/dvr/dvr_timerec.c b/src/dvr/dvr_timerec.c index 1016b550f..25417608e 100644 --- a/src/dvr/dvr_timerec.c +++ b/src/dvr/dvr_timerec.c @@ -31,23 +31,21 @@ static mtimer_t dvr_timerec_timer; /** * */ -static time_t -dvr_timerec_timecorrection(time_t clk, int hm, struct tm *tm) -{ +static time_t dvr_timerec_timecorrection(time_t clk, int hm, struct tm* tm) { time_t r; - int isdst; + int isdst; localtime_r(&clk, tm); - tm->tm_min = hm % 60; + tm->tm_min = hm % 60; tm->tm_hour = hm / 60; - tm->tm_sec = 0; - isdst = tm->tm_isdst; - r = mktime(tm); + tm->tm_sec = 0; + isdst = tm->tm_isdst; + r = mktime(tm); if (tm->tm_isdst != isdst) { - tm->tm_min = hm % 60; + tm->tm_min = hm % 60; tm->tm_hour = hm / 60; - tm->tm_sec = 0; - r = mktime(tm); + tm->tm_sec = 0; + r = mktime(tm); } return r; } @@ -55,10 +53,8 @@ dvr_timerec_timecorrection(time_t clk, int hm, struct tm *tm) /** * Unlink - and remove any unstarted */ -static void -dvr_timerec_purge_spawn(dvr_timerec_entry_t *dte, int delconf) -{ - dvr_entry_t *de = dte->dte_spawn; +static void dvr_timerec_purge_spawn(dvr_timerec_entry_t* dte, int delconf) { + dvr_entry_t* de = dte->dte_spawn; if (de && de->de_timerec) { dte->dte_spawn = NULL; @@ -75,14 +71,12 @@ dvr_timerec_purge_spawn(dvr_timerec_entry_t *dte, int delconf) /** * Title */ -static const char * -dvr_timerec_title(dvr_timerec_entry_t *dte, struct tm *start) -{ +static const char* dvr_timerec_title(dvr_timerec_entry_t* dte, struct tm* start) { size_t len; if (dte->dte_title == NULL) return _("Unknown"); - len = strftime(prop_sbuf, PROP_SBUF_LEN-1, dte->dte_title, start); + len = strftime(prop_sbuf, PROP_SBUF_LEN - 1, dte->dte_title, start); prop_sbuf[len] = '\0'; return prop_sbuf; } @@ -90,43 +84,41 @@ dvr_timerec_title(dvr_timerec_entry_t *dte, struct tm *start) /** * handle the timerec entry */ -void -dvr_timerec_check(dvr_timerec_entry_t *dte) -{ - dvr_entry_t *de; - time_t clk, start, stop, limit; - struct tm tm_start, tm_stop; - const char *title; - char buf[200]; - htsmsg_t *conf; - - if(dte->dte_enabled == 0 || dte->dte_weekdays == 0) +void dvr_timerec_check(dvr_timerec_entry_t* dte) { + dvr_entry_t* de; + time_t clk, start, stop, limit; + struct tm tm_start, tm_stop; + const char* title; + char buf[200]; + htsmsg_t* conf; + + if (dte->dte_enabled == 0 || dte->dte_weekdays == 0) goto fail; - if(dte->dte_start < 0 || dte->dte_start >= 24*60 || - dte->dte_stop < 0 || dte->dte_stop >= 24*60) + if (dte->dte_start < 0 || dte->dte_start >= 24 * 60 || dte->dte_stop < 0 || + dte->dte_stop >= 24 * 60) goto fail; - if(dte->dte_channel == NULL) + if (dte->dte_channel == NULL) goto fail; clk = gclk(); limit = clk - 600; start = dvr_timerec_timecorrection(clk, dte->dte_start, &tm_start); - stop = dvr_timerec_timecorrection(clk, dte->dte_stop, &tm_stop); + stop = dvr_timerec_timecorrection(clk, dte->dte_stop, &tm_stop); if (start < limit && stop < limit) { /* next day */ - clk += 24*60*60; + clk += 24 * 60 * 60; start = dvr_timerec_timecorrection(clk, dte->dte_start, &tm_start); stop = dvr_timerec_timecorrection(clk, dte->dte_stop, &tm_stop); } /* day boundary correction */ while (start > stop) { - clk += 24*60*60; + clk += 24 * 60 * 60; stop = dvr_timerec_timecorrection(clk, dte->dte_stop, &tm_stop); } - if(dte->dte_weekdays != 0x7f) { + if (dte->dte_weekdays != 0x7f) { localtime_r(&start, &tm_start); - if(!((1 << ((tm_start.tm_wday ?: 7) - 1)) & dte->dte_weekdays)) + if (!((1 << ((tm_start.tm_wday ?: 7) - 1)) & dte->dte_weekdays)) goto fail; } @@ -139,9 +131,11 @@ dvr_timerec_check(dvr_timerec_entry_t *dte) } title = dvr_timerec_title(dte, &tm_start); - snprintf(buf, sizeof(buf), _("Time recording%s%s"), - dte->dte_comment ? ": " : "", - dte->dte_comment ?: ""); + snprintf(buf, + sizeof(buf), + _("Time recording%s%s"), + dte->dte_comment ? ": " : "", + dte->dte_comment ?: ""); conf = htsmsg_create_map(); htsmsg_add_uuid(conf, "config_name", &dte->dte_config->dvr_id.in_uuid); @@ -168,10 +162,8 @@ fail: /** * */ -dvr_timerec_entry_t * -dvr_timerec_create(const char *uuid, htsmsg_t *conf) -{ - dvr_timerec_entry_t *dte; +dvr_timerec_entry_t* dvr_timerec_create(const char* uuid, htsmsg_t* conf) { + dvr_timerec_entry_t* dte; dte = calloc(1, sizeof(*dte)); @@ -182,13 +174,13 @@ dvr_timerec_create(const char *uuid, htsmsg_t *conf) return NULL; } - dte->dte_title = strdup("Time-%F_%R"); + dte->dte_title = strdup("Time-%F_%R"); dte->dte_weekdays = 0x7f; - dte->dte_pri = DVR_PRIO_DEFAULT; - dte->dte_start = -1; - dte->dte_stop = -1; - dte->dte_enabled = 1; - dte->dte_config = dvr_config_find_by_name_default(NULL); + dte->dte_pri = DVR_PRIO_DEFAULT; + dte->dte_start = -1; + dte->dte_stop = -1; + dte->dte_enabled = 1; + dte->dte_config = dvr_config_find_by_name_default(NULL); LIST_INSERT_HEAD(&dte->dte_config->dvr_timerec_entries, dte, dte_config_link); TAILQ_INSERT_TAIL(&timerec_entries, dte, dte_link); @@ -200,10 +192,8 @@ dvr_timerec_create(const char *uuid, htsmsg_t *conf) return dte; } -dvr_timerec_entry_t* -dvr_timerec_create_htsp(htsmsg_t *conf) -{ - dvr_timerec_entry_t *dte; +dvr_timerec_entry_t* dvr_timerec_create_htsp(htsmsg_t* conf) { + dvr_timerec_entry_t* dte; dte = dvr_timerec_create(NULL, conf); htsmsg_destroy(conf); @@ -214,21 +204,19 @@ dvr_timerec_create_htsp(htsmsg_t *conf) return dte; } -void -dvr_timerec_update_htsp (dvr_timerec_entry_t *dte, htsmsg_t *conf) -{ +void dvr_timerec_update_htsp(dvr_timerec_entry_t* dte, htsmsg_t* conf) { idnode_update(&dte->dte_id, conf); idnode_changed(&dte->dte_id); - tvhinfo(LS_DVR, "timerec \"%s\" on \"%s\": Updated", dte->dte_title ? dte->dte_title : "", + tvhinfo(LS_DVR, + "timerec \"%s\" on \"%s\": Updated", + dte->dte_title ? dte->dte_title : "", (dte->dte_channel && dte->dte_channel->ch_name) ? dte->dte_channel->ch_name : "any channel"); } /** * */ -static void -timerec_entry_destroy(dvr_timerec_entry_t *dte, int delconf) -{ +static void timerec_entry_destroy(dvr_timerec_entry_t* dte, int delconf) { char ubuf[UUID_HEX_SIZE]; idnode_save_check(&dte->dte_id, delconf); @@ -243,7 +231,7 @@ timerec_entry_destroy(dvr_timerec_entry_t *dte, int delconf) TAILQ_REMOVE(&timerec_entries, dte, dte_link); idnode_unlink(&dte->dte_id); - if(dte->dte_config != NULL) + if (dte->dte_config != NULL) LIST_REMOVE(dte, dte_config_link); free(dte->dte_name); @@ -253,7 +241,7 @@ timerec_entry_destroy(dvr_timerec_entry_t *dte, int delconf) free(dte->dte_creator); free(dte->dte_comment); - if(dte->dte_channel != NULL) + if (dte->dte_channel != NULL) LIST_REMOVE(dte, dte_channel_link); free(dte); @@ -263,38 +251,30 @@ timerec_entry_destroy(dvr_timerec_entry_t *dte, int delconf) * DVR Autorec Entry Class definition * **************************************************************************/ -static void -dvr_timerec_entry_class_changed(idnode_t *self) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)self; +static void dvr_timerec_entry_class_changed(idnode_t* self) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)self; dvr_timerec_check(dte); htsp_timerec_entry_update(dte); } -static htsmsg_t * -dvr_timerec_entry_class_save(idnode_t *self, char *filename, size_t fsize) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)self; - htsmsg_t *m = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* dvr_timerec_entry_class_save(idnode_t* self, char* filename, size_t fsize) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)self; + htsmsg_t* m = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(&dte->dte_id, m); if (filename) snprintf(filename, fsize, "dvr/timerec/%s", idnode_uuid_as_str(&dte->dte_id, ubuf)); return m; } -static void -dvr_timerec_entry_class_delete(idnode_t *self) -{ - timerec_entry_destroy((dvr_timerec_entry_t *)self, 1); +static void dvr_timerec_entry_class_delete(idnode_t* self) { + timerec_entry_destroy((dvr_timerec_entry_t*)self, 1); } -static int -dvr_timerec_entry_class_perm(idnode_t *self, access_t *a, htsmsg_t *msg_to_write) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)self; +static int dvr_timerec_entry_class_perm(idnode_t* self, access_t* a, htsmsg_t* msg_to_write) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)self; - if (access_verify2(a, ACCESS_OR|ACCESS_ADMIN|ACCESS_RECORDER)) + if (access_verify2(a, ACCESS_OR | ACCESS_ADMIN | ACCESS_RECORDER)) return -1; if (!access_verify2(a, ACCESS_ADMIN)) return 0; @@ -304,11 +284,9 @@ dvr_timerec_entry_class_perm(idnode_t *self, access_t *a, htsmsg_t *msg_to_write } static void -dvr_timerec_entry_class_get_title - (idnode_t *self, const char *lang, char *dst, size_t dstsize) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)self; - const char *s = ""; +dvr_timerec_entry_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)self; + const char* s = ""; if (dte->dte_name && dte->dte_name[0] != '\0') s = dte->dte_name; else if (dte->dte_comment && dte->dte_comment[0] != '\0') @@ -316,12 +294,11 @@ dvr_timerec_entry_class_get_title snprintf(dst, dstsize, "%s", s); } -static int -dvr_timerec_entry_class_channel_set(void *o, const void *v) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; - channel_t *ch = v ? channel_find_by_uuid(v) : NULL; - if (ch == NULL) ch = v ? channel_find_by_name(v) : NULL; +static int dvr_timerec_entry_class_channel_set(void* o, const void* v) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; + channel_t* ch = v ? channel_find_by_uuid(v) : NULL; + if (ch == NULL) + ch = v ? channel_find_by_name(v) : NULL; if (ch == NULL) { if (dte->dte_channel) { LIST_REMOVE(dte, dte_channel_link); @@ -329,8 +306,7 @@ dvr_timerec_entry_class_channel_set(void *o, const void *v) return 1; } } else if (dte->dte_channel != ch) { - if (dte->dte_id.in_access && - !channel_access(ch, dte->dte_id.in_access, 1)) + if (dte->dte_id.in_access && !channel_access(ch, dte->dte_id.in_access, 1)) return 0; if (dte->dte_channel) LIST_REMOVE(dte, dte_channel_link); @@ -341,10 +317,8 @@ dvr_timerec_entry_class_channel_set(void *o, const void *v) return 0; } -static const void * -dvr_timerec_entry_class_channel_get(void *o) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; +static const void* dvr_timerec_entry_class_channel_get(void* o) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; if (dte->dte_channel) idnode_uuid_as_str(&dte->dte_channel->ch_id, prop_sbuf); else @@ -352,24 +326,20 @@ dvr_timerec_entry_class_channel_get(void *o) return &prop_sbuf_ptr; } -static char * -dvr_timerec_entry_class_channel_rend(void *o, const char *lang) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; +static char* dvr_timerec_entry_class_channel_rend(void* o, const char* lang) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; if (dte->dte_channel) return strdup(channel_get_name(dte->dte_channel, tvh_gettext_lang(lang, channel_blank_name))); return NULL; } -static int -dvr_timerec_entry_class_time_set(void *o, const void *v, int *tm) -{ - const char *s = v; - int t; +static int dvr_timerec_entry_class_time_set(void* o, const void* v, int* tm) { + const char* s = v; + int t; - if(s == NULL || s[0] == '\0' || !isdigit(s[0])) + if (s == NULL || s[0] == '\0' || !isdigit(s[0])) t = -1; - else if(strchr(s, ':') != NULL) + else if (strchr(s, ':') != NULL) // formatted time string - convert t = (atoi(s) * 60) + atoi(s + 3); else { @@ -384,23 +354,17 @@ dvr_timerec_entry_class_time_set(void *o, const void *v, int *tm) return 0; } -static int -dvr_timerec_entry_class_start_set(void *o, const void *v) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; +static int dvr_timerec_entry_class_start_set(void* o, const void* v) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; return dvr_timerec_entry_class_time_set(o, v, &dte->dte_start); } -static int -dvr_timerec_entry_class_stop_set(void *o, const void *v) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; +static int dvr_timerec_entry_class_stop_set(void* o, const void* v) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; return dvr_timerec_entry_class_time_set(o, v, &dte->dte_stop); } -static const void * -dvr_timerec_entry_class_time_get(void *o, int tm) -{ +static const void* dvr_timerec_entry_class_time_get(void* o, int tm) { if (tm >= 0) snprintf(prop_sbuf, PROP_SBUF_LEN, "%02d:%02d", tm / 60, tm % 60); else @@ -408,32 +372,25 @@ dvr_timerec_entry_class_time_get(void *o, int tm) return &prop_sbuf_ptr; } -static const void * -dvr_timerec_entry_class_start_get(void *o) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; +static const void* dvr_timerec_entry_class_start_get(void* o) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; return dvr_timerec_entry_class_time_get(o, dte->dte_start); } -static const void * -dvr_timerec_entry_class_stop_get(void *o) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; +static const void* dvr_timerec_entry_class_stop_get(void* o) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; return dvr_timerec_entry_class_time_get(o, dte->dte_stop); } -static htsmsg_t * -dvr_timerec_entry_class_time_list(void *o, const char *lang) -{ +static htsmsg_t* dvr_timerec_entry_class_time_list(void* o, const char* lang) { return dvr_autorec_entry_class_time_list(o, tvh_gettext_lang(lang, N_("Invalid"))); } -static int -dvr_timerec_entry_class_config_name_set(void *o, const void *v) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; - dvr_config_t *cfg = v ? dvr_config_find_by_uuid(v) : NULL; - if (cfg == NULL) cfg = v ? dvr_config_find_by_name_default(v): NULL; +static int dvr_timerec_entry_class_config_name_set(void* o, const void* v) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; + dvr_config_t* cfg = v ? dvr_config_find_by_uuid(v) : NULL; + if (cfg == NULL) + cfg = v ? dvr_config_find_by_name_default(v) : NULL; if (cfg == NULL && dte->dte_config) { dte->dte_config = NULL; LIST_REMOVE(dte, dte_config_link); @@ -448,10 +405,8 @@ dvr_timerec_entry_class_config_name_set(void *o, const void *v) return 0; } -static const void * -dvr_timerec_entry_class_config_name_get(void *o) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; +static const void* dvr_timerec_entry_class_config_name_get(void* o) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; if (dte->dte_config) idnode_uuid_as_str(&dte->dte_config->dvr_id, prop_sbuf); else @@ -459,25 +414,21 @@ dvr_timerec_entry_class_config_name_get(void *o) return &prop_sbuf_ptr; } -static char * -dvr_timerec_entry_class_config_name_rend(void *o, const char *lang) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; +static char* dvr_timerec_entry_class_config_name_rend(void* o, const char* lang) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; if (dte->dte_config) return strdup(dte->dte_config->dvr_config_name); return NULL; } -static int -dvr_timerec_entry_class_weekdays_set(void *o, const void *v) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; - htsmsg_field_t *f; - uint32_t u32, bits = 0; +static int dvr_timerec_entry_class_weekdays_set(void* o, const void* v) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; + htsmsg_field_t* f; + uint32_t u32, bits = 0; - HTSMSG_FOREACH(f, (htsmsg_t *)v) - if (!htsmsg_field_get_u32(f, &u32) && u32 > 0 && u32 < 8) - bits |= (1 << (u32 - 1)); + HTSMSG_FOREACH(f, (htsmsg_t*)v) + if (!htsmsg_field_get_u32(f, &u32) && u32 > 0 && u32 < 8) + bits |= (1 << (u32 - 1)); if (bits != dte->dte_weekdays) { dte->dte_weekdays = bits; @@ -486,32 +437,23 @@ dvr_timerec_entry_class_weekdays_set(void *o, const void *v) return 0; } -static const void * -dvr_timerec_entry_class_weekdays_get(void *o) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; +static const void* dvr_timerec_entry_class_weekdays_get(void* o) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; return dvr_autorec_entry_class_weekdays_get(dte->dte_weekdays); } -static htsmsg_t * -dvr_timerec_entry_class_weekdays_default(void) -{ +static htsmsg_t* dvr_timerec_entry_class_weekdays_default(void) { return dvr_autorec_entry_class_weekdays_get(0x7f); } -static char * -dvr_timerec_entry_class_weekdays_rend(void *o, const char *lang) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; +static char* dvr_timerec_entry_class_weekdays_rend(void* o, const char* lang) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; return dvr_autorec_entry_class_weekdays_rend(dte->dte_weekdays, lang); } -static uint32_t -dvr_timerec_entry_class_owner_opts(void *o, uint32_t opts) -{ - dvr_timerec_entry_t *dte = (dvr_timerec_entry_t *)o; - if (dte && dte->dte_id.in_access && - !access_verify2(dte->dte_id.in_access, ACCESS_ADMIN)) +static uint32_t dvr_timerec_entry_class_owner_opts(void* o, uint32_t opts) { + dvr_timerec_entry_t* dte = (dvr_timerec_entry_t*)o; + if (dte && dte->dte_id.in_access && !access_verify2(dte->dte_id.in_access, ACCESS_ADMIN)) return PO_ADVANCED; return PO_RDONLY | PO_ADVANCED; } @@ -519,185 +461,173 @@ dvr_timerec_entry_class_owner_opts(void *o, uint32_t opts) CLASS_DOC(dvrtimerec) PROP_DOC(dvr_timerec_title_format) -const idclass_t dvr_timerec_entry_class = { - .ic_class = "dvrtimerec", - .ic_caption = N_("DVR - Time-based Recording (Timers)"), - .ic_event = "dvrtimerec", - .ic_doc = tvh_doc_dvrtimerec_class, - .ic_changed = dvr_timerec_entry_class_changed, - .ic_save = dvr_timerec_entry_class_save, - .ic_get_title = dvr_timerec_entry_class_get_title, - .ic_delete = dvr_timerec_entry_class_delete, - .ic_perm = dvr_timerec_entry_class_perm, - .ic_properties = (const property_t[]) { - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable the entry."), - .def.i = 1, - .off = offsetof(dvr_timerec_entry_t, dte_enabled), - }, - { - .type = PT_STR, - .id = "name", - .name = N_("Name"), - .desc = N_("Name of the entry."), - .off = offsetof(dvr_timerec_entry_t, dte_name), - }, - { - .type = PT_STR, - .id = "title", - .name = N_("Title"), - .desc = N_("Title of the recording - this is used to generate the filename."), - .doc = prop_doc_dvr_timerec_title_format, - .off = offsetof(dvr_timerec_entry_t, dte_title), - .def.s = "Time-%F_%R", - .opts = PO_ADVANCED - }, - { - .type = PT_STR, - .id = "directory", - .name = N_("Directory"), - .desc = N_("Directory override. Override the subdirectory " - "rules specified by the DVR configuration and put " - "all recordings done by this entry into the " - "specified subdirectory"), - .off = offsetof(dvr_timerec_entry_t, dte_directory), - .opts = PO_EXPERT - }, - { - .type = PT_STR, - .id = "channel", - .name = N_("Channel"), - .desc = N_("Channel to use/used for the recording."), - .set = dvr_timerec_entry_class_channel_set, - .get = dvr_timerec_entry_class_channel_get, - .rend = dvr_timerec_entry_class_channel_rend, - .list = channel_class_get_list, - }, - { - .type = PT_STR, - .id = "start", - .name = N_("Start"), - .desc = N_("Time to start the recording/time the recording started."), - .set = dvr_timerec_entry_class_start_set, - .get = dvr_timerec_entry_class_start_get, - .list = dvr_timerec_entry_class_time_list, - .def.s = "12:00", - .opts = PO_SORTKEY | PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "stop", - .name = N_("Stop"), - .desc = N_("Time to stop recording/time the recording stopped."), - .set = dvr_timerec_entry_class_stop_set, - .get = dvr_timerec_entry_class_stop_get, - .list = dvr_timerec_entry_class_time_list, - .def.s = "12:00", - .opts = PO_SORTKEY | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .islist = 1, - .id = "weekdays", - .name = N_("Days of Week"), - .desc = N_("Record on these days only."), - .set = dvr_timerec_entry_class_weekdays_set, - .get = dvr_timerec_entry_class_weekdays_get, - .list = dvr_autorec_entry_class_weekdays_list, - .rend = dvr_timerec_entry_class_weekdays_rend, - .def.list = dvr_timerec_entry_class_weekdays_default, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "pri", - .name = N_("Priority"), - .desc = N_("Priority of the recording. Higher priority entries " - "will take precedence and cancel lower-priority events. " - "The 'Not Set' value inherits the settings from " - "the assigned DVR configuration."), - .list = dvr_entry_class_pri_list, - .def.i = DVR_PRIO_DEFAULT, - .off = offsetof(dvr_timerec_entry_t, dte_pri), - .opts = PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "retention", - .name = N_("DVR log retention"), - .desc = N_("Number of days to retain entry information."), - .def.i = DVR_RET_REM_DVRCONFIG, - .off = offsetof(dvr_timerec_entry_t, dte_retention), - .list = dvr_entry_class_retention_list, - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_U32, - .id = "removal", - .name = N_("DVR file retention period"), - .desc = N_("Number of days to keep the recorded file."), - .def.i = DVR_RET_REM_DVRCONFIG, - .off = offsetof(dvr_timerec_entry_t, dte_removal), - .list = dvr_entry_class_removal_list, - .opts = PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "config_name", - .name = N_("DVR configuration"), - .desc = N_("DVR profile to use/used for the recording."), - .set = dvr_timerec_entry_class_config_name_set, - .get = dvr_timerec_entry_class_config_name_get, - .rend = dvr_timerec_entry_class_config_name_rend, - .list = dvr_entry_class_config_name_list, - .opts = PO_ADVANCED - }, - { - .type = PT_STR, - .id = "owner", - .name = N_("Owner"), - .desc = N_("Owner of the entry."), - .off = offsetof(dvr_timerec_entry_t, dte_owner), - .get_opts = dvr_timerec_entry_class_owner_opts, - }, - { - .type = PT_STR, - .id = "creator", - .name = N_("Creator"), - .desc = N_("The user who created the recording, or the " - "auto-recording source and IP address if scheduled " - "by a matching rule."), - .off = offsetof(dvr_timerec_entry_t, dte_creator), - .get_opts = dvr_timerec_entry_class_owner_opts, - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-form text field, enter whatever you like here."), - .off = offsetof(dvr_timerec_entry_t, dte_comment), - }, - {} - } -}; +const idclass_t dvr_timerec_entry_class = {.ic_class = "dvrtimerec", + .ic_caption = N_("DVR - Time-based Recording (Timers)"), + .ic_event = "dvrtimerec", + .ic_doc = tvh_doc_dvrtimerec_class, + .ic_changed = dvr_timerec_entry_class_changed, + .ic_save = dvr_timerec_entry_class_save, + .ic_get_title = dvr_timerec_entry_class_get_title, + .ic_delete = dvr_timerec_entry_class_delete, + .ic_perm = dvr_timerec_entry_class_perm, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable the entry."), + .def.i = 1, + .off = offsetof(dvr_timerec_entry_t, dte_enabled), + }, + { + .type = PT_STR, + .id = "name", + .name = N_("Name"), + .desc = N_("Name of the entry."), + .off = offsetof(dvr_timerec_entry_t, dte_name), + }, + {.type = PT_STR, + .id = "title", + .name = N_("Title"), + .desc = N_("Title of the recording - this is used to generate the filename."), + .doc = prop_doc_dvr_timerec_title_format, + .off = offsetof(dvr_timerec_entry_t, dte_title), + .def.s = "Time-%F_%R", + .opts = PO_ADVANCED}, + {.type = PT_STR, + .id = "directory", + .name = N_("Directory"), + .desc = N_("Directory override. Override the subdirectory " + "rules specified by the DVR configuration and put " + "all recordings done by this entry into the " + "specified subdirectory"), + .off = offsetof(dvr_timerec_entry_t, dte_directory), + .opts = PO_EXPERT}, + { + .type = PT_STR, + .id = "channel", + .name = N_("Channel"), + .desc = N_("Channel to use/used for the recording."), + .set = dvr_timerec_entry_class_channel_set, + .get = dvr_timerec_entry_class_channel_get, + .rend = dvr_timerec_entry_class_channel_rend, + .list = channel_class_get_list, + }, + { + .type = PT_STR, + .id = "start", + .name = N_("Start"), + .desc = N_("Time to start the recording/time the recording started."), + .set = dvr_timerec_entry_class_start_set, + .get = dvr_timerec_entry_class_start_get, + .list = dvr_timerec_entry_class_time_list, + .def.s = "12:00", + .opts = PO_SORTKEY | PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "stop", + .name = N_("Stop"), + .desc = N_("Time to stop recording/time the recording stopped."), + .set = dvr_timerec_entry_class_stop_set, + .get = dvr_timerec_entry_class_stop_get, + .list = dvr_timerec_entry_class_time_list, + .def.s = "12:00", + .opts = PO_SORTKEY | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .islist = 1, + .id = "weekdays", + .name = N_("Days of Week"), + .desc = N_("Record on these days only."), + .set = dvr_timerec_entry_class_weekdays_set, + .get = dvr_timerec_entry_class_weekdays_get, + .list = dvr_autorec_entry_class_weekdays_list, + .rend = dvr_timerec_entry_class_weekdays_rend, + .def.list = dvr_timerec_entry_class_weekdays_default, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "pri", + .name = N_("Priority"), + .desc = N_("Priority of the recording. Higher priority entries " + "will take precedence and cancel lower-priority events. " + "The 'Not Set' value inherits the settings from " + "the assigned DVR configuration."), + .list = dvr_entry_class_pri_list, + .def.i = DVR_PRIO_DEFAULT, + .off = offsetof(dvr_timerec_entry_t, dte_pri), + .opts = PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "retention", + .name = N_("DVR log retention"), + .desc = N_("Number of days to retain entry information."), + .def.i = DVR_RET_REM_DVRCONFIG, + .off = offsetof(dvr_timerec_entry_t, dte_retention), + .list = dvr_entry_class_retention_list, + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_U32, + .id = "removal", + .name = N_("DVR file retention period"), + .desc = N_("Number of days to keep the recorded file."), + .def.i = DVR_RET_REM_DVRCONFIG, + .off = offsetof(dvr_timerec_entry_t, dte_removal), + .list = dvr_entry_class_removal_list, + .opts = PO_ADVANCED | PO_DOC_NLIST, + }, + {.type = PT_STR, + .id = "config_name", + .name = N_("DVR configuration"), + .desc = N_("DVR profile to use/used for the recording."), + .set = dvr_timerec_entry_class_config_name_set, + .get = dvr_timerec_entry_class_config_name_get, + .rend = dvr_timerec_entry_class_config_name_rend, + .list = dvr_entry_class_config_name_list, + .opts = PO_ADVANCED}, + { + .type = PT_STR, + .id = "owner", + .name = N_("Owner"), + .desc = N_("Owner of the entry."), + .off = offsetof(dvr_timerec_entry_t, dte_owner), + .get_opts = dvr_timerec_entry_class_owner_opts, + }, + { + .type = PT_STR, + .id = "creator", + .name = N_("Creator"), + .desc = N_("The user who created the recording, or the " + "auto-recording source and IP address if scheduled " + "by a matching rule."), + .off = offsetof(dvr_timerec_entry_t, dte_creator), + .get_opts = dvr_timerec_entry_class_owner_opts, + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-form text field, enter whatever you like here."), + .off = offsetof(dvr_timerec_entry_t, dte_comment), + }, + {}}}; /** * */ -void -dvr_timerec_init(void) -{ - htsmsg_t *l, *c; - htsmsg_field_t *f; +void dvr_timerec_init(void) { + htsmsg_t * l, *c; + htsmsg_field_t* f; TAILQ_INIT(&timerec_entries); idclass_register(&dvr_timerec_entry_class); - if((l = hts_settings_load("dvr/timerec")) != NULL) { + if ((l = hts_settings_load("dvr/timerec")) != NULL) { HTSMSG_FOREACH(f, l) { - if((c = htsmsg_get_map_by_field(f)) == NULL) + if ((c = htsmsg_get_map_by_field(f)) == NULL) continue; (void)dvr_timerec_create(htsmsg_field_name(f), c); } @@ -705,10 +635,8 @@ dvr_timerec_init(void) } } -void -dvr_timerec_done(void) -{ - dvr_timerec_entry_t *dte; +void dvr_timerec_done(void) { + dvr_timerec_entry_t* dte; tvh_mutex_lock(&global_lock); while ((dte = TAILQ_FIRST(&timerec_entries)) != NULL) @@ -716,15 +644,13 @@ dvr_timerec_done(void) tvh_mutex_unlock(&global_lock); } -static void -dvr_timerec_timer_cb(void *aux) -{ - dvr_timerec_entry_t *dte; +static void dvr_timerec_timer_cb(void* aux) { + dvr_timerec_entry_t* dte; tvhtrace(LS_DVR, "timerec update"); /* check all entries */ - TAILQ_FOREACH(dte, &timerec_entries, dte_link) { + TAILQ_FOREACH (dte, &timerec_entries, dte_link) { dvr_timerec_check(dte); } @@ -732,9 +658,7 @@ dvr_timerec_timer_cb(void *aux) mtimer_arm_rel(&dvr_timerec_timer, dvr_timerec_timer_cb, NULL, sec2mono(3550)); } -void -dvr_timerec_update(void) -{ +void dvr_timerec_update(void) { /* check all timerec entries and load the timer */ dvr_timerec_timer_cb(NULL); } @@ -742,22 +666,18 @@ dvr_timerec_update(void) /** * */ -void -timerec_destroy_by_channel(channel_t *ch, int delconf) -{ - dvr_timerec_entry_t *dte; +void timerec_destroy_by_channel(channel_t* ch, int delconf) { + dvr_timerec_entry_t* dte; - while((dte = LIST_FIRST(&ch->ch_timerecs)) != NULL) + while ((dte = LIST_FIRST(&ch->ch_timerecs)) != NULL) timerec_entry_destroy(dte, delconf); } /** * */ -void -timerec_destroy_by_id(const char *id, int delconf) -{ - dvr_timerec_entry_t *dte; +void timerec_destroy_by_id(const char* id, int delconf) { + dvr_timerec_entry_t* dte; dte = dvr_timerec_find_by_uuid(id); if (dte) @@ -767,13 +687,11 @@ timerec_destroy_by_id(const char *id, int delconf) /** * */ -void -timerec_destroy_by_config(dvr_config_t *kcfg, int delconf) -{ - dvr_timerec_entry_t *dte; - dvr_config_t *cfg = NULL; +void timerec_destroy_by_config(dvr_config_t* kcfg, int delconf) { + dvr_timerec_entry_t* dte; + dvr_config_t* cfg = NULL; - while((dte = LIST_FIRST(&kcfg->dvr_timerec_entries)) != NULL) { + while ((dte = LIST_FIRST(&kcfg->dvr_timerec_entries)) != NULL) { LIST_REMOVE(dte, dte_config_link); if (cfg == NULL && delconf) cfg = dvr_config_find_by_name_default(NULL); @@ -788,13 +706,11 @@ timerec_destroy_by_config(dvr_config_t *kcfg, int delconf) /** * */ -uint32_t -dvr_timerec_get_retention_days( dvr_timerec_entry_t *dte ) -{ +uint32_t dvr_timerec_get_retention_days(dvr_timerec_entry_t* dte) { if (dte->dte_retention > 0) { if (dte->dte_retention > DVR_RET_REM_FOREVER) return DVR_RET_REM_FOREVER; - + return dte->dte_retention; } return dvr_retention_cleanup(dte->dte_config->dvr_retention_days); @@ -803,9 +719,7 @@ dvr_timerec_get_retention_days( dvr_timerec_entry_t *dte ) /** * */ -uint32_t -dvr_timerec_get_removal_days( dvr_timerec_entry_t *dte ) -{ +uint32_t dvr_timerec_get_removal_days(dvr_timerec_entry_t* dte) { if (dte->dte_removal > 0) { if (dte->dte_removal > DVR_RET_REM_FOREVER) return DVR_RET_REM_FOREVER; diff --git a/src/dvr/dvr_vfsmgr.c b/src/dvr/dvr_vfsmgr.c index ed44f437a..fad65b7fa 100644 --- a/src/dvr/dvr_vfsmgr.c +++ b/src/dvr/dvr_vfsmgr.c @@ -25,49 +25,45 @@ #include "notify.h" #include "tvhvfs.h" -#define MIB(v) ((int64_t)v*((int64_t)1024*1024)) -#define TOMIB(v) (v/((int64_t)1024*1024)) +#define MIB(v) ((int64_t)v * ((int64_t)1024 * 1024)) +#define TOMIB(v) (v / ((int64_t)1024 * 1024)) struct dvr_vfs_list dvrvfs_list; -static int dvr_disk_space_config_idx; -static int dvr_disk_space_config_size; -static int64_t dvr_disk_space_config_lastdelete; -static int64_t dvr_bfree; -static int64_t dvr_btotal; -static int64_t dvr_bused; +static int dvr_disk_space_config_idx; +static int dvr_disk_space_config_size; +static int64_t dvr_disk_space_config_lastdelete; +static int64_t dvr_bfree; +static int64_t dvr_btotal; +static int64_t dvr_bused; static tvh_mutex_t dvr_disk_space_mutex; -static mtimer_t dvr_disk_space_timer; -static tasklet_t dvr_disk_space_tasklet; +static mtimer_t dvr_disk_space_timer; +static tasklet_t dvr_disk_space_tasklet; /* * */ -static dvr_vfs_t * -dvr_vfs_find(dvr_vfs_t *old, tvh_fsid_t *id) -{ - dvr_vfs_t *dv; +static dvr_vfs_t* dvr_vfs_find(dvr_vfs_t* old, tvh_fsid_t* id) { + dvr_vfs_t* dv; if (old && tvh_vfs_fsid_match(&old->fsid, id)) return old; - LIST_FOREACH(dv, &dvrvfs_list, link) + LIST_FOREACH (dv, &dvrvfs_list, link) if (tvh_vfs_fsid_match(&dv->fsid, id)) return dv; - dv = calloc(1, sizeof(*dv)); + dv = calloc(1, sizeof(*dv)); dv->fsid = *id; LIST_INSERT_HEAD(&dvrvfs_list, dv, link); return dv; } -static dvr_vfs_t * -dvr_vfs_find1(dvr_vfs_t *old, htsmsg_t *m) -{ - int64_t v; - tvh_fsid_t fsid; - const char *s; +static dvr_vfs_t* dvr_vfs_find1(dvr_vfs_t* old, htsmsg_t* m) { + int64_t v; + tvh_fsid_t fsid; + const char* s; if (!htsmsg_get_s64(m, "fsid", &v)) { - fsid.fsid = v; + fsid.fsid = v; fsid.id[0] = '\0'; return dvr_vfs_find(old, &fsid); } else if ((s = htsmsg_get_str(m, "fsid0")) != NULL) { @@ -81,89 +77,83 @@ dvr_vfs_find1(dvr_vfs_t *old, htsmsg_t *m) /* * */ -void -dvr_vfs_refresh_entry(dvr_entry_t *de) -{ - htsmsg_field_t *f; - htsmsg_t *m; - struct stat st; - dvr_vfs_t *vfs = NULL; - uint64_t size; - const char *filename; - tvh_fsid_t fsid; +void dvr_vfs_refresh_entry(dvr_entry_t* de) { + htsmsg_field_t* f; + htsmsg_t* m; + struct stat st; + dvr_vfs_t* vfs = NULL; + uint64_t size; + const char* filename; + tvh_fsid_t fsid; lock_assert(&global_lock); if (de->de_files == NULL) return; HTSMSG_FOREACH(f, de->de_files) - if ((m = htsmsg_field_get_map(f)) != NULL) { - vfs = dvr_vfs_find1(vfs, m); - if (vfs) { - size = htsmsg_get_s64_or_default(m, "size", 0); - vfs->used_size = size <= vfs->used_size ? vfs->used_size - size : 0; - } - filename = htsmsg_get_str(m, "filename"); - if (filename == NULL || stat(filename, &st) < 0) { - tvherror(LS_DVR, "unable to stat file '%s': %s", filename, strerror(errno)); - goto rem; - } - if (tvh_vfs_fsid_build(filename, NULL, &fsid)) - goto rem; - vfs = dvr_vfs_find(vfs, &fsid); - if (vfs && st.st_size >= 0) { - if (fsid.fsid != 0) - htsmsg_set_s64(m, "fsid", fsid.fsid); - else - htsmsg_set_str(m, "fsid0", fsid.id); - htsmsg_set_s64(m, "size", st.st_size); - vfs->used_size += st.st_size; - } else { -rem: - htsmsg_delete_field(m, "fsid"); - htsmsg_delete_field(m, "size"); - } + if ((m = htsmsg_field_get_map(f)) != NULL) { + vfs = dvr_vfs_find1(vfs, m); + if (vfs) { + size = htsmsg_get_s64_or_default(m, "size", 0); + vfs->used_size = size <= vfs->used_size ? vfs->used_size - size : 0; + } + filename = htsmsg_get_str(m, "filename"); + if (filename == NULL || stat(filename, &st) < 0) { + tvherror(LS_DVR, "unable to stat file '%s': %s", filename, strerror(errno)); + goto rem; + } + if (tvh_vfs_fsid_build(filename, NULL, &fsid)) + goto rem; + vfs = dvr_vfs_find(vfs, &fsid); + if (vfs && st.st_size >= 0) { + if (fsid.fsid != 0) + htsmsg_set_s64(m, "fsid", fsid.fsid); + else + htsmsg_set_str(m, "fsid0", fsid.id); + htsmsg_set_s64(m, "size", st.st_size); + vfs->used_size += st.st_size; + } else { + rem: + htsmsg_delete_field(m, "fsid"); + htsmsg_delete_field(m, "size"); } + } } /* * */ -void -dvr_vfs_remove_entry(dvr_entry_t *de) -{ - htsmsg_field_t *f; - htsmsg_t *m; - dvr_vfs_t *vfs = NULL; - uint64_t size; +void dvr_vfs_remove_entry(dvr_entry_t* de) { + htsmsg_field_t* f; + htsmsg_t* m; + dvr_vfs_t* vfs = NULL; + uint64_t size; lock_assert(&global_lock); HTSMSG_FOREACH(f, de->de_files) - if ((m = htsmsg_field_get_map(f)) != NULL) { - vfs = dvr_vfs_find1(vfs, m); - if (vfs) { - size = htsmsg_get_s64_or_default(m, "size", 0); - vfs->used_size = size <= vfs->used_size ? vfs->used_size - size : 0; - } - htsmsg_delete_field(m, "fsid"); - htsmsg_delete_field(m, "size"); + if ((m = htsmsg_field_get_map(f)) != NULL) { + vfs = dvr_vfs_find1(vfs, m); + if (vfs) { + size = htsmsg_get_s64_or_default(m, "size", 0); + vfs->used_size = size <= vfs->used_size ? vfs->used_size - size : 0; } + htsmsg_delete_field(m, "fsid"); + htsmsg_delete_field(m, "size"); + } } /* * */ -int64_t -dvr_vfs_update_filename(const char *filename, htsmsg_t *fdata) -{ - dvr_vfs_t *vfs; +int64_t dvr_vfs_update_filename(const char* filename, htsmsg_t* fdata) { + dvr_vfs_t* vfs; struct stat st; - int64_t size; + int64_t size; if (filename == NULL || fdata == NULL) return -1; vfs = dvr_vfs_find1(NULL, fdata); if (vfs) { - size = htsmsg_get_s64_or_default(fdata, "size", 0); + size = htsmsg_get_s64_or_default(fdata, "size", 0); vfs->used_size = size <= vfs->used_size ? vfs->used_size - size : 0; if (stat(filename, &st) >= 0 && st.st_size >= 0) { htsmsg_set_s64(fdata, "size", st.st_size); @@ -179,22 +169,21 @@ dvr_vfs_update_filename(const char *filename, htsmsg_t *fdata) /** * Cleanup old recordings for this config until the dvr_cleanup_threshold is reached * Only "Keep until space needed" recordings are deleted, starting with the oldest one - * Return -1 on failure, -2 if disk stats unstable (no action taken), otherwise number of bytes cleaned + * Return -1 on failure, -2 if disk stats unstable (no action taken), otherwise number of bytes + * cleaned */ -static int64_t -dvr_disk_space_cleanup(dvr_config_t *cfg, int include_active) -{ - dvr_entry_t *de, *oldest; - time_t stoptime; - int64_t requiredBytes, maximalBytes, availBytes, usedBytes, diskBytes; - int64_t clearedBytes = 0, fileSize; +static int64_t dvr_disk_space_cleanup(dvr_config_t* cfg, int include_active) { + dvr_entry_t * de, *oldest; + time_t stoptime; + int64_t requiredBytes, maximalBytes, availBytes, usedBytes, diskBytes; + int64_t clearedBytes = 0, fileSize; struct statvfs diskdata; - struct tm tm; - int loops = 0; - char tbuf[64]; - const char *configName; - dvr_vfs_t *dvfs; - tvh_fsid_t fsid, fsid2; + struct tm tm; + int loops = 0; + char tbuf[64]; + const char* configName; + dvr_vfs_t* dvfs; + tvh_fsid_t fsid, fsid2; if (!cfg || !cfg->dvr_enabled) return -1; @@ -205,10 +194,11 @@ dvr_disk_space_cleanup(dvr_config_t *cfg, int include_active) dvfs = dvr_vfs_find(NULL, &fsid); /* When deleting a file from the disk, the system needs some time to actually do this */ - /* If calling this function too soon after the previous call, statvfs might be wrong/not updated yet */ + /* If calling this function too soon after the previous call, statvfs might be wrong/not updated + * yet */ /* So return a "disk stats unreliable" status */ if (dvr_disk_space_config_lastdelete + sec2mono(10) > mclk()) { - tvhtrace(LS_DVR,"disk space cleanup called <10s after last call - ignoring"); + tvhtrace(LS_DVR, "disk space cleanup called <10s after last call - ignoring"); return -2; } @@ -220,22 +210,31 @@ dvr_disk_space_cleanup(dvr_config_t *cfg, int include_active) configName = cfg != dvr_config_find_by_name(NULL) ? cfg->dvr_config_name : "Default profile"; if (diskBytes < requiredBytes) { - tvhwarn(LS_DVR,"disk space cleanup for config \"%s\", required free space \"%"PRId64" MiB\" is smaller than the total disk size!", - configName, TOMIB(requiredBytes)); + tvhwarn(LS_DVR, + "disk space cleanup for config \"%s\", required free space \"%" PRId64 + " MiB\" is smaller than the total disk size!", + configName, + TOMIB(requiredBytes)); if (maximalBytes >= usedBytes) return -1; } - tvhtrace(LS_DVR, "disk space cleanup for config \"%s\", required/current free space \"%"PRId64"/%"PRId64" MiB\", required/current used space \"%"PRId64"/%"PRId64" MiB\"", - configName, TOMIB(requiredBytes), TOMIB(availBytes), TOMIB(maximalBytes), TOMIB(usedBytes)); - - while (availBytes < requiredBytes || ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) { - oldest = NULL; + tvhtrace(LS_DVR, + "disk space cleanup for config \"%s\", required/current free space \"%" PRId64 "/%" PRId64 + " MiB\", required/current used space \"%" PRId64 "/%" PRId64 " MiB\"", + configName, + TOMIB(requiredBytes), + TOMIB(availBytes), + TOMIB(maximalBytes), + TOMIB(usedBytes)); + + while (availBytes < requiredBytes || + ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) { + oldest = NULL; stoptime = gclk(); - LIST_FOREACH(de, &dvrentries, de_global_link) { - if (de->de_sched_state != DVR_COMPLETED && - de->de_sched_state != DVR_MISSED_TIME) + LIST_FOREACH (de, &dvrentries, de_global_link) { + if (de->de_sched_state != DVR_COMPLETED && de->de_sched_state != DVR_MISSED_TIME) continue; if (dvr_entry_get_stop_time(de) > stoptime) @@ -255,7 +254,7 @@ dvr_disk_space_cleanup(dvr_config_t *cfg, int include_active) if (tvh_vfs_fsid_match(&fsid, &fsid2) == 0) continue; - oldest = de; // the oldest one until now + oldest = de; // the oldest one until now stoptime = dvr_entry_get_stop_time(de); } @@ -268,16 +267,23 @@ dvr_disk_space_cleanup(dvr_config_t *cfg, int include_active) localtime_r(&stoptime, &tm); if (strftime(tbuf, sizeof(tbuf), "%F %T", &tm) <= 0) *tbuf = 0; - tvhinfo(LS_DVR,"Delete \"until space needed\" recording \"%s\" with stop time \"%s\" and file size \"%"PRId64" MB\"", - lang_str_get(oldest->de_title, NULL), tbuf, TOMIB(fileSize)); + tvhinfo(LS_DVR, + "Delete \"until space needed\" recording \"%s\" with stop time \"%s\" and file size " + "\"%" PRId64 " MB\"", + lang_str_get(oldest->de_title, NULL), + tbuf, + TOMIB(fileSize)); dvr_disk_space_config_lastdelete = mclk(); dvr_entry_cancel_remove(oldest, 0); /* Remove stored files and mark as "removed" */ } else { /* Stop active recordings if cleanup is not possible */ if (loops == 0 && include_active) { - tvhwarn(LS_DVR, "No \"until space needed\" recordings found for config \"%s\", aborting active recordings now!", configName); - LIST_FOREACH(de, &dvrentries, de_global_link) { + tvhwarn(LS_DVR, + "No \"until space needed\" recordings found for config \"%s\", aborting active " + "recordings now!", + configName); + LIST_FOREACH (de, &dvrentries, de_global_link) { if (de->de_sched_state != DVR_RECORDING || !de->de_config || de->de_config != cfg) continue; dvr_stop_recording(de, SM_CODE_NO_SPACE, 1, 0); @@ -288,14 +294,23 @@ dvr_disk_space_cleanup(dvr_config_t *cfg, int include_active) loops++; if (loops >= 10) { - tvhwarn(LS_DVR, "Not able to clear the required disk space after deleting %i \"until space needed\" recordings...", loops); + tvhwarn(LS_DVR, + "Not able to clear the required disk space after deleting %i \"until space needed\" " + "recordings...", + loops); goto finish; } } finish: - tvhtrace(LS_DVR, "disk space cleanup for config \"%s\", cleared \"%"PRId64" MB\" of disk space, new free disk space \"%"PRId64" MiB\", new used disk space \"%"PRId64" MiB\"", - configName, TOMIB(clearedBytes), TOMIB(availBytes), TOMIB(usedBytes)); + tvhtrace(LS_DVR, + "disk space cleanup for config \"%s\", cleared \"%" PRId64 + " MB\" of disk space, new free disk space \"%" PRId64 " MiB\", new used disk space \"%" PRId64 + " MiB\"", + configName, + TOMIB(clearedBytes), + TOMIB(availBytes), + TOMIB(usedBytes)); return clearedBytes; } @@ -304,16 +319,14 @@ finish: * Check for each dvr config if the free disk size is below the dvr_cleanup_threshold * If so and we are using the dvr config ATM (active recording), we start the cleanup procedure */ -static void -dvr_disk_space_check() -{ - dvr_config_t *cfg; - dvr_entry_t *de; +static void dvr_disk_space_check() { + dvr_config_t* cfg; + dvr_entry_t* de; struct statvfs diskdata; - int64_t requiredBytes, maximalBytes, availBytes, usedBytes; - int idx = 0, cleanupDone = 0; - dvr_vfs_t *dvfs; - tvh_fsid_t fsid; + int64_t requiredBytes, maximalBytes, availBytes, usedBytes; + int idx = 0, cleanupDone = 0; + dvr_vfs_t* dvfs; + tvh_fsid_t fsid; tvh_mutex_lock(&global_lock); @@ -321,7 +334,7 @@ dvr_disk_space_check() if (dvr_disk_space_config_idx > dvr_disk_space_config_size) dvr_disk_space_config_idx = 1; - LIST_FOREACH(cfg, &dvrconfigs, config_link) { + LIST_FOREACH (cfg, &dvrconfigs, config_link) { idx++; if (!cfg->dvr_enabled) @@ -335,40 +348,49 @@ dvr_disk_space_check() dvfs = dvr_vfs_find(NULL, &fsid); - availBytes = diskdata.f_frsize * (int64_t)diskdata.f_bavail; - usedBytes = dvfs->used_size; + availBytes = diskdata.f_frsize * (int64_t)diskdata.f_bavail; + usedBytes = dvfs->used_size; requiredBytes = MIB(cfg->dvr_cleanup_threshold_free); - maximalBytes = MIB(cfg->dvr_cleanup_threshold_used); + maximalBytes = MIB(cfg->dvr_cleanup_threshold_used); - if (availBytes < requiredBytes || ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) { - LIST_FOREACH(de, &dvrentries, de_global_link) { + if (availBytes < requiredBytes || + ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) { + LIST_FOREACH (de, &dvrentries, de_global_link) { /* only start cleanup if we are actually writing files right now */ if (de->de_sched_state != DVR_RECORDING || !de->de_config || de->de_config != cfg) continue; if (availBytes < requiredBytes) { - tvhwarn(LS_DVR,"running out of free disk space for dvr config \"%s\", required free space \"%"PRId64" MiB\", current free space \"%"PRId64" MiB\"", - cfg != dvr_config_find_by_name(NULL) ? cfg->dvr_config_name : "Default profile", - TOMIB(requiredBytes), TOMIB(availBytes)); + tvhwarn(LS_DVR, + "running out of free disk space for dvr config \"%s\", required free space \"%" PRId64 + " MiB\", current free space \"%" PRId64 " MiB\"", + cfg != dvr_config_find_by_name(NULL) ? cfg->dvr_config_name : "Default profile", + TOMIB(requiredBytes), + TOMIB(availBytes)); } else { - tvhwarn(LS_DVR,"running out of used disk space for dvr config \"%s\", required used space \"%"PRId64" MiB\", current used space \"%"PRId64" MiB\"", - cfg != dvr_config_find_by_name(NULL) ? cfg->dvr_config_name : "Default profile", - TOMIB(maximalBytes), TOMIB(usedBytes)); + tvhwarn(LS_DVR, + "running out of used disk space for dvr config \"%s\", required used space \"%" PRId64 + " MiB\", current used space \"%" PRId64 " MiB\"", + cfg != dvr_config_find_by_name(NULL) ? cfg->dvr_config_name : "Default profile", + TOMIB(maximalBytes), + TOMIB(usedBytes)); } - /* only cleanup one directory at the time as the system needs time to delete the actual files */ + /* only cleanup one directory at the time as the system needs time to delete the actual + * files */ dvr_disk_space_cleanup(de->de_config, 1); - cleanupDone = 1; + cleanupDone = 1; dvr_disk_space_config_idx = idx; break; } if (!cleanupDone) goto checking; } else { -checking: - tvhtrace(LS_DVR, "checking free and used disk space for config \"%s\" : OK", - cfg != dvr_config_find_by_name(NULL) ? cfg->dvr_config_name : "Default profile"); + checking: + tvhtrace(LS_DVR, + "checking free and used disk space for config \"%s\" : OK", + cfg != dvr_config_find_by_name(NULL) ? cfg->dvr_config_name : "Default profile"); } } @@ -383,12 +405,10 @@ checking: /** * */ -static void -dvr_get_disk_space_update(const char *path, int locked) -{ +static void dvr_get_disk_space_update(const char* path, int locked) { struct statvfs diskdata; - dvr_vfs_t *dvfs; - tvh_fsid_t fsid; + dvr_vfs_t* dvfs; + tvh_fsid_t fsid; if (tvh_vfs_fsid_build(path, &diskdata, &fsid)) return; @@ -400,23 +420,21 @@ dvr_get_disk_space_update(const char *path, int locked) tvh_mutex_unlock(&global_lock); tvh_mutex_lock(&dvr_disk_space_mutex); - dvr_bfree = diskdata.f_frsize * (int64_t)diskdata.f_bavail; + dvr_bfree = diskdata.f_frsize * (int64_t)diskdata.f_bavail; dvr_btotal = diskdata.f_frsize * (int64_t)diskdata.f_blocks; - dvr_bused = dvfs ? dvfs->used_size : 0; + dvr_bused = dvfs ? dvfs->used_size : 0; tvh_mutex_unlock(&dvr_disk_space_mutex); } /** * */ -static void -dvr_get_disk_space_tcb(void *opaque, int dearmed) -{ +static void dvr_get_disk_space_tcb(void* opaque, int dearmed) { if (!dearmed) { - htsmsg_t *m = htsmsg_create_map(); + htsmsg_t* m = htsmsg_create_map(); /* update disk space from default dvr config */ - dvr_get_disk_space_update((char *)opaque, 0); + dvr_get_disk_space_update((char*)opaque, 0); htsmsg_add_s64(m, "freediskspace", dvr_bfree); htsmsg_add_s64(m, "useddiskspace", dvr_bused); htsmsg_add_s64(m, "totaldiskspace", dvr_btotal); @@ -429,11 +447,9 @@ dvr_get_disk_space_tcb(void *opaque, int dearmed) free(opaque); } -static void -dvr_get_disk_space_cb(void *aux) -{ - dvr_config_t *cfg; - char *path; +static void dvr_get_disk_space_cb(void* aux) { + dvr_config_t* cfg; + char* path; lock_assert(&global_lock); @@ -449,13 +465,11 @@ dvr_get_disk_space_cb(void *aux) * Check the available disk space for a new recording. * If '0' (= error or below configured minimum), a new recording should not be started. */ -int -dvr_vfs_rec_start_check(dvr_config_t *cfg) -{ +int dvr_vfs_rec_start_check(dvr_config_t* cfg) { struct statvfs diskdata; - dvr_vfs_t *dvfs; - tvh_fsid_t fsid; - int64_t availBytes, requiredBytes, usedBytes, maximalBytes, cleanedBytes; + dvr_vfs_t* dvfs; + tvh_fsid_t fsid; + int64_t availBytes, requiredBytes, usedBytes, maximalBytes, cleanedBytes; lock_assert(&global_lock); if (!cfg || !cfg->dvr_enabled) @@ -469,16 +483,18 @@ dvr_vfs_rec_start_check(dvr_config_t *cfg) dvfs = dvr_vfs_find(NULL, &fsid); usedBytes = dvfs->used_size; - if (availBytes < requiredBytes || ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) { + if (availBytes < requiredBytes || + ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) { /* Not enough space to start recording, check if cleanup helps */ cleanedBytes = dvr_disk_space_cleanup(cfg, 0); if (cleanedBytes == -1) return 0; - else if (cleanedBytes == -2) // Disk stats may be unreliable, continue anyway + else if (cleanedBytes == -2) // Disk stats may be unreliable, continue anyway return 1; availBytes += cleanedBytes; usedBytes -= cleanedBytes; - if (availBytes < requiredBytes || ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) + if (availBytes < requiredBytes || + ((maximalBytes < usedBytes) && cfg->dvr_cleanup_threshold_used)) return 0; } return 1; @@ -487,19 +503,15 @@ dvr_vfs_rec_start_check(dvr_config_t *cfg) /** * */ -void -dvr_disk_space_boot(void) -{ +void dvr_disk_space_boot(void) { LIST_INIT(&dvrvfs_list); } /** * */ -void -dvr_disk_space_init(void) -{ - dvr_config_t *cfg = dvr_config_find_by_name_default(NULL); +void dvr_disk_space_init(void) { + dvr_config_t* cfg = dvr_config_find_by_name_default(NULL); tvh_mutex_init(&dvr_disk_space_mutex, NULL); dvr_get_disk_space_update(cfg->dvr_storage, 1); mtimer_arm_rel(&dvr_disk_space_timer, dvr_get_disk_space_cb, NULL, sec2mono(5)); @@ -508,10 +520,8 @@ dvr_disk_space_init(void) /** * */ -void -dvr_disk_space_done(void) -{ - dvr_vfs_t *vfs; +void dvr_disk_space_done(void) { + dvr_vfs_t* vfs; tasklet_disarm(&dvr_disk_space_tasklet); tvh_mutex_lock(&global_lock); @@ -526,15 +536,13 @@ dvr_disk_space_done(void) /** * */ -int -dvr_get_disk_space(int64_t *bfree, int64_t *bused, int64_t *btotal) -{ +int dvr_get_disk_space(int64_t* bfree, int64_t* bused, int64_t* btotal) { int res = 0; tvh_mutex_lock(&dvr_disk_space_mutex); if (dvr_bfree || dvr_btotal) { - *bfree = dvr_bfree; - *bused = dvr_bused; + *bfree = dvr_bfree; + *bused = dvr_bused; *btotal = dvr_btotal; } else { res = -EINVAL; diff --git a/src/epg.c b/src/epg.c index c8f160233..72e0a68f8 100644 --- a/src/epg.c +++ b/src/epg.c @@ -55,13 +55,12 @@ epg_object_list_t epg_object_updated; int epg_in_load; /* Global counter */ -static uint32_t _epg_object_idx = 0; +static uint32_t _epg_object_idx = 0; /* * */ -static inline epg_object_tree_t *epg_id_tree( epg_object_t *eo ) -{ +static inline epg_object_tree_t* epg_id_tree(epg_object_t* eo) { return &epg_objects[eo->id & EPG_HASH_MASK]; } @@ -69,26 +68,22 @@ static inline epg_object_tree_t *epg_id_tree( epg_object_t *eo ) * Comparators / Ordering * *************************************************************************/ -static int _id_cmp ( const void *a, const void *b ) -{ +static int _id_cmp(const void* a, const void* b) { return ((epg_object_t*)a)->id - ((epg_object_t*)b)->id; } -static int _ebc_start_cmp ( const void *a, const void *b ) -{ +static int _ebc_start_cmp(const void* a, const void* b) { return ((epg_broadcast_t*)a)->start - ((epg_broadcast_t*)b)->start; } -void epg_updated ( void ) -{ - epg_object_t *eo; +void epg_updated(void) { + epg_object_t* eo; lock_assert(&global_lock); /* Remove unref'd */ while ((eo = LIST_FIRST(&epg_object_unref))) { - tvhtrace(LS_EPG, - "unref'd object %u created during update", eo->id); + tvhtrace(LS_EPG, "unref'd object %u created during update", eo->id); LIST_REMOVE(eo, un_link); eo->ops->destroy(eo); } @@ -109,31 +104,26 @@ void epg_updated ( void ) * Object (Generic routines) * *************************************************************************/ -static void _epg_object_destroy - ( epg_object_t *eo, epg_object_tree_t *tree ) -{ +static void _epg_object_destroy(epg_object_t* eo, epg_object_tree_t* tree) { assert(eo->refcount == 0); - tvhtrace(LS_EPG, "eo [%p, %u, %d] destroy", - eo, eo->id, eo->type); - if (eo->_updated) LIST_REMOVE(eo, up_link); + tvhtrace(LS_EPG, "eo [%p, %u, %d] destroy", eo, eo->id, eo->type); + if (eo->_updated) + LIST_REMOVE(eo, up_link); RB_REMOVE(epg_id_tree(eo), eo, id_link); } -static void _epg_object_getref ( void *o ) -{ - epg_object_t *eo = o; - tvhtrace(LS_EPG, "eo [%p, %u, %d] getref %d", - eo, eo->id, eo->type, eo->refcount+1); - if (eo->refcount == 0) LIST_REMOVE(eo, un_link); +static void _epg_object_getref(void* o) { + epg_object_t* eo = o; + tvhtrace(LS_EPG, "eo [%p, %u, %d] getref %d", eo, eo->id, eo->type, eo->refcount + 1); + if (eo->refcount == 0) + LIST_REMOVE(eo, un_link); eo->refcount++; } -static int _epg_object_putref ( void *o ) -{ - epg_object_t *eo = o; - tvhtrace(LS_EPG, "eo [%p, %u, %d] putref %d", - eo, eo->id, eo->type, eo->refcount-1); - assert(eo->refcount>0); +static int _epg_object_putref(void* o) { + epg_object_t* eo = o; + tvhtrace(LS_EPG, "eo [%p, %u, %d] putref %d", eo, eo->id, eo->type, eo->refcount - 1); + assert(eo->refcount > 0); eo->refcount--; if (!eo->refcount) { eo->ops->destroy(eo); @@ -142,52 +132,53 @@ static int _epg_object_putref ( void *o ) return 0; } -static void _epg_object_set_updated0 ( void *o ) -{ - epg_object_t *eo = o; - tvhtrace(LS_EPG, "eo [%p, %u, %d] updated", - eo, eo->id, eo->type); +static void _epg_object_set_updated0(void* o) { + epg_object_t* eo = o; + tvhtrace(LS_EPG, "eo [%p, %u, %d] updated", eo, eo->id, eo->type); eo->_updated = 1; eo->updated = gclk(); LIST_INSERT_HEAD(&epg_object_updated, eo, up_link); } -static inline void _epg_object_set_updated ( void *o ) -{ - if (!((epg_object_t *)o)->_updated) +static inline void _epg_object_set_updated(void* o) { + if (!((epg_object_t*)o)->_updated) _epg_object_set_updated0(o); } -static int _epg_object_can_remove ( void *_old, void *_new ) -{ +static int _epg_object_can_remove(void* _old, void* _new) { epggrab_module_t *ograb, *ngrab; - ngrab = ((epg_object_t *)_new)->grabber; - if (ngrab == NULL) return 0; - ograb = ((epg_object_t *)_old)->grabber; - if (ograb == NULL || ograb == ngrab) return 1; - if (ngrab->priority > ograb->priority) return 1; + ngrab = ((epg_object_t*)_new)->grabber; + if (ngrab == NULL) + return 0; + ograb = ((epg_object_t*)_old)->grabber; + if (ograb == NULL || ograb == ngrab) + return 1; + if (ngrab->priority > ograb->priority) + return 1; return 0; } -static int _epg_object_set_grabber ( void *o, epggrab_module_t *ngrab ) -{ - epggrab_module_t *ograb; - if (!ngrab) return 1; // grab=NULL is override - ograb = ((epg_object_t *)o)->grabber; - if (ograb == ngrab) return 1; - if (ograb && ograb->priority >= ngrab->priority) return 0; - ((epg_object_t *)o)->grabber = ngrab; +static int _epg_object_set_grabber(void* o, epggrab_module_t* ngrab) { + epggrab_module_t* ograb; + if (!ngrab) + return 1; // grab=NULL is override + ograb = ((epg_object_t*)o)->grabber; + if (ograb == ngrab) + return 1; + if (ograb && ograb->priority >= ngrab->priority) + return 0; + ((epg_object_t*)o)->grabber = ngrab; return 1; } -static void _epg_object_create ( void *o ) -{ - epg_object_t *eo = o; - uint32_t id = eo->id; - if (!id) eo->id = ++_epg_object_idx; - if (!eo->id) eo->id = ++_epg_object_idx; - tvhtrace(LS_EPG, "eo [%p, %u, %d] created", - eo, eo->id, eo->type); +static void _epg_object_create(void* o) { + epg_object_t* eo = o; + uint32_t id = eo->id; + if (!id) + eo->id = ++_epg_object_idx; + if (!eo->id) + eo->id = ++_epg_object_idx; + tvhtrace(LS_EPG, "eo [%p, %u, %d] created", eo, eo->id, eo->type); _epg_object_set_updated(eo); LIST_INSERT_HEAD(&epg_object_unref, eo, un_link); while (1) { @@ -198,27 +189,26 @@ static void _epg_object_create ( void *o ) abort(); } eo->id = ++_epg_object_idx; - if (!eo->id) eo->id = ++_epg_object_idx; + if (!eo->id) + eo->id = ++_epg_object_idx; } } -epg_object_t *epg_object_find_by_id ( uint32_t id, epg_object_type_t type ) -{ +epg_object_t* epg_object_find_by_id(uint32_t id, epg_object_type_t type) { epg_object_t *eo, temp; temp.id = id; - eo = RB_FIND(epg_id_tree(&temp), &temp, id_link, _id_cmp); + eo = RB_FIND(epg_id_tree(&temp), &temp, id_link, _id_cmp); if (eo && eo->type == type) return eo; return NULL; } -static htsmsg_t * _epg_object_serialize ( void *o ) -{ - htsmsg_t *m; - epg_object_t *eo = o; - tvhtrace(LS_EPG, "eo [%p, %u, %d] serialize", - eo, eo->id, eo->type); - if (!eo->id || !eo->type) return NULL; +static htsmsg_t* _epg_object_serialize(void* o) { + htsmsg_t* m; + epg_object_t* eo = o; + tvhtrace(LS_EPG, "eo [%p, %u, %d] serialize", eo, eo->id, eo->type); + if (!eo->id || !eo->type) + return NULL; m = htsmsg_create_map(); htsmsg_add_u32(m, "id", eo->id); htsmsg_add_u32(m, "tp", eo->type); @@ -228,34 +218,45 @@ static htsmsg_t * _epg_object_serialize ( void *o ) return m; } -static epg_object_t *_epg_object_deserialize ( htsmsg_t *m, epg_object_t *eo ) -{ - int64_t s64; - uint32_t u32; - const char *s; - if (htsmsg_get_u32(m, "id", &eo->id)) return NULL; - if (htsmsg_get_u32(m, "tp", &u32)) return NULL; - if (u32 != eo->type) return NULL; +static epg_object_t* _epg_object_deserialize(htsmsg_t* m, epg_object_t* eo) { + int64_t s64; + uint32_t u32; + const char* s; + if (htsmsg_get_u32(m, "id", &eo->id)) + return NULL; + if (htsmsg_get_u32(m, "tp", &u32)) + return NULL; + if (u32 != eo->type) + return NULL; if ((s = htsmsg_get_str(m, "gr"))) eo->grabber = epggrab_module_find_by_id(s); if (!htsmsg_get_s64(m, "up", &s64)) { _epg_object_set_updated(eo); eo->updated = s64; } - tvhtrace(LS_EPG, "eo [%p, %u, %d, %s, %s] deserialize", - eo, eo->id, eo->type, s, eo->grabber ? eo->grabber->id : NULL); + tvhtrace(LS_EPG, + "eo [%p, %u, %d, %s, %s] deserialize", + eo, + eo->id, + eo->type, + s, + eo->grabber ? eo->grabber->id : NULL); return eo; } -static int _epg_object_set_str - ( void *o, char **old, const char *newstr, - epg_changes_t *changed, epg_changes_t cflag ) -{ - int save = 0; - epg_object_t *eo = o; - if (!eo) return 0; - if (changed) *changed |= cflag; - if (!*old && !newstr) return 0; +static int _epg_object_set_str(void* o, + char** old, + const char* newstr, + epg_changes_t* changed, + epg_changes_t cflag) { + int save = 0; + epg_object_t* eo = o; + if (!eo) + return 0; + if (changed) + *changed |= cflag; + if (!*old && !newstr) + return 0; if (!*old || !newstr || strcmp(*old, newstr)) { free(*old); *old = newstr ? strdup(newstr) : NULL; @@ -266,62 +267,73 @@ static int _epg_object_set_str } /* "Template" for setting objects. */ -#define EPG_OBJECT_SET_FN(FNNAME,TYPE,DESTROY,COMPARE,COPY) \ -static int FNNAME \ - ( void *o, TYPE **old, const TYPE *new, \ - epg_changes_t *changed, epg_changes_t cflag ) \ -{ \ - if (!o) return 0; \ - if (changed) *changed |= cflag; \ - if (!*old) { \ - if (!new) \ - return 0; \ - } \ - if (!new) { \ - DESTROY(*old); \ - *old = NULL; \ - _epg_object_set_updated(o); \ - return 1; \ - } \ - if (COMPARE(*old, new)) { \ - DESTROY(*old); \ - *old = COPY(new); \ - _epg_object_set_updated(o); \ - return 1; \ - } \ - return 0; \ -} - -EPG_OBJECT_SET_FN(_epg_object_set_lang_str, lang_str_t, - lang_str_destroy, lang_str_compare, lang_str_copy) -EPG_OBJECT_SET_FN(_epg_object_set_string_list, string_list_t, - string_list_destroy, string_list_cmp, string_list_copy) -EPG_OBJECT_SET_FN(_epg_object_set_htsmsg, htsmsg_t, - htsmsg_destroy, htsmsg_cmp, htsmsg_copy) +#define EPG_OBJECT_SET_FN(FNNAME, TYPE, DESTROY, COMPARE, COPY) \ + static int FNNAME(void* o, \ + TYPE** old, \ + const TYPE* new, \ + epg_changes_t* changed, \ + epg_changes_t cflag) { \ + if (!o) \ + return 0; \ + if (changed) \ + *changed |= cflag; \ + if (!*old) { \ + if (!new) \ + return 0; \ + } \ + if (!new) { \ + DESTROY(*old); \ + *old = NULL; \ + _epg_object_set_updated(o); \ + return 1; \ + } \ + if (COMPARE(*old, new)) { \ + DESTROY(*old); \ + *old = COPY(new); \ + _epg_object_set_updated(o); \ + return 1; \ + } \ + return 0; \ + } + +EPG_OBJECT_SET_FN(_epg_object_set_lang_str, + lang_str_t, + lang_str_destroy, + lang_str_compare, + lang_str_copy) +EPG_OBJECT_SET_FN(_epg_object_set_string_list, + string_list_t, + string_list_destroy, + string_list_cmp, + string_list_copy) +EPG_OBJECT_SET_FN(_epg_object_set_htsmsg, htsmsg_t, htsmsg_destroy, htsmsg_cmp, htsmsg_copy) #undef EPG_OBJECT_SET_FN -#define EPG_OBJECT_SET_FN(FNNAME,TYPE) \ -static int FNNAME \ - ( void *o, TYPE *old, const TYPE nval, \ - epg_changes_t *changed, epg_changes_t cflag ) \ -{ \ - int save; \ - if (!o) return 0; \ - if (changed) *changed |= cflag; \ - if ((save = (*old != nval)) != 0) { \ - *old = nval; \ - _epg_object_set_updated(o); \ - } \ - return save; \ -} +#define EPG_OBJECT_SET_FN(FNNAME, TYPE) \ + static int FNNAME(void* o, \ + TYPE* old, \ + const TYPE nval, \ + epg_changes_t* changed, \ + epg_changes_t cflag) { \ + int save; \ + if (!o) \ + return 0; \ + if (changed) \ + *changed |= cflag; \ + if ((save = (*old != nval)) != 0) { \ + *old = nval; \ + _epg_object_set_updated(o); \ + } \ + return save; \ + } EPG_OBJECT_SET_FN(_epg_object_set_u8, uint8_t) EPG_OBJECT_SET_FN(_epg_object_set_u16, uint16_t) #undef EPG_OBJECT_SET_FN -htsmsg_t *epg_object_serialize ( epg_object_t *eo ) -{ - if (!eo) return NULL; +htsmsg_t* epg_object_serialize(epg_object_t* eo) { + if (!eo) + return NULL; switch (eo->type) { case EPG_BROADCAST: return epg_broadcast_serialize((epg_broadcast_t*)eo); @@ -330,10 +342,10 @@ htsmsg_t *epg_object_serialize ( epg_object_t *eo ) } } -epg_object_t *epg_object_deserialize ( htsmsg_t *msg, int create, int *save ) -{ +epg_object_t* epg_object_deserialize(htsmsg_t* msg, int create, int* save) { uint32_t type; - if (!msg) return NULL; + if (!msg) + return NULL; type = htsmsg_get_u32_or_default(msg, "type", 0); switch (type) { case EPG_BROADCAST: @@ -346,14 +358,13 @@ epg_object_t *epg_object_deserialize ( htsmsg_t *msg, int create, int *save ) * Episode * *************************************************************************/ -htsmsg_t *epg_episode_epnum_serialize ( epg_episode_num_t *num ) -{ - htsmsg_t *m; - if (!num) return NULL; - if (!num->e_num && !num->e_cnt && - !num->s_num && !num->s_cnt && - !num->p_num && !num->p_cnt && - !num->text) return NULL; +htsmsg_t* epg_episode_epnum_serialize(epg_episode_num_t* num) { + htsmsg_t* m; + if (!num) + return NULL; + if (!num->e_num && !num->e_cnt && !num->s_num && !num->s_cnt && !num->p_num && !num->p_cnt && + !num->text) + return NULL; m = htsmsg_create_map(); if (num->e_num) htsmsg_add_u32(m, "enum", num->e_num); @@ -372,67 +383,64 @@ htsmsg_t *epg_episode_epnum_serialize ( epg_episode_num_t *num ) return m; } -void epg_episode_epnum_deserialize - ( htsmsg_t *m, epg_episode_num_t *num ) -{ - const char *str; - uint32_t u32; +void epg_episode_epnum_deserialize(htsmsg_t* m, epg_episode_num_t* num) { + const char* str; + uint32_t u32; assert(m && num); memset(num, 0, sizeof(epg_episode_num_t)); - if (!htsmsg_get_u32(m, "enum", &u32) || - !htsmsg_get_u32(m, "e_num", &u32)) + if (!htsmsg_get_u32(m, "enum", &u32) || !htsmsg_get_u32(m, "e_num", &u32)) num->e_num = u32; - if (!htsmsg_get_u32(m, "ecnt", &u32) || - !htsmsg_get_u32(m, "e_cnt", &u32)) + if (!htsmsg_get_u32(m, "ecnt", &u32) || !htsmsg_get_u32(m, "e_cnt", &u32)) num->e_cnt = u32; - if (!htsmsg_get_u32(m, "snum", &u32) || - !htsmsg_get_u32(m, "s_num", &u32)) + if (!htsmsg_get_u32(m, "snum", &u32) || !htsmsg_get_u32(m, "s_num", &u32)) num->s_num = u32; - if (!htsmsg_get_u32(m, "scnt", &u32) || - !htsmsg_get_u32(m, "s_cnt", &u32)) + if (!htsmsg_get_u32(m, "scnt", &u32) || !htsmsg_get_u32(m, "s_cnt", &u32)) num->s_cnt = u32; - if (!htsmsg_get_u32(m, "pnum", &u32) || - !htsmsg_get_u32(m, "p_num", &u32)) + if (!htsmsg_get_u32(m, "pnum", &u32) || !htsmsg_get_u32(m, "p_num", &u32)) num->p_num = u32; - if (!htsmsg_get_u32(m, "pcnt", &u32) || - !htsmsg_get_u32(m, "p_cnt", &u32)) + if (!htsmsg_get_u32(m, "pcnt", &u32) || !htsmsg_get_u32(m, "p_cnt", &u32)) num->p_cnt = u32; if ((str = htsmsg_get_str(m, "text"))) num->text = strdup(str); } -size_t epg_episode_num_format - ( epg_episode_num_t *epnum, char *buf, size_t len, - const char *pre, const char *sfmt, - const char *sep, const char *efmt, - const char *cfmt ) -{ +size_t epg_episode_num_format(epg_episode_num_t* epnum, + char* buf, + size_t len, + const char* pre, + const char* sfmt, + const char* sep, + const char* efmt, + const char* cfmt) { size_t i = 0; - if (!epnum || !buf || !len) return 0; + if (!epnum || !buf || !len) + return 0; buf[0] = '\0'; if (epnum->e_num || epnum->s_num) { - if (pre) tvh_strlcatf(buf, len, i, "%s", pre); + if (pre) + tvh_strlcatf(buf, len, i, "%s", pre); if (sfmt && epnum->s_num) { tvh_strlcatf(buf, len, i, sfmt, epnum->s_num); if (cfmt && epnum->s_cnt) tvh_strlcatf(buf, len, i, cfmt, epnum->s_cnt); - if (sep && efmt && epnum->e_num) tvh_strlcatf(buf, len, i, "%s", sep); + if (sep && efmt && epnum->e_num) + tvh_strlcatf(buf, len, i, "%s", sep); } if (efmt && epnum->e_num) tvh_strlcatf(buf, len, i, efmt, epnum->e_num); if (cfmt && epnum->e_cnt) tvh_strlcatf(buf, len, i, cfmt, epnum->e_cnt); } else if (epnum->text) { - if (pre) tvh_strlcatf(buf, len, i, "%s", pre); + if (pre) + tvh_strlcatf(buf, len, i, "%s", pre); tvh_strlcatf(buf, len, i, "%s", epnum->text); } return i; } -int epg_episode_number_cmp ( const epg_episode_num_t *a, const epg_episode_num_t *b ) -{ +int epg_episode_number_cmp(const epg_episode_num_t* a, const epg_episode_num_t* b) { if (a->e_num) { if (a->s_num != b->s_num) { return a->s_num - b->s_num; @@ -447,20 +455,25 @@ int epg_episode_number_cmp ( const epg_episode_num_t *a, const epg_episode_num_t return 0; } -int epg_episode_number_cmpfull ( const epg_episode_num_t *a, const epg_episode_num_t *b ) -{ +int epg_episode_number_cmpfull(const epg_episode_num_t* a, const epg_episode_num_t* b) { int i = a->s_cnt - b->s_cnt; - if (i) return i; + if (i) + return i; i = a->s_num - b->s_num; - if (i) return i; + if (i) + return i; i = a->e_cnt - b->e_cnt; - if (i) return i; + if (i) + return i; i = a->e_num - b->e_num; - if (i) return i; + if (i) + return i; i = a->p_cnt - b->p_cnt; - if (i) return i; + if (i) + return i; i = a->p_num - b->p_num; - if (i) return i; + if (i) + return i; return strcasecmp(a->text ?: "", b->text ?: ""); } @@ -468,19 +481,19 @@ int epg_episode_number_cmpfull ( const epg_episode_num_t *a, const epg_episode_n * Channel * *************************************************************************/ -int epg_channel_ignore_broadcast(channel_t *ch, time_t start) -{ +int epg_channel_ignore_broadcast(channel_t* ch, time_t start) { if (ch->ch_epg_limit && start >= gclk() + ch->ch_epg_limit * 3600 * 24) return 1; return 0; } -static void _epg_channel_rem_broadcast - ( channel_t *ch, epg_broadcast_t *ebc, epg_broadcast_t *ebc_new ) -{ +static void +_epg_channel_rem_broadcast(channel_t* ch, epg_broadcast_t* ebc, epg_broadcast_t* ebc_new) { RB_REMOVE(&ch->ch_epg_schedule, ebc, sched_link); - if (ch->ch_epg_now == ebc) ch->ch_epg_now = NULL; - if (ch->ch_epg_next == ebc) ch->ch_epg_next = NULL; + if (ch->ch_epg_now == ebc) + ch->ch_epg_now = NULL; + if (ch->ch_epg_next == ebc) + ch->ch_epg_next = NULL; if (ebc_new) { dvr_event_replaced(ebc, ebc_new); } else { @@ -489,12 +502,11 @@ static void _epg_channel_rem_broadcast _epg_object_putref(ebc); } -static void _epg_channel_timer_callback ( void *p ) -{ - time_t next = 0; +static void _epg_channel_timer_callback(void* p) { + time_t next = 0; epg_broadcast_t *ebc, *cur, *nxt; - channel_t *ch = (channel_t*)p; - char tm1[32]; + channel_t* ch = (channel_t*)p; + char tm1[32]; /* Clear now/next */ if ((cur = ch->ch_epg_now)) { @@ -513,19 +525,21 @@ static void _epg_channel_timer_callback ( void *p ) while ((ebc = RB_FIRST(&ch->ch_epg_schedule))) { /* Expire */ - if ( ebc->stop <= gclk() ) { - tvhdebug(LS_EPG, "expire event %u (%s) from %s", - ebc->id, epg_broadcast_get_title(ebc, NULL), - channel_get_name(ch, channel_blank_name)); + if (ebc->stop <= gclk()) { + tvhdebug(LS_EPG, + "expire event %u (%s) from %s", + ebc->id, + epg_broadcast_get_title(ebc, NULL), + channel_get_name(ch, channel_blank_name)); _epg_channel_rem_broadcast(ch, ebc, NULL); continue; // skip to next - /* No now */ + /* No now */ } else if (ebc->start > gclk()) { ch->ch_epg_next = ebc; next = ebc->start; - /* Now/Next */ + /* Now/Next */ } else { ch->ch_epg_now = ebc; ch->ch_epg_next = RB_NEXT(ebc, sched_link); @@ -536,41 +550,51 @@ static void _epg_channel_timer_callback ( void *p ) /* Change (update HTSP) */ if (cur != ch->ch_epg_now || nxt != ch->ch_epg_next) { - tvhdebug(LS_EPG, "now/next %u/%u set on %s", - ch->ch_epg_now ? ch->ch_epg_now->id : 0, - ch->ch_epg_next ? ch->ch_epg_next->id : 0, - channel_get_name(ch, channel_blank_name)); - tvhdebug(LS_EPG, "inform HTSP of now event change on %s", - channel_get_name(ch, channel_blank_name)); + tvhdebug(LS_EPG, + "now/next %u/%u set on %s", + ch->ch_epg_now ? ch->ch_epg_now->id : 0, + ch->ch_epg_next ? ch->ch_epg_next->id : 0, + channel_get_name(ch, channel_blank_name)); + tvhdebug(LS_EPG, + "inform HTSP of now event change on %s", + channel_get_name(ch, channel_blank_name)); htsp_channel_update_nownext(ch); } /* re-arm */ if (next) { - tvhdebug(LS_EPG, "arm channel timer @ %s for %s", - gmtime2local(next, tm1, sizeof(tm1)), channel_get_name(ch, channel_blank_name)); + tvhdebug(LS_EPG, + "arm channel timer @ %s for %s", + gmtime2local(next, tm1, sizeof(tm1)), + channel_get_name(ch, channel_blank_name)); gtimer_arm_absn(&ch->ch_epg_timer, _epg_channel_timer_callback, ch, next); } /* Remove refs */ - if (cur) cur->ops->putref(cur); - if (nxt) nxt->ops->putref(nxt); -} - -static epg_broadcast_t *_epg_channel_add_broadcast - ( channel_t *ch, epg_broadcast_t **bcast, epggrab_module_t *src, - int create, int *save, epg_changes_t *changed ) -{ - int timer = 0; + if (cur) + cur->ops->putref(cur); + if (nxt) + nxt->ops->putref(nxt); +} + +static epg_broadcast_t* _epg_channel_add_broadcast(channel_t* ch, + epg_broadcast_t** bcast, + epggrab_module_t* src, + int create, + int* save, + epg_changes_t* changed) { + int timer = 0; epg_broadcast_t *ebc, *ret; - char tm1[32], tm2[32]; + char tm1[32], tm2[32]; if (!src) { - tvherror(LS_EPG, "skipped event (!grabber) %u (%s) on %s @ %s to %s", - (*bcast)->id, epg_broadcast_get_title(*bcast, NULL), - channel_get_name(ch, channel_blank_name), - gmtime2local((*bcast)->start, tm1, sizeof(tm1)), - gmtime2local((*bcast)->stop, tm2, sizeof(tm2))); + tvherror(LS_EPG, + "skipped event (!grabber) %u (%s) on %s @ %s to %s", + (*bcast)->id, + epg_broadcast_get_title(*bcast, NULL), + channel_get_name(ch, channel_blank_name), + gmtime2local((*bcast)->start, tm1, sizeof(tm1)), + gmtime2local((*bcast)->stop, tm2, sizeof(tm2))); return NULL; } @@ -578,16 +602,17 @@ static epg_broadcast_t *_epg_channel_add_broadcast (*bcast)->channel = ch; /* Find (only) */ - if ( !create ) { + if (!create) { return RB_FIND(&ch->ch_epg_schedule, *bcast, sched_link, _ebc_start_cmp); - /* Find/Create */ + /* Find/Create */ } else { ret = RB_INSERT_SORTED(&ch->ch_epg_schedule, *bcast, sched_link, _ebc_start_cmp); /* New */ if (!ret) { - if (changed) *changed |= EPG_CHANGED_CREATE; + if (changed) + *changed |= EPG_CHANGED_CREATE; *save = 1; ret = *bcast; *bcast = NULL; @@ -595,14 +620,16 @@ static epg_broadcast_t *_epg_channel_add_broadcast // Note: sets updated _epg_object_getref(ret); ret->grabber = src; - tvhtrace(LS_EPG, "added event %u (%s) on %s @ %s to %s (grabber %s)", - ret->id, epg_broadcast_get_title(ret, NULL), - channel_get_name(ch, channel_blank_name), - gmtime2local(ret->start, tm1, sizeof(tm1)), - gmtime2local(ret->stop, tm2, sizeof(tm2)), - src->id); - - /* Existing */ + tvhtrace(LS_EPG, + "added event %u (%s) on %s @ %s to %s (grabber %s)", + ret->id, + epg_broadcast_get_title(ret, NULL), + channel_get_name(ch, channel_blank_name), + gmtime2local(ret->start, tm1, sizeof(tm1)), + gmtime2local(ret->stop, tm2, sizeof(tm2)), + src->id); + + /* Existing */ } else { if (!_epg_object_set_grabber(ret, src)) return NULL; @@ -611,16 +638,18 @@ static epg_broadcast_t *_epg_channel_add_broadcast if (ret->stop == (*bcast)->stop) { return ret; - /* Extend in time */ + /* Extend in time */ } else { ret->stop = (*bcast)->stop; _epg_object_set_updated(ret); - tvhtrace(LS_EPG, "updated event %u (%s) on %s @ %s to %s (grabber %s)", - ret->id, epg_broadcast_get_title(ret, NULL), - channel_get_name(ch, channel_blank_name), - gmtime2local(ret->start, tm1, sizeof(tm1)), - gmtime2local(ret->stop, tm2, sizeof(tm2)), - src->id); + tvhtrace(LS_EPG, + "updated event %u (%s) on %s @ %s to %s (grabber %s)", + ret->id, + epg_broadcast_get_title(ret, NULL), + channel_get_name(ch, channel_blank_name), + gmtime2local(ret->start, tm1, sizeof(tm1)), + gmtime2local(ret->stop, tm2, sizeof(tm2)), + src->id); } } } @@ -630,87 +659,100 @@ static epg_broadcast_t *_epg_channel_add_broadcast /* Remove overlapping (before) */ while ((ebc = RB_PREV(ret, sched_link)) != NULL) { - if (ebc->stop <= ret->start) break; + if (ebc->stop <= ret->start) + break; if (!_epg_object_can_remove(ebc, ret)) { - tvhtrace(LS_EPG, "grabber %s for event %u has higher priority than overlap (b), removing added", - ebc->grabber->id, ebc->id); + tvhtrace(LS_EPG, + "grabber %s for event %u has higher priority than overlap (b), removing added", + ebc->grabber->id, + ebc->id); _epg_channel_rem_broadcast(ch, ret, NULL); return NULL; } if (config.epg_cut_window && ebc->stop - ebc->start > config.epg_cut_window * 2 && ebc->stop - ret->start <= config.epg_cut_window) { - tvhtrace(LS_EPG, "cut stop for overlap (b) event %u (%s) on %s @ %s to %s", - ebc->id, epg_broadcast_get_title(ebc, NULL), - channel_get_name(ch, channel_blank_name), - gmtime2local(ebc->start, tm1, sizeof(tm1)), - gmtime2local(ebc->stop, tm2, sizeof(tm2))); + tvhtrace(LS_EPG, + "cut stop for overlap (b) event %u (%s) on %s @ %s to %s", + ebc->id, + epg_broadcast_get_title(ebc, NULL), + channel_get_name(ch, channel_blank_name), + gmtime2local(ebc->start, tm1, sizeof(tm1)), + gmtime2local(ebc->stop, tm2, sizeof(tm2))); ebc->stop = ret->start; _epg_object_set_updated(ebc); continue; } - tvhtrace(LS_EPG, "remove overlap (b) event %u (%s) on %s @ %s to %s", - ebc->id, epg_broadcast_get_title(ebc, NULL), - channel_get_name(ch, channel_blank_name), - gmtime2local(ebc->start, tm1, sizeof(tm1)), - gmtime2local(ebc->stop, tm2, sizeof(tm2))); + tvhtrace(LS_EPG, + "remove overlap (b) event %u (%s) on %s @ %s to %s", + ebc->id, + epg_broadcast_get_title(ebc, NULL), + channel_get_name(ch, channel_blank_name), + gmtime2local(ebc->start, tm1, sizeof(tm1)), + gmtime2local(ebc->stop, tm2, sizeof(tm2))); _epg_channel_rem_broadcast(ch, ebc, ret); } /* Remove overlapping (after) */ while ((ebc = RB_NEXT(ret, sched_link)) != NULL) { - if (ebc->start >= ret->stop) break; + if (ebc->start >= ret->stop) + break; if (!_epg_object_can_remove(ebc, ret)) { - tvhtrace(LS_EPG, "grabber %s for event %u has higher priority than overlap (a), removing added", - ebc->grabber->id, ebc->id); + tvhtrace(LS_EPG, + "grabber %s for event %u has higher priority than overlap (a), removing added", + ebc->grabber->id, + ebc->id); _epg_channel_rem_broadcast(ch, ret, NULL); return NULL; } if (config.epg_cut_window && ret->stop - ret->start > config.epg_cut_window * 2 && ret->stop - ebc->start <= config.epg_cut_window) { - tvhtrace(LS_EPG, "cut stop for overlap (a) event %u (%s) on %s @ %s to %s", - ebc->id, epg_broadcast_get_title(ebc, NULL), - channel_get_name(ch, channel_blank_name), - gmtime2local(ebc->start, tm1, sizeof(tm1)), - gmtime2local(ebc->stop, tm2, sizeof(tm2))); + tvhtrace(LS_EPG, + "cut stop for overlap (a) event %u (%s) on %s @ %s to %s", + ebc->id, + epg_broadcast_get_title(ebc, NULL), + channel_get_name(ch, channel_blank_name), + gmtime2local(ebc->start, tm1, sizeof(tm1)), + gmtime2local(ebc->stop, tm2, sizeof(tm2))); ret->stop = ebc->start; _epg_object_set_updated(ebc); continue; } - tvhtrace(LS_EPG, "remove overlap (a) event %u (%s) on %s @ %s to %s", - ebc->id, epg_broadcast_get_title(ebc, NULL), - channel_get_name(ch, channel_blank_name), - gmtime2local(ebc->start, tm1, sizeof(tm1)), - gmtime2local(ebc->stop, tm2, sizeof(tm2))); + tvhtrace(LS_EPG, + "remove overlap (a) event %u (%s) on %s @ %s to %s", + ebc->id, + epg_broadcast_get_title(ebc, NULL), + channel_get_name(ch, channel_blank_name), + gmtime2local(ebc->start, tm1, sizeof(tm1)), + gmtime2local(ebc->stop, tm2, sizeof(tm2))); _epg_channel_rem_broadcast(ch, ebc, ret); } /* Check now/next change */ if (RB_FIRST(&ch->ch_epg_schedule) == ret) { timer = 1; - } else if (ch->ch_epg_now && - RB_NEXT(ch->ch_epg_now, sched_link) == ret) { + } else if (ch->ch_epg_now && RB_NEXT(ch->ch_epg_now, sched_link) == ret) { timer = 1; } /* Reset timer - it might free return event! */ ret->ops->getref(ret); - if (timer) _epg_channel_timer_callback(ch); - if (ret->ops->putref(ret)) return NULL; + if (timer) + _epg_channel_timer_callback(ch); + if (ret->ops->putref(ret)) + return NULL; return ret; } -void epg_channel_unlink ( channel_t *ch ) -{ - epg_broadcast_t *ebc; +void epg_channel_unlink(channel_t* ch) { + epg_broadcast_t* ebc; while ((ebc = RB_FIRST(&ch->ch_epg_schedule))) _epg_channel_rem_broadcast(ch, ebc, NULL); gtimer_disarm(&ch->ch_epg_timer); } -static int epg_match_event_fuzzy(epg_broadcast_t *a, epg_broadcast_t *b) -{ - time_t t1, t2; - const char *title1, *title2; +static int epg_match_event_fuzzy(epg_broadcast_t* a, epg_broadcast_t* b) { + time_t t1, t2; + const char * title1, *title2; epg_episode_num_t num1, num2; if (a == NULL || b == NULL) @@ -752,9 +794,8 @@ static int epg_match_event_fuzzy(epg_broadcast_t *a, epg_broadcast_t *b) return 0; } -epg_broadcast_t *epg_match_now_next ( channel_t *ch, epg_broadcast_t *ebc ) -{ - epg_broadcast_t *ret; +epg_broadcast_t* epg_match_now_next(channel_t* ch, epg_broadcast_t* ebc) { + epg_broadcast_t* ret; if (epg_match_event_fuzzy(ch->ch_epg_now, ebc)) ret = ch->ch_epg_now; @@ -772,29 +813,23 @@ epg_broadcast_t *epg_match_now_next ( channel_t *ch, epg_broadcast_t *ebc ) * Broadcast set * *************************************************************************/ -static int _set_uri_cmp(const void *_a, const void *_b) -{ +static int _set_uri_cmp(const void* _a, const void* _b) { const epg_set_t *a = _a, *b = _b; return strcmp(a->uri, b->uri); } -epg_set_t *epg_set_broadcast_find_by_uri - (epg_set_tree_t *tree, const char *uri) -{ - epg_set_t *dummy; +epg_set_t* epg_set_broadcast_find_by_uri(epg_set_tree_t* tree, const char* uri) { + epg_set_t* dummy; if (tree == NULL || uri == NULL || uri[0] == '\0') return NULL; - dummy = (epg_set_t *)(uri - offsetof(epg_set_t, uri)); + dummy = (epg_set_t*)(uri - offsetof(epg_set_t, uri)); return RB_FIND(tree, dummy, set_link, _set_uri_cmp); } - -epg_set_t *epg_set_broadcast_insert - (epg_set_tree_t *tree, epg_broadcast_t *b, const char *uri) -{ - epg_set_t *es; - epg_set_item_t *item; +epg_set_t* epg_set_broadcast_insert(epg_set_tree_t* tree, epg_broadcast_t* b, const char* uri) { + epg_set_t* es; + epg_set_item_t* item; if (tree == NULL || b == NULL) return NULL; @@ -807,20 +842,18 @@ epg_set_t *epg_set_broadcast_insert strcpy(es->uri, uri); RB_INSERT_SORTED(tree, es, set_link, _set_uri_cmp); } - item = malloc(sizeof(*item)); + item = malloc(sizeof(*item)); item->broadcast = b; LIST_INSERT_HEAD(&es->broadcasts, item, item_link); return es; } -void epg_set_broadcast_remove - (epg_set_tree_t *tree, epg_set_t *set, epg_broadcast_t *b) -{ - epg_set_item_t *item; +void epg_set_broadcast_remove(epg_set_tree_t* tree, epg_set_t* set, epg_broadcast_t* b) { + epg_set_item_t* item; if (tree == NULL || set == NULL) return; - LIST_FOREACH(item, &set->broadcasts, item_link) + LIST_FOREACH (item, &set->broadcasts, item_link) if (item->broadcast == b) { LIST_REMOVE(item, item_link); free(item); @@ -837,32 +870,40 @@ void epg_set_broadcast_remove * Broadcast * *************************************************************************/ -static void _epg_broadcast_destroy ( void *eo ) -{ - epg_broadcast_t *ebc = eo; - epg_genre_t *eg; - char id[16]; +static void _epg_broadcast_destroy(void* eo) { + epg_broadcast_t* ebc = eo; + epg_genre_t* eg; + char id[16]; if (ebc->_created) { htsp_event_delete(ebc); snprintf(id, sizeof(id), "%u", ebc->id); notify_delayed(id, "epg", "delete"); } - if (ebc->title) lang_str_destroy(ebc->title); - if (ebc->subtitle) lang_str_destroy(ebc->subtitle); - if (ebc->summary) lang_str_destroy(ebc->summary); - if (ebc->description) lang_str_destroy(ebc->description); + if (ebc->title) + lang_str_destroy(ebc->title); + if (ebc->subtitle) + lang_str_destroy(ebc->subtitle); + if (ebc->summary) + lang_str_destroy(ebc->summary); + if (ebc->description) + lang_str_destroy(ebc->description); while ((eg = LIST_FIRST(&ebc->genre))) { LIST_REMOVE(eg, link); free(eg); } free(ebc->image); free(ebc->epnum.text); - if (ebc->credits) htsmsg_destroy(ebc->credits); - if (ebc->credits_cached) lang_str_destroy(ebc->credits_cached); - if (ebc->category) string_list_destroy(ebc->category); - if (ebc->keyword) string_list_destroy(ebc->keyword); - if (ebc->keyword_cached) lang_str_destroy(ebc->keyword_cached); + if (ebc->credits) + htsmsg_destroy(ebc->credits); + if (ebc->credits_cached) + lang_str_destroy(ebc->credits_cached); + if (ebc->category) + string_list_destroy(ebc->category); + if (ebc->keyword) + string_list_destroy(ebc->keyword); + if (ebc->keyword_cached) + lang_str_destroy(ebc->keyword_cached); epg_set_broadcast_remove(&epg_serieslinks, ebc->serieslink, ebc); epg_set_broadcast_remove(&epg_episodelinks, ebc->episodelink, ebc); _epg_object_destroy(eo, NULL); @@ -870,15 +911,14 @@ static void _epg_broadcast_destroy ( void *eo ) free(ebc); } -static void _epg_broadcast_update_running ( epg_broadcast_t *broadcast ) -{ - channel_t *ch; - epg_broadcast_t *now; - int orunning = broadcast->running; +static void _epg_broadcast_update_running(epg_broadcast_t* broadcast) { + channel_t* ch; + epg_broadcast_t* now; + int orunning = broadcast->running; broadcast->running = broadcast->update_running; - ch = broadcast->channel; - now = ch ? ch->ch_epg_now : NULL; + ch = broadcast->channel; + now = ch ? ch->ch_epg_now : NULL; if (broadcast->update_running == EPG_RUNNING_STOP) { if (now == broadcast && orunning == broadcast->running) broadcast->stop = gclk() - 1; @@ -892,10 +932,9 @@ static void _epg_broadcast_update_running ( epg_broadcast_t *broadcast ) broadcast->update_running = EPG_RUNNING_NOTSET; } -static void _epg_broadcast_updated ( void *eo ) -{ - epg_broadcast_t *ebc = eo; - char id[16]; +static void _epg_broadcast_updated(void* eo) { + epg_broadcast_t* ebc = eo; + char id[16]; if (!epg_in_load) snprintf(id, sizeof(id), "%u", ebc->id); @@ -919,45 +958,50 @@ static void _epg_broadcast_updated ( void *eo ) } static epg_object_ops_t _epg_broadcast_ops = { - .getref = _epg_object_getref, - .putref = _epg_object_putref, - .destroy = _epg_broadcast_destroy, - .update = _epg_broadcast_updated, + .getref = _epg_object_getref, + .putref = _epg_object_putref, + .destroy = _epg_broadcast_destroy, + .update = _epg_broadcast_updated, }; -static epg_broadcast_t **_epg_broadcast_skel ( void ) -{ - static epg_broadcast_t *skel = NULL; +static epg_broadcast_t** _epg_broadcast_skel(void) { + static epg_broadcast_t* skel = NULL; if (!skel) { - skel = calloc(1, sizeof(epg_broadcast_t)); + skel = calloc(1, sizeof(epg_broadcast_t)); skel->type = EPG_BROADCAST; skel->ops = &_epg_broadcast_ops; } return &skel; } -epg_broadcast_t *epg_broadcast_find_by_time - ( channel_t *channel, epggrab_module_t *src, - time_t start, time_t stop, int create, int *save, epg_changes_t *changed ) -{ - epg_broadcast_t **ebc; - if (!channel || !start || !stop) return NULL; - if (stop <= start) return NULL; - if (stop <= gclk()) return NULL; +epg_broadcast_t* epg_broadcast_find_by_time(channel_t* channel, + epggrab_module_t* src, + time_t start, + time_t stop, + int create, + int* save, + epg_changes_t* changed) { + epg_broadcast_t** ebc; + if (!channel || !start || !stop) + return NULL; + if (stop <= start) + return NULL; + if (stop <= gclk()) + return NULL; - ebc = _epg_broadcast_skel(); - (*ebc)->start = start; - (*ebc)->stop = stop; + ebc = _epg_broadcast_skel(); + (*ebc)->start = start; + (*ebc)->stop = stop; return _epg_channel_add_broadcast(channel, ebc, src, create, save, changed); } -int epg_broadcast_change_finish - ( epg_broadcast_t *broadcast, epg_changes_t changes, int merge ) -{ +int epg_broadcast_change_finish(epg_broadcast_t* broadcast, epg_changes_t changes, int merge) { int save = 0; - if (merge) return 0; - if (changes & EPG_CHANGED_CREATE) return 0; + if (merge) + return 0; + if (changes & EPG_CHANGED_CREATE) + return 0; if (!(changes & EPG_CHANGED_SERIESLINK)) save |= epg_broadcast_set_serieslink_uri(broadcast, NULL, NULL); if (!(changes & EPG_CHANGED_EPISODE)) @@ -1029,16 +1073,13 @@ int epg_broadcast_change_finish return save; } -epg_broadcast_t *epg_broadcast_clone - ( channel_t *channel, epg_broadcast_t *src, int *save ) -{ - epg_broadcast_t *ebc; - epg_changes_t changes = 0; +epg_broadcast_t* epg_broadcast_clone(channel_t* channel, epg_broadcast_t* src, int* save) { + epg_broadcast_t* ebc; + epg_changes_t changes = 0; - if (!src) return NULL; - ebc = epg_broadcast_find_by_time(channel, src->grabber, - src->start, src->stop, - 1, save, &changes); + if (!src) + return NULL; + ebc = epg_broadcast_find_by_time(channel, src->grabber, src->start, src->stop, 1, save, &changes); if (ebc) { /* Copy metadata */ *save |= epg_broadcast_set_is_widescreen(ebc, src->is_widescreen, &changes); @@ -1064,10 +1105,12 @@ epg_broadcast_t *epg_broadcast_clone *save |= epg_broadcast_set_credits(ebc, src->credits, &changes); *save |= epg_broadcast_set_category(ebc, src->category, &changes); *save |= epg_broadcast_set_keyword(ebc, src->keyword, &changes); - *save |= epg_broadcast_set_serieslink_uri - (ebc, src->serieslink ? src->serieslink->uri : NULL, &changes); - *save |= epg_broadcast_set_episodelink_uri - (ebc, src->episodelink ? src->episodelink->uri : NULL, &changes); + *save |= epg_broadcast_set_serieslink_uri(ebc, + src->serieslink ? src->serieslink->uri : NULL, + &changes); + *save |= epg_broadcast_set_episodelink_uri(ebc, + src->episodelink ? src->episodelink->uri : NULL, + &changes); *save |= epg_broadcast_set_first_aired(ebc, src->first_aired, &changes); *save |= epg_broadcast_set_copyright_year(ebc, src->copyright_year, &changes); _epg_object_set_grabber(ebc, src->grabber); @@ -1076,23 +1119,20 @@ epg_broadcast_t *epg_broadcast_clone return ebc; } -epg_broadcast_t *epg_broadcast_find_by_id ( uint32_t id ) -{ +epg_broadcast_t* epg_broadcast_find_by_id(uint32_t id) { return (epg_broadcast_t*)epg_object_find_by_id(id, EPG_BROADCAST); } -epg_broadcast_t *epg_broadcast_find_by_eid ( channel_t *ch, uint16_t eid ) -{ - epg_broadcast_t *e; - RB_FOREACH(e, &ch->ch_epg_schedule, sched_link) { - if (e->dvb_eid == eid && e->stop > gclk()) return e; +epg_broadcast_t* epg_broadcast_find_by_eid(channel_t* ch, uint16_t eid) { + epg_broadcast_t* e; + RB_FOREACH (e, &ch->ch_epg_schedule, sched_link) { + if (e->dvb_eid == eid && e->stop > gclk()) + return e; } return NULL; } -int epg_broadcast_set_running - ( epg_broadcast_t *broadcast, epg_running_t running ) -{ +int epg_broadcast_set_running(epg_broadcast_t* broadcast, epg_running_t running) { int save = 0; if (running != broadcast->running) { broadcast->update_running = running; @@ -1102,10 +1142,10 @@ int epg_broadcast_set_running return save; } -static int _epg_broadcast_set_set - ( epg_broadcast_t *ebc, const char *uri, - epg_set_tree_t *tree, epg_set_t **set ) -{ +static int _epg_broadcast_set_set(epg_broadcast_t* ebc, + const char* uri, + epg_set_tree_t* tree, + epg_set_t** set) { if (*set == NULL) { if (uri == NULL || uri[0] == '\0') return 0; @@ -1118,205 +1158,181 @@ static int _epg_broadcast_set_set return 1; } - -int epg_broadcast_set_serieslink_uri - ( epg_broadcast_t *ebc, const char *uri, epg_changes_t *changed ) -{ - if (!ebc) return 0; - if (changed) *changed |= EPG_CHANGED_SERIESLINK; +int epg_broadcast_set_serieslink_uri(epg_broadcast_t* ebc, + const char* uri, + epg_changes_t* changed) { + if (!ebc) + return 0; + if (changed) + *changed |= EPG_CHANGED_SERIESLINK; return _epg_broadcast_set_set(ebc, uri, &epg_serieslinks, &ebc->serieslink); } -int epg_broadcast_set_episodelink_uri - ( epg_broadcast_t *ebc, const char *uri, epg_changes_t *changed ) -{ - if (!ebc) return 0; - if (changed) *changed |= EPG_CHANGED_EPISODE; +int epg_broadcast_set_episodelink_uri(epg_broadcast_t* ebc, + const char* uri, + epg_changes_t* changed) { + if (!ebc) + return 0; + if (changed) + *changed |= EPG_CHANGED_EPISODE; return _epg_broadcast_set_set(ebc, uri, &epg_episodelinks, &ebc->episodelink); } -int epg_broadcast_set_dvb_eid - ( epg_broadcast_t *b, uint16_t dvb_eid, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u16(b, &b->dvb_eid, dvb_eid, - changed, EPG_CHANGED_DVB_EID); +int epg_broadcast_set_dvb_eid(epg_broadcast_t* b, uint16_t dvb_eid, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u16(b, &b->dvb_eid, dvb_eid, changed, EPG_CHANGED_DVB_EID); } -int epg_broadcast_set_is_widescreen - ( epg_broadcast_t *b, uint8_t ws, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u8(b, &b->is_widescreen, ws, - changed, EPG_CHANGED_IS_WIDESCREEN); +int epg_broadcast_set_is_widescreen(epg_broadcast_t* b, uint8_t ws, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u8(b, &b->is_widescreen, ws, changed, EPG_CHANGED_IS_WIDESCREEN); } -int epg_broadcast_set_is_hd - ( epg_broadcast_t *b, uint8_t hd, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u8(b, &b->is_hd, hd, - changed, EPG_CHANGED_IS_HD); +int epg_broadcast_set_is_hd(epg_broadcast_t* b, uint8_t hd, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u8(b, &b->is_hd, hd, changed, EPG_CHANGED_IS_HD); } -int epg_broadcast_set_lines - ( epg_broadcast_t *b, uint16_t lines, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u16(b, &b->lines, lines, - changed, EPG_CHANGED_LINES); +int epg_broadcast_set_lines(epg_broadcast_t* b, uint16_t lines, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u16(b, &b->lines, lines, changed, EPG_CHANGED_LINES); } -int epg_broadcast_set_aspect - ( epg_broadcast_t *b, uint16_t aspect, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u16(b, &b->aspect, aspect, - changed, EPG_CHANGED_ASPECT); +int epg_broadcast_set_aspect(epg_broadcast_t* b, uint16_t aspect, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u16(b, &b->aspect, aspect, changed, EPG_CHANGED_ASPECT); } -int epg_broadcast_set_is_deafsigned - ( epg_broadcast_t *b, uint8_t ds, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u8(b, &b->is_deafsigned, ds, - changed, EPG_CHANGED_DEAFSIGNED); +int epg_broadcast_set_is_deafsigned(epg_broadcast_t* b, uint8_t ds, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u8(b, &b->is_deafsigned, ds, changed, EPG_CHANGED_DEAFSIGNED); } -int epg_broadcast_set_is_subtitled - ( epg_broadcast_t *b, uint8_t st, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u8(b, &b->is_subtitled, st, - changed, EPG_CHANGED_SUBTITLED); +int epg_broadcast_set_is_subtitled(epg_broadcast_t* b, uint8_t st, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u8(b, &b->is_subtitled, st, changed, EPG_CHANGED_SUBTITLED); } -int epg_broadcast_set_is_audio_desc - ( epg_broadcast_t *b, uint8_t ad, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u8(b, &b->is_audio_desc, ad, - changed, EPG_CHANGED_AUDIO_DESC); +int epg_broadcast_set_is_audio_desc(epg_broadcast_t* b, uint8_t ad, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u8(b, &b->is_audio_desc, ad, changed, EPG_CHANGED_AUDIO_DESC); } -int epg_broadcast_set_is_new - ( epg_broadcast_t *b, uint8_t n, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u8(b, &b->is_new, n, - changed, EPG_CHANGED_IS_NEW); +int epg_broadcast_set_is_new(epg_broadcast_t* b, uint8_t n, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u8(b, &b->is_new, n, changed, EPG_CHANGED_IS_NEW); } -int epg_broadcast_set_is_repeat - ( epg_broadcast_t *b, uint8_t r, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u8(b, &b->is_repeat, r, - changed, EPG_CHANGED_IS_REPEAT); +int epg_broadcast_set_is_repeat(epg_broadcast_t* b, uint8_t r, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u8(b, &b->is_repeat, r, changed, EPG_CHANGED_IS_REPEAT); } -int epg_broadcast_set_is_bw - ( epg_broadcast_t *b, uint8_t bw, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u8(b, &b->is_bw, bw, - changed, EPG_CHANGED_IS_BW); +int epg_broadcast_set_is_bw(epg_broadcast_t* b, uint8_t bw, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u8(b, &b->is_bw, bw, changed, EPG_CHANGED_IS_BW); } -int epg_broadcast_set_star_rating - ( epg_broadcast_t *b, uint8_t stars, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u8(b, &b->star_rating, stars, - changed, EPG_CHANGED_STAR_RATING); +int epg_broadcast_set_star_rating(epg_broadcast_t* b, uint8_t stars, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u8(b, &b->star_rating, stars, changed, EPG_CHANGED_STAR_RATING); } -int epg_broadcast_set_title - ( epg_broadcast_t *b, const lang_str_t *title, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_lang_str(b, &b->title, title, - changed, EPG_CHANGED_TITLE); +int epg_broadcast_set_title(epg_broadcast_t* b, const lang_str_t* title, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_lang_str(b, &b->title, title, changed, EPG_CHANGED_TITLE); } -int epg_broadcast_set_subtitle - ( epg_broadcast_t *b, const lang_str_t *subtitle, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_lang_str(b, &b->subtitle, - subtitle, changed, EPG_CHANGED_SUBTITLE); +int epg_broadcast_set_subtitle(epg_broadcast_t* b, + const lang_str_t* subtitle, + epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_lang_str(b, &b->subtitle, subtitle, changed, EPG_CHANGED_SUBTITLE); } -int epg_broadcast_set_summary - ( epg_broadcast_t *b, const lang_str_t *str, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_lang_str(b, &b->summary, str, - changed, EPG_CHANGED_SUMMARY); +int epg_broadcast_set_summary(epg_broadcast_t* b, const lang_str_t* str, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_lang_str(b, &b->summary, str, changed, EPG_CHANGED_SUMMARY); } -int epg_broadcast_set_description - ( epg_broadcast_t *b, const lang_str_t *str, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_lang_str(b, &b->description, str, - changed, EPG_CHANGED_DESCRIPTION); +int epg_broadcast_set_description(epg_broadcast_t* b, + const lang_str_t* str, + epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_lang_str(b, &b->description, str, changed, EPG_CHANGED_DESCRIPTION); } -int epg_broadcast_set_credits -( epg_broadcast_t *b, const htsmsg_t *credits, epg_changes_t *changed ) -{ - if (!b) return 0; +int epg_broadcast_set_credits(epg_broadcast_t* b, const htsmsg_t* credits, epg_changes_t* changed) { + if (!b) + return 0; const int mod = _epg_object_set_htsmsg(b, &b->credits, credits, changed, EPG_CHANGED_CREDITS); if (mod) { - /* Copy in to cached csv for regex searching in autorec/GUI. - * We use just one string (rather than regex across each entry - * separately) so you could do a regex of "Douglas.*Stallone" - * to match the movies with the two actors. - */ - if (!b->credits_cached) { - b->credits_cached = lang_str_create(); - } - lang_str_set(&b->credits_cached, "", NULL); - - if (b->credits) { - int add_sep = 0; - htsmsg_field_t *f; - HTSMSG_FOREACH(f, b->credits) { - if (add_sep) { - lang_str_append(b->credits_cached, ", ", NULL); - } else { - add_sep = 1; - } - lang_str_append(b->credits_cached, htsmsg_field_name(f), NULL); - } - } else { - if (b->credits_cached) { - lang_str_destroy(b->credits_cached); - b->credits_cached = NULL; + /* Copy in to cached csv for regex searching in autorec/GUI. + * We use just one string (rather than regex across each entry + * separately) so you could do a regex of "Douglas.*Stallone" + * to match the movies with the two actors. + */ + if (!b->credits_cached) { + b->credits_cached = lang_str_create(); + } + lang_str_set(&b->credits_cached, "", NULL); + + if (b->credits) { + int add_sep = 0; + htsmsg_field_t* f; + HTSMSG_FOREACH(f, b->credits) { + if (add_sep) { + lang_str_append(b->credits_cached, ", ", NULL); + } else { + add_sep = 1; } + lang_str_append(b->credits_cached, htsmsg_field_name(f), NULL); } + } else { + if (b->credits_cached) { + lang_str_destroy(b->credits_cached); + b->credits_cached = NULL; + } + } } return mod; } -int epg_broadcast_set_category -( epg_broadcast_t *b, const string_list_t *msg, epg_changes_t *changed ) -{ - if (!b) return 0; +int epg_broadcast_set_category(epg_broadcast_t* b, + const string_list_t* msg, + epg_changes_t* changed) { + if (!b) + return 0; return _epg_object_set_string_list(b, &b->category, msg, changed, EPG_CHANGED_CATEGORY); } -int epg_broadcast_set_keyword -( epg_broadcast_t *b, const string_list_t *msg, epg_changes_t *changed ) -{ - if (!b) return 0; +int epg_broadcast_set_keyword(epg_broadcast_t* b, + const string_list_t* msg, + epg_changes_t* changed) { + if (!b) + return 0; const int mod = _epg_object_set_string_list(b, &b->keyword, msg, changed, EPG_CHANGED_KEYWORD); if (mod) { /* Copy in to cached csv for regex searching in autorec/GUI. */ if (msg) { /* 1==>human readable */ - char *str = string_list_2_csv(msg, ',', 1); + char* str = string_list_2_csv(msg, ',', 1); lang_str_set(&b->keyword_cached, str, NULL); free(str); } else { @@ -1329,81 +1345,67 @@ int epg_broadcast_set_keyword return mod; } -int epg_broadcast_set_image - ( epg_broadcast_t *b, const char *image, epg_changes_t *changed ) -{ +int epg_broadcast_set_image(epg_broadcast_t* b, const char* image, epg_changes_t* changed) { int save; - if (!b) return 0; - save = _epg_object_set_str(b, &b->image, image, - changed, EPG_CHANGED_IMAGE); + if (!b) + return 0; + save = _epg_object_set_str(b, &b->image, image, changed, EPG_CHANGED_IMAGE); if (save) imagecache_get_id(image); return save; } -int epg_broadcast_set_epnumber - ( epg_broadcast_t *b, uint16_t number, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u16(b, &b->epnum.e_num, number, - changed, EPG_CHANGED_EPNUM_NUM); +int epg_broadcast_set_epnumber(epg_broadcast_t* b, uint16_t number, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u16(b, &b->epnum.e_num, number, changed, EPG_CHANGED_EPNUM_NUM); } -int epg_broadcast_set_eppart - ( epg_broadcast_t *b, uint16_t part, uint16_t count, - epg_changes_t *changed ) -{ +int epg_broadcast_set_eppart(epg_broadcast_t* b, + uint16_t part, + uint16_t count, + epg_changes_t* changed) { int save = 0; - if (!b) return 0; - save |= _epg_object_set_u16(b, &b->epnum.p_num, part, - changed, EPG_CHANGED_EPPAR_NUM); - save |= _epg_object_set_u16(b, &b->epnum.p_cnt, count, - changed, EPG_CHANGED_EPPAR_CNT); + if (!b) + return 0; + save |= _epg_object_set_u16(b, &b->epnum.p_num, part, changed, EPG_CHANGED_EPPAR_NUM); + save |= _epg_object_set_u16(b, &b->epnum.p_cnt, count, changed, EPG_CHANGED_EPPAR_CNT); return save; } -int epg_broadcast_set_epnum - ( epg_broadcast_t *b, epg_episode_num_t *num, epg_changes_t *changed ) -{ - int save = 0; - static epg_episode_num_t _zero = { 0 }; +int epg_broadcast_set_epnum(epg_broadcast_t* b, epg_episode_num_t* num, epg_changes_t* changed) { + int save = 0; + static epg_episode_num_t _zero = {0}; if (!b) return 0; if (!num) num = &_zero; if (num->s_num) - save |= _epg_object_set_u16(b, &b->epnum.s_num, - num->s_num, changed, EPG_CHANGED_EPSER_NUM); + save |= _epg_object_set_u16(b, &b->epnum.s_num, num->s_num, changed, EPG_CHANGED_EPSER_NUM); if (num->s_cnt) - save |= _epg_object_set_u16(b, &b->epnum.s_cnt, - num->s_cnt, changed, EPG_CHANGED_EPSER_CNT); + save |= _epg_object_set_u16(b, &b->epnum.s_cnt, num->s_cnt, changed, EPG_CHANGED_EPSER_CNT); if (num->e_num) - save |= _epg_object_set_u16(b, &b->epnum.e_num, - num->e_num, changed, EPG_CHANGED_EPNUM_NUM); + save |= _epg_object_set_u16(b, &b->epnum.e_num, num->e_num, changed, EPG_CHANGED_EPNUM_NUM); if (num->e_cnt) - save |= _epg_object_set_u16(b, &b->epnum.e_cnt, - num->e_cnt, changed, EPG_CHANGED_EPNUM_CNT); + save |= _epg_object_set_u16(b, &b->epnum.e_cnt, num->e_cnt, changed, EPG_CHANGED_EPNUM_CNT); if (num->p_num) - save |= _epg_object_set_u16(b, &b->epnum.p_num, - num->p_num, changed, EPG_CHANGED_EPPAR_NUM); + save |= _epg_object_set_u16(b, &b->epnum.p_num, num->p_num, changed, EPG_CHANGED_EPPAR_NUM); if (num->p_cnt) - save |= _epg_object_set_u16(b, &b->epnum.p_cnt, - num->p_cnt, changed, EPG_CHANGED_EPPAR_CNT); + save |= _epg_object_set_u16(b, &b->epnum.p_cnt, num->p_cnt, changed, EPG_CHANGED_EPPAR_CNT); if (num->text) - save |= _epg_object_set_str(b, &b->epnum.text, - num->text, changed, EPG_CHANGED_EPTEXT); + save |= _epg_object_set_str(b, &b->epnum.text, num->text, changed, EPG_CHANGED_EPTEXT); return save; } -int epg_broadcast_set_genre - ( epg_broadcast_t *b, epg_genre_list_t *genre, epg_changes_t *changed ) -{ - int save = 0; +int epg_broadcast_set_genre(epg_broadcast_t* b, epg_genre_list_t* genre, epg_changes_t* changed) { + int save = 0; epg_genre_t *g1, *g2; - if (!b) return 0; + if (!b) + return 0; - if (changed) *changed |= EPG_CHANGED_GENRE; + if (changed) + *changed |= EPG_CHANGED_GENRE; g1 = LIST_FIRST(&b->genre); @@ -1420,48 +1422,46 @@ int epg_broadcast_set_genre /* Insert all entries */ if (genre) { - LIST_FOREACH(g1, genre, link) + LIST_FOREACH (g1, genre, link) save |= epg_genre_list_add(&b->genre, g1); } return save; } -int epg_broadcast_set_copyright_year - ( epg_broadcast_t *b, uint16_t year, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u16(b, &b->copyright_year, year, - changed, EPG_CHANGED_COPYRIGHT_YEAR); +int epg_broadcast_set_copyright_year(epg_broadcast_t* b, uint16_t year, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u16(b, &b->copyright_year, year, changed, EPG_CHANGED_COPYRIGHT_YEAR); } -int epg_broadcast_set_age_rating - ( epg_broadcast_t *b, uint8_t age, epg_changes_t *changed ) -{ - if (!b) return 0; - return _epg_object_set_u8(b, &b->age_rating, age, - changed, EPG_CHANGED_AGE_RATING); +int epg_broadcast_set_age_rating(epg_broadcast_t* b, uint8_t age, epg_changes_t* changed) { + if (!b) + return 0; + return _epg_object_set_u8(b, &b->age_rating, age, changed, EPG_CHANGED_AGE_RATING); } -int epg_broadcast_set_rating_label - ( epg_broadcast_t *b, ratinglabel_t *rating_label, epg_changes_t *changed ) -{ - if (!b || !rating_label) return 0; +int epg_broadcast_set_rating_label(epg_broadcast_t* b, + ratinglabel_t* rating_label, + epg_changes_t* changed) { + if (!b || !rating_label) + return 0; - if(rating_label != b->rating_label){ + if (rating_label != b->rating_label) { b->rating_label = rating_label; - if (changed) *changed |= EPG_CHANGED_RATING_LABEL; + if (changed) + *changed |= EPG_CHANGED_RATING_LABEL; return 1; } return 0; } -int epg_broadcast_set_first_aired - ( epg_broadcast_t *b, time_t aired, epg_changes_t *changed ) -{ - if (!b) return 0; - if (changed) *changed |= EPG_CHANGED_FIRST_AIRED; +int epg_broadcast_set_first_aired(epg_broadcast_t* b, time_t aired, epg_changes_t* changed) { + if (!b) + return 0; + if (changed) + *changed |= EPG_CHANGED_FIRST_AIRED; if (b->first_aired != aired) { b->first_aired = aired; _epg_object_set_updated(b); @@ -1470,61 +1470,60 @@ int epg_broadcast_set_first_aired return 0; } -epg_broadcast_t *epg_broadcast_get_prev ( epg_broadcast_t *b ) -{ - if (!b) return NULL; +epg_broadcast_t* epg_broadcast_get_prev(epg_broadcast_t* b) { + if (!b) + return NULL; return RB_PREV(b, sched_link); } -epg_broadcast_t *epg_broadcast_get_next ( epg_broadcast_t *b ) -{ - if (!b) return NULL; +epg_broadcast_t* epg_broadcast_get_next(epg_broadcast_t* b) { + if (!b) + return NULL; return RB_NEXT(b, sched_link); } -const char *epg_broadcast_get_title ( const epg_broadcast_t *b, const char *lang ) -{ - if (!b || !b->title) return NULL; +const char* epg_broadcast_get_title(const epg_broadcast_t* b, const char* lang) { + if (!b || !b->title) + return NULL; return lang_str_get(b->title, lang); } -const char *epg_broadcast_get_subtitle ( epg_broadcast_t *b, const char *lang ) -{ - if (!b || !b->subtitle) return NULL; +const char* epg_broadcast_get_subtitle(epg_broadcast_t* b, const char* lang) { + if (!b || !b->subtitle) + return NULL; return lang_str_get(b->subtitle, lang); } -const ratinglabel_t *epg_broadcast_get_rating_label ( epg_broadcast_t *b ) -{ - if (!b || !b->rating_label) return NULL; +const ratinglabel_t* epg_broadcast_get_rating_label(epg_broadcast_t* b) { + if (!b || !b->rating_label) + return NULL; return b->rating_label; } -const char *epg_broadcast_get_summary ( epg_broadcast_t *b, const char *lang ) -{ - if (!b || !b->summary) return NULL; +const char* epg_broadcast_get_summary(epg_broadcast_t* b, const char* lang) { + if (!b || !b->summary) + return NULL; return lang_str_get(b->summary, lang); } -const char *epg_broadcast_get_credits_cached ( epg_broadcast_t *b, const char *lang) -{ - if (!b || !b->credits_cached) return NULL; +const char* epg_broadcast_get_credits_cached(epg_broadcast_t* b, const char* lang) { + if (!b || !b->credits_cached) + return NULL; return lang_str_get(b->credits_cached, lang); } -const char *epg_broadcast_get_keyword_cached ( epg_broadcast_t *b, const char *lang) -{ - if (!b || !b->keyword_cached) return NULL; +const char* epg_broadcast_get_keyword_cached(epg_broadcast_t* b, const char* lang) { + if (!b || !b->keyword_cached) + return NULL; return lang_str_get(b->keyword_cached, lang); } -const char *epg_broadcast_get_description ( epg_broadcast_t *b, const char *lang ) -{ - if (!b || !b->description) return NULL; +const char* epg_broadcast_get_description(epg_broadcast_t* b, const char* lang) { + if (!b || !b->description) + return NULL; return lang_str_get(b->description, lang); } -void epg_broadcast_get_epnum ( const epg_broadcast_t *b, epg_episode_num_t *num ) -{ +void epg_broadcast_get_epnum(const epg_broadcast_t* b, epg_episode_num_t* num) { if (!b || !num) { if (num) memset(num, 0, sizeof(*num)); @@ -1533,26 +1532,29 @@ void epg_broadcast_get_epnum ( const epg_broadcast_t *b, epg_episode_num_t *num *num = b->epnum; } -size_t epg_broadcast_epnumber_format - ( epg_broadcast_t *b, char *buf, size_t len, - const char *pre, const char *sfmt, - const char *sep, const char *efmt, - const char *cfmt ) -{ - if (!b) return 0; +size_t epg_broadcast_epnumber_format(epg_broadcast_t* b, + char* buf, + size_t len, + const char* pre, + const char* sfmt, + const char* sep, + const char* efmt, + const char* cfmt) { + if (!b) + return 0; epg_episode_num_t num; epg_broadcast_get_epnum(b, &num); - return epg_episode_num_format(&num, buf, len, pre, - sfmt, sep, efmt, cfmt); + return epg_episode_num_format(&num, buf, len, pre, sfmt, sep, efmt, cfmt); } -htsmsg_t *epg_broadcast_serialize ( epg_broadcast_t *broadcast ) -{ - htsmsg_t *m, *a; - epg_genre_t *eg; - char ubuf[UUID_HEX_SIZE]; - if (!broadcast) return NULL; - if (!(m = _epg_object_serialize((epg_object_t*)broadcast))) return NULL; +htsmsg_t* epg_broadcast_serialize(epg_broadcast_t* broadcast) { + htsmsg_t * m, *a; + epg_genre_t* eg; + char ubuf[UUID_HEX_SIZE]; + if (!broadcast) + return NULL; + if (!(m = _epg_object_serialize((epg_object_t*)broadcast))) + return NULL; htsmsg_add_s64(m, "start", broadcast->start); htsmsg_add_s64(m, "stop", broadcast->stop); if (broadcast->channel) @@ -1583,10 +1585,9 @@ htsmsg_t *epg_broadcast_serialize ( epg_broadcast_t *broadcast ) htsmsg_add_u32(m, "star", broadcast->star_rating); if (broadcast->age_rating) htsmsg_add_u32(m, "age", broadcast->age_rating); - if (broadcast->rating_label) - { - htsmsg_add_str(m, "ratlab", idnode_uuid_as_str((idnode_t *)(broadcast->rating_label), ubuf)); - } + if (broadcast->rating_label) { + htsmsg_add_str(m, "ratlab", idnode_uuid_as_str((idnode_t*)(broadcast->rating_label), ubuf)); + } if (broadcast->image) htsmsg_add_str(m, "img", broadcast->image); if (broadcast->title) @@ -1600,11 +1601,13 @@ htsmsg_t *epg_broadcast_serialize ( epg_broadcast_t *broadcast ) if ((a = epg_episode_epnum_serialize(&broadcast->epnum)) != NULL) htsmsg_add_msg(m, "epn", a); a = NULL; - LIST_FOREACH(eg, &broadcast->genre, link) { - if (!a) a = htsmsg_create_list(); + LIST_FOREACH (eg, &broadcast->genre, link) { + if (!a) + a = htsmsg_create_list(); htsmsg_add_u32(a, NULL, eg->code); } - if (a) htsmsg_add_msg(m, "genre", a); + if (a) + htsmsg_add_msg(m, "genre", a); if (broadcast->copyright_year) htsmsg_add_u32(m, "cyear", broadcast->copyright_year); if (broadcast->first_aired) @@ -1624,41 +1627,46 @@ htsmsg_t *epg_broadcast_serialize ( epg_broadcast_t *broadcast ) return m; } -epg_broadcast_t *epg_broadcast_deserialize - ( htsmsg_t *m, int create, int *save ) -{ - channel_t *ch = NULL; - epg_broadcast_t *ebc, **skel = _epg_broadcast_skel(); - lang_str_t *ls; - htsmsg_t *hm; - htsmsg_field_t *f; - string_list_t *sl; - const char *str; - uint32_t eid, u32; - epg_changes_t changes = 0; - int64_t start, stop, s64; +epg_broadcast_t* epg_broadcast_deserialize(htsmsg_t* m, int create, int* save) { + channel_t* ch = NULL; + epg_broadcast_t * ebc, **skel = _epg_broadcast_skel(); + lang_str_t* ls; + htsmsg_t* hm; + htsmsg_field_t* f; + string_list_t* sl; + const char* str; + uint32_t eid, u32; + epg_changes_t changes = 0; + int64_t start, stop, s64; epg_episode_num_t num; - if (htsmsg_get_s64(m, "start", &start)) return NULL; - if (htsmsg_get_s64(m, "stop", &stop)) return NULL; - if (!start || !stop) return NULL; - if (stop <= start) return NULL; - if (stop <= gclk()) return NULL; + if (htsmsg_get_s64(m, "start", &start)) + return NULL; + if (htsmsg_get_s64(m, "stop", &stop)) + return NULL; + if (!start || !stop) + return NULL; + if (stop <= start) + return NULL; + if (stop <= gclk()) + return NULL; _epg_object_deserialize(m, (epg_object_t*)*skel); /* Set properties */ - (*skel)->start = start; - (*skel)->stop = stop; + (*skel)->start = start; + (*skel)->stop = stop; /* Get channel */ if ((str = htsmsg_get_str(m, "ch"))) ch = channel_find(str); - if (!ch) return NULL; + if (!ch) + return NULL; /* Create */ ebc = _epg_channel_add_broadcast(ch, skel, (*skel)->grabber, create, save, &changes); - if (!ebc) return NULL; + if (!ebc) + return NULL; /* Get metadata */ if (!htsmsg_get_u32(m, "eid", &eid)) @@ -1687,10 +1695,9 @@ epg_broadcast_t *epg_broadcast_deserialize *save |= epg_broadcast_set_star_rating(ebc, u32, &changes); if (!htsmsg_get_u32(m, "age", &u32)) *save |= epg_broadcast_set_age_rating(ebc, u32, &changes); - if ((str = htsmsg_get_str(m, "ratlab"))) - { - //Convert the UUID string saved on disk into an idnode ID - //and then fetch the ratinglabel object. + if ((str = htsmsg_get_str(m, "ratlab"))) { + // Convert the UUID string saved on disk into an idnode ID + // and then fetch the ratinglabel object. *save |= epg_broadcast_set_rating_label(ebc, ratinglabel_find_from_uuid(str), &changes); } @@ -1698,7 +1705,7 @@ epg_broadcast_t *epg_broadcast_deserialize *save |= epg_broadcast_set_image(ebc, str, &changes); if ((hm = htsmsg_get_list(m, "genre"))) { - epg_genre_list_t *egl = calloc(1, sizeof(epg_genre_list_t)); + epg_genre_list_t* egl = calloc(1, sizeof(epg_genre_list_t)); HTSMSG_FOREACH(f, hm) { epg_genre_t genre; genre.code = (uint8_t)f->hmf_s64; @@ -1728,7 +1735,8 @@ epg_broadcast_t *epg_broadcast_deserialize if ((hm = htsmsg_get_map(m, "epn"))) { epg_episode_epnum_deserialize(hm, &num); *save |= epg_broadcast_set_epnum(ebc, &num, &changes); - if (num.text) free(num.text); + if (num.text) + free(num.text); } if (!htsmsg_get_u32(m, "cyear", &u32)) @@ -1771,225 +1779,243 @@ epg_broadcast_t *epg_broadcast_deserialize // Reference (Sept 2016): // http://www.etsi.org/deliver/etsi_en/300400_300499/300468/01.11.01_60/en_300468v011101p.pdf -#define C_ (const char *[]) -static const char **_epg_genre_names[16][16] = { - { /* 00 */ - C_{ "", NULL } - }, - { /* 01 */ - C_{ N_("Movie"), N_("Drama"), NULL }, - C_{ N_("Detective"), N_("Thriller"), NULL }, - C_{ N_("Adventure"), N_("Western"), N_("War"), NULL }, - C_{ N_("Science fiction"), N_("Fantasy"), N_("Horror"), NULL }, - C_{ N_("Comedy"), NULL }, - C_{ N_("Soap"), N_("Melodrama"), N_("Folkloric"), NULL }, - C_{ N_("Romance"), NULL }, - C_{ N_("Serious"), N_("Classical"), N_("Religious"), N_("Historical movie"), N_("Drama"), NULL }, - C_{ N_("Adult movie"), N_("Drama"), NULL }, - C_{ N_("Movie / drama"), NULL }, - C_{ N_("Movie / drama"), NULL }, - C_{ N_("Movie / drama"), NULL }, - C_{ N_("Movie / drama"), NULL }, - C_{ N_("Movie / drama"), NULL }, - C_{ N_("Movie / drama"), NULL }, - C_{ N_("Movie / drama"), NULL }, - }, - { /* 02 */ - C_{ N_("News"), N_("Current affairs"), NULL }, - C_{ N_("News"), N_("Weather report"), NULL }, - C_{ N_("News magazine"), NULL }, - C_{ N_("Documentary"), NULL }, - C_{ N_("Discussion"), N_("Interview"), N_("Debate"), NULL }, - C_{ N_("News / Current Affairs"), NULL }, - C_{ N_("News / Current Affairs"), NULL }, - C_{ N_("News / Current Affairs"), NULL }, - C_{ N_("News / Current Affairs"), NULL }, - C_{ N_("News / Current Affairs"), NULL }, - C_{ N_("News / Current Affairs"), NULL }, - C_{ N_("News / Current Affairs"), NULL }, - C_{ N_("News / Current Affairs"), NULL }, - C_{ N_("News / Current Affairs"), NULL }, - C_{ N_("News / Current Affairs"), NULL }, - C_{ N_("News / Current Affairs"), NULL }, - }, - { /* 03 */ - C_{ N_("Show"), N_("Game show"), NULL }, - C_{ N_("Game show"), N_("Quiz"), N_("Contest"), NULL }, - C_{ N_("Variety show"), NULL }, - C_{ N_("Talk show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - C_{ N_("Show / Game show"), NULL }, - }, - { /* 04 */ - C_{ N_("Sports"), NULL }, - C_{ N_("Special events (Olympic Games, World Cup, etc.)"), NULL }, - C_{ N_("Sports magazines"), NULL }, - C_{ N_("Football"), N_("Soccer"), NULL }, - C_{ N_("Tennis"), N_("Squash"), NULL }, - C_{ N_("Team sports (excluding football)"), NULL }, - C_{ N_("Athletics"), NULL }, - C_{ N_("Motor sport"), NULL }, - C_{ N_("Water sport"), NULL }, - C_{ N_("Winter sports"), NULL }, - C_{ N_("Equestrian"), NULL }, - C_{ N_("Martial sports"), NULL }, - C_{ N_("Sports"), NULL }, - C_{ N_("Sports"), NULL }, - C_{ N_("Sports"), NULL }, - C_{ N_("Sports"), NULL }, - }, - { /* 05 */ - C_{ N_("Children's / Youth programs"), NULL }, - C_{ N_("Pre-school children's programs"), NULL }, - C_{ N_("Entertainment programs for 6 to 14"), NULL }, - C_{ N_("Entertainment programs for 10 to 16"), NULL }, - C_{ N_("Informational"), N_("Educational"), N_("School programs"), NULL }, - C_{ N_("Cartoons"), N_("Puppets"), NULL }, - C_{ N_("Children's / Youth Programs"), NULL }, - C_{ N_("Children's / Youth Programs"), NULL }, - C_{ N_("Children's / Youth Programs"), NULL }, - C_{ N_("Children's / Youth Programs"), NULL }, - C_{ N_("Children's / Youth Programs"), NULL }, - C_{ N_("Children's / Youth Programs"), NULL }, - C_{ N_("Children's / Youth Programs"), NULL }, - C_{ N_("Children's / Youth Programs"), NULL }, - C_{ N_("Children's / Youth Programs"), NULL }, - C_{ N_("Children's / Youth Programs"), NULL }, - }, - { /* 06 */ - C_{ N_("Music"), N_("Ballet"), N_("Dance"), NULL }, - C_{ N_("Rock"), N_("Pop"), NULL }, - C_{ N_("Serious music"), N_("Classical music"), NULL }, - C_{ N_("Folk"), N_("Traditional music"), NULL }, - C_{ N_("Jazz"), NULL }, - C_{ N_("Musical"), N_("Opera"), NULL }, - C_{ N_("Ballet"), NULL }, - C_{ N_("Music / Ballet / Dance"), NULL }, - C_{ N_("Music / Ballet / Dance"), NULL }, - C_{ N_("Music / Ballet / Dance"), NULL }, - C_{ N_("Music / Ballet / Dance"), NULL }, - C_{ N_("Music / Ballet / Dance"), NULL }, - C_{ N_("Music / Ballet / Dance"), NULL }, - C_{ N_("Music / Ballet / Dance"), NULL }, - C_{ N_("Music / Ballet / Dance"), NULL }, - C_{ N_("Music / Ballet / Dance"), NULL }, - }, - { /* 07 */ - C_{ N_("Arts"), N_("Culture (without music)"), NULL }, - C_{ N_("Performing arts"), NULL }, - C_{ N_("Fine arts"), NULL }, - C_{ N_("Religion"), NULL }, - C_{ N_("Popular culture"), N_("Traditional arts"), NULL }, - C_{ N_("Literature"), NULL }, - C_{ N_("Film"), N_("Cinema"), NULL }, - C_{ N_("Experimental film"), N_("Video"), NULL }, - C_{ N_("Broadcasting"), N_("Press"), NULL }, - C_{ N_("New media"), NULL }, - C_{ N_("Arts magazines"), N_("Culture magazines"), NULL }, - C_{ N_("Fashion"), NULL }, - C_{ N_("Arts / Culture (without music)"), NULL }, - C_{ N_("Arts / Culture (without music)"), NULL }, - C_{ N_("Arts / Culture (without music)"), NULL }, - C_{ N_("Arts / Culture (without music)"), NULL }, - }, - { /* 08 */ - C_{ N_("Social"), N_("Political issues"), N_("Economics"), NULL }, - C_{ N_("Magazines"), N_("Reports"), N_("Documentary"), NULL }, - C_{ N_("Economics"), N_("Social advisory"), NULL }, - C_{ N_("Remarkable people"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - C_{ N_("Social / Political issues / Economics"), NULL }, - }, - { /* 09 */ - C_{ N_("Education"), N_("Science"), N_("Factual topics"), NULL }, - C_{ N_("Nature"), N_("Animals"), N_("Environment"), NULL }, - C_{ N_("Technology"), N_("Natural sciences"), NULL }, - C_{ N_("Medicine"), N_("Physiology"), N_("Psychology"), NULL }, - C_{ N_("Foreign countries"), N_("Expeditions"), NULL }, - C_{ N_("Social"), N_("Spiritual sciences"), NULL }, - C_{ N_("Further education"), NULL }, - C_{ N_("Languages"), NULL }, - C_{ N_("Education / Science / Factual topics"), NULL }, - C_{ N_("Education / Science / Factual topics"), NULL }, - C_{ N_("Education / Science / Factual topics"), NULL }, - C_{ N_("Education / Science / Factual topics"), NULL }, - C_{ N_("Education / Science / Factual topics"), NULL }, - C_{ N_("Education / Science / Factual topics"), NULL }, - C_{ N_("Education / Science / Factual topics"), NULL }, - C_{ N_("Education / Science / Factual topics"), NULL }, - }, - { /* 10 */ - C_{ N_("Leisure hobbies"), NULL }, - C_{ N_("Tourism / Travel"), NULL }, - C_{ N_("Handicraft"), NULL }, - C_{ N_("Motoring"), NULL }, - C_{ N_("Fitness and health"), NULL }, - C_{ N_("Cooking"), NULL }, - C_{ N_("Advertisement / Shopping"), NULL }, - C_{ N_("Gardening"), NULL }, - C_{ N_("Leisure hobbies"), NULL }, - C_{ N_("Leisure hobbies"), NULL }, - C_{ N_("Leisure hobbies"), NULL }, - C_{ N_("Leisure hobbies"), NULL }, - C_{ N_("Leisure hobbies"), NULL }, - C_{ N_("Leisure hobbies"), NULL }, - C_{ N_("Leisure hobbies"), NULL }, - C_{ N_("Leisure hobbies"), NULL }, - } -}; - -static const char *_genre_get_name(int a, int b, const char *lang) -{ +#define C_ (const char*[]) +static const char** _epg_genre_names[16][16] = {{/* 00 */ + C_{"", NULL}}, + { + /* 01 */ + C_{N_("Movie"), N_("Drama"), NULL}, + C_{N_("Detective"), N_("Thriller"), NULL}, + C_{N_("Adventure"), N_("Western"), N_("War"), NULL}, + C_{N_("Science fiction"), N_("Fantasy"), N_("Horror"), NULL}, + C_{N_("Comedy"), NULL}, + C_{N_("Soap"), N_("Melodrama"), N_("Folkloric"), NULL}, + C_{N_("Romance"), NULL}, + C_{N_("Serious"), + N_("Classical"), + N_("Religious"), + N_("Historical movie"), + N_("Drama"), + NULL}, + C_{N_("Adult movie"), N_("Drama"), NULL}, + C_{N_("Movie / drama"), NULL}, + C_{N_("Movie / drama"), NULL}, + C_{N_("Movie / drama"), NULL}, + C_{N_("Movie / drama"), NULL}, + C_{N_("Movie / drama"), NULL}, + C_{N_("Movie / drama"), NULL}, + C_{N_("Movie / drama"), NULL}, + }, + { + /* 02 */ + C_{N_("News"), N_("Current affairs"), NULL}, + C_{N_("News"), N_("Weather report"), NULL}, + C_{N_("News magazine"), NULL}, + C_{N_("Documentary"), NULL}, + C_{N_("Discussion"), N_("Interview"), N_("Debate"), NULL}, + C_{N_("News / Current Affairs"), NULL}, + C_{N_("News / Current Affairs"), NULL}, + C_{N_("News / Current Affairs"), NULL}, + C_{N_("News / Current Affairs"), NULL}, + C_{N_("News / Current Affairs"), NULL}, + C_{N_("News / Current Affairs"), NULL}, + C_{N_("News / Current Affairs"), NULL}, + C_{N_("News / Current Affairs"), NULL}, + C_{N_("News / Current Affairs"), NULL}, + C_{N_("News / Current Affairs"), NULL}, + C_{N_("News / Current Affairs"), NULL}, + }, + { + /* 03 */ + C_{N_("Show"), N_("Game show"), NULL}, + C_{N_("Game show"), N_("Quiz"), N_("Contest"), NULL}, + C_{N_("Variety show"), NULL}, + C_{N_("Talk show"), NULL}, + C_{N_("Show / Game show"), NULL}, + C_{N_("Show / Game show"), NULL}, + C_{N_("Show / Game show"), NULL}, + C_{N_("Show / Game show"), NULL}, + C_{N_("Show / Game show"), NULL}, + C_{N_("Show / Game show"), NULL}, + C_{N_("Show / Game show"), NULL}, + C_{N_("Show / Game show"), NULL}, + C_{N_("Show / Game show"), NULL}, + C_{N_("Show / Game show"), NULL}, + C_{N_("Show / Game show"), NULL}, + C_{N_("Show / Game show"), NULL}, + }, + { + /* 04 */ + C_{N_("Sports"), NULL}, + C_{N_("Special events (Olympic Games, World Cup, etc.)"), NULL}, + C_{N_("Sports magazines"), NULL}, + C_{N_("Football"), N_("Soccer"), NULL}, + C_{N_("Tennis"), N_("Squash"), NULL}, + C_{N_("Team sports (excluding football)"), NULL}, + C_{N_("Athletics"), NULL}, + C_{N_("Motor sport"), NULL}, + C_{N_("Water sport"), NULL}, + C_{N_("Winter sports"), NULL}, + C_{N_("Equestrian"), NULL}, + C_{N_("Martial sports"), NULL}, + C_{N_("Sports"), NULL}, + C_{N_("Sports"), NULL}, + C_{N_("Sports"), NULL}, + C_{N_("Sports"), NULL}, + }, + { + /* 05 */ + C_{N_("Children's / Youth programs"), NULL}, + C_{N_("Pre-school children's programs"), NULL}, + C_{N_("Entertainment programs for 6 to 14"), NULL}, + C_{N_("Entertainment programs for 10 to 16"), NULL}, + C_{N_("Informational"), N_("Educational"), N_("School programs"), NULL}, + C_{N_("Cartoons"), N_("Puppets"), NULL}, + C_{N_("Children's / Youth Programs"), NULL}, + C_{N_("Children's / Youth Programs"), NULL}, + C_{N_("Children's / Youth Programs"), NULL}, + C_{N_("Children's / Youth Programs"), NULL}, + C_{N_("Children's / Youth Programs"), NULL}, + C_{N_("Children's / Youth Programs"), NULL}, + C_{N_("Children's / Youth Programs"), NULL}, + C_{N_("Children's / Youth Programs"), NULL}, + C_{N_("Children's / Youth Programs"), NULL}, + C_{N_("Children's / Youth Programs"), NULL}, + }, + { + /* 06 */ + C_{N_("Music"), N_("Ballet"), N_("Dance"), NULL}, + C_{N_("Rock"), N_("Pop"), NULL}, + C_{N_("Serious music"), N_("Classical music"), NULL}, + C_{N_("Folk"), N_("Traditional music"), NULL}, + C_{N_("Jazz"), NULL}, + C_{N_("Musical"), N_("Opera"), NULL}, + C_{N_("Ballet"), NULL}, + C_{N_("Music / Ballet / Dance"), NULL}, + C_{N_("Music / Ballet / Dance"), NULL}, + C_{N_("Music / Ballet / Dance"), NULL}, + C_{N_("Music / Ballet / Dance"), NULL}, + C_{N_("Music / Ballet / Dance"), NULL}, + C_{N_("Music / Ballet / Dance"), NULL}, + C_{N_("Music / Ballet / Dance"), NULL}, + C_{N_("Music / Ballet / Dance"), NULL}, + C_{N_("Music / Ballet / Dance"), NULL}, + }, + { + /* 07 */ + C_{N_("Arts"), N_("Culture (without music)"), NULL}, + C_{N_("Performing arts"), NULL}, + C_{N_("Fine arts"), NULL}, + C_{N_("Religion"), NULL}, + C_{N_("Popular culture"), N_("Traditional arts"), NULL}, + C_{N_("Literature"), NULL}, + C_{N_("Film"), N_("Cinema"), NULL}, + C_{N_("Experimental film"), N_("Video"), NULL}, + C_{N_("Broadcasting"), N_("Press"), NULL}, + C_{N_("New media"), NULL}, + C_{N_("Arts magazines"), N_("Culture magazines"), NULL}, + C_{N_("Fashion"), NULL}, + C_{N_("Arts / Culture (without music)"), NULL}, + C_{N_("Arts / Culture (without music)"), NULL}, + C_{N_("Arts / Culture (without music)"), NULL}, + C_{N_("Arts / Culture (without music)"), NULL}, + }, + { + /* 08 */ + C_{N_("Social"), N_("Political issues"), N_("Economics"), NULL}, + C_{N_("Magazines"), N_("Reports"), N_("Documentary"), NULL}, + C_{N_("Economics"), N_("Social advisory"), NULL}, + C_{N_("Remarkable people"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + C_{N_("Social / Political issues / Economics"), NULL}, + }, + { + /* 09 */ + C_{N_("Education"), N_("Science"), N_("Factual topics"), NULL}, + C_{N_("Nature"), N_("Animals"), N_("Environment"), NULL}, + C_{N_("Technology"), N_("Natural sciences"), NULL}, + C_{N_("Medicine"), N_("Physiology"), N_("Psychology"), NULL}, + C_{N_("Foreign countries"), N_("Expeditions"), NULL}, + C_{N_("Social"), N_("Spiritual sciences"), NULL}, + C_{N_("Further education"), NULL}, + C_{N_("Languages"), NULL}, + C_{N_("Education / Science / Factual topics"), NULL}, + C_{N_("Education / Science / Factual topics"), NULL}, + C_{N_("Education / Science / Factual topics"), NULL}, + C_{N_("Education / Science / Factual topics"), NULL}, + C_{N_("Education / Science / Factual topics"), NULL}, + C_{N_("Education / Science / Factual topics"), NULL}, + C_{N_("Education / Science / Factual topics"), NULL}, + C_{N_("Education / Science / Factual topics"), NULL}, + }, + { + /* 10 */ + C_{N_("Leisure hobbies"), NULL}, + C_{N_("Tourism / Travel"), NULL}, + C_{N_("Handicraft"), NULL}, + C_{N_("Motoring"), NULL}, + C_{N_("Fitness and health"), NULL}, + C_{N_("Cooking"), NULL}, + C_{N_("Advertisement / Shopping"), NULL}, + C_{N_("Gardening"), NULL}, + C_{N_("Leisure hobbies"), NULL}, + C_{N_("Leisure hobbies"), NULL}, + C_{N_("Leisure hobbies"), NULL}, + C_{N_("Leisure hobbies"), NULL}, + C_{N_("Leisure hobbies"), NULL}, + C_{N_("Leisure hobbies"), NULL}, + C_{N_("Leisure hobbies"), NULL}, + C_{N_("Leisure hobbies"), NULL}, + }}; + +static const char* _genre_get_name(int a, int b, const char* lang) { static __thread char name[64]; - size_t l = 0; - const char **p = _epg_genre_names[a][b]; - name[0] = '\0'; + size_t l = 0; + const char** p = _epg_genre_names[a][b]; + name[0] = '\0'; if (p == NULL) return NULL; - for ( ; *p; p++) - tvh_strlcatf(name, sizeof(name), l, "%s%s", l ? " / " : "", - lang ? tvh_gettext_lang(lang, *p) : *p); + for (; *p; p++) + tvh_strlcatf(name, + sizeof(name), + l, + "%s%s", + l ? " / " : "", + lang ? tvh_gettext_lang(lang, *p) : *p); return name; } // match strings, ignoring case and whitespace // Note: | 0x20 is a cheats (fast) way of lowering case -static int _genre_str_match ( const char *a, const char *b ) -{ - if (!a || !b) return 0; +static int _genre_str_match(const char* a, const char* b) { + if (!a || !b) + return 0; while (*a != '\0' || *b != '\0') { - while (*a == ' ') a++; - while (*b == ' ') b++; - if ((*a | 0x20) != (*b | 0x20)) return 0; - a++; b++; + while (*a == ' ') + a++; + while (*b == ' ') + b++; + if ((*a | 0x20) != (*b | 0x20)) + return 0; + a++; + b++; } return (*a == '\0' && *b == '\0'); // end of string(both) } -static uint8_t _epg_genre_find_by_name ( const char *name, const char *lang ) -{ - uint8_t a, b; - const char *s; +static uint8_t _epg_genre_find_by_name(const char* name, const char* lang) { + uint8_t a, b; + const char* s; for (a = 1; a < 11; a++) { for (b = 0; b < 16; b++) { s = _genre_get_name(a, b, lang); @@ -2000,25 +2026,29 @@ static uint8_t _epg_genre_find_by_name ( const char *name, const char *lang ) return 0; // undefined } -uint8_t epg_genre_get_eit ( const epg_genre_t *genre ) -{ - if (!genre) return 0; +uint8_t epg_genre_get_eit(const epg_genre_t* genre) { + if (!genre) + return 0; return genre->code; } -size_t epg_genre_get_str ( const epg_genre_t *genre, int major_only, - int major_prefix, char *buf, size_t len, - const char *lang ) -{ - const char *s; - int maj, min; - size_t ret = 0; - if (!genre || !buf) return 0; +size_t epg_genre_get_str(const epg_genre_t* genre, + int major_only, + int major_prefix, + char* buf, + size_t len, + const char* lang) { + const char* s; + int maj, min; + size_t ret = 0; + if (!genre || !buf) + return 0; maj = (genre->code >> 4) & 0xf; - s = _genre_get_name(maj, 0, lang); - if (s[0] == '\0') return 0; + s = _genre_get_name(maj, 0, lang); + if (s[0] == '\0') + return 0; min = major_only ? 0 : (genre->code & 0xf); - if (!min || major_prefix ) { + if (!min || major_prefix) { tvh_strlcatf(buf, len, ret, "%s", s); } if (min) { @@ -2031,20 +2061,21 @@ size_t epg_genre_get_str ( const epg_genre_t *genre, int major_only, return ret; } -int epg_genre_list_add ( epg_genre_list_t *list, epg_genre_t *genre ) -{ +int epg_genre_list_add(epg_genre_list_t* list, epg_genre_t* genre) { epg_genre_t *g1, *g2; - if (!list || !genre || !genre->code) return 0; + if (!list || !genre || !genre->code) + return 0; g1 = LIST_FIRST(list); if (!g1) { - g2 = calloc(1, sizeof(epg_genre_t)); + g2 = calloc(1, sizeof(epg_genre_t)); g2->code = genre->code; LIST_INSERT_HEAD(list, g2, link); } else { while (g1) { /* Already exists */ - if (g1->code == genre->code) return 0; + if (g1->code == genre->code) + return 0; /* Update a major only entry */ if (g1->code == (genre->code & 0xF0)) { @@ -2054,7 +2085,7 @@ int epg_genre_list_add ( epg_genre_list_t *list, epg_genre_t *genre ) /* Insert before */ if (g1->code > genre->code) { - g2 = calloc(1, sizeof(epg_genre_t)); + g2 = calloc(1, sizeof(epg_genre_t)); g2->code = genre->code; LIST_INSERT_BEFORE(g1, g2, link); break; @@ -2062,7 +2093,7 @@ int epg_genre_list_add ( epg_genre_list_t *list, epg_genre_t *genre ) /* Insert after (end) */ if (!(g2 = LIST_NEXT(g1, link))) { - g2 = calloc(1, sizeof(epg_genre_t)); + g2 = calloc(1, sizeof(epg_genre_t)); g2->code = genre->code; LIST_INSERT_AFTER(g1, g2, link); break; @@ -2075,15 +2106,13 @@ int epg_genre_list_add ( epg_genre_list_t *list, epg_genre_t *genre ) return 1; } -int epg_genre_list_add_by_eit ( epg_genre_list_t *list, uint8_t eit ) -{ +int epg_genre_list_add_by_eit(epg_genre_list_t* list, uint8_t eit) { epg_genre_t g; g.code = eit; return epg_genre_list_add(list, &g); } -int epg_genre_list_add_by_str ( epg_genre_list_t *list, const char *str, const char *lang ) -{ +int epg_genre_list_add_by_str(epg_genre_list_t* list, const char* str, const char* lang) { epg_genre_t g; g.code = _epg_genre_find_by_name(str, lang); return epg_genre_list_add(list, &g); @@ -2091,22 +2120,22 @@ int epg_genre_list_add_by_str ( epg_genre_list_t *list, const char *str, const c // Note: if partial=1 and genre is a major only category then all minor // entries will also match -int epg_genre_list_contains - ( epg_genre_list_t *list, epg_genre_t *genre, int partial ) -{ - uint8_t mask = 0xFF; - epg_genre_t *g; - if (!list || !genre) return 0; - if (partial && !(genre->code & 0x0F)) mask = 0xF0; - LIST_FOREACH(g, list, link) { - if ((g->code & mask) == genre->code) break; +int epg_genre_list_contains(epg_genre_list_t* list, epg_genre_t* genre, int partial) { + uint8_t mask = 0xFF; + epg_genre_t* g; + if (!list || !genre) + return 0; + if (partial && !(genre->code & 0x0F)) + mask = 0xF0; + LIST_FOREACH (g, list, link) { + if ((g->code & mask) == genre->code) + break; } return g ? 1 : 0; } -void epg_genre_list_destroy ( epg_genre_list_t *list ) -{ - epg_genre_t *g; +void epg_genre_list_destroy(epg_genre_list_t* list) { + epg_genre_t* g; while ((g = LIST_FIRST(list))) { LIST_REMOVE(g, link); free(g); @@ -2114,13 +2143,12 @@ void epg_genre_list_destroy ( epg_genre_list_t *list ) free(list); } -htsmsg_t *epg_genres_list_all ( int major_only, int major_prefix, const char *lang ) -{ - int i, j; - htsmsg_t *e, *m; - const char *s; +htsmsg_t* epg_genres_list_all(int major_only, int major_prefix, const char* lang) { + int i, j; + htsmsg_t * e, *m; + const char* s; m = htsmsg_create_list(); - for (i = 0; i < 16; i++ ) { + for (i = 0; i < 16; i++) { for (j = 0; j < (major_only ? 1 : 16); j++) { if (_epg_genre_names[i][j]) { e = htsmsg_create_map(); @@ -2139,98 +2167,113 @@ htsmsg_t *epg_genres_list_all ( int major_only, int major_prefix, const char *la * Querying * *************************************************************************/ -static inline int -_eq_comp_num ( epg_filter_num_t *f, int64_t val ) -{ +static inline int _eq_comp_num(epg_filter_num_t* f, int64_t val) { switch (f->comp) { - case EC_EQ: return val != f->val1; - case EC_LT: return val > f->val1; - case EC_GT: return val < f->val1; - case EC_RG: return val < f->val1 || val > f->val2; - default: return 0; + case EC_EQ: + return val != f->val1; + case EC_LT: + return val > f->val1; + case EC_GT: + return val < f->val1; + case EC_RG: + return val < f->val1 || val > f->val2; + default: + return 0; } } -static inline int -_eq_comp_str ( epg_filter_str_t *f, const char *str ) -{ - if (!str) return 0; +static inline int _eq_comp_str(epg_filter_str_t* f, const char* str) { + if (!str) + return 0; switch (f->comp) { - case EC_EQ: return strcmp(str, f->str); - case EC_LT: return strcmp(str, f->str) > 0; - case EC_GT: return strcmp(str, f->str) < 0; - case EC_IN: return strstr(str, f->str) != NULL; - case EC_RE: return regex_match(&f->re, str) != 0; - default: return 0; + case EC_EQ: + return strcmp(str, f->str); + case EC_LT: + return strcmp(str, f->str) > 0; + case EC_GT: + return strcmp(str, f->str) < 0; + case EC_IN: + return strstr(str, f->str) != NULL; + case EC_RE: + return regex_match(&f->re, str) != 0; + default: + return 0; } } -static void -_eq_add ( epg_query_t *eq, epg_broadcast_t *e ) -{ +static void _eq_add(epg_query_t* eq, epg_broadcast_t* e) { const char *s, *lang = eq->lang; - int fulltext = eq->stitle && eq->fulltext; + int fulltext = eq->stitle && eq->fulltext; /* Filtering */ - if (e == NULL) return; - if (e->stop < gclk()) return; - if (_eq_comp_num(&eq->start, e->start)) return; - if (_eq_comp_num(&eq->stop, e->stop)) return; + if (e == NULL) + return; + if (e->stop < gclk()) + return; + if (_eq_comp_num(&eq->start, e->start)) + return; + if (_eq_comp_num(&eq->stop, e->stop)) + return; if (eq->duration.comp != EC_NO) { int64_t duration = (int64_t)e->stop - (int64_t)e->start; - if (_eq_comp_num(&eq->duration, duration)) return; + if (_eq_comp_num(&eq->duration, duration)) + return; } if (eq->stars.comp != EC_NO) - if (_eq_comp_num(&eq->stars, e->star_rating)) return; + if (_eq_comp_num(&eq->stars, e->star_rating)) + return; if (eq->age.comp != EC_NO) - if (_eq_comp_num(&eq->age, e->age_rating)) return; + if (_eq_comp_num(&eq->age, e->age_rating)) + return; if (eq->channel_num.comp != EC_NO) - if (_eq_comp_num(&eq->channel_num, channel_get_number(e->channel))) return; + if (_eq_comp_num(&eq->channel_num, channel_get_number(e->channel))) + return; if (eq->channel_name.comp != EC_NO) - if (_eq_comp_str(&eq->channel_name, channel_get_name(e->channel, NULL))) return; + if (_eq_comp_str(&eq->channel_name, channel_get_name(e->channel, NULL))) + return; if (eq->cat1 && *eq->cat1) { - /* No category? Can't match our requested category */ - if (!e->category) - return; - if (!string_list_contains_string(e->category, eq->cat1)) - return; + /* No category? Can't match our requested category */ + if (!e->category) + return; + if (!string_list_contains_string(e->category, eq->cat1)) + return; } if (eq->cat2 && *eq->cat2) { - /* No category? Can't match our requested category */ - if (!e->category) - return; - if (!string_list_contains_string(e->category, eq->cat2)) - return; + /* No category? Can't match our requested category */ + if (!e->category) + return; + if (!string_list_contains_string(e->category, eq->cat2)) + return; } if (eq->cat3 && *eq->cat3) { - /* No category? Can't match our requested category */ - if (!e->category) - return; - if (!string_list_contains_string(e->category, eq->cat3)) - return; + /* No category? Can't match our requested category */ + if (!e->category) + return; + if (!string_list_contains_string(e->category, eq->cat3)) + return; } if (eq->genre_count) { epg_genre_t genre; - uint32_t i, r = 0; + uint32_t i, r = 0; for (i = 0; i < eq->genre_count; i++) { genre.code = eq->genre[i]; - if (genre.code == 0) continue; - if (epg_genre_list_contains(&e->genre, &genre, 1)) r++; + if (genre.code == 0) + continue; + if (epg_genre_list_contains(&e->genre, &genre, 1)) + r++; } - if (!r) return; + if (!r) + return; } if (eq->new_only) { if (!e->is_new) return; } if (fulltext) { - if ((s = epg_broadcast_get_title(e, lang)) == NULL || - regex_match(&eq->stitle_re, s)) { - if ((s = epg_broadcast_get_subtitle(e, lang)) == NULL || - regex_match(&eq->stitle_re, s)) { - if ((s = epg_broadcast_get_summary(e, lang)) == NULL || - regex_match(&eq->stitle_re, s)) { + if ((s = epg_broadcast_get_title(e, lang)) == NULL || regex_match(&eq->stitle_re, s)) { + if ((s = epg_broadcast_get_subtitle(e, lang)) == NULL || regex_match(&eq->stitle_re, s)) { + if ((s = epg_broadcast_get_summary(e, lang)) == NULL || regex_match(&eq->stitle_re, s)) { if ((s = epg_broadcast_get_description(e, lang)) == NULL || regex_match(&eq->stitle_re, s)) { if ((s = epg_broadcast_get_credits_cached(e, lang)) == NULL || @@ -2246,163 +2289,166 @@ _eq_add ( epg_query_t *eq, epg_broadcast_t *e ) } } if (eq->title.comp != EC_NO || (eq->stitle && !fulltext)) { - if ((s = epg_broadcast_get_title(e, lang)) == NULL) return; - if (eq->stitle && !fulltext && regex_match(&eq->stitle_re, s)) return; - if (eq->title.comp != EC_NO && _eq_comp_str(&eq->title, s)) return; + if ((s = epg_broadcast_get_title(e, lang)) == NULL) + return; + if (eq->stitle && !fulltext && regex_match(&eq->stitle_re, s)) + return; + if (eq->title.comp != EC_NO && _eq_comp_str(&eq->title, s)) + return; } if (eq->subtitle.comp != EC_NO) { - if ((s = epg_broadcast_get_subtitle(e, lang)) == NULL) return; - if (_eq_comp_str(&eq->subtitle, s)) return; + if ((s = epg_broadcast_get_subtitle(e, lang)) == NULL) + return; + if (_eq_comp_str(&eq->subtitle, s)) + return; } if (eq->summary.comp != EC_NO) { - if ((s = epg_broadcast_get_summary(e, lang)) == NULL) return; - if (_eq_comp_str(&eq->summary, s)) return; + if ((s = epg_broadcast_get_summary(e, lang)) == NULL) + return; + if (_eq_comp_str(&eq->summary, s)) + return; } if (eq->description.comp != EC_NO) { - if ((s = epg_broadcast_get_description(e, lang)) == NULL) return; - if (_eq_comp_str(&eq->description, s)) return; + if ((s = epg_broadcast_get_description(e, lang)) == NULL) + return; + if (_eq_comp_str(&eq->description, s)) + return; } /* More space */ if (eq->entries == eq->allocated) { eq->allocated = MAX(100, eq->allocated + 100); - eq->result = realloc(eq->result, eq->allocated * sizeof(epg_broadcast_t *)); + eq->result = realloc(eq->result, eq->allocated * sizeof(epg_broadcast_t*)); } /* Store */ eq->result[eq->entries++] = e; } -static void -_eq_add_channel ( epg_query_t *eq, channel_t *ch ) -{ - epg_broadcast_t *ebc; - RB_FOREACH(ebc, &ch->ch_epg_schedule, sched_link) +static void _eq_add_channel(epg_query_t* eq, channel_t* ch) { + epg_broadcast_t* ebc; + RB_FOREACH (ebc, &ch->ch_epg_schedule, sched_link) _eq_add(eq, ebc); } -static int -_eq_init_str( epg_filter_str_t *f ) -{ - if (f->comp != EC_RE) return 0; +static int _eq_init_str(epg_filter_str_t* f) { + if (f->comp != EC_RE) + return 0; return regex_compile(&f->re, f->str, TVHREGEX_CASELESS, LS_EPG); } -static void -_eq_done_str( epg_filter_str_t *f ) -{ +static void _eq_done_str(epg_filter_str_t* f) { if (f->comp == EC_RE) regex_free(&f->re); free(f->str); f->str = NULL; } -static int _epg_sort_start_ascending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_start_ascending(const void* a, const void* b, void* eq) { return (*(epg_broadcast_t**)a)->start - (*(epg_broadcast_t**)b)->start; } -static int _epg_sort_start_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_start_descending(const void* a, const void* b, void* eq) { return (*(epg_broadcast_t**)b)->start - (*(epg_broadcast_t**)a)->start; } -static int _epg_sort_stop_ascending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_stop_ascending(const void* a, const void* b, void* eq) { return (*(epg_broadcast_t**)a)->stop - (*(epg_broadcast_t**)b)->stop; } -static int _epg_sort_stop_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_stop_descending(const void* a, const void* b, void* eq) { return (*(epg_broadcast_t**)b)->stop - (*(epg_broadcast_t**)a)->stop; } -static inline int64_t _epg_sort_duration( const epg_broadcast_t *b ) -{ +static inline int64_t _epg_sort_duration(const epg_broadcast_t* b) { return b->stop - b->start; } -static int _epg_sort_duration_ascending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_duration_ascending(const void* a, const void* b, void* eq) { return _epg_sort_duration(*(epg_broadcast_t**)a) - _epg_sort_duration(*(epg_broadcast_t**)b); } -static int _epg_sort_duration_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_duration_descending(const void* a, const void* b, void* eq) { return _epg_sort_duration(*(epg_broadcast_t**)b) - _epg_sort_duration(*(epg_broadcast_t**)a); } -static int _epg_sort_title_ascending ( const void *a, const void *b, void *eq ) -{ - const char *s1 = epg_broadcast_get_title(*(epg_broadcast_t**)a, ((epg_query_t *)eq)->lang); - const char *s2 = epg_broadcast_get_title(*(epg_broadcast_t**)b, ((epg_query_t *)eq)->lang); - if (s1 == NULL && s2 == NULL) return 0; - if (s1 == NULL && s2) return 1; - if (s1 && s2 == NULL) return -1; +static int _epg_sort_title_ascending(const void* a, const void* b, void* eq) { + const char* s1 = epg_broadcast_get_title(*(epg_broadcast_t**)a, ((epg_query_t*)eq)->lang); + const char* s2 = epg_broadcast_get_title(*(epg_broadcast_t**)b, ((epg_query_t*)eq)->lang); + if (s1 == NULL && s2 == NULL) + return 0; + if (s1 == NULL && s2) + return 1; + if (s1 && s2 == NULL) + return -1; int r = strcmp(s1, s2); if (r == 0) { - s1 = epg_broadcast_get_subtitle(*(epg_broadcast_t**)a, ((epg_query_t *)eq)->lang); - s2 = epg_broadcast_get_subtitle(*(epg_broadcast_t**)b, ((epg_query_t *)eq)->lang); - if (s1 == NULL && s2 == NULL) return 0; - if (s1 == NULL && s2) return 1; - if (s1 && s2 == NULL) return -1; + s1 = epg_broadcast_get_subtitle(*(epg_broadcast_t**)a, ((epg_query_t*)eq)->lang); + s2 = epg_broadcast_get_subtitle(*(epg_broadcast_t**)b, ((epg_query_t*)eq)->lang); + if (s1 == NULL && s2 == NULL) + return 0; + if (s1 == NULL && s2) + return 1; + if (s1 && s2 == NULL) + return -1; r = strcmp(s1, s2); } return r; } -static int _epg_sort_title_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_title_descending(const void* a, const void* b, void* eq) { return _epg_sort_title_ascending(a, b, eq) * -1; } -static int _epg_sort_subtitle_ascending ( const void *a, const void *b, void *eq ) -{ - const char *s1 = epg_broadcast_get_subtitle(*(epg_broadcast_t**)a, ((epg_query_t *)eq)->lang); - const char *s2 = epg_broadcast_get_subtitle(*(epg_broadcast_t**)b, ((epg_query_t *)eq)->lang); - if (s1 == NULL && s2 == NULL) return 0; - if (s1 == NULL && s2) return 1; - if (s1 && s2 == NULL) return -1; +static int _epg_sort_subtitle_ascending(const void* a, const void* b, void* eq) { + const char* s1 = epg_broadcast_get_subtitle(*(epg_broadcast_t**)a, ((epg_query_t*)eq)->lang); + const char* s2 = epg_broadcast_get_subtitle(*(epg_broadcast_t**)b, ((epg_query_t*)eq)->lang); + if (s1 == NULL && s2 == NULL) + return 0; + if (s1 == NULL && s2) + return 1; + if (s1 && s2 == NULL) + return -1; return strcmp(s1, s2); } -static int _epg_sort_subtitle_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_subtitle_descending(const void* a, const void* b, void* eq) { return _epg_sort_subtitle_ascending(a, b, eq) * -1; } -static int _epg_sort_summary_ascending ( const void *a, const void *b, void *eq ) -{ - const char *s1 = epg_broadcast_get_summary(*(epg_broadcast_t**)a, ((epg_query_t *)eq)->lang); - const char *s2 = epg_broadcast_get_summary(*(epg_broadcast_t**)b, ((epg_query_t *)eq)->lang); - if (s1 == NULL && s2 == NULL) return 0; - if (s1 == NULL && s2) return 1; - if (s1 && s2 == NULL) return -1; +static int _epg_sort_summary_ascending(const void* a, const void* b, void* eq) { + const char* s1 = epg_broadcast_get_summary(*(epg_broadcast_t**)a, ((epg_query_t*)eq)->lang); + const char* s2 = epg_broadcast_get_summary(*(epg_broadcast_t**)b, ((epg_query_t*)eq)->lang); + if (s1 == NULL && s2 == NULL) + return 0; + if (s1 == NULL && s2) + return 1; + if (s1 && s2 == NULL) + return -1; return strcmp(s1, s2); } -static int _epg_sort_summary_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_summary_descending(const void* a, const void* b, void* eq) { return _epg_sort_summary_ascending(a, b, eq) * -1; } -static int _epg_sort_description_ascending ( const void *a, const void *b, void *eq ) -{ - const char *s1 = epg_broadcast_get_description(*(epg_broadcast_t**)a, ((epg_query_t *)eq)->lang); - const char *s2 = epg_broadcast_get_description(*(epg_broadcast_t**)b, ((epg_query_t *)eq)->lang); - if (s1 == NULL && s2 == NULL) return 0; - if (s1 == NULL && s2) return 1; - if (s1 && s2 == NULL) return -1; +static int _epg_sort_description_ascending(const void* a, const void* b, void* eq) { + const char* s1 = epg_broadcast_get_description(*(epg_broadcast_t**)a, ((epg_query_t*)eq)->lang); + const char* s2 = epg_broadcast_get_description(*(epg_broadcast_t**)b, ((epg_query_t*)eq)->lang); + if (s1 == NULL && s2 == NULL) + return 0; + if (s1 == NULL && s2) + return 1; + if (s1 && s2 == NULL) + return -1; return strcmp(s1, s2); } -static int _epg_sort_description_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_description_descending(const void* a, const void* b, void* eq) { return _epg_sort_description_ascending(a, b, eq) * -1; } -static int _epg_sort_extratext_ascending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_extratext_ascending(const void* a, const void* b, void* eq) { int r = _epg_sort_subtitle_ascending(a, b, eq); if (r == 0) { r = _epg_sort_summary_ascending(a, b, eq); @@ -2412,65 +2458,55 @@ static int _epg_sort_extratext_ascending ( const void *a, const void *b, void *e return r; } -static int _epg_sort_extratext_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_extratext_descending(const void* a, const void* b, void* eq) { return _epg_sort_extratext_ascending(a, b, eq) * -1; } -static int _epg_sort_channel_ascending ( const void *a, const void *b, void *eq ) -{ - char *s1 = strdup(channel_get_name((*(epg_broadcast_t**)a)->channel, "")); - const char *s2 = channel_get_name((*(epg_broadcast_t**)b)->channel, ""); - int r = strcmp(s1, s2); +static int _epg_sort_channel_ascending(const void* a, const void* b, void* eq) { + char* s1 = strdup(channel_get_name((*(epg_broadcast_t**)a)->channel, "")); + const char* s2 = channel_get_name((*(epg_broadcast_t**)b)->channel, ""); + int r = strcmp(s1, s2); free(s1); return r; } -static int _epg_sort_channel_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_channel_descending(const void* a, const void* b, void* eq) { return _epg_sort_description_ascending(a, b, eq) * -1; } -static int _epg_sort_channel_num_ascending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_channel_num_ascending(const void* a, const void* b, void* eq) { int64_t v1 = channel_get_number((*(epg_broadcast_t**)a)->channel); int64_t v2 = channel_get_number((*(epg_broadcast_t**)b)->channel); return v1 - v2; } -static int _epg_sort_channel_num_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_channel_num_descending(const void* a, const void* b, void* eq) { const int64_t v1 = channel_get_number((*(epg_broadcast_t**)a)->channel); const int64_t v2 = channel_get_number((*(epg_broadcast_t**)b)->channel); return v2 - v1; } -static int _epg_sort_stars_ascending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_stars_ascending(const void* a, const void* b, void* eq) { return (*(epg_broadcast_t**)a)->star_rating - (*(epg_broadcast_t**)b)->star_rating; } -static int _epg_sort_stars_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_stars_descending(const void* a, const void* b, void* eq) { return (*(epg_broadcast_t**)b)->star_rating - (*(epg_broadcast_t**)a)->star_rating; } -static int _epg_sort_age_ascending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_age_ascending(const void* a, const void* b, void* eq) { return (*(epg_broadcast_t**)a)->age_rating - (*(epg_broadcast_t**)b)->age_rating; } -static int _epg_sort_age_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_age_descending(const void* a, const void* b, void* eq) { return (*(epg_broadcast_t**)b)->age_rating - (*(epg_broadcast_t**)a)->age_rating; } -static uint64_t _epg_sort_genre_hash( epg_broadcast_t *b ) -{ - uint64_t h = 0, t; - epg_genre_t *g; +static uint64_t _epg_sort_genre_hash(epg_broadcast_t* b) { + uint64_t h = 0, t; + epg_genre_t* g; - LIST_FOREACH(g, &b->genre, link) { + LIST_FOREACH (g, &b->genre, link) { t = h >> 28; h <<= 8; h += (uint64_t)g->code + t; @@ -2478,104 +2514,156 @@ static uint64_t _epg_sort_genre_hash( epg_broadcast_t *b ) return h; } -static int _epg_sort_genre_ascending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_genre_ascending(const void* a, const void* b, void* eq) { const uint64_t v1 = _epg_sort_genre_hash(*(epg_broadcast_t**)a); const uint64_t v2 = _epg_sort_genre_hash(*(epg_broadcast_t**)b); return v1 - v2; } -static int _epg_sort_genre_descending ( const void *a, const void *b, void *eq ) -{ +static int _epg_sort_genre_descending(const void* a, const void* b, void* eq) { return _epg_sort_genre_ascending(a, b, eq) * -1; } -epg_broadcast_t ** -epg_query ( epg_query_t *eq, access_t *perm ) -{ - channel_t *channel; - channel_tag_t *tag; - int (*fcn)(const void *, const void *, void *) = NULL; +epg_broadcast_t** epg_query(epg_query_t* eq, access_t* perm) { + channel_t* channel; + channel_tag_t* tag; + int (*fcn)(const void*, const void*, void*) = NULL; /* Setup exp */ - if (_eq_init_str(&eq->title)) goto fin; - if (_eq_init_str(&eq->subtitle)) goto fin; - if (_eq_init_str(&eq->summary)) goto fin; - if (_eq_init_str(&eq->description)) goto fin; - if (_eq_init_str(&eq->extratext)) goto fin; - if (_eq_init_str(&eq->channel_name)) goto fin; + if (_eq_init_str(&eq->title)) + goto fin; + if (_eq_init_str(&eq->subtitle)) + goto fin; + if (_eq_init_str(&eq->summary)) + goto fin; + if (_eq_init_str(&eq->description)) + goto fin; + if (_eq_init_str(&eq->extratext)) + goto fin; + if (_eq_init_str(&eq->channel_name)) + goto fin; if (eq->stitle) if (regex_compile(&eq->stitle_re, eq->stitle, TVHREGEX_CASELESS, LS_EPG)) goto fin; - channel = channel_find_by_uuid(eq->channel) ?: - channel_find_by_name(eq->channel); + channel = channel_find_by_uuid(eq->channel) ?: channel_find_by_name(eq->channel); - tag = channel_tag_find_by_uuid(eq->channel_tag) ?: - channel_tag_find_by_name(eq->channel_tag, 0); + tag = channel_tag_find_by_uuid(eq->channel_tag) ?: channel_tag_find_by_name(eq->channel_tag, 0); /* Single channel */ if (channel && tag == NULL) { if (channel_access(channel, perm, 0)) _eq_add_channel(eq, channel); - /* Tag based */ + /* Tag based */ } else if (tag) { - idnode_list_mapping_t *ilm; - channel_t *ch2; - LIST_FOREACH(ilm, &tag->ct_ctms, ilm_in1_link) { - ch2 = (channel_t *)ilm->ilm_in2; - if(ch2 == channel || channel == NULL) + idnode_list_mapping_t* ilm; + channel_t* ch2; + LIST_FOREACH (ilm, &tag->ct_ctms, ilm_in1_link) { + ch2 = (channel_t*)ilm->ilm_in2; + if (ch2 == channel || channel == NULL) if (channel_access(ch2, perm, 0)) _eq_add_channel(eq, ch2); } - /* All channels */ + /* All channels */ } else { CHANNEL_FOREACH(channel) - if (channel_access(channel, perm, 0)) - _eq_add_channel(eq, channel); + if (channel_access(channel, perm, 0)) + _eq_add_channel(eq, channel); } switch (eq->sort_dir) { - case ES_ASC: - switch (eq->sort_key) { - case ESK_START: fcn = _epg_sort_start_ascending; break; - case ESK_STOP: fcn = _epg_sort_stop_ascending; break; - case ESK_DURATION: fcn = _epg_sort_duration_ascending; break; - case ESK_TITLE: fcn = _epg_sort_title_ascending; break; - case ESK_SUBTITLE: fcn = _epg_sort_subtitle_ascending; break; - case ESK_SUMMARY: fcn = _epg_sort_summary_ascending; break; - case ESK_DESCRIPTION: fcn = _epg_sort_description_ascending; break; - case ESK_EXTRATEXT: fcn = _epg_sort_extratext_ascending; break; - case ESK_CHANNEL: fcn = _epg_sort_channel_ascending; break; - case ESK_CHANNEL_NUM: fcn = _epg_sort_channel_num_ascending; break; - case ESK_STARS: fcn = _epg_sort_stars_ascending; break; - case ESK_AGE: fcn = _epg_sort_age_ascending; break; - case ESK_GENRE: fcn = _epg_sort_genre_ascending; break; - } - break; - case ES_DSC: - switch (eq->sort_key) { - case ESK_START: fcn = _epg_sort_start_descending; break; - case ESK_STOP: fcn = _epg_sort_stop_descending; break; - case ESK_DURATION: fcn = _epg_sort_duration_descending; break; - case ESK_TITLE: fcn = _epg_sort_title_descending; break; - case ESK_SUBTITLE: fcn = _epg_sort_subtitle_descending; break; - case ESK_SUMMARY: fcn = _epg_sort_summary_descending; break; - case ESK_DESCRIPTION: fcn = _epg_sort_description_descending; break; - case ESK_EXTRATEXT: fcn = _epg_sort_extratext_descending; break; - case ESK_CHANNEL: fcn = _epg_sort_channel_descending; break; - case ESK_CHANNEL_NUM: fcn = _epg_sort_channel_num_descending; break; - case ESK_STARS: fcn = _epg_sort_stars_descending; break; - case ESK_AGE: fcn = _epg_sort_age_descending; break; - case ESK_GENRE: fcn = _epg_sort_genre_descending; break; - } - break; + case ES_ASC: + switch (eq->sort_key) { + case ESK_START: + fcn = _epg_sort_start_ascending; + break; + case ESK_STOP: + fcn = _epg_sort_stop_ascending; + break; + case ESK_DURATION: + fcn = _epg_sort_duration_ascending; + break; + case ESK_TITLE: + fcn = _epg_sort_title_ascending; + break; + case ESK_SUBTITLE: + fcn = _epg_sort_subtitle_ascending; + break; + case ESK_SUMMARY: + fcn = _epg_sort_summary_ascending; + break; + case ESK_DESCRIPTION: + fcn = _epg_sort_description_ascending; + break; + case ESK_EXTRATEXT: + fcn = _epg_sort_extratext_ascending; + break; + case ESK_CHANNEL: + fcn = _epg_sort_channel_ascending; + break; + case ESK_CHANNEL_NUM: + fcn = _epg_sort_channel_num_ascending; + break; + case ESK_STARS: + fcn = _epg_sort_stars_ascending; + break; + case ESK_AGE: + fcn = _epg_sort_age_ascending; + break; + case ESK_GENRE: + fcn = _epg_sort_genre_ascending; + break; + } + break; + case ES_DSC: + switch (eq->sort_key) { + case ESK_START: + fcn = _epg_sort_start_descending; + break; + case ESK_STOP: + fcn = _epg_sort_stop_descending; + break; + case ESK_DURATION: + fcn = _epg_sort_duration_descending; + break; + case ESK_TITLE: + fcn = _epg_sort_title_descending; + break; + case ESK_SUBTITLE: + fcn = _epg_sort_subtitle_descending; + break; + case ESK_SUMMARY: + fcn = _epg_sort_summary_descending; + break; + case ESK_DESCRIPTION: + fcn = _epg_sort_description_descending; + break; + case ESK_EXTRATEXT: + fcn = _epg_sort_extratext_descending; + break; + case ESK_CHANNEL: + fcn = _epg_sort_channel_descending; + break; + case ESK_CHANNEL_NUM: + fcn = _epg_sort_channel_num_descending; + break; + case ESK_STARS: + fcn = _epg_sort_stars_descending; + break; + case ESK_AGE: + fcn = _epg_sort_age_descending; + break; + case ESK_GENRE: + fcn = _epg_sort_genre_descending; + break; + } + break; } - tvh_qsort_r(eq->result, eq->entries, sizeof(epg_broadcast_t *), fcn, eq); + tvh_qsort_r(eq->result, eq->entries, sizeof(epg_broadcast_t*), fcn, eq); fin: _eq_done_str(&eq->title); @@ -2588,13 +2676,20 @@ fin: if (eq->stitle) regex_free(&eq->stitle_re); - free(eq->lang); eq->lang = NULL; - free(eq->channel); eq->channel = NULL; - free(eq->channel_tag); eq->channel_tag = NULL; - free(eq->stitle); eq->stitle = NULL; - free(eq->cat1); eq->cat1 = NULL; - free(eq->cat2); eq->cat2 = NULL; - free(eq->cat3); eq->cat3 = NULL; + free(eq->lang); + eq->lang = NULL; + free(eq->channel); + eq->channel = NULL; + free(eq->channel_tag); + eq->channel_tag = NULL; + free(eq->stitle); + eq->stitle = NULL; + free(eq->cat1); + eq->cat1 = NULL; + free(eq->cat2); + eq->cat2 = NULL; + free(eq->cat3); + eq->cat3 = NULL; if (eq->genre != eq->genre_static) free(eq->genre); @@ -2603,36 +2698,33 @@ fin: return eq->result; } -void epg_query_free(epg_query_t *eq) -{ - free(eq->result); eq->result = NULL; +void epg_query_free(epg_query_t* eq) { + free(eq->result); + eq->result = NULL; } - /* ************************************************************************** * Miscellaneous * *************************************************************************/ -htsmsg_t *epg_config_serialize( void ) -{ - htsmsg_t *m = htsmsg_create_map(); +htsmsg_t* epg_config_serialize(void) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_u32(m, "last_id", _epg_object_idx); return m; } -int epg_config_deserialize( htsmsg_t *m ) -{ +int epg_config_deserialize(htsmsg_t* m) { if (htsmsg_get_u32(m, "last_id", &_epg_object_idx)) return 0; return 1; /* ok */ } -void epg_skel_done(void) -{ - epg_broadcast_t **broad; +void epg_skel_done(void) { + epg_broadcast_t** broad; broad = _epg_broadcast_skel(); - free(*broad); *broad = NULL; + free(*broad); + *broad = NULL; assert(RB_FIRST(&epg_serieslinks) == NULL); assert(RB_FIRST(&epg_episodelinks) == NULL); } diff --git a/src/epg.h b/src/epg.h index da595fd39..11fd9bfff 100644 --- a/src/epg.h +++ b/src/epg.h @@ -24,7 +24,7 @@ #include "lang_str.h" #include "string_list.h" #include "access.h" -#include "ratinglabels.h" //Needed for the ratinglabel_t struct. +#include "ratinglabels.h" //Needed for the ratinglabel_t struct. /* * External forward decls @@ -37,23 +37,23 @@ struct epggrab_module; /* * Map/List types */ -typedef LIST_HEAD(,epg_object) epg_object_list_t; -typedef RB_HEAD (,epg_object) epg_object_tree_t; -typedef LIST_HEAD(,epg_broadcast) epg_broadcast_list_t; -typedef RB_HEAD (,epg_broadcast) epg_broadcast_tree_t; -typedef RB_HEAD (,epg_set) epg_set_tree_t; -typedef LIST_HEAD(,epg_genre) epg_genre_list_t; +typedef LIST_HEAD(, epg_object) epg_object_list_t; +typedef RB_HEAD(, epg_object) epg_object_tree_t; +typedef LIST_HEAD(, epg_broadcast) epg_broadcast_list_t; +typedef RB_HEAD(, epg_broadcast) epg_broadcast_tree_t; +typedef RB_HEAD(, epg_set) epg_set_tree_t; +typedef LIST_HEAD(, epg_genre) epg_genre_list_t; /* * Typedefs (most are redundant!) */ -typedef struct epg_genre epg_genre_t; -typedef struct epg_object epg_object_t; -typedef struct epg_broadcast epg_broadcast_t; -typedef struct epg_set_item epg_set_item_t; -typedef struct epg_set epg_set_t; +typedef struct epg_genre epg_genre_t; +typedef struct epg_object epg_object_t; +typedef struct epg_broadcast epg_broadcast_t; +typedef struct epg_set_item epg_set_item_t; +typedef struct epg_set epg_set_t; -extern int epg_in_load; +extern int epg_in_load; extern epg_set_tree_t epg_episodelinks; extern epg_set_tree_t epg_serieslinks; @@ -73,40 +73,40 @@ typedef enum { * ***********************************************************************/ /* Genre object */ -struct epg_genre -{ +struct epg_genre { LIST_ENTRY(epg_genre) link; - uint8_t code; + uint8_t code; }; /* Accessors */ -uint8_t epg_genre_get_eit ( const epg_genre_t *genre ); -size_t epg_genre_get_str ( const epg_genre_t *genre, int major_only, - int major_prefix, char *buf, size_t len, - const char *lang ); +uint8_t epg_genre_get_eit(const epg_genre_t* genre); +size_t epg_genre_get_str(const epg_genre_t* genre, + int major_only, + int major_prefix, + char* buf, + size_t len, + const char* lang); /* Delete */ -void epg_genre_list_destroy ( epg_genre_list_t *list ); +void epg_genre_list_destroy(epg_genre_list_t* list); /* Add to list */ -int epg_genre_list_add ( epg_genre_list_t *list, epg_genre_t *genre ); -int epg_genre_list_add_by_eit ( epg_genre_list_t *list, uint8_t eit ); -int epg_genre_list_add_by_str ( epg_genre_list_t *list, const char *str, const char *lang ); +int epg_genre_list_add(epg_genre_list_t* list, epg_genre_t* genre); +int epg_genre_list_add_by_eit(epg_genre_list_t* list, uint8_t eit); +int epg_genre_list_add_by_str(epg_genre_list_t* list, const char* str, const char* lang); /* Search */ -int epg_genre_list_contains - ( epg_genre_list_t *list, epg_genre_t *genre, int partial ); +int epg_genre_list_contains(epg_genre_list_t* list, epg_genre_t* genre, int partial); /* List all available genres */ -htsmsg_t *epg_genres_list_all ( int major_only, int major_prefix, const char *lang ); +htsmsg_t* epg_genres_list_all(int major_only, int major_prefix, const char* lang); /* ************************************************************************ * Generic Object * ***********************************************************************/ /* Object type */ -typedef enum epg_object_type -{ +typedef enum epg_object_type { EPG_UNDEF, EPG_BROADCAST, } epg_object_type_t; @@ -116,92 +116,90 @@ typedef enum epg_object_type typedef uint64_t epg_changes_t; /* Change flags */ -#define EPG_CHANGED_CREATE (1ULL<<0) -#define EPG_CHANGED_TITLE (1ULL<<1) -#define EPG_CHANGED_SUBTITLE (1ULL<<2) -#define EPG_CHANGED_SUMMARY (1ULL<<3) -#define EPG_CHANGED_DESCRIPTION (1ULL<<4) -#define EPG_CHANGED_IMAGE (1ULL<<5) -#define EPG_CHANGED_CREDITS (1ULL<<6) -#define EPG_CHANGED_CATEGORY (1ULL<<7) -#define EPG_CHANGED_KEYWORD (1ULL<<8) -#define EPG_CHANGED_DVB_EID (1ULL<<9) -#define EPG_CHANGED_IS_WIDESCREEN (1ULL<<10) -#define EPG_CHANGED_IS_HD (1ULL<<11) -#define EPG_CHANGED_LINES (1ULL<<12) -#define EPG_CHANGED_ASPECT (1ULL<<13) -#define EPG_CHANGED_DEAFSIGNED (1ULL<<14) -#define EPG_CHANGED_SUBTITLED (1ULL<<15) -#define EPG_CHANGED_AUDIO_DESC (1ULL<<16) -#define EPG_CHANGED_IS_NEW (1ULL<<17) -#define EPG_CHANGED_IS_REPEAT (1ULL<<18) -#define EPG_CHANGED_SERIESLINK (1ULL<<19) -#define EPG_CHANGED_EPISODE (1ULL<<20) -#define EPG_CHANGED_GENRE (1ULL<<21) -#define EPG_CHANGED_EPNUM_NUM (1ULL<<22) -#define EPG_CHANGED_EPNUM_CNT (1ULL<<23) -#define EPG_CHANGED_EPPAR_NUM (1ULL<<24) -#define EPG_CHANGED_EPPAR_CNT (1ULL<<25) -#define EPG_CHANGED_EPSER_NUM (1ULL<<26) -#define EPG_CHANGED_EPSER_CNT (1ULL<<27) -#define EPG_CHANGED_EPTEXT (1ULL<<28) -#define EPG_CHANGED_IS_BW (1ULL<<29) -#define EPG_CHANGED_STAR_RATING (1ULL<<30) -#define EPG_CHANGED_AGE_RATING (1ULL<<31) -#define EPG_CHANGED_FIRST_AIRED (1ULL<<32) -#define EPG_CHANGED_COPYRIGHT_YEAR (1ULL<<33) -#define EPG_CHANGED_RATING_LABEL (1ULL<<34) +#define EPG_CHANGED_CREATE (1ULL << 0) +#define EPG_CHANGED_TITLE (1ULL << 1) +#define EPG_CHANGED_SUBTITLE (1ULL << 2) +#define EPG_CHANGED_SUMMARY (1ULL << 3) +#define EPG_CHANGED_DESCRIPTION (1ULL << 4) +#define EPG_CHANGED_IMAGE (1ULL << 5) +#define EPG_CHANGED_CREDITS (1ULL << 6) +#define EPG_CHANGED_CATEGORY (1ULL << 7) +#define EPG_CHANGED_KEYWORD (1ULL << 8) +#define EPG_CHANGED_DVB_EID (1ULL << 9) +#define EPG_CHANGED_IS_WIDESCREEN (1ULL << 10) +#define EPG_CHANGED_IS_HD (1ULL << 11) +#define EPG_CHANGED_LINES (1ULL << 12) +#define EPG_CHANGED_ASPECT (1ULL << 13) +#define EPG_CHANGED_DEAFSIGNED (1ULL << 14) +#define EPG_CHANGED_SUBTITLED (1ULL << 15) +#define EPG_CHANGED_AUDIO_DESC (1ULL << 16) +#define EPG_CHANGED_IS_NEW (1ULL << 17) +#define EPG_CHANGED_IS_REPEAT (1ULL << 18) +#define EPG_CHANGED_SERIESLINK (1ULL << 19) +#define EPG_CHANGED_EPISODE (1ULL << 20) +#define EPG_CHANGED_GENRE (1ULL << 21) +#define EPG_CHANGED_EPNUM_NUM (1ULL << 22) +#define EPG_CHANGED_EPNUM_CNT (1ULL << 23) +#define EPG_CHANGED_EPPAR_NUM (1ULL << 24) +#define EPG_CHANGED_EPPAR_CNT (1ULL << 25) +#define EPG_CHANGED_EPSER_NUM (1ULL << 26) +#define EPG_CHANGED_EPSER_CNT (1ULL << 27) +#define EPG_CHANGED_EPTEXT (1ULL << 28) +#define EPG_CHANGED_IS_BW (1ULL << 29) +#define EPG_CHANGED_STAR_RATING (1ULL << 30) +#define EPG_CHANGED_AGE_RATING (1ULL << 31) +#define EPG_CHANGED_FIRST_AIRED (1ULL << 32) +#define EPG_CHANGED_COPYRIGHT_YEAR (1ULL << 33) +#define EPG_CHANGED_RATING_LABEL (1ULL << 34) typedef struct epg_object_ops { - void (*getref) ( void *o ); ///< Get a reference - int (*putref) ( void *o ); ///< Release a reference - void (*destroy) ( void *o ); ///< Delete the object - void (*update) ( void *o ); ///< Updated + void (*getref)(void* o); ///< Get a reference + int (*putref)(void* o); ///< Release a reference + void (*destroy)(void* o); ///< Delete the object + void (*update)(void* o); ///< Updated } epg_object_ops_t; /* Object */ -struct epg_object -{ - RB_ENTRY(epg_object) id_link; ///< Global (ID) link - LIST_ENTRY(epg_object) un_link; ///< Global unref'd link - LIST_ENTRY(epg_object) up_link; ///< Global updated link - - epg_object_type_t type; ///< Specific object type - uint32_t id; ///< Internal ID - time_t updated; ///< Last time object was changed - - uint8_t _updated; ///< Flag to indicate updated - uint8_t _created; ///< Flag to indicate creation - int refcount; ///< Reference counting +struct epg_object { + RB_ENTRY(epg_object) id_link; ///< Global (ID) link + LIST_ENTRY(epg_object) un_link; ///< Global unref'd link + LIST_ENTRY(epg_object) up_link; ///< Global updated link + + epg_object_type_t type; ///< Specific object type + uint32_t id; ///< Internal ID + time_t updated; ///< Last time object was changed + + uint8_t _updated; ///< Flag to indicate updated + uint8_t _created; ///< Flag to indicate creation + int refcount; ///< Reference counting // Note: could use LIST_ENTRY field to determine this! - struct epggrab_module *grabber; ///< Originating grabber + struct epggrab_module* grabber; ///< Originating grabber - epg_object_ops_t *ops; ///< Operations on the object + epg_object_ops_t* ops; ///< Operations on the object }; /* Get an object by ID (special case usage) */ -epg_object_t *epg_object_find_by_id ( uint32_t id, epg_object_type_t type ); -htsmsg_t *epg_object_serialize ( epg_object_t *eo ); -epg_object_t *epg_object_deserialize ( htsmsg_t *msg, int create, int *save ); +epg_object_t* epg_object_find_by_id(uint32_t id, epg_object_type_t type); +htsmsg_t* epg_object_serialize(epg_object_t* eo); +epg_object_t* epg_object_deserialize(htsmsg_t* msg, int create, int* save); /* ************************************************************************ * Episode numbering * ***********************************************************************/ -typedef struct epg_episode_num -{ +typedef struct epg_episode_num { uint16_t s_num; ///< Series number uint16_t s_cnt; ///< Series count uint16_t e_num; ///< Episode number uint16_t e_cnt; ///< Episode count uint16_t p_num; ///< Part number uint16_t p_cnt; ///< Part count - char *text; ///< Arbitary text description of episode num + char* text; ///< Arbitary text description of episode num } epg_episode_num_t; -htsmsg_t *epg_episode_epnum_serialize( epg_episode_num_t *num ); -void epg_episode_epnum_deserialize( htsmsg_t *m, epg_episode_num_t *num ); +htsmsg_t* epg_episode_epnum_serialize(epg_episode_num_t* num); +void epg_episode_epnum_deserialize(htsmsg_t* m, epg_episode_num_t* num); /* EpNum format helper */ // output string will be: @@ -213,15 +211,16 @@ void epg_episode_epnum_deserialize( htsmsg_t *m, epg_episode_num_t *num ); // ret += sprintf(efmt, episode_num) // if (episode_cnt) ret += sprintf(cfmt, episode_cnt) // and will return num chars written -size_t epg_episode_num_format - ( epg_episode_num_t *epnum, char *buf, size_t len, - const char *pre, const char *sfmt, - const char *sep, const char *efmt, - const char *cfmt ); -int epg_episode_number_cmp - ( const epg_episode_num_t *a, const epg_episode_num_t *b ); -int epg_episode_number_cmpfull - ( const epg_episode_num_t *a, const epg_episode_num_t *b ); +size_t epg_episode_num_format(epg_episode_num_t* epnum, + char* buf, + size_t len, + const char* pre, + const char* sfmt, + const char* sep, + const char* efmt, + const char* cfmt); +int epg_episode_number_cmp(const epg_episode_num_t* a, const epg_episode_num_t* b); +int epg_episode_number_cmpfull(const epg_episode_num_t* a, const epg_episode_num_t* b); /* ************************************************************************ * Broadcast set @@ -229,7 +228,7 @@ int epg_episode_number_cmpfull struct epg_set_item { LIST_ENTRY(epg_set_item) item_link; - epg_broadcast_t *broadcast; + epg_broadcast_t* broadcast; }; struct epg_set { @@ -238,246 +237,215 @@ struct epg_set { char uri[0]; }; -epg_set_t *epg_set_broadcast_insert - (epg_set_tree_t *tree, epg_broadcast_t *b, const char *uri); -void epg_set_broadcast_remove - (epg_set_tree_t *tree, epg_set_t *set, epg_broadcast_t *b); -epg_set_t *epg_set_broadcast_find_by_uri - (epg_set_tree_t *tree, const char *uri); +epg_set_t* epg_set_broadcast_insert(epg_set_tree_t* tree, epg_broadcast_t* b, const char* uri); +void epg_set_broadcast_remove(epg_set_tree_t* tree, epg_set_t* set, epg_broadcast_t* b); +epg_set_t* epg_set_broadcast_find_by_uri(epg_set_tree_t* tree, const char* uri); /* ************************************************************************ * Broadcast - specific airing (channel & time) of an episode * ***********************************************************************/ /* Object */ -struct epg_broadcast -{ - epg_object_t; ///< Parent object +struct epg_broadcast { + epg_object_t; ///< Parent object - struct channel *channel; ///< Channel being broadcast on - RB_ENTRY(epg_broadcast) sched_link; ///< Schedule link - LIST_HEAD(, dvr_entry) dvr_entries; ///< Associated DVR entries + struct channel* channel; ///< Channel being broadcast on + RB_ENTRY(epg_broadcast) sched_link; ///< Schedule link + LIST_HEAD(, dvr_entry) dvr_entries; ///< Associated DVR entries /* */ - uint16_t dvb_eid; ///< DVB Event ID - time_t start; ///< Start time - time_t stop; ///< End time + uint16_t dvb_eid; ///< DVB Event ID + time_t start; ///< Start time + time_t stop; ///< End time /* Some quality info */ - uint16_t lines; ///< Lines in image (quality) - uint16_t aspect; ///< Aspect ratio (*100) - uint8_t is_widescreen; ///< Is widescreen - uint8_t is_hd; ///< Is HD - uint8_t is_bw; ///< Is black and white + uint16_t lines; ///< Lines in image (quality) + uint16_t aspect; ///< Aspect ratio (*100) + uint8_t is_widescreen; ///< Is widescreen + uint8_t is_hd; ///< Is HD + uint8_t is_bw; ///< Is black and white /* Some accessibility support */ - uint8_t is_deafsigned; ///< In screen signing - uint8_t is_subtitled; ///< Teletext subtitles - uint8_t is_audio_desc; ///< Audio description + uint8_t is_deafsigned; ///< In screen signing + uint8_t is_subtitled; ///< Teletext subtitles + uint8_t is_audio_desc; ///< Audio description /* Misc flags */ - uint8_t star_rating; ///< Star rating - uint8_t age_rating; ///< Age certificate - ratinglabel_t *rating_label; ///< Age certificate label (eg: 'PG') - uint8_t is_new; ///< New series / file premiere - uint8_t is_repeat; ///< Repeat screening - uint8_t running; ///< EPG running flag - uint8_t update_running; ///< new EPG running flag + uint8_t star_rating; ///< Star rating + uint8_t age_rating; ///< Age certificate + ratinglabel_t* rating_label; ///< Age certificate label (eg: 'PG') + uint8_t is_new; ///< New series / file premiere + uint8_t is_repeat; ///< Repeat screening + uint8_t running; ///< EPG running flag + uint8_t update_running; ///< new EPG running flag /* Broadcast level text */ - lang_str_t *title; ///< Title - lang_str_t *subtitle; ///< Sub-title - lang_str_t *summary; ///< Summary - lang_str_t *description; ///< Description - - char *image; ///< Episode image - epg_genre_list_t genre; ///< Episode genre(s) - epg_episode_num_t epnum; ///< Episode numbering; NOTE: use the accessor routine! - - htsmsg_t *credits; ///< Cast/Credits map of name -> role type (actor, presenter, director, etc). - lang_str_t *credits_cached; ///< Comma separated cast (for regex searching in GUI/autorec). Kept in sync with cast_map - string_list_t *category; ///< Extra categories (typically from xmltv) such as "Western" or "Sumo Wrestling". - ///< These extra categories are often a superset of our EN 300 468 DVB genre. - ///< Used with drop-down lists in the GUI. - string_list_t *keyword; ///< Extra keywords (typically from xmltv) such as "Wild West" or "Unicorn". - lang_str_t *keyword_cached; ///< Cached CSV version for regex searches. - epg_set_t *serieslink; ///< Series Link - epg_set_t *episodelink; ///< Episode Link - - time_t first_aired; ///< Original airdate - uint16_t copyright_year; ///< xmltv DTD gives a tag "date" (separate to previously-shown/first aired). - ///< This is the date programme was "finished...probably the copyright date." - ///< We'll call it copyright_year since words like "complete" and "finished" - ///< sound too similar to dvr recorded functionality. We'll only store the - ///< year since we only get year not month and day. + lang_str_t* title; ///< Title + lang_str_t* subtitle; ///< Sub-title + lang_str_t* summary; ///< Summary + lang_str_t* description; ///< Description + + char* image; ///< Episode image + epg_genre_list_t genre; ///< Episode genre(s) + epg_episode_num_t epnum; ///< Episode numbering; NOTE: use the accessor routine! + + htsmsg_t* credits; ///< Cast/Credits map of name -> role type (actor, presenter, director, etc). + lang_str_t* credits_cached; ///< Comma separated cast (for regex searching in GUI/autorec). Kept + ///< in sync with cast_map + string_list_t* category; ///< Extra categories (typically from xmltv) such as "Western" or "Sumo + ///< Wrestling". These extra categories are often a superset of our EN + ///< 300 468 DVB genre. Used with drop-down lists in the GUI. + string_list_t* + keyword; ///< Extra keywords (typically from xmltv) such as "Wild West" or "Unicorn". + lang_str_t* keyword_cached; ///< Cached CSV version for regex searches. + epg_set_t* serieslink; ///< Series Link + epg_set_t* episodelink; ///< Episode Link + + time_t first_aired; ///< Original airdate + uint16_t + copyright_year; ///< xmltv DTD gives a tag "date" (separate to previously-shown/first aired). + ///< This is the date programme was "finished...probably the copyright date." + ///< We'll call it copyright_year since words like "complete" and "finished" + ///< sound too similar to dvr recorded functionality. We'll only store the + ///< year since we only get year not month and day. }; /* Lookup */ -epg_broadcast_t *epg_broadcast_find_by_time - ( struct channel *ch, struct epggrab_module *src, - time_t start, time_t stop, int create, int *save, epg_changes_t *changes ); -epg_broadcast_t *epg_broadcast_find_by_eid ( struct channel *ch, uint16_t eid ); -epg_broadcast_t *epg_broadcast_find_by_id ( uint32_t id ); +epg_broadcast_t* epg_broadcast_find_by_time(struct channel* ch, + struct epggrab_module* src, + time_t start, + time_t stop, + int create, + int* save, + epg_changes_t* changes); +epg_broadcast_t* epg_broadcast_find_by_eid(struct channel* ch, uint16_t eid); +epg_broadcast_t* epg_broadcast_find_by_id(uint32_t id); /* Post-modify */ -int epg_broadcast_change_finish( epg_broadcast_t *b, epg_changes_t changed, int merge ) - __attribute__((warn_unused_result)); +int epg_broadcast_change_finish(epg_broadcast_t* b, epg_changes_t changed, int merge) + __attribute__((warn_unused_result)); /* Special */ -epg_broadcast_t *epg_broadcast_clone - ( struct channel *channel, epg_broadcast_t *src, int *save ); +epg_broadcast_t* epg_broadcast_clone(struct channel* channel, epg_broadcast_t* src, int* save); /* Mutators */ -int epg_broadcast_set_dvb_eid - ( epg_broadcast_t *b, uint16_t dvb_eid, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_running - ( epg_broadcast_t *b, epg_running_t running ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_is_widescreen - ( epg_broadcast_t *b, uint8_t ws, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_is_hd - ( epg_broadcast_t *b, uint8_t hd, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_lines - ( epg_broadcast_t *b, uint16_t lines, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_aspect - ( epg_broadcast_t *b, uint16_t aspect, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_is_deafsigned - ( epg_broadcast_t *b, uint8_t ds, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_is_subtitled - ( epg_broadcast_t *b, uint8_t st, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_is_audio_desc - ( epg_broadcast_t *b, uint8_t ad, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_is_new - ( epg_broadcast_t *b, uint8_t n, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_is_repeat - ( epg_broadcast_t *b, uint8_t r, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_title - ( epg_broadcast_t *b, const lang_str_t *str, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_subtitle - ( epg_broadcast_t *b, const lang_str_t *str, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_summary - ( epg_broadcast_t *b, const lang_str_t *str, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_description - ( epg_broadcast_t *b, const lang_str_t *str, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_credits -( epg_broadcast_t *b, const htsmsg_t *msg, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_category -( epg_broadcast_t *b, const string_list_t *msg, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_keyword -( epg_broadcast_t *b, const string_list_t *msg, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_serieslink_uri - ( epg_broadcast_t *b, const char *uri, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_episodelink_uri - ( epg_broadcast_t *b, const char *uri, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_epnumber - ( epg_broadcast_t *b, uint16_t number, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_eppart - ( epg_broadcast_t *b, uint16_t number, uint16_t count, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_epnum - ( epg_broadcast_t *b, epg_episode_num_t *num, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_genre - ( epg_broadcast_t *b, epg_genre_list_t *g, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_image - ( epg_broadcast_t *b, const char *i, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_is_bw - ( epg_broadcast_t *b, uint8_t bw, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_first_aired - ( epg_broadcast_t *b, time_t aired, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_star_rating - ( epg_broadcast_t *b, uint8_t stars, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_copyright_year - ( epg_broadcast_t *b, uint16_t stars, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_age_rating - ( epg_broadcast_t *b, uint8_t age, epg_changes_t *changed ) - __attribute__((warn_unused_result)); -int epg_broadcast_set_rating_label - ( epg_broadcast_t *b, ratinglabel_t *rating_label, epg_changes_t *changed ) - __attribute__((warn_unused_result)); +int epg_broadcast_set_dvb_eid(epg_broadcast_t* b, uint16_t dvb_eid, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_running(epg_broadcast_t* b, epg_running_t running) + __attribute__((warn_unused_result)); +int epg_broadcast_set_is_widescreen(epg_broadcast_t* b, uint8_t ws, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_is_hd(epg_broadcast_t* b, uint8_t hd, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_lines(epg_broadcast_t* b, uint16_t lines, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_aspect(epg_broadcast_t* b, uint16_t aspect, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_is_deafsigned(epg_broadcast_t* b, uint8_t ds, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_is_subtitled(epg_broadcast_t* b, uint8_t st, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_is_audio_desc(epg_broadcast_t* b, uint8_t ad, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_is_new(epg_broadcast_t* b, uint8_t n, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_is_repeat(epg_broadcast_t* b, uint8_t r, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_title(epg_broadcast_t* b, const lang_str_t* str, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_subtitle(epg_broadcast_t* b, const lang_str_t* str, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_summary(epg_broadcast_t* b, const lang_str_t* str, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_description(epg_broadcast_t* b, const lang_str_t* str, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_credits(epg_broadcast_t* b, const htsmsg_t* msg, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_category(epg_broadcast_t* b, const string_list_t* msg, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_keyword(epg_broadcast_t* b, const string_list_t* msg, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_serieslink_uri(epg_broadcast_t* b, const char* uri, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_episodelink_uri(epg_broadcast_t* b, const char* uri, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_epnumber(epg_broadcast_t* b, uint16_t number, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_eppart(epg_broadcast_t* b, + uint16_t number, + uint16_t count, + epg_changes_t* changed) __attribute__((warn_unused_result)); +int epg_broadcast_set_epnum(epg_broadcast_t* b, epg_episode_num_t* num, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_genre(epg_broadcast_t* b, epg_genre_list_t* g, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_image(epg_broadcast_t* b, const char* i, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_is_bw(epg_broadcast_t* b, uint8_t bw, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_first_aired(epg_broadcast_t* b, time_t aired, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_star_rating(epg_broadcast_t* b, uint8_t stars, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_copyright_year(epg_broadcast_t* b, uint16_t stars, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_age_rating(epg_broadcast_t* b, uint8_t age, epg_changes_t* changed) + __attribute__((warn_unused_result)); +int epg_broadcast_set_rating_label(epg_broadcast_t* b, + ratinglabel_t* rating_label, + epg_changes_t* changed) __attribute__((warn_unused_result)); /* Accessors */ -epg_broadcast_t *epg_broadcast_get_prev( epg_broadcast_t *b ); -epg_broadcast_t *epg_broadcast_get_next( epg_broadcast_t *b ); -const char *epg_broadcast_get_title - ( const epg_broadcast_t *b, const char *lang ); -const char *epg_broadcast_get_subtitle - ( epg_broadcast_t *b, const char *lang ); -const char *epg_broadcast_get_summary - ( epg_broadcast_t *b, const char *lang ); -const char *epg_broadcast_get_description - ( epg_broadcast_t *b, const char *lang ); +epg_broadcast_t* epg_broadcast_get_prev(epg_broadcast_t* b); +epg_broadcast_t* epg_broadcast_get_next(epg_broadcast_t* b); +const char* epg_broadcast_get_title(const epg_broadcast_t* b, const char* lang); +const char* epg_broadcast_get_subtitle(epg_broadcast_t* b, const char* lang); +const char* epg_broadcast_get_summary(epg_broadcast_t* b, const char* lang); +const char* epg_broadcast_get_description(epg_broadcast_t* b, const char* lang); /* Get the cached (csv) version for regex searching */ -const char *epg_broadcast_get_credits_cached - ( epg_broadcast_t *b, const char *lang ); -const char *epg_broadcast_get_keyword_cached - ( epg_broadcast_t *b, const char *lang ); -const ratinglabel_t *epg_broadcast_get_rating_label - ( epg_broadcast_t *b ); +const char* epg_broadcast_get_credits_cached(epg_broadcast_t* b, const char* lang); +const char* epg_broadcast_get_keyword_cached(epg_broadcast_t* b, const char* lang); +const ratinglabel_t* epg_broadcast_get_rating_label(epg_broadcast_t* b); /* Episode number heplers */ // Note: this does NOT strdup the text field -void epg_broadcast_get_epnum - ( const epg_broadcast_t *b, epg_episode_num_t *epnum ); -size_t epg_broadcast_epnumber_format - ( epg_broadcast_t *b, char *buf, size_t len, - const char *pre, const char *sfmt, - const char *sep, const char *efmt, - const char *cfmt ); - -static inline int epg_episode_match(epg_broadcast_t *a, epg_broadcast_t *b) -{ - if (a == NULL || b == NULL) return 0; - if (a->episodelink == NULL || b->episodelink == NULL) return 0; +void epg_broadcast_get_epnum(const epg_broadcast_t* b, epg_episode_num_t* epnum); +size_t epg_broadcast_epnumber_format(epg_broadcast_t* b, + char* buf, + size_t len, + const char* pre, + const char* sfmt, + const char* sep, + const char* efmt, + const char* cfmt); + +static inline int epg_episode_match(epg_broadcast_t* a, epg_broadcast_t* b) { + if (a == NULL || b == NULL) + return 0; + if (a->episodelink == NULL || b->episodelink == NULL) + return 0; return a->episodelink == b->episodelink; } /* Serialization */ -htsmsg_t *epg_broadcast_serialize ( epg_broadcast_t *b ); -epg_broadcast_t *epg_broadcast_deserialize - ( htsmsg_t *m, int create, int *save ); +htsmsg_t* epg_broadcast_serialize(epg_broadcast_t* b); +epg_broadcast_t* epg_broadcast_deserialize(htsmsg_t* m, int create, int* save); /* ************************************************************************ * Channel - provides mapping from EPG channels to real channels * ***********************************************************************/ -int epg_channel_ignore_broadcast( struct channel *ch, time_t start ); +int epg_channel_ignore_broadcast(struct channel* ch, time_t start); /* Unlink */ -void epg_channel_unlink ( struct channel *ch ); +void epg_channel_unlink(struct channel* ch); /* Match now / next events */ -epg_broadcast_t *epg_match_now_next ( struct channel *ch, epg_broadcast_t *ebc ); +epg_broadcast_t* epg_match_now_next(struct channel* ch, epg_broadcast_t* ebc); /* ************************************************************************ * Global config * ***********************************************************************/ -htsmsg_t *epg_config_serialize ( void ); -int epg_config_deserialize ( htsmsg_t *m ); +htsmsg_t* epg_config_serialize(void); +int epg_config_deserialize(htsmsg_t* m); /* ************************************************************************ * Querying @@ -494,7 +462,7 @@ typedef enum { } epg_comp_t; typedef struct epg_filter_str { - char *str; + char* str; tvh_regex_t re; epg_comp_t comp; } epg_filter_str_t; @@ -507,34 +475,34 @@ typedef struct epg_filter_num { typedef struct epg_query { /* Configuration */ - char *lang; + char* lang; /* Filter */ - epg_filter_num_t start; - epg_filter_num_t stop; - epg_filter_num_t duration; - epg_filter_str_t title; - epg_filter_str_t subtitle; - epg_filter_str_t summary; - epg_filter_str_t description; - epg_filter_str_t extratext; - epg_filter_num_t episode; - epg_filter_num_t stars; - epg_filter_num_t age; - epg_filter_str_t channel_name; - epg_filter_num_t channel_num; - char *stitle; - tvh_regex_t stitle_re; - int fulltext; - int new_only; - char *channel; - char *channel_tag; - uint32_t genre_count; - uint8_t *genre; - uint8_t genre_static[16]; - char *cat1; - char *cat2; - char *cat3; + epg_filter_num_t start; + epg_filter_num_t stop; + epg_filter_num_t duration; + epg_filter_str_t title; + epg_filter_str_t subtitle; + epg_filter_str_t summary; + epg_filter_str_t description; + epg_filter_str_t extratext; + epg_filter_num_t episode; + epg_filter_num_t stars; + epg_filter_num_t age; + epg_filter_str_t channel_name; + epg_filter_num_t channel_num; + char* stitle; + tvh_regex_t stitle_re; + int fulltext; + int new_only; + char* channel; + char* channel_tag; + uint32_t genre_count; + uint8_t* genre; + uint8_t genre_static[16]; + char* cat1; + char* cat2; + char* cat3; enum { ESK_START, @@ -551,29 +519,26 @@ typedef struct epg_query { ESK_AGE, ESK_GENRE } sort_key; - enum { - ES_ASC, - ES_DSC - } sort_dir; + enum { ES_ASC, ES_DSC } sort_dir; /* Result */ - epg_broadcast_t **result; + epg_broadcast_t** result; uint32_t entries; uint32_t allocated; } epg_query_t; -epg_broadcast_t **epg_query(epg_query_t *eq, access_t *perm); -void epg_query_free(epg_query_t *eq); +epg_broadcast_t** epg_query(epg_query_t* eq, access_t* perm); +void epg_query_free(epg_query_t* eq); /* ************************************************************************ * Setup/Shutdown * ***********************************************************************/ -void epg_init (void); -void epg_done (void); -void epg_skel_done (void); -void epg_save (void); -void epg_save_callback (void *p); -void epg_updated (void); +void epg_init(void); +void epg_done(void); +void epg_skel_done(void); +void epg_save(void); +void epg_save_callback(void* p); +void epg_updated(void); #endif /* EPG_H */ diff --git a/src/epgdb.c b/src/epgdb.c index 054f35d32..329936687 100644 --- a/src/epgdb.c +++ b/src/epgdb.c @@ -35,8 +35,8 @@ #include "config.h" #include "memoryinfo.h" -#define EPG_DB_VERSION 3 -#define EPG_DB_ALLOC_STEP (1024*1024) +#define EPG_DB_VERSION 3 +#define EPG_DB_ALLOC_STEP (1024 * 1024) extern epg_object_tree_t epg_episodes; @@ -47,29 +47,30 @@ extern epg_object_tree_t epg_episodes; /* * Process v3 data */ -static void -_epgdb_v3_process( char **sect, htsmsg_t *m, epggrab_stats_t *stats ) -{ - int save = 0; - const char *s; +static void _epgdb_v3_process(char** sect, htsmsg_t* m, epggrab_stats_t* stats) { + int save = 0; + const char* s; /* New section */ - if ( (s = htsmsg_get_str(m, "__section__")) ) { - if (*sect) free(*sect); + if ((s = htsmsg_get_str(m, "__section__"))) { + if (*sect) + free(*sect); *sect = strdup(s); - - /* Broadcasts */ - } else if ( !strcmp(*sect, "broadcasts") ) { - if (epg_broadcast_deserialize(m, 1, &save)) stats->broadcasts.total++; - /* Global config */ - } else if ( !strcmp(*sect, "config") ) { - if (epg_config_deserialize(m)) stats->config.total++; + /* Broadcasts */ + } else if (!strcmp(*sect, "broadcasts")) { + if (epg_broadcast_deserialize(m, 1, &save)) + stats->broadcasts.total++; - /* Unknown */ + /* Global config */ + } else if (!strcmp(*sect, "config")) { + if (epg_config_deserialize(m)) + stats->config.total++; + + /* Unknown */ } else { tvhdebug(LS_EPGDB, "malformed database section [%s]", *sect); - //htsmsg_print(m); + // htsmsg_print(m); } } @@ -77,15 +78,15 @@ _epgdb_v3_process( char **sect, htsmsg_t *m, epggrab_stats_t *stats ) * Memoryinfo */ -static void epg_memoryinfo_broadcasts_update(memoryinfo_t *my) -{ - channel_t *ch; - epg_broadcast_t *ebc; - int64_t size = 0, count = 0; +static void epg_memoryinfo_broadcasts_update(memoryinfo_t* my) { + channel_t* ch; + epg_broadcast_t* ebc; + int64_t size = 0, count = 0; CHANNEL_FOREACH(ch) { - if (ch->ch_epg_parent) continue; - RB_FOREACH(ebc, &ch->ch_epg_schedule, sched_link) { + if (ch->ch_epg_parent) + continue; + RB_FOREACH (ebc, &ch->ch_epg_schedule, sched_link) { size += sizeof(*ebc); size += tvh_strlen(ebc->image); size += tvh_strlen(ebc->epnum.text); @@ -99,71 +100,68 @@ static void epg_memoryinfo_broadcasts_update(memoryinfo_t *my) memoryinfo_update(my, size, count); } -static memoryinfo_t epg_memoryinfo_broadcasts = { - .my_name = "EPG Broadcasts", - .my_update = epg_memoryinfo_broadcasts_update -}; +static memoryinfo_t epg_memoryinfo_broadcasts = {.my_name = "EPG Broadcasts", + .my_update = epg_memoryinfo_broadcasts_update}; /* * Recovery */ static sigjmp_buf epg_mmap_env; -static void epg_mmap_sigbus (int sig, siginfo_t *siginfo, void *ptr) -{ +static void epg_mmap_sigbus(int sig, siginfo_t* siginfo, void* ptr) { siglongjmp(epg_mmap_env, 1); } /* * Load data */ -void epg_init ( void ) -{ - int fd = -1, r; - struct stat st; - size_t remain; - uint8_t *mem, *rp, *zlib_mem = NULL; - epggrab_stats_t stats; - int ver = EPG_DB_VERSION; +void epg_init(void) { + int fd = -1, r; + struct stat st; + size_t remain; + uint8_t * mem, *rp, *zlib_mem = NULL; + epggrab_stats_t stats; + int ver = EPG_DB_VERSION; struct sigaction act, oldact; - char *sect = NULL; + char* sect = NULL; memoryinfo_register(&epg_memoryinfo_broadcasts); /* Find the right file (and version) */ while (fd < 0 && ver > 0) { fd = hts_settings_open_file(0, "epgdb.v%d", ver); - if (fd > 0) break; + if (fd > 0) + break; ver--; } - if ( fd < 0 ) + if (fd < 0) fd = hts_settings_open_file(0, "epgdb"); - if ( fd < 0 ) { + if (fd < 0) { tvhdebug(LS_EPGDB, "database does not exist"); return; } - memset (&act, 0, sizeof(act)); + memset(&act, 0, sizeof(act)); act.sa_sigaction = epg_mmap_sigbus; - act.sa_flags = SA_SIGINFO; + act.sa_flags = SA_SIGINFO; if (sigaction(SIGBUS, &act, &oldact)) { tvherror(LS_EPGDB, "failed to install SIGBUS handler"); close(fd); return; } - + /* Map file to memory */ - if ( fstat(fd, &st) != 0 ) { + if (fstat(fd, &st) != 0) { tvherror(LS_EPGDB, "failed to detect database size"); goto end; } - if ( !st.st_size ) { + if (!st.st_size) { tvhdebug(LS_EPGDB, "database is empty"); goto end; } - remain = st.st_size; + remain = st.st_size; rp = mem = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0); - if ( mem == MAP_FAILED ) { + if (mem == MAP_FAILED) { tvherror(LS_EPGDB, "failed to mmap database"); goto end; } @@ -176,13 +174,14 @@ void epg_init ( void ) } #if ENABLE_ZLIB - if (remain > 12 && memcmp(rp, "\xff\xffGZIP01", 8) == 0 && - (rp[7] == '0' || rp[7] == '1')) { + if (remain > 12 && memcmp(rp, "\xff\xffGZIP01", 8) == 0 && (rp[7] == '0' || rp[7] == '1')) { uint32_t orig = (rp[8] << 24) | (rp[9] << 16) | (rp[10] << 8) | rp[11]; - tvhinfo(LS_EPGDB, "gzip format detected, inflating (ratio %.1f%% deflated size %zd)", - (float)((remain * 100.0) / orig), remain); + tvhinfo(LS_EPGDB, + "gzip format detected, inflating (ratio %.1f%% deflated size %zd)", + (float)((remain * 100.0) / orig), + remain); rp = zlib_mem = tvh_gzip_inflate(rp + 12, remain - 12, orig); - remain = rp ? orig : 0; + remain = rp ? orig : 0; } #endif @@ -190,11 +189,11 @@ void epg_init ( void ) /* Process */ memset(&stats, 0, sizeof(stats)); - while ( remain > 4 ) { + while (remain > 4) { /* Get message length */ - size_t msglen = remain; - htsmsg_t *m; + size_t msglen = remain; + htsmsg_t* m; r = htsmsg_binary2_deserialize(&m, rp, &msglen, NULL); /* Safety check */ @@ -204,11 +203,12 @@ void epg_init ( void ) } /* Next */ - rp += msglen; + rp += msglen; remain -= msglen; /* Skip */ - if (!m) continue; + if (!m) + continue; /* Process */ switch (ver) { @@ -226,7 +226,7 @@ void epg_init ( void ) free(sect); if (!stats.config.total) { - htsmsg_t *m = htsmsg_create_map(); + htsmsg_t* m = htsmsg_create_map(); /* it's not correct, but at least something */ htsmsg_add_u32(m, "last_id", 64 * 1024 * 1024); if (!epg_config_deserialize(m)) @@ -247,13 +247,12 @@ end: close(fd); } -void epg_done ( void ) -{ - channel_t *ch; +void epg_done(void) { + channel_t* ch; tvh_mutex_lock(&global_lock); CHANNEL_FOREACH(ch) - epg_channel_unlink(ch); + epg_channel_unlink(ch); epg_skel_done(); memoryinfo_unregister(&epg_memoryinfo_broadcasts); tvh_mutex_unlock(&global_lock); @@ -263,11 +262,10 @@ void epg_done ( void ) * Save * *************************************************************************/ -static int _epg_write ( sbuf_t *sb, htsmsg_t *m ) -{ - int ret = 1; +static int _epg_write(sbuf_t* sb, htsmsg_t* m) { + int ret = 1; size_t msglen; - void *msgdata; + void* msgdata; if (m) { int r; r = htsmsg_binary2_serialize(m, &msgdata, &msglen, 0x10000); @@ -286,20 +284,18 @@ static int _epg_write ( sbuf_t *sb, htsmsg_t *m ) return ret; } -static int _epg_write_sect ( sbuf_t *sb, const char *sect ) -{ - htsmsg_t *m = htsmsg_create_map(); +static int _epg_write_sect(sbuf_t* sb, const char* sect) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "__section__", sect); return _epg_write(sb, m); } -static void epg_save_tsk_callback ( void *p, int dearmed ) -{ - char tmppath[PATH_MAX+4]; - char path[PATH_MAX]; - sbuf_t *sb = p; - size_t size = sb->sb_ptr, orig; - int fd, r; +static void epg_save_tsk_callback(void* p, int dearmed) { + char tmppath[PATH_MAX + 4]; + char path[PATH_MAX]; + sbuf_t* sb = p; + size_t size = sb->sb_ptr, orig; + int fd, r; tvhinfo(LS_EPGDB, "save start"); hts_settings_buildpath(tmppath, sizeof(path), "epgdb.v%d", EPG_DB_VERSION); @@ -314,7 +310,7 @@ static void epg_save_tsk_callback ( void *p, int dearmed ) #if ENABLE_ZLIB if (config.epg_compress) { r = tvh_gzip_deflate_fd_header(fd, sb->sb_data, size, &orig, 3, "01") < 0; - } else + } else #endif r = tvh_write(fd, sb->sb_data, orig = size); close(fd); @@ -333,18 +329,16 @@ static void epg_save_tsk_callback ( void *p, int dearmed ) free(sb); } -void epg_save_callback ( void *p ) -{ +void epg_save_callback(void* p) { epg_save(); } -void epg_save ( void ) -{ - sbuf_t *sb = malloc(sizeof(*sb)); - epg_broadcast_t *ebc; - channel_t *ch; - epggrab_stats_t stats; - extern gtimer_t epggrab_save_timer; +void epg_save(void) { + sbuf_t* sb = malloc(sizeof(*sb)); + epg_broadcast_t* ebc; + channel_t* ch; + epggrab_stats_t stats; + extern gtimer_t epggrab_save_timer; if (!sb) return; @@ -354,17 +348,24 @@ void epg_save ( void ) sbuf_init_fixed(sb, EPG_DB_ALLOC_STEP); if (epggrab_conf.epgdb_periodicsave) - gtimer_arm_rel(&epggrab_save_timer, epg_save_callback, NULL, - epggrab_conf.epgdb_periodicsave * 3600); + gtimer_arm_rel(&epggrab_save_timer, + epg_save_callback, + NULL, + epggrab_conf.epgdb_periodicsave * 3600); memset(&stats, 0, sizeof(stats)); - if ( _epg_write_sect(sb, "config") ) goto error; - if (_epg_write(sb, epg_config_serialize())) goto error; - if ( _epg_write_sect(sb, "broadcasts") ) goto error; + if (_epg_write_sect(sb, "config")) + goto error; + if (_epg_write(sb, epg_config_serialize())) + goto error; + if (_epg_write_sect(sb, "broadcasts")) + goto error; CHANNEL_FOREACH(ch) { - if (ch->ch_epg_parent) continue; - RB_FOREACH(ebc, &ch->ch_epg_schedule, sched_link) { - if (_epg_write(sb, epg_broadcast_serialize(ebc))) goto error; + if (ch->ch_epg_parent) + continue; + RB_FOREACH (ebc, &ch->ch_epg_schedule, sched_link) { + if (_epg_write(sb, epg_broadcast_serialize(ebc))) + goto error; stats.broadcasts.total++; } } diff --git a/src/epggrab.c b/src/epggrab.c index 369651be7..e57a061fe 100644 --- a/src/epggrab.c +++ b/src/epggrab.c @@ -40,23 +40,23 @@ #include "memoryinfo.h" /* Thread protection */ -static int epggrab_confver; -tvh_mutex_t epggrab_mutex; -static tvh_cond_t epggrab_cond; -static tvh_mutex_t epggrab_data_mutex; -static tvh_cond_t epggrab_data_cond; -int epggrab_running; +static int epggrab_confver; +tvh_mutex_t epggrab_mutex; +static tvh_cond_t epggrab_cond; +static tvh_mutex_t epggrab_data_mutex; +static tvh_cond_t epggrab_data_cond; +int epggrab_running; static TAILQ_HEAD(, epggrab_module) epggrab_data_modules; -static memoryinfo_t epggrab_data_memoryinfo = { .my_name = "EPG grabber data queue" }; +static memoryinfo_t epggrab_data_memoryinfo = {.my_name = "EPG grabber data queue"}; /* Config */ -epggrab_module_list_t epggrab_modules; +epggrab_module_list_t epggrab_modules; -gtimer_t epggrab_save_timer; +gtimer_t epggrab_save_timer; -static cron_multi_t *epggrab_cron_multi; +static cron_multi_t* epggrab_cron_multi; /* ************************************************************************** * Internal Grab Thread @@ -65,22 +65,21 @@ static cron_multi_t *epggrab_cron_multi; /* * Grab from module */ -static void _epggrab_module_grab ( epggrab_module_int_t *mod ) -{ - int64_t tm1, tm2; - htsmsg_t *data; +static void _epggrab_module_grab(epggrab_module_int_t* mod) { + int64_t tm1, tm2; + htsmsg_t* data; if (!mod->enabled) return; /* Grab */ - tm1 = getfastmonoclock(); + tm1 = getfastmonoclock(); data = mod->trans(mod, mod->grab(mod)); - tm2 = getfastmonoclock() + (MONOCLOCK_RESOLUTION / 2); + tm2 = getfastmonoclock() + (MONOCLOCK_RESOLUTION / 2); /* Process */ - if ( data ) { - tvhinfo(mod->subsys, "%s: grab took %"PRId64" seconds", mod->id, mono2sec(tm2 - tm1)); + if (data) { + tvhinfo(mod->subsys, "%s: grab took %" PRId64 " seconds", mod->id, mono2sec(tm2 - tm1)); epggrab_module_parse(mod, data); } else { tvhwarn(mod->subsys, "%s: grab returned no data", mod->id); @@ -90,19 +89,18 @@ static void _epggrab_module_grab ( epggrab_module_int_t *mod ) /* * Thread (for internal grabbing) */ -static void *_epggrab_internal_thread( void *aux ) -{ - epggrab_module_t *mod; - int err, confver; - struct timespec cron_next, current_time; - time_t t; +static void* _epggrab_internal_thread(void* aux) { + epggrab_module_t* mod; + int err, confver; + struct timespec cron_next, current_time; + time_t t; - confver = epggrab_conf.int_initial ? -1 /* force first run */ : epggrab_confver; + confver = epggrab_conf.int_initial ? -1 /* force first run */ : epggrab_confver; /* Setup timeout */ clock_gettime(CLOCK_REALTIME, &cron_next); cron_next.tv_nsec = 0; - cron_next.tv_sec += 120; + cron_next.tv_sec += 120; /* Time for other jobs */ while (atomic_get(&epggrab_running)) { @@ -110,10 +108,12 @@ static void *_epggrab_internal_thread( void *aux ) err = ETIMEDOUT; while (atomic_get(&epggrab_running)) { err = tvh_cond_timedwait_ts(&epggrab_cond, &epggrab_mutex, &cron_next); - if (err == ETIMEDOUT) break; + if (err == ETIMEDOUT) + break; } tvh_mutex_unlock(&epggrab_mutex); - if (err == ETIMEDOUT) break; + if (err == ETIMEDOUT) + break; } clock_gettime(CLOCK_REALTIME, &cron_next); @@ -125,9 +125,10 @@ static void *_epggrab_internal_thread( void *aux ) tvh_mutex_lock(&epggrab_mutex); while (atomic_get(&epggrab_running) && confver == epggrab_confver) { err = tvh_cond_timedwait_ts(&epggrab_cond, &epggrab_mutex, &cron_next); - if (err == ETIMEDOUT) break; + if (err == ETIMEDOUT) + break; } - confver = epggrab_confver; + confver = epggrab_confver; clock_gettime(CLOCK_REALTIME, ¤t_time); if (!cron_multi_next(epggrab_cron_multi, current_time.tv_sec, &t)) @@ -138,20 +139,18 @@ static void *_epggrab_internal_thread( void *aux ) /* Run grabber(s) */ /* Note: this loop is not protected, assuming static boot allocation */ - LIST_FOREACH(mod, &epggrab_modules, link) { + LIST_FOREACH (mod, &epggrab_modules, link) { if (!atomic_get(&epggrab_running)) break; if (mod->type == EPGGRAB_INT) - _epggrab_module_grab((epggrab_module_int_t *)mod); + _epggrab_module_grab((epggrab_module_int_t*)mod); } } return NULL; } -void -epggrab_rerun_internal(void) -{ +void epggrab_rerun_internal(void) { epggrab_confver++; tvh_cond_signal(&epggrab_cond, 0); } @@ -159,15 +158,14 @@ epggrab_rerun_internal(void) /* * Thread (for data queue processing) */ -static void *_epggrab_data_thread( void *aux ) -{ - epggrab_module_t *mod; - epggrab_queued_data_t *eq; +static void* _epggrab_data_thread(void* aux) { + epggrab_module_t* mod; + epggrab_queued_data_t* eq; while (atomic_get(&epggrab_running)) { tvh_mutex_lock(&epggrab_data_mutex); do { - eq = NULL; + eq = NULL; mod = TAILQ_FIRST(&epggrab_data_modules); if (mod) { eq = TAILQ_FIRST(&mod->data_queue); @@ -200,17 +198,18 @@ static void *_epggrab_data_thread( void *aux ) return NULL; } -void epggrab_queue_data(epggrab_module_t *mod, - const void *data1, uint32_t len1, - const void *data2, uint32_t len2) -{ - epggrab_queued_data_t *eq; - size_t len; +void epggrab_queue_data(epggrab_module_t* mod, + const void* data1, + uint32_t len1, + const void* data2, + uint32_t len2) { + epggrab_queued_data_t* eq; + size_t len; if (!atomic_get(&epggrab_running)) return; len = sizeof(*eq) + len1 + len2; - eq = malloc(len); + eq = malloc(len); if (eq == NULL) return; eq->eq_len = len1 + len2; @@ -232,11 +231,10 @@ void epggrab_queue_data(epggrab_module_t *mod, * Configuration * *************************************************************************/ -static void _epggrab_load ( void ) -{ - htsmsg_t *m, *a, *map; - htsmsg_field_t *f; - epggrab_module_t *mod; +static void _epggrab_load(void) { + htsmsg_t * m, *a, *map; + htsmsg_field_t* f; + epggrab_module_t* mod; /* Load settings */ m = hts_settings_load("epggrab/config"); @@ -253,22 +251,23 @@ static void _epggrab_load ( void ) } } htsmsg_destroy(m); - /* Defaults */ + /* Defaults */ } else { free(epggrab_conf.cron); epggrab_conf.cron = strdup("# Default config (00:04 and 12:04 everyday)\n4 */12 * * *"); - LIST_FOREACH(mod, &epggrab_modules, link) // enable only OTA EIT and OTA PSIP by default + LIST_FOREACH (mod, &epggrab_modules, link) // enable only OTA EIT and OTA PSIP by default if (mod->type == EPGGRAB_OTA && - ((mod->subsys == LS_TBL_EIT && strcmp(mod->id, "eit") == 0) || - mod->subsys == LS_PSIP)) { + ((mod->subsys == LS_TBL_EIT && strcmp(mod->id, "eit") == 0) || mod->subsys == LS_PSIP)) { mod->enabled = 1; epggrab_activate_module(mod, 1); } } if (epggrab_conf.epgdb_periodicsave) - gtimer_arm_rel(&epggrab_save_timer, epg_save_callback, NULL, - epggrab_conf.epgdb_periodicsave * 3600); + gtimer_arm_rel(&epggrab_save_timer, + epg_save_callback, + NULL, + epggrab_conf.epgdb_periodicsave * 3600); idnode_notify_changed(&epggrab_conf.idnode); @@ -282,23 +281,18 @@ static void _epggrab_load ( void ) * Class * *************************************************************************/ -static void -epggrab_class_changed(idnode_t *self) -{ -} +static void epggrab_class_changed(idnode_t* self) {} -static htsmsg_t * -epggrab_class_save(idnode_t *self, char *filename, size_t fsize) -{ - epggrab_module_t *mod; - htsmsg_t *m, *a; +static htsmsg_t* epggrab_class_save(idnode_t* self, char* filename, size_t fsize) { + epggrab_module_t* mod; + htsmsg_t * m, *a; /* Save */ m = htsmsg_create_map(); idnode_save(&epggrab_conf.idnode, m); a = htsmsg_create_map(); - LIST_FOREACH(mod, &epggrab_modules, link) { - htsmsg_t *m = htsmsg_create_map(); + LIST_FOREACH (mod, &epggrab_modules, link) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "class", mod->idnode.in_class->ic_class); idnode_save(&mod->idnode, m); htsmsg_add_msg(a, mod->id, m); @@ -309,28 +303,20 @@ epggrab_class_save(idnode_t *self, char *filename, size_t fsize) return m; } -epggrab_conf_t epggrab_conf = { - .idnode.in_class = &epggrab_class -}; +epggrab_conf_t epggrab_conf = {.idnode.in_class = &epggrab_class}; -static void -epggrab_class_cron_notify(void *self, const char *lang) -{ +static void epggrab_class_cron_notify(void* self, const char* lang) { tvh_mutex_lock(&epggrab_mutex); free(epggrab_cron_multi); epggrab_cron_multi = cron_multi_set(epggrab_conf.cron); tvh_mutex_unlock(&epggrab_mutex); } -static void -epggrab_class_ota_cron_notify(void *self, const char *lang) -{ +static void epggrab_class_ota_cron_notify(void* self, const char* lang) { epggrab_ota_set_cron(); } -static void -epggrab_class_ota_genre_translation_notify(void *self, const char *lang) -{ +static void epggrab_class_ota_genre_translation_notify(void* self, const char* lang) { epggrab_ota_set_genre_translation(); } @@ -338,191 +324,187 @@ CLASS_DOC(epgconf) PROP_DOC(cron) PROP_DOC(ota_genre_translation) -const idclass_t epggrab_class = { - .ic_snode = &epggrab_conf.idnode, - .ic_class = "epggrab", - .ic_caption = N_("Channels / EPG - EPG Grabber Configuration"), - .ic_doc = tvh_doc_epgconf_class, - .ic_event = "epggrab", - .ic_perm_def = ACCESS_ADMIN, - .ic_changed = epggrab_class_changed, - .ic_save = epggrab_class_save, - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - { - .name = N_("Internal Grabber Settings"), - .number = 2, - }, - { - .name = N_("OTA (Over-the-air) Grabber Settings"), - .number = 3, - }, - { - .name = N_("OTA (Over-the-air) Genre Translation"), - .number = 4, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "channel_rename", - .name = N_("Update channel name"), - .desc = N_("Automatically update channel names using " - "information provided by the enabled EPG providers. " - "Note, this may cause unwanted changes to " - "already defined channel names."), - .off = offsetof(epggrab_conf_t, channel_rename), - .opts = PO_ADVANCED, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "channel_renumber", - .name = N_("Update channel number"), - .desc = N_("Automatically update channel numbers using " - "information provided by the enabled EPG providers. " - "Note, this may cause unwanted changes to " - "already defined channel numbers."), - .off = offsetof(epggrab_conf_t, channel_renumber), - .opts = PO_ADVANCED, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "channel_reicon", - .name = N_("Update channel icon"), - .desc = N_("Automatically update channel icons using " - "information provided by the enabled EPG providers. " - "Note, this may cause unwanted changes to " - "already defined channel icons."), - .off = offsetof(epggrab_conf_t, channel_reicon), - .opts = PO_ADVANCED, - .group = 1, - }, - { - .type = PT_INT, - .id = "epgdb_periodicsave", - .name = N_("Periodically save EPG to disk (hours)"), - .desc = N_("Writes the current in-memory EPG database to disk " - "every x hours, so should a crash/unexpected " - "shutdown occur EPG data is saved " - "periodically to the database (re-read on next " - "startup). Set to 0 to disable."), - .off = offsetof(epggrab_conf_t, epgdb_periodicsave), - .group = 1, - }, - { - .type = PT_BOOL, - .id = "epgdb_saveafterimport", - .name = N_("Save EPG to disk after xmltv import"), - .desc = N_("Writes the current in-memory EPG database to disk " - "shortly after an xmltv import has completed, so should a crash/unexpected " - "shutdown occur EPG data is saved " - "(re-read on next startup)."), - .off = offsetof(epggrab_conf_t, epgdb_saveafterimport), - .group = 1, - }, - { - .type = PT_BOOL, - .id = "epgdb_processparentallabels", - .name = N_("Process Parental Rating Labels"), - .desc = N_("Convert broadcast ratings codes into " - "human-readable labels like 'PG' or 'FSK 16'."), - .off = offsetof(epggrab_conf_t, epgdb_processparentallabels), - .group = 1, - }, - { - .type = PT_STR, - .id = "cron", - .name = N_("Cron multi-line"), - .desc = N_("Multiple lines of the cron time specification. " - "The default cron triggers the internal grabbers " - "daily at 12:04 and 00:04. See Help on how to define " - "your own."), - .doc = prop_doc_cron, - .off = offsetof(epggrab_conf_t, cron), - .notify = epggrab_class_cron_notify, - .opts = PO_MULTILINE | PO_ADVANCED, - .group = 2, - }, - { - .type = PT_BOOL, - .id = "int_initial", - .name = N_("Force initial EPG grab at start-up (internal grabbers)"), - .desc = N_("Force an initial EPG grab at start-up (internal grabbers)."), - .off = offsetof(epggrab_conf_t, int_initial), - .opts = PO_ADVANCED, - .group = 2, - }, - { - .type = PT_BOOL, - .id = "ota_initial", - .name = N_("Force initial EPG grab at start-up"), - .desc = N_("Force an initial EPG grab at start-up."), - .off = offsetof(epggrab_conf_t, ota_initial), - .opts = PO_ADVANCED, - .group = 3, - }, - { - .type = PT_STR, - .id = "ota_cron", - .name = N_("Over-the-air Cron multi-line"), - .desc = N_("Multiple lines of the cron time specification. " - "The default cron triggers the over-the-air " - "grabber daily at 02:04 and 14:04. See Help on how " - "to define your own."), - .doc = prop_doc_cron, - .off = offsetof(epggrab_conf_t, ota_cron), - .notify = epggrab_class_ota_cron_notify, - .opts = PO_MULTILINE | PO_ADVANCED, - .group = 3, - }, - { - .type = PT_U32, - .id = "ota_timeout", - .name = N_("EPG scan time-out in seconds (30-7200)"), - .desc = N_("The maximum amount of time a grabber is allowed " - "scan a mux for data (in seconds)."), - .off = offsetof(epggrab_conf_t, ota_timeout), - .opts = PO_EXPERT, - .group = 3, - }, - { - .type = PT_STR, - .id = "ota_genre_translation", - .name = N_("Over-the-air Genre Translation"), - .desc = N_("Translate the genre codes received from the broadcaster to another genre code." - "
Use the form xxx=yyy, where xxx and yyy are " - "'ETSI EN 300 468' content descriptor values expressed in decimal (0-255). " - "
Genre code xxx will be converted to genre code yyy." - "
Use a separate line for each genre code to be converted."), - .doc = prop_doc_ota_genre_translation, - .off = offsetof(epggrab_conf_t, ota_genre_translation), - .notify = epggrab_class_ota_genre_translation_notify, - .opts = PO_MULTILINE | PO_EXPERT, - .group = 4, - }, - {} - } -}; +const idclass_t epggrab_class = {.ic_snode = &epggrab_conf.idnode, + .ic_class = "epggrab", + .ic_caption = N_("Channels / EPG - EPG Grabber Configuration"), + .ic_doc = tvh_doc_epgconf_class, + .ic_event = "epggrab", + .ic_perm_def = ACCESS_ADMIN, + .ic_changed = epggrab_class_changed, + .ic_save = epggrab_class_save, + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + { + .name = N_("Internal Grabber Settings"), + .number = 2, + }, + { + .name = N_("OTA (Over-the-air) Grabber Settings"), + .number = 3, + }, + { + .name = N_("OTA (Over-the-air) Genre Translation"), + .number = 4, + }, + {}}, + .ic_properties = (const property_t[]){ + { + .type = PT_BOOL, + .id = "channel_rename", + .name = N_("Update channel name"), + .desc = N_("Automatically update channel names using " + "information provided by the enabled EPG providers. " + "Note, this may cause unwanted changes to " + "already defined channel names."), + .off = offsetof(epggrab_conf_t, channel_rename), + .opts = PO_ADVANCED, + .group = 1, + }, + { + .type = PT_BOOL, + .id = "channel_renumber", + .name = N_("Update channel number"), + .desc = N_("Automatically update channel numbers using " + "information provided by the enabled EPG providers. " + "Note, this may cause unwanted changes to " + "already defined channel numbers."), + .off = offsetof(epggrab_conf_t, channel_renumber), + .opts = PO_ADVANCED, + .group = 1, + }, + { + .type = PT_BOOL, + .id = "channel_reicon", + .name = N_("Update channel icon"), + .desc = N_("Automatically update channel icons using " + "information provided by the enabled EPG providers. " + "Note, this may cause unwanted changes to " + "already defined channel icons."), + .off = offsetof(epggrab_conf_t, channel_reicon), + .opts = PO_ADVANCED, + .group = 1, + }, + { + .type = PT_INT, + .id = "epgdb_periodicsave", + .name = N_("Periodically save EPG to disk (hours)"), + .desc = N_("Writes the current in-memory EPG database to disk " + "every x hours, so should a crash/unexpected " + "shutdown occur EPG data is saved " + "periodically to the database (re-read on next " + "startup). Set to 0 to disable."), + .off = offsetof(epggrab_conf_t, epgdb_periodicsave), + .group = 1, + }, + { + .type = PT_BOOL, + .id = "epgdb_saveafterimport", + .name = N_("Save EPG to disk after xmltv import"), + .desc = N_("Writes the current in-memory EPG database to disk " + "shortly after an xmltv import has completed, so should a crash/unexpected " + "shutdown occur EPG data is saved " + "(re-read on next startup)."), + .off = offsetof(epggrab_conf_t, epgdb_saveafterimport), + .group = 1, + }, + { + .type = PT_BOOL, + .id = "epgdb_processparentallabels", + .name = N_("Process Parental Rating Labels"), + .desc = N_("Convert broadcast ratings codes into " + "human-readable labels like 'PG' or 'FSK 16'."), + .off = offsetof(epggrab_conf_t, epgdb_processparentallabels), + .group = 1, + }, + { + .type = PT_STR, + .id = "cron", + .name = N_("Cron multi-line"), + .desc = N_("Multiple lines of the cron time specification. " + "The default cron triggers the internal grabbers " + "daily at 12:04 and 00:04. See Help on how to define " + "your own."), + .doc = prop_doc_cron, + .off = offsetof(epggrab_conf_t, cron), + .notify = epggrab_class_cron_notify, + .opts = PO_MULTILINE | PO_ADVANCED, + .group = 2, + }, + { + .type = PT_BOOL, + .id = "int_initial", + .name = N_("Force initial EPG grab at start-up (internal grabbers)"), + .desc = N_("Force an initial EPG grab at start-up (internal grabbers)."), + .off = offsetof(epggrab_conf_t, int_initial), + .opts = PO_ADVANCED, + .group = 2, + }, + { + .type = PT_BOOL, + .id = "ota_initial", + .name = N_("Force initial EPG grab at start-up"), + .desc = N_("Force an initial EPG grab at start-up."), + .off = offsetof(epggrab_conf_t, ota_initial), + .opts = PO_ADVANCED, + .group = 3, + }, + { + .type = PT_STR, + .id = "ota_cron", + .name = N_("Over-the-air Cron multi-line"), + .desc = N_("Multiple lines of the cron time specification. " + "The default cron triggers the over-the-air " + "grabber daily at 02:04 and 14:04. See Help on how " + "to define your own."), + .doc = prop_doc_cron, + .off = offsetof(epggrab_conf_t, ota_cron), + .notify = epggrab_class_ota_cron_notify, + .opts = PO_MULTILINE | PO_ADVANCED, + .group = 3, + }, + { + .type = PT_U32, + .id = "ota_timeout", + .name = N_("EPG scan time-out in seconds (30-7200)"), + .desc = N_("The maximum amount of time a grabber is allowed " + "scan a mux for data (in seconds)."), + .off = offsetof(epggrab_conf_t, ota_timeout), + .opts = PO_EXPERT, + .group = 3, + }, + { + .type = PT_STR, + .id = "ota_genre_translation", + .name = N_("Over-the-air Genre Translation"), + .desc = + N_("Translate the genre codes received from the broadcaster to another genre code." + "
Use the form xxx=yyy, where xxx and yyy are " + "'ETSI EN 300 468' content descriptor values expressed in decimal (0-255). " + "
Genre code xxx will be converted to genre code yyy." + "
Use a separate line for each genre code to be converted."), + .doc = prop_doc_ota_genre_translation, + .off = offsetof(epggrab_conf_t, ota_genre_translation), + .notify = epggrab_class_ota_genre_translation_notify, + .opts = PO_MULTILINE | PO_EXPERT, + .group = 4, + }, + {}}}; /* ************************************************************************** * Initialisation * *************************************************************************/ -int epggrab_activate_module ( epggrab_module_t *mod, int a ) -{ +int epggrab_activate_module(epggrab_module_t* mod, int a) { int save = 0; - if (!mod) return 0; + if (!mod) + return 0; if (mod->activate) { - save = mod->activate(mod, a); + save = mod->activate(mod, a); } else if (a != mod->active) { - mod->active = a; - save = 1; + mod->active = a; + save = 1; } return save; } @@ -530,24 +512,23 @@ int epggrab_activate_module ( epggrab_module_t *mod, int a ) /* * Initialise */ -pthread_t epggrab_tid; -pthread_t epggrab_data_tid; +pthread_t epggrab_tid; +pthread_t epggrab_data_tid; -void epggrab_init ( void ) -{ +void epggrab_init(void) { memoryinfo_register(&epggrab_data_memoryinfo); /* Defaults */ - epggrab_conf.cron = NULL; - epggrab_conf.int_initial = 1; - epggrab_conf.channel_rename = 0; - epggrab_conf.channel_renumber = 0; - epggrab_conf.channel_reicon = 0; - epggrab_conf.epgdb_periodicsave = 0; - epggrab_conf.epgdb_saveafterimport = 0; + epggrab_conf.cron = NULL; + epggrab_conf.int_initial = 1; + epggrab_conf.channel_rename = 0; + epggrab_conf.channel_renumber = 0; + epggrab_conf.channel_reicon = 0; + epggrab_conf.epgdb_periodicsave = 0; + epggrab_conf.epgdb_saveafterimport = 0; epggrab_conf.epgdb_processparentallabels = 0; - epggrab_cron_multi = NULL; + epggrab_cron_multi = NULL; tvh_mutex_init(&epggrab_mutex, NULL); tvh_mutex_init(&epggrab_data_mutex, NULL); @@ -592,9 +573,8 @@ void epggrab_init ( void ) /* * Cleanup */ -void epggrab_done ( void ) -{ - epggrab_module_t *mod; +void epggrab_done(void) { + epggrab_module_t* mod; atomic_set(&epggrab_running, 0); tvh_cond_signal(&epggrab_cond, 0); @@ -612,9 +592,9 @@ void epggrab_done ( void ) mod->done(mod); tvh_mutex_lock(&global_lock); epggrab_channel_flush(mod, 0); - free((void *)mod->id); - free((void *)mod->saveid); - free((void *)mod->name); + free((void*)mod->id); + free((void*)mod->saveid); + free((void*)mod->name); free(mod); } epggrab_ota_shutdown(); diff --git a/src/epggrab.h b/src/epggrab.h index 62020a49a..c712d6dc7 100644 --- a/src/epggrab.h +++ b/src/epggrab.h @@ -25,16 +25,16 @@ * Typedefs/Forward decls * *************************************************************************/ -typedef struct epggrab_queued_data epggrab_queued_data_t; -typedef struct epggrab_module epggrab_module_t; -typedef struct epggrab_module_int epggrab_module_int_t; -typedef struct epggrab_module_ext epggrab_module_ext_t; -typedef struct epggrab_module_ota epggrab_module_ota_t; -typedef struct epggrab_module_ota_scraper epggrab_module_ota_scraper_t; -typedef struct epggrab_ota_mux epggrab_ota_mux_t; -typedef struct epggrab_ota_mux_eit_plist epggrab_ota_mux_eit_plist_t; -typedef struct epggrab_ota_map epggrab_ota_map_t; -typedef struct epggrab_ota_svc_link epggrab_ota_svc_link_t; +typedef struct epggrab_queued_data epggrab_queued_data_t; +typedef struct epggrab_module epggrab_module_t; +typedef struct epggrab_module_int epggrab_module_int_t; +typedef struct epggrab_module_ext epggrab_module_ext_t; +typedef struct epggrab_module_ota epggrab_module_ota_t; +typedef struct epggrab_module_ota_scraper epggrab_module_ota_scraper_t; +typedef struct epggrab_ota_mux epggrab_ota_mux_t; +typedef struct epggrab_ota_mux_eit_plist epggrab_ota_mux_eit_plist_t; +typedef struct epggrab_ota_map epggrab_ota_map_t; +typedef struct epggrab_ota_svc_link epggrab_ota_svc_link_t; LIST_HEAD(epggrab_module_list, epggrab_module); typedef struct epggrab_module_list epggrab_module_list_t; @@ -46,15 +46,13 @@ struct channel; * Grabber Stats * *************************************************************************/ -typedef struct epggrab_stats_part -{ +typedef struct epggrab_stats_part { int created; int modified; int total; } epggrab_stats_part_t; -typedef struct epggrab_stats -{ +typedef struct epggrab_stats { epggrab_stats_part_t channels; epggrab_stats_part_t brands; epggrab_stats_part_t seasons; @@ -78,62 +76,61 @@ TAILQ_HEAD(epggrab_channel_queue, epggrab_channel); /* * Grab channel */ -typedef struct epggrab_channel -{ - idnode_t idnode; +typedef struct epggrab_channel { + idnode_t idnode; TAILQ_ENTRY(epggrab_channel) all_link; ///< Global link - RB_ENTRY(epggrab_channel) link; ///< Global tree link - epggrab_module_t *mod; ///< Linked module + RB_ENTRY(epggrab_channel) link; ///< Global tree link + epggrab_module_t* mod; ///< Linked module - int updated; ///< EPG channel was updated - int enabled; ///< Enabled/disabled - char *id; ///< Grabber's ID + int updated; ///< EPG channel was updated + int enabled; ///< Enabled/disabled + char* id; ///< Grabber's ID - char *name; ///< Channel name - htsmsg_t *names; ///< List of all channel names for grabber's ID - htsmsg_t *newnames;///< List of all channel names for grabber's ID (scan) - char *icon; ///< Channel icon - char *comment; ///< Channel comment (EPG) - int64_t lcn; ///< Channel number (split) + char* name; ///< Channel name + htsmsg_t* names; ///< List of all channel names for grabber's ID + htsmsg_t* newnames; ///< List of all channel names for grabber's ID (scan) + char* icon; ///< Channel icon + char* comment; ///< Channel comment (EPG) + int64_t lcn; ///< Channel number (split) - time_t laststamp;///< Last update timestamp + time_t laststamp; ///< Last update timestamp - int only_one; ///< Map to only one channel (auto) - idnode_list_head_t channels; ///< Mapped channels (1 = epggrab channel, 2 = channel) + int only_one; ///< Map to only one channel (auto) + idnode_list_head_t channels; ///< Mapped channels (1 = epggrab channel, 2 = channel) - int update_chicon; ///< Update channel icon - int update_chnum; ///< Update channel number - int update_chname; ///< Update channel name + int update_chicon; ///< Update channel icon + int update_chnum; ///< Update channel number + int update_chname; ///< Update channel name } epggrab_channel_t; /* * Access functions */ -htsmsg_t *epggrab_channel_list ( int ota ); +htsmsg_t* epggrab_channel_list(int ota); /* * Mutators */ -int epggrab_channel_set_name ( epggrab_channel_t *ch, const char *name ); -int epggrab_channel_set_icon ( epggrab_channel_t *ch, const char *icon ); -int epggrab_channel_set_number ( epggrab_channel_t *ch, int major, int minor ); +int epggrab_channel_set_name(epggrab_channel_t* ch, const char* name); +int epggrab_channel_set_icon(epggrab_channel_t* ch, const char* icon); +int epggrab_channel_set_number(epggrab_channel_t* ch, int major, int minor); /* * Updated/link */ -void epggrab_channel_updated ( epggrab_channel_t *ch ); -void epggrab_channel_link_delete ( epggrab_channel_t *ec, struct channel *ch, int delconf ); -int epggrab_channel_link ( epggrab_channel_t *ec, struct channel *ch, void *origin ); -int epggrab_channel_map ( idnode_t *ec, idnode_t *ch, void *origin ); +void epggrab_channel_updated(epggrab_channel_t* ch); +void epggrab_channel_link_delete(epggrab_channel_t* ec, struct channel* ch, int delconf); +int epggrab_channel_link(epggrab_channel_t* ec, struct channel* ch, void* origin); +int epggrab_channel_map(idnode_t* ec, idnode_t* ch, void* origin); /* ID */ -const char *epggrab_channel_get_id ( epggrab_channel_t *ch ); -epggrab_channel_t *epggrab_channel_find_by_id ( const char *id ); +const char* epggrab_channel_get_id(epggrab_channel_t* ch); +epggrab_channel_t* epggrab_channel_find_by_id(const char* id); /* * Check type */ -int epggrab_channel_is_ota ( epggrab_channel_t *ec ); +int epggrab_channel_is_ota(epggrab_channel_t* ec); /* ************************************************************************** * Grabber Modules @@ -142,124 +139,115 @@ int epggrab_channel_is_ota ( epggrab_channel_t *ec ); /* * Data queue */ -struct epggrab_queued_data -{ +struct epggrab_queued_data { TAILQ_ENTRY(epggrab_queued_data) eq_link; - uint32_t eq_len; - uint8_t eq_data[0]; ///< Data are allocated at the end of structure + uint32_t eq_len; + uint8_t eq_data[0]; ///< Data are allocated at the end of structure }; /* * Grabber base class */ -struct epggrab_module -{ - idnode_t idnode; - LIST_ENTRY(epggrab_module) link; ///< Global list link - TAILQ_ENTRY(epggrab_module) qlink; ///< Queued data link +struct epggrab_module { + idnode_t idnode; + LIST_ENTRY(epggrab_module) link; ///< Global list link + TAILQ_ENTRY(epggrab_module) qlink; ///< Queued data link enum { EPGGRAB_OTA, EPGGRAB_INT, EPGGRAB_EXT, - } type; ///< Grabber type - const char *id; ///< Module identifier - int subsys; ///< Module log subsystem - const char *saveid; ///< Module save identifier - const char *name; ///< Module name (for display) - int enabled; ///< Whether the module is enabled - int active; ///< Whether the module is active - int priority; ///< Priority of the module - epggrab_channel_tree_t channels; ///< Channel list + } type; ///< Grabber type + const char* id; ///< Module identifier + int subsys; ///< Module log subsystem + const char* saveid; ///< Module save identifier + const char* name; ///< Module name (for display) + int enabled; ///< Whether the module is enabled + int active; ///< Whether the module is active + int priority; ///< Priority of the module + epggrab_channel_tree_t channels; ///< Channel list TAILQ_HEAD(, epggrab_queued_data) data_queue; /* Activate */ - int (*activate)( void *m, int activate ); + int (*activate)(void* m, int activate); /* Free */ - void (*done)( void *m ); + void (*done)(void* m); /* Process queued data */ - void (*process_data)( void *m, void *data, uint32_t len ); + void (*process_data)(void* m, void* data, uint32_t len); }; /* * Internal grabber */ -struct epggrab_module_int -{ - epggrab_module_t ; ///< Parent object +struct epggrab_module_int { + epggrab_module_t; ///< Parent object - const char *path; ///< Path for the command - const char *args; ///< Extra arguments + const char* path; ///< Path for the command + const char* args; ///< Extra arguments - int xmltv_chnum; - int xmltv_scrape_extra; ///< Scrape actors and extra details - int xmltv_scrape_onto_desc; ///< Include scraped actors - ///< and extra details on to programme description for viewing by legacy clients. - int xmltv_use_category_not_genre; ///< Use category tags and don't map to DVB genres. + int xmltv_chnum; + int xmltv_scrape_extra; ///< Scrape actors and extra details + int xmltv_scrape_onto_desc; ///< Include scraped actors + ///< and extra details on to programme description for viewing by + ///< legacy clients. + int xmltv_use_category_not_genre; ///< Use category tags and don't map to DVB genres. /* Handle data */ - char* (*grab) ( void *mod ); - htsmsg_t* (*trans) ( void *mod, char *data ); - int (*parse) ( void *mod, htsmsg_t *data, epggrab_stats_t *stat ); + char* (*grab)(void* mod); + htsmsg_t* (*trans)(void* mod, char* data); + int (*parse)(void* mod, htsmsg_t* data, epggrab_stats_t* stat); }; /* * External grabber */ -struct epggrab_module_ext -{ - epggrab_module_int_t ; ///< Parent object +struct epggrab_module_ext { + epggrab_module_int_t; ///< Parent object - int sock; ///< Socket descriptor + int sock; ///< Socket descriptor - pthread_t tid; ///< Thread ID + pthread_t tid; ///< Thread ID }; -struct epggrab_ota_svc_link -{ - tvh_uuid_t uuid; - uint64_t last_tune_count; +struct epggrab_ota_svc_link { + tvh_uuid_t uuid; + uint64_t last_tune_count; RB_ENTRY(epggrab_ota_svc_link) link; }; struct epggrab_ota_mux_eit_plist { LIST_ENTRY(epggrab_ota_mux_eit_plist) link; - const char *src; - void *priv; + const char* src; + void* priv; }; /* * TODO: this could be embedded in the mux itself, but by using a soft-link * and keeping it here I can somewhat isolate it from the mpegts code */ -struct epggrab_ota_mux -{ - tvh_uuid_t om_mux_uuid; ///< Soft-link to mux - LIST_HEAD(,epggrab_ota_map) om_modules; ///< List of linked mods - - uint8_t om_done; ///< The full completion mark for this round - uint8_t om_complete; ///< Has completed a scan - uint8_t om_requeue; ///< Requeue when stolen - uint8_t om_save; ///< something changed - uint8_t om_detected; ///< detected some activity - mtimer_t om_timer; ///< Per mux active timer - mtimer_t om_data_timer; ///< Any EPG data seen? - mtimer_t om_handlers_timer; ///< Run handlers callback - int64_t om_retry_time; ///< Next time to retry - - char *om_force_modname;///< Force this module +struct epggrab_ota_mux { + tvh_uuid_t om_mux_uuid; ///< Soft-link to mux + LIST_HEAD(, epggrab_ota_map) om_modules; ///< List of linked mods - enum { - EPGGRAB_OTA_MUX_IDLE, - EPGGRAB_OTA_MUX_PENDING, - EPGGRAB_OTA_MUX_ACTIVE - } om_q_type; + uint8_t om_done; ///< The full completion mark for this round + uint8_t om_complete; ///< Has completed a scan + uint8_t om_requeue; ///< Requeue when stolen + uint8_t om_save; ///< something changed + uint8_t om_detected; ///< detected some activity + mtimer_t om_timer; ///< Per mux active timer + mtimer_t om_data_timer; ///< Any EPG data seen? + mtimer_t om_handlers_timer; ///< Run handlers callback + int64_t om_retry_time; ///< Next time to retry + + char* om_force_modname; ///< Force this module + + enum { EPGGRAB_OTA_MUX_IDLE, EPGGRAB_OTA_MUX_PENDING, EPGGRAB_OTA_MUX_ACTIVE } om_q_type; - TAILQ_ENTRY(epggrab_ota_mux) om_q_link; - RB_ENTRY(epggrab_ota_mux) om_global_link; + TAILQ_ENTRY(epggrab_ota_mux) om_q_link; + RB_ENTRY(epggrab_ota_mux) om_global_link; LIST_HEAD(, epggrab_ota_mux_eit_plist) om_eit_plist; }; @@ -267,90 +255,88 @@ struct epggrab_ota_mux /* * Link between ota_mux and ota_module */ -struct epggrab_ota_map -{ - LIST_ENTRY(epggrab_ota_map) om_link; - epggrab_module_ota_t *om_module; - int om_complete; - uint8_t om_first; - uint64_t om_tune_count; - RB_HEAD(,epggrab_ota_svc_link) om_svcs; ///< Services we carry data for - void *om_opaque; +struct epggrab_ota_map { + LIST_ENTRY(epggrab_ota_map) om_link; + epggrab_module_ota_t* om_module; + int om_complete; + uint8_t om_first; + uint64_t om_tune_count; + RB_HEAD(, epggrab_ota_svc_link) om_svcs; ///< Services we carry data for + void* om_opaque; }; /* * Over the air grabber */ -struct epggrab_module_ota -{ - epggrab_module_t ; ///< Parent object +struct epggrab_module_ota { + epggrab_module_t; ///< Parent object /* Transponder tuning */ - int (*start) ( epggrab_ota_map_t *map, struct mpegts_mux *mm ); - int (*stop) ( epggrab_ota_map_t *map, struct mpegts_mux *mm ); - void (*handlers) (epggrab_ota_map_t *map, struct mpegts_mux *mm ); - int (*tune) ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om, - struct mpegts_mux *mm ); - void *opaque; + int (*start)(epggrab_ota_map_t* map, struct mpegts_mux* mm); + int (*stop)(epggrab_ota_map_t* map, struct mpegts_mux* mm); + void (*handlers)(epggrab_ota_map_t* map, struct mpegts_mux* mm); + int (*tune)(epggrab_ota_map_t* map, epggrab_ota_mux_t* om, struct mpegts_mux* mm); + void* opaque; }; /* * Over the air grabber that supports configurable scraping of data. */ -struct epggrab_module_ota_scraper -{ - epggrab_module_ota_t ; ///< Parent object - char *scrape_config; ///< Config to use or blank/NULL for default. - int scrape_episode; ///< Scrape season/episode from EIT summary - int scrape_title; ///< Scrape title from EIT title + summary - int scrape_subtitle;///< Scrape subtitle from EIT summary - int scrape_summary; ///< Scrape summary from EIT summary +struct epggrab_module_ota_scraper { + epggrab_module_ota_t; ///< Parent object + char* scrape_config; ///< Config to use or blank/NULL for default. + int scrape_episode; ///< Scrape season/episode from EIT summary + int scrape_title; ///< Scrape title from EIT title + summary + int scrape_subtitle; ///< Scrape subtitle from EIT summary + int scrape_summary; ///< Scrape summary from EIT summary }; /* * */ typedef struct epggrab_conf { - idnode_t idnode; - char *cron; - uint32_t channel_rename; - uint32_t channel_renumber; - uint32_t channel_reicon; - uint32_t epgdb_periodicsave; - uint32_t epgdb_saveafterimport; - uint32_t epgdb_processparentallabels; - char *ota_cron; - char *ota_genre_translation; - uint32_t ota_timeout; - uint32_t ota_initial; - uint32_t int_initial; + idnode_t idnode; + char* cron; + uint32_t channel_rename; + uint32_t channel_renumber; + uint32_t channel_reicon; + uint32_t epgdb_periodicsave; + uint32_t epgdb_saveafterimport; + uint32_t epgdb_processparentallabels; + char* ota_cron; + char* ota_genre_translation; + uint32_t ota_timeout; + uint32_t ota_initial; + uint32_t int_initial; } epggrab_conf_t; /* * */ -extern epggrab_conf_t epggrab_conf; -extern const idclass_t epggrab_class; -extern const idclass_t epggrab_class_mod; -extern const idclass_t epggrab_class_mod_int; -extern const idclass_t epggrab_class_mod_ext; -extern const idclass_t epggrab_class_mod_ota; -extern const idclass_t epggrab_channel_class; +extern epggrab_conf_t epggrab_conf; +extern const idclass_t epggrab_class; +extern const idclass_t epggrab_class_mod; +extern const idclass_t epggrab_class_mod_int; +extern const idclass_t epggrab_class_mod_ext; +extern const idclass_t epggrab_class_mod_ota; +extern const idclass_t epggrab_channel_class; extern struct epggrab_channel_queue epggrab_channel_entries; /* * Access the Module list */ -epggrab_module_t* epggrab_module_find_by_id ( const char *id ); -const char * epggrab_module_type(epggrab_module_t *mod); -const char * epggrab_module_get_status(epggrab_module_t *mod); +epggrab_module_t* epggrab_module_find_by_id(const char* id); +const char* epggrab_module_type(epggrab_module_t* mod); +const char* epggrab_module_get_status(epggrab_module_t* mod); /* * Data queue */ -void epggrab_queue_data(epggrab_module_t *mod, - const void *data1, uint32_t len1, - const void *data2, uint32_t len2); +void epggrab_queue_data(epggrab_module_t* mod, + const void* data1, + uint32_t len1, + const void* data2, + uint32_t len2); /* ************************************************************************** * Setup/Configuration @@ -367,20 +353,20 @@ extern int epggrab_ota_running; /* * Set configuration */ -int epggrab_activate_module ( epggrab_module_t *mod, int activate ); -void epggrab_ota_set_cron ( void ); -void epggrab_ota_set_genre_translation ( void ); -void epggrab_ota_trigger ( int secs ); -void epggrab_rerun_internal ( void ); +int epggrab_activate_module(epggrab_module_t* mod, int activate); +void epggrab_ota_set_cron(void); +void epggrab_ota_set_genre_translation(void); +void epggrab_ota_trigger(int secs); +void epggrab_rerun_internal(void); /* * Load/Save */ -void epggrab_init ( void ); -void epggrab_done ( void ); -void epggrab_ota_init ( void ); -void epggrab_ota_post ( void ); -void epggrab_ota_shutdown ( void ); +void epggrab_init(void); +void epggrab_done(void); +void epggrab_ota_init(void); +void epggrab_ota_post(void); +void epggrab_ota_shutdown(void); /* ************************************************************************** * Global Functions @@ -389,22 +375,22 @@ void epggrab_ota_shutdown ( void ); /* * Channel handling */ -void epggrab_channel_add ( struct channel *ch ); -void epggrab_channel_rem ( struct channel *ch ); -void epggrab_channel_mod ( struct channel *ch ); +void epggrab_channel_add(struct channel* ch); +void epggrab_channel_rem(struct channel* ch); +void epggrab_channel_mod(struct channel* ch); /* * OTA kick */ -void epggrab_ota_queue_mux( struct mpegts_mux *mm ); -epggrab_ota_mux_t *epggrab_ota_find_mux ( struct mpegts_mux *mm ); -htsmsg_t *epggrab_ota_module_id_list( const char *lang ); -const char *epggrab_ota_check_module_id( const char *id ); +void epggrab_ota_queue_mux(struct mpegts_mux* mm); +epggrab_ota_mux_t* epggrab_ota_find_mux(struct mpegts_mux* mm); +htsmsg_t* epggrab_ota_module_id_list(const char* lang); +const char* epggrab_ota_check_module_id(const char* id); /* * Global variable for genre translation */ -extern unsigned char *epggrab_ota_genre_translation; +extern unsigned char* epggrab_ota_genre_translation; #endif /* __EPGGRAB_H__ */ diff --git a/src/epggrab/channel.c b/src/epggrab/channel.c index 2bda67fd8..5e32db78d 100644 --- a/src/epggrab/channel.c +++ b/src/epggrab/channel.c @@ -36,15 +36,11 @@ SKEL_DECLARE(epggrab_channel_skel, epggrab_channel_t); * EPG Grab Channel functions * *************************************************************************/ -static inline int -is_paired( epggrab_channel_t *ec ) -{ +static inline int is_paired(epggrab_channel_t* ec) { return ec->only_one && LIST_FIRST(&ec->channels); } -static inline int -epggrab_channel_check ( epggrab_channel_t *ec, channel_t *ch ) -{ +static inline int epggrab_channel_check(epggrab_channel_t* ec, channel_t* ch) { if (!ec || !ch || !ch->ch_epgauto || !ch->ch_enabled) return 0; if (ch->ch_epg_parent || !ec->enabled) @@ -55,9 +51,8 @@ epggrab_channel_check ( epggrab_channel_t *ec, channel_t *ch ) } /* Check if channels match by epgid */ -int epggrab_channel_match_epgid ( epggrab_channel_t *ec, channel_t *ch ) -{ - const char *chid; +int epggrab_channel_match_epgid(epggrab_channel_t* ec, channel_t* ch) { + const char* chid; if (ec->id == NULL) return 0; @@ -70,10 +65,9 @@ int epggrab_channel_match_epgid ( epggrab_channel_t *ec, channel_t *ch ) } /* Check if channels match by name */ -int epggrab_channel_match_name ( epggrab_channel_t *ec, channel_t *ch ) -{ - const char *name, *s; - htsmsg_field_t *f; +int epggrab_channel_match_name(epggrab_channel_t* ec, channel_t* ch) { + const char * name, *s; + htsmsg_field_t* f; if (!epggrab_channel_check(ec, ch)) return 0; @@ -87,44 +81,42 @@ int epggrab_channel_match_name ( epggrab_channel_t *ec, channel_t *ch ) if (ec->names) HTSMSG_FOREACH(f, ec->names) - if ((s = htsmsg_field_get_str(f)) != NULL) - if (!strcasecmp(s, name)) - return 1; + if ((s = htsmsg_field_get_str(f)) != NULL) + if (!strcasecmp(s, name)) + return 1; return 0; } /* Check if channels match by number */ -int epggrab_channel_match_number ( epggrab_channel_t *ec, channel_t *ch ) -{ +int epggrab_channel_match_number(epggrab_channel_t* ec, channel_t* ch) { if (ec->lcn == 0) return 0; if (!epggrab_channel_check(ec, ch)) return 0; - if (ec->lcn && ec->lcn == channel_get_number(ch)) return 1; + if (ec->lcn && ec->lcn == channel_get_number(ch)) + return 1; return 0; } /* Delete ilm */ -static void -_epgggrab_channel_link_delete(idnode_list_mapping_t *ilm, int delconf) -{ - epggrab_channel_t *ec = (epggrab_channel_t *)ilm->ilm_in1; - channel_t *ch = (channel_t *)ilm->ilm_in2; - tvhdebug(ec->mod->subsys, "%s: unlinking %s from %s", - ec->mod->id, ec->id, channel_get_name(ch, channel_blank_name)); +static void _epgggrab_channel_link_delete(idnode_list_mapping_t* ilm, int delconf) { + epggrab_channel_t* ec = (epggrab_channel_t*)ilm->ilm_in1; + channel_t* ch = (channel_t*)ilm->ilm_in2; + tvhdebug(ec->mod->subsys, + "%s: unlinking %s from %s", + ec->mod->id, + ec->id, + channel_get_name(ch, channel_blank_name)); idnode_list_unlink(ilm, delconf ? ec : NULL); } /* Destroy */ -void -epggrab_channel_link_delete - ( epggrab_channel_t *ec, channel_t *ch, int delconf ) -{ - idnode_list_mapping_t *ilm; - LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) +void epggrab_channel_link_delete(epggrab_channel_t* ec, channel_t* ch, int delconf) { + idnode_list_mapping_t* ilm; + LIST_FOREACH (ilm, &ec->channels, ilm_in1_link) if (ilm->ilm_in1 == &ec->idnode && ilm->ilm_in2 == &ch->ch_id) { _epgggrab_channel_link_delete(ilm, delconf); return; @@ -132,17 +124,14 @@ epggrab_channel_link_delete } /* Destroy all links */ -static void epggrab_channel_links_delete( epggrab_channel_t *ec, int delconf ) -{ - idnode_list_mapping_t *ilm; +static void epggrab_channel_links_delete(epggrab_channel_t* ec, int delconf) { + idnode_list_mapping_t* ilm; while ((ilm = LIST_FIRST(&ec->channels))) _epgggrab_channel_link_delete(ilm, delconf); } /* Do update */ -static void -epggrab_channel_sync( epggrab_channel_t *ec, channel_t *ch ) -{ +static void epggrab_channel_sync(epggrab_channel_t* ec, channel_t* ch) { int save = 0; if (ec->update_chname && ec->name && epggrab_conf.channel_rename) @@ -156,16 +145,15 @@ epggrab_channel_sync( epggrab_channel_t *ec, channel_t *ch ) } /* Link epggrab channel to real channel */ -int -epggrab_channel_link ( epggrab_channel_t *ec, channel_t *ch, void *origin ) -{ - idnode_list_mapping_t *ilm; +int epggrab_channel_link(epggrab_channel_t* ec, channel_t* ch, void* origin) { + idnode_list_mapping_t* ilm; /* No change */ - if (!ch || !ch->ch_enabled) return 0; + if (!ch || !ch->ch_enabled) + return 0; /* Already linked */ - LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) + LIST_FOREACH (ilm, &ec->channels, ilm_in1_link) if (ilm->ilm_in2 == &ch->ch_id) { ilm->ilm_mark = 0; epggrab_channel_sync(ec, ch); @@ -173,12 +161,13 @@ epggrab_channel_link ( epggrab_channel_t *ec, channel_t *ch, void *origin ) } /* New link */ - tvhdebug(ec->mod->subsys, "%s: linking %s to %s", - ec->mod->id, ec->id, channel_get_name(ch, channel_blank_name)); + tvhdebug(ec->mod->subsys, + "%s: linking %s to %s", + ec->mod->id, + ec->id, + channel_get_name(ch, channel_blank_name)); - ilm = idnode_list_link(&ec->idnode, &ec->channels, - &ch->ch_id, &ch->ch_epggrab, - origin, 1); + ilm = idnode_list_link(&ec->idnode, &ec->channels, &ch->ch_id, &ch->ch_epggrab, origin, 1); if (ilm == NULL) return 0; @@ -189,25 +178,24 @@ epggrab_channel_link ( epggrab_channel_t *ec, channel_t *ch, void *origin ) return 1; } -int -epggrab_channel_map ( idnode_t *ec, idnode_t *ch, void *origin ) -{ - return epggrab_channel_link((epggrab_channel_t *)ec, (channel_t *)ch, origin); +int epggrab_channel_map(idnode_t* ec, idnode_t* ch, void* origin) { + return epggrab_channel_link((epggrab_channel_t*)ec, (channel_t*)ch, origin); } /* Set name */ -int epggrab_channel_set_name ( epggrab_channel_t *ec, const char *name ) -{ - idnode_list_mapping_t *ilm; - channel_t *ch; - int save = 0; - if (!ec || !name) return 0; +int epggrab_channel_set_name(epggrab_channel_t* ec, const char* name) { + idnode_list_mapping_t* ilm; + channel_t* ch; + int save = 0; + if (!ec || !name) + return 0; if (!ec->newnames && (!ec->name || strcmp(ec->name, name))) { - if (ec->name) free(ec->name); + if (ec->name) + free(ec->name); ec->name = strdup(name); if (epggrab_conf.channel_rename) { - LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) { - ch = (channel_t *)ilm->ilm_in2; + LIST_FOREACH (ilm, &ec->channels, ilm_in1_link) { + ch = (channel_t*)ilm->ilm_in2; if (channel_set_name(ch, name)) idnode_changed(&ch->ch_id); } @@ -222,18 +210,19 @@ int epggrab_channel_set_name ( epggrab_channel_t *ec, const char *name ) } /* Set icon */ -int epggrab_channel_set_icon ( epggrab_channel_t *ec, const char *icon ) -{ - idnode_list_mapping_t *ilm; - channel_t *ch; - int save = 0; - if (!ec || !icon) return 0; - if (!ec->icon || strcmp(ec->icon, icon) ) { - if (ec->icon) free(ec->icon); +int epggrab_channel_set_icon(epggrab_channel_t* ec, const char* icon) { + idnode_list_mapping_t* ilm; + channel_t* ch; + int save = 0; + if (!ec || !icon) + return 0; + if (!ec->icon || strcmp(ec->icon, icon)) { + if (ec->icon) + free(ec->icon); ec->icon = strdup(icon); if (epggrab_conf.channel_reicon) { - LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) { - ch = (channel_t *)ilm->ilm_in2; + LIST_FOREACH (ilm, &ec->channels, ilm_in1_link) { + ch = (channel_t*)ilm->ilm_in2; if (channel_set_icon(ch, icon)) idnode_changed(&ch->ch_id); } @@ -245,22 +234,20 @@ int epggrab_channel_set_icon ( epggrab_channel_t *ec, const char *icon ) } /* Set channel number */ -int epggrab_channel_set_number ( epggrab_channel_t *ec, int major, int minor ) -{ - idnode_list_mapping_t *ilm; - channel_t *ch; - int64_t lcn; - int save = 0; - if (!ec || (major <= 0 && minor <= 0)) return 0; +int epggrab_channel_set_number(epggrab_channel_t* ec, int major, int minor) { + idnode_list_mapping_t* ilm; + channel_t* ch; + int64_t lcn; + int save = 0; + if (!ec || (major <= 0 && minor <= 0)) + return 0; lcn = (major * CHANNEL_SPLIT) + minor; if (ec->lcn != lcn) { ec->lcn = lcn; if (epggrab_conf.channel_renumber) { - LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) { - ch = (channel_t *)ilm->ilm_in2; - if (channel_set_number(ch, - lcn / CHANNEL_SPLIT, - lcn % CHANNEL_SPLIT)) + LIST_FOREACH (ilm, &ec->channels, ilm_in1_link) { + ch = (channel_t*)ilm->ilm_in2; + if (channel_set_number(ch, lcn / CHANNEL_SPLIT, lcn % CHANNEL_SPLIT)) idnode_changed(&ch->ch_id); } } @@ -271,9 +258,7 @@ int epggrab_channel_set_number ( epggrab_channel_t *ec, int major, int minor ) } /* Autolink EPG channel to channel */ -static int -epggrab_channel_autolink_one( epggrab_channel_t *ec, channel_t *ch ) -{ +static int epggrab_channel_autolink_one(epggrab_channel_t* ec, channel_t* ch) { if (epggrab_channel_match_epgid(ec, ch)) return epggrab_channel_link(ec, ch, NULL); else if (epggrab_channel_match_name(ec, ch)) @@ -284,30 +269,28 @@ epggrab_channel_autolink_one( epggrab_channel_t *ec, channel_t *ch ) } /* Autolink EPG channel to channel */ -static int -epggrab_channel_autolink( epggrab_channel_t *ec ) -{ - channel_t *ch; +static int epggrab_channel_autolink(epggrab_channel_t* ec) { + channel_t* ch; CHANNEL_FOREACH(ch) - if (epggrab_channel_match_epgid(ec, ch)) - if (epggrab_channel_link(ec, ch, NULL)) - return 1; + if (epggrab_channel_match_epgid(ec, ch)) + if (epggrab_channel_link(ec, ch, NULL)) + return 1; CHANNEL_FOREACH(ch) - if (epggrab_channel_match_name(ec, ch)) - if (epggrab_channel_link(ec, ch, NULL)) - return 1; + if (epggrab_channel_match_name(ec, ch)) + if (epggrab_channel_link(ec, ch, NULL)) + return 1; CHANNEL_FOREACH(ch) - if (epggrab_channel_match_number(ec, ch)) - if (epggrab_channel_link(ec, ch, NULL)) - return 1; + if (epggrab_channel_match_number(ec, ch)) + if (epggrab_channel_link(ec, ch, NULL)) + return 1; return 0; } /* Channel settings updated */ -void epggrab_channel_updated ( epggrab_channel_t *ec ) -{ - if (!ec) return; +void epggrab_channel_updated(epggrab_channel_t* ec) { + if (!ec) + return; /* Find a link */ if (!is_paired(ec)) @@ -318,17 +301,14 @@ void epggrab_channel_updated ( epggrab_channel_t *ec ) } /* ID comparison */ -static int _ch_id_cmp ( void *a, void *b ) -{ - return strcmp(((epggrab_channel_t*)a)->id, - ((epggrab_channel_t*)b)->id); +static int _ch_id_cmp(void* a, void* b) { + return strcmp(((epggrab_channel_t*)a)->id, ((epggrab_channel_t*)b)->id); } /* Create new entry */ -epggrab_channel_t *epggrab_channel_create - ( epggrab_module_t *owner, htsmsg_t *conf, const char *uuid ) -{ - epggrab_channel_t *ec; +epggrab_channel_t* +epggrab_channel_create(epggrab_module_t* owner, htsmsg_t* conf, const char* uuid) { + epggrab_channel_t* ec; ec = calloc(1, sizeof(*ec)); if (idnode_insert(&ec->idnode, uuid, &epggrab_channel_class, 0)) { @@ -338,10 +318,10 @@ epggrab_channel_t *epggrab_channel_create return NULL; } - ec->mod = owner; - ec->enabled = 1; + ec->mod = owner; + ec->enabled = 1; ec->update_chicon = 1; - ec->update_chnum = 1; + ec->update_chnum = 1; ec->update_chname = 1; if (conf) @@ -361,11 +341,10 @@ epggrab_channel_t *epggrab_channel_create } /* Find/Create channel in the list */ -epggrab_channel_t *epggrab_channel_find - ( epggrab_module_t *mod, const char *id, int create, int *save ) -{ - char *s; - epggrab_channel_t *ec; +epggrab_channel_t* +epggrab_channel_find(epggrab_module_t* mod, const char* id, int create, int* save) { + char* s; + epggrab_channel_t* ec; if (id == NULL || id[0] == '\0') { tvhwarn(LS_EPGGRAB, "%s: ignoring empty EPG id source", mod->id); @@ -378,7 +357,8 @@ epggrab_channel_t *epggrab_channel_find /* Replace / with # */ // Note: this is a bit of a nasty fix for #1774, but will do for now while (*s) { - if (*s == '/') *s = '#'; + if (*s == '/') + *s = '#'; s++; } @@ -386,31 +366,31 @@ epggrab_channel_t *epggrab_channel_find if (!create) { ec = RB_FIND(&mod->channels, epggrab_channel_skel, link, _ch_id_cmp); - /* Find/Create */ + /* Find/Create */ } else { ec = RB_INSERT_SORTED(&mod->channels, epggrab_channel_skel, link, _ch_id_cmp); if (!ec) { - ec = epggrab_channel_skel; + ec = epggrab_channel_skel; SKEL_USED(epggrab_channel_skel); ec->enabled = 1; - ec->id = strdup(ec->id); - ec->mod = mod; + ec->id = strdup(ec->id); + ec->mod = mod; TAILQ_INSERT_TAIL(&epggrab_channel_entries, ec, all_link); if (idnode_insert(&ec->idnode, NULL, &epggrab_channel_class, 0)) abort(); - *save = 1; + *save = 1; return ec; } } return ec; } -void epggrab_channel_destroy( epggrab_channel_t *ec, int delconf, int rb_remove ) -{ +void epggrab_channel_destroy(epggrab_channel_t* ec, int delconf, int rb_remove) { char ubuf[UUID_HEX_SIZE]; - if (ec == NULL) return; + if (ec == NULL) + return; idnode_save_check(&ec->idnode, delconf); @@ -423,7 +403,8 @@ void epggrab_channel_destroy( epggrab_channel_t *ec, int delconf, int rb_remove if (delconf) hts_settings_remove("epggrab/%s/channels/%s", - ec->mod->saveid, idnode_uuid_as_str(&ec->idnode, ubuf)); + ec->mod->saveid, + idnode_uuid_as_str(&ec->idnode, ubuf)); htsmsg_destroy(ec->newnames); htsmsg_destroy(ec->names); @@ -434,19 +415,16 @@ void epggrab_channel_destroy( epggrab_channel_t *ec, int delconf, int rb_remove free(ec); } -void epggrab_channel_flush - ( epggrab_module_t *mod, int delconf ) -{ - epggrab_channel_t *ec; +void epggrab_channel_flush(epggrab_module_t* mod, int delconf) { + epggrab_channel_t* ec; while ((ec = RB_FIRST(&mod->channels)) != NULL) epggrab_channel_destroy(ec, delconf, 1); } -void epggrab_channel_begin_scan ( epggrab_module_t *mod ) -{ - epggrab_channel_t *ec; +void epggrab_channel_begin_scan(epggrab_module_t* mod) { + epggrab_channel_t* ec; lock_assert(&global_lock); - RB_FOREACH(ec, &mod->channels, link) { + RB_FOREACH (ec, &mod->channels, link) { ec->updated = 0; if (ec->newnames) { htsmsg_destroy(ec->newnames); @@ -455,15 +433,14 @@ void epggrab_channel_begin_scan ( epggrab_module_t *mod ) } } -void epggrab_channel_end_scan ( epggrab_module_t *mod ) -{ - epggrab_channel_t *ec; +void epggrab_channel_end_scan(epggrab_module_t* mod) { + epggrab_channel_t* ec; lock_assert(&global_lock); - RB_FOREACH(ec, &mod->channels, link) { + RB_FOREACH (ec, &mod->channels, link) { if (ec->newnames) { if (htsmsg_cmp(ec->names, ec->newnames)) { htsmsg_destroy(ec->names); - ec->names = ec->newnames; + ec->names = ec->newnames; ec->updated = 1; } else { htsmsg_destroy(ec->newnames); @@ -481,46 +458,39 @@ void epggrab_channel_end_scan ( epggrab_module_t *mod ) * Global routines * *************************************************************************/ -void epggrab_channel_add ( channel_t *ch ) -{ - epggrab_module_t *mod; - epggrab_channel_t *ec; +void epggrab_channel_add(channel_t* ch) { + epggrab_module_t* mod; + epggrab_channel_t* ec; - LIST_FOREACH(mod, &epggrab_modules, link) - RB_FOREACH(ec, &mod->channels, link) { + LIST_FOREACH (mod, &epggrab_modules, link) + RB_FOREACH (ec, &mod->channels, link) { if (!is_paired(ec)) epggrab_channel_autolink_one(ec, ch); } } -void epggrab_channel_rem ( channel_t *ch ) -{ - idnode_list_mapping_t *ilm; +void epggrab_channel_rem(channel_t* ch) { + idnode_list_mapping_t* ilm; while ((ilm = LIST_FIRST(&ch->ch_epggrab)) != NULL) idnode_list_unlink(ilm, ch); } -void epggrab_channel_mod ( channel_t *ch ) -{ +void epggrab_channel_mod(channel_t* ch) { return epggrab_channel_add(ch); } -const char * -epggrab_channel_get_id ( epggrab_channel_t *ec ) -{ - static char buf[1024]; - epggrab_module_t *m = ec->mod; +const char* epggrab_channel_get_id(epggrab_channel_t* ec) { + static char buf[1024]; + epggrab_module_t* m = ec->mod; snprintf(buf, sizeof(buf), "%s|%s", m->id, ec->id); return buf; } -epggrab_channel_t * -epggrab_channel_find_by_id ( const char *id ) -{ - char buf[1024]; - char *mid, *cid; - epggrab_module_t *mod; +epggrab_channel_t* epggrab_channel_find_by_id(const char* id) { + char buf[1024]; + char * mid, *cid; + epggrab_module_t* mod; strlcpy(buf, id, sizeof(buf)); if ((mid = strtok_r(buf, "|", &cid)) && cid) if ((mod = epggrab_module_find_by_id(mid)) != NULL) @@ -528,9 +498,7 @@ epggrab_channel_find_by_id ( const char *id ) return NULL; } -int -epggrab_channel_is_ota ( epggrab_channel_t *ec ) -{ +int epggrab_channel_is_ota(epggrab_channel_t* ec) { return ec->mod->type == EPGGRAB_OTA; } @@ -539,82 +507,66 @@ epggrab_channel_is_ota ( epggrab_channel_t *ec ) */ static void -epggrab_channel_class_get_title - (idnode_t *self, const char *lang, char *dst, size_t dstsize) -{ - epggrab_channel_t *ec = (epggrab_channel_t*)self; +epggrab_channel_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + epggrab_channel_t* ec = (epggrab_channel_t*)self; - snprintf(dst, dstsize, "%s: %s (%s)", - ec->name ?: ec->id, ec->id, ec->mod->name); + snprintf(dst, dstsize, "%s: %s (%s)", ec->name ?: ec->id, ec->id, ec->mod->name); } -static htsmsg_t * -epggrab_channel_class_save(idnode_t *self, char *filename, size_t fsize) -{ - epggrab_channel_t *ec = (epggrab_channel_t *)self; - htsmsg_t *m = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* epggrab_channel_class_save(idnode_t* self, char* filename, size_t fsize) { + epggrab_channel_t* ec = (epggrab_channel_t*)self; + htsmsg_t* m = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(&ec->idnode, m); if (filename) - snprintf(filename, fsize, "epggrab/%s/channels/%s", - ec->mod->saveid, idnode_uuid_as_str(&ec->idnode, ubuf)); + snprintf(filename, + fsize, + "epggrab/%s/channels/%s", + ec->mod->saveid, + idnode_uuid_as_str(&ec->idnode, ubuf)); return m; } -static void -epggrab_channel_class_delete(idnode_t *self) -{ - epggrab_channel_destroy((epggrab_channel_t *)self, 1, 1); +static void epggrab_channel_class_delete(idnode_t* self) { + epggrab_channel_destroy((epggrab_channel_t*)self, 1, 1); } -static const void * -epggrab_channel_class_modid_get ( void *obj ) -{ - epggrab_channel_t *ec = obj; +static const void* epggrab_channel_class_modid_get(void* obj) { + epggrab_channel_t* ec = obj; snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", ec->mod->id ?: ""); return &prop_sbuf_ptr; } -static int -epggrab_channel_class_modid_set ( void *obj, const void *p ) -{ +static int epggrab_channel_class_modid_set(void* obj, const void* p) { return 0; } -static const void * -epggrab_channel_class_module_get ( void *obj ) -{ - epggrab_channel_t *ec = obj; +static const void* epggrab_channel_class_module_get(void* obj) { + epggrab_channel_t* ec = obj; snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", ec->mod->name ?: ""); return &prop_sbuf_ptr; } -static const void * -epggrab_channel_class_path_get ( void *obj ) -{ - epggrab_channel_t *ec = obj; +static const void* epggrab_channel_class_path_get(void* obj) { + epggrab_channel_t* ec = obj; if (ec->mod->type == EPGGRAB_INT || ec->mod->type == EPGGRAB_EXT) - snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", ((epggrab_module_int_t *)ec->mod)->path ?: ""); + snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", ((epggrab_module_int_t*)ec->mod)->path ?: ""); else prop_sbuf[0] = '\0'; return &prop_sbuf_ptr; } -static const void * -epggrab_channel_class_names_get ( void *obj ) -{ - epggrab_channel_t *ec = obj; - char *s = ec->names ? htsmsg_list_2_csv(ec->names, ',', 0) : NULL; +static const void* epggrab_channel_class_names_get(void* obj) { + epggrab_channel_t* ec = obj; + char* s = ec->names ? htsmsg_list_2_csv(ec->names, ',', 0) : NULL; snprintf(prop_sbuf, PROP_SBUF_LEN, "%s", s ?: ""); free(s); return &prop_sbuf_ptr; } -static int -epggrab_channel_class_names_set ( void *obj, const void *p ) -{ - htsmsg_t *m = htsmsg_csv_2_list(p, ','); - epggrab_channel_t *ec = obj; +static int epggrab_channel_class_names_set(void* obj, const void* p) { + htsmsg_t* m = htsmsg_csv_2_list(p, ','); + epggrab_channel_t* ec = obj; if (htsmsg_cmp(ec->names, m)) { htsmsg_destroy(ec->names); ec->names = m; @@ -624,10 +576,8 @@ epggrab_channel_class_names_set ( void *obj, const void *p ) return 0; } -static void -epggrab_channel_class_enabled_notify ( void *obj, const char *lang ) -{ - epggrab_channel_t *ec = obj; +static void epggrab_channel_class_enabled_notify(void* obj, const char* lang) { + epggrab_channel_t* ec = obj; if (!ec->enabled) { epggrab_channel_links_delete(ec, 1); } else { @@ -635,97 +585,80 @@ epggrab_channel_class_enabled_notify ( void *obj, const char *lang ) } } -static const void * -epggrab_channel_class_channels_get ( void *obj ) -{ - epggrab_channel_t *ec = obj; +static const void* epggrab_channel_class_channels_get(void* obj) { + epggrab_channel_t* ec = obj; return idnode_list_get1(&ec->channels); } -static int -epggrab_channel_class_channels_set ( void *obj, const void *p ) -{ - epggrab_channel_t *ec = obj; - return idnode_list_set1(&ec->idnode, &ec->channels, - &channel_class, (htsmsg_t *)p, - epggrab_channel_map); +static int epggrab_channel_class_channels_set(void* obj, const void* p) { + epggrab_channel_t* ec = obj; + return idnode_list_set1(&ec->idnode, + &ec->channels, + &channel_class, + (htsmsg_t*)p, + epggrab_channel_map); } -static char * -epggrab_channel_class_channels_rend ( void *obj, const char *lang ) -{ - epggrab_channel_t *ec = obj; +static char* epggrab_channel_class_channels_rend(void* obj, const char* lang) { + epggrab_channel_t* ec = obj; return idnode_list_get_csv1(&ec->channels, lang); } static idnode_slist_t epggrab_channel_class_update_slist[] = { - { - .id = "update_icon", - .name = N_("Icon"), - .off = offsetof(epggrab_channel_t, update_chicon), - }, - { - .id = "update_chnum", - .name = N_("Number"), - .off = offsetof(epggrab_channel_t, update_chnum), - }, - { - .id = "update_chname", - .name = N_("Name"), - .off = offsetof(epggrab_channel_t, update_chname), - }, - {} -}; - -static htsmsg_t * -epggrab_channel_class_update_enum ( void *obj, const char *lang ) -{ + { + .id = "update_icon", + .name = N_("Icon"), + .off = offsetof(epggrab_channel_t, update_chicon), + }, + { + .id = "update_chnum", + .name = N_("Number"), + .off = offsetof(epggrab_channel_t, update_chnum), + }, + { + .id = "update_chname", + .name = N_("Name"), + .off = offsetof(epggrab_channel_t, update_chname), + }, + {}}; + +static htsmsg_t* epggrab_channel_class_update_enum(void* obj, const char* lang) { return idnode_slist_enum(obj, epggrab_channel_class_update_slist, lang); } -static const void * -epggrab_channel_class_update_get ( void *obj ) -{ +static const void* epggrab_channel_class_update_get(void* obj) { return idnode_slist_get(obj, epggrab_channel_class_update_slist); } -static char * -epggrab_channel_class_update_rend ( void *obj, const char *lang ) -{ +static char* epggrab_channel_class_update_rend(void* obj, const char* lang) { return idnode_slist_rend(obj, epggrab_channel_class_update_slist, lang); } -static int -epggrab_channel_class_update_set ( void *obj, const void *p ) -{ +static int epggrab_channel_class_update_set(void* obj, const void* p) { return idnode_slist_set(obj, epggrab_channel_class_update_slist, p); } -static void -epggrab_channel_class_update_notify ( void *obj, const char *lang ) -{ - epggrab_channel_t *ec = obj; - channel_t *ch; - idnode_list_mapping_t *ilm; +static void epggrab_channel_class_update_notify(void* obj, const char* lang) { + epggrab_channel_t* ec = obj; + channel_t* ch; + idnode_list_mapping_t* ilm; if (!ec->update_chicon && !ec->update_chnum && !ec->update_chname) return; - LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) { - ch = (channel_t *)ilm->ilm_in2; + LIST_FOREACH (ilm, &ec->channels, ilm_in1_link) { + ch = (channel_t*)ilm->ilm_in2; epggrab_channel_sync(ec, ch); } } -static void -epggrab_channel_class_only_one_notify ( void *obj, const char *lang ) -{ - epggrab_channel_t *ec = obj; - channel_t *ch, *first = NULL; +static void epggrab_channel_class_only_one_notify(void* obj, const char* lang) { + epggrab_channel_t* ec = obj; + channel_t * ch, *first = NULL; idnode_list_mapping_t *ilm1, *ilm2; if (ec->only_one) { - for(ilm1 = LIST_FIRST(&ec->channels); ilm1; ilm1 = ilm2) { + for (ilm1 = LIST_FIRST(&ec->channels); ilm1; ilm1 = ilm2) { ilm2 = LIST_NEXT(ilm1, ilm_in1_link); - ch = (channel_t *)ilm1->ilm_in2; + ch = (channel_t*)ilm1->ilm_in2; if (!first) first = ch; else if (ch->ch_epgauto && first) @@ -738,172 +671,134 @@ epggrab_channel_class_only_one_notify ( void *obj, const char *lang ) CLASS_DOC(epggrabber_channel) -const idclass_t epggrab_channel_class = { - .ic_class = "epggrab_channel", - .ic_caption = N_("Channels / EPG - EPG Grabber Channels"), - .ic_doc = tvh_doc_epggrabber_channel_class, - .ic_event = "epggrab_channel", - .ic_perm_def = ACCESS_ADMIN, - .ic_save = epggrab_channel_class_save, - .ic_get_title = epggrab_channel_class_get_title, - .ic_delete = epggrab_channel_class_delete, - .ic_groups = (const property_group_t[]) { - { - .name = N_("Configuration"), - .number = 1, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable EPG data for the entry."), - .off = offsetof(epggrab_channel_t, enabled), - .notify = epggrab_channel_class_enabled_notify, - .group = 1 - }, - { - .type = PT_STR, - .id = "modid", - .name = N_("Module ID"), - .desc = N_("Module ID used to grab EPG data."), - .get = epggrab_channel_class_modid_get, - .set = epggrab_channel_class_modid_set, - .opts = PO_RDONLY | PO_HIDDEN, - .group = 1 - }, - { - .type = PT_STR, - .id = "module", - .name = N_("Module"), - .desc = N_("Name of the module used to grab EPG data."), - .get = epggrab_channel_class_module_get, - .opts = PO_RDONLY | PO_NOSAVE, - .group = 1 - }, - { - .type = PT_STR, - .id = "path", - .name = N_("Path"), - .desc = N_("Data path (if applicable)."), - .get = epggrab_channel_class_path_get, - .opts = PO_RDONLY | PO_NOSAVE, - .group = 1 - }, - { - .type = PT_TIME, - .id = "updated", - .name = N_("Updated"), - .desc = N_("Date the EPG data was last updated (not set for OTA " - "grabbers)."), - .off = offsetof(epggrab_channel_t, laststamp), - .opts = PO_RDONLY | PO_NOSAVE, - .group = 1 - }, - { - .type = PT_STR, - .id = "id", - .name = N_("ID"), - .desc = N_("EPG data ID."), - .off = offsetof(epggrab_channel_t, id), - .group = 1 - }, - { - .type = PT_STR, - .id = "name", - .name = N_("Name"), - .desc = N_("Service name found in EPG data."), - .off = offsetof(epggrab_channel_t, name), - .group = 1 - }, - { - .type = PT_STR, - .id = "names", - .name = N_("Names"), - .desc = N_("Additional service names found in EPG data."), - .get = epggrab_channel_class_names_get, - .set = epggrab_channel_class_names_set, - .group = 1 - }, - { - .type = PT_S64, - .intextra = CHANNEL_SPLIT, - .id = "number", - .name = N_("Number"), - .desc = N_("Channel number as defined in EPG data."), - .off = offsetof(epggrab_channel_t, lcn), - .group = 1 - }, - { - .type = PT_STR, - .id = "icon", - .name = N_("Icon"), - .desc = N_("Channel icon as defined in EPG data."), - .off = offsetof(epggrab_channel_t, icon), - .group = 1 - }, - { - .type = PT_STR, - .islist = 1, - .id = "channels", - .name = N_("Channels"), - .desc = N_("Channels EPG data is used by."), - .set = epggrab_channel_class_channels_set, - .get = epggrab_channel_class_channels_get, - .list = channel_class_get_list, - .rend = epggrab_channel_class_channels_rend, - .group = 1 - }, - { - .type = PT_BOOL, - .id = "only_one", - .name = N_("Once per auto channel"), - .desc = N_("Only use this EPG data once when automatically " - "determining what EPG data to set for a channel."), - .off = offsetof(epggrab_channel_t, only_one), - .notify = epggrab_channel_class_only_one_notify, - .group = 1 - }, - { - .type = PT_INT, - .islist = 1, - .id = "update", - .name = N_("Channel update options"), - .desc = N_("Options used when updating channels."), - .notify = epggrab_channel_class_update_notify, - .list = epggrab_channel_class_update_enum, - .get = epggrab_channel_class_update_get, - .set = epggrab_channel_class_update_set, - .rend = epggrab_channel_class_update_rend, - .opts = PO_ADVANCED - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-form text field, enter whatever you like."), - .off = offsetof(epggrab_channel_t, comment), - .group = 1 - }, - {} - } -}; +const idclass_t epggrab_channel_class = {.ic_class = "epggrab_channel", + .ic_caption = N_("Channels / EPG - EPG Grabber Channels"), + .ic_doc = tvh_doc_epggrabber_channel_class, + .ic_event = "epggrab_channel", + .ic_perm_def = ACCESS_ADMIN, + .ic_save = epggrab_channel_class_save, + .ic_get_title = epggrab_channel_class_get_title, + .ic_delete = epggrab_channel_class_delete, + .ic_groups = (const property_group_t[]){{ + .name = N_("Configuration"), + .number = 1, + }, + {}}, + .ic_properties = (const property_t[]){{.type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable EPG data for the entry."), + .off = offsetof(epggrab_channel_t, enabled), + .notify = epggrab_channel_class_enabled_notify, + .group = 1}, + {.type = PT_STR, + .id = "modid", + .name = N_("Module ID"), + .desc = N_("Module ID used to grab EPG data."), + .get = epggrab_channel_class_modid_get, + .set = epggrab_channel_class_modid_set, + .opts = PO_RDONLY | PO_HIDDEN, + .group = 1}, + {.type = PT_STR, + .id = "module", + .name = N_("Module"), + .desc = N_("Name of the module used to grab EPG data."), + .get = epggrab_channel_class_module_get, + .opts = PO_RDONLY | PO_NOSAVE, + .group = 1}, + {.type = PT_STR, + .id = "path", + .name = N_("Path"), + .desc = N_("Data path (if applicable)."), + .get = epggrab_channel_class_path_get, + .opts = PO_RDONLY | PO_NOSAVE, + .group = 1}, + {.type = PT_TIME, + .id = "updated", + .name = N_("Updated"), + .desc = N_("Date the EPG data was last updated (not set for OTA " + "grabbers)."), + .off = offsetof(epggrab_channel_t, laststamp), + .opts = PO_RDONLY | PO_NOSAVE, + .group = 1}, + {.type = PT_STR, + .id = "id", + .name = N_("ID"), + .desc = N_("EPG data ID."), + .off = offsetof(epggrab_channel_t, id), + .group = 1}, + {.type = PT_STR, + .id = "name", + .name = N_("Name"), + .desc = N_("Service name found in EPG data."), + .off = offsetof(epggrab_channel_t, name), + .group = 1}, + {.type = PT_STR, + .id = "names", + .name = N_("Names"), + .desc = N_("Additional service names found in EPG data."), + .get = epggrab_channel_class_names_get, + .set = epggrab_channel_class_names_set, + .group = 1}, + {.type = PT_S64, + .intextra = CHANNEL_SPLIT, + .id = "number", + .name = N_("Number"), + .desc = N_("Channel number as defined in EPG data."), + .off = offsetof(epggrab_channel_t, lcn), + .group = 1}, + {.type = PT_STR, + .id = "icon", + .name = N_("Icon"), + .desc = N_("Channel icon as defined in EPG data."), + .off = offsetof(epggrab_channel_t, icon), + .group = 1}, + {.type = PT_STR, + .islist = 1, + .id = "channels", + .name = N_("Channels"), + .desc = N_("Channels EPG data is used by."), + .set = epggrab_channel_class_channels_set, + .get = epggrab_channel_class_channels_get, + .list = channel_class_get_list, + .rend = epggrab_channel_class_channels_rend, + .group = 1}, + {.type = PT_BOOL, + .id = "only_one", + .name = N_("Once per auto channel"), + .desc = N_("Only use this EPG data once when automatically " + "determining what EPG data to set for a channel."), + .off = offsetof(epggrab_channel_t, only_one), + .notify = epggrab_channel_class_only_one_notify, + .group = 1}, + {.type = PT_INT, + .islist = 1, + .id = "update", + .name = N_("Channel update options"), + .desc = N_("Options used when updating channels."), + .notify = epggrab_channel_class_update_notify, + .list = epggrab_channel_class_update_enum, + .get = epggrab_channel_class_update_get, + .set = epggrab_channel_class_update_set, + .rend = epggrab_channel_class_update_rend, + .opts = PO_ADVANCED}, + {.type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-form text field, enter whatever you like."), + .off = offsetof(epggrab_channel_t, comment), + .group = 1}, + {}}}; /* * */ -void -epggrab_channel_init( void ) -{ +void epggrab_channel_init(void) { TAILQ_INIT(&epggrab_channel_entries); idclass_register(&epggrab_channel_class); } -void -epggrab_channel_done( void ) -{ +void epggrab_channel_done(void) { assert(TAILQ_FIRST(&epggrab_channel_entries) == NULL); SKEL_FREE(epggrab_channel_skel); } diff --git a/src/epggrab/module.c b/src/epggrab/module.c index e47c29c34..0b80b1d76 100644 --- a/src/epggrab/module.c +++ b/src/epggrab/module.c @@ -38,29 +38,28 @@ extern gtimer_t epggrab_save_timer; * Module Access * *************************************************************************/ -epggrab_module_t* epggrab_module_find_by_id ( const char *id ) -{ - epggrab_module_t *m; - LIST_FOREACH(m, &epggrab_modules, link) +epggrab_module_t* epggrab_module_find_by_id(const char* id) { + epggrab_module_t* m; + LIST_FOREACH (m, &epggrab_modules, link) if (!strcmp(m->id, id)) return m; return NULL; } -const char * -epggrab_module_type(epggrab_module_t *mod) -{ +const char* epggrab_module_type(epggrab_module_t* mod) { switch (mod->type) { - case EPGGRAB_OTA: return N_("Over-the-air"); - case EPGGRAB_INT: return N_("Internal"); - case EPGGRAB_EXT: return N_("External"); - default: return N_("Unknown"); + case EPGGRAB_OTA: + return N_("Over-the-air"); + case EPGGRAB_INT: + return N_("Internal"); + case EPGGRAB_EXT: + return N_("External"); + default: + return N_("Unknown"); } } -const char * -epggrab_module_get_status(epggrab_module_t *mod) -{ +const char* epggrab_module_get_status(epggrab_module_t* mod) { if (mod->enabled) return "epggrabmodEnabled"; return "epggrabmodNone"; @@ -70,50 +69,42 @@ epggrab_module_get_status(epggrab_module_t *mod) * Class */ -static void epggrab_mod_class_title - (idnode_t *self, const char *lang, char *dst, size_t dstsize) -{ - epggrab_module_t *mod = (epggrab_module_t *)self; - const char *s1 = tvh_gettext_lang(lang, epggrab_module_type(mod)); - const char *s2 = tvh_str_default(mod->name, mod->id); +static void epggrab_mod_class_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + epggrab_module_t* mod = (epggrab_module_t*)self; + const char* s1 = tvh_gettext_lang(lang, epggrab_module_type(mod)); + const char* s2 = tvh_str_default(mod->name, mod->id); snprintf(dst, dstsize, "%s: %s", s1, s2); } -static void -epggrab_mod_class_changed(idnode_t *self) -{ - epggrab_module_t *mod = (epggrab_module_t *)self; +static void epggrab_mod_class_changed(idnode_t* self) { + epggrab_module_t* mod = (epggrab_module_t*)self; epggrab_activate_module(mod, mod->enabled); idnode_changed(&epggrab_conf.idnode); } -static const void *epggrab_mod_class_type_get(void *o) -{ - static const char *s; - s = epggrab_module_type((epggrab_module_t *)o); +static const void* epggrab_mod_class_type_get(void* o) { + static const char* s; + s = epggrab_module_type((epggrab_module_t*)o); return &s; } -static int epggrab_mod_class_type_set(void *o, const void *v) -{ +static int epggrab_mod_class_type_set(void* o, const void* v) { return 0; } -static htsmsg_t * -epggrab_module_ota_scrapper_config_list ( void *o, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_list(); - htsmsg_t *e = htsmsg_create_map(); +static htsmsg_t* epggrab_module_ota_scrapper_config_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_list(); + htsmsg_t* e = htsmsg_create_map(); htsmsg_add_str(e, "key", ""); htsmsg_add_str(e, "val", tvh_gettext_lang(lang, N_("Use default configuration"))); htsmsg_add_msg(m, NULL, e); - htsmsg_t *config; + htsmsg_t* config; /* We load all the config so we can get the names of ones that are * valid. This is a bit of overhead but we are rarely called since * this is for the configuration GUI drop-down. */ - if((config = hts_settings_load_r(1, "epggrab/eit/scrape")) != NULL) { - htsmsg_field_t *f; + if ((config = hts_settings_load_r(1, "epggrab/eit/scrape")) != NULL) { + htsmsg_field_t* f; HTSMSG_FOREACH(f, config) { e = htsmsg_create_map(); htsmsg_add_str(e, "key", htsmsg_field_name(f)); @@ -125,229 +116,195 @@ epggrab_module_ota_scrapper_config_list ( void *o, const char *lang ) return m; } - - CLASS_DOC(epggrabber_modules) PROP_DOC(epggrabber_priority) -const idclass_t epggrab_mod_class = { - .ic_class = "epggrab_mod", - .ic_caption = N_("Channels / EPG - EPG Grabber Modules"), - .ic_doc = tvh_doc_epggrabber_modules_class, - .ic_event = "epggrab_mod", - .ic_perm_def = ACCESS_ADMIN, - .ic_get_title = epggrab_mod_class_title, - .ic_changed = epggrab_mod_class_changed, - .ic_groups = (const property_group_t[]) { - { - .name = N_("Grabber Settings"), - .number = 1, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "name", - .name = N_("Name"), - .desc = N_("The EPG grabber name."), - .off = offsetof(epggrab_module_t, name), - .opts = PO_RDONLY, - .group = 1, - }, - { - .type = PT_STR, - .id = "type", - .name = N_("Type"), - .desc = N_("The EPG grabber type."), - .get = epggrab_mod_class_type_get, - .set = epggrab_mod_class_type_set, - .opts = PO_RDONLY | PO_LOCALE, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable the grabber."), - .off = offsetof(epggrab_module_t, enabled), - .group = 1, - }, - { - .type = PT_INT, - .id = "priority", - .name = N_("Priority"), - .desc = N_("Grabber priority. This option lets you pick which " - "EPG grabber's data get used first. Priority is " - "given to the grabber with the highest value set here. " - "See Help for more info."), - .doc = prop_doc_epggrabber_priority, - .off = offsetof(epggrab_module_t, priority), - .opts = PO_EXPERT, - .group = 1 - }, - {} - } -}; - -const idclass_t epggrab_mod_int_class = { - .ic_super = &epggrab_mod_class, - .ic_class = "epggrab_mod_int", - .ic_caption = N_("Internal EPG grabber"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "path", - .name = N_("Path"), - .desc = N_("Path to the grabber executable."), - .off = offsetof(epggrab_module_int_t, path), - .opts = PO_RDONLY | PO_NOSAVE, - .group = 1 - }, - { - .type = PT_STR, - .id = "args", - .name = N_("Extra arguments"), - .desc = N_("Additional arguments to pass to the grabber."), - .off = offsetof(epggrab_module_int_t, args), - .opts = PO_ADVANCED, - .group = 1 - }, - {} - } -}; - -const idclass_t epggrab_mod_ext_class = { - .ic_super = &epggrab_mod_class, - .ic_class = "epggrab_mod_ext", - .ic_caption = N_("External EPG grabber"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "path", - .name = N_("Path"), - .desc = N_("Path to the socket Tvheadend will read data from."), - .off = offsetof(epggrab_module_ext_t, path), - .opts = PO_RDONLY | PO_NOSAVE, - .group = 1 - }, - {} - } -}; - -const idclass_t epggrab_mod_ota_class = { - .ic_super = &epggrab_mod_class, - .ic_class = "epggrab_mod_ota", - .ic_caption = N_("EPG - Over-the-air EPG Grabber"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t epggrab_mod_ota_scraper_class = { - .ic_super = &epggrab_mod_ota_class, - .ic_class = "epggrab_mod_ota_scraper", - .ic_caption = N_("Over-the-air EPG grabber with scraping"), - .ic_groups = (const property_group_t[]) { - { - .name = N_("EPG behaviour"), - .number = 1, - }, - { - .name = N_("Scrape behaviour"), - .number = 2, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - /* The "eit" grabber is used by a number of countries so - * we can't ship a config file named "eit" since regex use - * in the UK won't be the same as in Italy. - * - * So, this option allows the user to specify the configuration - * file to use from the ones that we do ship without them having - * to mess around in the filesystem copying files. - * - * For example they can simply specify "uk" to use its - * configuration file. - */ - .type = PT_STR, - .id = "scrape_config", - .name = N_("Scraper configuration to use"), - .desc = N_("Configuration containing regular expressions to use for " - "scraping additional information from the broadcast guide." - "This option does not access or retrieve details from the " - "Internet." - "This can be left blank to use the default or " - "set to one of the Tvheadend configurations from the " - "epggrab/eit/scrape directory such as " - "\"uk\" (without the quotes)." - ), - .off = offsetof(epggrab_module_ota_scraper_t, scrape_config), - .list = epggrab_module_ota_scrapper_config_list, - .group = 2, - }, - { - .type = PT_BOOL, - .id = "scrape_episode", - .name = N_("Scrape Episode"), - .desc = N_("Enable/disable scraping episode details using the grabber."), - .off = offsetof(epggrab_module_ota_scraper_t, scrape_episode), - .group = 2, - }, - { - .type = PT_BOOL, - .id = "scrape_title", - .name = N_("Scrape Title"), - .desc = N_("Enable/disable scraping title from the programme title and description. " - "Some broadcasters can split the title over the separate title, " - "and summary fields. This allows scraping of common split title formats " - "from within the broadcast title and summary field if supported by the " - "configuration file." - ), - .off = offsetof(epggrab_module_ota_scraper_t, scrape_title), - .group = 2, - }, - { - .type = PT_BOOL, - .id = "scrape_subtitle", - .name = N_("Scrape Subtitle"), - .desc = N_("Enable/disable scraping subtitle from the programme description. " - "Some broadcasters do not send separate title, subtitle, description, " - "and summary fields. This allows scraping of common subtitle formats " - "from within the broadcast summary field if supported by the " - "configuration file." - ), - .off = offsetof(epggrab_module_ota_scraper_t, scrape_subtitle), - .group = 2, - }, - { - .type = PT_BOOL, - .id = "scrape_summary", - .name = N_("Scrape Summary"), - .desc = N_("Enable/disable scraping summary from the programme description. " - "Some broadcasters do not send separate title, subtitle, description, " - "and summary fields. This allows scraping of a modified summary " - "from within the broadcast summary field if supported by the " - "configuration file." - ), - .off = offsetof(epggrab_module_ota_scraper_t, scrape_summary), - .group = 2, - }, - {} - } -}; +const idclass_t epggrab_mod_class = {.ic_class = "epggrab_mod", + .ic_caption = N_("Channels / EPG - EPG Grabber Modules"), + .ic_doc = tvh_doc_epggrabber_modules_class, + .ic_event = "epggrab_mod", + .ic_perm_def = ACCESS_ADMIN, + .ic_get_title = epggrab_mod_class_title, + .ic_changed = epggrab_mod_class_changed, + .ic_groups = (const property_group_t[]){{ + .name = N_("Grabber Settings"), + .number = 1, + }, + {}}, + .ic_properties = (const property_t[]){{ + .type = PT_STR, + .id = "name", + .name = N_("Name"), + .desc = N_("The EPG grabber name."), + .off = offsetof(epggrab_module_t, name), + .opts = PO_RDONLY, + .group = 1, + }, + { + .type = PT_STR, + .id = "type", + .name = N_("Type"), + .desc = N_("The EPG grabber type."), + .get = epggrab_mod_class_type_get, + .set = epggrab_mod_class_type_set, + .opts = PO_RDONLY | PO_LOCALE, + .group = 1, + }, + { + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable the grabber."), + .off = offsetof(epggrab_module_t, enabled), + .group = 1, + }, + {.type = PT_INT, + .id = "priority", + .name = N_("Priority"), + .desc = N_("Grabber priority. This option lets you pick which " + "EPG grabber's data get used first. Priority is " + "given to the grabber with the highest value set here. " + "See Help for more info."), + .doc = prop_doc_epggrabber_priority, + .off = offsetof(epggrab_module_t, priority), + .opts = PO_EXPERT, + .group = 1}, + {}}}; + +const idclass_t epggrab_mod_int_class = {.ic_super = &epggrab_mod_class, + .ic_class = "epggrab_mod_int", + .ic_caption = N_("Internal EPG grabber"), + .ic_properties = (const property_t[]){{.type = PT_STR, + .id = "path", + .name = N_("Path"), + .desc = N_("Path to the grabber executable."), + .off = offsetof(epggrab_module_int_t, path), + .opts = PO_RDONLY | PO_NOSAVE, + .group = 1}, + {.type = PT_STR, + .id = "args", + .name = N_("Extra arguments"), + .desc = N_("Additional arguments to pass to the grabber."), + .off = offsetof(epggrab_module_int_t, args), + .opts = PO_ADVANCED, + .group = 1}, + {}}}; + +const idclass_t epggrab_mod_ext_class = {.ic_super = &epggrab_mod_class, + .ic_class = "epggrab_mod_ext", + .ic_caption = N_("External EPG grabber"), + .ic_properties = + (const property_t[]){{.type = PT_STR, + .id = "path", + .name = N_("Path"), + .desc = N_("Path to the socket Tvheadend will read data from."), + .off = offsetof(epggrab_module_ext_t, path), + .opts = PO_RDONLY | PO_NOSAVE, + .group = 1}, + {}}}; + +const idclass_t epggrab_mod_ota_class = {.ic_super = &epggrab_mod_class, + .ic_class = "epggrab_mod_ota", + .ic_caption = N_("EPG - Over-the-air EPG Grabber"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t epggrab_mod_ota_scraper_class = {.ic_super = &epggrab_mod_ota_class, + .ic_class = "epggrab_mod_ota_scraper", + .ic_caption = N_("Over-the-air EPG grabber with scraping"), + .ic_groups = (const property_group_t[]){{ + .name = N_("EPG behaviour"), + .number = 1, + }, + { + .name = N_("Scrape behaviour"), + .number = 2, + }, + {}}, + .ic_properties = (const property_t[]){ + { + /* The "eit" grabber is used by a number of countries so + * we can't ship a config file named "eit" since regex use + * in the UK won't be the same as in Italy. + * + * So, this option allows the user to specify the configuration + * file to use from the ones that we do ship without them having + * to mess around in the filesystem copying files. + * + * For example they can simply specify "uk" to use its + * configuration file. + */ + .type = PT_STR, + .id = "scrape_config", + .name = N_("Scraper configuration to use"), + .desc = N_("Configuration containing regular expressions to use for " + "scraping additional information from the broadcast guide." + "This option does not access or retrieve details from the " + "Internet." + "This can be left blank to use the default or " + "set to one of the Tvheadend configurations from the " + "epggrab/eit/scrape directory such as " + "\"uk\" (without the quotes)."), + .off = offsetof(epggrab_module_ota_scraper_t, scrape_config), + .list = epggrab_module_ota_scrapper_config_list, + .group = 2, + }, + { + .type = PT_BOOL, + .id = "scrape_episode", + .name = N_("Scrape Episode"), + .desc = N_("Enable/disable scraping episode details using the grabber."), + .off = offsetof(epggrab_module_ota_scraper_t, scrape_episode), + .group = 2, + }, + { + .type = PT_BOOL, + .id = "scrape_title", + .name = N_("Scrape Title"), + .desc = N_("Enable/disable scraping title from the programme title and description. " + "Some broadcasters can split the title over the separate title, " + "and summary fields. This allows scraping of common split title formats " + "from within the broadcast title and summary field if supported by the " + "configuration file."), + .off = offsetof(epggrab_module_ota_scraper_t, scrape_title), + .group = 2, + }, + { + .type = PT_BOOL, + .id = "scrape_subtitle", + .name = N_("Scrape Subtitle"), + .desc = N_("Enable/disable scraping subtitle from the programme description. " + "Some broadcasters do not send separate title, subtitle, description, " + "and summary fields. This allows scraping of common subtitle formats " + "from within the broadcast summary field if supported by the " + "configuration file."), + .off = offsetof(epggrab_module_ota_scraper_t, scrape_subtitle), + .group = 2, + }, + { + .type = PT_BOOL, + .id = "scrape_summary", + .name = N_("Scrape Summary"), + .desc = N_("Enable/disable scraping summary from the programme description. " + "Some broadcasters do not send separate title, subtitle, description, " + "and summary fields. This allows scraping of a modified summary " + "from within the broadcast summary field if supported by the " + "configuration file."), + .off = offsetof(epggrab_module_ota_scraper_t, scrape_summary), + .group = 2, + }, + {}}}; /* ************************************************************************** * Generic module routines * *************************************************************************/ -epggrab_module_t *epggrab_module_create - ( epggrab_module_t *skel, const idclass_t *cls, - const char *id, int subsys, const char *saveid, - const char *name, int priority ) -{ +epggrab_module_t* epggrab_module_create(epggrab_module_t* skel, + const idclass_t* cls, + const char* id, + int subsys, + const char* saveid, + const char* name, + int priority) { assert(skel); /* Setup */ @@ -372,12 +329,11 @@ epggrab_module_t *epggrab_module_create /* * Run the parse */ -void epggrab_module_parse( void *m, htsmsg_t *data ) -{ - int64_t tm1, tm2; - int save = 0; - epggrab_stats_t stats; - epggrab_module_int_t *mod = m; +void epggrab_module_parse(void* m, htsmsg_t* data) { + int64_t tm1, tm2; + int save = 0; + epggrab_stats_t stats; + epggrab_module_int_t* mod = m; /* Parse */ memset(&stats, 0, sizeof(stats)); @@ -387,22 +343,37 @@ void epggrab_module_parse( void *m, htsmsg_t *data ) htsmsg_destroy(data); /* Debug stats */ - tvhinfo(mod->subsys, "%s: parse took %"PRId64" seconds", mod->id, mono2sec(tm2 - tm1)); - tvhinfo(mod->subsys, "%s: channels tot=%5d new=%5d mod=%5d", - mod->id, stats.channels.total, stats.channels.created, - stats.channels.modified); - tvhinfo(mod->subsys, "%s: brands tot=%5d new=%5d mod=%5d", - mod->id, stats.brands.total, stats.brands.created, - stats.brands.modified); - tvhinfo(mod->subsys, "%s: seasons tot=%5d new=%5d mod=%5d", - mod->id, stats.seasons.total, stats.seasons.created, - stats.seasons.modified); - tvhinfo(mod->subsys, "%s: episodes tot=%5d new=%5d mod=%5d", - mod->id, stats.episodes.total, stats.episodes.created, - stats.episodes.modified); - tvhinfo(mod->subsys, "%s: broadcasts tot=%5d new=%5d mod=%5d", - mod->id, stats.broadcasts.total, stats.broadcasts.created, - stats.broadcasts.modified); + tvhinfo(mod->subsys, "%s: parse took %" PRId64 " seconds", mod->id, mono2sec(tm2 - tm1)); + tvhinfo(mod->subsys, + "%s: channels tot=%5d new=%5d mod=%5d", + mod->id, + stats.channels.total, + stats.channels.created, + stats.channels.modified); + tvhinfo(mod->subsys, + "%s: brands tot=%5d new=%5d mod=%5d", + mod->id, + stats.brands.total, + stats.brands.created, + stats.brands.modified); + tvhinfo(mod->subsys, + "%s: seasons tot=%5d new=%5d mod=%5d", + mod->id, + stats.seasons.total, + stats.seasons.created, + stats.seasons.modified); + tvhinfo(mod->subsys, + "%s: episodes tot=%5d new=%5d mod=%5d", + mod->id, + stats.episodes.total, + stats.episodes.created, + stats.episodes.modified); + tvhinfo(mod->subsys, + "%s: broadcasts tot=%5d new=%5d mod=%5d", + mod->id, + stats.broadcasts.total, + stats.broadcasts.created, + stats.broadcasts.modified); /* Now we've parsed, do we need to save? */ if (save && epggrab_conf.epgdb_saveafterimport) { @@ -418,8 +389,7 @@ void epggrab_module_parse( void *m, htsmsg_t *data ) * If periodic saving is enabled then the callback will then * rearm the timer for x hours after the previous save. */ - gtimer_arm_rel(&epggrab_save_timer, epg_save_callback, NULL, - 60 * 2); + gtimer_arm_rel(&epggrab_save_timer, epg_save_callback, NULL, 60 * 2); tvh_mutex_unlock(&global_lock); } } @@ -428,13 +398,13 @@ void epggrab_module_parse( void *m, htsmsg_t *data ) * Module channel routines * *************************************************************************/ -void epggrab_module_channels_load ( const char *modid ) -{ - epggrab_module_t *mod = NULL; - htsmsg_t *m, *e; - htsmsg_field_t *f; - const char *id; - if (!modid) return; +void epggrab_module_channels_load(const char* modid) { + epggrab_module_t* mod = NULL; + htsmsg_t * m, *e; + htsmsg_field_t* f; + const char* id; + if (!modid) + return; if ((m = hts_settings_load_r(1, "epggrab/%s/channels", modid))) { HTSMSG_FOREACH(f, m) { if ((e = htsmsg_get_map_by_field(f))) { @@ -453,53 +423,57 @@ void epggrab_module_channels_load ( const char *modid ) * Internal module routines * *************************************************************************/ -static void -epggrab_module_int_done( void *m ) -{ - epggrab_module_int_t *mod = m; - mod->active = 0; - free((char *)mod->path); +static void epggrab_module_int_done(void* m) { + epggrab_module_int_t* mod = m; + mod->active = 0; + free((char*)mod->path); mod->path = NULL; - free((char *)mod->args); + free((char*)mod->args); mod->args = NULL; } -epggrab_module_int_t *epggrab_module_int_create - ( epggrab_module_int_t *skel, const idclass_t *cls, - const char *id, int subsys, const char *saveid, - const char *name, int priority, - const char *path, - char* (*grab) (void*m), - int (*parse) (void *m, htsmsg_t *data, epggrab_stats_t *sta), - htsmsg_t* (*trans) (void *mod, char *data) ) -{ +epggrab_module_int_t* epggrab_module_int_create(epggrab_module_int_t* skel, + const idclass_t* cls, + const char* id, + int subsys, + const char* saveid, + const char* name, + int priority, + const char* path, + char* (*grab)(void* m), + int (*parse)(void* m, htsmsg_t* data, epggrab_stats_t* sta), + htsmsg_t* (*trans)(void* mod, char* data)) { /* Allocate data */ - if (!skel) skel = calloc(1, sizeof(epggrab_module_int_t)); + if (!skel) + skel = calloc(1, sizeof(epggrab_module_int_t)); /* Pass through */ epggrab_module_create((epggrab_module_t*)skel, - cls ?: &epggrab_mod_int_class, - id, subsys, saveid, name, priority); + cls ?: &epggrab_mod_int_class, + id, + subsys, + saveid, + name, + priority); /* Int data */ - skel->type = EPGGRAB_INT; - skel->path = strdup(path); - skel->args = NULL; - skel->grab = grab ?: epggrab_module_grab_spawn; - skel->trans = trans ?: epggrab_module_trans_xml; - skel->parse = parse; - skel->done = epggrab_module_int_done; + skel->type = EPGGRAB_INT; + skel->path = strdup(path); + skel->args = NULL; + skel->grab = grab ?: epggrab_module_grab_spawn; + skel->trans = trans ?: epggrab_module_trans_xml; + skel->parse = parse; + skel->done = epggrab_module_int_done; return skel; } -char *epggrab_module_grab_spawn ( void *m ) -{ - int rd = -1, outlen; - char *outbuf; - epggrab_module_int_t *mod = m; - char **argv = NULL; - char *path; +char* epggrab_module_grab_spawn(void* m) { + int rd = -1, outlen; + char* outbuf; + epggrab_module_int_t* mod = m; + char** argv = NULL; + char* path; /* Debug */ tvhinfo(mod->subsys, "%s: grab %s", mod->id, mod->path); @@ -511,7 +485,7 @@ char *epggrab_module_grab_spawn ( void *m ) strcat(path, " "); strcat(path, mod->args); } else { - path = (char *)mod->path; + path = (char*)mod->path; } /* Arguments */ @@ -543,15 +517,13 @@ error: return NULL; } +htsmsg_t* epggrab_module_trans_xml(void* m, char* c) { + htsmsg_t* ret; + char errbuf[100]; + epggrab_module_t* mod = m; - -htsmsg_t *epggrab_module_trans_xml ( void *m, char *c ) -{ - htsmsg_t *ret; - char errbuf[100]; - epggrab_module_t *mod = m; - - if (!c) return NULL; + if (!c) + return NULL; /* Extract */ ret = htsmsg_xml_deserialize(c, errbuf, sizeof(errbuf)); @@ -567,44 +539,43 @@ htsmsg_t *epggrab_module_trans_xml ( void *m, char *c ) /* * Socket handler */ -static void _epggrab_socket_handler ( epggrab_module_ext_t *mod, int s ) -{ - size_t outlen; - char *outbuf; - time_t tm1, tm2; - htsmsg_t *data = NULL; +static void _epggrab_socket_handler(epggrab_module_ext_t* mod, int s) { + size_t outlen; + char* outbuf; + time_t tm1, tm2; + htsmsg_t* data = NULL; /* Grab/Translate */ time(&tm1); outlen = file_readall(s, &outbuf); - if (outlen) data = mod->trans(mod, outbuf); + if (outlen) + data = mod->trans(mod, outbuf); time(&tm2); /* Process */ - if ( data ) { - tvhinfo(mod->subsys, "%s: grab took %"PRItime_t" seconds", mod->id, tm2 - tm1); + if (data) { + tvhinfo(mod->subsys, "%s: grab took %" PRItime_t " seconds", mod->id, tm2 - tm1); epggrab_module_parse(mod, data); - /* Failed */ + /* Failed */ } else { tvherror(mod->subsys, "%s: failed to read data", mod->id); } } - /* * External (socket) grab thread */ -static void *_epggrab_socket_thread ( void *p ) -{ - int s, s1; - epggrab_module_ext_t *mod = (epggrab_module_ext_t*)p; +static void* _epggrab_socket_thread(void* p) { + int s, s1; + epggrab_module_ext_t* mod = (epggrab_module_ext_t*)p; tvhinfo(mod->subsys, "%s: external socket enabled", mod->id); while (mod->enabled && (s1 = atomic_get(&mod->sock)) >= 0) { tvhdebug(mod->subsys, "%s: waiting for connection", mod->id); s = accept(s1, NULL, NULL); - if (s < 0) continue; + if (s < 0) + continue; tvhdebug(mod->subsys, "%s: got connection %d", mod->id, s); _epggrab_socket_handler(mod, s); close(s); @@ -616,15 +587,13 @@ static void *_epggrab_socket_thread ( void *p ) /* * Shutdown socket module */ -static void -epggrab_module_done_socket( void *m ) -{ - epggrab_module_ext_t *mod = (epggrab_module_ext_t*)m; - int sock; +static void epggrab_module_done_socket(void* m) { + epggrab_module_ext_t* mod = (epggrab_module_ext_t*)m; + int sock; assert(mod->type == EPGGRAB_EXT); mod->active = 0; - sock = atomic_exchange(&mod->sock, -1); + sock = atomic_exchange(&mod->sock, -1); shutdown(sock, SHUT_RDWR); close(sock); if (mod->tid) { @@ -640,25 +609,24 @@ epggrab_module_done_socket( void *m ) /* * Activate socket module */ -static int -epggrab_module_activate_socket ( void *m, int a ) -{ - pthread_attr_t tattr; - struct sockaddr_un addr; - epggrab_module_ext_t *mod = (epggrab_module_ext_t*)m; - const char *path; +static int epggrab_module_activate_socket(void* m, int a) { + pthread_attr_t tattr; + struct sockaddr_un addr; + epggrab_module_ext_t* mod = (epggrab_module_ext_t*)m; + const char* path; assert(mod->type == EPGGRAB_EXT); int sock; /* Ignore */ - if (mod->active == a) return 0; + if (mod->active == a) + return 0; /* Disable */ if (!a) { path = strdup(mod->path); epggrab_module_done_socket(m); mod->path = path; - /* Enable */ + /* Enable */ } else { unlink(mod->path); // just in case! hts_settings_makedirs(mod->path); @@ -669,8 +637,7 @@ epggrab_module_activate_socket ( void *m, int a ) memset(&addr, 0, sizeof(struct sockaddr_un)); addr.sun_family = AF_UNIX; strlcpy(addr.sun_path, mod->path, sizeof(addr.sun_path)); - if (bind(sock, (struct sockaddr*)&addr, - sizeof(struct sockaddr_un)) != 0) { + if (bind(sock, (struct sockaddr*)&addr, sizeof(struct sockaddr_un)) != 0) { tvherror(mod->subsys, "%s: failed to bind socket: %s", mod->id, strerror(errno)); close(sock); return 0; @@ -694,25 +661,36 @@ epggrab_module_activate_socket ( void *m, int a ) /* * Create a module */ -epggrab_module_ext_t *epggrab_module_ext_create - ( epggrab_module_ext_t *skel, const idclass_t *cls, - const char *id, int subsys, const char *saveid, - const char *name, int priority, const char *sockid, - int (*parse) (void *m, htsmsg_t *data, epggrab_stats_t *sta), - htsmsg_t* (*trans) (void *mod, char *data) ) -{ +epggrab_module_ext_t* epggrab_module_ext_create(epggrab_module_ext_t* skel, + const idclass_t* cls, + const char* id, + int subsys, + const char* saveid, + const char* name, + int priority, + const char* sockid, + int (*parse)(void* m, htsmsg_t* data, epggrab_stats_t* sta), + htsmsg_t* (*trans)(void* mod, char* data)) { char path[512]; /* Allocate data */ - if (!skel) skel = calloc(1, sizeof(epggrab_module_ext_t)); + if (!skel) + skel = calloc(1, sizeof(epggrab_module_ext_t)); atomic_set(&skel->sock, -1); /* Pass through */ hts_settings_buildpath(path, sizeof(path), "epggrab/%s.sock", sockid); epggrab_module_int_create((epggrab_module_int_t*)skel, - cls ?: &epggrab_mod_ext_class, - id, subsys, saveid, name, priority, path, - NULL, parse, trans); + cls ?: &epggrab_mod_ext_class, + id, + subsys, + saveid, + name, + priority, + path, + NULL, + parse, + trans); /* Local */ skel->type = EPGGRAB_EXT; @@ -726,18 +704,25 @@ epggrab_module_ext_t *epggrab_module_ext_create * OTA module functions * *************************************************************************/ -epggrab_module_ota_t *epggrab_module_ota_create - ( epggrab_module_ota_t *skel, - const char *id, int subsys, const char *saveid, - const char *name, int priority, const idclass_t *idclass, - const epggrab_ota_module_ops_t *ops ) -{ - if (!skel) skel = calloc(1, sizeof(epggrab_module_ota_t)); +epggrab_module_ota_t* epggrab_module_ota_create(epggrab_module_ota_t* skel, + const char* id, + int subsys, + const char* saveid, + const char* name, + int priority, + const idclass_t* idclass, + const epggrab_ota_module_ops_t* ops) { + if (!skel) + skel = calloc(1, sizeof(epggrab_module_ota_t)); /* Pass through */ epggrab_module_create((epggrab_module_t*)skel, - idclass ?: &epggrab_mod_ota_class, - id, subsys, saveid, name, priority); + idclass ?: &epggrab_mod_ota_class, + id, + subsys, + saveid, + name, + priority); /* Setup */ skel->type = EPGGRAB_OTA; diff --git a/src/epggrab/module/eit.c b/src/epggrab/module/eit.c index 1b40b1dc3..e518f3975 100644 --- a/src/epggrab/module/eit.c +++ b/src/epggrab/module/eit.c @@ -36,49 +36,47 @@ typedef struct eit_nit { LIST_ENTRY(eit_nit) link; - char *name; + char* name; uint16_t onid[32]; uint16_t tsid[32]; uint16_t nbid[32]; - int onid_count; - int tsid_count; - int nbid_count; + int onid_count; + int tsid_count; + int nbid_count; } eit_nit_t; typedef struct eit_sdt { LIST_ENTRY(eit_sdt) link; uint16_t onid[32]; uint16_t tsid[32]; - int onid_count; - int tsid_count; + int onid_count; + int tsid_count; } eit_sdt_t; -typedef struct eit_private -{ +typedef struct eit_private { TAILQ_ENTRY(eit_private) link; - lang_str_t *name; - epggrab_module_ota_t *module; - uint16_t pid; - uint16_t bat_pid; - int conv; - uint32_t sdt_enable; - uint32_t hacks; - uint32_t priv; - char slave[32]; + lang_str_t* name; + epggrab_module_ota_t* module; + uint16_t pid; + uint16_t bat_pid; + int conv; + uint32_t sdt_enable; + uint32_t hacks; + uint32_t priv; + char slave[32]; LIST_HEAD(, eit_nit) nit; LIST_HEAD(, eit_sdt) sdt; - epggrab_ota_module_ops_t *ops; + epggrab_ota_module_ops_t* ops; } eit_private_t; -#define EIT_CONV_HUFFMAN 1 +#define EIT_CONV_HUFFMAN 1 -#define EIT_HACK_INTEREST4E (1<<0) -#define EIT_HACK_EXTRAMUXLOOKUP (1<<1) -#define EIT_HACK_SVCNETLOOKUP (1<<2) +#define EIT_HACK_INTEREST4E (1 << 0) +#define EIT_HACK_EXTRAMUXLOOKUP (1 << 1) +#define EIT_HACK_SVCNETLOOKUP (1 << 2) /* Queued data structure */ -typedef struct eit_data -{ +typedef struct eit_data { tvh_uuid_t svc_uuid; uint16_t onid; int tableid; @@ -90,18 +88,17 @@ typedef struct eit_data } eit_data_t; /* Provider configuration */ -typedef struct eit_module_t -{ - epggrab_module_ota_scraper_t ; ///< Base struct - int short_target; - int running_immediate; ///< Handle quickly the events from the current table +typedef struct eit_module_t { + epggrab_module_ota_scraper_t; ///< Base struct + int short_target; + int running_immediate; ///< Handle quickly the events from the current table eit_pattern_list_t p_snum; eit_pattern_list_t p_enum; - eit_pattern_list_t p_airdate; ///< Original air date parser - eit_pattern_list_t p_scrape_title; ///< Scrape title from title + summary data - eit_pattern_list_t p_scrape_subtitle;///< Scrape subtitle from summary data - eit_pattern_list_t p_scrape_summary; ///< Scrape summary from summary data - eit_pattern_list_t p_is_new; ///< Is programme new to air + eit_pattern_list_t p_airdate; ///< Original air date parser + eit_pattern_list_t p_scrape_title; ///< Scrape title from title + summary data + eit_pattern_list_t p_scrape_subtitle; ///< Scrape subtitle from summary data + eit_pattern_list_t p_scrape_summary; ///< Scrape summary from summary data + eit_pattern_list_t p_is_new; ///< Is programme new to air } eit_module_t; static TAILQ_HEAD(, eit_private) eit_private_list; @@ -110,62 +107,57 @@ static TAILQ_HEAD(, eit_private) eit_private_list; * Status handling * ***********************************************************************/ -typedef struct eit_event -{ - char uri[529]; - char suri[529]; +typedef struct eit_event { + char uri[529]; + char suri[529]; - lang_str_t *title; - lang_str_t *subtitle; - lang_str_t *summary; - lang_str_t *desc; + lang_str_t* title; + lang_str_t* subtitle; + lang_str_t* summary; + lang_str_t* desc; - const char *default_charset; + const char* default_charset; #if TODO_ADD_EXTRA - htsmsg_t *extra; + htsmsg_t* extra; #endif - epg_genre_list_t *genre; + epg_genre_list_t* genre; epg_episode_num_t en; - uint8_t hd, ws; - uint8_t ad, st, ds; - uint8_t bw; + uint8_t hd, ws; + uint8_t ad, st, ds; + uint8_t bw; - uint8_t parental; - ratinglabel_t *rating_label; + uint8_t parental; + ratinglabel_t* rating_label; - uint8_t is_new; - time_t first_aired; - uint16_t copyright_year; + uint8_t is_new; + time_t first_aired; + uint16_t copyright_year; } eit_event_t; - /* * Forward declarations */ -static void _eit_module_load_config(eit_module_t *mod); -static void _eit_scrape_clear(eit_module_t *mod); -static void _eit_done(void *mod); +static void _eit_module_load_config(eit_module_t* mod); +static void _eit_scrape_clear(eit_module_t* mod); +static void _eit_done(void* mod); /* ************************************************************************ * Diagnostics * ***********************************************************************/ // Dump a descriptor tag for debug (looking for new tags etc...) -static void -_eit_dtag_dump - ( epggrab_module_t *mod, uint8_t dtag, uint8_t dlen, const uint8_t *buf ) -{ +static void _eit_dtag_dump(epggrab_module_t* mod, uint8_t dtag, uint8_t dlen, const uint8_t* buf) { #if APS_DEBUG - int i = 0, j = 0; + int i = 0, j = 0; char tmp[100]; tvhdebug(mod->subsys, "%s: dtag 0x%02X len %d", mt->mt_name, dtag, dlen); while (i < dlen) { - j += sprintf(tmp+j, "%02X ", buf[i]); + j += sprintf(tmp + j, "%02X ", buf[i]); i++; if ((i % 8) == 0 || (i == dlen)) { tvhdebug(mod->subsys, "%s: %s", mt->mt_name, tmp); @@ -179,23 +171,21 @@ _eit_dtag_dump * EIT Event descriptors * ***********************************************************************/ -static dvb_string_conv_t _eit_freesat_conv[2] = { - { 0x1f, freesat_huffman_decode }, - { 0x00, NULL } -}; +static dvb_string_conv_t _eit_freesat_conv[2] = {{0x1f, freesat_huffman_decode}, {0x00, NULL}}; /* * Get string */ -static int _eit_get_string_with_len - ( epggrab_module_t *mod, - char *dst, size_t dstlen, - const uint8_t *src, size_t srclen, const char *charset ) -{ - epggrab_module_ota_t *m = (epggrab_module_ota_t *)mod; - dvb_string_conv_t *cptr = NULL; - - if (((eit_private_t *)m->opaque)->conv == EIT_CONV_HUFFMAN) +static int _eit_get_string_with_len(epggrab_module_t* mod, + char* dst, + size_t dstlen, + const uint8_t* src, + size_t srclen, + const char* charset) { + epggrab_module_ota_t* m = (epggrab_module_ota_t*)mod; + dvb_string_conv_t* cptr = NULL; + + if (((eit_private_t*)m->opaque)->conv == EIT_CONV_HUFFMAN) cptr = _eit_freesat_conv; /* Convert */ @@ -205,14 +195,14 @@ static int _eit_get_string_with_len /* * Short Event - 0x4d */ -static int _eit_desc_short_event - ( epggrab_module_t *mod, const uint8_t *ptr, int len, eit_event_t *ev ) -{ - int r; +static int +_eit_desc_short_event(epggrab_module_t* mod, const uint8_t* ptr, int len, eit_event_t* ev) { + int r; char lang[4]; char buf[512]; - if ( len < 5 ) return -1; + if (len < 5) + return -1; /* Language */ memcpy(lang, ptr, 3); @@ -221,24 +211,25 @@ static int _eit_desc_short_event ptr += 3; /* Title */ - if ( (r = _eit_get_string_with_len(mod, buf, sizeof(buf), - ptr, len, ev->default_charset)) < 0 ) { + if ((r = _eit_get_string_with_len(mod, buf, sizeof(buf), ptr, len, ev->default_charset)) < 0) { return -1; - } else if ( r > 1 ) { - if (!ev->title) ev->title = lang_str_create(); + } else if (r > 1) { + if (!ev->title) + ev->title = lang_str_create(); lang_str_add(ev->title, buf, lang); } len -= r; ptr += r; - if ( len < 1 ) return -1; + if (len < 1) + return -1; /* Summary */ - if ( (r = _eit_get_string_with_len(mod, buf, sizeof(buf), - ptr, len, ev->default_charset)) < 0 ) { + if ((r = _eit_get_string_with_len(mod, buf, sizeof(buf), ptr, len, ev->default_charset)) < 0) { return -1; - } else if ( r > 1 ) { - if (!ev->summary) ev->summary = lang_str_create(); + } else if (r > 1) { + if (!ev->summary) + ev->summary = lang_str_create(); lang_str_add(ev->summary, buf, lang); } @@ -248,15 +239,15 @@ static int _eit_desc_short_event /* * Extended Event - 0x4e */ -static int _eit_desc_ext_event - ( epggrab_module_t *mod, const uint8_t *ptr, int len, eit_event_t *ev ) -{ - int r, ilen; - char ikey[512], ival[512]; - char buf[512], lang[4]; - const uint8_t *iptr; +static int +_eit_desc_ext_event(epggrab_module_t* mod, const uint8_t* ptr, int len, eit_event_t* ev) { + int r, ilen; + char ikey[512], ival[512]; + char buf[512], lang[4]; + const uint8_t* iptr; - if (len < 6) return -1; + if (len < 6) + return -1; /* Descriptor numbering (skip) */ len -= 1; @@ -269,11 +260,12 @@ static int _eit_desc_ext_event ptr += 3; /* Key/Value items */ - ilen = *ptr; - len -= 1; - ptr += 1; - iptr = ptr; - if (len < ilen) return -1; + ilen = *ptr; + len -= 1; + ptr += 1; + iptr = ptr; + if (len < ilen) + return -1; /* Skip past */ ptr += ilen; @@ -283,16 +275,16 @@ static int _eit_desc_ext_event while (ilen) { /* Key */ - if ( (r = _eit_get_string_with_len(mod, ikey, sizeof(ikey), - iptr, ilen, ev->default_charset)) < 0 ) + if ((r = _eit_get_string_with_len(mod, ikey, sizeof(ikey), iptr, ilen, ev->default_charset)) < + 0) break; ilen -= r; iptr += r; /* Value */ - if ( (r = _eit_get_string_with_len(mod, ival, sizeof(ival), - iptr, ilen, ev->default_charset)) < 0 ) + if ((r = _eit_get_string_with_len(mod, ival, sizeof(ival), iptr, ilen, ev->default_charset)) < + 0) break; ilen -= r; @@ -302,18 +294,17 @@ static int _eit_desc_ext_event // TODO: extend existing? #if TODO_ADD_EXTRA if (*ikey && *ival) { - if (!ev->extra) ev->extra = htsmsg_create_map(); + if (!ev->extra) + ev->extra = htsmsg_create_map(); htsmsg_add_str(ev->extra, ikey, ival); } #endif } /* Description */ - if ( _eit_get_string_with_len(mod, - buf, sizeof(buf), - ptr, len, - ev->default_charset) > 1 ) { - if (!ev->desc) ev->desc = lang_str_create(); + if (_eit_get_string_with_len(mod, buf, sizeof(buf), ptr, len, ev->default_charset) > 1) { + if (!ev->desc) + ev->desc = lang_str_create(); lang_str_append(ev->desc, buf, lang); } @@ -324,12 +315,12 @@ static int _eit_desc_ext_event * Component Descriptor - 0x50 */ -static int _eit_desc_component - ( epggrab_module_t *mod, const uint8_t *ptr, int len, eit_event_t *ev ) -{ +static int +_eit_desc_component(epggrab_module_t* mod, const uint8_t* ptr, int len, eit_event_t* ev) { uint8_t c, t; - if (len < 6) return -1; + if (len < 6) + return -1; /* Stream Content and Type */ c = *ptr & 0x0f; @@ -339,48 +330,46 @@ static int _eit_desc_component if (c == 0x1) { if (t > 0x08 && t < 0x11) { ev->hd = 1; - if ( t != 0x09 && t != 0x0d ) + if (t != 0x09 && t != 0x0d) ev->ws = 1; - } else if (t == 0x02 || t == 0x03 || t == 0x04 || - t == 0x06 || t == 0x07 || t == 0x08 ) { + } else if (t == 0x02 || t == 0x03 || t == 0x04 || t == 0x06 || t == 0x07 || t == 0x08) { ev->ws = 1; } - /* MPEG2 (audio) */ + /* MPEG2 (audio) */ } else if (c == 0x2) { /* Described */ if (t == 0x40 || t == 0x41) ev->ad = 1; - /* Misc */ + /* Misc */ } else if (c == 0x3) { if (t == 0x1 || (t >= 0x10 && t <= 0x14) || (t >= 0x20 && t <= 0x24)) ev->st = 1; else if (t == 0x30 || t == 0x31) ev->ds = 1; - /* H264 */ + /* H264 */ } else if (c == 0x5) { if (t == 0x0b || t == 0x0c || t == 0x10) ev->hd = ev->ws = 1; else if (t == 0x03 || t == 0x04 || t == 0x07 || t == 0x08) ev->ws = 1; - /* AAC */ - } else if ( c == 0x6 ) { + /* AAC */ + } else if (c == 0x6) { /* Described */ if (t == 0x40 || t == 0x44) ev->ad = 1; - /* HEVC */ - } else if ( c == 0x9 ) { + /* HEVC */ + } else if (c == 0x9) { ev->ws = 1; if (t > 3) ev->hd = 2; - } return 0; @@ -390,28 +379,31 @@ static int _eit_desc_component * Content Descriptor - 0x54 */ -static int _eit_desc_content - ( epggrab_module_t *mod, const uint8_t *ptr, int len, eit_event_t *ev ) -{ - uint8_t tempPtr = 0; //Temporary variable to hold a (potentially) changed *ptr value. - tempPtr = *ptr; +static int _eit_desc_content(epggrab_module_t* mod, const uint8_t* ptr, int len, eit_event_t* ev) { + uint8_t tempPtr = 0; // Temporary variable to hold a (potentially) changed *ptr value. + tempPtr = *ptr; while (len > 1) { - //If the genre translation table has been loaded, it will not be a null pointer. - if (epggrab_ota_genre_translation){ - //Get the potentially new genre value. + // If the genre translation table has been loaded, it will not be a null pointer. + if (epggrab_ota_genre_translation) { + // Get the potentially new genre value. tempPtr = epggrab_ota_genre_translation[*ptr]; - //If we did get a translation, write a trace for debugging. - if(tempPtr != *ptr) - { - tvhtrace(LS_TBL_EIT, "Translating '%d' (0x%02x) to '%d' (0x%02x)", *ptr, *ptr, tempPtr, tempPtr); + // If we did get a translation, write a trace for debugging. + if (tempPtr != *ptr) { + tvhtrace(LS_TBL_EIT, + "Translating '%d' (0x%02x) to '%d' (0x%02x)", + *ptr, + *ptr, + tempPtr, + tempPtr); } - }//END genre translation table loaded. + } // END genre translation table loaded. - if (tempPtr == 0xb1) //0xB1 is the genre code for 'Black and White' + if (tempPtr == 0xb1) // 0xB1 is the genre code for 'Black and White' ev->bw = 1; - else if (tempPtr < 0xb0) { //0xB0 is the start of the 'Special Characteristics' block. - if (!ev->genre) ev->genre = calloc(1, sizeof(epg_genre_list_t)); - epg_genre_list_add_by_eit(ev->genre, (const uint8_t)tempPtr); //Cast as a 'const' + else if (tempPtr < 0xb0) { // 0xB0 is the start of the 'Special Characteristics' block. + if (!ev->genre) + ev->genre = calloc(1, sizeof(epg_genre_list_t)); + epg_genre_list_add_by_eit(ev->genre, (const uint8_t)tempPtr); // Cast as a 'const' } len -= 2; ptr += 2; @@ -422,34 +414,28 @@ static int _eit_desc_content /* * Parental rating Descriptor - 0x55 */ -static int _eit_desc_parental - ( epggrab_module_t *mod, const uint8_t *ptr, int len, eit_event_t *ev ) -{ +static int _eit_desc_parental(epggrab_module_t* mod, const uint8_t* ptr, int len, eit_event_t* ev) { int cnt = 0, sum = 0, i = 3; - char tmpCountry[4]; - int tmpAge = 0; - ratinglabel_t *rl = NULL; + char tmpCountry[4]; + int tmpAge = 0; + ratinglabel_t* rl = NULL; while (len > 3) { - //If we are processing parental rating labels. - if(epggrab_conf.epgdb_processparentallabels) - { - //Get the recommended age for this rating. - //0x00 undefined - //0x01 to 0x0F minimum age = rating + 3 years - //0x10 to 0xFF defined by the broadcaster - if(ptr[i] == 0) - { + // If we are processing parental rating labels. + if (epggrab_conf.epgdb_processparentallabels) { + // Get the recommended age for this rating. + // 0x00 undefined + // 0x01 to 0x0F minimum age = rating + 3 years + // 0x10 to 0xFF defined by the broadcaster + if (ptr[i] == 0) { tmpAge = 0; - } - else - { - tmpAge = ptr[i]; //Do not add 3 here, do that with the 'display age'. + } else { + tmpAge = ptr[i]; // Do not add 3 here, do that with the 'display age'. } - //Get the country code for this rating. + // Get the country code for this rating. tmpCountry[0] = ptr[0]; tmpCountry[1] = ptr[1]; tmpCountry[2] = ptr[2]; @@ -457,31 +443,31 @@ static int _eit_desc_parental tvhtrace(LS_TBL_EIT, "Country '%s', age '%d'", tmpCountry, tmpAge); - //Look for a matching rating label + // Look for a matching rating label rl = ratinglabel_find_from_eit(tmpCountry, tmpAge); - //If we have found a rating label, save the details and exit. - //ie, ony use the first parental rating found. - //TODO: In future, if (eg in Europe) the rating codes from multiple - //countries are present, select the one that user prefers. - //A new config option will be needed for this. - //HOWEVER: A sampling of EIT data from European users - //suggests that this will not be necessary. - if(rl){ - ev->parental = rl->rl_display_age; + // If we have found a rating label, save the details and exit. + // ie, ony use the first parental rating found. + // TODO: In future, if (eg in Europe) the rating codes from multiple + // countries are present, select the one that user prefers. + // A new config option will be needed for this. + // HOWEVER: A sampling of EIT data from European users + // suggests that this will not be necessary. + if (rl) { + ev->parental = rl->rl_display_age; ev->rating_label = rl; return 0; } - }//END rating labels are being processed. - //If rating labels are not processed, do the original TVH process. + } // END rating labels are being processed. + // If rating labels are not processed, do the original TVH process. - if ( ptr[i] && ptr[i] < 0x10 ) { + if (ptr[i] && ptr[i] < 0x10) { cnt++; sum += (ptr[i] + 3); } len -= 4; - i += 4; - }//END loop through descriptors + i += 4; + } // END loop through descriptors // Note: we ignore the country code and average the lot! if (cnt) ev->parental = (uint8_t)(sum / cnt); @@ -492,34 +478,35 @@ static int _eit_desc_parental /* * Content ID - 0x76 */ -static int _eit_desc_crid - ( epggrab_module_t *mod, const uint8_t *ptr, int len, - eit_event_t *ev, eit_data_t *ed ) -{ - int r; +static int _eit_desc_crid(epggrab_module_t* mod, + const uint8_t* ptr, + int len, + eit_event_t* ev, + eit_data_t* ed) { + int r; uint8_t type; - char buf[512], *crid; - int clen; + char buf[512], *crid; + int clen; while (len > 3) { /* Explicit only */ - if ( (*ptr & 0x3) == 0 ) { + if ((*ptr & 0x3) == 0) { crid = NULL; type = *ptr >> 2; - r = _eit_get_string_with_len(mod, buf, sizeof(buf), - ptr+1, len-1, - ev->default_charset); - if (r < 0) return -1; - if (r == 0) continue; + r = _eit_get_string_with_len(mod, buf, sizeof(buf), ptr + 1, len - 1, ev->default_charset); + if (r < 0) + return -1; + if (r == 0) + continue; /* Episode */ if (type == 0x1 || type == 0x31) { crid = ev->uri; clen = sizeof(ev->uri); - /* Season */ + /* Season */ } else if (type == 0x2 || type == 0x32) { crid = ev->suri; clen = sizeof(ev->suri); @@ -555,8 +542,7 @@ static int _eit_desc_crid /* * */ -static int positive_atoi(const char *s) -{ +static int positive_atoi(const char* s) { int i = atoi(s); return i >= 0 ? i : 0; } @@ -566,36 +552,33 @@ static int positive_atoi(const char *s) * @param eit_mod - our module with regex to use. * @param ev - [out] modified event data. */ -static void -_eit_scrape_episode(lang_str_t *str, - eit_module_t *eit_mod, - eit_event_t *ev) -{ - lang_str_ele_t *se; - char buffer[2048]; +static void _eit_scrape_episode(lang_str_t* str, eit_module_t* eit_mod, eit_event_t* ev) { + lang_str_ele_t* se; + char buffer[2048]; - if (!str) return; + if (!str) + return; /* search for season number */ - RB_FOREACH(se, str, link) { + RB_FOREACH (se, str, link) { if (eit_pattern_apply_list(buffer, sizeof(buffer), se->str, se->lang, &eit_mod->p_snum)) if ((ev->en.s_num = positive_atoi(buffer))) { - tvhtrace(LS_TBL_EIT," extract season number %d using %s", ev->en.s_num, eit_mod->id); + tvhtrace(LS_TBL_EIT, " extract season number %d using %s", ev->en.s_num, eit_mod->id); break; } } /* ...for episode number */ - RB_FOREACH(se, str, link) { + RB_FOREACH (se, str, link) { if (eit_pattern_apply_list(buffer, sizeof(buffer), se->str, se->lang, &eit_mod->p_enum)) - if ((ev->en.e_num = positive_atoi(buffer))) { - tvhtrace(LS_TBL_EIT," extract episode number %d using %s", ev->en.e_num, eit_mod->id); - break; - } + if ((ev->en.e_num = positive_atoi(buffer))) { + tvhtrace(LS_TBL_EIT, " extract episode number %d using %s", ev->en.e_num, eit_mod->id); + break; + } } /* Extract original air date year */ - RB_FOREACH(se, str, link) { + RB_FOREACH (se, str, link) { if (eit_pattern_apply_list(buffer, sizeof(buffer), se->str, se->lang, &eit_mod->p_airdate)) { if (strlen(buffer) == 4) { /* Year component only, so assume it is the copyright year. */ @@ -606,7 +589,7 @@ _eit_scrape_episode(lang_str_t *str, } /* Extract is_new flag. Any match is assumed to mean "new" */ - RB_FOREACH(se, str, link) { + RB_FOREACH (se, str, link) { if (eit_pattern_apply_list(buffer, sizeof(buffer), se->str, se->lang, &eit_mod->p_is_new)) { ev->is_new = 1; break; @@ -618,11 +601,9 @@ _eit_scrape_episode(lang_str_t *str, * @param eit_mod - our module with regex to use. * @param ev - [out] modified event data. */ -static void -_eit_scrape_text(eit_module_t *eit_mod, eit_event_t *ev) -{ - lang_str_ele_t *se; - char buffer[2048]; +static void _eit_scrape_text(eit_module_t* eit_mod, eit_event_t* ev) { + lang_str_ele_t* se; + char buffer[2048]; if (!ev->summary) return; @@ -633,14 +614,24 @@ _eit_scrape_text(eit_module_t *eit_mod, eit_event_t *ev) * and the summary (the latter to tidy up). */ if (ev->title && eit_mod->scrape_title) { - char title_summary[2048]; - lang_str_t *ls = lang_str_create(); - RB_FOREACH(se, ev->title, link) { - snprintf(title_summary, sizeof(title_summary), "%s %% %s", - se->str, lang_str_get(ev->summary, se->lang)); - if (eit_pattern_apply_list(buffer, sizeof(buffer), title_summary, se->lang, &eit_mod->p_scrape_title)) { - tvhtrace(LS_TBL_EIT, " scrape title '%s' from '%s' using %s", - buffer, title_summary, eit_mod->id); + char title_summary[2048]; + lang_str_t* ls = lang_str_create(); + RB_FOREACH (se, ev->title, link) { + snprintf(title_summary, + sizeof(title_summary), + "%s %% %s", + se->str, + lang_str_get(ev->summary, se->lang)); + if (eit_pattern_apply_list(buffer, + sizeof(buffer), + title_summary, + se->lang, + &eit_mod->p_scrape_title)) { + tvhtrace(LS_TBL_EIT, + " scrape title '%s' from '%s' using %s", + buffer, + title_summary, + eit_mod->id); lang_str_set(&ls, buffer, se->lang); } } @@ -649,21 +640,35 @@ _eit_scrape_text(eit_module_t *eit_mod, eit_event_t *ev) } if (eit_mod->scrape_subtitle) { - RB_FOREACH(se, ev->summary, link) { - if (eit_pattern_apply_list(buffer, sizeof(buffer), se->str, se->lang, &eit_mod->p_scrape_subtitle)) { - tvhtrace(LS_TBL_EIT, " scrape subtitle '%s' from '%s' using %s", - buffer, se->str, eit_mod->id); + RB_FOREACH (se, ev->summary, link) { + if (eit_pattern_apply_list(buffer, + sizeof(buffer), + se->str, + se->lang, + &eit_mod->p_scrape_subtitle)) { + tvhtrace(LS_TBL_EIT, + " scrape subtitle '%s' from '%s' using %s", + buffer, + se->str, + eit_mod->id); lang_str_set(&ev->subtitle, buffer, se->lang); } } } if (eit_mod->scrape_summary) { - lang_str_t *ls = lang_str_create(); - RB_FOREACH(se, ev->summary, link) { - if (eit_pattern_apply_list(buffer, sizeof(buffer), se->str, se->lang, &eit_mod->p_scrape_summary)) { - tvhtrace(LS_TBL_EIT, " scrape summary '%s' from '%s' using %s", - buffer, se->str, eit_mod->id); + lang_str_t* ls = lang_str_create(); + RB_FOREACH (se, ev->summary, link) { + if (eit_pattern_apply_list(buffer, + sizeof(buffer), + se->str, + se->lang, + &eit_mod->p_scrape_summary)) { + tvhtrace(LS_TBL_EIT, + " scrape summary '%s' from '%s' using %s", + buffer, + se->str, + eit_mod->id); lang_str_set(&ls, buffer, se->lang); } } @@ -676,43 +681,49 @@ _eit_scrape_text(eit_module_t *eit_mod, eit_event_t *ev) * EIT Event * ***********************************************************************/ -static int _eit_process_event_one - ( epggrab_module_t *mod, int tableid, int sect, - mpegts_service_t *svc, channel_t *ch, - eit_event_t *ev, - const uint8_t *ptr, int len, - int local, int *save ) -{ - int save2 = 0, rsonly = 0; - time_t start, stop; - uint16_t eid; - uint8_t running; +static int _eit_process_event_one(epggrab_module_t* mod, + int tableid, + int sect, + mpegts_service_t* svc, + channel_t* ch, + eit_event_t* ev, + const uint8_t* ptr, + int len, + int local, + int* save) { + int save2 = 0, rsonly = 0; + time_t start, stop; + uint16_t eid; + uint8_t running; epg_broadcast_t *ebc, _ebc; - epg_running_t run; - epg_changes_t changes = 0; - char tm1[32], tm2[32]; - int short_target = ((eit_module_t *)mod)->short_target; + epg_running_t run; + epg_changes_t changes = 0; + char tm1[32], tm2[32]; + int short_target = ((eit_module_t*)mod)->short_target; /* Core fields */ eid = ptr[0] << 8 | ptr[1]; start = dvb_convert_date(&ptr[2], local); - stop = start + bcdtoint(ptr[7] & 0xff) * 3600 + - bcdtoint(ptr[8] & 0xff) * 60 + - bcdtoint(ptr[9] & 0xff); + stop = start + bcdtoint(ptr[7] & 0xff) * 3600 + bcdtoint(ptr[8] & 0xff) * 60 + + bcdtoint(ptr[9] & 0xff); running = (ptr[10] >> 5) & 0x07; if (epg_channel_ignore_broadcast(ch, start)) return 0; /* Find broadcast */ - ebc = epg_broadcast_find_by_time(ch, mod, start, stop, 1, &save2, &changes); - tvhtrace(LS_TBL_EIT, "svc='%s', ch='%s', eid=%5d, tbl=%02x, running=%d, start=%s," - " stop=%s, ebc=%p", - svc->s_dvb_svcname ?: "(null)", - ch ? channel_get_name(ch, channel_blank_name) : "(null)", - eid, tableid, running, - gmtime2local(start, tm1, sizeof(tm1)), - gmtime2local(stop, tm2, sizeof(tm2)), ebc); + ebc = epg_broadcast_find_by_time(ch, mod, start, stop, 1, &save2, &changes); + tvhtrace(LS_TBL_EIT, + "svc='%s', ch='%s', eid=%5d, tbl=%02x, running=%d, start=%s," + " stop=%s, ebc=%p", + svc->s_dvb_svcname ?: "(null)", + ch ? channel_get_name(ch, channel_blank_name) : "(null)", + eid, + tableid, + running, + gmtime2local(start, tm1, sizeof(tm1)), + gmtime2local(stop, tm2, sizeof(tm2)), + ebc); if (!ebc) { if (tableid == 0x4e) rsonly = 1; @@ -724,13 +735,13 @@ static int _eit_process_event_one if (!ev->title) goto running; memset(&_ebc, 0, sizeof(_ebc)); - _ebc.dvb_eid = eid; - _ebc.start = start; - _ebc.stop = stop; + _ebc.dvb_eid = eid; + _ebc.start = start; + _ebc.stop = stop; _ebc.episodelink = epg_set_broadcast_find_by_uri(&epg_episodelinks, ev->uri); - _ebc.serieslink = epg_set_broadcast_find_by_uri(&epg_serieslinks, ev->suri); - _ebc.title = lang_str_copy(ev->title); - ebc = epg_match_now_next(ch, &_ebc); + _ebc.serieslink = epg_set_broadcast_find_by_uri(&epg_serieslinks, ev->suri); + _ebc.title = lang_str_copy(ev->title); + ebc = epg_match_now_next(ch, &_ebc); tvhtrace(mod->subsys, "%s: running state only ebc=%p", svc->s_dvb_svcname ?: "(null)", ebc); lang_str_destroy(_ebc.title); goto running; @@ -746,8 +757,7 @@ static int _eit_process_event_one /* Summary/Description */ if (ev->summary) - if (short_target != 0 || - (ev->subtitle && lang_str_compare(ev->summary, ev->subtitle))) + if (short_target != 0 || (ev->subtitle && lang_str_compare(ev->summary, ev->subtitle))) *save |= epg_broadcast_set_summary(ebc, ev->summary, &changes); if (ev->desc) *save |= epg_broadcast_set_description(ebc, ev->desc, &changes); @@ -785,11 +795,10 @@ static int _eit_process_event_one if (ev->parental) *save |= epg_broadcast_set_age_rating(ebc, ev->parental, &changes); - if (ev->rating_label) - { + if (ev->rating_label) { tvhtrace(mod->subsys, "About to save rating label '%p'", ev->rating_label); *save |= epg_broadcast_set_rating_label(ebc, ev->rating_label, &changes); - } + } if (ev->subtitle) *save |= epg_broadcast_set_subtitle(ebc, ev->subtitle, &changes); @@ -809,16 +818,23 @@ static int _eit_process_event_one *save |= epg_broadcast_change_finish(ebc, changes, 0); - running: /* use running flag only for current broadcast */ if (ebc && running && tableid == 0x4e) { if (sect == 0) { switch (running) { - case 2: run = EPG_RUNNING_WARM; break; - case 3: run = EPG_RUNNING_PAUSE; break; - case 4: run = EPG_RUNNING_NOW; break; - default: run = EPG_RUNNING_STOP; break; + case 2: + run = EPG_RUNNING_WARM; + break; + case 3: + run = EPG_RUNNING_PAUSE; + break; + case 4: + run = EPG_RUNNING_NOW; + break; + default: + run = EPG_RUNNING_STOP; + break; } *save |= epg_broadcast_set_running(ebc, run); } else if (sect == 1 && running != 2 && running != 3 && running != 4) { @@ -828,42 +844,46 @@ running: return 0; } -static int _eit_process_event - ( epggrab_module_t *mod, eit_data_t *ed, - const uint8_t *ptr0, int len0, - int *save, int lock ) -{ - eit_module_t *eit_mod = (eit_module_t *)mod; - idnode_list_mapping_t *ilm = NULL; - mpegts_service_t *svc; - channel_t *ch; - eit_event_t ev; - const int tableid = ed->tableid; - const int sect = ed->sect; - const int local = ed->local_time; - const uint8_t *ptr; - int r, len; - uint8_t dtag, dlen; - int dllen; - - if (len0 < 12) return -1; +static int _eit_process_event(epggrab_module_t* mod, + eit_data_t* ed, + const uint8_t* ptr0, + int len0, + int* save, + int lock) { + eit_module_t* eit_mod = (eit_module_t*)mod; + idnode_list_mapping_t* ilm = NULL; + mpegts_service_t* svc; + channel_t* ch; + eit_event_t ev; + const int tableid = ed->tableid; + const int sect = ed->sect; + const int local = ed->local_time; + const uint8_t* ptr; + int r, len; + uint8_t dtag, dlen; + int dllen; + + if (len0 < 12) + return -1; dllen = ((ptr0[10] & 0x0f) << 8) | ptr0[11]; - len = len0 - 12; - ptr = ptr0 + 12; + len = len0 - 12; + ptr = ptr0 + 12; - if (len < dllen) return -1; + if (len < dllen) + return -1; memset(&ev, 0, sizeof(ev)); if (ed->charset_len) - ev.default_charset = (char *)ed->data + ed->cridauth_len; + ev.default_charset = (char*)ed->data + ed->cridauth_len; while (dllen > 2) { dtag = ptr[0]; dlen = ptr[1]; dllen -= 2; - ptr += 2; - if (dllen < dlen) break; + ptr += 2; + if (dllen < dlen) + break; tvhtrace(mod->subsys, "%s: dtag %02X dlen %d", mod->id, dtag, dlen); tvhlog_hexdump(mod->subsys, ptr, dlen); @@ -883,12 +903,15 @@ static int _eit_process_event break; case DVB_DESC_PARENTAL_RAT: r = _eit_desc_parental(mod, ptr, dlen, &ev); - if(epggrab_conf.epgdb_processparentallabels){ - if(ev.rating_label){ - tvhtrace(mod->subsys, "RATINGLABEL '%d' '%s'", ev.parental, ev.rating_label->rl_display_label); - } else { - tvhtrace(mod->subsys, "RATINGLABEL '%d' ''", ev.parental); - } + if (epggrab_conf.epgdb_processparentallabels) { + if (ev.rating_label) { + tvhtrace(mod->subsys, + "RATINGLABEL '%d' '%s'", + ev.parental, + ev.rating_label->rl_display_label); + } else { + tvhtrace(mod->subsys, "RATINGLABEL '%d' ''", ev.parental); + } } break; @@ -901,9 +924,10 @@ static int _eit_process_event break; } - if (r < 0) break; + if (r < 0) + break; dllen -= dlen; - ptr += dlen; + ptr += dlen; } /* Do all scraping here, outside the global lock. @@ -926,13 +950,13 @@ static int _eit_process_event if (lock) tvh_mutex_lock(&global_lock); - svc = (mpegts_service_t *)service_find_by_uuid0(&ed->svc_uuid); + svc = (mpegts_service_t*)service_find_by_uuid0(&ed->svc_uuid); if (svc && eit_mod->opaque) { - LIST_FOREACH(ilm, &svc->s_channels, ilm_in1_link) { - ch = (channel_t *)ilm->ilm_in2; - if (!ch->ch_enabled || ch->ch_epg_parent) continue; - if (_eit_process_event_one(mod, tableid, sect, svc, ch, - &ev, ptr0, len0, local, save) < 0) + LIST_FOREACH (ilm, &svc->s_channels, ilm_in1_link) { + ch = (channel_t*)ilm->ilm_in2; + if (!ch->ch_enabled || ch->ch_epg_parent) + continue; + if (_eit_process_event_one(mod, tableid, sect, svc, ch, &ev, ptr0, len0, local, save) < 0) break; } } @@ -940,25 +964,29 @@ static int _eit_process_event tvh_mutex_unlock(&global_lock); #if TODO_ADD_EXTRA - if (ev.extra) htsmsg_destroy(ev.extra); + if (ev.extra) + htsmsg_destroy(ev.extra); #endif - if (ev.genre) epg_genre_list_destroy(ev.genre); - if (ev.title) lang_str_destroy(ev.title); - if (ev.subtitle) lang_str_destroy(ev.subtitle); - if (ev.summary) lang_str_destroy(ev.summary); - if (ev.desc) lang_str_destroy(ev.desc); + if (ev.genre) + epg_genre_list_destroy(ev.genre); + if (ev.title) + lang_str_destroy(ev.title); + if (ev.subtitle) + lang_str_destroy(ev.subtitle); + if (ev.summary) + lang_str_destroy(ev.summary); + if (ev.desc) + lang_str_destroy(ev.desc); if (ilm) return -1; return 12 + (((ptr0[10] & 0x0f) << 8) | ptr0[11]); } -static void -_eit_process_data(void *m, void *data, uint32_t len) -{ - int save = 0, r; - size_t hlen; - eit_data_t *ed = data; +static void _eit_process_data(void* m, void* data, uint32_t len) { + int save = 0, r; + size_t hlen; + eit_data_t* ed = data; assert(len >= sizeof(ed)); hlen = sizeof(*ed) + ed->cridauth_len + ed->charset_len; @@ -981,9 +1009,7 @@ _eit_process_data(void *m, void *data, uint32_t len) } } -static void -_eit_process_immediate(void *m, const void *ptr, uint32_t len, eit_data_t *ed) -{ +static void _eit_process_immediate(void* m, const void* ptr, uint32_t len, eit_data_t* ed) { int save = 0, r; while (len) { @@ -998,33 +1024,30 @@ _eit_process_immediate(void *m, const void *ptr, uint32_t len, eit_data_t *ed) epg_updated(); } -static int -_eit_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int r, sect, last, ver; - uint8_t seg; - uint16_t onid, tsid, sid; - uint32_t extraid, hacks; - mpegts_service_t *svc; - mpegts_mux_t *mm; - epggrab_ota_map_t *map; - epggrab_module_t *mod; - epggrab_ota_mux_t *ota = NULL; - mpegts_psi_table_state_t *st; - th_subscription_t *ths; - eit_data_t *data; - const char *cridauth, *charset; - int cridauth_len, charset_len, data_len; - eit_private_t *priv; +static int _eit_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int r, sect, last, ver; + uint8_t seg; + uint16_t onid, tsid, sid; + uint32_t extraid, hacks; + mpegts_service_t* svc; + mpegts_mux_t* mm; + epggrab_ota_map_t* map; + epggrab_module_t* mod; + epggrab_ota_mux_t* ota = NULL; + mpegts_psi_table_state_t* st; + th_subscription_t* ths; + eit_data_t* data; + const char * cridauth, *charset; + int cridauth_len, charset_len, data_len; + eit_private_t* priv; if (!epggrab_ota_running) return -1; - mm = mt->mt_mux; - map = mt->mt_opaque; - mod = (epggrab_module_t *)map->om_module; - priv = (eit_private_t *)((epggrab_module_ota_t *)mod)->opaque; + mm = mt->mt_mux; + map = mt->mt_opaque; + mod = (epggrab_module_t*)map->om_module; + priv = (eit_private_t*)((epggrab_module_ota_t*)mod)->opaque; if (priv == NULL) return -1; hacks = priv->hacks; @@ -1037,7 +1060,7 @@ _eit_callback } /* Validate */ - if(tableid < 0x4e || tableid > 0x6f || len < 11) { + if (tableid < 0x4e || tableid > 0x6f || len < 11) { if (ths) atomic_add(&ths->ths_total_err, 1); return -1; @@ -1051,8 +1074,13 @@ _eit_callback extraid = ((uint32_t)tsid << 16) | sid; // TODO: extra ID should probably include onid - tvhtrace(LS_TBL_EIT, "%s: sid %i tsid %04x onid %04x seg %02x", - mt->mt_name, sid, tsid, onid, seg); + tvhtrace(LS_TBL_EIT, + "%s: sid %i tsid %04x onid %04x seg %02x", + mt->mt_name, + sid, + tsid, + onid, + seg); /* Register interest */ if (tableid == 0x4e || (tableid >= 0x50 && tableid < 0x60) || @@ -1060,18 +1088,30 @@ _eit_callback ota = epggrab_ota_register((epggrab_module_ota_t*)mod, NULL, mm); /* Begin */ - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, - tableid, extraid, 11, &st, §, &last, &ver, 0); - if (r == 0) goto complete; - if (r < 0) return r; - if (tableid != 0x4e && r != 1) return r; + r = dvb_table_begin((mpegts_psi_table_t*)mt, + ptr, + len, + tableid, + extraid, + 11, + &st, + §, + &last, + &ver, + 0); + if (r == 0) + goto complete; + if (r < 0) + return r; + if (tableid != 0x4e && r != 1) + return r; if (st && r > 0) { uint32_t mask; - int sa = seg & 0xF8; - int sb = 7 - (seg & 0x07); - mask = (~(0xFF << sb) & 0xFF); + int sa = seg & 0xF8; + int sb = 7 - (seg & 0x07); + mask = (~(0xFF << sb) & 0xFF); mask <<= (24 - (sa % 32)); - st->sections[sa/32] &= ~mask; + st->sections[sa / 32] &= ~mask; } /* UK Cable Virgin: EPG data for services in other transponders is transmitted @@ -1079,7 +1119,7 @@ _eit_callback if ((hacks & EIT_HACK_EXTRAMUXLOOKUP) != 0 && (tableid == 0x50 || tableid == 0x4E)) { mm = mpegts_network_find_mux(mm->mm_network, onid, tsid, 1); } - if(!mm) + if (!mm) goto done; /* Get transport stream */ @@ -1088,17 +1128,20 @@ _eit_callback if (tableid == 0x4f || tableid >= 0x60) { mm = mpegts_network_find_mux(mm->mm_network, onid, tsid, 1); } else { - if ((mm->mm_tsid != tsid || mm->mm_onid != onid) && - !mm->mm_eit_tsid_nocheck) { - if (mm->mm_onid != MPEGTS_ONID_NONE && - mm->mm_tsid != MPEGTS_TSID_NONE) + if ((mm->mm_tsid != tsid || mm->mm_onid != onid) && !mm->mm_eit_tsid_nocheck) { + if (mm->mm_onid != MPEGTS_ONID_NONE && mm->mm_tsid != MPEGTS_TSID_NONE) tvhtrace(LS_TBL_EIT, - "%s: invalid tsid found tid 0x%02X, onid:tsid %d:%d != %d:%d", - mt->mt_name, tableid, mm->mm_onid, mm->mm_tsid, onid, tsid); + "%s: invalid tsid found tid 0x%02X, onid:tsid %d:%d != %d:%d", + mt->mt_name, + tableid, + mm->mm_onid, + mm->mm_tsid, + onid, + tsid); mm = NULL; } } - if(!mm) + if (!mm) goto done; /* Get service */ @@ -1139,15 +1182,15 @@ svc_ok: cridauth = svc->s_dvb_cridauth; if (!cridauth) cridauth = svc->s_dvb_mux->mm_crid_authority; - cridauth_len = cridauth ? strlen(cridauth) + 1 : 0; - charset = dvb_charset_find(NULL, NULL, svc); - charset_len = charset ? strlen(charset) + 1 : 0; - data_len = sizeof(*data) + cridauth_len + charset_len; - data = alloca(data_len); - data->tableid = tableid; - data->sect = sect; - data->svc_uuid = svc->s_id.in_uuid; - data->onid = onid; + cridauth_len = cridauth ? strlen(cridauth) + 1 : 0; + charset = dvb_charset_find(NULL, NULL, svc); + charset_len = charset ? strlen(charset) + 1 : 0; + data_len = sizeof(*data) + cridauth_len + charset_len; + data = alloca(data_len); + data->tableid = tableid; + data->sect = sect; + data->svc_uuid = svc->s_id.in_uuid; + data->onid = onid; data->local_time = mm->mm_network->mn_localtime; if (cridauth_len) { data->cridauth_len = cridauth_len; @@ -1161,7 +1204,7 @@ svc_ok: } else { data->charset_len = 0; } - if (((eit_module_t *)mod)->running_immediate && tableid == 0x4e) { + if (((eit_module_t*)mod)->running_immediate && tableid == 0x4e) { /* handle running state immediately */ _eit_process_immediate(mod, ptr, len, data); } else { @@ -1171,7 +1214,7 @@ svc_ok: } done: - r = dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + r = dvb_table_end((mpegts_psi_table_t*)mt, st, sect); complete: if (ota && !r && (tableid >= 0x50 && tableid < 0x60)) epggrab_ota_complete((epggrab_module_ota_t*)mod, ota); @@ -1183,19 +1226,15 @@ complete: * Module Setup * ***********************************************************************/ -static int _eit_start - ( epggrab_ota_map_t *map, mpegts_mux_t *dm ) -{ +static int _eit_start(epggrab_ota_map_t* map, mpegts_mux_t* dm) { return 0; } -static void _eit_install_one_handler - ( mpegts_mux_t *dm, epggrab_ota_map_t *map ) -{ - epggrab_module_ota_t *m = map->om_module; - eit_private_t *priv = m->opaque; - int pid = priv->pid; - int opts = 0; +static void _eit_install_one_handler(mpegts_mux_t* dm, epggrab_ota_map_t* map) { + epggrab_module_ota_t* m = map->om_module; + eit_private_t* priv = m->opaque; + int pid = priv->pid; + int opts = 0; /* Standard (0x12) */ if (pid == 0) { @@ -1203,20 +1242,26 @@ static void _eit_install_one_handler opts = MT_RECORD; } - mpegts_table_add(dm, 0, 0, _eit_callback, map, map->om_module->id, LS_TBL_EIT, - MT_CRC | opts, pid, MPS_WEIGHT_EIT); + mpegts_table_add(dm, + 0, + 0, + _eit_callback, + map, + map->om_module->id, + LS_TBL_EIT, + MT_CRC | opts, + pid, + MPS_WEIGHT_EIT); tvhdebug(m->subsys, "%s: installed table handler (pid %d)", m->id, pid); } -static void _eit_install_handlers - ( epggrab_ota_map_t *_map, mpegts_mux_t *dm ) -{ - epggrab_ota_mux_t *om; - epggrab_ota_map_t *map, *map2; - epggrab_module_ota_t *m, *m2; - epggrab_ota_mux_eit_plist_t *plist; - eit_private_t *priv, *priv2; - const char *modname; +static void _eit_install_handlers(epggrab_ota_map_t* _map, mpegts_mux_t* dm) { + epggrab_ota_mux_t* om; + epggrab_ota_map_t * map, *map2; + epggrab_module_ota_t * m, *m2; + epggrab_ota_mux_eit_plist_t* plist; + eit_private_t * priv, *priv2; + const char* modname; om = epggrab_ota_find_mux(dm); if (!om) @@ -1224,16 +1269,16 @@ static void _eit_install_handlers modname = om->om_force_modname; priv = NULL; - map = NULL; + map = NULL; if (strempty(modname)) { - LIST_FOREACH(plist, &om->om_eit_plist, link) { - priv2 = (eit_private_t *)plist->priv; + LIST_FOREACH (plist, &om->om_eit_plist, link) { + priv2 = (eit_private_t*)plist->priv; if (!priv || priv->module->priority < priv2->module->priority) { /* ignore priority for the slave, always prefer master */ if (priv && strcmp(priv->slave, priv2->module->id) == 0) continue; /* find the ota map */ - m = priv2->module; + m = priv2->module; map = epggrab_ota_find_map(om, m); if (!map || !m->enabled) { tvhtrace(m->subsys, "handlers - module '%s' not enabled", m->id); @@ -1243,10 +1288,10 @@ static void _eit_install_handlers } } } else { - m = (epggrab_module_ota_t *)epggrab_module_find_by_id(modname); + m = (epggrab_module_ota_t*)epggrab_module_find_by_id(modname); if (m) { - priv = (eit_private_t *)m->opaque; - map = epggrab_ota_find_map(om, m); + priv = (eit_private_t*)m->opaque; + map = epggrab_ota_find_map(om, m); } } @@ -1256,8 +1301,16 @@ static void _eit_install_handlers epggrab_ota_free_eit_plist(om); if (priv->bat_pid) { - mpegts_table_add(dm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, NULL, - "ebat", LS_TBL_BASE, MT_CRC, priv->bat_pid, MPS_WEIGHT_EIT); + mpegts_table_add(dm, + DVB_BAT_BASE, + DVB_BAT_MASK, + dvb_bat_callback, + NULL, + "ebat", + LS_TBL_BASE, + MT_CRC, + priv->bat_pid, + MPS_WEIGHT_EIT); } m = priv->module; @@ -1265,7 +1318,7 @@ static void _eit_install_handlers tvhtrace(m->subsys, "handlers - detected module '%s'", m->id); if (!strempty(priv->slave)) { - m2 = (epggrab_module_ota_t *)epggrab_module_find_by_id(priv->slave); + m2 = (epggrab_module_ota_t*)epggrab_module_find_by_id(priv->slave); if (m2) { map2 = epggrab_ota_find_map(om, m2); if (map2) { @@ -1280,11 +1333,15 @@ static void _eit_install_handlers mpegts_mux_set_epg_module(dm, m->id); } -static int _eit_activate(void *m, int e) -{ - eit_module_t *mod = m; - tvhtrace(LS_TBL_EIT, "_eit_activate %s change to %d from %d with scrape_episode of %d and scrape_subtitle of %d", - mod->id, e, mod->active, mod->scrape_episode, mod->scrape_subtitle); +static int _eit_activate(void* m, int e) { + eit_module_t* mod = m; + tvhtrace(LS_TBL_EIT, + "_eit_activate %s change to %d from %d with scrape_episode of %d and scrape_subtitle of %d", + mod->id, + e, + mod->active, + mod->scrape_episode, + mod->scrape_subtitle); const int original_status = mod->active; /* We expect to be activated/deactivated infrequently so free up the @@ -1304,11 +1361,9 @@ static int _eit_activate(void *m, int e) return e != original_status; } -static int _eit_tune - ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om, mpegts_mux_t *mm ) -{ - int r = 0; - mpegts_service_t *s; +static int _eit_tune(epggrab_ota_map_t* map, epggrab_ota_mux_t* om, mpegts_mux_t* mm) { + int r = 0; + mpegts_service_t* s; epggrab_ota_svc_link_t *osl, *nxt; lock_assert(&global_lock); @@ -1335,8 +1390,7 @@ static int _eit_tune return r; } -static int eit_nit_array_check(uint16_t val, uint16_t *array, int array_count) -{ +static int eit_nit_array_check(uint16_t val, uint16_t* array, int array_count) { int i; if (array_count <= 0) @@ -1347,44 +1401,48 @@ static int eit_nit_array_check(uint16_t val, uint16_t *array, int array_count) return 1; } -static void eit_queue_priv - (mpegts_mux_t *dm, const char *src, eit_private_t *priv) -{ - epggrab_ota_mux_t *om; +static void eit_queue_priv(mpegts_mux_t* dm, const char* src, eit_private_t* priv) { + epggrab_ota_mux_t* om; epggrab_ota_mux_eit_plist_t *plist, *plist2; om = epggrab_ota_find_mux(dm); if (!om) return; - LIST_FOREACH(plist2, &om->om_eit_plist, link) + LIST_FOREACH (plist2, &om->om_eit_plist, link) if (plist2->priv == priv) return; tvhtrace(LS_TBL_EIT, "%s - detected module '%s'", src, priv->module->id); - plist = calloc(1, sizeof(*plist)); - plist->src = src; + plist = calloc(1, sizeof(*plist)); + plist->src = src; plist->priv = priv; LIST_INSERT_HEAD(&om->om_eit_plist, plist, link); om->om_detected = 1; } -void eit_nit_callback - (mpegts_table_t *mt, uint16_t nbid, const char *name, uint32_t nitpriv) -{ - mpegts_mux_t *dm = mt->mt_mux; - eit_nit_t *nit; - eit_private_t *priv = NULL; - - tvhtrace(LS_TBL_EIT, "NIT - tsid %04X (%d) onid %04X (%d) nbid %04X (%d) network name '%s' private %08X", - dm->mm_tsid, dm->mm_tsid, dm->mm_onid, dm->mm_onid, nbid, nbid, name, nitpriv); - - TAILQ_FOREACH(priv, &eit_private_list, link) { +void eit_nit_callback(mpegts_table_t* mt, uint16_t nbid, const char* name, uint32_t nitpriv) { + mpegts_mux_t* dm = mt->mt_mux; + eit_nit_t* nit; + eit_private_t* priv = NULL; + + tvhtrace(LS_TBL_EIT, + "NIT - tsid %04X (%d) onid %04X (%d) nbid %04X (%d) network name '%s' private %08X", + dm->mm_tsid, + dm->mm_tsid, + dm->mm_onid, + dm->mm_onid, + nbid, + nbid, + name, + nitpriv); + + TAILQ_FOREACH (priv, &eit_private_list, link) { if (priv->priv && priv->priv != nitpriv) continue; if (LIST_FIRST(&priv->nit)) { - LIST_FOREACH(nit, &priv->nit, link) { + LIST_FOREACH (nit, &priv->nit, link) { if (nit->name && strcmp(nit->name, name)) continue; if (eit_nit_array_check(dm->mm_onid, nit->onid, nit->onid_count)) @@ -1408,22 +1466,26 @@ void eit_nit_callback eit_queue_priv(dm, "NIT", priv); } -void eit_sdt_callback(mpegts_table_t *mt, uint32_t sdtpriv) -{ - mpegts_mux_t *dm = mt->mt_mux; - eit_sdt_t *sdt; - eit_private_t *priv = NULL; +void eit_sdt_callback(mpegts_table_t* mt, uint32_t sdtpriv) { + mpegts_mux_t* dm = mt->mt_mux; + eit_sdt_t* sdt; + eit_private_t* priv = NULL; - tvhtrace(LS_TBL_EIT, "SDT - tsid %04X (%d) onid %04X (%d) private %08X", - dm->mm_tsid, dm->mm_tsid, dm->mm_onid, dm->mm_onid, sdtpriv); + tvhtrace(LS_TBL_EIT, + "SDT - tsid %04X (%d) onid %04X (%d) private %08X", + dm->mm_tsid, + dm->mm_tsid, + dm->mm_onid, + dm->mm_onid, + sdtpriv); - TAILQ_FOREACH(priv, &eit_private_list, link) { + TAILQ_FOREACH (priv, &eit_private_list, link) { if (!priv->sdt_enable) continue; if (priv->priv && priv->priv != sdtpriv) continue; if (LIST_FIRST(&priv->sdt)) { - LIST_FOREACH(sdt, &priv->sdt, link) { + LIST_FOREACH (sdt, &priv->sdt, link) { if (eit_nit_array_check(dm->mm_onid, sdt->onid, sdt->onid_count)) continue; if (eit_nit_array_check(dm->mm_tsid, sdt->tsid, sdt->tsid_count)) @@ -1443,8 +1505,7 @@ void eit_sdt_callback(mpegts_table_t *mt, uint32_t sdtpriv) eit_queue_priv(dm, "SDT", priv); } -static void _eit_scrape_clear(eit_module_t *mod) -{ +static void _eit_scrape_clear(eit_module_t* mod) { eit_pattern_free_list(&mod->p_snum); eit_pattern_free_list(&mod->p_enum); eit_pattern_free_list(&mod->p_airdate); @@ -1454,8 +1515,7 @@ static void _eit_scrape_clear(eit_module_t *mod) eit_pattern_free_list(&mod->p_is_new); } -static int _eit_scrape_load_one ( htsmsg_t *m, eit_module_t* mod ) -{ +static int _eit_scrape_load_one(htsmsg_t* m, eit_module_t* mod) { if (mod->scrape_episode) { eit_pattern_compile_named_list(&mod->p_snum, m, "season_num"); eit_pattern_compile_named_list(&mod->p_enum, m, "episode_num"); @@ -1478,8 +1538,7 @@ static int _eit_scrape_load_one ( htsmsg_t *m, eit_module_t* mod ) return 1; } -static void _eit_module_load_config(eit_module_t *mod) -{ +static void _eit_module_load_config(eit_module_t* mod) { if (!mod->scrape_episode && !mod->scrape_subtitle) { tvhinfo(LS_TBL_EIT, "module %s - scraper disabled by config", mod->id); return; @@ -1490,13 +1549,13 @@ static void _eit_module_load_config(eit_module_t *mod) * Otherwise we default to using configuration based on the module * name such as "uk_freeview". */ - const char *config_file = mod->scrape_config && *mod->scrape_config ? - mod->scrape_config : mod->id; + const char* config_file = + mod->scrape_config && *mod->scrape_config ? mod->scrape_config : mod->id; tvhinfo(LS_TBL_EIT, "scraper %s attempt to load config \"%s\"", mod->id, config_file); - htsmsg_t *m = hts_settings_load(config_path, config_file); - char *generic_name = NULL; + htsmsg_t* m = hts_settings_load(config_path, config_file); + char* generic_name = NULL; if (!m) { /* No config file so try loading a generic config based on * the first component of the id. In the above case it would @@ -1505,12 +1564,12 @@ static void _eit_module_load_config(eit_module_t *mod) */ generic_name = strdup(config_file); if (generic_name) { - char *underscore = strstr(generic_name, "_"); + char* underscore = strstr(generic_name, "_"); if (underscore) { /* Terminate the string at the underscore */ *underscore = 0; config_file = generic_name; - m = hts_settings_load(config_path, config_file); + m = hts_settings_load(config_path, config_file); } } } @@ -1523,16 +1582,15 @@ static void _eit_module_load_config(eit_module_t *mod) tvhwarn(LS_TBL_EIT, "scraper %s failed to load config \"%s\"", mod->id, config_file); htsmsg_destroy(m); } else { - tvhinfo(LS_TBL_EIT, "scraper %s no scraper config files found", mod->id); + tvhinfo(LS_TBL_EIT, "scraper %s no scraper config files found", mod->id); } if (generic_name) free(generic_name); } -static void _eit_done0( eit_private_t *priv ) -{ - eit_nit_t *nit; +static void _eit_done0(eit_private_t* priv) { + eit_nit_t* nit; while ((nit = LIST_FIRST(&priv->nit)) != NULL) { LIST_REMOVE(nit, link); free(nit->name); @@ -1543,81 +1601,78 @@ static void _eit_done0( eit_private_t *priv ) free(priv); } -void _eit_done ( void *m ) -{ - eit_module_t *mod = m; - eit_private_t *priv = mod->opaque; +void _eit_done(void* m) { + eit_module_t* mod = m; + eit_private_t* priv = mod->opaque; _eit_scrape_clear(mod); mod->opaque = NULL; TAILQ_REMOVE(&eit_private_list, priv, link); _eit_done0(priv); } -static htsmsg_t * -epggrab_mod_eit_class_short_list ( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("Subtitle"), 0 }, - { N_("Summary"), 1 }, - { N_("Subtitle and summary"), 2 } - }; +static htsmsg_t* epggrab_mod_eit_class_short_list(void* o, const char* lang) { + static const struct strtab tab[] = {{N_("Subtitle"), 0}, + {N_("Summary"), 1}, + {N_("Subtitle and summary"), 2}}; return strtab2htsmsg(tab, 1, lang); } -static const idclass_t epggrab_mod_eit_class = { - .ic_super = &epggrab_mod_ota_scraper_class, - .ic_class = "epggrab_mod_eit", - .ic_caption = N_("Over-the-air EIT EPG grabber"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "short_target", - .name = N_("Short EIT description"), - .desc = N_("Set the short EIT destription to given target (subtitle, summary or both)."), - .off = offsetof(eit_module_t, short_target), - .list = epggrab_mod_eit_class_short_list, - .group = 1, - .opts = PO_EXPERT, - }, - { - .type = PT_BOOL, - .id = "running_immediate", - .name = N_("Running state immediately"), - .desc = N_("Handle the running state (EITp/f) immediately. " - "Usually, keep this off. It might increase " - "the recordings accuracy on very slow systems."), - .off = offsetof(eit_module_t, running_immediate), - .group = 1, - .opts = PO_EXPERT, - }, - {} - } -}; - -static eit_module_t *eit_module_ota_create - ( const char *id, int subsys, const char *saveid, - const char *name, int priority, - epggrab_ota_module_ops_t *ops ) -{ - eit_module_t * mod = (eit_module_t *) - epggrab_module_ota_create(calloc(1, sizeof(eit_module_t)), - id, subsys, saveid, name, priority, - &epggrab_mod_eit_class, ops); +static const idclass_t epggrab_mod_eit_class = {.ic_super = &epggrab_mod_ota_scraper_class, + .ic_class = "epggrab_mod_eit", + .ic_caption = N_("Over-the-air EIT EPG grabber"), + .ic_properties = (const property_t[]){ + { + .type = PT_INT, + .id = "short_target", + .name = N_("Short EIT description"), + .desc = + N_("Set the short EIT destription to given target (subtitle, summary or both)."), + .off = offsetof(eit_module_t, short_target), + .list = epggrab_mod_eit_class_short_list, + .group = 1, + .opts = PO_EXPERT, + }, + { + .type = PT_BOOL, + .id = "running_immediate", + .name = N_("Running state immediately"), + .desc = N_("Handle the running state (EITp/f) immediately. " + "Usually, keep this off. It might increase " + "the recordings accuracy on very slow systems."), + .off = offsetof(eit_module_t, running_immediate), + .group = 1, + .opts = PO_EXPERT, + }, + {}}}; + +static eit_module_t* eit_module_ota_create(const char* id, + int subsys, + const char* saveid, + const char* name, + int priority, + epggrab_ota_module_ops_t* ops) { + eit_module_t* mod = (eit_module_t*)epggrab_module_ota_create(calloc(1, sizeof(eit_module_t)), + id, + subsys, + saveid, + name, + priority, + &epggrab_mod_eit_class, + ops); return mod; } -static void eit_parse_list - ( htsmsg_t *conf, const char *fname, uint16_t *list, int list_len, int *count ) -{ - htsmsg_t *l = htsmsg_get_list(conf, fname); - htsmsg_field_t *f; - int val; +static void +eit_parse_list(htsmsg_t* conf, const char* fname, uint16_t* list, int list_len, int* count) { + htsmsg_t* l = htsmsg_get_list(conf, fname); + htsmsg_field_t* f; + int val; *count = 0; if (l == 0) { val = htsmsg_get_s32_or_default(conf, fname, -1); if (val >= 0) { list[0] = val; - *count = 1; + *count = 1; } return; } @@ -1632,37 +1687,36 @@ static void eit_parse_list } } -static void eit_init_one ( const char *id, htsmsg_t *conf ) -{ - epggrab_ota_module_ops_t *ops; - eit_private_t *priv; - eit_nit_t *nit; - eit_sdt_t *sdt; - const char *s; - htsmsg_t *map, *e; - htsmsg_field_t *f; - int prio = htsmsg_get_s32_or_default(conf, "prio", 1); - lang_str_t *name_str = lang_str_deserialize(conf, "name"); - - ops = calloc(1, sizeof(*ops)); - priv = calloc(1, sizeof(*priv)); - ops->start = _eit_start; - ops->handlers = _eit_install_handlers; - ops->done = _eit_done; - ops->activate = _eit_activate; +static void eit_init_one(const char* id, htsmsg_t* conf) { + epggrab_ota_module_ops_t* ops; + eit_private_t* priv; + eit_nit_t* nit; + eit_sdt_t* sdt; + const char* s; + htsmsg_t * map, *e; + htsmsg_field_t* f; + int prio = htsmsg_get_s32_or_default(conf, "prio", 1); + lang_str_t* name_str = lang_str_deserialize(conf, "name"); + + ops = calloc(1, sizeof(*ops)); + priv = calloc(1, sizeof(*priv)); + ops->start = _eit_start; + ops->handlers = _eit_install_handlers; + ops->done = _eit_done; + ops->activate = _eit_activate; ops->process_data = _eit_process_data; - ops->tune = _eit_tune; - ops->opaque = priv; - priv->ops = ops; - priv->pid = htsmsg_get_s32_or_default(conf, "pid", 0); - s = htsmsg_get_str(conf, "conv"); + ops->tune = _eit_tune; + ops->opaque = priv; + priv->ops = ops; + priv->pid = htsmsg_get_s32_or_default(conf, "pid", 0); + s = htsmsg_get_str(conf, "conv"); if (s && strcmp(s, "huffman") == 0) priv->conv = EIT_CONV_HUFFMAN; priv->priv = htsmsg_get_u32_or_default(conf, "priv", 0); - map = htsmsg_get_map(conf, "nit"); + map = htsmsg_get_map(conf, "nit"); if (map) { HTSMSG_FOREACH(f, map) { - nit = calloc(1, sizeof(*nit)); + nit = calloc(1, sizeof(*nit)); nit->name = htsmsg_field_name(f)[0] ? strdup(htsmsg_field_name(f)) : NULL; if ((e = htsmsg_field_get_map(f)) != NULL) { eit_parse_list(e, "onid", nit->onid, ARRAY_SIZE(nit->onid), &nit->onid_count); @@ -1673,7 +1727,7 @@ static void eit_init_one ( const char *id, htsmsg_t *conf ) } } priv->sdt_enable = htsmsg_get_u32_or_default(conf, "sdt_enable", 0); - map = htsmsg_get_map(conf, "sdt"); + map = htsmsg_get_map(conf, "sdt"); if (map) { HTSMSG_FOREACH(f, map) { sdt = calloc(1, sizeof(*sdt)); @@ -1689,7 +1743,8 @@ static void eit_init_one ( const char *id, htsmsg_t *conf ) HTSMSG_FOREACH(f, map) { if (strcmp(htsmsg_field_name(f), "slave") == 0) { s = htsmsg_field_get_str(f); - if (s) strncpy(priv->slave, s, sizeof(priv->slave) - 1); + if (s) + strncpy(priv->slave, s, sizeof(priv->slave) - 1); } else if (strcmp(htsmsg_field_name(f), "interest-4e") == 0) priv->hacks |= EIT_HACK_INTEREST4E; else if (strcmp(htsmsg_field_name(f), "extra-mux-lookup") == 0) @@ -1697,17 +1752,16 @@ static void eit_init_one ( const char *id, htsmsg_t *conf ) else if (strcmp(htsmsg_field_name(f), "svc-net-lookup") == 0) priv->hacks |= EIT_HACK_EXTRAMUXLOOKUP; else if (strcmp(htsmsg_field_name(f), "bat") == 0) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; priv->bat_pid = htsmsg_get_s32_or_default(e, "pid", 0); } } } priv->name = name_str; if (name_str) { - priv->module = (epggrab_module_ota_t *) - eit_module_ota_create(id, LS_TBL_EIT, NULL, - lang_str_get(name_str, NULL), - prio, ops); + priv->module = (epggrab_module_ota_t*) + eit_module_ota_create(id, LS_TBL_EIT, NULL, lang_str_get(name_str, NULL), prio, ops); TAILQ_INSERT_TAIL(&eit_private_list, priv, link); } else { tvherror(LS_TBL_EIT, "missing name for '%s' in config", id); @@ -1715,10 +1769,9 @@ static void eit_init_one ( const char *id, htsmsg_t *conf ) } } -void eit_init ( void ) -{ - htsmsg_field_t *f; - htsmsg_t *c, *e; +void eit_init(void) { + htsmsg_field_t* f; + htsmsg_t * c, *e; TAILQ_INIT(&eit_private_list); @@ -1728,44 +1781,41 @@ void eit_init ( void ) return; } HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; eit_init_one(htsmsg_field_name(f), e); } htsmsg_destroy(c); } -htsmsg_t *eit_module_id_list( const char *lang ) -{ +htsmsg_t* eit_module_id_list(const char* lang) { eit_private_t *priv, *priv2; - htsmsg_t *e, *l = htsmsg_create_list(); + htsmsg_t * e, *l = htsmsg_create_list(); - TAILQ_FOREACH(priv, &eit_private_list, link) { - TAILQ_FOREACH(priv2, &eit_private_list, link) + TAILQ_FOREACH (priv, &eit_private_list, link) { + TAILQ_FOREACH (priv2, &eit_private_list, link) if (strcmp(priv2->slave, priv->module->id) == 0) break; - if (priv2) continue; /* show only parents */ + if (priv2) + continue; /* show only parents */ e = htsmsg_create_key_val(priv->module->id, lang_str_get(priv->name, lang)); htsmsg_add_msg(l, NULL, e); } return l; } -const char *eit_check_module_id ( const char *id ) -{ - eit_private_t *priv; +const char* eit_check_module_id(const char* id) { + eit_private_t* priv; - if (!id) return NULL; - TAILQ_FOREACH(priv, &eit_private_list, link) { + if (!id) + return NULL; + TAILQ_FOREACH (priv, &eit_private_list, link) { if (strcmp(id, priv->module->id) == 0) return priv->module->id; } return NULL; } -void eit_done ( void ) -{ -} +void eit_done(void) {} -void eit_load ( void ) -{ -} +void eit_load(void) {} diff --git a/src/epggrab/module/eitpatternlist.c b/src/epggrab/module/eitpatternlist.c index 61176695b..bc6be461c 100644 --- a/src/epggrab/module/eitpatternlist.c +++ b/src/epggrab/module/eitpatternlist.c @@ -22,12 +22,11 @@ #include "eitpatternlist.h" #include "htsmsg.h" -#define MAX_TEXT_LEN 2048 +#define MAX_TEXT_LEN 2048 -static char *get_languages_string(htsmsg_field_t *field) -{ - const char *s; - htsmsg_t *langlist; +static char* get_languages_string(htsmsg_field_t* field) { + const char* s; + htsmsg_t* langlist; if (field == NULL) return NULL; @@ -38,10 +37,10 @@ static char *get_languages_string(htsmsg_field_t *field) } else { langlist = htsmsg_field_get_list(field); if (langlist) { - htsmsg_field_t *item; - char langbuf[MAX_TEXT_LEN]; - size_t l = 0; - langbuf[0] = '\0'; + htsmsg_field_t* item; + char langbuf[MAX_TEXT_LEN]; + size_t l = 0; + langbuf[0] = '\0'; HTSMSG_FOREACH(item, langlist) { s = htsmsg_field_get_str(item); if (s) @@ -54,32 +53,34 @@ static char *get_languages_string(htsmsg_field_t *field) return NULL; } -void eit_pattern_compile_list ( eit_pattern_list_t *list, htsmsg_t *l, int flags ) -{ - eit_pattern_t *pattern; - htsmsg_field_t *f; - const char *text; - int filter; - char *langs; +void eit_pattern_compile_list(eit_pattern_list_t* list, htsmsg_t* l, int flags) { + eit_pattern_t* pattern; + htsmsg_field_t* f; + const char* text; + int filter; + char* langs; TAILQ_INIT(list); - if (!l) return; + if (!l) + return; HTSMSG_FOREACH(f, l) { - text = htsmsg_field_get_str(f); + text = htsmsg_field_get_str(f); filter = 0; - langs = NULL; + langs = NULL; if (text == NULL) { - htsmsg_t *m = htsmsg_field_get_map(f); - if (m == NULL) continue; + htsmsg_t* m = htsmsg_field_get_map(f); + if (m == NULL) + continue; text = htsmsg_get_str(m, "pattern"); - if (text == NULL) continue; + if (text == NULL) + continue; filter = htsmsg_get_bool_or_default(m, "filter", 0); - langs = get_languages_string(htsmsg_field_find(m, "lang")); + langs = get_languages_string(htsmsg_field_find(m, "lang")); } - pattern = calloc(1, sizeof(eit_pattern_t)); - pattern->text = strdup(text); + pattern = calloc(1, sizeof(eit_pattern_t)); + pattern->text = strdup(text); pattern->filter = filter; - pattern->langs = langs; + pattern->langs = langs; if (regex_compile(&pattern->compiled, pattern->text, flags, LS_EPGGRAB)) { tvhwarn(LS_EPGGRAB, "error compiling pattern \"%s\"", pattern->text); free(pattern->langs); @@ -92,14 +93,13 @@ void eit_pattern_compile_list ( eit_pattern_list_t *list, htsmsg_t *l, int flags } } -void eit_pattern_compile_named_list ( eit_pattern_list_t *list, htsmsg_t *m, const char *key) -{ +void eit_pattern_compile_named_list(eit_pattern_list_t* list, htsmsg_t* m, const char* key) { #if defined(TVHREGEX_TYPE) - htsmsg_t *m_alt = htsmsg_get_map(m, TVHREGEX_TYPE); + htsmsg_t* m_alt = htsmsg_get_map(m, TVHREGEX_TYPE); if (!m_alt) m_alt = htsmsg_get_map(m, "pcre"); if (m_alt) { - htsmsg_t *res = htsmsg_get_list(m_alt, key); + htsmsg_t* res = htsmsg_get_list(m_alt, key); if (res) { eit_pattern_compile_list(list, res, 0); return; @@ -109,28 +109,31 @@ void eit_pattern_compile_named_list ( eit_pattern_list_t *list, htsmsg_t *m, con eit_pattern_compile_list(list, htsmsg_get_list(m, key), TVHREGEX_POSIX); } -static void rtrim(char *buf) -{ +static void rtrim(char* buf) { size_t len = strlen(buf); while (len > 0 && isspace(buf[len - 1])) --len; buf[len] = '\0'; } -void *eit_pattern_apply_list(char *buf, size_t size_buf, const char *text, const char *lang, eit_pattern_list_t *l) -{ - eit_pattern_t *p; - char textbuf[MAX_TEXT_LEN]; - char matchbuf[MAX_TEXT_LEN]; - int matchno; +void* eit_pattern_apply_list(char* buf, + size_t size_buf, + const char* text, + const char* lang, + eit_pattern_list_t* l) { + eit_pattern_t* p; + char textbuf[MAX_TEXT_LEN]; + char matchbuf[MAX_TEXT_LEN]; + int matchno; assert(buf); assert(text); - if (!l) return NULL; + if (!l) + return NULL; /* search and concatenate all subgroup matches - there must be at least one */ - TAILQ_FOREACH(p, l, p_links) { + TAILQ_FOREACH (p, l, p_links) { if (p->langs && lang) { if (strstr(p->langs, lang) == NULL) { continue; @@ -138,14 +141,14 @@ void *eit_pattern_apply_list(char *buf, size_t size_buf, const char *text, const } if (!regex_match(&p->compiled, text) && !regex_match_substring(&p->compiled, 1, buf, size_buf)) { - for (matchno = 2; ; ++matchno) { + for (matchno = 2;; ++matchno) { if (regex_match_substring(&p->compiled, matchno, matchbuf, sizeof(matchbuf))) break; size_t len = strlen(buf); strlcat(buf, matchbuf, size_buf - len); } rtrim(buf); - tvhtrace(LS_EPGGRAB," pattern \"%s\" matches '%s' from '%s'", p->text, buf, text); + tvhtrace(LS_EPGGRAB, " pattern \"%s\" matches '%s' from '%s'", p->text, buf, text); if (p->filter) { strlcpy(textbuf, buf, MAX_TEXT_LEN); text = textbuf; @@ -157,11 +160,11 @@ void *eit_pattern_apply_list(char *buf, size_t size_buf, const char *text, const return NULL; } -void eit_pattern_free_list ( eit_pattern_list_t *l ) -{ - eit_pattern_t *p; +void eit_pattern_free_list(eit_pattern_list_t* l) { + eit_pattern_t* p; - if (!l) return; + if (!l) + return; while ((p = TAILQ_FIRST(l)) != NULL) { TAILQ_REMOVE(l, p, p_links); free(p->langs); diff --git a/src/epggrab/module/eitpatternlist.h b/src/epggrab/module/eitpatternlist.h index 369206e95..d1bff9b05 100644 --- a/src/epggrab/module/eitpatternlist.h +++ b/src/epggrab/module/eitpatternlist.h @@ -22,30 +22,35 @@ #include "queue.h" #include "tvhregex.h" -typedef struct eit_pattern -{ - char *text; - tvh_regex_t compiled; - int filter; - char *langs; - TAILQ_ENTRY(eit_pattern) p_links; +typedef struct eit_pattern { + char* text; + tvh_regex_t compiled; + int filter; + char* langs; + TAILQ_ENTRY(eit_pattern) p_links; } eit_pattern_t; TAILQ_HEAD(eit_pattern_list, eit_pattern); typedef struct eit_pattern_list eit_pattern_list_t; /* is list empty? */ -static inline int eit_pattern_list_empty ( eit_pattern_list_t *list ) - { return TAILQ_EMPTY(list); } +static inline int eit_pattern_list_empty(eit_pattern_list_t* list) { + return TAILQ_EMPTY(list); +} /* Compile a regular expression pattern from a message */ -void eit_pattern_compile_list ( eit_pattern_list_t *list, htsmsg_t *l, int flags ); -/* Compile a regular expression pattern from a named message, applying message location conventions */ -void eit_pattern_compile_named_list ( eit_pattern_list_t *list, htsmsg_t *m, const char *key); +void eit_pattern_compile_list(eit_pattern_list_t* list, htsmsg_t* l, int flags); +/* Compile a regular expression pattern from a named message, applying message location conventions + */ +void eit_pattern_compile_named_list(eit_pattern_list_t* list, htsmsg_t* m, const char* key); /* Apply the compiled pattern to text. If it matches then return the * match in buf which is of size size_buf. * Return the buf or NULL if no match. */ -void *eit_pattern_apply_list(char *buf, size_t size_buf, const char *text, const char *lang, eit_pattern_list_t *l); -void eit_pattern_free_list ( eit_pattern_list_t *l ); +void* eit_pattern_apply_list(char* buf, + size_t size_buf, + const char* text, + const char* lang, + eit_pattern_list_t* l); +void eit_pattern_free_list(eit_pattern_list_t* l); #endif diff --git a/src/epggrab/module/opentv.c b/src/epggrab/module/opentv.c index c76507d3a..454a1aab0 100644 --- a/src/epggrab/module/opentv.c +++ b/src/epggrab/module/opentv.c @@ -45,64 +45,58 @@ typedef struct opentv_status opentv_status_t; /* Queued data */ -typedef struct opentv_data -{ +typedef struct opentv_data { int cid; int mjd; } opentv_data_t; /* Huffman dictionary */ -typedef struct opentv_dict -{ - char *id; - huffman_node_t *codes; +typedef struct opentv_dict { + char* id; + huffman_node_t* codes; RB_ENTRY(opentv_dict) h_link; } opentv_dict_t; -typedef struct opentv_genre -{ - char *id; - uint8_t map[256]; +typedef struct opentv_genre { + char* id; + uint8_t map[256]; RB_ENTRY(opentv_genre) h_link; } opentv_genre_t; /* Provider configuration */ -typedef struct opentv_module_t -{ - epggrab_module_ota_t ; ///< Base struct - - int onid; - int tsid; - int sid; - int bouquetid; - int bouquet_auto; - int *channel; - int *title; - int *summary; - opentv_dict_t *dict; - opentv_genre_t *genre; - int titles_time; - int summaries_time; - eit_pattern_list_t p_snum; - eit_pattern_list_t p_enum; - eit_pattern_list_t p_pnum; - eit_pattern_list_t p_subt; - eit_pattern_list_t p_cleanup_title; - opentv_status_t *sta; +typedef struct opentv_module_t { + epggrab_module_ota_t; ///< Base struct + + int onid; + int tsid; + int sid; + int bouquetid; + int bouquet_auto; + int* channel; + int* title; + int* summary; + opentv_dict_t* dict; + opentv_genre_t* genre; + int titles_time; + int summaries_time; + eit_pattern_list_t p_snum; + eit_pattern_list_t p_enum; + eit_pattern_list_t p_pnum; + eit_pattern_list_t p_subt; + eit_pattern_list_t p_cleanup_title; + opentv_status_t* sta; } opentv_module_t; /* * Dictionary list */ -RB_HEAD(, opentv_dict) _opentv_dicts; +RB_HEAD(, opentv_dict) _opentv_dicts; -static int _dict_cmp ( void *a, void *b ) -{ +static int _dict_cmp(void* a, void* b) { return strcmp(((opentv_dict_t*)a)->id, ((opentv_dict_t*)b)->id); } -static opentv_dict_t *_opentv_dict_find ( const char *id ) -{ +static opentv_dict_t* _opentv_dict_find(const char* id) { opentv_dict_t skel; skel.id = (char*)id; return RB_FIND(&_opentv_dicts, &skel, h_link, _dict_cmp); @@ -113,13 +107,11 @@ static opentv_dict_t *_opentv_dict_find ( const char *id ) */ RB_HEAD(, opentv_genre) _opentv_genres; -static int _genre_cmp ( void *a, void *b ) -{ +static int _genre_cmp(void* a, void* b) { return strcmp(((opentv_genre_t*)a)->id, ((opentv_genre_t*)b)->id); } -static opentv_genre_t *_opentv_genre_find ( const char *id ) -{ +static opentv_genre_t* _opentv_genre_find(const char* id) { opentv_genre_t skel; skel.id = (char*)id; return RB_FIND(&_opentv_genres, &skel, h_link, _genre_cmp); @@ -130,44 +122,40 @@ static opentv_genre_t *_opentv_genre_find ( const char *id ) * ***********************************************************************/ /* Internal event structure */ -typedef struct opentv_event -{ - uint16_t eid; ///< Events ID - time_t start; ///< Start time - time_t stop; ///< Event stop time - char *title; ///< Event title - char *summary; ///< Event summary - char *desc; ///< Event description - uint8_t cat; ///< Event category - uint16_t serieslink; ///< Series link ID - int cid; ///< Channel ID +typedef struct opentv_event { + uint16_t eid; ///< Events ID + time_t start; ///< Start time + time_t stop; ///< Event stop time + char* title; ///< Event title + char* summary; ///< Event summary + char* desc; ///< Event description + uint8_t cat; ///< Event category + uint16_t serieslink; ///< Series link ID + int cid; ///< Channel ID } opentv_event_t; /* Queued (unresolved) event entry */ typedef struct opentv_entry { - RB_ENTRY(opentv_entry) link; - opentv_event_t event; + RB_ENTRY(opentv_entry) link; + opentv_event_t event; } opentv_entry_t; /* Scan status */ -struct opentv_status -{ - opentv_module_t *os_mod; - epggrab_ota_map_t *os_map; - int os_refcount; - epggrab_ota_mux_t *os_ota; - int64_t os_titles_start; - int64_t os_summaries_start; +struct opentv_status { + opentv_module_t* os_mod; + epggrab_ota_map_t* os_map; + int os_refcount; + epggrab_ota_mux_t* os_ota; + int64_t os_titles_start; + int64_t os_summaries_start; RB_HEAD(, opentv_entry) os_entries; }; -static void opentv_remove_entry(opentv_status_t *sta, opentv_entry_t *entry); +static void opentv_remove_entry(opentv_status_t* sta, opentv_entry_t* entry); -static void -opentv_status_destroy ( mpegts_table_t *mt ) -{ - opentv_status_t *st = mt->mt_opaque; - opentv_entry_t *entry; +static void opentv_status_destroy(mpegts_table_t* mt) { + opentv_status_t* st = mt->mt_opaque; + opentv_entry_t* entry; lock_assert(&global_lock); assert(st->os_refcount > 0); --st->os_refcount; @@ -183,9 +171,8 @@ opentv_status_destroy ( mpegts_table_t *mt ) * EPG Object wrappers * ***********************************************************************/ -static epggrab_channel_t *_opentv_find_epggrab_channel - ( opentv_module_t *mod, int cid, int create, int *save ) -{ +static epggrab_channel_t* +_opentv_find_epggrab_channel(opentv_module_t* mod, int cid, int create, int* save) { char chid[256]; snprintf(chid, sizeof(chid), "%s-%d", mod->id, cid); return epggrab_channel_find((epggrab_module_t*)mod, chid, create, save); @@ -196,42 +183,37 @@ static epggrab_channel_t *_opentv_find_epggrab_channel * ***********************************************************************/ /* Free the event */ -static void _opentv_event_free(opentv_event_t *ev) -{ +static void _opentv_event_free(opentv_event_t* ev) { free(ev->title); free(ev->summary); free(ev->desc); } /* Compare event id and channel id codes */ -static int _entry_cmp ( void *a, void *b ) -{ +static int _entry_cmp(void* a, void* b) { int eid_cmp, cid_cmp; - eid_cmp = (int)(((opentv_entry_t*)a)->event.eid) - - (int)(((opentv_entry_t*)b)->event.eid); + eid_cmp = (int)(((opentv_entry_t*)a)->event.eid) - (int)(((opentv_entry_t*)b)->event.eid); - cid_cmp = ((opentv_entry_t*)a)->event.cid - - ((opentv_entry_t*)b)->event.cid; + cid_cmp = ((opentv_entry_t*)a)->event.cid - ((opentv_entry_t*)b)->event.cid; return eid_cmp != 0 ? eid_cmp : cid_cmp; } /* Find event entry */ -static opentv_entry_t *opentv_find_entry(opentv_status_t *sta, uint16_t eid, int cid) -{ +static opentv_entry_t* opentv_find_entry(opentv_status_t* sta, uint16_t eid, int cid) { opentv_entry_t *oe, _tmp; - if (sta == NULL) return NULL; + if (sta == NULL) + return NULL; _tmp.event.eid = eid; _tmp.event.cid = cid; - oe = RB_FIND(&sta->os_entries, &_tmp, link, _entry_cmp); + oe = RB_FIND(&sta->os_entries, &_tmp, link, _entry_cmp); return oe; } /* Remove event entry */ -static void opentv_remove_entry(opentv_status_t *sta, opentv_entry_t *entry) -{ +static void opentv_remove_entry(opentv_status_t* sta, opentv_entry_t* entry) { if (entry) { RB_REMOVE(&sta->os_entries, entry, link); _opentv_event_free(&entry->event); @@ -240,14 +222,14 @@ static void opentv_remove_entry(opentv_status_t *sta, opentv_entry_t *entry) } /* Add event entry */ -static void opentv_add_entry(opentv_status_t *sta, opentv_event_t *ev) -{ - if (sta == NULL) return; +static void opentv_add_entry(opentv_status_t* sta, opentv_event_t* ev) { + if (sta == NULL) + return; opentv_entry_t *entry, *nentry = calloc(1, sizeof(*nentry)); nentry->event = *ev; - entry = RB_INSERT_SORTED(&sta->os_entries, nentry, link, _entry_cmp); + entry = RB_INSERT_SORTED(&sta->os_entries, nentry, link, _entry_cmp); if (entry) { _opentv_event_free(&entry->event); entry->event = *ev; @@ -257,18 +239,17 @@ static void opentv_add_entry(opentv_status_t *sta, opentv_event_t *ev) } /* Parse huffman encoded string */ -static char *_opentv_parse_string - ( opentv_module_t *prov, const uint8_t *buf, int len ) -{ - int ok = 0; +static char* _opentv_parse_string(opentv_module_t* prov, const uint8_t* buf, int len) { + int ok = 0; char *ret, *tmp; - if (len <= 0) return NULL; + if (len <= 0) + return NULL; // Note: unlikely decoded string will be longer (though its possible) - ret = tmp = malloc(2*len); - *ret = 0; - if (huffman_decode(prov->dict->codes, buf, len, 0x20, tmp, 2*len)) { + ret = tmp = malloc(2 * len); + *ret = 0; + if (huffman_decode(prov->dict->codes, buf, len, 0x20, tmp, 2 * len)) { /* Ignore (empty) strings */ while (*tmp) { @@ -287,42 +268,41 @@ static char *_opentv_parse_string } /* Parse a specific record */ -static int _opentv_parse_event_record - ( opentv_module_t *prov, opentv_event_t *ev, - const uint8_t *buf, int len, - time_t mjd ) -{ +static int _opentv_parse_event_record(opentv_module_t* prov, + opentv_event_t* ev, + const uint8_t* buf, + int len, + time_t mjd) { uint8_t rtag = buf[0]; - int rlen = buf[1]; - if (rlen+2 > len) + int rlen = buf[1]; + if (rlen + 2 > len) return -1; - if (rlen+2 <= len) { + if (rlen + 2 <= len) { switch (rtag) { case 0xb5: // title if (rlen >= 7) { - ev->start = (((int)buf[2] << 9) | (buf[3] << 1)) - + mjd; - ev->stop = (((int)buf[4] << 9) | (buf[5] << 1)) - + ev->start; - ev->cat = buf[6]; + ev->start = (((int)buf[2] << 9) | (buf[3] << 1)) + mjd; + ev->stop = (((int)buf[4] << 9) | (buf[5] << 1)) + ev->start; + ev->cat = buf[6]; if (prov->genre) ev->cat = prov->genre->map[ev->cat]; if (!ev->title) { - ev->title = _opentv_parse_string(prov, buf+9, rlen-7); + ev->title = _opentv_parse_string(prov, buf + 9, rlen - 7); if (!strcmp(prov->dict->id, "skynz")) { - if ((strlen(ev->title) >= 6) && (ev->title[0] == '[') && (ev->title[1] == '[') && (ev->title[4] == ']') && (ev->title[5] == ']')) - memmove(ev->title,ev->title+6,strlen(ev->title)-5); - } - } + if ((strlen(ev->title) >= 6) && (ev->title[0] == '[') && (ev->title[1] == '[') && + (ev->title[4] == ']') && (ev->title[5] == ']')) + memmove(ev->title, ev->title + 6, strlen(ev->title) - 5); + } + } } break; case 0xb9: // summary if (!ev->summary) - ev->summary = _opentv_parse_string(prov, buf+2, rlen); + ev->summary = _opentv_parse_string(prov, buf + 2, rlen); break; case 0xbb: // description if (!ev->desc) - ev->desc = _opentv_parse_string(prov, buf+2, rlen); + ev->desc = _opentv_parse_string(prov, buf + 2, rlen); break; case 0xc1: // series link if (!ev->serieslink) @@ -336,42 +316,43 @@ static int _opentv_parse_event_record } /* Parse a specific event */ -static int _opentv_parse_event - ( opentv_module_t *prov, - const uint8_t *buf, int len, int cid, time_t mjd, - opentv_event_t *ev ) -{ - int slen = (((int)buf[2] & 0xf) << 8) | buf[3]; - int i = 4, r; - - if (slen+4 > len) { - tvhtrace(LS_OPENTV, "event len (%d) > table len (%d)", slen+4, len); +static int _opentv_parse_event(opentv_module_t* prov, + const uint8_t* buf, + int len, + int cid, + time_t mjd, + opentv_event_t* ev) { + int slen = (((int)buf[2] & 0xf) << 8) | buf[3]; + int i = 4, r; + + if (slen + 4 > len) { + tvhtrace(LS_OPENTV, "event len (%d) > table len (%d)", slen + 4, len); return -1; } ev->eid = ((uint16_t)buf[0] << 8) | buf[1]; ev->cid = cid; - /* Process records */ - while (i < slen+4) { - r = _opentv_parse_event_record(prov, ev, buf+i, len-i, mjd); + /* Process records */ + while (i < slen + 4) { + r = _opentv_parse_event_record(prov, ev, buf + i, len - i, mjd); if (r < 0) return -1; i += r; } - return slen+4; + return slen + 4; } /* Add entry */ -static int -opentv_do_event - (opentv_module_t *mod, epg_broadcast_t *ebc, - opentv_event_t *ev, channel_t *ch, - const char *lang, epg_changes_t *changes) -{ - int save = 0; - lang_str_t *ls; - char buffer[2048], *s; +static int opentv_do_event(opentv_module_t* mod, + epg_broadcast_t* ebc, + opentv_event_t* ev, + channel_t* ch, + const char* lang, + epg_changes_t* changes) { + int save = 0; + lang_str_t* ls; + char buffer[2048], *s; /* Summary / Description */ if (ev->summary) { @@ -393,8 +374,11 @@ opentv_do_event if (ev->serieslink) { char suri[257], ubuf[UUID_HEX_SIZE]; - snprintf(suri, 256, "opentv://channel-%s/series-%d", - channel_get_uuid(ch, ubuf), ev->serieslink); + snprintf(suri, + 256, + "opentv://channel-%s/series-%d", + channel_get_uuid(ch, ubuf), + ev->serieslink); save |= epg_broadcast_set_serieslink_uri(ebc, suri, changes); } @@ -417,7 +401,7 @@ opentv_do_event lang_str_destroy(ls); } if (ev->cat) { - epg_genre_list_t *egl = calloc(1, sizeof(epg_genre_list_t)); + epg_genre_list_t* egl = calloc(1, sizeof(epg_genre_list_t)); epg_genre_list_add_by_eit(egl, ev->cat); save |= epg_broadcast_set_genre(ebc, egl, changes); epg_genre_list_destroy(egl); @@ -429,20 +413,19 @@ opentv_do_event /* search for season number */ if (eit_pattern_apply_list(buffer, sizeof(buffer), ev->summary, lang, &mod->p_snum)) if ((en.s_num = atoi(buffer))) - tvhtrace(LS_OPENTV," extract season number %d", en.s_num); + tvhtrace(LS_OPENTV, " extract season number %d", en.s_num); /* ...for episode number */ if (eit_pattern_apply_list(buffer, sizeof(buffer), ev->summary, lang, &mod->p_enum)) if ((en.e_num = atoi(buffer))) - tvhtrace(LS_OPENTV," extract episode number %d", en.e_num); + tvhtrace(LS_OPENTV, " extract episode number %d", en.e_num); /* ...for part number */ if (eit_pattern_apply_list(buffer, sizeof(buffer), ev->summary, lang, &mod->p_pnum)) { if (buffer[0] >= 'a' && buffer[0] <= 'z') en.p_num = buffer[0] - 'a' + 1; - else - if (buffer[0] >= 'A' && buffer[0] <= 'Z') - en.p_num = buffer[0] - 'A' + 1; + else if (buffer[0] >= 'A' && buffer[0] <= 'Z') + en.p_num = buffer[0] - 'A' + 1; if (en.p_num) - tvhtrace(LS_OPENTV," extract part number %d", en.p_num); + tvhtrace(LS_OPENTV, " extract part number %d", en.p_num); } /* save any found number */ if (en.s_num || en.e_num || en.p_num) @@ -461,25 +444,27 @@ opentv_do_event } /* Parse an event section */ -static int -opentv_parse_event_section_one - ( opentv_module_t *mod, int cid, int mjd, - channel_t *ch, const char *lang, - const uint8_t *buf, int len ) -{ - int i, r, save = 0, merge; - epggrab_module_t *src = (epggrab_module_t*)mod; - epg_broadcast_t *ebc; - opentv_event_t ev; - opentv_entry_t *entry; - epg_changes_t changes; +static int opentv_parse_event_section_one(opentv_module_t* mod, + int cid, + int mjd, + channel_t* ch, + const char* lang, + const uint8_t* buf, + int len) { + int i, r, save = 0, merge; + epggrab_module_t* src = (epggrab_module_t*)mod; + epg_broadcast_t* ebc; + opentv_event_t ev; + opentv_entry_t* entry; + epg_changes_t changes; /* Loop around event entries */ i = 7; while (i < len) { memset(&ev, 0, sizeof(opentv_event_t)); - r = _opentv_parse_event(mod, buf+i, len-i, cid, mjd, &ev); - if (r < 0) break; + r = _opentv_parse_event(mod, buf + i, len - i, cid, mjd, &ev); + if (r < 0) + break; i += r; /* @@ -493,15 +478,19 @@ opentv_parse_event_section_one /* Find broadcast */ if (ev.start && ev.stop) { - ebc = epg_broadcast_find_by_time(ch, src, ev.start, ev.stop, - 1, &save, &changes); - tvhdebug(LS_OPENTV, "find by time start %"PRItime_t " stop " - "%"PRItime_t " ch %"PRId64" eid %d = %p", - ev.start, ev.stop, ch->ch_number, ev.eid, ebc); + ebc = epg_broadcast_find_by_time(ch, src, ev.start, ev.stop, 1, &save, &changes); + tvhdebug(LS_OPENTV, + "find by time start %" PRItime_t " stop " + "%" PRItime_t " ch %" PRId64 " eid %d = %p", + ev.start, + ev.stop, + ch->ch_number, + ev.eid, + ebc); save |= epg_broadcast_set_dvb_eid(ebc, ev.eid, &changes); } else { ebc = epg_broadcast_find_by_eid(ch, ev.eid); - tvhdebug(LS_OPENTV, "find by ch %"PRId64" eid %d = %p", ch->ch_number, ev.eid, ebc); + tvhdebug(LS_OPENTV, "find by ch %" PRId64 " eid %d = %p", ch->ch_number, ev.eid, ebc); if (ebc) { if (ebc->grabber != src) goto done; @@ -525,7 +514,7 @@ opentv_parse_event_section_one } /* Cleanup */ -done: + done: _opentv_event_free(&ev); } @@ -533,43 +522,42 @@ done: } static int -opentv_parse_event_section - ( opentv_module_t *mod, int cid, int mjd, - const uint8_t *buf, int len ) -{ - channel_t *ch; - epggrab_channel_t *ec; - idnode_list_mapping_t *ilm; - const char *lang = NULL; - int save = 0; +opentv_parse_event_section(opentv_module_t* mod, int cid, int mjd, const uint8_t* buf, int len) { + channel_t* ch; + epggrab_channel_t* ec; + idnode_list_mapping_t* ilm; + const char* lang = NULL; + int save = 0; /* Get language (bit of a hack) */ - if (!strcmp(mod->dict->id, "skyit")) lang = "it"; - else if (!strcmp(mod->dict->id, "skyeng")) lang = "eng"; - else if (!strcmp(mod->dict->id, "skynz")) lang = "eng"; + if (!strcmp(mod->dict->id, "skyit")) + lang = "it"; + else if (!strcmp(mod->dict->id, "skyeng")) + lang = "eng"; + else if (!strcmp(mod->dict->id, "skynz")) + lang = "eng"; /* Channel */ - if (!(ec = _opentv_find_epggrab_channel(mod, cid, 0, NULL))) return 0; + if (!(ec = _opentv_find_epggrab_channel(mod, cid, 0, NULL))) + return 0; /* Iterate all channels */ - LIST_FOREACH(ilm, &ec->channels, ilm_in2_link) { - ch = (channel_t *)ilm->ilm_in2; - if (!ch->ch_enabled || ch->ch_epg_parent) continue; - save |= opentv_parse_event_section_one(mod, cid, mjd, ch, - lang, buf, len); + LIST_FOREACH (ilm, &ec->channels, ilm_in2_link) { + ch = (channel_t*)ilm->ilm_in2; + if (!ch->ch_enabled || ch->ch_epg_parent) + continue; + save |= opentv_parse_event_section_one(mod, cid, mjd, ch, lang, buf, len); } /* Update EPG */ - if (save) epg_updated(); + if (save) + epg_updated(); return 0; } -static void -_opentv_process_data - ( void *m, void *data, uint32_t len ) -{ - opentv_module_t *mod = m; - opentv_data_t od; +static void _opentv_process_data(void* m, void* data, uint32_t len) { + opentv_module_t* mod = m; + opentv_data_t od; assert(len >= sizeof(od)); memcpy(&od, data, sizeof(od)); @@ -577,36 +565,44 @@ _opentv_process_data len -= sizeof(od); tvh_mutex_lock(&global_lock); opentv_parse_event_section(mod, od.cid, od.mjd, data, len); - tvh_mutex_unlock(&global_lock); + tvh_mutex_unlock(&global_lock); } /* ************************************************************************ * OpenTV channel processing * ***********************************************************************/ -static int -opentv_desc_channels - ( mpegts_table_t *mt, mpegts_mux_t *mm, uint16_t nbid, - const uint8_t dtag, const uint8_t *buf, int len ) -{ - opentv_status_t *sta = mt->mt_opaque; - opentv_module_t *mod = sta->os_mod; - epggrab_channel_t *ec; - idnode_list_mapping_t *ilm; - mpegts_service_t *svc; - channel_t *ch; - int sid, cid, cnum, unk; - int type; - int save = 0; - int i = 2; +static int opentv_desc_channels(mpegts_table_t* mt, + mpegts_mux_t* mm, + uint16_t nbid, + const uint8_t dtag, + const uint8_t* buf, + int len) { + opentv_status_t* sta = mt->mt_opaque; + opentv_module_t* mod = sta->os_mod; + epggrab_channel_t* ec; + idnode_list_mapping_t* ilm; + mpegts_service_t* svc; + channel_t* ch; + int sid, cid, cnum, unk; + int type; + int save = 0; + int i = 2; while (i < len) { - sid = ((int)buf[i] << 8) | buf[i+1]; + sid = ((int)buf[i] << 8) | buf[i + 1]; type = buf[2]; - cid = ((int)buf[i+3] << 8) | buf[i+4]; - cnum = ((int)buf[i+5] << 8) | buf[i+6]; - unk = ((int)buf[i+7] << 8) | buf[i+8]; - tvhtrace(LS_OPENTV, "%s: sid %04X type %02X cid %04X cnum %d unk %04X", mt->mt_name, sid, type, cid, cnum, unk); + cid = ((int)buf[i + 3] << 8) | buf[i + 4]; + cnum = ((int)buf[i + 5] << 8) | buf[i + 6]; + unk = ((int)buf[i + 7] << 8) | buf[i + 8]; + tvhtrace(LS_OPENTV, + "%s: sid %04X type %02X cid %04X cnum %d unk %04X", + mt->mt_name, + sid, + type, + cid, + cnum, + unk); cnum = cnum < 65535 ? cnum : 0; /* Find the service */ @@ -624,24 +620,28 @@ opentv_desc_channels } else goto skip_chnum; } - tvhtrace(LS_OPENTV, "%s: cnum changed (%i != %i)", mt->mt_name, cnum, (int)svc->s_dvb_opentv_chnum); + tvhtrace(LS_OPENTV, + "%s: cnum changed (%i != %i)", + mt->mt_name, + cnum, + (int)svc->s_dvb_opentv_chnum); svc->s_dvb_opentv_chnum = cnum; - svc->s_dvb_opentv_id = unk; + svc->s_dvb_opentv_id = unk; mpegts_network_bouquet_trigger(mm->mm_network, 0); - service_request_save((service_t *)svc); + service_request_save((service_t*)svc); } -skip_chnum: + skip_chnum: if (svc && LIST_FIRST(&svc->s_channels)) { - ec =_opentv_find_epggrab_channel(mod, cid, 1, &save); + ec = _opentv_find_epggrab_channel(mod, cid, 1, &save); ilm = LIST_FIRST(&ec->channels); - ch = (channel_t *)LIST_FIRST(&svc->s_channels)->ilm_in2; + ch = (channel_t*)LIST_FIRST(&svc->s_channels)->ilm_in2; tvhtrace(mt->mt_subsys, "%s: ec = %p, ilm = %p", mt->mt_name, ec, ilm); if (ilm && ilm->ilm_in2 != &ch->ch_id) { epggrab_channel_link_delete(ec, ch, 1); ilm = NULL; } - + if (!ilm && ec->enabled) epggrab_channel_link(ec, ch, NULL); save |= epggrab_channel_set_number(ec, cnum, 0); @@ -652,27 +652,26 @@ skip_chnum: return 0; } -static int -opentv_table_callback - ( mpegts_table_t *mt, const uint8_t *buf, int len, int tableid ) -{ - int r = 1; - int sect, last, ver; - opentv_data_t od; - mpegts_psi_table_state_t *st; - opentv_status_t *sta; - opentv_module_t *mod; - epggrab_ota_mux_t *ota; - th_subscription_t *ths; - - if (!epggrab_ota_running) return -1; +static int opentv_table_callback(mpegts_table_t* mt, const uint8_t* buf, int len, int tableid) { + int r = 1; + int sect, last, ver; + opentv_data_t od; + mpegts_psi_table_state_t* st; + opentv_status_t* sta; + opentv_module_t* mod; + epggrab_ota_mux_t* ota; + th_subscription_t* ths; + + if (!epggrab_ota_running) + return -1; sta = mt->mt_opaque; mod = sta->os_mod; ota = sta->os_ota; /* Validate */ - if (len < 7) return -1; + if (len < 7) + return -1; /* Extra ID */ od.cid = ((int)buf[0] << 8) | buf[1]; @@ -686,25 +685,36 @@ opentv_table_callback subscription_add_bytes_out(ths, len); } - /* Begin */ - r = dvb_table_begin((mpegts_psi_table_t *)mt, buf, len, - tableid, (uint64_t)(od.cid) << 32 | od.mjd, 7, - &st, §, &last, &ver, 0); - if (r != 1) goto done; + r = dvb_table_begin((mpegts_psi_table_t*)mt, + buf, + len, + tableid, + (uint64_t)(od.cid) << 32 | od.mjd, + 7, + &st, + §, + &last, + &ver, + 0); + if (r != 1) + goto done; /* Process */ - epggrab_queue_data((epggrab_module_t *)mod, &od, sizeof(od), buf, len); + epggrab_queue_data((epggrab_module_t*)mod, &od, sizeof(od), buf, len); /* End */ - r = dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + r = dvb_table_end((mpegts_psi_table_t*)mt, st, sect); /* Complete */ done: if (!r) { sta->os_map->om_first = 0; /* valid data mark */ - tvhtrace(mt->mt_subsys, "%s: pid %d complete remain %d", - mt->mt_name, mt->mt_pid, sta->os_refcount-1); + tvhtrace(mt->mt_subsys, + "%s: pid %d complete remain %d", + mt->mt_name, + mt->mt_pid, + sta->os_refcount - 1); /* wait for more data, eat whole time window */ if (mt->mt_table == OPENTV_TITLE_BASE) { @@ -714,7 +724,7 @@ done: if (sta->os_summaries_start + sec2mono(mod->summaries_time) >= mclk()) return 0; } - + /* Last PID */ if (sta->os_refcount == 1) { if (mt->mt_table == OPENTV_TITLE_BASE) { @@ -732,17 +742,15 @@ done: return 0; } -static int -opentv_bat_callback - ( mpegts_table_t *mt, const uint8_t *buf, int len, int tableid ) -{ - int *t, r; - opentv_status_t *sta; - opentv_module_t *mod; - epggrab_ota_mux_t *ota; - th_subscription_t *ths; +static int opentv_bat_callback(mpegts_table_t* mt, const uint8_t* buf, int len, int tableid) { + int * t, r; + opentv_status_t* sta; + opentv_module_t* mod; + epggrab_ota_mux_t* ota; + th_subscription_t* ths; - if (!epggrab_ota_running) return -1; + if (!epggrab_ota_running) + return -1; sta = mt->mt_opaque; mod = sta->os_mod; @@ -759,8 +767,7 @@ opentv_bat_callback /* Register */ if (!ota) { - sta->os_ota = ota - = epggrab_ota_register((epggrab_module_ota_t*)mod, NULL, mt->mt_mux); + sta->os_ota = ota = epggrab_ota_register((epggrab_module_ota_t*)mod, NULL, mt->mt_mux); } /* Complete */ @@ -770,12 +777,17 @@ opentv_bat_callback /* Install event handlers */ t = mod->title; while (*t) { - mpegts_table_t *mt2; + mpegts_table_t* mt2; mt2 = mpegts_table_add(mt->mt_mux, - OPENTV_TITLE_BASE, OPENTV_TABLE_MASK, - opentv_table_callback, mt->mt_opaque, - mod->id, LS_OPENTV, MT_CRC, *t++, - MPS_WEIGHT_EIT); + OPENTV_TITLE_BASE, + OPENTV_TABLE_MASK, + opentv_table_callback, + mt->mt_opaque, + mod->id, + LS_OPENTV, + MT_CRC, + *t++, + MPS_WEIGHT_EIT); if (mt2) { if (!mt2->mt_destroy) { sta->os_refcount++; @@ -788,12 +800,17 @@ opentv_bat_callback /* Install tables for summaries */ t = mod->summary; while (*t) { - mpegts_table_t *mt2; + mpegts_table_t* mt2; mt2 = mpegts_table_add(mt->mt_mux, - OPENTV_SUMMARY_BASE, OPENTV_TABLE_MASK, - opentv_table_callback, sta, - mod->id, LS_OPENTV, MT_CRC, *t++, - MPS_WEIGHT_EIT); + OPENTV_SUMMARY_BASE, + OPENTV_TABLE_MASK, + opentv_table_callback, + sta, + mod->id, + LS_OPENTV, + MT_CRC, + *t++, + MPS_WEIGHT_EIT); if (mt2) { sta->os_refcount++; mt2->mt_destroy = opentv_status_destroy; @@ -812,37 +829,40 @@ opentv_bat_callback * Module callbacks * ***********************************************************************/ -static int _opentv_start - ( epggrab_ota_map_t *map, mpegts_mux_t *mm ) -{ - int *t; - opentv_module_t *mod = (opentv_module_t*)map->om_module; - epggrab_module_ota_t *m = map->om_module; - opentv_status_t *sta = NULL; - mpegts_table_t *mt; - static struct mpegts_table_mux_cb bat_desc[] = { - { .tag = 0xB1, .cb = opentv_desc_channels }, - { .tag = 0x00, .cb = NULL } - }; +static int _opentv_start(epggrab_ota_map_t* map, mpegts_mux_t* mm) { + int* t; + opentv_module_t* mod = (opentv_module_t*)map->om_module; + epggrab_module_ota_t* m = map->om_module; + opentv_status_t* sta = NULL; + mpegts_table_t* mt; + static struct mpegts_table_mux_cb bat_desc[] = {{.tag = 0xB1, .cb = opentv_desc_channels}, + {.tag = 0x00, .cb = NULL}}; /* Ignore */ - if (mod->tsid != mm->mm_tsid) return -1; + if (mod->tsid != mm->mm_tsid) + return -1; /* Install tables */ tvhdebug(mod->subsys, "%s: install table handlers", mod->id); /* Channels */ - t = mod->channel; + t = mod->channel; while (*t) { if (!sta) { - sta = calloc(1, sizeof(opentv_status_t)); + sta = calloc(1, sizeof(opentv_status_t)); sta->os_mod = mod; sta->os_map = map; } - mt = mpegts_table_add(mm, DVB_BAT_BASE, DVB_BAT_MASK, - opentv_bat_callback, sta, - m->id, LS_OPENTV, MT_CRC, *t++, - MPS_WEIGHT_EIT); + mt = mpegts_table_add(mm, + DVB_BAT_BASE, + DVB_BAT_MASK, + opentv_bat_callback, + sta, + m->id, + LS_OPENTV, + MT_CRC, + *t++, + MPS_WEIGHT_EIT); if (mt) { mt->mt_mux_cb = bat_desc; if (!mt->mt_destroy) { @@ -866,52 +886,51 @@ static int _opentv_start * Configuration * ***********************************************************************/ -static int* _pid_list_to_array ( htsmsg_t *m ) -{ - int i = 1; - int *ret; - htsmsg_field_t *f; - HTSMSG_FOREACH(f, m) - if (f->hmf_s64) i++; +static int* _pid_list_to_array(htsmsg_t* m) { + int i = 1; + int* ret; + htsmsg_field_t* f; + HTSMSG_FOREACH(f, m) + if (f->hmf_s64) + i++; ret = calloc(i, sizeof(int)); i = 0; - HTSMSG_FOREACH(f, m) - if (f->hmf_s64) { - ret[i] = (int)f->hmf_s64; - i++; - } + HTSMSG_FOREACH(f, m) + if (f->hmf_s64) { + ret[i] = (int)f->hmf_s64; + i++; + } return ret; } -static int _opentv_genre_load_one ( const char *id, htsmsg_t *m ) -{ - htsmsg_field_t *f; - opentv_genre_t *genre = calloc(1, sizeof(opentv_genre_t)); - genre->id = (char*)id; +static int _opentv_genre_load_one(const char* id, htsmsg_t* m) { + htsmsg_field_t* f; + opentv_genre_t* genre = calloc(1, sizeof(opentv_genre_t)); + genre->id = (char*)id; if (RB_INSERT_SORTED(&_opentv_genres, genre, h_link, _genre_cmp)) { tvhdebug(LS_OPENTV, "ignore duplicate genre map %s", id); free(genre); return 0; } else { genre->id = strdup(id); - int i = 0; + int i = 0; HTSMSG_FOREACH(f, m) { genre->map[i] = (uint8_t)f->hmf_s64; - if (++i == 256) break; + if (++i == 256) + break; } } return 1; } -static void _opentv_genre_load ( htsmsg_t *m ) -{ - int r; - htsmsg_t *e; - htsmsg_field_t *f; +static void _opentv_genre_load(htsmsg_t* m) { + int r; + htsmsg_t* e; + htsmsg_field_t* f; HTSMSG_FOREACH(f, m) { if ((e = htsmsg_get_list(m, htsmsg_field_name(f)))) { if ((r = _opentv_genre_load_one(htsmsg_field_name(f), e))) { - if (r > 0) + if (r > 0) tvhdebug(LS_OPENTV, "genre map %s loaded", htsmsg_field_name(f)); else tvhwarn(LS_OPENTV, "genre map %s failed", htsmsg_field_name(f)); @@ -921,10 +940,9 @@ static void _opentv_genre_load ( htsmsg_t *m ) htsmsg_destroy(m); } -static int _opentv_dict_load_one ( const char *id, htsmsg_t *m ) -{ - opentv_dict_t *dict = calloc(1, sizeof(opentv_dict_t)); - dict->id = (char*)id; +static int _opentv_dict_load_one(const char* id, htsmsg_t* m) { + opentv_dict_t* dict = calloc(1, sizeof(opentv_dict_t)); + dict->id = (char*)id; if (RB_INSERT_SORTED(&_opentv_dicts, dict, h_link, _dict_cmp)) { tvhdebug(LS_OPENTV, "ignore duplicate dictionary %s", id); free(dict); @@ -942,28 +960,25 @@ static int _opentv_dict_load_one ( const char *id, htsmsg_t *m ) } } -static void _opentv_dict_load ( htsmsg_t *m ) -{ - int r; - htsmsg_t *e; - htsmsg_field_t *f; +static void _opentv_dict_load(htsmsg_t* m) { + int r; + htsmsg_t* e; + htsmsg_field_t* f; HTSMSG_FOREACH(f, m) { if ((e = htsmsg_get_list(m, htsmsg_field_name(f)))) { if ((r = _opentv_dict_load_one(htsmsg_field_name(f), e))) { - if (r > 0) + if (r > 0) tvhdebug(LS_OPENTV, "dictionary %s loaded", htsmsg_field_name(f)); else tvhwarn(LS_OPENTV, "dictionary %s failed", htsmsg_field_name(f)); } } - } + } htsmsg_destroy(m); } - -static void _opentv_done( void *m ) -{ - opentv_module_t *mod = (opentv_module_t *)m; +static void _opentv_done(void* m) { + opentv_module_t* mod = (opentv_module_t*)m; free(mod->channel); free(mod->title); @@ -976,47 +991,55 @@ static void _opentv_done( void *m ) eit_pattern_free_list(&mod->p_cleanup_title); } -static int _opentv_tune - ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om, mpegts_mux_t *mm ) -{ - opentv_module_t *mod = (opentv_module_t*)map->om_module; +static int _opentv_tune(epggrab_ota_map_t* map, epggrab_ota_mux_t* om, mpegts_mux_t* mm) { + opentv_module_t* mod = (opentv_module_t*)map->om_module; /* Ignore */ - if (mod->tsid != mm->mm_tsid) return 0; + if (mod->tsid != mm->mm_tsid) + return 0; return 1; } -static int _opentv_prov_load_one ( const char *id, htsmsg_t *m ) -{ - char ibuf[100], nbuf[1000]; - htsmsg_t *cl, *tl, *sl; - uint32_t tsid, sid, onid, bouquetid; - uint32_t titles_time, summaries_time; - const char *str, *name; - opentv_dict_t *dict; - opentv_genre_t *genre; - opentv_module_t *mod; +static int _opentv_prov_load_one(const char* id, htsmsg_t* m) { + char ibuf[100], nbuf[1000]; + htsmsg_t * cl, *tl, *sl; + uint32_t tsid, sid, onid, bouquetid; + uint32_t titles_time, summaries_time; + const char * str, *name; + opentv_dict_t* dict; + opentv_genre_t* genre; + opentv_module_t* mod; static epggrab_ota_module_ops_t ops = { - .start = _opentv_start, - .done = _opentv_done, - .tune = _opentv_tune, - .process_data = _opentv_process_data, + .start = _opentv_start, + .done = _opentv_done, + .tune = _opentv_tune, + .process_data = _opentv_process_data, }; /* Check config */ - if (!(name = htsmsg_get_str(m, "name"))) return -1; - if (!(str = htsmsg_get_str(m, "dict"))) return -1; - if (!(dict = _opentv_dict_find(str))) return -1; - if (!(cl = htsmsg_get_list(m, "channel"))) return -1; - if (!(tl = htsmsg_get_list(m, "title"))) return -1; - if (!(sl = htsmsg_get_list(m, "summary"))) return -1; + if (!(name = htsmsg_get_str(m, "name"))) + return -1; + if (!(str = htsmsg_get_str(m, "dict"))) + return -1; + if (!(dict = _opentv_dict_find(str))) + return -1; + if (!(cl = htsmsg_get_list(m, "channel"))) + return -1; + if (!(tl = htsmsg_get_list(m, "title"))) + return -1; + if (!(sl = htsmsg_get_list(m, "summary"))) + return -1; if (htsmsg_get_u32(m, "onid", &onid)) - if (htsmsg_get_u32(m, "nid", &onid)) return -1; - if (htsmsg_get_u32(m, "tsid", &tsid)) return -1; - if (htsmsg_get_u32(m, "sid", &sid)) return -1; - if (htsmsg_get_u32(m, "bouquetid", &bouquetid)) return -1; - titles_time = htsmsg_get_u32_or_default(m, "titles_time", 30); + if (htsmsg_get_u32(m, "nid", &onid)) + return -1; + if (htsmsg_get_u32(m, "tsid", &tsid)) + return -1; + if (htsmsg_get_u32(m, "sid", &sid)) + return -1; + if (htsmsg_get_u32(m, "bouquetid", &bouquetid)) + return -1; + titles_time = htsmsg_get_u32_or_default(m, "titles_time", 30); summaries_time = htsmsg_get_u32_or_default(m, "summaries_time", 240); /* Genre map (optional) */ @@ -1028,27 +1051,33 @@ static int _opentv_prov_load_one ( const char *id, htsmsg_t *m ) /* Exists (we expect some duplicates due to config layout) */ sprintf(ibuf, "opentv-%s", id); - if (epggrab_module_find_by_id(ibuf)) return 0; + if (epggrab_module_find_by_id(ibuf)) + return 0; /* Create */ sprintf(nbuf, "OpenTV: %s", name); - mod = (opentv_module_t *) - epggrab_module_ota_create(calloc(1, sizeof(opentv_module_t)), - ibuf, LS_OPENTV, NULL, nbuf, 2, NULL, &ops); + mod = (opentv_module_t*)epggrab_module_ota_create(calloc(1, sizeof(opentv_module_t)), + ibuf, + LS_OPENTV, + NULL, + nbuf, + 2, + NULL, + &ops); /* Add provider details */ - mod->dict = dict; - mod->genre = genre; - mod->onid = onid; - mod->tsid = tsid; - mod->sid = sid; - mod->bouquetid = bouquetid; - mod->bouquet_auto = bouquetid == 0; - mod->titles_time = MAX(titles_time, 120); + mod->dict = dict; + mod->genre = genre; + mod->onid = onid; + mod->tsid = tsid; + mod->sid = sid; + mod->bouquetid = bouquetid; + mod->bouquet_auto = bouquetid == 0; + mod->titles_time = MAX(titles_time, 120); mod->summaries_time = MAX(summaries_time, 600); - mod->channel = _pid_list_to_array(cl); - mod->title = _pid_list_to_array(tl); - mod->summary = _pid_list_to_array(sl); + mod->channel = _pid_list_to_array(cl); + mod->title = _pid_list_to_array(tl); + mod->summary = _pid_list_to_array(sl); eit_pattern_compile_named_list(&mod->p_snum, m, "season_num"); eit_pattern_compile_named_list(&mod->p_enum, m, "episode_num"); eit_pattern_compile_named_list(&mod->p_pnum, m, "part_num"); @@ -1058,11 +1087,10 @@ static int _opentv_prov_load_one ( const char *id, htsmsg_t *m ) return 1; } -static void _opentv_prov_load ( htsmsg_t *m ) -{ - int r; - htsmsg_t *e; - htsmsg_field_t *f; +static void _opentv_prov_load(htsmsg_t* m) { + int r; + htsmsg_t* e; + htsmsg_field_t* f; HTSMSG_FOREACH(f, m) { if ((e = htsmsg_get_map_by_field(f))) { if ((r = _opentv_prov_load_one(htsmsg_field_name(f), e))) { @@ -1076,26 +1104,25 @@ static void _opentv_prov_load ( htsmsg_t *m ) htsmsg_destroy(m); } -htsmsg_t *opentv_module_id_list( const char *lang ) -{ - epggrab_module_t *m; - htsmsg_t *e, *l = htsmsg_create_list(); +htsmsg_t* opentv_module_id_list(const char* lang) { + epggrab_module_t* m; + htsmsg_t * e, *l = htsmsg_create_list(); - LIST_FOREACH(m, &epggrab_modules, link) { - if (strncmp(m->id, "opentv-", 7)) continue; + LIST_FOREACH (m, &epggrab_modules, link) { + if (strncmp(m->id, "opentv-", 7)) + continue; e = htsmsg_create_key_val(m->id, m->name); htsmsg_add_msg(l, NULL, e); } return l; } -const char *opentv_check_module_id ( const char *id ) -{ - epggrab_module_t *m; +const char* opentv_check_module_id(const char* id) { + epggrab_module_t* m; if (!id || strncmp(id, "opentv-", 7)) return NULL; - LIST_FOREACH(m, &epggrab_modules, link) + LIST_FOREACH (m, &epggrab_modules, link) if (strcmp(m->id, id) == 0) return m->id; return NULL; @@ -1105,9 +1132,8 @@ const char *opentv_check_module_id ( const char *id ) * Module Setup * ***********************************************************************/ -void opentv_init ( void ) -{ - htsmsg_t *m; +void opentv_init(void) { + htsmsg_t* m; /* Load dictionaries */ if ((m = hts_settings_load("epggrab/opentv/dict"))) @@ -1125,10 +1151,9 @@ void opentv_init ( void ) tvhdebug(LS_OPENTV, "providers loaded"); } -void opentv_done ( void ) -{ - opentv_dict_t *dict; - opentv_genre_t *genre; +void opentv_done(void) { + opentv_dict_t* dict; + opentv_genre_t* genre; while ((dict = RB_FIRST(&_opentv_dicts)) != NULL) { RB_REMOVE(&_opentv_dicts, dict, h_link); @@ -1143,11 +1168,10 @@ void opentv_done ( void ) } } -void opentv_load ( void ) -{ - epggrab_module_t *m; +void opentv_load(void) { + epggrab_module_t* m; - LIST_FOREACH(m, &epggrab_modules, link) + LIST_FOREACH (m, &epggrab_modules, link) if (strncmp(m->id, "opentv-", 7) == 0) epggrab_module_channels_load(m->id); } diff --git a/src/epggrab/module/psip.c b/src/epggrab/module/psip.c index a462c2fee..390e79ca2 100644 --- a/src/epggrab/module/psip.c +++ b/src/epggrab/module/psip.c @@ -31,8 +31,8 @@ #define PSIP_EPG_TABLE_LIMIT 512 -static int _psip_eit_callback(mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid); -static int _psip_ett_callback(mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid); +static int _psip_eit_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid); +static int _psip_ett_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid); /* ************************************************************************ * Status handling @@ -40,25 +40,23 @@ static int _psip_ett_callback(mpegts_table_t *mt, const uint8_t *ptr, int len, i typedef struct psip_table { TAILQ_ENTRY(psip_table) pt_link; - mpegts_table_t *pt_table; /* pointer to mpegts_table to receive EIT/ETT tables/sections */ - uint16_t pt_pid; /* packet ID */ - uint16_t pt_type; /* EIT/ETT table type */ + mpegts_table_t* pt_table; /* pointer to mpegts_table to receive EIT/ETT tables/sections */ + uint16_t pt_pid; /* packet ID */ + uint16_t pt_type; /* EIT/ETT table type */ } psip_table_t; typedef struct psip_status { - epggrab_module_ota_t *ps_mod; - epggrab_ota_map_t *ps_map; - int ps_refcount; - epggrab_ota_mux_t *ps_ota; - mpegts_mux_t *ps_mm; + epggrab_module_ota_t* ps_mod; + epggrab_ota_map_t* ps_map; + int ps_refcount; + epggrab_ota_mux_t* ps_ota; + mpegts_mux_t* ps_mm; TAILQ_HEAD(, psip_table) ps_tables; } psip_status_t; -static void -psip_status_destroy ( mpegts_table_t *mt ) -{ - psip_status_t *st = mt->mt_opaque; - psip_table_t *pt; +static void psip_status_destroy(mpegts_table_t* mt) { + psip_status_t* st = mt->mt_opaque; + psip_table_t* pt; lock_assert(&global_lock); assert(st->ps_refcount > 0); @@ -70,7 +68,7 @@ psip_status_destroy ( mpegts_table_t *mt ) } free(st); } else { - TAILQ_FOREACH(pt, &st->ps_tables, pt_link) + TAILQ_FOREACH (pt, &st->ps_tables, pt_link) if (pt->pt_table == mt) { pt->pt_table = NULL; break; @@ -85,20 +83,16 @@ psip_status_destroy ( mpegts_table_t *mt ) #define IS_EIT(t) ((t) >= 0x100 && (t) <= 0x17f) #define IS_ETT(t) ((t) >= 0x200 && (t) <= 0x27f) -static psip_table_t * -psip_find_table(psip_status_t *ps, uint16_t pid) -{ - psip_table_t *pt; - TAILQ_FOREACH(pt, &ps->ps_tables, pt_link) +static psip_table_t* psip_find_table(psip_status_t* ps, uint16_t pid) { + psip_table_t* pt; + TAILQ_FOREACH (pt, &ps->ps_tables, pt_link) if (pt->pt_pid == pid) return pt; return pt; } -static psip_table_t * -psip_update_table(psip_status_t *ps, uint16_t pid, int type) -{ - psip_table_t *pt; +static psip_table_t* psip_update_table(psip_status_t* ps, uint16_t pid, int type) { + psip_table_t* pt; if (!IS_EIT(type) && !IS_ETT(type)) return NULL; @@ -119,41 +113,49 @@ assign: return pt; } -static mpegts_table_t * -psip_activate_table(psip_status_t *ps, psip_table_t *pt) -{ - mpegts_table_t *mt; +static mpegts_table_t* psip_activate_table(psip_status_t* ps, psip_table_t* pt) { + mpegts_table_t* mt; if (IS_EIT(pt->pt_type)) { /* This is an EIT table */ - mt = mpegts_table_add(ps->ps_mm, DVB_ATSC_EIT_BASE, DVB_ATSC_EIT_MASK, - _psip_eit_callback, ps, "aeit", LS_PSIP, - MT_CRC | MT_RECORD, pt->pt_pid, - MPS_WEIGHT_EIT); + mt = mpegts_table_add(ps->ps_mm, + DVB_ATSC_EIT_BASE, + DVB_ATSC_EIT_MASK, + _psip_eit_callback, + ps, + "aeit", + LS_PSIP, + MT_CRC | MT_RECORD, + pt->pt_pid, + MPS_WEIGHT_EIT); } else if (IS_ETT(pt->pt_type)) { /* This is an ETT table */ - mt = mpegts_table_add(ps->ps_mm, DVB_ATSC_ETT_BASE, DVB_ATSC_ETT_MASK, - _psip_ett_callback, ps, "ett", LS_PSIP, - MT_CRC | MT_RECORD, pt->pt_pid, - MPS_WEIGHT_ETT); + mt = mpegts_table_add(ps->ps_mm, + DVB_ATSC_ETT_BASE, + DVB_ATSC_ETT_MASK, + _psip_ett_callback, + ps, + "ett", + LS_PSIP, + MT_CRC | MT_RECORD, + pt->pt_pid, + MPS_WEIGHT_ETT); } else { abort(); } ps->ps_refcount++; mt->mt_destroy = psip_status_destroy; - pt->pt_table = mt; + pt->pt_table = mt; tvhtrace(LS_PSIP, "table activated - pid 0x%04X type 0x%04X", mt->mt_pid, pt->pt_type); return mt; } -static void -psip_reschedule_tables(psip_status_t *ps) -{ +static void psip_reschedule_tables(psip_status_t* ps) { psip_table_t **tables, *pt; - int total, i; + int total, i; total = 0; - TAILQ_FOREACH(pt, &ps->ps_tables, pt_link) { + TAILQ_FOREACH (pt, &ps->ps_tables, pt_link) { total++; if (pt->pt_table) { tvhtrace(LS_PSIP, "table late: pid = 0x%04X, type = 0x%04X\n", pt->pt_pid, pt->pt_type); @@ -161,12 +163,12 @@ psip_reschedule_tables(psip_status_t *ps) pt->pt_table = NULL; } } - tables = malloc(total * sizeof(psip_table_t *)); + tables = malloc(total * sizeof(psip_table_t*)); tvhtrace(LS_PSIP, "reschedule tables, total %d", total); i = 0; - TAILQ_FOREACH(pt, &ps->ps_tables, pt_link) + TAILQ_FOREACH (pt, &ps->ps_tables, pt_link) tables[i++] = pt; for (i = 0; i < total && i < PSIP_EPG_TABLE_LIMIT; i++) { @@ -183,91 +185,106 @@ psip_reschedule_tables(psip_status_t *ps) * EIT Event * ***********************************************************************/ -static int -_psip_eit_callback_channel - (psip_status_t *ps, channel_t *ch, const uint8_t *ptr, int len, int count) -{ - uint16_t eventid; - uint32_t starttime, length; - time_t start, stop; - int save = 0, save2, i, size; - uint8_t titlelen; - unsigned int dlen; - epg_broadcast_t *ebc; - lang_str_t *title; - epg_changes_t changes2; - epggrab_module_t *mod = (epggrab_module_t *)ps->ps_mod; - int etmlocation; +static int _psip_eit_callback_channel(psip_status_t* ps, + channel_t* ch, + const uint8_t* ptr, + int len, + int count) { + uint16_t eventid; + uint32_t starttime, length; + time_t start, stop; + int save = 0, save2, i, size; + uint8_t titlelen; + unsigned int dlen; + epg_broadcast_t* ebc; + lang_str_t* title; + epg_changes_t changes2; + epggrab_module_t* mod = (epggrab_module_t*)ps->ps_mod; + int etmlocation; for (i = 0; len >= 12 && i < count; len -= size, ptr += size, i++) { - eventid = (ptr[0] & 0x3f) << 8 | ptr[1]; - starttime = ptr[2] << 24 | ptr[3] << 16 | ptr[4] << 8 | ptr[5]; - start = atsc_convert_gpstime(starttime); + eventid = (ptr[0] & 0x3f) << 8 | ptr[1]; + starttime = ptr[2] << 24 | ptr[3] << 16 | ptr[4] << 8 | ptr[5]; + start = atsc_convert_gpstime(starttime); etmlocation = (ptr[6] & 0x30) >> 4; - length = (ptr[6] & 0x0f) << 16 | ptr[7] << 8 | ptr[8]; - stop = start + length; - titlelen = ptr[9]; + length = (ptr[6] & 0x0f) << 16 | ptr[7] << 8 | ptr[8]; + stop = start + length; + titlelen = ptr[9]; - if (12 + titlelen > len) break; + if (12 + titlelen > len) + break; - dlen = ((ptr[10+titlelen] & 0x0f) << 8) | ptr[11+titlelen]; + dlen = ((ptr[10 + titlelen] & 0x0f) << 8) | ptr[11 + titlelen]; size = titlelen + dlen + 12; tvhtrace(LS_PSIP, " %03d: titlelen %d, dlen %d", i, titlelen, dlen); - if (size > len) break; + if (size > len) + break; - if (epg_channel_ignore_broadcast(ch, start)) continue; + if (epg_channel_ignore_broadcast(ch, start)) + continue; - title = atsc_get_string(ptr+10, titlelen); - if (title == NULL) continue; + title = atsc_get_string(ptr + 10, titlelen); + if (title == NULL) + continue; - tvhtrace(LS_PSIP, " %03d: [%s] eventid 0x%04x at %"PRItime_t", duration %d, etmlocation %x, title: '%s' (%d bytes)", - i, ch ? channel_get_name(ch, channel_blank_name) : "(null)", - eventid, start, length, etmlocation, - lang_str_get(title, NULL), titlelen); + tvhtrace(LS_PSIP, + " %03d: [%s] eventid 0x%04x at %" PRItime_t + ", duration %d, etmlocation %x, title: '%s' (%d bytes)", + i, + ch ? channel_get_name(ch, channel_blank_name) : "(null)", + eventid, + start, + length, + etmlocation, + lang_str_get(title, NULL), + titlelen); save2 = changes2 = 0; ebc = epg_broadcast_find_by_time(ch, mod, start, stop, 1, &save2, &changes2); - tvhtrace(LS_PSIP, " eid=%5d, start=%"PRItime_t", stop=%"PRItime_t", ebc=%p", - eventid, start, stop, ebc); - if (!ebc) goto next; + tvhtrace(LS_PSIP, + " eid=%5d, start=%" PRItime_t ", stop=%" PRItime_t ", ebc=%p", + eventid, + start, + stop, + ebc); + if (!ebc) + goto next; save2 |= epg_broadcast_set_dvb_eid(ebc, eventid, &changes2); - if(etmlocation == 0) + if (etmlocation == 0) save2 |= epg_broadcast_set_description(ebc, NULL, NULL); save |= epg_broadcast_set_title(ebc, title, &changes2); save |= save2; -next: + next: lang_str_destroy(title); } return save; } -static int -_psip_eit_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int r; - int sect, last, ver; - int count; - int save = 0; - uint16_t tsid; - uint32_t extraid; - mpegts_mux_t *mm = mt->mt_mux; - psip_status_t *ps = mt->mt_opaque; - epggrab_ota_map_t *map = ps->ps_map; - epggrab_module_t *mod = (epggrab_module_t *)map->om_module; - channel_t *ch; - mpegts_service_t *svc; - mpegts_psi_table_state_t *st; - idnode_list_mapping_t *ilm; - th_subscription_t *ths; +static int _psip_eit_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int r; + int sect, last, ver; + int count; + int save = 0; + uint16_t tsid; + uint32_t extraid; + mpegts_mux_t* mm = mt->mt_mux; + psip_status_t* ps = mt->mt_opaque; + epggrab_ota_map_t* map = ps->ps_map; + epggrab_module_t* mod = (epggrab_module_t*)map->om_module; + channel_t* ch; + mpegts_service_t* svc; + mpegts_psi_table_state_t* st; + idnode_list_mapping_t* ilm; + th_subscription_t* ths; /* Validate */ - if (tableid != 0xcb) return -1; + if (tableid != 0xcb) + return -1; /* Statistics */ ths = mpegts_mux_find_subscription_by_name(mm, "epggrab"); @@ -281,7 +298,7 @@ _psip_eit_callback extraid = tsid; /* Look up channel based on the source id */ - LIST_FOREACH(svc, &mm->mm_services, s_dvb_mux_link) { + LIST_FOREACH (svc, &mm->mm_services, s_dvb_mux_link) { if (svc->s_atsc_source_id == tsid) break; } @@ -295,30 +312,47 @@ _psip_eit_callback ps->ps_ota = epggrab_ota_register((epggrab_module_ota_t*)mod, NULL, mm); /* Begin */ - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, tableid, extraid, 7, - &st, §, &last, &ver, 0); - if (r == 0) goto complete; - if (r != 1) return r; - tvhtrace(LS_PSIP, "0x%04x: EIT tsid %04X (%s), ver %d", - mt->mt_pid, tsid, svc->s_dvb_svcname, ver); + r = dvb_table_begin((mpegts_psi_table_t*)mt, + ptr, + len, + tableid, + extraid, + 7, + &st, + §, + &last, + &ver, + 0); + if (r == 0) + goto complete; + if (r != 1) + return r; + tvhtrace(LS_PSIP, + "0x%04x: EIT tsid %04X (%s), ver %d", + mt->mt_pid, + tsid, + svc->s_dvb_svcname, + ver); /* # events */ count = ptr[6]; tvhtrace(LS_PSIP, "event count %d data len %d", count, len); - ptr += 7; - len -= 7; + ptr += 7; + len -= 7; /* Sanity check */ - if (len < 12) goto done; + if (len < 12) + goto done; /* Register this */ if (ps->ps_ota) epggrab_ota_service_add(map, ps->ps_ota, &svc->s_id.in_uuid, 1); /* For each associated channels */ - LIST_FOREACH(ilm, &svc->s_channels, ilm_in1_link) { - ch = (channel_t *)ilm->ilm_in2; - if (!ch->ch_enabled || ch->ch_epg_parent) continue; + LIST_FOREACH (ilm, &svc->s_channels, ilm_in1_link) { + ch = (channel_t*)ilm->ilm_in2; + if (!ch->ch_enabled || ch->ch_epg_parent) + continue; save |= _psip_eit_callback_channel(ps, ch, ptr, len, count); } @@ -326,36 +360,34 @@ _psip_eit_callback epg_updated(); done: - r = dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + r = dvb_table_end((mpegts_psi_table_t*)mt, st, sect); complete: return r; } -static int -_psip_ett_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int r; - int sect, last, ver; - int save = 0, found = 0; - uint16_t tsid; - uint32_t extraid, sourceid, eventid; - int isevent; - mpegts_mux_t *mm = mt->mt_mux; - psip_status_t *ps = mt->mt_opaque; - epggrab_ota_map_t *map = ps->ps_map; - epggrab_module_t *mod = (epggrab_module_t *)map->om_module; - mpegts_service_t *svc; - mpegts_psi_table_state_t *st; - th_subscription_t *ths; - lang_str_t *description; - idnode_list_mapping_t *ilm; - channel_t *ch; - epg_changes_t changes; +static int _psip_ett_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int r; + int sect, last, ver; + int save = 0, found = 0; + uint16_t tsid; + uint32_t extraid, sourceid, eventid; + int isevent; + mpegts_mux_t* mm = mt->mt_mux; + psip_status_t* ps = mt->mt_opaque; + epggrab_ota_map_t* map = ps->ps_map; + epggrab_module_t* mod = (epggrab_module_t*)map->om_module; + mpegts_service_t* svc; + mpegts_psi_table_state_t* st; + th_subscription_t* ths; + lang_str_t* description; + idnode_list_mapping_t* ilm; + channel_t* ch; + epg_changes_t changes; /* Validate */ - if (tableid != 0xcc) return -1; + if (tableid != 0xcc) + return -1; /* Statistics */ ths = mpegts_mux_find_subscription_by_name(mm, "epggrab"); @@ -369,17 +401,28 @@ _psip_ett_callback extraid = tsid; /* Begin */ - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, tableid, extraid, 7, - &st, §, &last, &ver, 0); - if (r == 0) goto complete; - if (r != 1) return r; + r = dvb_table_begin((mpegts_psi_table_t*)mt, + ptr, + len, + tableid, + extraid, + 7, + &st, + §, + &last, + &ver, + 0); + if (r == 0) + goto complete; + if (r != 1) + return r; sourceid = (ptr[6] << 8) | ptr[7]; - eventid = (ptr[8] << 6) | ((ptr[9] >> 2) & 0x3f); - isevent = (ptr[9] & 0x2) >> 1; + eventid = (ptr[8] << 6) | ((ptr[9] >> 2) & 0x3f); + isevent = (ptr[9] & 0x2) >> 1; /* Look up channel based on the source id */ - LIST_FOREACH(svc, &mm->mm_services, s_dvb_mux_link) { + LIST_FOREACH (svc, &mm->mm_services, s_dvb_mux_link) { if (svc->s_atsc_source_id == sourceid) break; } @@ -393,27 +436,46 @@ _psip_ett_callback goto done; if (!isevent) { - tvhtrace(LS_PSIP, "0x%04x: channel ETT tableid 0x%04X [%s], ver %d", mt->mt_pid, tsid, svc->s_dvb_svcname, ver); + tvhtrace(LS_PSIP, + "0x%04x: channel ETT tableid 0x%04X [%s], ver %d", + mt->mt_pid, + tsid, + svc->s_dvb_svcname, + ver); } else { - found = 1; - description = atsc_get_string(ptr+10, len-10); - LIST_FOREACH(ilm, &svc->s_channels, ilm_in1_link) { - ch = (channel_t *)ilm->ilm_in2; - epg_broadcast_t *ebc; + found = 1; + description = atsc_get_string(ptr + 10, len - 10); + LIST_FOREACH (ilm, &svc->s_channels, ilm_in1_link) { + ch = (channel_t*)ilm->ilm_in2; + epg_broadcast_t* ebc; changes = 0; - ebc = epg_broadcast_find_by_eid(ch, eventid); + ebc = epg_broadcast_find_by_eid(ch, eventid); if (ebc && ebc->grabber == mod) { save |= epg_broadcast_set_description(ebc, description, &changes); - tvhtrace(LS_PSIP, "0x%04x: ETT tableid 0x%04X [%s], eventid 0x%04X (%d) ['%s'], ver %d", - mt->mt_pid, tsid, svc->s_dvb_svcname, eventid, eventid, - lang_str_get(ebc->title, "eng"), ver); + tvhtrace(LS_PSIP, + "0x%04x: ETT tableid 0x%04X [%s], eventid 0x%04X (%d) ['%s'], ver %d", + mt->mt_pid, + tsid, + svc->s_dvb_svcname, + eventid, + eventid, + lang_str_get(ebc->title, "eng"), + ver); } else { found = 0; } } if (found == 0) { - tvhtrace(LS_PSIP, "0x%04x: ETT tableid 0x%04X [%s], eventid 0x%04X (%d), ver %d - no matching broadcast found [%.80s]", - mt->mt_pid, tsid, svc->s_dvb_svcname, eventid, eventid, ver, lang_str_get(description, NULL)); + tvhtrace(LS_PSIP, + "0x%04x: ETT tableid 0x%04X [%s], eventid 0x%04X (%d), ver %d - no matching broadcast " + "found [%.80s]", + mt->mt_pid, + tsid, + svc->s_dvb_svcname, + eventid, + eventid, + ver, + lang_str_get(description, NULL)); } lang_str_destroy(description); } @@ -422,31 +484,29 @@ _psip_ett_callback epg_updated(); done: - r = dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + r = dvb_table_end((mpegts_psi_table_t*)mt, st, sect); /* Reset version caching for ETT tables. */ - dvb_table_reset((mpegts_psi_table_t *)mt); + dvb_table_reset((mpegts_psi_table_t*)mt); complete: return r; } -static int -_psip_mgt_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int r; - int sect, last, ver; - int count, i; - uint16_t tsid; - uint32_t extraid; - mpegts_mux_t *mm = mt->mt_mux; - psip_status_t *ps = mt->mt_opaque; - mpegts_psi_table_state_t *st; - th_subscription_t *ths; +static int _psip_mgt_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int r; + int sect, last, ver; + int count, i; + uint16_t tsid; + uint32_t extraid; + mpegts_mux_t* mm = mt->mt_mux; + psip_status_t* ps = mt->mt_opaque; + mpegts_psi_table_state_t* st; + th_subscription_t* ths; /* Validate */ - if (tableid != 0xc7) return -1; + if (tableid != 0xc7) + return -1; /* Statistics */ ths = mpegts_mux_find_subscription_by_name(mm, "epggrab"); @@ -460,30 +520,52 @@ _psip_mgt_callback extraid = tsid; /* Begin */ - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, tableid, extraid, 7, - &st, §, &last, &ver, 0); - if (r != 1) return r; + r = dvb_table_begin((mpegts_psi_table_t*)mt, + ptr, + len, + tableid, + extraid, + 7, + &st, + §, + &last, + &ver, + 0); + if (r != 1) + return r; /* # tables */ count = ptr[6] << 8 | ptr[7]; - ptr += 8; - len -= 8; + ptr += 8; + len -= 8; - tvhtrace(LS_PSIP, "0x%04x: MGT tsid %04X (%d), ver %d, count %d", mt->mt_pid, tsid, tsid, ver, count); + tvhtrace(LS_PSIP, + "0x%04x: MGT tsid %04X (%d), ver %d, count %d", + mt->mt_pid, + tsid, + tsid, + ver, + count); for (i = 0; i < count && len >= 11; i++) { unsigned int type, tablepid, tablever, tablesize; unsigned int dlen; dlen = ((ptr[9] & 0x3) << 8) | ptr[10]; - if (dlen + 11 > len) return -1; + if (dlen + 11 > len) + return -1; - type = ptr[0] << 8 | ptr[1]; - tablepid = (ptr[2] & 0x1f) << 8 | ptr[3]; - tablever = ptr[4] & 0x1f; + type = ptr[0] << 8 | ptr[1]; + tablepid = (ptr[2] & 0x1f) << 8 | ptr[3]; + tablever = ptr[4] & 0x1f; tablesize = ptr[5] << 24 | ptr[6] << 16 | ptr[7] << 8 | ptr[8]; - tvhdebug(LS_PSIP, "table %d - type 0x%04X, pid 0x%04X, ver 0x%04X, size 0x%08X", - i, type, tablepid, tablever, tablesize); + tvhdebug(LS_PSIP, + "table %d - type 0x%04X, pid 0x%04X, ver 0x%04X, size 0x%08X", + i, + type, + tablepid, + tablever, + tablesize); psip_update_table(ps, tablepid, type); @@ -494,30 +576,34 @@ _psip_mgt_callback psip_reschedule_tables(ps); - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); } /* ************************************************************************ * Module Setup * ***********************************************************************/ -static int _psip_start - ( epggrab_ota_map_t *map, mpegts_mux_t *dm ) -{ - mpegts_table_t *mt; - psip_status_t *ps; +static int _psip_start(epggrab_ota_map_t* map, mpegts_mux_t* dm) { + mpegts_table_t* mt; + psip_status_t* ps; ps = calloc(1, sizeof(*ps)); TAILQ_INIT(&ps->ps_tables); - ps->ps_mod = map->om_module; - ps->ps_map = map; - ps->ps_mm = dm; + ps->ps_mod = map->om_module; + ps->ps_map = map; + ps->ps_mm = dm; /* Listen for Master Guide Table */ - mt = mpegts_table_add(dm, DVB_ATSC_MGT_BASE, DVB_ATSC_MGT_MASK, - _psip_mgt_callback, ps, "mgt", LS_TBL_EIT, - MT_CRC | MT_RECORD, - DVB_ATSC_MGT_PID, MPS_WEIGHT_MGT); + mt = mpegts_table_add(dm, + DVB_ATSC_MGT_BASE, + DVB_ATSC_MGT_MASK, + _psip_mgt_callback, + ps, + "mgt", + LS_TBL_EIT, + MT_CRC | MT_RECORD, + DVB_ATSC_MGT_PID, + MPS_WEIGHT_MGT); if (mt && !mt->mt_destroy) { ps->ps_refcount++; mt->mt_destroy = psip_status_destroy; @@ -529,24 +615,19 @@ static int _psip_start return 0; } -static int _psip_stop - ( epggrab_ota_map_t *map, mpegts_mux_t *dm ) -{ +static int _psip_stop(epggrab_ota_map_t* map, mpegts_mux_t* dm) { tvhdebug(LS_PSIP, "Calling _psip_stop"); return 0; } -static void _psip_done (void *x) -{ +static void _psip_done(void* x) { tvhdebug(LS_PSIP, "Calling _psip_done"); } -static int _psip_tune - ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om, mpegts_mux_t *mm ) -{ - int r = 0; - mpegts_service_t *s; +static int _psip_tune(epggrab_ota_map_t* map, epggrab_ota_mux_t* om, mpegts_mux_t* mm) { + int r = 0; + mpegts_service_t* s; epggrab_ota_svc_link_t *osl, *nxt; lock_assert(&global_lock); @@ -557,7 +638,7 @@ static int _psip_tune /* Check if any services are mapped */ // FIXME: copied from the eit module - is this a good idea here? - // TODO: using indirect ref's like this is inefficient, should + // TODO: using indirect ref's like this is inefficient, should // consider changeing it? for (osl = RB_FIRST(&map->om_svcs); osl != NULL; osl = nxt) { nxt = RB_NEXT(osl, link); @@ -574,31 +655,26 @@ static int _psip_tune return r; } -htsmsg_t *psip_module_id_list( const char *lang ) -{ +htsmsg_t* psip_module_id_list(const char* lang) { htsmsg_t *e, *l = htsmsg_create_list(); e = htsmsg_create_key_val("psip", "PSIP: ATSC Grabber"); htsmsg_add_msg(l, NULL, e); return l; } -const char *psip_check_module_id ( const char *id ) -{ +const char* psip_check_module_id(const char* id) { if (id && strcmp(id, "psip") == 0) return "psip"; return NULL; } -void psip_init ( void ) -{ +void psip_init(void) { static epggrab_ota_module_ops_t ops = { - .start = _psip_start, - .stop = _psip_stop, - .done = _psip_done, - .tune = _psip_tune, + .start = _psip_start, + .stop = _psip_stop, + .done = _psip_done, + .tune = _psip_tune, }; - epggrab_module_ota_create(NULL, "psip", LS_PSIP, NULL, "PSIP: ATSC Grabber", - 1, NULL, &ops); + epggrab_module_ota_create(NULL, "psip", LS_PSIP, NULL, "PSIP: ATSC Grabber", 1, NULL, &ops); } - diff --git a/src/epggrab/module/xmltv.c b/src/epggrab/module/xmltv.c index f21133470..74d0324d6 100644 --- a/src/epggrab/module/xmltv.c +++ b/src/epggrab/module/xmltv.c @@ -51,15 +51,14 @@ /** * */ -static time_t _xmltv_str2time(const char *in) -{ +static time_t _xmltv_str2time(const char* in) { struct tm tm; - int tz = 0, r; - int sp = 0; - char str[32]; + int tz = 0, r; + int sp = 0; + char str[32]; memset(&tm, 0, sizeof(tm)); - tm.tm_mday = 1; /* Day is one-based not zero-based */ + tm.tm_mday = 1; /* Day is one-based not zero-based */ strlcpy(str, in, sizeof(str)); /* split tz */ @@ -71,15 +70,20 @@ static time_t _xmltv_str2time(const char *in) /* parse tz */ // TODO: handle string TZ? if (str[sp]) { - sscanf(str+sp, "%d", &tz); - tz = (tz % 100) * 60 + (tz / 100) * 3600; // Convert from HHMM to seconds + sscanf(str + sp, "%d", &tz); + tz = (tz % 100) * 60 + (tz / 100) * 3600; // Convert from HHMM to seconds str[sp] = 0; } /* parse time */ - r = sscanf(str, "%04d%02d%02d%02d%02d%02d", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec); + r = sscanf(str, + "%04d%02d%02d%02d%02d%02d", + &tm.tm_year, + &tm.tm_mon, + &tm.tm_mday, + &tm.tm_hour, + &tm.tm_min, + &tm.tm_sec); /* Time "can be 'YYYYMMDDhhmmss' or some initial substring...you can * have 'YYYYMM'" according to DTD. The imprecise dates are used @@ -89,8 +93,10 @@ static time_t _xmltv_str2time(const char *in) * if they have been parsed since timegm has some fields based * differently to others. */ - if (r > 1) tm.tm_mon -= 1; - if (r > 0) tm.tm_year -= 1900; + if (r > 1) + tm.tm_mon -= 1; + if (r > 0) + tm.tm_year -= 1900; tm.tm_isdst = -1; if (r > 0) { @@ -134,26 +140,24 @@ static time_t _xmltv_str2time(const char *in) * */ -static const char *xmltv_ns_get_parse_num - (const char *s, uint16_t *ap, uint16_t *bp) -{ +static const char* xmltv_ns_get_parse_num(const char* s, uint16_t* ap, uint16_t* bp) { int a = -1, b = -1; - while(1) { - if(!*s) + while (1) { + if (!*s) goto out; - if(*s == '.') { + if (*s == '.') { s++; goto out; } - if(*s == '/') + if (*s == '/') break; - if(*s >= '0' && *s <= '9') { - if(a == -1) - a = 0; + if (*s >= '0' && *s <= '9') { + if (a == -1) + a = 0; a = a * 10 + *s - '0'; } s++; @@ -161,53 +165,54 @@ static const char *xmltv_ns_get_parse_num s++; // slash - while(1) { - if(!*s) + while (1) { + if (!*s) break; - if(*s == '.') { + if (*s == '.') { s++; break; } - if(*s >= '0' && *s <= '9') { - if(b == -1) - b = 0; + if (*s >= '0' && *s <= '9') { + if (b == -1) + b = 0; b = b * 10 + *s - '0'; } s++; } - - out: - if(ap && a >= 0) *ap = a + 1; - if(bp && b >= 0) *bp = b; +out: + if (ap && a >= 0) + *ap = a + 1; + if (bp && b >= 0) + *bp = b; return s; } -static void parse_xmltv_ns_episode - (const char *s, epg_episode_num_t *epnum) -{ +static void parse_xmltv_ns_episode(const char* s, epg_episode_num_t* epnum) { s = xmltv_ns_get_parse_num(s, &(epnum->s_num), &(epnum->s_cnt)); s = xmltv_ns_get_parse_num(s, &(epnum->e_num), &(epnum->e_cnt)); s = xmltv_ns_get_parse_num(s, &(epnum->p_num), &(epnum->p_cnt)); } -static void parse_xmltv_dd_progid - (epggrab_module_t *mod, const char *s, char **uri, char **suri, - epg_episode_num_t *epnum) -{ +static void parse_xmltv_dd_progid(epggrab_module_t* mod, + const char* s, + char** uri, + char** suri, + epg_episode_num_t* epnum) { const int s_len = strlen(s); - if (s_len < 2) return; + if (s_len < 2) + return; const int buf_size = s_len + strlen(mod->id) + 13; - char * buf = (char *) malloc( buf_size); + char* buf = (char*)malloc(buf_size); /* Raw URI */ - int e = snprintf( buf, buf_size, "ddprogid://%s/%s", mod->id, s); + int e = snprintf(buf, buf_size, "ddprogid://%s/%s", mod->id, s); /* SH - series without episode id so ignore */ if (strncmp("SH", s, 2)) - *uri = strdup(buf); + *uri = strdup(buf); else *suri = strdup(buf); @@ -216,8 +221,9 @@ static void parse_xmltv_dd_progid while (--e && buf[e] != '.') {} if (e) { buf[e] = '\0'; - *suri = strdup(buf); - if (buf[e+1]) sscanf(&buf[e+1], "%hu", &(epnum->e_num)); + *suri = strdup(buf); + if (buf[e + 1]) + sscanf(&buf[e + 1], "%hu", &(epnum->e_num)); } } free(buf); @@ -226,28 +232,26 @@ static void parse_xmltv_dd_progid /** * */ -static void get_episode_info - ( epggrab_module_t *mod, - htsmsg_t *tags, char **uri, char **suri, - epg_episode_num_t *epnum ) -{ - htsmsg_field_t *f; - htsmsg_t *c, *a; - const char *sys, *cdata; +static void get_episode_info(epggrab_module_t* mod, + htsmsg_t* tags, + char** uri, + char** suri, + epg_episode_num_t* epnum) { + htsmsg_field_t* f; + htsmsg_t * c, *a; + const char * sys, *cdata; HTSMSG_FOREACH(f, tags) { - if((c = htsmsg_get_map_by_field(f)) == NULL || - strcmp(htsmsg_field_name(f), "episode-num") || - (a = htsmsg_get_map(c, "attrib")) == NULL || - (cdata = htsmsg_get_str(c, "cdata")) == NULL || - (sys = htsmsg_get_str(a, "system")) == NULL) + if ((c = htsmsg_get_map_by_field(f)) == NULL || strcmp(htsmsg_field_name(f), "episode-num") || + (a = htsmsg_get_map(c, "attrib")) == NULL || (cdata = htsmsg_get_str(c, "cdata")) == NULL || + (sys = htsmsg_get_str(a, "system")) == NULL) continue; - if(!strcmp(sys, "onscreen")) + if (!strcmp(sys, "onscreen")) epnum->text = (char*)cdata; - else if(!strcmp(sys, "xmltv_ns")) + else if (!strcmp(sys, "xmltv_ns")) parse_xmltv_ns_episode(cdata, epnum); - else if(!strcmp(sys, "dd_progid")) + else if (!strcmp(sys, "dd_progid")) parse_xmltv_dd_progid(mod, cdata, uri, suri, epnum); } } @@ -259,23 +263,22 @@ static void get_episode_info * job */ static int -xmltv_parse_vid_quality - ( epg_broadcast_t *ebc, htsmsg_t *m, int8_t *bw, epg_changes_t *changes ) -{ - int save = 0; - int hd = 0, lines = 0, aspect = 0; - const char *str; - if (!ebc || !m) return 0; +xmltv_parse_vid_quality(epg_broadcast_t* ebc, htsmsg_t* m, int8_t* bw, epg_changes_t* changes) { + int save = 0; + int hd = 0, lines = 0, aspect = 0; + const char* str; + if (!ebc || !m) + return 0; if ((str = htsmsg_xml_get_cdata_str(m, "colour"))) *bw = strcmp(str, "no") ? 0 : 1; if ((str = htsmsg_xml_get_cdata_str(m, "quality"))) { if (strstr(str, "HD")) { - hd = 1; + hd = 1; } else if (strstr(str, "FHD")) { - hd = 2; + hd = 2; } else if (strstr(str, "UHD")) { - hd = 3; + hd = 3; } else if (strstr(str, "480")) { lines = 480; aspect = 150; @@ -320,17 +323,14 @@ xmltv_parse_vid_quality /* * Parse accessibility data */ -int -xmltv_parse_accessibility - ( epg_broadcast_t *ebc, htsmsg_t *m, epg_changes_t *changes ) -{ - int save = 0; - htsmsg_t *tag; - htsmsg_field_t *f; - const char *str; +int xmltv_parse_accessibility(epg_broadcast_t* ebc, htsmsg_t* m, epg_changes_t* changes) { + int save = 0; + htsmsg_t* tag; + htsmsg_field_t* f; + const char* str; HTSMSG_FOREACH(f, m) { - if(!strcmp(htsmsg_field_name(f), "subtitles")) { + if (!strcmp(htsmsg_field_name(f), "subtitles")) { if ((tag = htsmsg_get_map_by_field(f))) { str = htsmsg_xml_get_attr_str(tag, "type"); if (str && !strcmp(str, "teletext")) @@ -348,13 +348,14 @@ xmltv_parse_accessibility /* * Previously shown */ -static int _xmltv_parse_previously_shown - ( epg_broadcast_t *ebc, time_t *first_aired, - htsmsg_t *tag, epg_changes_t *changes ) -{ - int ret; - const char *start; - if (!ebc || !tag) return 0; +static int _xmltv_parse_previously_shown(epg_broadcast_t* ebc, + time_t* first_aired, + htsmsg_t* tag, + epg_changes_t* changes) { + int ret; + const char* start; + if (!ebc || !tag) + return 0; ret = epg_broadcast_set_is_repeat(ebc, 1, changes); if ((start = htsmsg_xml_get_attr_str(tag, "start"))) *first_aired = _xmltv_str2time(start); @@ -364,55 +365,56 @@ static int _xmltv_parse_previously_shown /* * Date finished, typically copyright date. */ -static int _xmltv_parse_date_finished - ( epg_broadcast_t *ebc, - htsmsg_t *tag, epg_changes_t *changes ) -{ - if (!ebc || !tag) return 0; - const char *str = htsmsg_xml_get_cdata_str(tag, "date"); +static int _xmltv_parse_date_finished(epg_broadcast_t* ebc, htsmsg_t* tag, epg_changes_t* changes) { + if (!ebc || !tag) + return 0; + const char* str = htsmsg_xml_get_cdata_str(tag, "date"); if (str) { - /* Technically the date could contain information about month - * and even second it was completed. We only want the four - * digit year. - */ - const size_t len = strlen(str); - if (len >= 4) { - char year_buf[32]; - strlcpy(year_buf, str, 5); - const int64_t year = atoll(year_buf); - /* Sanity check the year before copying it over. */ - if (year > 1800 && year < 2500) { - return epg_broadcast_set_copyright_year(ebc, year, changes); - } + /* Technically the date could contain information about month + * and even second it was completed. We only want the four + * digit year. + */ + const size_t len = strlen(str); + if (len >= 4) { + char year_buf[32]; + strlcpy(year_buf, str, 5); + const int64_t year = atoll(year_buf); + /* Sanity check the year before copying it over. */ + if (year > 1800 && year < 2500) { + return epg_broadcast_set_copyright_year(ebc, year, changes); } + } } return 0; } - /* * Star rating * * 3.3/5 * */ -static int _xmltv_parse_star_rating - ( epg_broadcast_t *ebc, htsmsg_t *body, epg_changes_t *changes ) -{ - double a, b; - htsmsg_t *stars, *tags; +static int _xmltv_parse_star_rating(epg_broadcast_t* ebc, htsmsg_t* body, epg_changes_t* changes) { + double a, b; + htsmsg_t * stars, *tags; const char *s1, *s2; - char *s1end, *s2end; + char * s1end, *s2end; - if (!ebc || !body) return 0; - if (!(stars = htsmsg_get_map(body, "star-rating"))) return 0; - if (!(tags = htsmsg_get_map(stars, "tags"))) return 0; - if (!(s1 = htsmsg_xml_get_cdata_str(tags, "value"))) return 0; - if (!(s2 = strstr(s1, "/"))) return 0; + if (!ebc || !body) + return 0; + if (!(stars = htsmsg_get_map(body, "star-rating"))) + return 0; + if (!(tags = htsmsg_get_map(stars, "tags"))) + return 0; + if (!(s1 = htsmsg_xml_get_cdata_str(tags, "value"))) + return 0; + if (!(s2 = strstr(s1, "/"))) + return 0; a = strtod(s1, &s1end); b = strtod(s2 + 1, &s2end); - if ( a == 0.0f || b == 0.0f) return 0; + if (a == 0.0f || b == 0.0f) + return 0; return epg_broadcast_set_star_rating(ebc, (100 * a) / b, changes); } @@ -445,62 +447,66 @@ static int _xmltv_parse_star_rating * [rating system=MPAA] values R, PG, G, PG-13 etc * [rating system=advisory] values "strong sexual content","Language", etc */ -static int _xmltv_parse_age_rating - ( epg_broadcast_t *ebc, htsmsg_t *body, epg_changes_t *changes ) -{ - uint8_t age = 0; - htsmsg_t *rating, *tags, *attrib; - const char *s1; +static int _xmltv_parse_age_rating(epg_broadcast_t* ebc, htsmsg_t* body, epg_changes_t* changes) { + uint8_t age = 0; + htsmsg_t * rating, *tags, *attrib; + const char* s1; - if (!ebc || !body) return 0; + if (!ebc || !body) + return 0; - htsmsg_field_t *f; + htsmsg_field_t* f; - const char *rating_system; //System attribute from the 'rating' tag : - ratinglabel_t *rl = NULL; + const char* rating_system; // System attribute from the 'rating' tag : + ratinglabel_t* rl = NULL; - //Clear the rating label. - //If the event is already in the EPG DB with another - //rating label, this will clear the existing rating lable - //prior to setting the new one -if- the new one - //just happens to be null. + // Clear the rating label. + // If the event is already in the EPG DB with another + // rating label, this will clear the existing rating lable + // prior to setting the new one -if- the new one + // just happens to be null. ebc->rating_label = rl; - //Only look for rating labels if enabled. - if(epggrab_conf.epgdb_processparentallabels){ + // Only look for rating labels if enabled. + if (epggrab_conf.epgdb_processparentallabels) { HTSMSG_FOREACH(f, body) { if (!strcmp(htsmsg_field_name(f), "rating") && (rating = htsmsg_get_map_by_field(f))) { - //Look for a 'system' attribute of the 'rating' tag + // Look for a 'system' attribute of the 'rating' tag rating_system = NULL; - if ((attrib = htsmsg_get_map(rating, "attrib"))){ + if ((attrib = htsmsg_get_map(rating, "attrib"))) { rating_system = htsmsg_get_str(attrib, "system"); - }//END get the atrtibutes for the rating tag. - //Look for sub-tags of the 'rating' tag - if ((tags = htsmsg_get_map(rating, "tags"))) { - //Look the the 'value' tag containing the actual rating text + } // END get the atrtibutes for the rating tag. + // Look for sub-tags of the 'rating' tag + if ((tags = htsmsg_get_map(rating, "tags"))) { + // Look the the 'value' tag containing the actual rating text if ((s1 = htsmsg_xml_get_cdata_str(tags, "value"))) { - //tvherror(LS_RATINGLABELS, "XMLTV got system: '%s' / '%s'", rating_system, s1); + // tvherror(LS_RATINGLABELS, "XMLTV got system: '%s' / '%s'", rating_system, s1); rl = ratinglabel_find_from_xmltv(rating_system, s1); - if(rl){ - tvhtrace(LS_RATINGLABELS, "Found label: '%s' / '%s' / '%s' / '%d'", rl->rl_authority, rl->rl_label, rl->rl_country, rl->rl_age); + if (rl) { + tvhtrace(LS_RATINGLABELS, + "Found label: '%s' / '%s' / '%s' / '%d'", + rl->rl_authority, + rl->rl_label, + rl->rl_country, + rl->rl_age); ebc->rating_label = rl; - if (rl->rl_display_age >= 0 && rl->rl_display_age < 22){ + if (rl->rl_display_age >= 0 && rl->rl_display_age < 22) { return epg_broadcast_set_age_rating(ebc, rl->rl_display_age, changes); - }//END age sanity test - }//END we matched a rating label - }//END we got a value to inspect - }//END get sub-tags of the rating tag. - }//END got the 'rating' tag. - }//END loop through each XML tag - }//END rating labels enabled + } // END age sanity test + } // END we matched a rating label + } // END we got a value to inspect + } // END get sub-tags of the rating tag. + } // END got the 'rating' tag. + } // END loop through each XML tag + } // END rating labels enabled else - //Perform the existing XMLTV lookup + // Perform the existing XMLTV lookup { HTSMSG_FOREACH(f, body) { if (!strcmp(htsmsg_field_name(f), "rating") && (rating = htsmsg_get_map_by_field(f))) { - if ((tags = htsmsg_get_map(rating, "tags"))) { + if ((tags = htsmsg_get_map(rating, "tags"))) { if ((s1 = htsmsg_xml_get_cdata_str(tags, "value"))) { /* We map some common ratings since some movies only * have one of these flags rather than an age rating. @@ -527,22 +533,20 @@ static int _xmltv_parse_age_rating } } - return 0; } /* * Parse category list */ -static epg_genre_list_t -*_xmltv_parse_categories ( htsmsg_t *tags ) -{ - htsmsg_t *e; - htsmsg_field_t *f; - epg_genre_list_t *egl = NULL; +static epg_genre_list_t* _xmltv_parse_categories(htsmsg_t* tags) { + htsmsg_t* e; + htsmsg_field_t* f; + epg_genre_list_t* egl = NULL; HTSMSG_FOREACH(f, tags) { if (!strcmp(htsmsg_field_name(f), "category") && (e = htsmsg_get_map_by_field(f))) { - if (!egl) egl = calloc(1, sizeof(epg_genre_list_t)); + if (!egl) + egl = calloc(1, sizeof(epg_genre_list_t)); epg_genre_list_add_by_str(egl, htsmsg_get_str(e, "cdata"), NULL); } } @@ -552,16 +556,15 @@ static epg_genre_list_t /* * Parse a series of language strings */ -static void -_xmltv_parse_lang_str ( lang_str_t **ls, htsmsg_t *tags, const char *tname ) -{ - htsmsg_t *e, *attrib; - htsmsg_field_t *f; - const char *lang; +static void _xmltv_parse_lang_str(lang_str_t** ls, htsmsg_t* tags, const char* tname) { + htsmsg_t * e, *attrib; + htsmsg_field_t* f; + const char* lang; HTSMSG_FOREACH(f, tags) { if (!strcmp(htsmsg_field_name(f), tname) && (e = htsmsg_get_map_by_field(f))) { - if (!*ls) *ls = lang_str_create(); + if (!*ls) + *ls = lang_str_create(); lang = NULL; if ((attrib = htsmsg_get_map(e, "attrib"))) lang = htsmsg_get_str(attrib, "lang"); @@ -572,19 +575,18 @@ _xmltv_parse_lang_str ( lang_str_t **ls, htsmsg_t *tags, const char *tname ) /// Make a string list from the contents of all tags in the message /// that have tagname. -__attribute__((warn_unused_result)) -static string_list_t * - _xmltv_make_str_list_from_matching(htsmsg_t *tags, const char *tagname) -{ - htsmsg_t *e; - htsmsg_field_t *f; - string_list_t *tag_list = NULL; +__attribute__((warn_unused_result)) static string_list_t* +_xmltv_make_str_list_from_matching(htsmsg_t* tags, const char* tagname) { + htsmsg_t* e; + htsmsg_field_t* f; + string_list_t* tag_list = NULL; HTSMSG_FOREACH(f, tags) { if (!strcmp(htsmsg_field_name(f), tagname) && (e = htsmsg_get_map_by_field(f))) { - const char *str = htsmsg_get_str(e, "cdata"); + const char* str = htsmsg_get_str(e, "cdata"); if (str && *str) { - if (!tag_list) tag_list = string_list_create(); + if (!tag_list) + tag_list = string_list_create(); string_list_insert_lowercase(tag_list, str); } } @@ -593,7 +595,6 @@ static string_list_t * return tag_list; } - /// Parse credits from the message tags and store the name/type (such /// as actor, director) in to out_credits (created if necessary). /// Also return a string list of the names only. @@ -607,58 +608,58 @@ static string_list_t * /// /// Returns string list of {"Fred Foo", "Simon Scott", "Vic Vicson"} and /// out_credits containing the names and actor/director. -__attribute__((warn_unused_result)) -static string_list_t * -_xmltv_parse_credits(htsmsg_t **out_credits, htsmsg_t *tags) -{ - htsmsg_t *credits = htsmsg_get_map(tags, "credits"); +__attribute__((warn_unused_result)) static string_list_t* +_xmltv_parse_credits(htsmsg_t** out_credits, htsmsg_t* tags) { + htsmsg_t* credits = htsmsg_get_map(tags, "credits"); if (!credits) return NULL; - htsmsg_t *credits_tags; - if (!(credits_tags = htsmsg_get_map(credits, "tags"))) + htsmsg_t* credits_tags; + if (!(credits_tags = htsmsg_get_map(credits, "tags"))) return NULL; - string_list_t *credits_names = NULL; - htsmsg_t *e; - htsmsg_field_t *f; + string_list_t* credits_names = NULL; + htsmsg_t* e; + htsmsg_field_t* f; HTSMSG_FOREACH(f, credits_tags) { - const char *fname = htsmsg_field_name(f); - if ((!strcmp(fname, "actor") || - !strcmp(fname, "director") || - !strcmp(fname, "guest") || - !strcmp(fname, "presenter") || - !strcmp(fname, "writer") - ) && - (e = htsmsg_get_map_by_field(f))) { + const char* fname = htsmsg_field_name(f); + if ((!strcmp(fname, "actor") || !strcmp(fname, "director") || !strcmp(fname, "guest") || + !strcmp(fname, "presenter") || !strcmp(fname, "writer")) && + (e = htsmsg_get_map_by_field(f))) { const char* str = htsmsg_get_str(e, "cdata"); - char *s, *str2 = NULL, *saveptr = NULL; - if (str == NULL) continue; + char * s, *str2 = NULL, *saveptr = NULL; + if (str == NULL) + continue; if (strstr(str, "|") == 0) { if (strlen(str) > 255) { - str2 = strdup(str); + str2 = strdup(str); str2[255] = '\0'; - str = str2; + str = str2; } - if (!credits_names) credits_names = string_list_create(); + if (!credits_names) + credits_names = string_list_create(); string_list_insert(credits_names, str); - if (!*out_credits) *out_credits = htsmsg_create_map(); + if (!*out_credits) + *out_credits = htsmsg_create_map(); htsmsg_add_str(*out_credits, str, fname); } else { - for (s = str2 = strdup(str); ; s = NULL) { + for (s = str2 = strdup(str);; s = NULL) { s = strtok_r(s, "|", &saveptr); - if (s == NULL) break; + if (s == NULL) + break; if (strlen(s) > 255) s[255] = '\0'; - if (!credits_names) credits_names = string_list_create(); + if (!credits_names) + credits_names = string_list_create(); string_list_insert(credits_names, s); - if (!*out_credits) *out_credits = htsmsg_create_map(); + if (!*out_credits) + *out_credits = htsmsg_create_map(); htsmsg_add_str(*out_credits, s, fname); } } @@ -674,20 +675,21 @@ _xmltv_parse_credits(htsmsg_t **out_credits, htsmsg_t *tags) * it to the desc with a prefix of name. */ static void -xmltv_appendit(lang_str_t **_desc, string_list_t *list, - const char *name, lang_str_t *summary) -{ - lang_str_t *desc, *lstr; - lang_str_ele_t *e; - const char *s; - if (!list) return; - char *str = string_list_2_csv(list, ',', 1); - if (!str) return; +xmltv_appendit(lang_str_t** _desc, string_list_t* list, const char* name, lang_str_t* summary) { + lang_str_t * desc, *lstr; + lang_str_ele_t* e; + const char* s; + if (!list) + return; + char* str = string_list_2_csv(list, ',', 1); + if (!str) + return; desc = NULL; lstr = *_desc ?: summary; if (lstr) { - RB_FOREACH(e, lstr, link) { - if (!desc) desc = lang_str_create(); + RB_FOREACH (e, lstr, link) { + if (!desc) + desc = lang_str_create(); s = *_desc ? lang_str_get_only(*_desc, e->lang) : NULL; if (s) { lang_str_append(desc, s, e->lang); @@ -707,27 +709,29 @@ xmltv_appendit(lang_str_t **_desc, string_list_t *list, /** * Parse tags inside of a programme */ -static int _xmltv_parse_programme_tags - (epggrab_module_t *mod, channel_t *ch, htsmsg_t *tags, - time_t start, time_t stop, const char *icon, - epggrab_stats_t *stats) -{ - const int scrape_extra = ((epggrab_module_int_t *)mod)->xmltv_scrape_extra; - const int scrape_onto_desc = ((epggrab_module_int_t *)mod)->xmltv_scrape_onto_desc; - const int use_category_not_genre = ((epggrab_module_int_t *)mod)->xmltv_use_category_not_genre; - int save = 0; - epg_changes_t changes = 0; - epg_broadcast_t *ebc; - epg_genre_list_t *egl; +static int _xmltv_parse_programme_tags(epggrab_module_t* mod, + channel_t* ch, + htsmsg_t* tags, + time_t start, + time_t stop, + const char* icon, + epggrab_stats_t* stats) { + const int scrape_extra = ((epggrab_module_int_t*)mod)->xmltv_scrape_extra; + const int scrape_onto_desc = ((epggrab_module_int_t*)mod)->xmltv_scrape_onto_desc; + const int use_category_not_genre = ((epggrab_module_int_t*)mod)->xmltv_use_category_not_genre; + int save = 0; + epg_changes_t changes = 0; + epg_broadcast_t* ebc; + epg_genre_list_t* egl; epg_episode_num_t epnum; - epg_set_t *set; - char *suri = NULL, *uri = NULL; - lang_str_t *title = NULL; - lang_str_t *desc = NULL; - lang_str_t *summary = NULL; - lang_str_t *subtitle = NULL; - time_t first_aired = 0; - int8_t bw = -1; + epg_set_t* set; + char * suri = NULL, *uri = NULL; + lang_str_t* title = NULL; + lang_str_t* desc = NULL; + lang_str_t* summary = NULL; + lang_str_t* subtitle = NULL; + time_t first_aired = 0; + int8_t bw = -1; if (epg_channel_ignore_broadcast(ch, start)) return 0; @@ -752,10 +756,10 @@ static int _xmltv_parse_programme_tags * from programme such as credits and keywords. */ if (scrape_extra || scrape_onto_desc) { - htsmsg_t *credits = NULL; - string_list_t *credits_names = _xmltv_parse_credits(&credits, tags); - string_list_t *category = _xmltv_make_str_list_from_matching(tags, "category"); - string_list_t *keyword = _xmltv_make_str_list_from_matching(tags, "keyword"); + htsmsg_t* credits = NULL; + string_list_t* credits_names = _xmltv_parse_credits(&credits, tags); + string_list_t* category = _xmltv_make_str_list_from_matching(tags, "category"); + string_list_t* keyword = _xmltv_make_str_list_from_matching(tags, "keyword"); if (scrape_extra && credits) save |= epg_broadcast_set_credits(ebc, credits, &changes); @@ -764,7 +768,6 @@ static int _xmltv_parse_programme_tags if (scrape_extra && keyword) save |= epg_broadcast_set_keyword(ebc, keyword, &changes); - /* Append the details on to the description, mainly for legacy * clients. This allow you to view the details in the description * on old boxes/tablets that don't parse the newer fields or @@ -776,10 +779,14 @@ static int _xmltv_parse_programme_tags xmltv_appendit(&desc, keyword, N_("Keywords: "), summary); } - if (credits) htsmsg_destroy(credits); - if (credits_names) string_list_destroy(credits_names); - if (category) string_list_destroy(category); - if (keyword) string_list_destroy(keyword); + if (credits) + htsmsg_destroy(credits); + if (credits_names) + string_list_destroy(credits_names); + if (category) + string_list_destroy(category); + if (keyword) + string_list_destroy(keyword); #undef APPENDIT } /* desc */ @@ -798,11 +805,11 @@ static int _xmltv_parse_programme_tags save |= xmltv_parse_accessibility(ebc, tags, &changes); /* Misc */ - save |= _xmltv_parse_previously_shown(ebc, &first_aired, - htsmsg_get_map(tags, "previously-shown"), - &changes); - if (htsmsg_get_map(tags, "premiere") || - htsmsg_get_map(tags, "new")) + save |= _xmltv_parse_previously_shown(ebc, + &first_aired, + htsmsg_get_map(tags, "previously-shown"), + &changes); + if (htsmsg_get_map(tags, "premiere") || htsmsg_get_map(tags, "new")) save |= epg_broadcast_set_is_new(ebc, 1, &changes); /* @@ -884,55 +891,66 @@ static int _xmltv_parse_programme_tags stats->broadcasts.modified++; /* Cleanup */ - if (title) lang_str_destroy(title); - if (subtitle) lang_str_destroy(subtitle); - if (desc) lang_str_destroy(desc); - if (summary) lang_str_destroy(summary); + if (title) + lang_str_destroy(title); + if (subtitle) + lang_str_destroy(subtitle); + if (desc) + lang_str_destroy(desc); + if (summary) + lang_str_destroy(summary); return save; } /** * Parse a tag from xmltv */ -static int _xmltv_parse_programme - (epggrab_module_t *mod, htsmsg_t *body, epggrab_stats_t *stats) -{ - int chsave = 0, save = 0; - htsmsg_t *attribs, *tags, *subtag; - const char *s, *chid, *icon = NULL; - time_t start, stop; - channel_t *ch; - epggrab_channel_t *ec; - idnode_list_mapping_t *ilm; - - if(body == NULL) return 0; - - if((attribs = htsmsg_get_map(body, "attrib")) == NULL) return 0; - if((tags = htsmsg_get_map(body, "tags")) == NULL) return 0; - if((chid = htsmsg_get_str(attribs, "channel")) == NULL) return 0; - if((ec = epggrab_channel_find(mod, chid, 1, &chsave)) == NULL) return 0; +static int _xmltv_parse_programme(epggrab_module_t* mod, htsmsg_t* body, epggrab_stats_t* stats) { + int chsave = 0, save = 0; + htsmsg_t * attribs, *tags, *subtag; + const char * s, *chid, *icon = NULL; + time_t start, stop; + channel_t* ch; + epggrab_channel_t* ec; + idnode_list_mapping_t* ilm; + + if (body == NULL) + return 0; + + if ((attribs = htsmsg_get_map(body, "attrib")) == NULL) + return 0; + if ((tags = htsmsg_get_map(body, "tags")) == NULL) + return 0; + if ((chid = htsmsg_get_str(attribs, "channel")) == NULL) + return 0; + if ((ec = epggrab_channel_find(mod, chid, 1, &chsave)) == NULL) + return 0; if (chsave) { stats->channels.created++; stats->channels.modified++; } - if (!LIST_FIRST(&ec->channels)) return 0; - if((s = htsmsg_get_str(attribs, "start")) == NULL) return 0; + if (!LIST_FIRST(&ec->channels)) + return 0; + if ((s = htsmsg_get_str(attribs, "start")) == NULL) + return 0; start = _xmltv_str2time(s); - if((s = htsmsg_get_str(attribs, "stop")) == NULL) return 0; - stop = _xmltv_str2time(s); + if ((s = htsmsg_get_str(attribs, "stop")) == NULL) + return 0; + stop = _xmltv_str2time(s); - if((subtag = htsmsg_get_map(tags, "icon")) != NULL && - (attribs = htsmsg_get_map(subtag, "attrib")) != NULL) + if ((subtag = htsmsg_get_map(tags, "icon")) != NULL && + (attribs = htsmsg_get_map(subtag, "attrib")) != NULL) icon = htsmsg_get_str(attribs, "src"); - if(stop <= start || stop <= gclk()) return 0; + if (stop <= start || stop <= gclk()) + return 0; ec->laststamp = gclk(); - LIST_FOREACH(ilm, &ec->channels, ilm_in1_link) { - ch = (channel_t *)ilm->ilm_in2; - if (!ch->ch_enabled || ch->ch_epg_parent) continue; - save |= _xmltv_parse_programme_tags(mod, ch, tags, - start, stop, icon, stats); + LIST_FOREACH (ilm, &ec->channels, ilm_in1_link) { + ch = (channel_t*)ilm->ilm_in2; + if (!ch->ch_enabled || ch->ch_epg_parent) + continue; + save |= _xmltv_parse_programme_tags(mod, ch, tags, start, stop, icon, stats); } return save; } @@ -940,32 +958,37 @@ static int _xmltv_parse_programme /** * Parse a tag from xmltv */ -static int _xmltv_parse_channel - (epggrab_module_t *mod, htsmsg_t *body, epggrab_stats_t *stats) -{ - int save = 0, chnum = ((epggrab_module_ext_t *)mod)->xmltv_chnum; - htsmsg_t *attribs, *tags, *subtag; - const char *id, *name, *icon; - epggrab_channel_t *ch; - htsmsg_field_t *f; - htsmsg_t *dnames; - - if(body == NULL) return 0; - - if((attribs = htsmsg_get_map(body, "attrib")) == NULL) return 0; - if((id = htsmsg_get_str(attribs, "id")) == NULL) return 0; - if((tags = htsmsg_get_map(body, "tags")) == NULL) return 0; - if((ch = epggrab_channel_find(mod, id, 1, &save)) == NULL) return 0; +static int _xmltv_parse_channel(epggrab_module_t* mod, htsmsg_t* body, epggrab_stats_t* stats) { + int save = 0, chnum = ((epggrab_module_ext_t*)mod)->xmltv_chnum; + htsmsg_t * attribs, *tags, *subtag; + const char * id, *name, *icon; + epggrab_channel_t* ch; + htsmsg_field_t* f; + htsmsg_t* dnames; + + if (body == NULL) + return 0; + + if ((attribs = htsmsg_get_map(body, "attrib")) == NULL) + return 0; + if ((id = htsmsg_get_str(attribs, "id")) == NULL) + return 0; + if ((tags = htsmsg_get_map(body, "tags")) == NULL) + return 0; + if ((ch = epggrab_channel_find(mod, id, 1, &save)) == NULL) + return 0; ch->laststamp = gclk(); stats->channels.total++; - if (save) stats->channels.created++; + if (save) + stats->channels.created++; dnames = htsmsg_create_list(); HTSMSG_FOREACH(f, tags) { - if (!(subtag = htsmsg_field_get_map(f))) continue; + if (!(subtag = htsmsg_field_get_map(f))) + continue; if (strcmp(htsmsg_field_name(f), "display-name") == 0) { - name = htsmsg_get_str(subtag, "cdata"); - const char *cur = name; + name = htsmsg_get_str(subtag, "cdata"); + const char* cur = name; if (chnum && cur) { /* Some xmltv providers supply a display-name that is the @@ -999,23 +1022,23 @@ static int _xmltv_parse_channel if (major && (!*cur || (*cur == ' ' && chnum == 1))) { save |= epggrab_channel_set_number(ch, major, minor); /* Skip extra spaces between channel number and actual name */ - while (*cur == ' ') ++cur; + while (*cur == ' ') + ++cur; } } if (cur && *cur) htsmsg_add_str_exclusive(dnames, cur); - } - else if (strcmp(htsmsg_field_name(f), "icon") == 0) { - if ((attribs = htsmsg_get_map(subtag, "attrib")) != NULL && - (icon = htsmsg_get_str(attribs, "src")) != NULL) { + } else if (strcmp(htsmsg_field_name(f), "icon") == 0) { + if ((attribs = htsmsg_get_map(subtag, "attrib")) != NULL && + (icon = htsmsg_get_str(attribs, "src")) != NULL) { save |= epggrab_channel_set_icon(ch, icon); } } } HTSMSG_FOREACH(f, dnames) { - const char *s; + const char* s; if ((s = htsmsg_field_get_str(f)) != NULL) save |= epggrab_channel_set_name(ch, s); @@ -1030,14 +1053,12 @@ static int _xmltv_parse_channel /** * */ -static int _xmltv_parse_tv - (epggrab_module_t *mod, htsmsg_t *body, epggrab_stats_t *stats) -{ - int gsave = 0, save; - htsmsg_t *tags; - htsmsg_field_t *f; - - if((tags = htsmsg_get_map(body, "tags")) == NULL) +static int _xmltv_parse_tv(epggrab_module_t* mod, htsmsg_t* body, epggrab_stats_t* stats) { + int gsave = 0, save; + htsmsg_t* tags; + htsmsg_field_t* f; + + if ((tags = htsmsg_get_map(body, "tags")) == NULL) return 0; tvh_mutex_lock(&global_lock); @@ -1046,14 +1067,15 @@ static int _xmltv_parse_tv HTSMSG_FOREACH(f, tags) { save = 0; - if(!strcmp(htsmsg_field_name(f), "channel")) { + if (!strcmp(htsmsg_field_name(f), "channel")) { tvh_mutex_lock(&global_lock); save = _xmltv_parse_channel(mod, htsmsg_get_map_by_field(f), stats); tvh_mutex_unlock(&global_lock); - } else if(!strcmp(htsmsg_field_name(f), "programme")) { + } else if (!strcmp(htsmsg_field_name(f), "programme")) { tvh_mutex_lock(&global_lock); save = _xmltv_parse_programme(mod, htsmsg_get_map_by_field(f), stats); - if (save) epg_updated(); + if (save) + epg_updated(); tvh_mutex_unlock(&global_lock); } gsave |= save; @@ -1066,15 +1088,13 @@ static int _xmltv_parse_tv return gsave; } -static int _xmltv_parse - ( void *mod, htsmsg_t *data, epggrab_stats_t *stats ) -{ +static int _xmltv_parse(void* mod, htsmsg_t* data, epggrab_stats_t* stats) { htsmsg_t *tags, *tv; - if((tags = htsmsg_get_map(data, "tags")) == NULL) + if ((tags = htsmsg_get_map(data, "tags")) == NULL) return 0; - if((tv = htsmsg_get_map(tags, "tv")) == NULL) + if ((tv = htsmsg_get_map(tags, "tv")) == NULL) return 0; return _xmltv_parse_tv(mod, tv, stats); @@ -1085,147 +1105,122 @@ static int _xmltv_parse * ***********************************************************************/ #define DN_CHNUM_NAME N_("Channel numbers (heuristic)") -#define DN_CHNUM_DESC \ +#define DN_CHNUM_DESC \ N_("Try to obtain channel numbers from the display-name xml tag. " \ "If the first word is number, it is used as the channel number.") #define SCRAPE_EXTRA_NAME N_("Scrape credits and extra information") -#define SCRAPE_EXTRA_DESC \ - N_("Obtain list of credits (actors, etc.), keywords and extra information from the xml tags (if available). " \ - "Some xmltv providers supply a list of actors and additional keywords to " \ - "describe programmes. This option will retrieve this additional information. " \ - "This can be very detailed (20+ actors per movie) " \ - "and will take a lot of memory and resources on this box, and will " \ - "pass this information to your client machines and GUI too, using " \ - "memory and resources on those boxes too. " \ +#define SCRAPE_EXTRA_DESC \ + N_("Obtain list of credits (actors, etc.), keywords and extra information from the xml tags " \ + "(if available). " \ + "Some xmltv providers supply a list of actors and additional keywords to " \ + "describe programmes. This option will retrieve this additional information. " \ + "This can be very detailed (20+ actors per movie) " \ + "and will take a lot of memory and resources on this box, and will " \ + "pass this information to your client machines and GUI too, using " \ + "memory and resources on those boxes too. " \ "Do not enable on low-spec machines.") #define SCRAPE_ONTO_DESC_NAME N_("Alter programme description to include detailed information") -#define SCRAPE_ONTO_DESC_DESC \ - N_("If enabled then this will alter the programme descriptions to " \ - "include information about actors, keywords and categories (if available from the xmltv file). " \ - "This is useful for legacy clients that can not parse newer Tvheadend messages " \ - "containing this information or do not display the information. "\ - "For example the modified description might include 'Starring: Lorem Ipsum'. " \ - "The description is altered for all clients, both legacy, modern, and GUI. "\ - "Enabling scraping of detailed information can use significant resources (memory and CPU). "\ - "You should not enable this if you use 'duplicate detect if different description' " \ +#define SCRAPE_ONTO_DESC_DESC \ + N_("If enabled then this will alter the programme descriptions to " \ + "include information about actors, keywords and categories (if available from the xmltv " \ + "file). " \ + "This is useful for legacy clients that can not parse newer Tvheadend messages " \ + "containing this information or do not display the information. " \ + "For example the modified description might include 'Starring: Lorem Ipsum'. " \ + "The description is altered for all clients, both legacy, modern, and GUI. " \ + "Enabling scraping of detailed information can use significant resources (memory and CPU). " \ + "You should not enable this if you use 'duplicate detect if different description' " \ "since the descriptions will change due to added information.") #define USE_CATEGORY_NOT_GENRE_NAME N_("Use category instead of genre") -#define USE_CATEGORY_NOT_GENRE_DESC \ - N_("Some xmltv providers supply multiple category tags, however mapping "\ - "to genres is imprecise and many categories have no genre mapping "\ - "at all. Some frontends will only pass through categories " \ - "unchanged if there is no genre so for these we can " \ - "avoid the genre mappings and only use categories. " \ - "If this option is not ticked then we continue to map " \ +#define USE_CATEGORY_NOT_GENRE_DESC \ + N_("Some xmltv providers supply multiple category tags, however mapping " \ + "to genres is imprecise and many categories have no genre mapping " \ + "at all. Some frontends will only pass through categories " \ + "unchanged if there is no genre so for these we can " \ + "avoid the genre mappings and only use categories. " \ + "If this option is not ticked then we continue to map " \ "xmltv categories to genres and supply both to clients.") -static htsmsg_t * -xmltv_dn_chnum_list ( void *o, const char *lang ) -{ +static htsmsg_t* xmltv_dn_chnum_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Disabled"), 0 }, - { N_("First word"), 1 }, - { N_("Only digits"), 2 }, + {N_("Disabled"), 0}, + {N_("First word"), 1}, + {N_("Only digits"), 2}, }; return strtab2htsmsg(tab, 1, lang); } -const idclass_t epggrab_mod_int_xmltv_class = { - .ic_super = &epggrab_mod_int_class, - .ic_class = "epggrab_mod_int_xmltv", - .ic_caption = N_("EPG - Internal XMLTV EPG Grabber"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "dn_chnum", - .name = DN_CHNUM_NAME, - .desc = DN_CHNUM_DESC, - .off = offsetof(epggrab_module_int_t, xmltv_chnum), - .list = xmltv_dn_chnum_list, - .opts = PO_DOC_NLIST, - .group = 1 - }, - { - .type = PT_BOOL, - .id = "scrape_extra", - .name = SCRAPE_EXTRA_NAME, - .desc = SCRAPE_EXTRA_DESC, - .off = offsetof(epggrab_module_int_t, xmltv_scrape_extra), - .group = 1 - }, - { - .type = PT_BOOL, - .id = "scrape_onto_desc", - .name = SCRAPE_ONTO_DESC_NAME, - .desc = SCRAPE_ONTO_DESC_DESC, - .off = offsetof(epggrab_module_int_t, xmltv_scrape_onto_desc), - .group = 1 - }, - { - .type = PT_BOOL, - .id = "use_category_not_genre", - .name = USE_CATEGORY_NOT_GENRE_NAME, - .desc = USE_CATEGORY_NOT_GENRE_DESC, - .off = offsetof(epggrab_module_int_t, xmltv_use_category_not_genre), - .group = 1 - }, - {} - } -}; - -const idclass_t epggrab_mod_ext_xmltv_class = { - .ic_super = &epggrab_mod_ext_class, - .ic_class = "epggrab_mod_ext_xmltv", - .ic_caption = N_("EPG - External XMLTV EPG Grabber"), - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "dn_chnum", - .name = DN_CHNUM_NAME, - .desc = DN_CHNUM_DESC, - .off = offsetof(epggrab_module_ext_t, xmltv_chnum), - .opts = PO_DOC_NLIST, - .group = 1 - }, - { - .type = PT_BOOL, - .id = "scrape_extra", - .name = SCRAPE_EXTRA_NAME, - .desc = SCRAPE_EXTRA_DESC, - .off = offsetof(epggrab_module_int_t, xmltv_scrape_extra), - .group = 1 - }, - { - .type = PT_BOOL, - .id = "scrape_onto_desc", - .name = SCRAPE_ONTO_DESC_NAME, - .desc = SCRAPE_ONTO_DESC_DESC, - .off = offsetof(epggrab_module_int_t, xmltv_scrape_onto_desc), - .group = 1 - }, - { - .type = PT_BOOL, - .id = "use_category_not_genre", - .name = USE_CATEGORY_NOT_GENRE_NAME, - .desc = USE_CATEGORY_NOT_GENRE_DESC, - .off = offsetof(epggrab_module_int_t, xmltv_use_category_not_genre), - .group = 1 - }, - {} - } -}; - -static void _xmltv_load_grabbers ( void ) -{ - int outlen = -1, rd = -1; - size_t i, p, n; - char *outbuf; - char name[1000]; - char *tmp, *tmp2 = NULL, *path; - epggrab_module_t *mod; +const idclass_t epggrab_mod_int_xmltv_class = {.ic_super = &epggrab_mod_int_class, + .ic_class = "epggrab_mod_int_xmltv", + .ic_caption = N_("EPG - Internal XMLTV EPG Grabber"), + .ic_properties = (const property_t[]){{.type = PT_INT, + .id = "dn_chnum", + .name = DN_CHNUM_NAME, + .desc = DN_CHNUM_DESC, + .off = offsetof(epggrab_module_int_t, xmltv_chnum), + .list = xmltv_dn_chnum_list, + .opts = PO_DOC_NLIST, + .group = 1}, + {.type = PT_BOOL, + .id = "scrape_extra", + .name = SCRAPE_EXTRA_NAME, + .desc = SCRAPE_EXTRA_DESC, + .off = offsetof(epggrab_module_int_t, xmltv_scrape_extra), + .group = 1}, + {.type = PT_BOOL, + .id = "scrape_onto_desc", + .name = SCRAPE_ONTO_DESC_NAME, + .desc = SCRAPE_ONTO_DESC_DESC, + .off = offsetof(epggrab_module_int_t, xmltv_scrape_onto_desc), + .group = 1}, + {.type = PT_BOOL, + .id = "use_category_not_genre", + .name = USE_CATEGORY_NOT_GENRE_NAME, + .desc = USE_CATEGORY_NOT_GENRE_DESC, + .off = offsetof(epggrab_module_int_t, xmltv_use_category_not_genre), + .group = 1}, + {}}}; + +const idclass_t epggrab_mod_ext_xmltv_class = {.ic_super = &epggrab_mod_ext_class, + .ic_class = "epggrab_mod_ext_xmltv", + .ic_caption = N_("EPG - External XMLTV EPG Grabber"), + .ic_properties = (const property_t[]){{.type = PT_BOOL, + .id = "dn_chnum", + .name = DN_CHNUM_NAME, + .desc = DN_CHNUM_DESC, + .off = offsetof(epggrab_module_ext_t, xmltv_chnum), + .opts = PO_DOC_NLIST, + .group = 1}, + {.type = PT_BOOL, + .id = "scrape_extra", + .name = SCRAPE_EXTRA_NAME, + .desc = SCRAPE_EXTRA_DESC, + .off = offsetof(epggrab_module_int_t, xmltv_scrape_extra), + .group = 1}, + {.type = PT_BOOL, + .id = "scrape_onto_desc", + .name = SCRAPE_ONTO_DESC_NAME, + .desc = SCRAPE_ONTO_DESC_DESC, + .off = offsetof(epggrab_module_int_t, xmltv_scrape_onto_desc), + .group = 1}, + {.type = PT_BOOL, + .id = "use_category_not_genre", + .name = USE_CATEGORY_NOT_GENRE_NAME, + .desc = USE_CATEGORY_NOT_GENRE_DESC, + .off = offsetof(epggrab_module_int_t, xmltv_use_category_not_genre), + .group = 1}, + {}}}; + +static void _xmltv_load_grabbers(void) { + int outlen = -1, rd = -1; + size_t i, p, n; + char* outbuf; + char name[1000]; + char * tmp, *tmp2 = NULL, *path; + epggrab_module_t* mod; /* Load data */ if (spawn_and_give_stdout(XMLTV_FIND, NULL, NULL, &rd, NULL, 1) >= 0) @@ -1234,67 +1229,84 @@ static void _xmltv_load_grabbers ( void ) close(rd); /* Process */ - if ( outlen > 0 ) { + if (outlen > 0) { p = n = i = 0; - while ( i < outlen ) { - if ( outbuf[i] == '\n' || outbuf[i] == '\0' ) { + while (i < outlen) { + if (outbuf[i] == '\n' || outbuf[i] == '\0') { outbuf[i] = '\0'; sprintf(name, "XMLTV: %s", &outbuf[n]); - epggrab_module_int_create(NULL, &epggrab_mod_int_xmltv_class, - &outbuf[p], LS_XMLTV, "xmltv", - name, 3, &outbuf[p], - NULL, _xmltv_parse, NULL); + epggrab_module_int_create(NULL, + &epggrab_mod_int_xmltv_class, + &outbuf[p], + LS_XMLTV, + "xmltv", + name, + 3, + &outbuf[p], + NULL, + _xmltv_parse, + NULL); p = n = i + 1; - } else if ( outbuf[i] == '\\') { + } else if (outbuf[i] == '\\') { memmove(outbuf, outbuf + 1, strlen(outbuf)); if (outbuf[i]) i++; continue; - } else if ( outbuf[i] == '|' ) { + } else if (outbuf[i] == '|') { outbuf[i] = '\0'; - n = i + 1; + n = i + 1; } i++; } free(outbuf); - /* Internal search */ + /* Internal search */ } else if ((tmp = getenv("PATH"))) { tvhdebug(LS_XMLTV, "using internal grab search"); - char bin[PATH_MAX]; - char *argv[] = { - NULL, - (char *)"--description", - NULL - }; - path = strdup(tmp); - tmp = strtok_r(path, ":", &tmp2); + char bin[PATH_MAX]; + char* argv[] = {NULL, (char*)"--description", NULL}; + path = strdup(tmp); + tmp = strtok_r(path, ":", &tmp2); while (tmp) { - DIR *dir; - struct dirent *de; - struct stat st; + DIR* dir; + struct dirent* de; + struct stat st; if ((dir = opendir(tmp))) { while ((de = readdir(dir))) { - if (strstr(de->d_name, XMLTV_GRAB) != de->d_name) continue; - if (de->d_name[0] && de->d_name[strlen(de->d_name)-1] == '~') continue; + if (strstr(de->d_name, XMLTV_GRAB) != de->d_name) + continue; + if (de->d_name[0] && de->d_name[strlen(de->d_name) - 1] == '~') + continue; snprintf(bin, sizeof(bin), "%s/%s", tmp, de->d_name); - if (stat(bin, &st)) continue; - if (!(st.st_mode & S_IEXEC)) continue; - if (!S_ISREG(st.st_mode)) continue; + if (stat(bin, &st)) + continue; + if (!(st.st_mode & S_IEXEC)) + continue; + if (!S_ISREG(st.st_mode)) + continue; rd = -1; if (spawn_and_give_stdout(bin, argv, NULL, &rd, NULL, 1) >= 0 && (outlen = file_readall(rd, &outbuf)) > 0) { close(rd); - if (outbuf[outlen-1] == '\n') outbuf[outlen-1] = '\0'; + if (outbuf[outlen - 1] == '\n') + outbuf[outlen - 1] = '\0'; snprintf(name, sizeof(name), "XMLTV: %s", outbuf); mod = epggrab_module_find_by_id(bin); if (mod) { - free((void *)mod->name); + free((void*)mod->name); mod->name = strdup(outbuf); } else { - epggrab_module_int_create(NULL, &epggrab_mod_int_xmltv_class, - bin, LS_XMLTV, "xmltv", name, 3, bin, - NULL, _xmltv_parse, NULL); + epggrab_module_int_create(NULL, + &epggrab_mod_int_xmltv_class, + bin, + LS_XMLTV, + "xmltv", + name, + 3, + bin, + NULL, + _xmltv_parse, + NULL); } free(outbuf); } else { @@ -1310,22 +1322,25 @@ static void _xmltv_load_grabbers ( void ) } } -void xmltv_init ( void ) -{ +void xmltv_init(void) { /* External module */ - epggrab_module_ext_create(NULL, &epggrab_mod_ext_xmltv_class, - "xmltv", LS_XMLTV, "xmltv", "XMLTV", 3, "xmltv", - _xmltv_parse, NULL); + epggrab_module_ext_create(NULL, + &epggrab_mod_ext_xmltv_class, + "xmltv", + LS_XMLTV, + "xmltv", + "XMLTV", + 3, + "xmltv", + _xmltv_parse, + NULL); /* Standard modules */ _xmltv_load_grabbers(); } -void xmltv_done ( void ) -{ -} +void xmltv_done(void) {} -void xmltv_load ( void ) -{ +void xmltv_load(void) { epggrab_module_channels_load("xmltv"); } diff --git a/src/epggrab/otamux.c b/src/epggrab/otamux.c index aa7d94c81..43931eed3 100644 --- a/src/epggrab/otamux.c +++ b/src/epggrab/otamux.c @@ -32,90 +32,80 @@ #include #include -#define EPGGRAB_OTA_MIN_TIMEOUT 30 -#define EPGGRAB_OTA_MAX_TIMEOUT 7200 +#define EPGGRAB_OTA_MIN_TIMEOUT 30 +#define EPGGRAB_OTA_MAX_TIMEOUT 7200 -#define EPGGRAB_OTA_DONE_COMPLETE 0 -#define EPGGRAB_OTA_DONE_TIMEOUT 1 -#define EPGGRAB_OTA_DONE_NO_DATA 2 -#define EPGGRAB_OTA_DONE_STOLEN 3 +#define EPGGRAB_OTA_DONE_COMPLETE 0 +#define EPGGRAB_OTA_DONE_TIMEOUT 1 +#define EPGGRAB_OTA_DONE_NO_DATA 2 +#define EPGGRAB_OTA_DONE_STOLEN 3 -typedef TAILQ_HEAD(epggrab_ota_head,epggrab_ota_mux) epggrab_ota_head_t; +typedef TAILQ_HEAD(epggrab_ota_head, epggrab_ota_mux) epggrab_ota_head_t; -cron_multi_t *epggrab_ota_cron_multi; +cron_multi_t* epggrab_ota_cron_multi; -RB_HEAD(,epggrab_ota_mux) epggrab_ota_all; -epggrab_ota_head_t epggrab_ota_pending; -epggrab_ota_head_t epggrab_ota_active; +RB_HEAD(, epggrab_ota_mux) epggrab_ota_all; +epggrab_ota_head_t epggrab_ota_pending; +epggrab_ota_head_t epggrab_ota_active; -mtimer_t epggrab_ota_kick_timer; -gtimer_t epggrab_ota_start_timer; +mtimer_t epggrab_ota_kick_timer; +gtimer_t epggrab_ota_start_timer; -int epggrab_ota_running; -int epggrab_ota_pending_flag; +int epggrab_ota_running; +int epggrab_ota_pending_flag; -tvh_mutex_t epggrab_ota_mutex; +tvh_mutex_t epggrab_ota_mutex; -//If the pointer is not null, translation values have also been loaded. -unsigned char *epggrab_ota_genre_translation = NULL; +// If the pointer is not null, translation values have also been loaded. +unsigned char* epggrab_ota_genre_translation = NULL; SKEL_DECLARE(epggrab_ota_mux_skel, epggrab_ota_mux_t); SKEL_DECLARE(epggrab_svc_link_skel, epggrab_ota_svc_link_t); -static void epggrab_ota_kick ( int delay ); +static void epggrab_ota_kick(int delay); -static void epggrab_ota_timeout_cb ( void *p ); -static void epggrab_ota_data_timeout_cb ( void *p ); -static void epggrab_ota_handlers_timeout_cb ( void *p ); -static void epggrab_ota_kick_cb ( void *p ); +static void epggrab_ota_timeout_cb(void* p); +static void epggrab_ota_data_timeout_cb(void* p); +static void epggrab_ota_handlers_timeout_cb(void* p); +static void epggrab_ota_kick_cb(void* p); -static void epggrab_mux_start ( mpegts_mux_t *mm, void *p ); +static void epggrab_mux_start(mpegts_mux_t* mm, void* p); -static void epggrab_ota_save ( epggrab_ota_mux_t *ota ); +static void epggrab_ota_save(epggrab_ota_mux_t* ota); -static void epggrab_ota_free ( epggrab_ota_head_t *head, epggrab_ota_mux_t *ota ); +static void epggrab_ota_free(epggrab_ota_head_t* head, epggrab_ota_mux_t* ota); /* ************************************************************************** * Utilities * *************************************************************************/ -epggrab_ota_map_t *epggrab_ota_find_map - ( epggrab_ota_mux_t *om, epggrab_module_ota_t *m ) -{ - epggrab_ota_map_t *map; +epggrab_ota_map_t* epggrab_ota_find_map(epggrab_ota_mux_t* om, epggrab_module_ota_t* m) { + epggrab_ota_map_t* map; - LIST_FOREACH(map, &om->om_modules, om_link) + LIST_FOREACH (map, &om->om_modules, om_link) if (map->om_module == m) return map; return NULL; } -htsmsg_t *epggrab_ota_module_id_list( const char *lang ) -{ - htsmsg_t *l = eit_module_id_list(lang); +htsmsg_t* epggrab_ota_module_id_list(const char* lang) { + htsmsg_t* l = eit_module_id_list(lang); htsmsg_concat(l, opentv_module_id_list(lang)); htsmsg_concat(l, psip_module_id_list(lang)); return l; } -const char *epggrab_ota_check_module_id( const char *id ) -{ - return eit_check_module_id(id) ?: - opentv_check_module_id(id) ?: - psip_check_module_id(id); +const char* epggrab_ota_check_module_id(const char* id) { + return eit_check_module_id(id) ?: opentv_check_module_id(id) ?: psip_check_module_id(id); } -static int -om_id_cmp ( epggrab_ota_mux_t *a, epggrab_ota_mux_t *b ) -{ +static int om_id_cmp(epggrab_ota_mux_t* a, epggrab_ota_mux_t* b) { return uuid_cmp(&a->om_mux_uuid, &b->om_mux_uuid); } -static int -om_mux_cmp ( epggrab_ota_mux_t *a, epggrab_ota_mux_t *b ) -{ - mpegts_mux_t *a1 = mpegts_mux_find0(&a->om_mux_uuid); - mpegts_mux_t *b1 = mpegts_mux_find0(&b->om_mux_uuid); +static int om_mux_cmp(epggrab_ota_mux_t* a, epggrab_ota_mux_t* b) { + mpegts_mux_t* a1 = mpegts_mux_find0(&a->om_mux_uuid); + mpegts_mux_t* b1 = mpegts_mux_find0(&b->om_mux_uuid); if (a1 == NULL || b1 == NULL) { if (a1 == NULL && b1 == NULL) return 0; @@ -124,15 +114,11 @@ om_mux_cmp ( epggrab_ota_mux_t *a, epggrab_ota_mux_t *b ) return mpegts_mux_compare(a1, b1); } -static int -om_svcl_cmp ( epggrab_ota_svc_link_t *a, epggrab_ota_svc_link_t *b ) -{ +static int om_svcl_cmp(epggrab_ota_svc_link_t* a, epggrab_ota_svc_link_t* b) { return uuid_cmp(&a->uuid, &b->uuid); } -static int -epggrab_ota_timeout_get ( void ) -{ +static int epggrab_ota_timeout_get(void) { int timeout = epggrab_conf.ota_timeout; if (timeout < EPGGRAB_OTA_MIN_TIMEOUT) @@ -143,10 +129,8 @@ epggrab_ota_timeout_get ( void ) return timeout; } -void -epggrab_ota_free_eit_plist ( epggrab_ota_mux_t *ota ) -{ - epggrab_ota_mux_eit_plist_t *plist; +void epggrab_ota_free_eit_plist(epggrab_ota_mux_t* ota) { + epggrab_ota_mux_eit_plist_t* plist; while ((plist = LIST_FIRST(&ota->om_eit_plist)) != NULL) { LIST_REMOVE(plist, link); @@ -154,10 +138,8 @@ epggrab_ota_free_eit_plist ( epggrab_ota_mux_t *ota ) } } -static int -epggrab_ota_queue_one( epggrab_ota_mux_t *om ) -{ - om->om_done = 0; +static int epggrab_ota_queue_one(epggrab_ota_mux_t* om) { + om->om_done = 0; om->om_requeue = 1; if (om->om_q_type != EPGGRAB_OTA_MUX_IDLE) return 0; @@ -166,19 +148,16 @@ epggrab_ota_queue_one( epggrab_ota_mux_t *om ) return 1; } -epggrab_ota_mux_t *epggrab_ota_find_mux ( mpegts_mux_t *mm ) -{ +epggrab_ota_mux_t* epggrab_ota_find_mux(mpegts_mux_t* mm) { epggrab_ota_mux_t *om, tmp; tmp.om_mux_uuid = mm->mm_id.in_uuid; - om = RB_FIND(&epggrab_ota_all, &tmp, om_global_link, om_id_cmp); + om = RB_FIND(&epggrab_ota_all, &tmp, om_global_link, om_id_cmp); return om; } -void -epggrab_ota_queue_mux( mpegts_mux_t *mm ) -{ - epggrab_ota_mux_t *om; - int epg_flag; +void epggrab_ota_queue_mux(mpegts_mux_t* mm) { + epggrab_ota_mux_t* om; + int epg_flag; if (!mm) return; @@ -193,21 +172,17 @@ epggrab_ota_queue_mux( mpegts_mux_t *mm ) epggrab_ota_kick(4); } -static void -epggrab_ota_requeue ( void ) -{ - epggrab_ota_mux_t *om; +static void epggrab_ota_requeue(void) { + epggrab_ota_mux_t* om; /* * enqueue all muxes, but ommit the delayed ones (active+pending) */ - RB_FOREACH(om, &epggrab_ota_all, om_global_link) + RB_FOREACH (om, &epggrab_ota_all, om_global_link) epggrab_ota_queue_one(om); } -static void -epggrab_ota_kick ( int delay ) -{ +static void epggrab_ota_kick(int delay) { /* next round is pending? queue rest of ota muxes */ if (epggrab_ota_pending_flag) { epggrab_ota_pending_flag = 0; @@ -220,26 +195,24 @@ epggrab_ota_kick ( int delay ) mtimer_arm_rel(&epggrab_ota_kick_timer, epggrab_ota_kick_cb, NULL, sec2mono(delay)); } -static void -epggrab_ota_done ( epggrab_ota_mux_t *om, int reason ) -{ - static const char *reasons[] = { - [EPGGRAB_OTA_DONE_COMPLETE] = "complete", - [EPGGRAB_OTA_DONE_TIMEOUT] = "timeout", - [EPGGRAB_OTA_DONE_NO_DATA] = "no data", - [EPGGRAB_OTA_DONE_STOLEN] = "stolen" - }; - char ubuf[UUID_HEX_SIZE]; - mpegts_mux_t *mm; - epggrab_ota_map_t *map; +static void epggrab_ota_done(epggrab_ota_mux_t* om, int reason) { + static const char* reasons[] = {[EPGGRAB_OTA_DONE_COMPLETE] = "complete", + [EPGGRAB_OTA_DONE_TIMEOUT] = "timeout", + [EPGGRAB_OTA_DONE_NO_DATA] = "no data", + [EPGGRAB_OTA_DONE_STOLEN] = "stolen"}; + char ubuf[UUID_HEX_SIZE]; + mpegts_mux_t* mm; + epggrab_ota_map_t* map; if (om->om_save) epggrab_ota_save(om); mm = mpegts_mux_find0(&om->om_mux_uuid); if (mm == NULL) { - tvhdebug(LS_EPGGRAB, "unable to find mux %s (grab done: %s)", - uuid_get_hex(&om->om_mux_uuid, ubuf), reasons[reason]); + tvhdebug(LS_EPGGRAB, + "unable to find mux %s (grab done: %s)", + uuid_get_hex(&om->om_mux_uuid, ubuf), + reasons[reason]); return; } tvhdebug(LS_EPGGRAB, "grab done for %s (%s)", mm->mm_nicename, reasons[reason]); @@ -251,7 +224,7 @@ epggrab_ota_done ( epggrab_ota_mux_t *om, int reason ) assert(om->om_q_type == EPGGRAB_OTA_MUX_ACTIVE); TAILQ_REMOVE(&epggrab_ota_active, om, om_q_link); om->om_q_type = EPGGRAB_OTA_MUX_IDLE; - LIST_FOREACH(map, &om->om_modules, om_link) + LIST_FOREACH (map, &om->om_modules, om_link) if (map->om_module->stop) map->om_module->stop(map, mm); if (reason == EPGGRAB_OTA_DONE_STOLEN) { @@ -264,10 +237,12 @@ epggrab_ota_done ( epggrab_ota_mux_t *om, int reason ) } } else if (reason == EPGGRAB_OTA_DONE_TIMEOUT) { om->om_requeue = 0; - LIST_FOREACH(map, &om->om_modules, om_link) + LIST_FOREACH (map, &om->om_modules, om_link) if (!map->om_complete) - tvhwarn(LS_EPGGRAB, "%s - data completion timeout for %s", - map->om_module->name, mm->mm_nicename); + tvhwarn(LS_EPGGRAB, + "%s - data completion timeout for %s", + map->om_module->name, + mm->mm_nicename); } else { om->om_requeue = 0; } @@ -280,9 +255,7 @@ epggrab_ota_done ( epggrab_ota_mux_t *om, int reason ) epggrab_ota_kick(1); } -static void -epggrab_ota_complete_mark ( epggrab_ota_mux_t *om, int done ) -{ +static void epggrab_ota_complete_mark(epggrab_ota_mux_t* om, int done) { om->om_done = 1; if (!om->om_complete) { om->om_complete = 1; @@ -290,15 +263,13 @@ epggrab_ota_complete_mark ( epggrab_ota_mux_t *om, int done ) } } -static void -epggrab_ota_start ( epggrab_ota_mux_t *om, mpegts_mux_t *mm ) -{ - epggrab_module_t *m; - epggrab_module_ota_t *omod; - epggrab_ota_map_t *map; - char *modname = om->om_force_modname; - mpegts_mux_instance_t *mmi = mm->mm_active; - int grace; +static void epggrab_ota_start(epggrab_ota_mux_t* om, mpegts_mux_t* mm) { + epggrab_module_t* m; + epggrab_module_ota_t* omod; + epggrab_ota_map_t* map; + char* modname = om->om_force_modname; + mpegts_mux_instance_t* mmi = mm->mm_active; + int grace; /* In pending queue? Remove.. */ if (om->om_q_type == EPGGRAB_OTA_MUX_PENDING) @@ -307,30 +278,33 @@ epggrab_ota_start ( epggrab_ota_mux_t *om, mpegts_mux_t *mm ) assert(om->om_q_type == EPGGRAB_OTA_MUX_IDLE); TAILQ_INSERT_TAIL(&epggrab_ota_active, om, om_q_link); - om->om_q_type = EPGGRAB_OTA_MUX_ACTIVE; + om->om_q_type = EPGGRAB_OTA_MUX_ACTIVE; om->om_detected = 0; - grace = mpegts_input_grace(mmi->mmi_input, mm); - mtimer_arm_rel(&om->om_timer, epggrab_ota_timeout_cb, om, - sec2mono(epggrab_ota_timeout_get() + grace)); - mtimer_arm_rel(&om->om_data_timer, epggrab_ota_data_timeout_cb, om, - sec2mono(30 + grace)); /* 30 seconds to receive any EPG info */ + grace = mpegts_input_grace(mmi->mmi_input, mm); + mtimer_arm_rel(&om->om_timer, + epggrab_ota_timeout_cb, + om, + sec2mono(epggrab_ota_timeout_get() + grace)); + mtimer_arm_rel(&om->om_data_timer, + epggrab_ota_data_timeout_cb, + om, + sec2mono(30 + grace)); /* 30 seconds to receive any EPG info */ if (strempty(modname)) { - mtimer_arm_rel(&om->om_data_timer, epggrab_ota_handlers_timeout_cb, om, - sec2mono(5 + grace)); + mtimer_arm_rel(&om->om_data_timer, epggrab_ota_handlers_timeout_cb, om, sec2mono(5 + grace)); } else { mtimer_disarm(&om->om_data_timer); } if (modname) { - LIST_FOREACH(m, &epggrab_modules, link) + LIST_FOREACH (m, &epggrab_modules, link) if (!strcmp(m->id, modname)) { - epggrab_ota_register((epggrab_module_ota_t *)m, om, mm); + epggrab_ota_register((epggrab_module_ota_t*)m, om, mm); break; } } epggrab_ota_free_eit_plist(om); - LIST_FOREACH(map, &om->om_modules, om_link) { - omod = map->om_module; - map->om_first = 1; + LIST_FOREACH (map, &om->om_modules, om_link) { + omod = map->om_module; + map->om_first = 1; map->om_complete = 0; if (omod->enabled && !strempty(modname) && strcmp(modname, omod->id)) { map->om_complete = 1; @@ -350,43 +324,39 @@ epggrab_ota_start ( epggrab_ota_mux_t *om, mpegts_mux_t *mm ) * MPEG-TS listener * *************************************************************************/ -static void -epggrab_mux_start ( mpegts_mux_t *mm, void *p ) -{ - epggrab_module_t *m; - epggrab_ota_mux_t *ota; +static void epggrab_mux_start(mpegts_mux_t* mm, void* p) { + epggrab_module_t* m; + epggrab_ota_mux_t* ota; int epg_flag = mm->mm_is_epg(mm); if (epg_flag < 0 || epg_flag == MM_EPG_DISABLE) return; /* Already started */ - TAILQ_FOREACH(ota, &epggrab_ota_active, om_q_link) + TAILQ_FOREACH (ota, &epggrab_ota_active, om_q_link) if (!uuid_cmp(&ota->om_mux_uuid, &mm->mm_id.in_uuid)) return; /* Register all modules */ ota = NULL; - LIST_FOREACH(m, &epggrab_modules, link) { + LIST_FOREACH (m, &epggrab_modules, link) { if (m->type == EPGGRAB_OTA && m->enabled) - ota = epggrab_ota_register((epggrab_module_ota_t *)m, ota, mm); + ota = epggrab_ota_register((epggrab_module_ota_t*)m, ota, mm); } if (ota) epggrab_ota_start(ota, mm); } -static void -epggrab_mux_stop ( mpegts_mux_t *mm, void *p, int reason ) -{ - epggrab_ota_mux_t *ota; - int done = EPGGRAB_OTA_DONE_STOLEN; +static void epggrab_mux_stop(mpegts_mux_t* mm, void* p, int reason) { + epggrab_ota_mux_t* ota; + int done = EPGGRAB_OTA_DONE_STOLEN; if (reason == SM_CODE_NO_INPUT) done = EPGGRAB_OTA_DONE_NO_DATA; tvhtrace(LS_EPGGRAB, "mux %s (%p) stop", mm->mm_nicename, mm); - TAILQ_FOREACH(ota, &epggrab_ota_active, om_q_link) + TAILQ_FOREACH (ota, &epggrab_ota_active, om_q_link) if (!uuid_cmp(&ota->om_mux_uuid, &mm->mm_id.in_uuid)) { epggrab_ota_done(ota, done); break; @@ -397,12 +367,10 @@ epggrab_mux_stop ( mpegts_mux_t *mm, void *p, int reason ) * Module methods * *************************************************************************/ -epggrab_ota_mux_t * -epggrab_ota_register - ( epggrab_module_ota_t *mod, epggrab_ota_mux_t *ota, mpegts_mux_t *mm ) -{ - int save = 0; - epggrab_ota_map_t *map; +epggrab_ota_mux_t* +epggrab_ota_register(epggrab_module_ota_t* mod, epggrab_ota_mux_t* ota, mpegts_mux_t* mm) { + int save = 0; + epggrab_ota_map_t* map; if (!atomic_get(&epggrab_ota_running)) return NULL; @@ -415,7 +383,7 @@ epggrab_ota_register ota = RB_INSERT_SORTED(&epggrab_ota_all, epggrab_ota_mux_skel, om_global_link, om_id_cmp); if (!ota) { tvhinfo(LS_EPGGRAB, "%s - registering mux for OTA EPG", mm->mm_nicename); - ota = epggrab_ota_mux_skel; + ota = epggrab_ota_mux_skel; SKEL_USED(epggrab_ota_mux_skel); TAILQ_INSERT_SORTED(&epggrab_ota_pending, ota, om_q_link, om_mux_cmp); ota->om_q_type = EPGGRAB_OTA_MUX_PENDING; @@ -430,42 +398,44 @@ epggrab_ota_register if (!map) { map = calloc(1, sizeof(epggrab_ota_map_t)); RB_INIT(&map->om_svcs); - map->om_module = mod; + map->om_module = mod; LIST_INSERT_HEAD(&ota->om_modules, map, om_link); save = 1; } /* Save config */ - if (save) epggrab_ota_save(ota); + if (save) + epggrab_ota_save(ota); return ota; } -void -epggrab_ota_complete - ( epggrab_module_ota_t *mod, epggrab_ota_mux_t *ota ) -{ - int done = 1; - epggrab_ota_map_t *map; +void epggrab_ota_complete(epggrab_module_ota_t* mod, epggrab_ota_mux_t* ota) { + int done = 1; + epggrab_ota_map_t* map; lock_assert(&global_lock); if (!ota->om_complete) tvhdebug(mod->subsys, "%s: grab complete", mod->id); /* Test for completion */ - LIST_FOREACH(map, &ota->om_modules, om_link) { + LIST_FOREACH (map, &ota->om_modules, om_link) { if (map->om_module == mod) { map->om_complete = 1; } else if (!map->om_complete && !map->om_first) { done = 0; } - tvhtrace(LS_EPGGRAB, "%s complete %i first %i", - map->om_module->id, map->om_complete, map->om_first); + tvhtrace(LS_EPGGRAB, + "%s complete %i first %i", + map->om_module->id, + map->om_complete, + map->om_first); } epggrab_ota_complete_mark(ota, done); - if (!done) return; + if (!done) + return; /* Done */ if (ota->om_q_type == EPGGRAB_OTA_MUX_ACTIVE) @@ -480,10 +450,8 @@ epggrab_ota_complete * Timer callbacks * *************************************************************************/ -static void -epggrab_ota_timeout_cb ( void *p ) -{ - epggrab_ota_mux_t *om = p; +static void epggrab_ota_timeout_cb(void* p) { + epggrab_ota_mux_t* om = p; lock_assert(&global_lock); @@ -497,11 +465,9 @@ epggrab_ota_timeout_cb ( void *p ) epggrab_ota_complete_mark(om, 1); } -static void -epggrab_ota_data_timeout_cb ( void *p ) -{ - epggrab_ota_mux_t *om = p; - epggrab_ota_map_t *map; +static void epggrab_ota_data_timeout_cb(void* p) { + epggrab_ota_mux_t* om = p; + epggrab_ota_map_t* map; lock_assert(&global_lock); @@ -509,7 +475,7 @@ epggrab_ota_data_timeout_cb ( void *p ) return; /* Test for any valid data reception */ - LIST_FOREACH(map, &om->om_modules, om_link) { + LIST_FOREACH (map, &om->om_modules, om_link) { if (!map->om_first) break; } @@ -524,12 +490,10 @@ epggrab_ota_data_timeout_cb ( void *p ) } } -static void -epggrab_ota_handlers_timeout2_cb ( void *p ) -{ - epggrab_ota_mux_t *om = p; - epggrab_ota_map_t *map; - mpegts_mux_t *mm; +static void epggrab_ota_handlers_timeout2_cb(void* p) { + epggrab_ota_mux_t* om = p; + epggrab_ota_map_t* map; + mpegts_mux_t* mm; lock_assert(&global_lock); @@ -541,17 +505,15 @@ epggrab_ota_handlers_timeout2_cb ( void *p ) return; /* Run handlers */ - LIST_FOREACH(map, &om->om_modules, om_link) { + LIST_FOREACH (map, &om->om_modules, om_link) { if (!map->om_complete && map->om_module->handlers) map->om_module->handlers(map, mm); } } -static void -epggrab_ota_handlers_timeout_cb ( void *p ) -{ - epggrab_ota_mux_t *om = p; - epggrab_ota_map_t *map; +static void epggrab_ota_handlers_timeout_cb(void* p) { + epggrab_ota_mux_t* om = p; + epggrab_ota_map_t* map; lock_assert(&global_lock); @@ -559,35 +521,31 @@ epggrab_ota_handlers_timeout_cb ( void *p ) return; /* Test for any valid data reception */ - LIST_FOREACH(map, &om->om_modules, om_link) { + LIST_FOREACH (map, &om->om_modules, om_link) { if (!map->om_first) break; } if (!om->om_detected && map == NULL) { /* wait longer */ - mtimer_arm_rel(&om->om_handlers_timer, epggrab_ota_handlers_timeout_cb, - om, sec2mono(5)); + mtimer_arm_rel(&om->om_handlers_timer, epggrab_ota_handlers_timeout_cb, om, sec2mono(5)); } else { - mtimer_arm_rel(&om->om_handlers_timer, epggrab_ota_handlers_timeout2_cb, - om, sec2mono(20)); + mtimer_arm_rel(&om->om_handlers_timer, epggrab_ota_handlers_timeout2_cb, om, sec2mono(20)); } } -static void -epggrab_ota_kick_cb ( void *p ) -{ +static void epggrab_ota_kick_cb(void* p) { extern const idclass_t mpegts_mux_class; - epggrab_ota_map_t *map; - epggrab_ota_mux_t *om = TAILQ_FIRST(&epggrab_ota_pending); - mpegts_mux_t *mm; + epggrab_ota_map_t* map; + epggrab_ota_mux_t* om = TAILQ_FIRST(&epggrab_ota_pending); + mpegts_mux_t* mm; struct { - mpegts_network_t *net; - uint8_t failed; - uint8_t fatal; - } networks[64], *net; /* more than 64 networks? - you're a king */ - int i, r, networks_count = 0, epg_flag, kick = 1; - const char *modname; + mpegts_network_t* net; + uint8_t failed; + uint8_t fatal; + } networks[64], *net; /* more than 64 networks? - you're a king */ + int i, r, networks_count = 0, epg_flag, kick = 1; + const char* modname; lock_assert(&global_lock); @@ -616,7 +574,7 @@ next_one: goto done; if (net->failed) { TAILQ_INSERT_TAIL(&epggrab_ota_pending, om, om_q_link); - om->om_q_type = EPGGRAB_OTA_MUX_PENDING; + om->om_q_type = EPGGRAB_OTA_MUX_PENDING; om->om_retry_time = mclk() + sec2mono(60); goto done; } @@ -628,21 +586,21 @@ next_one: tvherror(LS_EPGGRAB, "ota epg - too many networks"); goto done; } - net = &networks[networks_count++]; - net->net = mm->mm_network; + net = &networks[networks_count++]; + net->net = mm->mm_network; net->failed = 0; - net->fatal = 0; + net->fatal = 0; } epg_flag = MM_EPG_DISABLE; if (mm->mm_is_enabled(mm)) { epg_flag = mm->mm_is_epg(mm); - modname = NULL; + modname = NULL; if (epg_flag == MM_EPG_MANUAL || epg_flag == MM_EPG_DETECTED) { modname = epggrab_ota_check_module_id(mm->mm_epg_module_id); if (strempty(modname)) { epg_flag = MM_EPG_ENABLE; - modname = NULL; + modname = NULL; } } else if (epg_flag > MM_EPG_FORCE) { epg_flag = MM_EPG_ENABLE; @@ -656,7 +614,7 @@ next_one: /* Check we have modules attached and enabled */ i = r = 0; - LIST_FOREACH(map, &om->om_modules, om_link) { + LIST_FOREACH (map, &om->om_modules, om_link) { if (map->om_module->enabled && map->om_module->tune(map, om, mm)) { i++; if (modname && !strcmp(modname, map->om_module->id)) @@ -673,15 +631,15 @@ next_one: /* Subscribe */ om->om_requeue = 1; - if ((r = mpegts_mux_subscribe(mm, NULL, "epggrab", - SUBSCRIPTION_PRIO_EPG, - SUBSCRIPTION_EPG | - SUBSCRIPTION_ONESHOT | - SUBSCRIPTION_TABLES))) { + if ((r = mpegts_mux_subscribe(mm, + NULL, + "epggrab", + SUBSCRIPTION_PRIO_EPG, + SUBSCRIPTION_EPG | SUBSCRIPTION_ONESHOT | SUBSCRIPTION_TABLES))) { if (r != SM_CODE_NO_ADAPTERS) { tvhtrace(LS_EPGGRAB, "subscription failed for %s (result %d)", mm->mm_nicename, r); TAILQ_INSERT_TAIL(&epggrab_ota_pending, om, om_q_link); - om->om_q_type = EPGGRAB_OTA_MUX_PENDING; + om->om_q_type = EPGGRAB_OTA_MUX_PENDING; om->om_retry_time = mclk() + sec2mono(60); if (r == SM_CODE_NO_FREE_ADAPTER) net->failed = 1; @@ -708,9 +666,9 @@ done: if (tvhtrace_enabled()) { i = r = 0; - RB_FOREACH(om, &epggrab_ota_all, om_global_link) + RB_FOREACH (om, &epggrab_ota_all, om_global_link) i++; - TAILQ_FOREACH(om, &epggrab_ota_pending, om_q_link) + TAILQ_FOREACH (om, &epggrab_ota_pending, om_q_link) r++; tvhtrace(LS_EPGGRAB, "mux stats - all %i pending %i", i, r); } @@ -720,20 +678,15 @@ done: * Start times management */ -static void -epggrab_ota_start_cb ( void *p ); +static void epggrab_ota_start_cb(void* p); -static void -epggrab_ota_next_arm( time_t next ) -{ - tvhtrace(LS_EPGGRAB, "next ota start event in %"PRItime_t" seconds", next - time(NULL)); +static void epggrab_ota_next_arm(time_t next) { + tvhtrace(LS_EPGGRAB, "next ota start event in %" PRItime_t " seconds", next - time(NULL)); gtimer_arm_absn(&epggrab_ota_start_timer, epggrab_ota_start_cb, NULL, next); dbus_emit_signal_s64("/epggrab/ota", "next", next); } -static void -epggrab_ota_start_cb ( void *p ) -{ +static void epggrab_ota_start_cb(void* p) { time_t next; tvhtrace(LS_EPGGRAB, "ota start callback"); @@ -750,9 +703,7 @@ epggrab_ota_start_cb ( void *p ) tvh_mutex_unlock(&epggrab_ota_mutex); } -static void -epggrab_ota_arm ( time_t last ) -{ +static void epggrab_ota_arm(time_t last) { time_t next; tvh_mutex_lock(&epggrab_ota_mutex); @@ -774,31 +725,28 @@ epggrab_ota_arm ( time_t last ) */ static void -epggrab_ota_service_trace ( epggrab_ota_mux_t *ota, - epggrab_ota_svc_link_t *svcl, - const char *op ) -{ - mpegts_mux_t *mm; - mpegts_service_t *svc; - const char *nicename; +epggrab_ota_service_trace(epggrab_ota_mux_t* ota, epggrab_ota_svc_link_t* svcl, const char* op) { + mpegts_mux_t* mm; + mpegts_service_t* svc; + const char* nicename; if (!tvhtrace_enabled()) return; - mm = mpegts_mux_find0(&ota->om_mux_uuid); + mm = mpegts_mux_find0(&ota->om_mux_uuid); nicename = mm ? mm->mm_nicename : ""; - svc = mpegts_service_find_by_uuid0(&svcl->uuid); + svc = mpegts_service_find_by_uuid0(&svcl->uuid); if (mm && svc) { tvhtrace(LS_EPGGRAB, "ota %s %s service %s", nicename, op, svc->s_nicename); } else if (tvheadend_is_running()) tvhtrace(LS_EPGGRAB, "ota %s %s, problem? (%p %p)", nicename, op, mm, svc); } -void -epggrab_ota_service_add ( epggrab_ota_map_t *map, epggrab_ota_mux_t *ota, - tvh_uuid_t *uuid, int save ) -{ - epggrab_ota_svc_link_t *svcl; +void epggrab_ota_service_add(epggrab_ota_map_t* map, + epggrab_ota_mux_t* ota, + tvh_uuid_t* uuid, + int save) { + epggrab_ota_svc_link_t* svcl; if (uuid == NULL || !atomic_get(&epggrab_ota_running)) return; @@ -815,10 +763,10 @@ epggrab_ota_service_add ( epggrab_ota_map_t *map, epggrab_ota_mux_t *ota, svcl->last_tune_count = map->om_tune_count; } -void -epggrab_ota_service_del ( epggrab_ota_map_t *map, epggrab_ota_mux_t *ota, - epggrab_ota_svc_link_t *svcl, int save ) -{ +void epggrab_ota_service_del(epggrab_ota_map_t* map, + epggrab_ota_mux_t* ota, + epggrab_ota_svc_link_t* svcl, + int save) { if (svcl == NULL || (!atomic_get(&epggrab_ota_running) && save)) return; epggrab_ota_service_trace(ota, svcl, "delete"); @@ -832,23 +780,21 @@ epggrab_ota_service_del ( epggrab_ota_map_t *map, epggrab_ota_mux_t *ota, * Config * *************************************************************************/ -static void -epggrab_ota_save ( epggrab_ota_mux_t *ota ) -{ - epggrab_ota_map_t *map; - epggrab_ota_svc_link_t *svcl; - htsmsg_t *e, *l, *l2, *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static void epggrab_ota_save(epggrab_ota_mux_t* ota) { + epggrab_ota_map_t* map; + epggrab_ota_svc_link_t* svcl; + htsmsg_t * e, *l, *l2, *c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; ota->om_save = 0; htsmsg_add_u32(c, "complete", ota->om_complete); l = htsmsg_create_list(); - LIST_FOREACH(map, &ota->om_modules, om_link) { + LIST_FOREACH (map, &ota->om_modules, om_link) { e = htsmsg_create_map(); htsmsg_add_str(e, "id", map->om_module->id); if (RB_FIRST(&map->om_svcs)) { l2 = htsmsg_create_list(); - RB_FOREACH(svcl, &map->om_svcs, link) + RB_FOREACH (svcl, &map->om_svcs, link) htsmsg_add_uuid(l2, NULL, &svcl->uuid); htsmsg_add_msg(e, "services", l2); } @@ -859,17 +805,14 @@ epggrab_ota_save ( epggrab_ota_mux_t *ota ) htsmsg_destroy(c); } -static void -epggrab_ota_load_one - ( const char *uuid, htsmsg_t *c ) -{ - htsmsg_t *l, *l2, *e; - htsmsg_field_t *f, *f2; - mpegts_mux_t *mm; - epggrab_module_ota_t *mod; - epggrab_ota_mux_t *ota; - epggrab_ota_map_t *map; - const char *id; +static void epggrab_ota_load_one(const char* uuid, htsmsg_t* c) { + htsmsg_t * l, *l2, *e; + htsmsg_field_t * f, *f2; + mpegts_mux_t* mm; + epggrab_module_ota_t* mod; + epggrab_ota_mux_t* ota; + epggrab_ota_map_t* map; + const char* id; mm = mpegts_mux_find(uuid); if (!mm) { @@ -887,16 +830,19 @@ epggrab_ota_load_one } ota->om_complete = htsmsg_get_u32_or_default(c, "complete", 0) != 0; - if (!(l = htsmsg_get_list(c, "modules"))) return; + if (!(l = htsmsg_get_list(c, "modules"))) + return; HTSMSG_FOREACH(f, l) { - if (!(e = htsmsg_field_get_map(f))) continue; - if (!(id = htsmsg_get_str(e, "id"))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; + if (!(id = htsmsg_get_str(e, "id"))) + continue; if (!(mod = (epggrab_module_ota_t*)epggrab_module_find_by_id(id))) continue; map = calloc(1, sizeof(epggrab_ota_map_t)); RB_INIT(&map->om_svcs); - map->om_module = mod; + map->om_module = mod; if ((l2 = htsmsg_get_list(e, "services")) != NULL) { HTSMSG_FOREACH(f2, l2) { tvh_uuid_t u; @@ -908,17 +854,16 @@ epggrab_ota_load_one } } -void -epggrab_ota_init ( void ) -{ - htsmsg_t *c, *m; - htsmsg_field_t *f; - char path[1024]; - struct stat st; +void epggrab_ota_init(void) { + htsmsg_t * c, *m; + htsmsg_field_t* f; + char path[1024]; + struct stat st; epggrab_conf.ota_initial = 1; epggrab_conf.ota_timeout = 600; - epggrab_conf.ota_cron = strdup("# Default config (02:04 and 14:04 everyday)\n4 2 * * *\n4 14 * * *"); + epggrab_conf.ota_cron = + strdup("# Default config (02:04 and 14:04 everyday)\n4 2 * * *\n4 14 * * *"); epggrab_ota_cron_multi = cron_multi_set(epggrab_conf.ota_cron); epggrab_ota_pending_flag = 0; @@ -930,8 +875,8 @@ epggrab_ota_init ( void ) /* Add listener */ static mpegts_listener_t ml = { - .ml_mux_start = epggrab_mux_start, - .ml_mux_stop = epggrab_mux_stop, + .ml_mux_start = epggrab_mux_start, + .ml_mux_stop = epggrab_mux_stop, }; mpegts_add_listener(&ml); @@ -946,28 +891,25 @@ epggrab_ota_init ( void ) /* Load config */ if ((c = hts_settings_load_r(1, "epggrab/otamux"))) { HTSMSG_FOREACH(f, c) { - if (!(m = htsmsg_field_get_map(f))) continue; + if (!(m = htsmsg_field_get_map(f))) + continue; epggrab_ota_load_one(htsmsg_field_name(f), m); } htsmsg_destroy(c); } } -void -epggrab_ota_trigger ( int secs ) -{ +void epggrab_ota_trigger(int secs) { lock_assert(&global_lock); /* notify another system layers, that we will do EPG OTA */ - secs = MINMAX(secs, 1, 7*24*3600); + secs = MINMAX(secs, 1, 7 * 24 * 3600); dbus_emit_signal_s64("/epggrab/ota", "next", time(NULL) + secs); epggrab_ota_pending_flag = 1; epggrab_ota_kick(secs); } -void -epggrab_ota_post ( void ) -{ +void epggrab_ota_post(void) { time_t t = (time_t)-1; /* Init timer (call after full init - wait for network tuners) */ @@ -981,11 +923,9 @@ epggrab_ota_post ( void ) epggrab_ota_arm(t); } -static void -epggrab_ota_free ( epggrab_ota_head_t *head, epggrab_ota_mux_t *ota ) -{ - epggrab_ota_map_t *map; - epggrab_ota_svc_link_t *svcl; +static void epggrab_ota_free(epggrab_ota_head_t* head, epggrab_ota_mux_t* ota) { + epggrab_ota_map_t* map; + epggrab_ota_svc_link_t* svcl; mtimer_disarm(&ota->om_timer); mtimer_disarm(&ota->om_data_timer); @@ -1004,10 +944,8 @@ epggrab_ota_free ( epggrab_ota_head_t *head, epggrab_ota_mux_t *ota ) free(ota); } -void -epggrab_ota_shutdown ( void ) -{ - epggrab_ota_mux_t *ota; +void epggrab_ota_shutdown(void) { + epggrab_ota_mux_t* ota; atomic_set(&epggrab_ota_running, 0); while ((ota = TAILQ_FIRST(&epggrab_ota_active)) != NULL) @@ -1026,9 +964,7 @@ epggrab_ota_shutdown ( void ) * Global configuration handlers */ -void -epggrab_ota_set_cron ( void ) -{ +void epggrab_ota_set_cron(void) { lock_assert(&global_lock); tvh_mutex_lock(&epggrab_ota_mutex); @@ -1038,102 +974,104 @@ epggrab_ota_set_cron ( void ) epggrab_ota_arm((time_t)-1); } -void -epggrab_ota_set_genre_translation ( void ) -{ +void epggrab_ota_set_genre_translation(void) { tvhtrace(LS_EPGGRAB, "Processing genre code translations."); - //Take the raw setting data and parse it into the genre translation table. - //There is some sanity checking done, however, the data is entered as freeform - //text by the user and errors may still slip through. - //Note: Each line that comes back from the WebUI is separated by a LF (0x0A). + // Take the raw setting data and parse it into the genre translation table. + // There is some sanity checking done, however, the data is entered as freeform + // text by the user and errors may still slip through. + // Note: Each line that comes back from the WebUI is separated by a LF (0x0A). //^^^^ This has been tested with a Windows WebUI client and it only sends LF, not CR/LF. lock_assert(&global_lock); tvh_mutex_lock(&epggrab_ota_mutex); - //Allocate storage for the translation table. - //The pointer is initialised as NULL. If this function is not triggered + // Allocate storage for the translation table. + // The pointer is initialised as NULL. If this function is not triggered //(no setting in the file), the pointer will not be set and the EIT code - //where the actual translation ccurs can check for a null pointer before - //trying to translate. + // where the actual translation ccurs can check for a null pointer before + // trying to translate. epggrab_ota_genre_translation = calloc(sizeof(unsigned char) * 256, 1); - //Test to see if the translation table got space allocated, if not, - //complain and then exit the function. - if (!epggrab_ota_genre_translation){ + // Test to see if the translation table got space allocated, if not, + // complain and then exit the function. + if (!epggrab_ota_genre_translation) { tvherror(LS_EPGGRAB, "Unable to allocate memory, genre translations disabled."); tvh_mutex_unlock(&epggrab_ota_mutex); return; } - //Reset the translation table to 1:1 here before proceeding. - int i = 0; //Bugfix, some platforms don't like the variable declaration within the FOR. - for(i = 0; i < 256; i++) - { + // Reset the translation table to 1:1 here before proceeding. + int i = 0; // Bugfix, some platforms don't like the variable declaration within the FOR. + for (i = 0; i < 256; i++) { epggrab_ota_genre_translation[i] = i; } - int tempPos = 0; - int outPos = 0; - int tempLen = 0; - char *tempPair = NULL; - int tempFrom = -1; - int tempTo = -1; - tempLen = strlen(epggrab_conf.ota_genre_translation); + int tempPos = 0; + int outPos = 0; + int tempLen = 0; + char* tempPair = NULL; + int tempFrom = -1; + int tempTo = -1; + tempLen = strlen(epggrab_conf.ota_genre_translation); - //Make sure that this is large enough to take the whole config string in one go - //to allow for it being full of nonsense entered by the user. + // Make sure that this is large enough to take the whole config string in one go + // to allow for it being full of nonsense entered by the user. tempPair = calloc(tempLen + 1, 1); - //Read through the user input byte by byte and parse out the lines - for(tempPos = 0; tempPos < tempLen; tempPos++) - { - //If the current character is not a new line or a comma. (Comma is an undocumented courtesy!) - if(epggrab_conf.ota_genre_translation[tempPos] != 10 && epggrab_conf.ota_genre_translation[tempPos] != ',') - { - //Only allow numerals, '=' and '#' to pass through. - //ASCII 0-9 = 48-57, '=' = 61 (in decimal) - if((epggrab_conf.ota_genre_translation[tempPos] >= 48 && epggrab_conf.ota_genre_translation[tempPos] <= 57) || epggrab_conf.ota_genre_translation[tempPos] == 61 || epggrab_conf.ota_genre_translation[tempPos] == '#') - { - tempPair[outPos] = epggrab_conf.ota_genre_translation[tempPos]; + // Read through the user input byte by byte and parse out the lines + for (tempPos = 0; tempPos < tempLen; tempPos++) { + // If the current character is not a new line or a comma. (Comma is an undocumented courtesy!) + if (epggrab_conf.ota_genre_translation[tempPos] != 10 && + epggrab_conf.ota_genre_translation[tempPos] != ',') { + // Only allow numerals, '=' and '#' to pass through. + // ASCII 0-9 = 48-57, '=' = 61 (in decimal) + if ((epggrab_conf.ota_genre_translation[tempPos] >= 48 && + epggrab_conf.ota_genre_translation[tempPos] <= 57) || + epggrab_conf.ota_genre_translation[tempPos] == 61 || + epggrab_conf.ota_genre_translation[tempPos] == '#') { + tempPair[outPos] = epggrab_conf.ota_genre_translation[tempPos]; tempPair[outPos + 1] = 0; outPos++; } } - //If we have a new line or a comma or we are at the end of the config string - if(epggrab_conf.ota_genre_translation[tempPos] == 10 || epggrab_conf.ota_genre_translation[tempPos] == ',' || tempPos == (tempLen - 1)) - { - //Only process non-null strings. - if(strlen(tempPair) != 0) - { + // If we have a new line or a comma or we are at the end of the config string + if (epggrab_conf.ota_genre_translation[tempPos] == 10 || + epggrab_conf.ota_genre_translation[tempPos] == ',' || tempPos == (tempLen - 1)) { + // Only process non-null strings. + if (strlen(tempPair) != 0) { tempFrom = -1; - tempTo = -1; + tempTo = -1; sscanf(tempPair, "%d=%d", &tempFrom, &tempTo); - //Test that the to/from values are sane before proceeding. - if(tempFrom > -1 && tempFrom < 256 && tempTo > -1 && tempTo < 256) - { - tvhtrace(LS_EPGGRAB, "Valid translation from '%d' (0x%02x) to '%d' (0x%02x).", tempFrom, tempFrom, tempTo, tempTo); + // Test that the to/from values are sane before proceeding. + if (tempFrom > -1 && tempFrom < 256 && tempTo > -1 && tempTo < 256) { + tvhtrace(LS_EPGGRAB, + "Valid translation from '%d' (0x%02x) to '%d' (0x%02x).", + tempFrom, + tempFrom, + tempTo, + tempTo); epggrab_ota_genre_translation[tempFrom] = tempTo; - } - else - { + } else { tvhtrace(LS_EPGGRAB, "Ignoring '%s'.", tempPair); } - outPos = 0; + outPos = 0; tempPair[0] = 0; } } } int x = 0; - for(x = 0; x < 256; x++) - { - if(epggrab_ota_genre_translation[x] != x) - { - tvhtrace(LS_EPGGRAB, "Genre '%d' (0x%02x) translates to genre '%d' (0x%02x).", x, x, epggrab_ota_genre_translation[x], epggrab_ota_genre_translation[x]); + for (x = 0; x < 256; x++) { + if (epggrab_ota_genre_translation[x] != x) { + tvhtrace(LS_EPGGRAB, + "Genre '%d' (0x%02x) translates to genre '%d' (0x%02x).", + x, + x, + epggrab_ota_genre_translation[x], + epggrab_ota_genre_translation[x]); } } free(tempPair); diff --git a/src/epggrab/private.h b/src/epggrab/private.h index bc7aa5306..94ed4db1e 100644 --- a/src/epggrab/private.h +++ b/src/epggrab/private.h @@ -25,46 +25,45 @@ struct mpegts_mux; * Generic module routines * *************************************************************************/ -epggrab_module_t *epggrab_module_create - ( epggrab_module_t *skel, const idclass_t *cls, - const char *id, int subsys, const char *saveid, - const char *name, int priority ); +epggrab_module_t* epggrab_module_create(epggrab_module_t* skel, + const idclass_t* cls, + const char* id, + int subsys, + const char* saveid, + const char* name, + int priority); -char *epggrab_module_grab_spawn ( void *m ); -htsmsg_t *epggrab_module_trans_xml ( void *m, char *data ); +char* epggrab_module_grab_spawn(void* m); +htsmsg_t* epggrab_module_trans_xml(void* m, char* data); -void epggrab_module_ch_add ( void *m, struct channel *ch ); -void epggrab_module_ch_rem ( void *m, struct channel *ch ); -void epggrab_module_ch_mod ( void *m, struct channel *ch ); -void epggrab_module_ch_save ( void *m, epggrab_channel_t *ec ); +void epggrab_module_ch_add(void* m, struct channel* ch); +void epggrab_module_ch_rem(void* m, struct channel* ch); +void epggrab_module_ch_mod(void* m, struct channel* ch); +void epggrab_module_ch_save(void* m, epggrab_channel_t* ec); -void epggrab_module_parse ( void *m, htsmsg_t *data ); +void epggrab_module_parse(void* m, htsmsg_t* data); -void epggrab_module_channels_load ( const char *modid ); +void epggrab_module_channels_load(const char* modid); /* ************************************************************************** * Channel processing * *************************************************************************/ -int epggrab_channel_match_epgid ( epggrab_channel_t *ec, struct channel *ch ); -int epggrab_channel_match_name ( epggrab_channel_t *ec, struct channel *ch ); -int epggrab_channel_match_number ( epggrab_channel_t *ec, struct channel *ch ); +int epggrab_channel_match_epgid(epggrab_channel_t* ec, struct channel* ch); +int epggrab_channel_match_name(epggrab_channel_t* ec, struct channel* ch); +int epggrab_channel_match_number(epggrab_channel_t* ec, struct channel* ch); -epggrab_channel_t *epggrab_channel_create - ( epggrab_module_t *owner, htsmsg_t *conf, const char *uuid ); +epggrab_channel_t* +epggrab_channel_create(epggrab_module_t* owner, htsmsg_t* conf, const char* uuid); -epggrab_channel_t *epggrab_channel_find - ( epggrab_module_t *mod, const char *id, int create, int *save ); +epggrab_channel_t* +epggrab_channel_find(epggrab_module_t* mod, const char* id, int create, int* save); -void epggrab_channel_save ( epggrab_channel_t *ec ); -void epggrab_channel_destroy - ( epggrab_channel_t *ec, int delconf, int rb_remove ); -void epggrab_channel_flush - ( epggrab_module_t *mod, int delconf ); -void epggrab_channel_begin_scan - ( epggrab_module_t *mod ); -void epggrab_channel_end_scan - ( epggrab_module_t *mod ); +void epggrab_channel_save(epggrab_channel_t* ec); +void epggrab_channel_destroy(epggrab_channel_t* ec, int delconf, int rb_remove); +void epggrab_channel_flush(epggrab_module_t* mod, int delconf); +void epggrab_channel_begin_scan(epggrab_module_t* mod); +void epggrab_channel_end_scan(epggrab_module_t* mod); void epggrab_channel_init(void); void epggrab_channel_done(void); @@ -73,49 +72,56 @@ void epggrab_channel_done(void); * Internal module routines * *************************************************************************/ -epggrab_module_int_t *epggrab_module_int_create - ( epggrab_module_int_t *skel, const idclass_t *cls, - const char *id, int subsys, const char *saveid, - const char *name, int priority, - const char *path, - char* (*grab) (void*m), - int (*parse) (void *m, htsmsg_t *data, epggrab_stats_t *sta), - htsmsg_t* (*trans) (void *mod, char *data) ); +epggrab_module_int_t* epggrab_module_int_create(epggrab_module_int_t* skel, + const idclass_t* cls, + const char* id, + int subsys, + const char* saveid, + const char* name, + int priority, + const char* path, + char* (*grab)(void* m), + int (*parse)(void* m, htsmsg_t* data, epggrab_stats_t* sta), + htsmsg_t* (*trans)(void* mod, char* data)); /* ************************************************************************** * External module routines * *************************************************************************/ -epggrab_module_ext_t *epggrab_module_ext_create - ( epggrab_module_ext_t *skel, const idclass_t *cls, - const char *id, int subsys, const char *saveid, - const char *name, int priority, - const char *sockid, - int (*parse) (void *m, htsmsg_t *data, epggrab_stats_t *sta), - htsmsg_t* (*trans) (void *mod, char *data) ); +epggrab_module_ext_t* epggrab_module_ext_create(epggrab_module_ext_t* skel, + const idclass_t* cls, + const char* id, + int subsys, + const char* saveid, + const char* name, + int priority, + const char* sockid, + int (*parse)(void* m, htsmsg_t* data, epggrab_stats_t* sta), + htsmsg_t* (*trans)(void* mod, char* data)); /* ************************************************************************** * OTA module routines * *************************************************************************/ typedef struct epggrab_ota_module_ops { - int (*start) (epggrab_ota_map_t *map, struct mpegts_mux *mm); - int (*stop) (epggrab_ota_map_t *map, struct mpegts_mux *mm); - void (*handlers) (epggrab_ota_map_t *map, struct mpegts_mux *mm); - int (*activate) (void *m, int e); - void (*done) (void *m); - int (*tune) (epggrab_ota_map_t *map, epggrab_ota_mux_t *om, - struct mpegts_mux *mm); - void (*process_data) (void *m, void *data, uint32_t len); - void *opaque; + int (*start)(epggrab_ota_map_t* map, struct mpegts_mux* mm); + int (*stop)(epggrab_ota_map_t* map, struct mpegts_mux* mm); + void (*handlers)(epggrab_ota_map_t* map, struct mpegts_mux* mm); + int (*activate)(void* m, int e); + void (*done)(void* m); + int (*tune)(epggrab_ota_map_t* map, epggrab_ota_mux_t* om, struct mpegts_mux* mm); + void (*process_data)(void* m, void* data, uint32_t len); + void* opaque; } epggrab_ota_module_ops_t; -epggrab_module_ota_t *epggrab_module_ota_create - ( epggrab_module_ota_t *skel, - const char *id, int subsys, const char *saveid, - const char *name, int priority, - const idclass_t *idclass, - const epggrab_ota_module_ops_t *ops ); +epggrab_module_ota_t* epggrab_module_ota_create(epggrab_module_ota_t* skel, + const char* id, + int subsys, + const char* saveid, + const char* name, + int priority, + const idclass_t* idclass, + const epggrab_ota_module_ops_t* ops); /* ************************************************************************** * OTA mux link routines @@ -124,7 +130,7 @@ epggrab_module_ota_t *epggrab_module_ota_create /* * Config handling */ -void epggrab_ota_init ( void ); +void epggrab_ota_init(void); /* * Create/Find a link (unregistered) @@ -132,23 +138,23 @@ void epggrab_ota_init ( void ); * Note: this will return NULL for an already existing link that is currently * blocked (i.e. has completed within interval period) */ -epggrab_ota_mux_t *epggrab_ota_find - ( epggrab_module_ota_t *mod, struct mpegts_mux *dm ); -epggrab_ota_mux_t *epggrab_ota_create - ( epggrab_module_ota_t *mod, struct mpegts_mux *dm ); -void epggrab_ota_create_and_register_by_id - ( epggrab_module_ota_t *mod, uint16_t onid, uint16_t tsid, - int period, int interval, const char *name ); -void epggrab_ota_free_eit_plist ( epggrab_ota_mux_t *ota ); - -epggrab_ota_map_t *epggrab_ota_find_map - ( epggrab_ota_mux_t *om, epggrab_module_ota_t *m ); +epggrab_ota_mux_t* epggrab_ota_find(epggrab_module_ota_t* mod, struct mpegts_mux* dm); +epggrab_ota_mux_t* epggrab_ota_create(epggrab_module_ota_t* mod, struct mpegts_mux* dm); +void epggrab_ota_create_and_register_by_id(epggrab_module_ota_t* mod, + uint16_t onid, + uint16_t tsid, + int period, + int interval, + const char* name); +void epggrab_ota_free_eit_plist(epggrab_ota_mux_t* ota); + +epggrab_ota_map_t* epggrab_ota_find_map(epggrab_ota_mux_t* om, epggrab_module_ota_t* m); /* * Delete */ -void epggrab_ota_destroy ( epggrab_ota_mux_t *ota ); -void epggrab_ota_destroy_by_module ( epggrab_module_ota_t *mod ); +void epggrab_ota_destroy(epggrab_ota_mux_t* ota); +void epggrab_ota_destroy_by_module(epggrab_module_ota_t* mod); #if 0 void epggrab_ota_destroy_by_dm ( struct dvb_mux *dm ); #endif @@ -157,38 +163,34 @@ void epggrab_ota_destroy_by_dm ( struct dvb_mux *dm ); * In module functions */ -epggrab_ota_mux_t *epggrab_ota_register - ( epggrab_module_ota_t *mod, epggrab_ota_mux_t *ota, - struct mpegts_mux *mux ); +epggrab_ota_mux_t* +epggrab_ota_register(epggrab_module_ota_t* mod, epggrab_ota_mux_t* ota, struct mpegts_mux* mux); /* * State change */ -void epggrab_ota_complete - ( epggrab_module_ota_t *mod, epggrab_ota_mux_t *ota ); +void epggrab_ota_complete(epggrab_module_ota_t* mod, epggrab_ota_mux_t* ota); /* * Service list */ -void -epggrab_ota_service_add - ( epggrab_ota_map_t *map, epggrab_ota_mux_t *ota, - tvh_uuid_t *uuid, int save ); -void -epggrab_ota_service_del - ( epggrab_ota_map_t *map, epggrab_ota_mux_t *ota, - epggrab_ota_svc_link_t *svcl, int save ); +void epggrab_ota_service_add(epggrab_ota_map_t* map, + epggrab_ota_mux_t* ota, + tvh_uuid_t* uuid, + int save); +void epggrab_ota_service_del(epggrab_ota_map_t* map, + epggrab_ota_mux_t* ota, + epggrab_ota_svc_link_t* svcl, + int save); /* ************************************************************************** * Miscellaneous * *************************************************************************/ -int xmltv_parse_accessibility - ( epg_broadcast_t *ebc, htsmsg_t *m, epg_changes_t *changes ); +int xmltv_parse_accessibility(epg_broadcast_t* ebc, htsmsg_t* m, epg_changes_t* changes); /* Freesat huffman decoder */ -size_t freesat_huffman_decode - ( char *dst, size_t* dstlen, const uint8_t *src, size_t srclen ); +size_t freesat_huffman_decode(char* dst, size_t* dstlen, const uint8_t* src, size_t srclen); /* ************************************************************************** * Classes @@ -207,33 +209,32 @@ extern const idclass_t epggrab_mod_ota_scraper_class; * *************************************************************************/ /* EIT module */ -void eit_init ( void ); -void eit_done ( void ); -void eit_load ( void ); +void eit_init(void); +void eit_done(void); +void eit_load(void); -htsmsg_t *eit_module_id_list( const char *lang ); -const char *eit_check_module_id ( const char *id ); +htsmsg_t* eit_module_id_list(const char* lang); +const char* eit_check_module_id(const char* id); /* OpenTV module */ -void opentv_init ( void ); -void opentv_done ( void ); -void opentv_load ( void ); +void opentv_init(void); +void opentv_done(void); +void opentv_load(void); -htsmsg_t *opentv_module_id_list( const char *lang ); -const char *opentv_check_module_id ( const char *id ); +htsmsg_t* opentv_module_id_list(const char* lang); +const char* opentv_check_module_id(const char* id); /* XMLTV module */ -void xmltv_init ( void ); -void xmltv_done ( void ); -void xmltv_load ( void ); +void xmltv_init(void); +void xmltv_done(void); +void xmltv_load(void); /* PSIP module */ -void psip_init ( void ); -void psip_done ( void ); -void psip_load ( void ); - -htsmsg_t *psip_module_id_list( const char *lang ); -const char *psip_check_module_id ( const char *id ); +void psip_init(void); +void psip_done(void); +void psip_load(void); +htsmsg_t* psip_module_id_list(const char* lang); +const char* psip_check_module_id(const char* id); #endif /* __EPGGRAB_PRIVATE_H__ */ diff --git a/src/epggrab/support/freesat_huffman.c b/src/epggrab/support/freesat_huffman.c index 827a36602..2eec2bb8e 100644 --- a/src/epggrab/support/freesat_huffman.c +++ b/src/epggrab/support/freesat_huffman.c @@ -27,5828 +27,5828 @@ #include "epggrab/private.h" struct fsattab { - unsigned int value; - short bits; - char next; + unsigned int value; + short bits; + char next; }; -#define START '\0' -#define STOP '\0' -#define ESCAPE '\1' +#define START '\0' +#define STOP '\0' +#define ESCAPE '\1' struct fsattab fsat_table_1[] = { - /* 51 */ - { 0x00000000, 2, 84}, /* 0 'T' */ - { 0x40000000, 3, 66}, /* 1 'B' */ - { 0x80000000, 4, 67}, /* 2 'C' */ - { 0x90000000, 4, 73}, /* 3 'I' */ - { 0xd0000000, 4, 83}, /* 4 'S' */ - { 0x60000000, 5, 76}, /* 5 'L' */ - { 0x70000000, 5, 68}, /* 6 'D' */ - { 0x78000000, 5, 72}, /* 7 'H' */ - { 0xa0000000, 5, 82}, /* 8 'R' */ - { 0xa8000000, 5, 78}, /* 9 'N' */ - { 0xb0000000, 5, 69}, /* 10 'E' */ - { 0xc0000000, 5, 70}, /* 11 'F' */ - { 0xc8000000, 5, 65}, /* 12 'A' */ - { 0xe0000000, 5, 77}, /* 13 'M' */ - { 0xe8000000, 5, 80}, /* 14 'P' */ - { 0xf0000000, 5, 87}, /* 15 'W' */ - { 0x6c000000, 6, 81}, /* 16 'Q' */ - { 0xbc000000, 6, 71}, /* 17 'G' */ - { 0xf8000000, 6, 74}, /* 18 'J' */ - { 0x68000000, 7, 75}, /* 19 'K' */ - { 0xba000000, 7, 85}, /* 20 'U' */ - { 0xfc000000, 7, 79}, /* 21 'O' */ - { 0x6a000000, 8, 54}, /* 22 '6' */ - { 0x6b000000, 8, 46}, /* 23 '.' */ - { 0xb8000000, 8, 86}, /* 24 'V' */ - { 0xfe000000, 8, 89}, /* 25 'Y' */ - { 0xb9800000, 9, 50}, /* 26 '2' */ - { 0xff800000, 9, 88}, /* 27 'X' */ - { 0xb9000000, 10, 90}, /* 28 'Z' */ - { 0xff000000, 10, 56}, /* 29 '8' */ - { 0xb9400000, 11, 49}, /* 30 '1' */ - { 0xb9600000, 11, 51}, /* 31 '3' */ - { 0xff400000, 12, 52}, /* 32 '4' */ - { 0xff500000, 12, 39}, /* 33 '\'' */ - { 0xff700000, 12, 32}, /* 34 ' ' */ - { 0xff600000, 14, 53}, /* 35 '5' */ - { 0xff6c0000, 14, 48}, /* 36 '0' */ - { 0xff660000, 15, 109}, /* 37 'm' */ - { 0xff640000, 16, 99}, /* 38 'c' */ - { 0xff680000, 16, 57}, /* 39 '9' */ - { 0xff6a0000, 16, 97}, /* 40 'a' */ - { 0xff6b0000, 16, 100}, /* 41 'd' */ - { 0xff650000, 17, 115}, /* 42 's' */ - { 0xff658000, 17, 112}, /* 43 'p' */ - { 0xff690000, 17, 40}, /* 44 '(' */ - { 0xff698000, 18, 116}, /* 45 't' */ - { 0xff69c000, 19, 55}, /* 46 '7' */ - { 0xff69e000, 20, 1}, /* 47 '0x01' */ - { 0xff69f000, 20, 108}, /* 48 'l' */ - { 0x00000000, 1, 1}, /* 49 '0x01' */ - { 0x80000000, 1, 1}, /* 50 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 51 '0x01' */ - { 0x80000000, 1, 1}, /* 52 '0x01' */ - /* 0 */ - /* 2 */ - { 0x00000000, 1, 1}, /* 53 '0x01' */ - { 0x80000000, 1, 1}, /* 54 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 55 '0x01' */ - { 0x80000000, 1, 1}, /* 56 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 57 '0x01' */ - { 0x80000000, 1, 1}, /* 58 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 59 '0x01' */ - { 0x80000000, 1, 1}, /* 60 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 61 '0x01' */ - { 0x80000000, 1, 1}, /* 62 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 63 '0x01' */ - { 0x80000000, 1, 1}, /* 64 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 65 '0x01' */ - { 0x80000000, 1, 1}, /* 66 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 67 '0x01' */ - { 0x80000000, 1, 1}, /* 68 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 69 '0x01' */ - { 0x80000000, 1, 1}, /* 70 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 71 '0x01' */ - { 0x80000000, 1, 1}, /* 72 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 73 '0x01' */ - { 0x80000000, 1, 1}, /* 74 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 75 '0x01' */ - { 0x80000000, 1, 1}, /* 76 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 77 '0x01' */ - { 0x80000000, 1, 1}, /* 78 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 79 '0x01' */ - { 0x80000000, 1, 1}, /* 80 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 81 '0x01' */ - { 0x80000000, 1, 1}, /* 82 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 83 '0x01' */ - { 0x80000000, 1, 1}, /* 84 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 85 '0x01' */ - { 0x80000000, 1, 1}, /* 86 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 87 '0x01' */ - { 0x80000000, 1, 1}, /* 88 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 89 '0x01' */ - { 0x80000000, 1, 1}, /* 90 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 91 '0x01' */ - { 0x80000000, 1, 1}, /* 92 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 93 '0x01' */ - { 0x80000000, 1, 1}, /* 94 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 95 '0x01' */ - { 0x80000000, 1, 1}, /* 96 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 97 '0x01' */ - { 0x80000000, 1, 1}, /* 98 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 99 '0x01' */ - { 0x80000000, 1, 1}, /* 100 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 101 '0x01' */ - { 0x80000000, 1, 1}, /* 102 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 103 '0x01' */ - { 0x80000000, 1, 1}, /* 104 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 105 '0x01' */ - { 0x80000000, 1, 1}, /* 106 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 107 '0x01' */ - { 0x80000000, 1, 1}, /* 108 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 109 '0x01' */ - { 0x80000000, 1, 1}, /* 110 '0x01' */ - /* 70 */ - { 0x00000000, 4, 87}, /* 111 'W' */ - { 0x30000000, 4, 77}, /* 112 'M' */ - { 0x40000000, 4, 67}, /* 113 'C' */ - { 0x50000000, 4, 66}, /* 114 'B' */ - { 0x70000000, 4, 80}, /* 115 'P' */ - { 0x90000000, 4, 84}, /* 116 'T' */ - { 0xc0000000, 4, 78}, /* 117 'N' */ - { 0xf0000000, 4, 83}, /* 118 'S' */ - { 0x18000000, 5, 73}, /* 119 'I' */ - { 0x20000000, 5, 71}, /* 120 'G' */ - { 0x60000000, 5, 72}, /* 121 'H' */ - { 0x68000000, 5, 68}, /* 122 'D' */ - { 0x80000000, 5, 111}, /* 123 'o' */ - { 0x88000000, 5, 65}, /* 124 'A' */ - { 0xa0000000, 5, 116}, /* 125 't' */ - { 0xb0000000, 5, 97}, /* 126 'a' */ - { 0xb8000000, 5, 70}, /* 127 'F' */ - { 0xd0000000, 5, 76}, /* 128 'L' */ - { 0xd8000000, 5, 82}, /* 129 'R' */ - { 0x2c000000, 6, 85}, /* 130 'U' */ - { 0xac000000, 6, 79}, /* 131 'O' */ - { 0xe4000000, 6, 74}, /* 132 'J' */ - { 0xe8000000, 6, 69}, /* 133 'E' */ - { 0x10000000, 7, 102}, /* 134 'f' */ - { 0x12000000, 7, 81}, /* 135 'Q' */ - { 0x16000000, 7, 86}, /* 136 'V' */ - { 0x28000000, 7, 0}, /* 137 '0x00' */ - { 0x2a000000, 7, 119}, /* 138 'w' */ - { 0xe0000000, 7, 50}, /* 139 '2' */ - { 0xe2000000, 7, 75}, /* 140 'K' */ - { 0xec000000, 7, 89}, /* 141 'Y' */ - { 0xee000000, 7, 105}, /* 142 'i' */ - { 0x14000000, 8, 45}, /* 143 '-' */ - { 0xa9000000, 8, 49}, /* 144 '1' */ - { 0xa8000000, 9, 38}, /* 145 '&' */ - { 0xaa800000, 9, 88}, /* 146 'X' */ - { 0x15400000, 10, 114}, /* 147 'r' */ - { 0xa8800000, 10, 53}, /* 148 '5' */ - { 0xa8c00000, 10, 90}, /* 149 'Z' */ - { 0xaa400000, 10, 57}, /* 150 '9' */ - { 0xab400000, 10, 115}, /* 151 's' */ - { 0xab800000, 10, 52}, /* 152 '4' */ - { 0xabc00000, 10, 51}, /* 153 '3' */ - { 0x15000000, 11, 55}, /* 154 '7' */ - { 0x15800000, 11, 98}, /* 155 'b' */ - { 0x15c00000, 11, 121}, /* 156 'y' */ - { 0xaa000000, 11, 39}, /* 157 '\'' */ - { 0xab000000, 11, 54}, /* 158 '6' */ - { 0x15a00000, 12, 118}, /* 159 'v' */ - { 0x15b00000, 12, 100}, /* 160 'd' */ - { 0x15e00000, 12, 40}, /* 161 '(' */ - { 0xaa200000, 12, 32}, /* 162 ' ' */ - { 0xaa300000, 12, 48}, /* 163 '0' */ - { 0xab200000, 12, 110}, /* 164 'n' */ - { 0xab300000, 12, 56}, /* 165 '8' */ - { 0x15300000, 13, 103}, /* 166 'g' */ - { 0x15f00000, 13, 117}, /* 167 'u' */ - { 0x15200000, 14, 43}, /* 168 '+' */ - { 0x15240000, 14, 46}, /* 169 '.' */ - { 0x15280000, 14, 1}, /* 170 '0x01' */ - { 0x152c0000, 14, 108}, /* 171 'l' */ - { 0x153c0000, 14, 109}, /* 172 'm' */ - { 0x15f80000, 14, 112}, /* 173 'p' */ - { 0x15380000, 15, 92}, /* 174 '\\' */ - { 0x153a0000, 15, 47}, /* 175 '/' */ - { 0x15fe0000, 15, 101}, /* 176 'e' */ - { 0x15fd0000, 16, 34}, /* 177 '\"' */ - { 0x15fc8000, 17, 99}, /* 178 'c' */ - { 0x15fc0000, 18, 107}, /* 179 'k' */ - { 0x15fc4000, 18, 104}, /* 180 'h' */ - /* 7 */ - { 0x80000000, 1, 0}, /* 181 '0x00' */ - { 0x40000000, 2, 32}, /* 182 ' ' */ - { 0x20000000, 3, 46}, /* 183 '.' */ - { 0x10000000, 4, 33}, /* 184 '!' */ - { 0x08000000, 5, 34}, /* 185 '\"' */ - { 0x00000000, 6, 1}, /* 186 '0x01' */ - { 0x04000000, 6, 58}, /* 187 ':' */ - /* 3 */ - { 0x00000000, 1, 32}, /* 188 ' ' */ - { 0x80000000, 2, 1}, /* 189 '0x01' */ - { 0xc0000000, 2, 73}, /* 190 'I' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 191 '0x01' */ - { 0x80000000, 1, 1}, /* 192 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 193 '0x01' */ - { 0x80000000, 1, 1}, /* 194 '0x01' */ - /* 3 */ - { 0x80000000, 1, 32}, /* 195 ' ' */ - { 0x00000000, 2, 1}, /* 196 '0x01' */ - { 0x40000000, 2, 0}, /* 197 '0x00' */ - /* 4 */ - { 0x80000000, 1, 32}, /* 198 ' ' */ - { 0x40000000, 2, 66}, /* 199 'B' */ - { 0x00000000, 3, 1}, /* 200 '0x01' */ - { 0x20000000, 3, 46}, /* 201 '.' */ - /* 32 */ - { 0x80000000, 1, 115}, /* 202 's' */ - { 0x00000000, 3, 109}, /* 203 'm' */ - { 0x40000000, 3, 67}, /* 204 'C' */ - { 0x20000000, 4, 116}, /* 205 't' */ - { 0x30000000, 4, 32}, /* 206 ' ' */ - { 0x60000000, 5, 100}, /* 207 'd' */ - { 0x70000000, 5, 118}, /* 208 'v' */ - { 0x6c000000, 6, 114}, /* 209 'r' */ - { 0x7c000000, 6, 65}, /* 210 'A' */ - { 0x6a000000, 7, 110}, /* 211 'n' */ - { 0x68000000, 8, 71}, /* 212 'G' */ - { 0x79000000, 8, 108}, /* 213 'l' */ - { 0x69800000, 9, 68}, /* 214 'D' */ - { 0x78000000, 9, 66}, /* 215 'B' */ - { 0x78800000, 9, 101}, /* 216 'e' */ - { 0x7a800000, 9, 105}, /* 217 'i' */ - { 0x7b000000, 9, 54}, /* 218 '6' */ - { 0x69000000, 10, 76}, /* 219 'L' */ - { 0x7a400000, 10, 0}, /* 220 '0x00' */ - { 0x7bc00000, 10, 119}, /* 221 'w' */ - { 0x69400000, 11, 79}, /* 222 'O' */ - { 0x7a000000, 11, 83}, /* 223 'S' */ - { 0x7a200000, 11, 69}, /* 224 'E' */ - { 0x7ba00000, 11, 78}, /* 225 'N' */ - { 0x7b900000, 12, 82}, /* 226 'R' */ - { 0x69600000, 13, 97}, /* 227 'a' */ - { 0x69680000, 13, 77}, /* 228 'M' */ - { 0x69700000, 13, 75}, /* 229 'K' */ - { 0x69780000, 13, 70}, /* 230 'F' */ - { 0x7b800000, 13, 48}, /* 231 '0' */ - { 0x7b880000, 14, 1}, /* 232 '0x01' */ - { 0x7b8c0000, 14, 99}, /* 233 'c' */ - /* 12 */ - { 0x80000000, 1, 99}, /* 234 'c' */ - { 0x00000000, 3, 49}, /* 235 '1' */ - { 0x20000000, 4, 77}, /* 236 'M' */ - { 0x30000000, 4, 85}, /* 237 'U' */ - { 0x40000000, 4, 82}, /* 238 'R' */ - { 0x50000000, 4, 68}, /* 239 'D' */ - { 0x60000000, 4, 72}, /* 240 'H' */ - { 0x70000000, 5, 83}, /* 241 'S' */ - { 0x78000000, 6, 70}, /* 242 'F' */ - { 0x7c000000, 7, 71}, /* 243 'G' */ - { 0x7e000000, 8, 1}, /* 244 '0x01' */ - { 0x7f000000, 8, 89}, /* 245 'Y' */ - /* 3 */ - { 0x80000000, 1, 0}, /* 246 '0x00' */ - { 0x00000000, 2, 1}, /* 247 '0x01' */ - { 0x40000000, 2, 32}, /* 248 ' ' */ - /* 11 */ - { 0x00000000, 1, 42}, /* 249 '*' */ - { 0xa0000000, 3, 32}, /* 250 ' ' */ - { 0x80000000, 4, 100}, /* 251 'd' */ - { 0xc0000000, 4, 109}, /* 252 'm' */ - { 0xd0000000, 4, 116}, /* 253 't' */ - { 0xf0000000, 4, 115}, /* 254 's' */ - { 0x90000000, 5, 101}, /* 255 'e' */ - { 0xe0000000, 5, 103}, /* 256 'g' */ - { 0xe8000000, 5, 107}, /* 257 'k' */ - { 0x98000000, 6, 1}, /* 258 '0x01' */ - { 0x9c000000, 6, 121}, /* 259 'y' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 260 '0x01' */ - { 0x80000000, 1, 32}, /* 261 ' ' */ - /* 4 */ - { 0x80000000, 1, 32}, /* 262 ' ' */ - { 0x40000000, 2, 48}, /* 263 '0' */ - { 0x00000000, 3, 1}, /* 264 '0x01' */ - { 0x20000000, 3, 46}, /* 265 '.' */ - /* 37 */ - { 0xc0000000, 2, 32}, /* 266 ' ' */ - { 0x60000000, 3, 83}, /* 267 'S' */ - { 0x80000000, 3, 71}, /* 268 'G' */ - { 0xa0000000, 3, 79}, /* 269 'O' */ - { 0x30000000, 4, 84}, /* 270 'T' */ - { 0x40000000, 4, 85}, /* 271 'U' */ - { 0x00000000, 5, 69}, /* 272 'E' */ - { 0x10000000, 5, 68}, /* 273 'D' */ - { 0x08000000, 6, 109}, /* 274 'm' */ - { 0x18000000, 6, 48}, /* 275 '0' */ - { 0x1c000000, 6, 73}, /* 276 'I' */ - { 0x28000000, 6, 54}, /* 277 '6' */ - { 0x50000000, 6, 70}, /* 278 'F' */ - { 0x54000000, 6, 111}, /* 279 'o' */ - { 0x0c000000, 7, 76}, /* 280 'L' */ - { 0x0e000000, 7, 67}, /* 281 'C' */ - { 0x22000000, 7, 65}, /* 282 'A' */ - { 0x24000000, 7, 116}, /* 283 't' */ - { 0x26000000, 7, 89}, /* 284 'Y' */ - { 0x2e000000, 7, 50}, /* 285 '2' */ - { 0x58000000, 7, 66}, /* 286 'B' */ - { 0x5a000000, 7, 46}, /* 287 '.' */ - { 0x20000000, 8, 80}, /* 288 'P' */ - { 0x21000000, 8, 90}, /* 289 'Z' */ - { 0x5c000000, 8, 56}, /* 290 '8' */ - { 0x5d000000, 8, 105}, /* 291 'i' */ - { 0x5e000000, 8, 100}, /* 292 'd' */ - { 0x5f000000, 8, 72}, /* 293 'H' */ - { 0x2c800000, 9, 78}, /* 294 'N' */ - { 0x2d800000, 9, 82}, /* 295 'R' */ - { 0x2c000000, 10, 49}, /* 296 '1' */ - { 0x2c400000, 10, 87}, /* 297 'W' */ - { 0x2d200000, 11, 99}, /* 298 'c' */ - { 0x2d400000, 11, 97}, /* 299 'a' */ - { 0x2d600000, 11, 77}, /* 300 'M' */ - { 0x2d000000, 12, 1}, /* 301 '0x01' */ - { 0x2d100000, 12, 81}, /* 302 'Q' */ - /* 25 */ - { 0x80000000, 1, 46}, /* 303 '.' */ - { 0x40000000, 2, 0}, /* 304 '0x00' */ - { 0x20000000, 4, 32}, /* 305 ' ' */ - { 0x00000000, 5, 73}, /* 306 'I' */ - { 0x08000000, 5, 84}, /* 307 'T' */ - { 0x10000000, 5, 67}, /* 308 'C' */ - { 0x30000000, 5, 112}, /* 309 'p' */ - { 0x38000000, 5, 48}, /* 310 '0' */ - { 0x1c000000, 6, 72}, /* 311 'H' */ - { 0x1a000000, 8, 87}, /* 312 'W' */ - { 0x18800000, 9, 83}, /* 313 'S' */ - { 0x1b000000, 9, 51}, /* 314 '3' */ - { 0x1b800000, 9, 66}, /* 315 'B' */ - { 0x18000000, 10, 49}, /* 316 '1' */ - { 0x18400000, 10, 77}, /* 317 'M' */ - { 0x19800000, 10, 99}, /* 318 'c' */ - { 0x19000000, 11, 116}, /* 319 't' */ - { 0x19200000, 11, 82}, /* 320 'R' */ - { 0x19400000, 11, 70}, /* 321 'F' */ - { 0x19c00000, 11, 69}, /* 322 'E' */ - { 0x19e00000, 11, 65}, /* 323 'A' */ - { 0x19600000, 13, 1}, /* 324 '0x01' */ - { 0x19680000, 13, 108}, /* 325 'l' */ - { 0x19700000, 13, 100}, /* 326 'd' */ - { 0x19780000, 13, 85}, /* 327 'U' */ - /* 18 */ - { 0x00000000, 2, 49}, /* 328 '1' */ - { 0x80000000, 2, 55}, /* 329 '7' */ - { 0x40000000, 3, 52}, /* 330 '4' */ - { 0x60000000, 3, 50}, /* 331 '2' */ - { 0xc0000000, 3, 51}, /* 332 '3' */ - { 0xe0000000, 4, 53}, /* 333 '5' */ - { 0xf0000000, 6, 54}, /* 334 '6' */ - { 0xf8000000, 6, 67}, /* 335 'C' */ - { 0xf4000000, 7, 57}, /* 336 '9' */ - { 0xf6000000, 7, 32}, /* 337 ' ' */ - { 0xfc000000, 7, 56}, /* 338 '8' */ - { 0xff000000, 8, 85}, /* 339 'U' */ - { 0xfe000000, 10, 71}, /* 340 'G' */ - { 0xfe800000, 10, 48}, /* 341 '0' */ - { 0xfe400000, 11, 1}, /* 342 '0x01' */ - { 0xfe600000, 11, 87}, /* 343 'W' */ - { 0xfec00000, 11, 86}, /* 344 'V' */ - { 0xfee00000, 11, 83}, /* 345 'S' */ - /* 23 */ - { 0x00000000, 2, 54}, /* 346 '6' */ - { 0x40000000, 2, 32}, /* 347 ' ' */ - { 0xc0000000, 2, 48}, /* 348 '0' */ - { 0x90000000, 4, 112}, /* 349 'p' */ - { 0xa0000000, 4, 0}, /* 350 '0x00' */ - { 0x80000000, 5, 49}, /* 351 '1' */ - { 0x88000000, 5, 97}, /* 352 'a' */ - { 0xb8000000, 5, 55}, /* 353 '7' */ - { 0xb0000000, 7, 45}, /* 354 '-' */ - { 0xb4000000, 7, 115}, /* 355 's' */ - { 0xb3000000, 8, 52}, /* 356 '4' */ - { 0xb6000000, 8, 116}, /* 357 't' */ - { 0xb7800000, 9, 37}, /* 358 '%' */ - { 0xb2000000, 10, 56}, /* 359 '8' */ - { 0xb2400000, 10, 58}, /* 360 ':' */ - { 0xb2800000, 10, 53}, /* 361 '5' */ - { 0xb2c00000, 10, 50}, /* 362 '2' */ - { 0xb7000000, 10, 47}, /* 363 '/' */ - { 0xb7600000, 11, 85}, /* 364 'U' */ - { 0xb7500000, 12, 44}, /* 365 ',' */ - { 0xb7400000, 13, 46}, /* 366 '.' */ - { 0xb7480000, 14, 1}, /* 367 '0x01' */ - { 0xb74c0000, 14, 108}, /* 368 'l' */ - /* 22 */ - { 0x40000000, 2, 0}, /* 369 '0x00' */ - { 0x00000000, 3, 46}, /* 370 '.' */ - { 0xa0000000, 3, 48}, /* 371 '0' */ - { 0xe0000000, 3, 49}, /* 372 '1' */ - { 0x20000000, 4, 50}, /* 373 '2' */ - { 0x30000000, 4, 32}, /* 374 ' ' */ - { 0xd0000000, 4, 47}, /* 375 '/' */ - { 0x90000000, 5, 56}, /* 376 '8' */ - { 0xc0000000, 5, 51}, /* 377 '3' */ - { 0x80000000, 6, 53}, /* 378 '5' */ - { 0x84000000, 6, 115}, /* 379 's' */ - { 0x88000000, 6, 54}, /* 380 '6' */ - { 0x8c000000, 6, 58}, /* 381 ':' */ - { 0x98000000, 6, 39}, /* 382 '\'' */ - { 0xc8000000, 6, 88}, /* 383 'X' */ - { 0xcc000000, 6, 57}, /* 384 '9' */ - { 0x9e000000, 7, 52}, /* 385 '4' */ - { 0x9d000000, 8, 45}, /* 386 '-' */ - { 0x9c800000, 9, 55}, /* 387 '7' */ - { 0x9c000000, 10, 41}, /* 388 ')' */ - { 0x9c400000, 11, 1}, /* 389 '0x01' */ - { 0x9c600000, 11, 44}, /* 390 ',' */ - /* 18 */ - { 0x00000000, 1, 48}, /* 391 '0' */ - { 0xc0000000, 2, 52}, /* 392 '4' */ - { 0xa0000000, 3, 0}, /* 393 '0x00' */ - { 0x90000000, 4, 32}, /* 394 ' ' */ - { 0x80000000, 5, 58}, /* 395 ':' */ - { 0x8a000000, 7, 53}, /* 396 '5' */ - { 0x8e000000, 7, 47}, /* 397 '/' */ - { 0x88000000, 8, 46}, /* 398 '.' */ - { 0x89000000, 8, 49}, /* 399 '1' */ - { 0x8c000000, 8, 87}, /* 400 'W' */ - { 0x8d800000, 9, 55}, /* 401 '7' */ - { 0x8d200000, 11, 51}, /* 402 '3' */ - { 0x8d600000, 11, 90}, /* 403 'Z' */ - { 0x8d000000, 12, 110}, /* 404 'n' */ - { 0x8d100000, 12, 54}, /* 405 '6' */ - { 0x8d500000, 12, 39}, /* 406 '\'' */ - { 0x8d400000, 13, 1}, /* 407 '0x01' */ - { 0x8d480000, 13, 115}, /* 408 's' */ - /* 19 */ - { 0x00000000, 1, 32}, /* 409 ' ' */ - { 0x80000000, 2, 0}, /* 410 '0x00' */ - { 0xc0000000, 4, 114}, /* 411 'r' */ - { 0xd0000000, 4, 47}, /* 412 '/' */ - { 0xf0000000, 4, 66}, /* 413 'B' */ - { 0xe0000000, 5, 48}, /* 414 '0' */ - { 0xe8000000, 7, 58}, /* 415 ':' */ - { 0xec000000, 7, 45}, /* 416 '-' */ - { 0xea000000, 8, 49}, /* 417 '1' */ - { 0xeb000000, 8, 56}, /* 418 '8' */ - { 0xef000000, 8, 52}, /* 419 '4' */ - { 0xee000000, 10, 54}, /* 420 '6' */ - { 0xeec00000, 10, 57}, /* 421 '9' */ - { 0xee600000, 11, 116}, /* 422 't' */ - { 0xee800000, 11, 51}, /* 423 '3' */ - { 0xee400000, 12, 1}, /* 424 '0x01' */ - { 0xee500000, 12, 101}, /* 425 'e' */ - { 0xeea00000, 12, 55}, /* 426 '7' */ - { 0xeeb00000, 12, 53}, /* 427 '5' */ - /* 19 */ - { 0x00000000, 1, 0}, /* 428 '0x00' */ - { 0xc0000000, 2, 32}, /* 429 ' ' */ - { 0x90000000, 4, 58}, /* 430 ':' */ - { 0xb0000000, 4, 47}, /* 431 '/' */ - { 0x88000000, 5, 56}, /* 432 '8' */ - { 0xa8000000, 5, 46}, /* 433 '.' */ - { 0x80000000, 6, 57}, /* 434 '9' */ - { 0xa0000000, 6, 48}, /* 435 '0' */ - { 0xa4000000, 7, 77}, /* 436 'M' */ - { 0x85000000, 8, 73}, /* 437 'I' */ - { 0x86000000, 8, 41}, /* 438 ')' */ - { 0xa6000000, 8, 82}, /* 439 'R' */ - { 0xa7000000, 8, 45}, /* 440 '-' */ - { 0x84000000, 9, 87}, /* 441 'W' */ - { 0x87000000, 9, 80}, /* 442 'P' */ - { 0x87800000, 9, 53}, /* 443 '5' */ - { 0x84c00000, 10, 50}, /* 444 '2' */ - { 0x84800000, 11, 1}, /* 445 '0x01' */ - { 0x84a00000, 11, 39}, /* 446 '\'' */ - /* 11 */ - { 0x00000000, 1, 0}, /* 447 '0x00' */ - { 0xc0000000, 2, 32}, /* 448 ' ' */ - { 0xa0000000, 3, 48}, /* 449 '0' */ - { 0x90000000, 4, 47}, /* 450 '/' */ - { 0x84000000, 6, 45}, /* 451 '-' */ - { 0x8c000000, 6, 58}, /* 452 ':' */ - { 0x82000000, 7, 116}, /* 453 't' */ - { 0x88000000, 7, 51}, /* 454 '3' */ - { 0x8a000000, 7, 49}, /* 455 '1' */ - { 0x80000000, 8, 1}, /* 456 '0x01' */ - { 0x81000000, 8, 97}, /* 457 'a' */ - /* 16 */ - { 0x00000000, 2, 0}, /* 458 '0x00' */ - { 0x40000000, 2, 32}, /* 459 ' ' */ - { 0x80000000, 2, 48}, /* 460 '0' */ - { 0xe0000000, 3, 58}, /* 461 ':' */ - { 0xc8000000, 5, 46}, /* 462 '.' */ - { 0xd8000000, 5, 105}, /* 463 'i' */ - { 0xc0000000, 6, 45}, /* 464 '-' */ - { 0xd4000000, 6, 97}, /* 465 'a' */ - { 0xc6000000, 7, 52}, /* 466 '4' */ - { 0xd0000000, 7, 56}, /* 467 '8' */ - { 0xd2000000, 7, 47}, /* 468 '/' */ - { 0xc4000000, 8, 54}, /* 469 '6' */ - { 0xc5800000, 9, 57}, /* 470 '9' */ - { 0xc5000000, 10, 51}, /* 471 '3' */ - { 0xc5400000, 11, 1}, /* 472 '0x01' */ - { 0xc5600000, 11, 116}, /* 473 't' */ - /* 11 */ - { 0x80000000, 1, 0}, /* 474 '0x00' */ - { 0x40000000, 2, 32}, /* 475 ' ' */ - { 0x00000000, 3, 48}, /* 476 '0' */ - { 0x30000000, 4, 46}, /* 477 '.' */ - { 0x28000000, 5, 47}, /* 478 '/' */ - { 0x20000000, 7, 49}, /* 479 '1' */ - { 0x24000000, 7, 53}, /* 480 '5' */ - { 0x22000000, 8, 1}, /* 481 '0x01' */ - { 0x23000000, 8, 52}, /* 482 '4' */ - { 0x26000000, 8, 51}, /* 483 '3' */ - { 0x27000000, 8, 50}, /* 484 '2' */ - /* 15 */ - { 0x80000000, 1, 32}, /* 485 ' ' */ - { 0x00000000, 2, 48}, /* 486 '0' */ - { 0x40000000, 3, 58}, /* 487 ':' */ - { 0x68000000, 5, 0}, /* 488 '0x00' */ - { 0x60000000, 6, 116}, /* 489 't' */ - { 0x64000000, 6, 112}, /* 490 'p' */ - { 0x74000000, 6, 56}, /* 491 '8' */ - { 0x78000000, 6, 46}, /* 492 '.' */ - { 0x7c000000, 6, 54}, /* 493 '6' */ - { 0x70000000, 7, 53}, /* 494 '5' */ - { 0x72000000, 8, 57}, /* 495 '9' */ - { 0x73000000, 9, 77}, /* 496 'M' */ - { 0x73800000, 10, 70}, /* 497 'F' */ - { 0x73c00000, 11, 1}, /* 498 '0x01' */ - { 0x73e00000, 11, 99}, /* 499 'c' */ - /* 14 */ - { 0x00000000, 1, 49}, /* 500 '1' */ - { 0xc0000000, 2, 0}, /* 501 '0x00' */ - { 0x80000000, 4, 57}, /* 502 '9' */ - { 0xa0000000, 4, 46}, /* 503 '.' */ - { 0x98000000, 5, 48}, /* 504 '0' */ - { 0x90000000, 6, 32}, /* 505 ' ' */ - { 0x94000000, 6, 56}, /* 506 '8' */ - { 0xb0000000, 6, 55}, /* 507 '7' */ - { 0xb4000000, 6, 47}, /* 508 '/' */ - { 0xb8000000, 6, 54}, /* 509 '6' */ - { 0xbe000000, 7, 58}, /* 510 ':' */ - { 0xbd000000, 8, 52}, /* 511 '4' */ - { 0xbc000000, 9, 1}, /* 512 '0x01' */ - { 0xbc800000, 9, 51}, /* 513 '3' */ - /* 9 */ - { 0x80000000, 1, 32}, /* 514 ' ' */ - { 0x00000000, 2, 48}, /* 515 '0' */ - { 0x60000000, 3, 46}, /* 516 '.' */ - { 0x40000000, 4, 50}, /* 517 '2' */ - { 0x50000000, 5, 49}, /* 518 '1' */ - { 0x5c000000, 6, 51}, /* 519 '3' */ - { 0x5a000000, 7, 67}, /* 520 'C' */ - { 0x58000000, 8, 1}, /* 521 '0x01' */ - { 0x59000000, 8, 84}, /* 522 'T' */ - /* 3 */ - { 0x80000000, 1, 32}, /* 523 ' ' */ - { 0x00000000, 2, 1}, /* 524 '0x01' */ - { 0x40000000, 2, 46}, /* 525 '.' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 526 '0x01' */ - { 0x80000000, 1, 1}, /* 527 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 528 '0x01' */ - { 0x80000000, 1, 1}, /* 529 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 530 '0x01' */ - { 0x80000000, 1, 1}, /* 531 '0x01' */ - /* 5 */ - { 0x80000000, 1, 0}, /* 532 '0x00' */ - { 0x40000000, 2, 32}, /* 533 ' ' */ - { 0x20000000, 3, 58}, /* 534 ':' */ - { 0x00000000, 4, 1}, /* 535 '0x01' */ - { 0x10000000, 4, 46}, /* 536 '.' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 537 '0x01' */ - { 0x80000000, 1, 72}, /* 538 'H' */ - /* 44 */ - { 0x20000000, 3, 114}, /* 539 'r' */ - { 0x40000000, 3, 32}, /* 540 ' ' */ - { 0x80000000, 3, 108}, /* 541 'l' */ - { 0xc0000000, 3, 110}, /* 542 'n' */ - { 0x00000000, 4, 109}, /* 543 'm' */ - { 0x70000000, 4, 103}, /* 544 'g' */ - { 0xf0000000, 4, 100}, /* 545 'd' */ - { 0x10000000, 5, 119}, /* 546 'w' */ - { 0x60000000, 5, 84}, /* 547 'T' */ - { 0x68000000, 5, 99}, /* 548 'c' */ - { 0xa8000000, 5, 116}, /* 549 't' */ - { 0xb0000000, 5, 102}, /* 550 'f' */ - { 0xb8000000, 5, 105}, /* 551 'i' */ - { 0xe0000000, 5, 115}, /* 552 's' */ - { 0x18000000, 6, 117}, /* 553 'u' */ - { 0x1c000000, 6, 0}, /* 554 '0x00' */ - { 0xa4000000, 6, 82}, /* 555 'R' */ - { 0xe8000000, 6, 98}, /* 556 'b' */ - { 0xa2000000, 7, 118}, /* 557 'v' */ - { 0xec000000, 7, 112}, /* 558 'p' */ - { 0xa0000000, 8, 83}, /* 559 'S' */ - { 0xee000000, 8, 77}, /* 560 'M' */ - { 0xa1800000, 9, 80}, /* 561 'P' */ - { 0xef800000, 9, 46}, /* 562 '.' */ - { 0xa1000000, 11, 101}, /* 563 'e' */ - { 0xa1200000, 11, 66}, /* 564 'B' */ - { 0xa1400000, 11, 49}, /* 565 '1' */ - { 0xef600000, 11, 45}, /* 566 '-' */ - { 0xa1600000, 12, 107}, /* 567 'k' */ - { 0xa1700000, 12, 104}, /* 568 'h' */ - { 0xef000000, 12, 97}, /* 569 'a' */ - { 0xef400000, 12, 121}, /* 570 'y' */ - { 0xef500000, 12, 42}, /* 571 '*' */ - { 0xef100000, 13, 120}, /* 572 'x' */ - { 0xef180000, 13, 39}, /* 573 '\'' */ - { 0xef200000, 13, 78}, /* 574 'N' */ - { 0xef300000, 13, 50}, /* 575 '2' */ - { 0xef280000, 14, 58}, /* 576 ':' */ - { 0xef3c0000, 14, 122}, /* 577 'z' */ - { 0xef2c0000, 15, 76}, /* 578 'L' */ - { 0xef2e0000, 15, 70}, /* 579 'F' */ - { 0xef380000, 15, 68}, /* 580 'D' */ - { 0xef3a0000, 16, 1}, /* 581 '0x01' */ - { 0xef3b0000, 16, 113}, /* 582 'q' */ - /* 26 */ - { 0x00000000, 2, 67}, /* 583 'C' */ - { 0x40000000, 2, 66}, /* 584 'B' */ - { 0xa0000000, 3, 114}, /* 585 'r' */ - { 0x90000000, 4, 105}, /* 586 'i' */ - { 0xc0000000, 4, 111}, /* 587 'o' */ - { 0xd0000000, 4, 117}, /* 588 'u' */ - { 0xe0000000, 4, 97}, /* 589 'a' */ - { 0xf0000000, 4, 101}, /* 590 'e' */ - { 0x88000000, 5, 108}, /* 591 'l' */ - { 0x80000000, 7, 0}, /* 592 '0x00' */ - { 0x84000000, 7, 121}, /* 593 'y' */ - { 0x82000000, 8, 79}, /* 594 'O' */ - { 0x86000000, 8, 51}, /* 595 '3' */ - { 0x83800000, 9, 65}, /* 596 'A' */ - { 0x87000000, 9, 83}, /* 597 'S' */ - { 0x83400000, 10, 58}, /* 598 ':' */ - { 0x83000000, 11, 46}, /* 599 '.' */ - { 0x83200000, 11, 119}, /* 600 'w' */ - { 0x87a00000, 11, 104}, /* 601 'h' */ - { 0x87c00000, 11, 42}, /* 602 '*' */ - { 0x87e00000, 11, 32}, /* 603 ' ' */ - { 0x87900000, 12, 82}, /* 604 'R' */ - { 0x87800000, 13, 39}, /* 605 '\'' */ - { 0x878c0000, 14, 84}, /* 606 'T' */ - { 0x87880000, 15, 1}, /* 607 '0x01' */ - { 0x878a0000, 15, 52}, /* 608 '4' */ - /* 31 */ - { 0x00000000, 2, 111}, /* 609 'o' */ - { 0x40000000, 2, 32}, /* 610 ' ' */ - { 0x80000000, 3, 108}, /* 611 'l' */ - { 0xc0000000, 3, 104}, /* 612 'h' */ - { 0xa0000000, 4, 114}, /* 613 'r' */ - { 0xe0000000, 4, 97}, /* 614 'a' */ - { 0xb0000000, 5, 105}, /* 615 'i' */ - { 0xb8000000, 5, 101}, /* 616 'e' */ - { 0xf0000000, 6, 117}, /* 617 'u' */ - { 0xf4000000, 6, 66}, /* 618 'B' */ - { 0xf8000000, 7, 121}, /* 619 'y' */ - { 0xfc000000, 7, 33}, /* 620 '!' */ - { 0xfb000000, 8, 46}, /* 621 '.' */ - { 0xfa000000, 9, 119}, /* 622 'w' */ - { 0xfe000000, 9, 0}, /* 623 '0x00' */ - { 0xff000000, 9, 83}, /* 624 'S' */ - { 0xff800000, 9, 84}, /* 625 'T' */ - { 0xfac00000, 10, 50}, /* 626 '2' */ - { 0xfec00000, 10, 73}, /* 627 'I' */ - { 0xfa800000, 11, 52}, /* 628 '4' */ - { 0xfaa00000, 11, 42}, /* 629 '*' */ - { 0xfea00000, 11, 68}, /* 630 'D' */ - { 0xfe800000, 12, 85}, /* 631 'U' */ - { 0xfe900000, 13, 39}, /* 632 '\'' */ - { 0xfe980000, 14, 110}, /* 633 'n' */ - { 0xfe9c0000, 15, 122}, /* 634 'z' */ - { 0xfe9e0000, 17, 79}, /* 635 'O' */ - { 0xfe9e8000, 17, 69}, /* 636 'E' */ - { 0xfe9f0000, 17, 65}, /* 637 'A' */ - { 0xfe9f8000, 18, 1}, /* 638 '0x01' */ - { 0xfe9fc000, 18, 115}, /* 639 's' */ - /* 28 */ - { 0x40000000, 2, 111}, /* 640 'o' */ - { 0x80000000, 2, 97}, /* 641 'a' */ - { 0x00000000, 3, 114}, /* 642 'r' */ - { 0xc0000000, 3, 101}, /* 643 'e' */ - { 0xe0000000, 3, 105}, /* 644 'i' */ - { 0x20000000, 5, 116}, /* 645 't' */ - { 0x38000000, 5, 117}, /* 646 'u' */ - { 0x2c000000, 6, 32}, /* 647 ' ' */ - { 0x2a000000, 7, 74}, /* 648 'J' */ - { 0x30000000, 7, 121}, /* 649 'y' */ - { 0x34000000, 7, 0}, /* 650 '0x00' */ - { 0x36000000, 7, 73}, /* 651 'I' */ - { 0x33000000, 8, 58}, /* 652 ':' */ - { 0x28800000, 9, 42}, /* 653 '*' */ - { 0x29000000, 9, 45}, /* 654 '-' */ - { 0x29800000, 9, 38}, /* 655 '&' */ - { 0x32000000, 9, 39}, /* 656 '\'' */ - { 0x28000000, 10, 65}, /* 657 'A' */ - { 0x28400000, 10, 104}, /* 658 'h' */ - { 0x32a00000, 11, 78}, /* 659 'N' */ - { 0x32c00000, 11, 86}, /* 660 'V' */ - { 0x32e00000, 12, 68}, /* 661 'D' */ - { 0x32f00000, 12, 119}, /* 662 'w' */ - { 0x32800000, 13, 79}, /* 663 'O' */ - { 0x32880000, 13, 69}, /* 664 'E' */ - { 0x32980000, 13, 100}, /* 665 'd' */ - { 0x32900000, 14, 1}, /* 666 '0x01' */ - { 0x32940000, 14, 84}, /* 667 'T' */ - /* 45 */ - { 0x00000000, 2, 109}, /* 668 'm' */ - { 0x60000000, 3, 118}, /* 669 'v' */ - { 0xa0000000, 3, 110}, /* 670 'n' */ - { 0xe0000000, 3, 97}, /* 671 'a' */ - { 0x40000000, 4, 69}, /* 672 'E' */ - { 0x80000000, 4, 0}, /* 673 '0x00' */ - { 0xd0000000, 4, 120}, /* 674 'x' */ - { 0x98000000, 5, 100}, /* 675 'd' */ - { 0xc8000000, 5, 108}, /* 676 'l' */ - { 0x50000000, 6, 52}, /* 677 '4' */ - { 0x54000000, 6, 121}, /* 678 'y' */ - { 0x58000000, 6, 117}, /* 679 'u' */ - { 0x90000000, 6, 114}, /* 680 'r' */ - { 0xc0000000, 6, 105}, /* 681 'i' */ - { 0x5e000000, 7, 115}, /* 682 's' */ - { 0x94000000, 7, 70}, /* 683 'F' */ - { 0xc4000000, 7, 88}, /* 684 'X' */ - { 0x96000000, 8, 82}, /* 685 'R' */ - { 0xc7000000, 8, 32}, /* 686 ' ' */ - { 0x5d000000, 9, 103}, /* 687 'g' */ - { 0x97800000, 9, 58}, /* 688 ':' */ - { 0xc6000000, 9, 84}, /* 689 'T' */ - { 0xc6800000, 9, 39}, /* 690 '\'' */ - { 0x5c400000, 10, 99}, /* 691 'c' */ - { 0x5cc00000, 10, 113}, /* 692 'q' */ - { 0x5d800000, 10, 101}, /* 693 'e' */ - { 0x5dc00000, 10, 67}, /* 694 'C' */ - { 0x97000000, 10, 112}, /* 695 'p' */ - { 0x5c000000, 11, 45}, /* 696 '-' */ - { 0x5ca00000, 11, 90}, /* 697 'Z' */ - { 0x97600000, 11, 116}, /* 698 't' */ - { 0x5c200000, 12, 83}, /* 699 'S' */ - { 0x5c300000, 12, 46}, /* 700 '.' */ - { 0x97500000, 12, 87}, /* 701 'W' */ - { 0x5c800000, 13, 33}, /* 702 '!' */ - { 0x97400000, 13, 111}, /* 703 'o' */ - { 0x5c880000, 14, 102}, /* 704 'f' */ - { 0x5c8c0000, 14, 85}, /* 705 'U' */ - { 0x5c900000, 14, 78}, /* 706 'N' */ - { 0x5c940000, 14, 77}, /* 707 'M' */ - { 0x5c980000, 14, 76}, /* 708 'L' */ - { 0x5c9c0000, 14, 65}, /* 709 'A' */ - { 0x974c0000, 14, 68}, /* 710 'D' */ - { 0x97480000, 15, 1}, /* 711 '0x01' */ - { 0x974a0000, 15, 119}, /* 712 'w' */ - /* 26 */ - { 0x00000000, 2, 105}, /* 713 'i' */ - { 0x80000000, 2, 97}, /* 714 'a' */ - { 0x60000000, 3, 114}, /* 715 'r' */ - { 0xc0000000, 3, 117}, /* 716 'u' */ - { 0xe0000000, 3, 111}, /* 717 'o' */ - { 0x40000000, 4, 101}, /* 718 'e' */ - { 0x58000000, 5, 108}, /* 719 'l' */ - { 0x50000000, 7, 65}, /* 720 'A' */ - { 0x54000000, 7, 79}, /* 721 'O' */ - { 0x52000000, 8, 32}, /* 722 ' ' */ - { 0x53000000, 9, 104}, /* 723 'h' */ - { 0x53800000, 9, 116}, /* 724 't' */ - { 0x56800000, 9, 102}, /* 725 'f' */ - { 0x57800000, 9, 76}, /* 726 'L' */ - { 0x56400000, 10, 0}, /* 727 '0x00' */ - { 0x57000000, 11, 106}, /* 728 'j' */ - { 0x57200000, 11, 73}, /* 729 'I' */ - { 0x57400000, 11, 46}, /* 730 '.' */ - { 0x57600000, 11, 49}, /* 731 '1' */ - { 0x56000000, 12, 77}, /* 732 'M' */ - { 0x56200000, 12, 42}, /* 733 '*' */ - { 0x56300000, 12, 75}, /* 734 'K' */ - { 0x56100000, 13, 121}, /* 735 'y' */ - { 0x561c0000, 14, 72}, /* 736 'H' */ - { 0x56180000, 15, 1}, /* 737 '0x01' */ - { 0x561a0000, 15, 33}, /* 738 '!' */ - /* 25 */ - { 0x80000000, 2, 114}, /* 739 'r' */ - { 0x20000000, 3, 77}, /* 740 'M' */ - { 0x40000000, 3, 97}, /* 741 'a' */ - { 0x60000000, 3, 111}, /* 742 'o' */ - { 0xc0000000, 3, 105}, /* 743 'i' */ - { 0xe0000000, 3, 101}, /* 744 'e' */ - { 0x08000000, 5, 117}, /* 745 'u' */ - { 0x10000000, 5, 88}, /* 746 'X' */ - { 0x04000000, 6, 104}, /* 747 'h' */ - { 0x1c000000, 6, 108}, /* 748 'l' */ - { 0x02000000, 7, 121}, /* 749 'y' */ - { 0x18000000, 7, 119}, /* 750 'w' */ - { 0x00000000, 8, 58}, /* 751 ':' */ - { 0x1b000000, 8, 67}, /* 752 'C' */ - { 0x01800000, 9, 0}, /* 753 '0x00' */ - { 0x1a000000, 9, 45}, /* 754 '-' */ - { 0x1a800000, 10, 80}, /* 755 'P' */ - { 0x1ac00000, 10, 32}, /* 756 ' ' */ - { 0x01000000, 11, 39}, /* 757 '\'' */ - { 0x01400000, 11, 65}, /* 758 'A' */ - { 0x01200000, 12, 85}, /* 759 'U' */ - { 0x01600000, 12, 84}, /* 760 'T' */ - { 0x01700000, 12, 52}, /* 761 '4' */ - { 0x01300000, 13, 1}, /* 762 '0x01' */ - { 0x01380000, 13, 89}, /* 763 'Y' */ - /* 19 */ - { 0x00000000, 1, 111}, /* 764 'o' */ - { 0x80000000, 3, 97}, /* 765 'a' */ - { 0xa0000000, 3, 105}, /* 766 'i' */ - { 0xc0000000, 3, 101}, /* 767 'e' */ - { 0xe0000000, 4, 117}, /* 768 'u' */ - { 0xf0000000, 5, 82}, /* 769 'R' */ - { 0xf8000000, 6, 65}, /* 770 'A' */ - { 0xfc000000, 7, 46}, /* 771 '.' */ - { 0xfe800000, 9, 121}, /* 772 'y' */ - { 0xff000000, 9, 83}, /* 773 'S' */ - { 0xff800000, 10, 69}, /* 774 'E' */ - { 0xffc00000, 10, 114}, /* 775 'r' */ - { 0xfe000000, 11, 0}, /* 776 '0x00' */ - { 0xfe400000, 11, 76}, /* 777 'L' */ - { 0xfe600000, 11, 77}, /* 778 'M' */ - { 0xfe300000, 12, 119}, /* 779 'w' */ - { 0xfe280000, 13, 68}, /* 780 'D' */ - { 0xfe200000, 14, 1}, /* 781 '0x01' */ - { 0xfe240000, 14, 73}, /* 782 'I' */ - /* 41 */ - { 0x00000000, 1, 84}, /* 783 'T' */ - { 0x80000000, 3, 115}, /* 784 's' */ - { 0xa0000000, 3, 110}, /* 785 'n' */ - { 0xd0000000, 4, 116}, /* 786 't' */ - { 0xc8000000, 5, 32}, /* 787 ' ' */ - { 0xe8000000, 5, 39}, /* 788 '\'' */ - { 0xf8000000, 5, 114}, /* 789 'r' */ - { 0xc0000000, 6, 73}, /* 790 'I' */ - { 0xc4000000, 6, 0}, /* 791 '0x00' */ - { 0xe4000000, 6, 109}, /* 792 'm' */ - { 0xe0000000, 7, 100}, /* 793 'd' */ - { 0xe2000000, 7, 78}, /* 794 'N' */ - { 0xf2000000, 7, 122}, /* 795 'z' */ - { 0xf4000000, 7, 46}, /* 796 '.' */ - { 0xf0000000, 8, 97}, /* 797 'a' */ - { 0xf1000000, 8, 89}, /* 798 'Y' */ - { 0xf6000000, 9, 83}, /* 799 'S' */ - { 0xf7000000, 9, 99}, /* 800 'c' */ - { 0xf6a00000, 11, 68}, /* 801 'D' */ - { 0xf6c00000, 11, 102}, /* 802 'f' */ - { 0xf7800000, 11, 108}, /* 803 'l' */ - { 0xf7e00000, 11, 121}, /* 804 'y' */ - { 0xf6800000, 12, 86}, /* 805 'V' */ - { 0xf6e00000, 12, 111}, /* 806 'o' */ - { 0xf7b00000, 12, 70}, /* 807 'F' */ - { 0xf6900000, 13, 44}, /* 808 ',' */ - { 0xf6980000, 13, 65}, /* 809 'A' */ - { 0xf6f00000, 13, 79}, /* 810 'O' */ - { 0xf7a80000, 13, 103}, /* 811 'g' */ - { 0xf7c00000, 13, 67}, /* 812 'C' */ - { 0xf7c80000, 13, 58}, /* 813 ':' */ - { 0xf7d80000, 13, 118}, /* 814 'v' */ - { 0xf6f80000, 14, 112}, /* 815 'p' */ - { 0xf6fc0000, 14, 69}, /* 816 'E' */ - { 0xf7a00000, 14, 66}, /* 817 'B' */ - { 0xf7d00000, 14, 107}, /* 818 'k' */ - { 0xf7d40000, 14, 98}, /* 819 'b' */ - { 0xf7a40000, 16, 1}, /* 820 '0x01' */ - { 0xf7a50000, 16, 82}, /* 821 'R' */ - { 0xf7a60000, 16, 76}, /* 822 'L' */ - { 0xf7a70000, 16, 71}, /* 823 'G' */ - /* 16 */ - { 0x00000000, 2, 97}, /* 824 'a' */ - { 0x40000000, 2, 117}, /* 825 'u' */ - { 0xc0000000, 2, 101}, /* 826 'e' */ - { 0xa0000000, 3, 111}, /* 827 'o' */ - { 0x90000000, 4, 105}, /* 828 'i' */ - { 0x80000000, 5, 32}, /* 829 ' ' */ - { 0x88000000, 6, 75}, /* 830 'K' */ - { 0x8e000000, 7, 0}, /* 831 '0x00' */ - { 0x8c800000, 9, 115}, /* 832 's' */ - { 0x8d000000, 9, 70}, /* 833 'F' */ - { 0x8c000000, 10, 86}, /* 834 'V' */ - { 0x8c400000, 10, 39}, /* 835 '\'' */ - { 0x8dc00000, 10, 102}, /* 836 'f' */ - { 0x8da00000, 11, 71}, /* 837 'G' */ - { 0x8d800000, 12, 1}, /* 838 '0x01' */ - { 0x8d900000, 12, 68}, /* 839 'D' */ - /* 26 */ - { 0x40000000, 2, 105}, /* 840 'i' */ - { 0xc0000000, 2, 121}, /* 841 'y' */ - { 0x20000000, 3, 101}, /* 842 'e' */ - { 0xa0000000, 3, 32}, /* 843 ' ' */ - { 0x00000000, 4, 97}, /* 844 'a' */ - { 0x80000000, 4, 111}, /* 845 'o' */ - { 0x10000000, 5, 0}, /* 846 '0x00' */ - { 0x18000000, 5, 114}, /* 847 'r' */ - { 0x94000000, 6, 116}, /* 848 't' */ - { 0x98000000, 6, 110}, /* 849 'n' */ - { 0x9c000000, 6, 83}, /* 850 'S' */ - { 0x93000000, 8, 71}, /* 851 'G' */ - { 0x90000000, 9, 45}, /* 852 '-' */ - { 0x91800000, 9, 79}, /* 853 'O' */ - { 0x92000000, 9, 104}, /* 854 'h' */ - { 0x92800000, 9, 119}, /* 855 'w' */ - { 0x90800000, 10, 49}, /* 856 '1' */ - { 0x90c00000, 10, 39}, /* 857 '\'' */ - { 0x91600000, 11, 117}, /* 858 'u' */ - { 0x91000000, 12, 84}, /* 859 'T' */ - { 0x91100000, 12, 78}, /* 860 'N' */ - { 0x91200000, 12, 58}, /* 861 ':' */ - { 0x91300000, 12, 46}, /* 862 '.' */ - { 0x91400000, 12, 44}, /* 863 ',' */ - { 0x91500000, 13, 1}, /* 864 '0x01' */ - { 0x91580000, 13, 108}, /* 865 'l' */ - /* 19 */ - { 0x00000000, 2, 97}, /* 866 'a' */ - { 0x80000000, 2, 111}, /* 867 'o' */ - { 0xc0000000, 2, 105}, /* 868 'i' */ - { 0x40000000, 3, 101}, /* 869 'e' */ - { 0x70000000, 4, 117}, /* 870 'u' */ - { 0x68000000, 5, 75}, /* 871 'K' */ - { 0x60000000, 7, 108}, /* 872 'l' */ - { 0x64000000, 7, 65}, /* 873 'A' */ - { 0x66000000, 7, 32}, /* 874 ' ' */ - { 0x63000000, 8, 121}, /* 875 'y' */ - { 0x62000000, 10, 76}, /* 876 'L' */ - { 0x62400000, 10, 73}, /* 877 'I' */ - { 0x62800000, 11, 67}, /* 878 'C' */ - { 0x62a00000, 11, 46}, /* 879 '.' */ - { 0x62e00000, 11, 0}, /* 880 '0x00' */ - { 0x62d00000, 12, 39}, /* 881 '\'' */ - { 0x62c00000, 13, 69}, /* 882 'E' */ - { 0x62c80000, 14, 1}, /* 883 '0x01' */ - { 0x62cc0000, 14, 89}, /* 884 'Y' */ - /* 29 */ - { 0x40000000, 2, 97}, /* 885 'a' */ - { 0x80000000, 2, 111}, /* 886 'o' */ - { 0x00000000, 3, 101}, /* 887 'e' */ - { 0xe0000000, 3, 105}, /* 888 'i' */ - { 0x20000000, 4, 84}, /* 889 'T' */ - { 0xc0000000, 4, 121}, /* 890 'y' */ - { 0xd0000000, 4, 117}, /* 891 'u' */ - { 0x30000000, 5, 0}, /* 892 '0x00' */ - { 0x3c000000, 6, 99}, /* 893 'c' */ - { 0x39000000, 8, 114}, /* 894 'r' */ - { 0x3a000000, 8, 69}, /* 895 'E' */ - { 0x3b800000, 9, 70}, /* 896 'F' */ - { 0x38400000, 10, 90}, /* 897 'Z' */ - { 0x38c00000, 10, 32}, /* 898 ' ' */ - { 0x3b000000, 10, 49}, /* 899 '1' */ - { 0x3b400000, 10, 73}, /* 900 'I' */ - { 0x38200000, 11, 104}, /* 901 'h' */ - { 0x38800000, 11, 67}, /* 902 'C' */ - { 0x38100000, 12, 81}, /* 903 'Q' */ - { 0x38a00000, 12, 75}, /* 904 'K' */ - { 0x38b00000, 13, 80}, /* 905 'P' */ - { 0x38000000, 14, 58}, /* 906 ':' */ - { 0x38040000, 14, 46}, /* 907 '.' */ - { 0x38080000, 14, 39}, /* 908 '\'' */ - { 0x38b80000, 14, 77}, /* 909 'M' */ - { 0x380c0000, 15, 1}, /* 910 '0x01' */ - { 0x380e0000, 15, 119}, /* 911 'w' */ - { 0x38bc0000, 15, 83}, /* 912 'S' */ - { 0x38be0000, 15, 82}, /* 913 'R' */ - /* 22 */ - { 0x80000000, 1, 101}, /* 914 'e' */ - { 0x00000000, 2, 111}, /* 915 'o' */ - { 0x60000000, 3, 105}, /* 916 'i' */ - { 0x50000000, 4, 97}, /* 917 'a' */ - { 0x48000000, 5, 117}, /* 918 'u' */ - { 0x40000000, 6, 67}, /* 919 'C' */ - { 0x44000000, 8, 69}, /* 920 'E' */ - { 0x46000000, 8, 70}, /* 921 'F' */ - { 0x47000000, 9, 66}, /* 922 'B' */ - { 0x47800000, 9, 72}, /* 923 'H' */ - { 0x45800000, 10, 89}, /* 924 'Y' */ - { 0x45000000, 11, 71}, /* 925 'G' */ - { 0x45200000, 11, 39}, /* 926 '\'' */ - { 0x45600000, 11, 73}, /* 927 'I' */ - { 0x45c00000, 11, 65}, /* 928 'A' */ - { 0x45400000, 12, 77}, /* 929 'M' */ - { 0x45e00000, 12, 32}, /* 930 ' ' */ - { 0x45f00000, 12, 0}, /* 931 '0x00' */ - { 0x45500000, 13, 84}, /* 932 'T' */ - { 0x45580000, 14, 46}, /* 933 '.' */ - { 0x455c0000, 15, 1}, /* 934 '0x01' */ - { 0x455e0000, 15, 90}, /* 935 'Z' */ - /* 44 */ - { 0x00000000, 3, 39}, /* 936 '\'' */ - { 0x40000000, 3, 102}, /* 937 'f' */ - { 0xc0000000, 3, 117}, /* 938 'u' */ - { 0xe0000000, 3, 110}, /* 939 'n' */ - { 0x20000000, 4, 77}, /* 940 'M' */ - { 0x30000000, 4, 108}, /* 941 'l' */ - { 0x90000000, 4, 109}, /* 942 'm' */ - { 0x68000000, 5, 114}, /* 943 'r' */ - { 0x70000000, 5, 100}, /* 944 'd' */ - { 0x80000000, 5, 112}, /* 945 'p' */ - { 0xa0000000, 5, 104}, /* 946 'h' */ - { 0xb0000000, 5, 0}, /* 947 '0x00' */ - { 0x64000000, 6, 83}, /* 948 'S' */ - { 0x78000000, 6, 122}, /* 949 'z' */ - { 0x7c000000, 6, 98}, /* 950 'b' */ - { 0x8c000000, 6, 118}, /* 951 'v' */ - { 0xa8000000, 6, 119}, /* 952 'w' */ - { 0xac000000, 6, 85}, /* 953 'U' */ - { 0xb8000000, 7, 84}, /* 954 'T' */ - { 0xba000000, 7, 79}, /* 955 'O' */ - { 0xbc000000, 7, 75}, /* 956 'K' */ - { 0x61000000, 8, 67}, /* 957 'C' */ - { 0x62000000, 8, 120}, /* 958 'x' */ - { 0x63000000, 8, 46}, /* 959 '.' */ - { 0x89000000, 8, 116}, /* 960 't' */ - { 0x8b000000, 8, 32}, /* 961 ' ' */ - { 0xbe000000, 8, 115}, /* 962 's' */ - { 0xbf000000, 8, 78}, /* 963 'N' */ - { 0x60800000, 9, 103}, /* 964 'g' */ - { 0x88000000, 9, 45}, /* 965 '-' */ - { 0x8a800000, 9, 97}, /* 966 'a' */ - { 0x88800000, 10, 105}, /* 967 'i' */ - { 0x88c00000, 10, 101}, /* 968 'e' */ - { 0x8a400000, 10, 111}, /* 969 'o' */ - { 0x60000000, 11, 65}, /* 970 'A' */ - { 0x60200000, 11, 106}, /* 971 'j' */ - { 0x60400000, 11, 99}, /* 972 'c' */ - { 0x8a000000, 11, 50}, /* 973 '2' */ - { 0x60700000, 12, 82}, /* 974 'R' */ - { 0x8a200000, 12, 80}, /* 975 'P' */ - { 0x8a300000, 12, 58}, /* 976 ':' */ - { 0x60600000, 13, 69}, /* 977 'E' */ - { 0x60680000, 14, 1}, /* 978 '0x01' */ - { 0x606c0000, 14, 76}, /* 979 'L' */ - /* 28 */ - { 0x40000000, 2, 114}, /* 980 'r' */ - { 0x80000000, 2, 108}, /* 981 'l' */ - { 0x00000000, 3, 101}, /* 982 'e' */ - { 0x20000000, 3, 97}, /* 983 'a' */ - { 0xe0000000, 3, 111}, /* 984 'o' */ - { 0xd0000000, 4, 105}, /* 985 'i' */ - { 0xc0000000, 6, 68}, /* 986 'D' */ - { 0xc4000000, 6, 117}, /* 987 'u' */ - { 0xcc000000, 6, 104}, /* 988 'h' */ - { 0xc8000000, 8, 32}, /* 989 ' ' */ - { 0xca000000, 8, 50}, /* 990 '2' */ - { 0xc9000000, 9, 72}, /* 991 'H' */ - { 0xc9800000, 9, 77}, /* 992 'M' */ - { 0xcb000000, 9, 83}, /* 993 'S' */ - { 0xcb800000, 11, 58}, /* 994 ':' */ - { 0xcba00000, 11, 42}, /* 995 '*' */ - { 0xcbd00000, 12, 115}, /* 996 's' */ - { 0xcbc80000, 13, 73}, /* 997 'I' */ - { 0xcbe00000, 13, 0}, /* 998 '0x00' */ - { 0xcbe80000, 13, 71}, /* 999 'G' */ - { 0xcbf00000, 13, 39}, /* 1000 '\'' */ - { 0xcbf80000, 14, 121}, /* 1001 'y' */ - { 0xcbc00000, 15, 89}, /* 1002 'Y' */ - { 0xcbc20000, 15, 76}, /* 1003 'L' */ - { 0xcbc40000, 15, 67}, /* 1004 'C' */ - { 0xcbc60000, 15, 1}, /* 1005 '0x01' */ - { 0xcbfc0000, 15, 79}, /* 1006 'O' */ - { 0xcbfe0000, 15, 46}, /* 1007 '.' */ - /* 8 */ - { 0x80000000, 1, 117}, /* 1008 'u' */ - { 0x00000000, 3, 73}, /* 1009 'I' */ - { 0x20000000, 3, 0}, /* 1010 '0x00' */ - { 0x40000000, 3, 86}, /* 1011 'V' */ - { 0x70000000, 4, 32}, /* 1012 ' ' */ - { 0x68000000, 5, 67}, /* 1013 'C' */ - { 0x60000000, 6, 1}, /* 1014 '0x01' */ - { 0x64000000, 6, 39}, /* 1015 '\'' */ - /* 23 */ - { 0x00000000, 2, 97}, /* 1016 'a' */ - { 0x40000000, 2, 111}, /* 1017 'o' */ - { 0xc0000000, 2, 101}, /* 1018 'e' */ - { 0x80000000, 3, 105}, /* 1019 'i' */ - { 0xb0000000, 4, 117}, /* 1020 'u' */ - { 0xa8000000, 5, 69}, /* 1021 'E' */ - { 0xa0000000, 6, 68}, /* 1022 'D' */ - { 0xa6000000, 7, 0}, /* 1023 '0x00' */ - { 0xa5000000, 8, 104}, /* 1024 'h' */ - { 0xa4000000, 10, 73}, /* 1025 'I' */ - { 0xa4800000, 10, 121}, /* 1026 'y' */ - { 0xa4c00000, 10, 110}, /* 1027 'n' */ - { 0xa4600000, 12, 32}, /* 1028 ' ' */ - { 0xa4400000, 13, 39}, /* 1029 '\'' */ - { 0xa4580000, 13, 83}, /* 1030 'S' */ - { 0xa4700000, 13, 78}, /* 1031 'N' */ - { 0xa4480000, 14, 66}, /* 1032 'B' */ - { 0xa44c0000, 14, 46}, /* 1033 '.' */ - { 0xa4500000, 14, 38}, /* 1034 '&' */ - { 0xa4780000, 14, 84}, /* 1035 'T' */ - { 0xa47c0000, 14, 49}, /* 1036 '1' */ - { 0xa4540000, 15, 1}, /* 1037 '0x01' */ - { 0xa4560000, 15, 67}, /* 1038 'C' */ - /* 39 */ - { 0x20000000, 3, 111}, /* 1039 'o' */ - { 0x40000000, 3, 112}, /* 1040 'p' */ - { 0x60000000, 3, 117}, /* 1041 'u' */ - { 0xc0000000, 3, 104}, /* 1042 'h' */ - { 0xe0000000, 3, 116}, /* 1043 't' */ - { 0x10000000, 4, 97}, /* 1044 'a' */ - { 0x90000000, 4, 101}, /* 1045 'e' */ - { 0xb0000000, 4, 99}, /* 1046 'c' */ - { 0x00000000, 5, 110}, /* 1047 'n' */ - { 0x88000000, 5, 105}, /* 1048 'i' */ - { 0xa8000000, 5, 107}, /* 1049 'k' */ - { 0x0c000000, 6, 119}, /* 1050 'w' */ - { 0xa0000000, 6, 109}, /* 1051 'm' */ - { 0x0a000000, 7, 65}, /* 1052 'A' */ - { 0x84000000, 7, 108}, /* 1053 'l' */ - { 0xa4000000, 7, 113}, /* 1054 'q' */ - { 0xa6000000, 7, 77}, /* 1055 'M' */ - { 0x08000000, 8, 50}, /* 1056 '2' */ - { 0x09000000, 8, 80}, /* 1057 'P' */ - { 0x80000000, 8, 79}, /* 1058 'O' */ - { 0x82000000, 8, 73}, /* 1059 'I' */ - { 0x83000000, 8, 32}, /* 1060 ' ' */ - { 0x87000000, 8, 0}, /* 1061 '0x00' */ - { 0x81000000, 9, 121}, /* 1062 'y' */ - { 0x86000000, 9, 69}, /* 1063 'E' */ - { 0x81c00000, 10, 63}, /* 1064 '?' */ - { 0x86c00000, 10, 72}, /* 1065 'H' */ - { 0x81800000, 11, 66}, /* 1066 'B' */ - { 0x86800000, 11, 103}, /* 1067 'g' */ - { 0x81b00000, 12, 114}, /* 1068 'r' */ - { 0x86a00000, 12, 42}, /* 1069 '*' */ - { 0x86b00000, 13, 51}, /* 1070 '3' */ - { 0x86b80000, 13, 46}, /* 1071 '.' */ - { 0x81a00000, 14, 53}, /* 1072 '5' */ - { 0x81a80000, 14, 58}, /* 1073 ':' */ - { 0x81ac0000, 14, 49}, /* 1074 '1' */ - { 0x81a40000, 15, 67}, /* 1075 'C' */ - { 0x81a60000, 16, 1}, /* 1076 '0x01' */ - { 0x81a70000, 16, 89}, /* 1077 'Y' */ - /* 33 */ - { 0x00000000, 1, 104}, /* 1078 'h' */ - { 0xa0000000, 3, 111}, /* 1079 'o' */ - { 0xe0000000, 3, 86}, /* 1080 'V' */ - { 0x80000000, 4, 101}, /* 1081 'e' */ - { 0x90000000, 4, 114}, /* 1082 'r' */ - { 0xc0000000, 5, 97}, /* 1083 'a' */ - { 0xd0000000, 5, 119}, /* 1084 'w' */ - { 0xcc000000, 6, 105}, /* 1085 'i' */ - { 0xda000000, 7, 79}, /* 1086 'O' */ - { 0xde000000, 7, 72}, /* 1087 'H' */ - { 0xc9000000, 8, 121}, /* 1088 'y' */ - { 0xca000000, 8, 77}, /* 1089 'M' */ - { 0xd8000000, 8, 46}, /* 1090 '.' */ - { 0xdc000000, 8, 117}, /* 1091 'u' */ - { 0xdd000000, 8, 87}, /* 1092 'W' */ - { 0xc8800000, 9, 80}, /* 1093 'P' */ - { 0xcb000000, 9, 58}, /* 1094 ':' */ - { 0xcb800000, 9, 52}, /* 1095 '4' */ - { 0xd9800000, 9, 73}, /* 1096 'I' */ - { 0xd9000000, 10, 32}, /* 1097 ' ' */ - { 0xd9400000, 10, 0}, /* 1098 '0x00' */ - { 0xc8400000, 11, 88}, /* 1099 'X' */ - { 0xc8600000, 11, 115}, /* 1100 's' */ - { 0xc8000000, 12, 84}, /* 1101 'T' */ - { 0xc8100000, 12, 83}, /* 1102 'S' */ - { 0xc8200000, 12, 66}, /* 1103 'B' */ - { 0xc8300000, 13, 85}, /* 1104 'U' */ - { 0xc8380000, 14, 65}, /* 1105 'A' */ - { 0xc83c0000, 16, 67}, /* 1106 'C' */ - { 0xc83d0000, 16, 42}, /* 1107 '*' */ - { 0xc83f0000, 16, 78}, /* 1108 'N' */ - { 0xc83e0000, 17, 1}, /* 1109 '0x01' */ - { 0xc83e8000, 17, 89}, /* 1110 'Y' */ - /* 23 */ - { 0x00000000, 1, 110}, /* 1111 'n' */ - { 0x80000000, 2, 112}, /* 1112 'p' */ - { 0xd0000000, 4, 75}, /* 1113 'K' */ - { 0xf0000000, 4, 108}, /* 1114 'l' */ - { 0xc0000000, 5, 82}, /* 1115 'R' */ - { 0xe0000000, 5, 83}, /* 1116 'S' */ - { 0xcc000000, 6, 69}, /* 1117 'E' */ - { 0xec000000, 6, 115}, /* 1118 's' */ - { 0xca000000, 7, 103}, /* 1119 'g' */ - { 0xea000000, 7, 84}, /* 1120 'T' */ - { 0xc9000000, 8, 32}, /* 1121 ' ' */ - { 0xc8000000, 9, 45}, /* 1122 '-' */ - { 0xc8800000, 9, 114}, /* 1123 'r' */ - { 0xe8000000, 9, 50}, /* 1124 '2' */ - { 0xe8800000, 9, 109}, /* 1125 'm' */ - { 0xe9800000, 9, 0}, /* 1126 '0x00' */ - { 0xe9000000, 10, 46}, /* 1127 '.' */ - { 0xe9400000, 11, 99}, /* 1128 'c' */ - { 0xe9600000, 12, 107}, /* 1129 'k' */ - { 0xe9700000, 14, 1}, /* 1130 '0x01' */ - { 0xe9740000, 14, 122}, /* 1131 'z' */ - { 0xe9780000, 14, 116}, /* 1132 't' */ - { 0xe97c0000, 14, 66}, /* 1133 'B' */ - /* 21 */ - { 0x80000000, 1, 32}, /* 1134 ' ' */ - { 0x00000000, 3, 58}, /* 1135 ':' */ - { 0x60000000, 3, 105}, /* 1136 'i' */ - { 0x20000000, 4, 101}, /* 1137 'e' */ - { 0x30000000, 4, 97}, /* 1138 'a' */ - { 0x40000000, 4, 51}, /* 1139 '3' */ - { 0x54000000, 6, 67}, /* 1140 'C' */ - { 0x5c000000, 6, 0}, /* 1141 '0x00' */ - { 0x50000000, 7, 39}, /* 1142 '\'' */ - { 0x52000000, 7, 52}, /* 1143 '4' */ - { 0x5a000000, 7, 111}, /* 1144 'o' */ - { 0x59000000, 8, 73}, /* 1145 'I' */ - { 0x58000000, 10, 115}, /* 1146 's' */ - { 0x58400000, 10, 68}, /* 1147 'D' */ - { 0x58800000, 10, 46}, /* 1148 '.' */ - { 0x58c00000, 11, 56}, /* 1149 '8' */ - { 0x58e80000, 13, 117}, /* 1150 'u' */ - { 0x58f00000, 13, 114}, /* 1151 'r' */ - { 0x58f80000, 13, 66}, /* 1152 'B' */ - { 0x58e00000, 14, 1}, /* 1153 '0x01' */ - { 0x58e40000, 14, 69}, /* 1154 'E' */ - /* 18 */ - { 0x40000000, 2, 111}, /* 1155 'o' */ - { 0xc0000000, 2, 101}, /* 1156 'e' */ - { 0x20000000, 3, 104}, /* 1157 'h' */ - { 0x80000000, 3, 97}, /* 1158 'a' */ - { 0xa0000000, 3, 105}, /* 1159 'i' */ - { 0x00000000, 5, 46}, /* 1160 '.' */ - { 0x10000000, 5, 79}, /* 1161 'O' */ - { 0x18000000, 5, 114}, /* 1162 'r' */ - { 0x0c000000, 6, 121}, /* 1163 'y' */ - { 0x08000000, 7, 117}, /* 1164 'u' */ - { 0x0a000000, 8, 0}, /* 1165 '0x00' */ - { 0x0b800000, 9, 65}, /* 1166 'A' */ - { 0x0b200000, 11, 89}, /* 1167 'Y' */ - { 0x0b400000, 11, 84}, /* 1168 'T' */ - { 0x0b600000, 11, 32}, /* 1169 ' ' */ - { 0x0b000000, 12, 73}, /* 1170 'I' */ - { 0x0b100000, 13, 1}, /* 1171 '0x01' */ - { 0x0b180000, 13, 108}, /* 1172 'l' */ - /* 14 */ - { 0x00000000, 2, 0}, /* 1173 '0x00' */ - { 0x80000000, 2, 32}, /* 1174 ' ' */ - { 0xc0000000, 2, 116}, /* 1175 't' */ - { 0x40000000, 3, 84}, /* 1176 'T' */ - { 0x70000000, 4, 99}, /* 1177 'c' */ - { 0x68000000, 5, 109}, /* 1178 'm' */ - { 0x64000000, 6, 85}, /* 1179 'U' */ - { 0x60000000, 8, 97}, /* 1180 'a' */ - { 0x61000000, 8, 88}, /* 1181 'X' */ - { 0x62000000, 8, 45}, /* 1182 '-' */ - { 0x63000000, 9, 120}, /* 1183 'x' */ - { 0x63c00000, 10, 57}, /* 1184 '9' */ - { 0x63800000, 11, 1}, /* 1185 '0x01' */ - { 0x63a00000, 11, 105}, /* 1186 'i' */ - /* 19 */ - { 0x80000000, 1, 111}, /* 1187 'o' */ - { 0x40000000, 2, 101}, /* 1188 'e' */ - { 0x00000000, 3, 117}, /* 1189 'u' */ - { 0x30000000, 4, 32}, /* 1190 ' ' */ - { 0x20000000, 5, 118}, /* 1191 'v' */ - { 0x28000000, 6, 97}, /* 1192 'a' */ - { 0x2e000000, 8, 80}, /* 1193 'P' */ - { 0x2f000000, 8, 39}, /* 1194 '\'' */ - { 0x2c000000, 9, 110}, /* 1195 'n' */ - { 0x2d800000, 9, 114}, /* 1196 'r' */ - { 0x2c800000, 10, 68}, /* 1197 'D' */ - { 0x2cc00000, 11, 119}, /* 1198 'w' */ - { 0x2ce00000, 11, 115}, /* 1199 's' */ - { 0x2d000000, 11, 82}, /* 1200 'R' */ - { 0x2d200000, 11, 76}, /* 1201 'L' */ - { 0x2d400000, 11, 0}, /* 1202 '0x00' */ - { 0x2d600000, 12, 67}, /* 1203 'C' */ - { 0x2d700000, 13, 1}, /* 1204 '0x01' */ - { 0x2d780000, 13, 78}, /* 1205 'N' */ - /* 11 */ - { 0x80000000, 1, 111}, /* 1206 'o' */ - { 0x00000000, 2, 97}, /* 1207 'a' */ - { 0x40000000, 3, 105}, /* 1208 'i' */ - { 0x60000000, 5, 79}, /* 1209 'O' */ - { 0x68000000, 5, 117}, /* 1210 'u' */ - { 0x70000000, 5, 101}, /* 1211 'e' */ - { 0x78000000, 6, 32}, /* 1212 ' ' */ - { 0x7e000000, 7, 0}, /* 1213 '0x00' */ - { 0x7d000000, 8, 58}, /* 1214 ':' */ - { 0x7c000000, 9, 1}, /* 1215 '0x01' */ - { 0x7c800000, 9, 45}, /* 1216 '-' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 1217 '0x01' */ - { 0x80000000, 1, 1}, /* 1218 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 1219 '0x01' */ - { 0x80000000, 1, 120}, /* 1220 'x' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 1221 '0x01' */ - { 0x80000000, 1, 1}, /* 1222 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 1223 '0x01' */ - { 0x80000000, 1, 1}, /* 1224 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 1225 '0x01' */ - { 0x80000000, 1, 1}, /* 1226 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 1227 '0x01' */ - { 0x80000000, 1, 1}, /* 1228 '0x01' */ - /* 39 */ - { 0x20000000, 3, 114}, /* 1229 'r' */ - { 0x60000000, 3, 116}, /* 1230 't' */ - { 0x80000000, 3, 108}, /* 1231 'l' */ - { 0xc0000000, 3, 110}, /* 1232 'n' */ - { 0x10000000, 4, 109}, /* 1233 'm' */ - { 0x40000000, 4, 99}, /* 1234 'c' */ - { 0xa0000000, 4, 115}, /* 1235 's' */ - { 0xe0000000, 4, 121}, /* 1236 'y' */ - { 0xb0000000, 5, 32}, /* 1237 ' ' */ - { 0xb8000000, 5, 100}, /* 1238 'd' */ - { 0xf0000000, 5, 105}, /* 1239 'i' */ - { 0xf8000000, 5, 107}, /* 1240 'k' */ - { 0x08000000, 6, 98}, /* 1241 'b' */ - { 0x0c000000, 6, 0}, /* 1242 '0x00' */ - { 0x58000000, 6, 112}, /* 1243 'p' */ - { 0x5c000000, 6, 103}, /* 1244 'g' */ - { 0x00000000, 7, 101}, /* 1245 'e' */ - { 0x02000000, 7, 39}, /* 1246 '\'' */ - { 0x06000000, 7, 119}, /* 1247 'w' */ - { 0x52000000, 7, 117}, /* 1248 'u' */ - { 0x54000000, 7, 122}, /* 1249 'z' */ - { 0x56000000, 7, 118}, /* 1250 'v' */ - { 0x05000000, 8, 102}, /* 1251 'f' */ - { 0x51000000, 8, 104}, /* 1252 'h' */ - { 0x04800000, 9, 58}, /* 1253 ':' */ - { 0x04000000, 10, 33}, /* 1254 '!' */ - { 0x50000000, 10, 111}, /* 1255 'o' */ - { 0x50400000, 10, 120}, /* 1256 'x' */ - { 0x04400000, 11, 45}, /* 1257 '-' */ - { 0x04600000, 11, 97}, /* 1258 'a' */ - { 0x50a00000, 11, 46}, /* 1259 '.' */ - { 0x50c00000, 11, 78}, /* 1260 'N' */ - { 0x50e00000, 11, 44}, /* 1261 ',' */ - { 0x50800000, 12, 113}, /* 1262 'q' */ - { 0x50900000, 13, 106}, /* 1263 'j' */ - { 0x509c0000, 14, 63}, /* 1264 '?' */ - { 0x509a0000, 15, 74}, /* 1265 'J' */ - { 0x50980000, 16, 1}, /* 1266 '0x01' */ - { 0x50990000, 16, 85}, /* 1267 'U' */ - /* 24 */ - { 0x00000000, 3, 114}, /* 1268 'r' */ - { 0x20000000, 3, 111}, /* 1269 'o' */ - { 0x40000000, 3, 101}, /* 1270 'e' */ - { 0x60000000, 3, 97}, /* 1271 'a' */ - { 0x80000000, 3, 105}, /* 1272 'i' */ - { 0xb0000000, 4, 117}, /* 1273 'u' */ - { 0xc0000000, 4, 121}, /* 1274 'y' */ - { 0xd0000000, 4, 108}, /* 1275 'l' */ - { 0xf0000000, 4, 32}, /* 1276 ' ' */ - { 0xa8000000, 5, 115}, /* 1277 's' */ - { 0xe0000000, 5, 98}, /* 1278 'b' */ - { 0xe8000000, 5, 0}, /* 1279 '0x00' */ - { 0xa0000000, 6, 104}, /* 1280 'h' */ - { 0xa4000000, 7, 51}, /* 1281 '3' */ - { 0xa7000000, 8, 39}, /* 1282 '\'' */ - { 0xa6400000, 10, 116}, /* 1283 't' */ - { 0xa6800000, 10, 106}, /* 1284 'j' */ - { 0xa6000000, 11, 110}, /* 1285 'n' */ - { 0xa6200000, 11, 100}, /* 1286 'd' */ - { 0xa6e00000, 11, 119}, /* 1287 'w' */ - { 0xa6d00000, 12, 109}, /* 1288 'm' */ - { 0xa6c80000, 13, 46}, /* 1289 '.' */ - { 0xa6c00000, 14, 1}, /* 1290 '0x01' */ - { 0xa6c40000, 14, 58}, /* 1291 ':' */ - /* 37 */ - { 0x00000000, 2, 107}, /* 1292 'k' */ - { 0x40000000, 3, 111}, /* 1293 'o' */ - { 0x80000000, 3, 104}, /* 1294 'h' */ - { 0xc0000000, 3, 116}, /* 1295 't' */ - { 0xe0000000, 3, 101}, /* 1296 'e' */ - { 0x70000000, 4, 114}, /* 1297 'r' */ - { 0xa0000000, 5, 32}, /* 1298 ' ' */ - { 0xb0000000, 5, 105}, /* 1299 'i' */ - { 0xb8000000, 5, 97}, /* 1300 'a' */ - { 0x60000000, 6, 108}, /* 1301 'l' */ - { 0x64000000, 6, 121}, /* 1302 'y' */ - { 0x68000000, 6, 115}, /* 1303 's' */ - { 0x6c000000, 6, 0}, /* 1304 '0x00' */ - { 0xa8000000, 7, 99}, /* 1305 'c' */ - { 0xae000000, 7, 117}, /* 1306 'u' */ - { 0xaa000000, 8, 58}, /* 1307 ':' */ - { 0xab000000, 8, 80}, /* 1308 'P' */ - { 0xac800000, 9, 68}, /* 1309 'D' */ - { 0xad000000, 10, 71}, /* 1310 'G' */ - { 0xad800000, 10, 98}, /* 1311 'b' */ - { 0xac000000, 11, 76}, /* 1312 'L' */ - { 0xac200000, 11, 75}, /* 1313 'K' */ - { 0xac600000, 11, 65}, /* 1314 'A' */ - { 0xad400000, 11, 113}, /* 1315 'q' */ - { 0xadc00000, 11, 46}, /* 1316 '.' */ - { 0xade00000, 11, 67}, /* 1317 'C' */ - { 0xac400000, 12, 110}, /* 1318 'n' */ - { 0xac500000, 12, 39}, /* 1319 '\'' */ - { 0xad600000, 13, 66}, /* 1320 'B' */ - { 0xad680000, 13, 73}, /* 1321 'I' */ - { 0xad740000, 14, 102}, /* 1322 'f' */ - { 0xad780000, 14, 56}, /* 1323 '8' */ - { 0xad700000, 15, 77}, /* 1324 'M' */ - { 0xad720000, 15, 1}, /* 1325 '0x01' */ - { 0xad7e0000, 15, 70}, /* 1326 'F' */ - { 0xad7c0000, 16, 119}, /* 1327 'w' */ - { 0xad7d0000, 16, 81}, /* 1328 'Q' */ - /* 36 */ - { 0xc0000000, 2, 32}, /* 1329 ' ' */ - { 0x20000000, 3, 101}, /* 1330 'e' */ - { 0x80000000, 3, 0}, /* 1331 '0x00' */ - { 0xa0000000, 3, 97}, /* 1332 'a' */ - { 0x10000000, 4, 121}, /* 1333 'y' */ - { 0x40000000, 4, 105}, /* 1334 'i' */ - { 0x60000000, 4, 115}, /* 1335 's' */ - { 0x00000000, 5, 111}, /* 1336 'o' */ - { 0x50000000, 5, 100}, /* 1337 'd' */ - { 0x0c000000, 6, 117}, /* 1338 'u' */ - { 0x58000000, 6, 114}, /* 1339 'r' */ - { 0x5c000000, 6, 108}, /* 1340 'l' */ - { 0x74000000, 6, 118}, /* 1341 'v' */ - { 0x78000000, 6, 103}, /* 1342 'g' */ - { 0x08000000, 7, 39}, /* 1343 '\'' */ - { 0x7e000000, 7, 46}, /* 1344 '.' */ - { 0x0a000000, 8, 58}, /* 1345 ':' */ - { 0x0b000000, 8, 104}, /* 1346 'h' */ - { 0x70000000, 8, 99}, /* 1347 'c' */ - { 0x72000000, 8, 110}, /* 1348 'n' */ - { 0x73000000, 8, 119}, /* 1349 'w' */ - { 0x71000000, 9, 63}, /* 1350 '?' */ - { 0x7c000000, 9, 33}, /* 1351 '!' */ - { 0x7c800000, 9, 45}, /* 1352 '-' */ - { 0x7d000000, 9, 102}, /* 1353 'f' */ - { 0x71c00000, 10, 109}, /* 1354 'm' */ - { 0x7d800000, 10, 44}, /* 1355 ',' */ - { 0x7dc00000, 11, 116}, /* 1356 't' */ - { 0x7de00000, 11, 98}, /* 1357 'b' */ - { 0x71900000, 12, 41}, /* 1358 ')' */ - { 0x71a00000, 12, 47}, /* 1359 '/' */ - { 0x71b00000, 12, 107}, /* 1360 'k' */ - { 0x71880000, 13, 112}, /* 1361 'p' */ - { 0x71840000, 14, 122}, /* 1362 'z' */ - { 0x71800000, 15, 1}, /* 1363 '0x01' */ - { 0x71820000, 15, 52}, /* 1364 '4' */ - /* 42 */ - { 0x40000000, 2, 32}, /* 1365 ' ' */ - { 0x00000000, 3, 115}, /* 1366 's' */ - { 0xa0000000, 3, 114}, /* 1367 'r' */ - { 0x20000000, 4, 116}, /* 1368 't' */ - { 0x90000000, 4, 110}, /* 1369 'n' */ - { 0xc0000000, 4, 0}, /* 1370 '0x00' */ - { 0xe0000000, 4, 97}, /* 1371 'a' */ - { 0xf0000000, 4, 119}, /* 1372 'w' */ - { 0x80000000, 5, 108}, /* 1373 'l' */ - { 0xd8000000, 5, 101}, /* 1374 'e' */ - { 0x38000000, 6, 109}, /* 1375 'm' */ - { 0x88000000, 6, 99}, /* 1376 'c' */ - { 0x8c000000, 6, 100}, /* 1377 'd' */ - { 0x34000000, 7, 105}, /* 1378 'i' */ - { 0x36000000, 7, 112}, /* 1379 'p' */ - { 0x3c000000, 7, 98}, /* 1380 'b' */ - { 0xd0000000, 7, 118}, /* 1381 'v' */ - { 0xd6000000, 7, 121}, /* 1382 'y' */ - { 0x30000000, 8, 103}, /* 1383 'g' */ - { 0x31000000, 8, 102}, /* 1384 'f' */ - { 0x32000000, 8, 120}, /* 1385 'x' */ - { 0x3e000000, 8, 107}, /* 1386 'k' */ - { 0x3f000000, 8, 58}, /* 1387 ':' */ - { 0xd3000000, 8, 111}, /* 1388 'o' */ - { 0xd4000000, 8, 39}, /* 1389 '\'' */ - { 0x33800000, 9, 104}, /* 1390 'h' */ - { 0xd2800000, 9, 46}, /* 1391 '.' */ - { 0x33000000, 10, 80}, /* 1392 'P' */ - { 0x33400000, 10, 66}, /* 1393 'B' */ - { 0xd2000000, 10, 44}, /* 1394 ',' */ - { 0xd5000000, 10, 86}, /* 1395 'V' */ - { 0xd5400000, 10, 122}, /* 1396 'z' */ - { 0xd5c00000, 10, 106}, /* 1397 'j' */ - { 0xd2400000, 11, 52}, /* 1398 '4' */ - { 0xd2600000, 11, 63}, /* 1399 '?' */ - { 0xd5a00000, 11, 117}, /* 1400 'u' */ - { 0xd5900000, 12, 45}, /* 1401 '-' */ - { 0xd5880000, 13, 33}, /* 1402 '!' */ - { 0xd5840000, 14, 113}, /* 1403 'q' */ - { 0xd5820000, 15, 71}, /* 1404 'G' */ - { 0xd5800000, 16, 1}, /* 1405 '0x01' */ - { 0xd5810000, 16, 83}, /* 1406 'S' */ - /* 24 */ - { 0x00000000, 1, 32}, /* 1407 ' ' */ - { 0xa0000000, 3, 111}, /* 1408 'o' */ - { 0x90000000, 4, 116}, /* 1409 't' */ - { 0xc0000000, 4, 97}, /* 1410 'a' */ - { 0xd0000000, 4, 105}, /* 1411 'i' */ - { 0xf0000000, 4, 101}, /* 1412 'e' */ - { 0x80000000, 5, 46}, /* 1413 '.' */ - { 0xe0000000, 5, 114}, /* 1414 'r' */ - { 0xe8000000, 5, 102}, /* 1415 'f' */ - { 0x88000000, 6, 0}, /* 1416 '0x00' */ - { 0x8d000000, 8, 121}, /* 1417 'y' */ - { 0x8f000000, 8, 117}, /* 1418 'u' */ - { 0x8c000000, 9, 39}, /* 1419 '\'' */ - { 0x8e800000, 9, 108}, /* 1420 'l' */ - { 0x8cc00000, 10, 110}, /* 1421 'n' */ - { 0x8e000000, 10, 103}, /* 1422 'g' */ - { 0x8c800000, 11, 99}, /* 1423 'c' */ - { 0x8e400000, 11, 45}, /* 1424 '-' */ - { 0x8ca00000, 12, 44}, /* 1425 ',' */ - { 0x8cb00000, 12, 115}, /* 1426 's' */ - { 0x8e700000, 12, 58}, /* 1427 ':' */ - { 0x8e680000, 13, 107}, /* 1428 'k' */ - { 0x8e600000, 14, 1}, /* 1429 '0x01' */ - { 0x8e640000, 14, 98}, /* 1430 'b' */ - /* 33 */ - { 0x00000000, 2, 104}, /* 1431 'h' */ - { 0x80000000, 2, 32}, /* 1432 ' ' */ - { 0x40000000, 3, 0}, /* 1433 '0x00' */ - { 0x60000000, 3, 101}, /* 1434 'e' */ - { 0xc0000000, 4, 105}, /* 1435 'i' */ - { 0xe0000000, 5, 58}, /* 1436 ':' */ - { 0xe8000000, 5, 114}, /* 1437 'r' */ - { 0xf8000000, 5, 97}, /* 1438 'a' */ - { 0xd0000000, 6, 115}, /* 1439 's' */ - { 0xdc000000, 6, 108}, /* 1440 'l' */ - { 0xf4000000, 6, 117}, /* 1441 'u' */ - { 0xd6000000, 7, 98}, /* 1442 'b' */ - { 0xd8000000, 7, 103}, /* 1443 'g' */ - { 0xda000000, 7, 111}, /* 1444 'o' */ - { 0xf2000000, 7, 110}, /* 1445 'n' */ - { 0xd4000000, 8, 50}, /* 1446 '2' */ - { 0xf0000000, 8, 33}, /* 1447 '!' */ - { 0xf1800000, 9, 100}, /* 1448 'd' */ - { 0xd5000000, 10, 46}, /* 1449 '.' */ - { 0xd5400000, 10, 44}, /* 1450 ',' */ - { 0xd5800000, 10, 39}, /* 1451 '\'' */ - { 0xd5c00000, 10, 116}, /* 1452 't' */ - { 0xf1400000, 10, 121}, /* 1453 'y' */ - { 0xf1000000, 11, 119}, /* 1454 'w' */ - { 0xf1300000, 12, 109}, /* 1455 'm' */ - { 0xf12c0000, 14, 63}, /* 1456 '?' */ - { 0xf1200000, 15, 112}, /* 1457 'p' */ - { 0xf1220000, 15, 102}, /* 1458 'f' */ - { 0xf1240000, 15, 64}, /* 1459 '@' */ - { 0xf1260000, 15, 45}, /* 1460 '-' */ - { 0xf12a0000, 15, 59}, /* 1461 ';' */ - { 0xf1280000, 16, 1}, /* 1462 '0x01' */ - { 0xf1290000, 16, 122}, /* 1463 'z' */ - /* 31 */ - { 0x00000000, 1, 101}, /* 1464 'e' */ - { 0xa0000000, 3, 111}, /* 1465 'o' */ - { 0x90000000, 4, 105}, /* 1466 'i' */ - { 0xc0000000, 4, 97}, /* 1467 'a' */ - { 0xe0000000, 4, 32}, /* 1468 ' ' */ - { 0xf0000000, 4, 116}, /* 1469 't' */ - { 0xd0000000, 5, 114}, /* 1470 'r' */ - { 0xd8000000, 5, 0}, /* 1471 '0x00' */ - { 0x80000000, 6, 98}, /* 1472 'b' */ - { 0x84000000, 6, 117}, /* 1473 'u' */ - { 0x88000000, 8, 119}, /* 1474 'w' */ - { 0x89000000, 8, 100}, /* 1475 'd' */ - { 0x8a000000, 8, 110}, /* 1476 'n' */ - { 0x8b000000, 8, 121}, /* 1477 'y' */ - { 0x8c000000, 8, 33}, /* 1478 '!' */ - { 0x8d000000, 8, 108}, /* 1479 'l' */ - { 0x8f000000, 8, 46}, /* 1480 '.' */ - { 0x8e000000, 9, 39}, /* 1481 '\'' */ - { 0x8e800000, 10, 115}, /* 1482 's' */ - { 0x8ec00000, 11, 109}, /* 1483 'm' */ - { 0x8ef00000, 12, 58}, /* 1484 ':' */ - { 0x8ee00000, 14, 102}, /* 1485 'f' */ - { 0x8ee40000, 14, 63}, /* 1486 '?' */ - { 0x8ee80000, 14, 99}, /* 1487 'c' */ - { 0x8eec0000, 16, 118}, /* 1488 'v' */ - { 0x8eed0000, 16, 113}, /* 1489 'q' */ - { 0x8eee0000, 16, 103}, /* 1490 'g' */ - { 0x8eef0000, 18, 104}, /* 1491 'h' */ - { 0x8eef4000, 18, 1}, /* 1492 '0x01' */ - { 0x8eef8000, 18, 44}, /* 1493 ',' */ - { 0x8eefc000, 18, 42}, /* 1494 '*' */ - /* 35 */ - { 0x40000000, 2, 110}, /* 1495 'n' */ - { 0x00000000, 3, 99}, /* 1496 'c' */ - { 0x90000000, 4, 111}, /* 1497 'o' */ - { 0xa0000000, 4, 108}, /* 1498 'l' */ - { 0xc0000000, 4, 103}, /* 1499 'g' */ - { 0xd0000000, 4, 115}, /* 1500 's' */ - { 0xe0000000, 4, 116}, /* 1501 't' */ - { 0xf0000000, 4, 101}, /* 1502 'e' */ - { 0x28000000, 5, 97}, /* 1503 'a' */ - { 0x30000000, 5, 118}, /* 1504 'v' */ - { 0x80000000, 5, 114}, /* 1505 'r' */ - { 0x88000000, 5, 100}, /* 1506 'd' */ - { 0xb0000000, 5, 109}, /* 1507 'm' */ - { 0x20000000, 6, 112}, /* 1508 'p' */ - { 0x38000000, 6, 32}, /* 1509 ' ' */ - { 0xbc000000, 6, 102}, /* 1510 'f' */ - { 0x3c000000, 7, 122}, /* 1511 'z' */ - { 0x3e000000, 7, 0}, /* 1512 '0x00' */ - { 0xb8000000, 7, 98}, /* 1513 'b' */ - { 0xba000000, 7, 107}, /* 1514 'k' */ - { 0x25000000, 8, 45}, /* 1515 '-' */ - { 0x26000000, 8, 120}, /* 1516 'x' */ - { 0x24800000, 9, 39}, /* 1517 '\'' */ - { 0x27800000, 9, 113}, /* 1518 'q' */ - { 0x27000000, 10, 117}, /* 1519 'u' */ - { 0x27400000, 10, 105}, /* 1520 'i' */ - { 0x24200000, 11, 104}, /* 1521 'h' */ - { 0x24400000, 11, 58}, /* 1522 ':' */ - { 0x24600000, 11, 119}, /* 1523 'w' */ - { 0x24080000, 13, 44}, /* 1524 ',' */ - { 0x24100000, 13, 121}, /* 1525 'y' */ - { 0x24180000, 13, 47}, /* 1526 '/' */ - { 0x24000000, 14, 46}, /* 1527 '.' */ - { 0x24040000, 15, 1}, /* 1528 '0x01' */ - { 0x24060000, 15, 106}, /* 1529 'j' */ - /* 9 */ - { 0x00000000, 1, 121}, /* 1530 'y' */ - { 0xc0000000, 2, 111}, /* 1531 'o' */ - { 0xa0000000, 3, 101}, /* 1532 'e' */ - { 0x90000000, 4, 97}, /* 1533 'a' */ - { 0x88000000, 5, 117}, /* 1534 'u' */ - { 0x84000000, 6, 105}, /* 1535 'i' */ - { 0x80000000, 7, 0}, /* 1536 '0x00' */ - { 0x82000000, 8, 1}, /* 1537 '0x01' */ - { 0x83000000, 8, 32}, /* 1538 ' ' */ - /* 33 */ - { 0x00000000, 2, 32}, /* 1539 ' ' */ - { 0x80000000, 2, 101}, /* 1540 'e' */ - { 0x40000000, 3, 105}, /* 1541 'i' */ - { 0xc0000000, 3, 0}, /* 1542 '0x00' */ - { 0x60000000, 4, 121}, /* 1543 'y' */ - { 0x70000000, 4, 115}, /* 1544 's' */ - { 0xf0000000, 4, 102}, /* 1545 'f' */ - { 0xe4000000, 6, 97}, /* 1546 'a' */ - { 0xe8000000, 6, 108}, /* 1547 'l' */ - { 0xe2000000, 7, 58}, /* 1548 ':' */ - { 0xec000000, 7, 107}, /* 1549 'k' */ - { 0xe0000000, 8, 39}, /* 1550 '\'' */ - { 0xef000000, 8, 46}, /* 1551 '.' */ - { 0xe1800000, 9, 119}, /* 1552 'w' */ - { 0xee000000, 9, 111}, /* 1553 'o' */ - { 0xe1400000, 10, 104}, /* 1554 'h' */ - { 0xe1000000, 11, 98}, /* 1555 'b' */ - { 0xe1200000, 11, 44}, /* 1556 ',' */ - { 0xeee00000, 11, 110}, /* 1557 'n' */ - { 0xeea00000, 12, 63}, /* 1558 '?' */ - { 0xeec00000, 12, 109}, /* 1559 'm' */ - { 0xeed00000, 12, 33}, /* 1560 '!' */ - { 0xee900000, 13, 117}, /* 1561 'u' */ - { 0xee980000, 13, 99}, /* 1562 'c' */ - { 0xeeb00000, 13, 100}, /* 1563 'd' */ - { 0xeeb80000, 13, 116}, /* 1564 't' */ - { 0xee840000, 14, 106}, /* 1565 'j' */ - { 0xee880000, 14, 45}, /* 1566 '-' */ - { 0xee800000, 15, 112}, /* 1567 'p' */ - { 0xee820000, 15, 47}, /* 1568 '/' */ - { 0xee8e0000, 15, 83}, /* 1569 'S' */ - { 0xee8c0000, 16, 1}, /* 1570 '0x01' */ - { 0xee8d0000, 16, 114}, /* 1571 'r' */ - /* 36 */ - { 0x40000000, 2, 101}, /* 1572 'e' */ - { 0x00000000, 3, 108}, /* 1573 'l' */ - { 0xa0000000, 3, 97}, /* 1574 'a' */ - { 0x30000000, 4, 121}, /* 1575 'y' */ - { 0x80000000, 4, 0}, /* 1576 '0x00' */ - { 0x90000000, 4, 100}, /* 1577 'd' */ - { 0xc0000000, 4, 111}, /* 1578 'o' */ - { 0xe0000000, 4, 105}, /* 1579 'i' */ - { 0xf0000000, 4, 32}, /* 1580 ' ' */ - { 0x20000000, 5, 117}, /* 1581 'u' */ - { 0xd0000000, 5, 115}, /* 1582 's' */ - { 0x28000000, 6, 116}, /* 1583 't' */ - { 0x2c000000, 6, 109}, /* 1584 'm' */ - { 0xda000000, 7, 107}, /* 1585 'k' */ - { 0xd8000000, 8, 102}, /* 1586 'f' */ - { 0xdc000000, 8, 98}, /* 1587 'b' */ - { 0xde000000, 8, 39}, /* 1588 '\'' */ - { 0xdf000000, 8, 99}, /* 1589 'c' */ - { 0xd9800000, 9, 118}, /* 1590 'v' */ - { 0xdd000000, 9, 58}, /* 1591 ':' */ - { 0xd9400000, 10, 46}, /* 1592 '.' */ - { 0xdd800000, 10, 119}, /* 1593 'w' */ - { 0xd9000000, 11, 122}, /* 1594 'z' */ - { 0xdde00000, 11, 112}, /* 1595 'p' */ - { 0xd9200000, 12, 104}, /* 1596 'h' */ - { 0xd9300000, 12, 42}, /* 1597 '*' */ - { 0xddc00000, 13, 103}, /* 1598 'g' */ - { 0xddc80000, 13, 44}, /* 1599 ',' */ - { 0xddd00000, 14, 114}, /* 1600 'r' */ - { 0xddd40000, 14, 110}, /* 1601 'n' */ - { 0xdddc0000, 14, 45}, /* 1602 '-' */ - { 0xddd80000, 15, 33}, /* 1603 '!' */ - { 0xdddb0000, 16, 63}, /* 1604 '?' */ - { 0xddda8000, 17, 67}, /* 1605 'C' */ - { 0xddda0000, 18, 1}, /* 1606 '0x01' */ - { 0xddda4000, 18, 106}, /* 1607 'j' */ - /* 25 */ - { 0x80000000, 2, 101}, /* 1608 'e' */ - { 0x20000000, 3, 109}, /* 1609 'm' */ - { 0x60000000, 3, 32}, /* 1610 ' ' */ - { 0xe0000000, 3, 97}, /* 1611 'a' */ - { 0x00000000, 4, 105}, /* 1612 'i' */ - { 0x10000000, 4, 0}, /* 1613 '0x00' */ - { 0x40000000, 4, 121}, /* 1614 'y' */ - { 0xd0000000, 4, 112}, /* 1615 'p' */ - { 0x50000000, 5, 98}, /* 1616 'b' */ - { 0xc0000000, 5, 111}, /* 1617 'o' */ - { 0xc8000000, 6, 110}, /* 1618 'n' */ - { 0xcc000000, 6, 115}, /* 1619 's' */ - { 0x58000000, 7, 108}, /* 1620 'l' */ - { 0x5c000000, 7, 102}, /* 1621 'f' */ - { 0x5a000000, 8, 58}, /* 1622 ':' */ - { 0x5e000000, 8, 52}, /* 1623 '4' */ - { 0x5b000000, 9, 104}, /* 1624 'h' */ - { 0x5f000000, 9, 119}, /* 1625 'w' */ - { 0x5bc00000, 10, 39}, /* 1626 '\'' */ - { 0x5f800000, 10, 114}, /* 1627 'r' */ - { 0x5fc00000, 10, 117}, /* 1628 'u' */ - { 0x5ba00000, 11, 46}, /* 1629 '.' */ - { 0x5b900000, 12, 107}, /* 1630 'k' */ - { 0x5b800000, 13, 1}, /* 1631 '0x01' */ - { 0x5b880000, 13, 100}, /* 1632 'd' */ - /* 40 */ - { 0x00000000, 3, 105}, /* 1633 'i' */ - { 0x80000000, 3, 103}, /* 1634 'g' */ - { 0xa0000000, 3, 32}, /* 1635 ' ' */ - { 0xc0000000, 3, 100}, /* 1636 'd' */ - { 0x30000000, 4, 97}, /* 1637 'a' */ - { 0x40000000, 4, 115}, /* 1638 's' */ - { 0x60000000, 4, 101}, /* 1639 'e' */ - { 0xe0000000, 4, 0}, /* 1640 '0x00' */ - { 0xf0000000, 4, 116}, /* 1641 't' */ - { 0x70000000, 5, 99}, /* 1642 'c' */ - { 0x78000000, 5, 110}, /* 1643 'n' */ - { 0x28000000, 6, 121}, /* 1644 'y' */ - { 0x50000000, 6, 39}, /* 1645 '\'' */ - { 0x54000000, 6, 107}, /* 1646 'k' */ - { 0x5c000000, 6, 111}, /* 1647 'o' */ - { 0x20000000, 7, 114}, /* 1648 'r' */ - { 0x26000000, 7, 102}, /* 1649 'f' */ - { 0x2c000000, 7, 117}, /* 1650 'u' */ - { 0x2e000000, 7, 106}, /* 1651 'j' */ - { 0x22000000, 8, 118}, /* 1652 'v' */ - { 0x24000000, 8, 45}, /* 1653 '-' */ - { 0x25000000, 8, 46}, /* 1654 '.' */ - { 0x58000000, 8, 108}, /* 1655 'l' */ - { 0x5a000000, 8, 120}, /* 1656 'x' */ - { 0x5b000000, 8, 58}, /* 1657 ':' */ - { 0x23800000, 9, 44}, /* 1658 ',' */ - { 0x59800000, 9, 109}, /* 1659 'm' */ - { 0x23000000, 10, 33}, /* 1660 '!' */ - { 0x23400000, 11, 122}, /* 1661 'z' */ - { 0x59200000, 11, 63}, /* 1662 '?' */ - { 0x59400000, 11, 104}, /* 1663 'h' */ - { 0x59600000, 11, 98}, /* 1664 'b' */ - { 0x23600000, 12, 66}, /* 1665 'B' */ - { 0x23700000, 12, 42}, /* 1666 '*' */ - { 0x59000000, 12, 119}, /* 1667 'w' */ - { 0x59180000, 13, 113}, /* 1668 'q' */ - { 0x59140000, 14, 112}, /* 1669 'p' */ - { 0x59100000, 15, 59}, /* 1670 ';' */ - { 0x59120000, 16, 47}, /* 1671 '/' */ - { 0x59130000, 16, 1}, /* 1672 '0x01' */ - /* 42 */ - { 0x00000000, 2, 114}, /* 1673 'r' */ - { 0xc0000000, 3, 110}, /* 1674 'n' */ - { 0x40000000, 4, 102}, /* 1675 'f' */ - { 0x50000000, 4, 32}, /* 1676 ' ' */ - { 0x60000000, 4, 119}, /* 1677 'w' */ - { 0x80000000, 4, 111}, /* 1678 'o' */ - { 0xb0000000, 4, 117}, /* 1679 'u' */ - { 0x78000000, 5, 116}, /* 1680 't' */ - { 0x90000000, 5, 99}, /* 1681 'c' */ - { 0xa0000000, 5, 112}, /* 1682 'p' */ - { 0xa8000000, 5, 100}, /* 1683 'd' */ - { 0xe0000000, 5, 109}, /* 1684 'm' */ - { 0xf0000000, 5, 108}, /* 1685 'l' */ - { 0x70000000, 6, 97}, /* 1686 'a' */ - { 0x74000000, 6, 98}, /* 1687 'b' */ - { 0x98000000, 6, 121}, /* 1688 'y' */ - { 0x9c000000, 6, 0}, /* 1689 '0x00' */ - { 0xe8000000, 6, 115}, /* 1690 's' */ - { 0xec000000, 6, 107}, /* 1691 'k' */ - { 0xfa000000, 7, 118}, /* 1692 'v' */ - { 0xfc000000, 7, 103}, /* 1693 'g' */ - { 0xff000000, 8, 105}, /* 1694 'i' */ - { 0xf8800000, 9, 104}, /* 1695 'h' */ - { 0xf9000000, 9, 33}, /* 1696 '!' */ - { 0xfe000000, 9, 101}, /* 1697 'e' */ - { 0xfe800000, 9, 106}, /* 1698 'j' */ - { 0xf9800000, 10, 39}, /* 1699 '\'' */ - { 0xf8200000, 11, 63}, /* 1700 '?' */ - { 0xf8400000, 11, 58}, /* 1701 ':' */ - { 0xf9c00000, 11, 122}, /* 1702 'z' */ - { 0xf9e00000, 11, 120}, /* 1703 'x' */ - { 0xf8000000, 12, 74}, /* 1704 'J' */ - { 0xf8600000, 12, 46}, /* 1705 '.' */ - { 0xf8700000, 12, 45}, /* 1706 '-' */ - { 0xf8100000, 14, 52}, /* 1707 '4' */ - { 0xf8180000, 14, 44}, /* 1708 ',' */ - { 0xf81c0000, 14, 71}, /* 1709 'G' */ - { 0xf8160000, 15, 41}, /* 1710 ')' */ - { 0xf8140000, 16, 83}, /* 1711 'S' */ - { 0xf8150000, 17, 68}, /* 1712 'D' */ - { 0xf8158000, 18, 1}, /* 1713 '0x01' */ - { 0xf815c000, 18, 113}, /* 1714 'q' */ - /* 28 */ - { 0x00000000, 2, 101}, /* 1715 'e' */ - { 0x40000000, 3, 0}, /* 1716 '0x00' */ - { 0x80000000, 3, 105}, /* 1717 'i' */ - { 0xc0000000, 3, 111}, /* 1718 'o' */ - { 0x60000000, 4, 115}, /* 1719 's' */ - { 0xa0000000, 4, 32}, /* 1720 ' ' */ - { 0xe0000000, 4, 112}, /* 1721 'p' */ - { 0x70000000, 5, 108}, /* 1722 'l' */ - { 0x78000000, 5, 114}, /* 1723 'r' */ - { 0xb0000000, 5, 104}, /* 1724 'h' */ - { 0xf0000000, 5, 97}, /* 1725 'a' */ - { 0xb8000000, 6, 116}, /* 1726 't' */ - { 0xbc000000, 6, 39}, /* 1727 '\'' */ - { 0xf8000000, 7, 100}, /* 1728 'd' */ - { 0xfa000000, 7, 109}, /* 1729 'm' */ - { 0xfc000000, 7, 121}, /* 1730 'y' */ - { 0xfe800000, 9, 58}, /* 1731 ':' */ - { 0xff800000, 9, 33}, /* 1732 '!' */ - { 0xff000000, 10, 119}, /* 1733 'w' */ - { 0xff400000, 10, 117}, /* 1734 'u' */ - { 0xfe000000, 11, 98}, /* 1735 'b' */ - { 0xfe400000, 11, 45}, /* 1736 '-' */ - { 0xfe600000, 11, 46}, /* 1737 '.' */ - { 0xfe300000, 12, 110}, /* 1738 'n' */ - { 0xfe280000, 13, 107}, /* 1739 'k' */ - { 0xfe240000, 14, 44}, /* 1740 ',' */ - { 0xfe200000, 15, 1}, /* 1741 '0x01' */ - { 0xfe220000, 15, 99}, /* 1742 'c' */ - /* 5 */ - { 0x80000000, 1, 117}, /* 1743 'u' */ - { 0x40000000, 2, 0}, /* 1744 '0x00' */ - { 0x20000000, 3, 58}, /* 1745 ':' */ - { 0x00000000, 4, 1}, /* 1746 '0x01' */ - { 0x10000000, 4, 39}, /* 1747 '\'' */ - /* 40 */ - { 0x00000000, 3, 32}, /* 1748 ' ' */ - { 0x60000000, 3, 105}, /* 1749 'i' */ - { 0xa0000000, 3, 101}, /* 1750 'e' */ - { 0x30000000, 4, 121}, /* 1751 'y' */ - { 0x40000000, 4, 100}, /* 1752 'd' */ - { 0x80000000, 4, 115}, /* 1753 's' */ - { 0x90000000, 4, 116}, /* 1754 't' */ - { 0xc0000000, 4, 97}, /* 1755 'a' */ - { 0xd0000000, 4, 0}, /* 1756 '0x00' */ - { 0xf0000000, 4, 111}, /* 1757 'o' */ - { 0x58000000, 5, 110}, /* 1758 'n' */ - { 0xe8000000, 5, 108}, /* 1759 'l' */ - { 0x24000000, 6, 107}, /* 1760 'k' */ - { 0x28000000, 6, 114}, /* 1761 'r' */ - { 0x2c000000, 6, 109}, /* 1762 'm' */ - { 0x54000000, 6, 117}, /* 1763 'u' */ - { 0xe4000000, 6, 103}, /* 1764 'g' */ - { 0x20000000, 7, 39}, /* 1765 '\'' */ - { 0x52000000, 7, 99}, /* 1766 'c' */ - { 0xe2000000, 7, 58}, /* 1767 ':' */ - { 0x22000000, 8, 102}, /* 1768 'f' */ - { 0x23000000, 8, 46}, /* 1769 '.' */ - { 0x51000000, 8, 98}, /* 1770 'b' */ - { 0xe0000000, 8, 118}, /* 1771 'v' */ - { 0x50000000, 9, 44}, /* 1772 ',' */ - { 0x50800000, 9, 112}, /* 1773 'p' */ - { 0xe1000000, 9, 119}, /* 1774 'w' */ - { 0xe1c00000, 10, 106}, /* 1775 'j' */ - { 0xe1800000, 11, 45}, /* 1776 '-' */ - { 0xe1a00000, 12, 104}, /* 1777 'h' */ - { 0xe1b00000, 13, 71}, /* 1778 'G' */ - { 0xe1b80000, 14, 113}, /* 1779 'q' */ - { 0xe1be0000, 15, 83}, /* 1780 'S' */ - { 0xe1bc0000, 16, 33}, /* 1781 '!' */ - { 0xe1bd0000, 18, 42}, /* 1782 '*' */ - { 0xe1bd8000, 18, 84}, /* 1783 'T' */ - { 0xe1bd4000, 19, 1}, /* 1784 '0x01' */ - { 0xe1bd6000, 19, 69}, /* 1785 'E' */ - { 0xe1bdc000, 19, 49}, /* 1786 '1' */ - { 0xe1bde000, 19, 47}, /* 1787 '/' */ - /* 37 */ - { 0x80000000, 2, 32}, /* 1788 ' ' */ - { 0xc0000000, 2, 0}, /* 1789 '0x00' */ - { 0x60000000, 3, 116}, /* 1790 't' */ - { 0x00000000, 4, 115}, /* 1791 's' */ - { 0x20000000, 4, 105}, /* 1792 'i' */ - { 0x30000000, 4, 104}, /* 1793 'h' */ - { 0x18000000, 5, 59}, /* 1794 ';' */ - { 0x50000000, 5, 101}, /* 1795 'e' */ - { 0x44000000, 6, 111}, /* 1796 'o' */ - { 0x4c000000, 6, 99}, /* 1797 'c' */ - { 0x58000000, 6, 58}, /* 1798 ':' */ - { 0x10000000, 7, 46}, /* 1799 '.' */ - { 0x12000000, 7, 33}, /* 1800 '!' */ - { 0x16000000, 7, 121}, /* 1801 'y' */ - { 0x40000000, 7, 112}, /* 1802 'p' */ - { 0x48000000, 7, 97}, /* 1803 'a' */ - { 0x5e000000, 7, 117}, /* 1804 'u' */ - { 0x14000000, 8, 44}, /* 1805 ',' */ - { 0x15000000, 8, 102}, /* 1806 'f' */ - { 0x43000000, 8, 39}, /* 1807 '\'' */ - { 0x4b000000, 8, 110}, /* 1808 'n' */ - { 0x5c000000, 8, 108}, /* 1809 'l' */ - { 0x5d000000, 8, 114}, /* 1810 'r' */ - { 0x42800000, 9, 107}, /* 1811 'k' */ - { 0x4a000000, 9, 100}, /* 1812 'd' */ - { 0x42400000, 10, 109}, /* 1813 'm' */ - { 0x4ac00000, 10, 98}, /* 1814 'b' */ - { 0x42000000, 11, 63}, /* 1815 '?' */ - { 0x42200000, 11, 119}, /* 1816 'w' */ - { 0x4a800000, 11, 103}, /* 1817 'g' */ - { 0x4aa00000, 12, 113}, /* 1818 'q' */ - { 0x4ab40000, 14, 69}, /* 1819 'E' */ - { 0x4ab80000, 14, 45}, /* 1820 '-' */ - { 0x4ab00000, 15, 1}, /* 1821 '0x01' */ - { 0x4ab20000, 15, 41}, /* 1822 ')' */ - { 0x4abc0000, 15, 87}, /* 1823 'W' */ - { 0x4abe0000, 15, 49}, /* 1824 '1' */ - /* 39 */ - { 0x00000000, 3, 105}, /* 1825 'i' */ - { 0x60000000, 3, 0}, /* 1826 '0x00' */ - { 0x80000000, 3, 32}, /* 1827 ' ' */ - { 0xe0000000, 3, 104}, /* 1828 'h' */ - { 0x20000000, 4, 97}, /* 1829 'a' */ - { 0x40000000, 4, 114}, /* 1830 'r' */ - { 0xa0000000, 4, 115}, /* 1831 's' */ - { 0xb0000000, 4, 111}, /* 1832 'o' */ - { 0xd0000000, 4, 101}, /* 1833 'e' */ - { 0x38000000, 5, 116}, /* 1834 't' */ - { 0x50000000, 5, 121}, /* 1835 'y' */ - { 0xc0000000, 5, 117}, /* 1836 'u' */ - { 0x58000000, 6, 109}, /* 1837 'm' */ - { 0xc8000000, 6, 99}, /* 1838 'c' */ - { 0xcc000000, 6, 108}, /* 1839 'l' */ - { 0x30000000, 7, 39}, /* 1840 '\'' */ - { 0x34000000, 7, 58}, /* 1841 ':' */ - { 0x32000000, 8, 119}, /* 1842 'w' */ - { 0x36000000, 8, 33}, /* 1843 '!' */ - { 0x5c000000, 8, 46}, /* 1844 '.' */ - { 0x5d000000, 8, 98}, /* 1845 'b' */ - { 0x5e000000, 8, 69}, /* 1846 'E' */ - { 0x5f000000, 8, 102}, /* 1847 'f' */ - { 0x33000000, 9, 63}, /* 1848 '?' */ - { 0x37000000, 9, 110}, /* 1849 'n' */ - { 0x33800000, 10, 122}, /* 1850 'z' */ - { 0x37800000, 10, 100}, /* 1851 'd' */ - { 0x33e00000, 11, 44}, /* 1852 ',' */ - { 0x37c00000, 11, 80}, /* 1853 'P' */ - { 0x33c00000, 12, 118}, /* 1854 'v' */ - { 0x33d00000, 12, 45}, /* 1855 '-' */ - { 0x37e00000, 12, 41}, /* 1856 ')' */ - { 0x37f00000, 13, 103}, /* 1857 'g' */ - { 0x37f80000, 14, 1}, /* 1858 '0x01' */ - { 0x37fc0000, 15, 83}, /* 1859 'S' */ - { 0x37ff0000, 16, 52}, /* 1860 '4' */ - { 0x37fe0000, 17, 107}, /* 1861 'k' */ - { 0x37fe8000, 18, 106}, /* 1862 'j' */ - { 0x37fec000, 18, 112}, /* 1863 'p' */ - /* 34 */ - { 0x00000000, 2, 114}, /* 1864 'r' */ - { 0x80000000, 3, 115}, /* 1865 's' */ - { 0xe0000000, 3, 110}, /* 1866 'n' */ - { 0x40000000, 4, 101}, /* 1867 'e' */ - { 0x50000000, 4, 109}, /* 1868 'm' */ - { 0xc0000000, 4, 116}, /* 1869 't' */ - { 0x60000000, 5, 99}, /* 1870 'c' */ - { 0x68000000, 5, 103}, /* 1871 'g' */ - { 0x70000000, 5, 98}, /* 1872 'b' */ - { 0xa0000000, 5, 112}, /* 1873 'p' */ - { 0xa8000000, 5, 105}, /* 1874 'i' */ - { 0xb0000000, 5, 108}, /* 1875 'l' */ - { 0xd0000000, 5, 100}, /* 1876 'd' */ - { 0xd8000000, 5, 97}, /* 1877 'a' */ - { 0x78000000, 6, 0}, /* 1878 '0x00' */ - { 0xb8000000, 6, 121}, /* 1879 'y' */ - { 0x7c000000, 7, 122}, /* 1880 'z' */ - { 0xbc000000, 7, 32}, /* 1881 ' ' */ - { 0x7f000000, 8, 39}, /* 1882 '\'' */ - { 0xbe000000, 8, 45}, /* 1883 '-' */ - { 0x7e000000, 9, 107}, /* 1884 'k' */ - { 0xbf800000, 9, 58}, /* 1885 ':' */ - { 0x7e800000, 10, 102}, /* 1886 'f' */ - { 0x7ec00000, 10, 44}, /* 1887 ',' */ - { 0xbf000000, 10, 119}, /* 1888 'w' */ - { 0xbf400000, 12, 118}, /* 1889 'v' */ - { 0xbf500000, 12, 120}, /* 1890 'x' */ - { 0xbf700000, 12, 111}, /* 1891 'o' */ - { 0xbf600000, 13, 106}, /* 1892 'j' */ - { 0xbf680000, 14, 117}, /* 1893 'u' */ - { 0xbf6c0000, 15, 46}, /* 1894 '.' */ - { 0xbf6f0000, 16, 104}, /* 1895 'h' */ - { 0xbf6e0000, 17, 63}, /* 1896 '?' */ - { 0xbf6e8000, 17, 1}, /* 1897 '0x01' */ - /* 11 */ - { 0x80000000, 1, 101}, /* 1898 'e' */ - { 0x40000000, 2, 105}, /* 1899 'i' */ - { 0x20000000, 3, 97}, /* 1900 'a' */ - { 0x10000000, 4, 111}, /* 1901 'o' */ - { 0x00000000, 5, 32}, /* 1902 ' ' */ - { 0x0c000000, 6, 0}, /* 1903 '0x00' */ - { 0x08000000, 7, 121}, /* 1904 'y' */ - { 0x0b000000, 8, 115}, /* 1905 's' */ - { 0x0a800000, 9, 114}, /* 1906 'r' */ - { 0x0a000000, 10, 1}, /* 1907 '0x01' */ - { 0x0a400000, 10, 46}, /* 1908 '.' */ - /* 31 */ - { 0x00000000, 1, 115}, /* 1909 's' */ - { 0x80000000, 3, 32}, /* 1910 ' ' */ - { 0xc0000000, 3, 0}, /* 1911 '0x00' */ - { 0xb0000000, 4, 105}, /* 1912 'i' */ - { 0xe0000000, 4, 111}, /* 1913 'o' */ - { 0xa0000000, 5, 97}, /* 1914 'a' */ - { 0xf0000000, 5, 110}, /* 1915 'n' */ - { 0xf8000000, 5, 101}, /* 1916 'e' */ - { 0xae000000, 7, 121}, /* 1917 'y' */ - { 0xa8000000, 8, 109}, /* 1918 'm' */ - { 0xab000000, 8, 100}, /* 1919 'd' */ - { 0xad000000, 8, 108}, /* 1920 'l' */ - { 0xa9800000, 9, 98}, /* 1921 'b' */ - { 0xaa000000, 9, 107}, /* 1922 'k' */ - { 0xaa800000, 9, 114}, /* 1923 'r' */ - { 0xa9000000, 10, 106}, /* 1924 'j' */ - { 0xac400000, 10, 44}, /* 1925 ',' */ - { 0xacc00000, 10, 104}, /* 1926 'h' */ - { 0xa9600000, 11, 45}, /* 1927 '-' */ - { 0xac000000, 11, 99}, /* 1928 'c' */ - { 0xac200000, 11, 102}, /* 1929 'f' */ - { 0xaca00000, 11, 112}, /* 1930 'p' */ - { 0xa9400000, 12, 103}, /* 1931 'g' */ - { 0xac800000, 12, 116}, /* 1932 't' */ - { 0xa9500000, 13, 46}, /* 1933 '.' */ - { 0xa9580000, 13, 58}, /* 1934 ':' */ - { 0xac980000, 13, 113}, /* 1935 'q' */ - { 0xac940000, 14, 39}, /* 1936 '\'' */ - { 0xac920000, 15, 63}, /* 1937 '?' */ - { 0xac900000, 16, 1}, /* 1938 '0x01' */ - { 0xac910000, 16, 66}, /* 1939 'B' */ - /* 20 */ - { 0x00000000, 2, 112}, /* 1940 'p' */ - { 0x80000000, 2, 32}, /* 1941 ' ' */ - { 0xc0000000, 2, 116}, /* 1942 't' */ - { 0x60000000, 4, 0}, /* 1943 '0x00' */ - { 0x40000000, 5, 111}, /* 1944 'o' */ - { 0x50000000, 5, 99}, /* 1945 'c' */ - { 0x70000000, 5, 105}, /* 1946 'i' */ - { 0x78000000, 5, 109}, /* 1947 'm' */ - { 0x48000000, 6, 101}, /* 1948 'e' */ - { 0x58000000, 6, 121}, /* 1949 'y' */ - { 0x4c000000, 7, 117}, /* 1950 'u' */ - { 0x4e000000, 7, 102}, /* 1951 'f' */ - { 0x5e000000, 7, 44}, /* 1952 ',' */ - { 0x5c000000, 9, 103}, /* 1953 'g' */ - { 0x5c800000, 9, 97}, /* 1954 'a' */ - { 0x5d800000, 9, 57}, /* 1955 '9' */ - { 0x5d400000, 10, 39}, /* 1956 '\'' */ - { 0x5d200000, 11, 120}, /* 1957 'x' */ - { 0x5d000000, 12, 1}, /* 1958 '0x01' */ - { 0x5d100000, 12, 115}, /* 1959 's' */ - /* 36 */ - { 0x00000000, 1, 32}, /* 1960 ' ' */ - { 0xc0000000, 2, 0}, /* 1961 '0x00' */ - { 0x88000000, 5, 111}, /* 1962 'o' */ - { 0x90000000, 5, 115}, /* 1963 's' */ - { 0xa0000000, 5, 97}, /* 1964 'a' */ - { 0xb0000000, 5, 108}, /* 1965 'l' */ - { 0xb8000000, 5, 58}, /* 1966 ':' */ - { 0x98000000, 6, 100}, /* 1967 'd' */ - { 0x82000000, 7, 110}, /* 1968 'n' */ - { 0x84000000, 7, 116}, /* 1969 't' */ - { 0xa8000000, 7, 39}, /* 1970 '\'' */ - { 0xaa000000, 7, 98}, /* 1971 'b' */ - { 0xae000000, 7, 46}, /* 1972 '.' */ - { 0x80000000, 8, 105}, /* 1973 'i' */ - { 0x86000000, 8, 44}, /* 1974 ',' */ - { 0x87000000, 8, 112}, /* 1975 'p' */ - { 0x9c000000, 8, 109}, /* 1976 'm' */ - { 0x9e000000, 8, 99}, /* 1977 'c' */ - { 0xac000000, 8, 119}, /* 1978 'w' */ - { 0xad000000, 8, 101}, /* 1979 'e' */ - { 0x81000000, 9, 63}, /* 1980 '?' */ - { 0x81800000, 9, 102}, /* 1981 'f' */ - { 0x9d000000, 9, 114}, /* 1982 'r' */ - { 0x9d800000, 9, 103}, /* 1983 'g' */ - { 0x9f000000, 10, 122}, /* 1984 'z' */ - { 0x9f800000, 10, 45}, /* 1985 '-' */ - { 0x9fc00000, 10, 84}, /* 1986 'T' */ - { 0x9f400000, 12, 50}, /* 1987 '2' */ - { 0x9f600000, 12, 33}, /* 1988 '!' */ - { 0x9f700000, 12, 107}, /* 1989 'k' */ - { 0x9f500000, 13, 118}, /* 1990 'v' */ - { 0x9f580000, 14, 121}, /* 1991 'y' */ - { 0x9f5c0000, 15, 104}, /* 1992 'h' */ - { 0x9f5f0000, 16, 106}, /* 1993 'j' */ - { 0x9f5e0000, 17, 1}, /* 1994 '0x01' */ - { 0x9f5e8000, 17, 41}, /* 1995 ')' */ - /* 21 */ - { 0x00000000, 2, 122}, /* 1996 'z' */ - { 0x40000000, 2, 0}, /* 1997 '0x00' */ - { 0xa0000000, 3, 105}, /* 1998 'i' */ - { 0x80000000, 4, 121}, /* 1999 'y' */ - { 0x90000000, 4, 101}, /* 2000 'e' */ - { 0xc0000000, 4, 119}, /* 2001 'w' */ - { 0xd0000000, 4, 32}, /* 2002 ' ' */ - { 0xe0000000, 4, 108}, /* 2003 'l' */ - { 0xf0000000, 5, 97}, /* 2004 'a' */ - { 0xf8000000, 6, 111}, /* 2005 'o' */ - { 0xfc000000, 8, 109}, /* 2006 'm' */ - { 0xfd000000, 8, 58}, /* 2007 ':' */ - { 0xff000000, 8, 99}, /* 2008 'c' */ - { 0xfe000000, 9, 44}, /* 2009 ',' */ - { 0xfec00000, 10, 98}, /* 2010 'b' */ - { 0xfe800000, 11, 117}, /* 2011 'u' */ - { 0xfeb00000, 12, 33}, /* 2012 '!' */ - { 0xfea00000, 14, 1}, /* 2013 '0x01' */ - { 0xfea40000, 14, 116}, /* 2014 't' */ - { 0xfea80000, 14, 104}, /* 2015 'h' */ - { 0xfeac0000, 14, 63}, /* 2016 '?' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 2017 '0x01' */ - { 0x80000000, 1, 1}, /* 2018 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 2019 '0x01' */ - { 0x80000000, 1, 1}, /* 2020 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 2021 '0x01' */ - { 0x80000000, 1, 1}, /* 2022 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 2023 '0x01' */ - { 0x80000000, 1, 1}, /* 2024 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 2025 '0x01' */ - { 0x80000000, 1, 1} /* 2026 '0x01' */ + /* 51 */ + {0x00000000, 2, 84}, /* 0 'T' */ + {0x40000000, 3, 66}, /* 1 'B' */ + {0x80000000, 4, 67}, /* 2 'C' */ + {0x90000000, 4, 73}, /* 3 'I' */ + {0xd0000000, 4, 83}, /* 4 'S' */ + {0x60000000, 5, 76}, /* 5 'L' */ + {0x70000000, 5, 68}, /* 6 'D' */ + {0x78000000, 5, 72}, /* 7 'H' */ + {0xa0000000, 5, 82}, /* 8 'R' */ + {0xa8000000, 5, 78}, /* 9 'N' */ + {0xb0000000, 5, 69}, /* 10 'E' */ + {0xc0000000, 5, 70}, /* 11 'F' */ + {0xc8000000, 5, 65}, /* 12 'A' */ + {0xe0000000, 5, 77}, /* 13 'M' */ + {0xe8000000, 5, 80}, /* 14 'P' */ + {0xf0000000, 5, 87}, /* 15 'W' */ + {0x6c000000, 6, 81}, /* 16 'Q' */ + {0xbc000000, 6, 71}, /* 17 'G' */ + {0xf8000000, 6, 74}, /* 18 'J' */ + {0x68000000, 7, 75}, /* 19 'K' */ + {0xba000000, 7, 85}, /* 20 'U' */ + {0xfc000000, 7, 79}, /* 21 'O' */ + {0x6a000000, 8, 54}, /* 22 '6' */ + {0x6b000000, 8, 46}, /* 23 '.' */ + {0xb8000000, 8, 86}, /* 24 'V' */ + {0xfe000000, 8, 89}, /* 25 'Y' */ + {0xb9800000, 9, 50}, /* 26 '2' */ + {0xff800000, 9, 88}, /* 27 'X' */ + {0xb9000000, 10, 90}, /* 28 'Z' */ + {0xff000000, 10, 56}, /* 29 '8' */ + {0xb9400000, 11, 49}, /* 30 '1' */ + {0xb9600000, 11, 51}, /* 31 '3' */ + {0xff400000, 12, 52}, /* 32 '4' */ + {0xff500000, 12, 39}, /* 33 '\'' */ + {0xff700000, 12, 32}, /* 34 ' ' */ + {0xff600000, 14, 53}, /* 35 '5' */ + {0xff6c0000, 14, 48}, /* 36 '0' */ + {0xff660000, 15, 109}, /* 37 'm' */ + {0xff640000, 16, 99}, /* 38 'c' */ + {0xff680000, 16, 57}, /* 39 '9' */ + {0xff6a0000, 16, 97}, /* 40 'a' */ + {0xff6b0000, 16, 100}, /* 41 'd' */ + {0xff650000, 17, 115}, /* 42 's' */ + {0xff658000, 17, 112}, /* 43 'p' */ + {0xff690000, 17, 40}, /* 44 '(' */ + {0xff698000, 18, 116}, /* 45 't' */ + {0xff69c000, 19, 55}, /* 46 '7' */ + {0xff69e000, 20, 1}, /* 47 '0x01' */ + {0xff69f000, 20, 108}, /* 48 'l' */ + {0x00000000, 1, 1}, /* 49 '0x01' */ + {0x80000000, 1, 1}, /* 50 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 51 '0x01' */ + {0x80000000, 1, 1}, /* 52 '0x01' */ + /* 0 */ + /* 2 */ + {0x00000000, 1, 1}, /* 53 '0x01' */ + {0x80000000, 1, 1}, /* 54 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 55 '0x01' */ + {0x80000000, 1, 1}, /* 56 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 57 '0x01' */ + {0x80000000, 1, 1}, /* 58 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 59 '0x01' */ + {0x80000000, 1, 1}, /* 60 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 61 '0x01' */ + {0x80000000, 1, 1}, /* 62 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 63 '0x01' */ + {0x80000000, 1, 1}, /* 64 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 65 '0x01' */ + {0x80000000, 1, 1}, /* 66 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 67 '0x01' */ + {0x80000000, 1, 1}, /* 68 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 69 '0x01' */ + {0x80000000, 1, 1}, /* 70 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 71 '0x01' */ + {0x80000000, 1, 1}, /* 72 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 73 '0x01' */ + {0x80000000, 1, 1}, /* 74 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 75 '0x01' */ + {0x80000000, 1, 1}, /* 76 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 77 '0x01' */ + {0x80000000, 1, 1}, /* 78 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 79 '0x01' */ + {0x80000000, 1, 1}, /* 80 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 81 '0x01' */ + {0x80000000, 1, 1}, /* 82 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 83 '0x01' */ + {0x80000000, 1, 1}, /* 84 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 85 '0x01' */ + {0x80000000, 1, 1}, /* 86 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 87 '0x01' */ + {0x80000000, 1, 1}, /* 88 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 89 '0x01' */ + {0x80000000, 1, 1}, /* 90 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 91 '0x01' */ + {0x80000000, 1, 1}, /* 92 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 93 '0x01' */ + {0x80000000, 1, 1}, /* 94 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 95 '0x01' */ + {0x80000000, 1, 1}, /* 96 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 97 '0x01' */ + {0x80000000, 1, 1}, /* 98 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 99 '0x01' */ + {0x80000000, 1, 1}, /* 100 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 101 '0x01' */ + {0x80000000, 1, 1}, /* 102 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 103 '0x01' */ + {0x80000000, 1, 1}, /* 104 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 105 '0x01' */ + {0x80000000, 1, 1}, /* 106 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 107 '0x01' */ + {0x80000000, 1, 1}, /* 108 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 109 '0x01' */ + {0x80000000, 1, 1}, /* 110 '0x01' */ + /* 70 */ + {0x00000000, 4, 87}, /* 111 'W' */ + {0x30000000, 4, 77}, /* 112 'M' */ + {0x40000000, 4, 67}, /* 113 'C' */ + {0x50000000, 4, 66}, /* 114 'B' */ + {0x70000000, 4, 80}, /* 115 'P' */ + {0x90000000, 4, 84}, /* 116 'T' */ + {0xc0000000, 4, 78}, /* 117 'N' */ + {0xf0000000, 4, 83}, /* 118 'S' */ + {0x18000000, 5, 73}, /* 119 'I' */ + {0x20000000, 5, 71}, /* 120 'G' */ + {0x60000000, 5, 72}, /* 121 'H' */ + {0x68000000, 5, 68}, /* 122 'D' */ + {0x80000000, 5, 111}, /* 123 'o' */ + {0x88000000, 5, 65}, /* 124 'A' */ + {0xa0000000, 5, 116}, /* 125 't' */ + {0xb0000000, 5, 97}, /* 126 'a' */ + {0xb8000000, 5, 70}, /* 127 'F' */ + {0xd0000000, 5, 76}, /* 128 'L' */ + {0xd8000000, 5, 82}, /* 129 'R' */ + {0x2c000000, 6, 85}, /* 130 'U' */ + {0xac000000, 6, 79}, /* 131 'O' */ + {0xe4000000, 6, 74}, /* 132 'J' */ + {0xe8000000, 6, 69}, /* 133 'E' */ + {0x10000000, 7, 102}, /* 134 'f' */ + {0x12000000, 7, 81}, /* 135 'Q' */ + {0x16000000, 7, 86}, /* 136 'V' */ + {0x28000000, 7, 0}, /* 137 '0x00' */ + {0x2a000000, 7, 119}, /* 138 'w' */ + {0xe0000000, 7, 50}, /* 139 '2' */ + {0xe2000000, 7, 75}, /* 140 'K' */ + {0xec000000, 7, 89}, /* 141 'Y' */ + {0xee000000, 7, 105}, /* 142 'i' */ + {0x14000000, 8, 45}, /* 143 '-' */ + {0xa9000000, 8, 49}, /* 144 '1' */ + {0xa8000000, 9, 38}, /* 145 '&' */ + {0xaa800000, 9, 88}, /* 146 'X' */ + {0x15400000, 10, 114}, /* 147 'r' */ + {0xa8800000, 10, 53}, /* 148 '5' */ + {0xa8c00000, 10, 90}, /* 149 'Z' */ + {0xaa400000, 10, 57}, /* 150 '9' */ + {0xab400000, 10, 115}, /* 151 's' */ + {0xab800000, 10, 52}, /* 152 '4' */ + {0xabc00000, 10, 51}, /* 153 '3' */ + {0x15000000, 11, 55}, /* 154 '7' */ + {0x15800000, 11, 98}, /* 155 'b' */ + {0x15c00000, 11, 121}, /* 156 'y' */ + {0xaa000000, 11, 39}, /* 157 '\'' */ + {0xab000000, 11, 54}, /* 158 '6' */ + {0x15a00000, 12, 118}, /* 159 'v' */ + {0x15b00000, 12, 100}, /* 160 'd' */ + {0x15e00000, 12, 40}, /* 161 '(' */ + {0xaa200000, 12, 32}, /* 162 ' ' */ + {0xaa300000, 12, 48}, /* 163 '0' */ + {0xab200000, 12, 110}, /* 164 'n' */ + {0xab300000, 12, 56}, /* 165 '8' */ + {0x15300000, 13, 103}, /* 166 'g' */ + {0x15f00000, 13, 117}, /* 167 'u' */ + {0x15200000, 14, 43}, /* 168 '+' */ + {0x15240000, 14, 46}, /* 169 '.' */ + {0x15280000, 14, 1}, /* 170 '0x01' */ + {0x152c0000, 14, 108}, /* 171 'l' */ + {0x153c0000, 14, 109}, /* 172 'm' */ + {0x15f80000, 14, 112}, /* 173 'p' */ + {0x15380000, 15, 92}, /* 174 '\\' */ + {0x153a0000, 15, 47}, /* 175 '/' */ + {0x15fe0000, 15, 101}, /* 176 'e' */ + {0x15fd0000, 16, 34}, /* 177 '\"' */ + {0x15fc8000, 17, 99}, /* 178 'c' */ + {0x15fc0000, 18, 107}, /* 179 'k' */ + {0x15fc4000, 18, 104}, /* 180 'h' */ + /* 7 */ + {0x80000000, 1, 0}, /* 181 '0x00' */ + {0x40000000, 2, 32}, /* 182 ' ' */ + {0x20000000, 3, 46}, /* 183 '.' */ + {0x10000000, 4, 33}, /* 184 '!' */ + {0x08000000, 5, 34}, /* 185 '\"' */ + {0x00000000, 6, 1}, /* 186 '0x01' */ + {0x04000000, 6, 58}, /* 187 ':' */ + /* 3 */ + {0x00000000, 1, 32}, /* 188 ' ' */ + {0x80000000, 2, 1}, /* 189 '0x01' */ + {0xc0000000, 2, 73}, /* 190 'I' */ + /* 2 */ + {0x00000000, 1, 1}, /* 191 '0x01' */ + {0x80000000, 1, 1}, /* 192 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 193 '0x01' */ + {0x80000000, 1, 1}, /* 194 '0x01' */ + /* 3 */ + {0x80000000, 1, 32}, /* 195 ' ' */ + {0x00000000, 2, 1}, /* 196 '0x01' */ + {0x40000000, 2, 0}, /* 197 '0x00' */ + /* 4 */ + {0x80000000, 1, 32}, /* 198 ' ' */ + {0x40000000, 2, 66}, /* 199 'B' */ + {0x00000000, 3, 1}, /* 200 '0x01' */ + {0x20000000, 3, 46}, /* 201 '.' */ + /* 32 */ + {0x80000000, 1, 115}, /* 202 's' */ + {0x00000000, 3, 109}, /* 203 'm' */ + {0x40000000, 3, 67}, /* 204 'C' */ + {0x20000000, 4, 116}, /* 205 't' */ + {0x30000000, 4, 32}, /* 206 ' ' */ + {0x60000000, 5, 100}, /* 207 'd' */ + {0x70000000, 5, 118}, /* 208 'v' */ + {0x6c000000, 6, 114}, /* 209 'r' */ + {0x7c000000, 6, 65}, /* 210 'A' */ + {0x6a000000, 7, 110}, /* 211 'n' */ + {0x68000000, 8, 71}, /* 212 'G' */ + {0x79000000, 8, 108}, /* 213 'l' */ + {0x69800000, 9, 68}, /* 214 'D' */ + {0x78000000, 9, 66}, /* 215 'B' */ + {0x78800000, 9, 101}, /* 216 'e' */ + {0x7a800000, 9, 105}, /* 217 'i' */ + {0x7b000000, 9, 54}, /* 218 '6' */ + {0x69000000, 10, 76}, /* 219 'L' */ + {0x7a400000, 10, 0}, /* 220 '0x00' */ + {0x7bc00000, 10, 119}, /* 221 'w' */ + {0x69400000, 11, 79}, /* 222 'O' */ + {0x7a000000, 11, 83}, /* 223 'S' */ + {0x7a200000, 11, 69}, /* 224 'E' */ + {0x7ba00000, 11, 78}, /* 225 'N' */ + {0x7b900000, 12, 82}, /* 226 'R' */ + {0x69600000, 13, 97}, /* 227 'a' */ + {0x69680000, 13, 77}, /* 228 'M' */ + {0x69700000, 13, 75}, /* 229 'K' */ + {0x69780000, 13, 70}, /* 230 'F' */ + {0x7b800000, 13, 48}, /* 231 '0' */ + {0x7b880000, 14, 1}, /* 232 '0x01' */ + {0x7b8c0000, 14, 99}, /* 233 'c' */ + /* 12 */ + {0x80000000, 1, 99}, /* 234 'c' */ + {0x00000000, 3, 49}, /* 235 '1' */ + {0x20000000, 4, 77}, /* 236 'M' */ + {0x30000000, 4, 85}, /* 237 'U' */ + {0x40000000, 4, 82}, /* 238 'R' */ + {0x50000000, 4, 68}, /* 239 'D' */ + {0x60000000, 4, 72}, /* 240 'H' */ + {0x70000000, 5, 83}, /* 241 'S' */ + {0x78000000, 6, 70}, /* 242 'F' */ + {0x7c000000, 7, 71}, /* 243 'G' */ + {0x7e000000, 8, 1}, /* 244 '0x01' */ + {0x7f000000, 8, 89}, /* 245 'Y' */ + /* 3 */ + {0x80000000, 1, 0}, /* 246 '0x00' */ + {0x00000000, 2, 1}, /* 247 '0x01' */ + {0x40000000, 2, 32}, /* 248 ' ' */ + /* 11 */ + {0x00000000, 1, 42}, /* 249 '*' */ + {0xa0000000, 3, 32}, /* 250 ' ' */ + {0x80000000, 4, 100}, /* 251 'd' */ + {0xc0000000, 4, 109}, /* 252 'm' */ + {0xd0000000, 4, 116}, /* 253 't' */ + {0xf0000000, 4, 115}, /* 254 's' */ + {0x90000000, 5, 101}, /* 255 'e' */ + {0xe0000000, 5, 103}, /* 256 'g' */ + {0xe8000000, 5, 107}, /* 257 'k' */ + {0x98000000, 6, 1}, /* 258 '0x01' */ + {0x9c000000, 6, 121}, /* 259 'y' */ + /* 2 */ + {0x00000000, 1, 1}, /* 260 '0x01' */ + {0x80000000, 1, 32}, /* 261 ' ' */ + /* 4 */ + {0x80000000, 1, 32}, /* 262 ' ' */ + {0x40000000, 2, 48}, /* 263 '0' */ + {0x00000000, 3, 1}, /* 264 '0x01' */ + {0x20000000, 3, 46}, /* 265 '.' */ + /* 37 */ + {0xc0000000, 2, 32}, /* 266 ' ' */ + {0x60000000, 3, 83}, /* 267 'S' */ + {0x80000000, 3, 71}, /* 268 'G' */ + {0xa0000000, 3, 79}, /* 269 'O' */ + {0x30000000, 4, 84}, /* 270 'T' */ + {0x40000000, 4, 85}, /* 271 'U' */ + {0x00000000, 5, 69}, /* 272 'E' */ + {0x10000000, 5, 68}, /* 273 'D' */ + {0x08000000, 6, 109}, /* 274 'm' */ + {0x18000000, 6, 48}, /* 275 '0' */ + {0x1c000000, 6, 73}, /* 276 'I' */ + {0x28000000, 6, 54}, /* 277 '6' */ + {0x50000000, 6, 70}, /* 278 'F' */ + {0x54000000, 6, 111}, /* 279 'o' */ + {0x0c000000, 7, 76}, /* 280 'L' */ + {0x0e000000, 7, 67}, /* 281 'C' */ + {0x22000000, 7, 65}, /* 282 'A' */ + {0x24000000, 7, 116}, /* 283 't' */ + {0x26000000, 7, 89}, /* 284 'Y' */ + {0x2e000000, 7, 50}, /* 285 '2' */ + {0x58000000, 7, 66}, /* 286 'B' */ + {0x5a000000, 7, 46}, /* 287 '.' */ + {0x20000000, 8, 80}, /* 288 'P' */ + {0x21000000, 8, 90}, /* 289 'Z' */ + {0x5c000000, 8, 56}, /* 290 '8' */ + {0x5d000000, 8, 105}, /* 291 'i' */ + {0x5e000000, 8, 100}, /* 292 'd' */ + {0x5f000000, 8, 72}, /* 293 'H' */ + {0x2c800000, 9, 78}, /* 294 'N' */ + {0x2d800000, 9, 82}, /* 295 'R' */ + {0x2c000000, 10, 49}, /* 296 '1' */ + {0x2c400000, 10, 87}, /* 297 'W' */ + {0x2d200000, 11, 99}, /* 298 'c' */ + {0x2d400000, 11, 97}, /* 299 'a' */ + {0x2d600000, 11, 77}, /* 300 'M' */ + {0x2d000000, 12, 1}, /* 301 '0x01' */ + {0x2d100000, 12, 81}, /* 302 'Q' */ + /* 25 */ + {0x80000000, 1, 46}, /* 303 '.' */ + {0x40000000, 2, 0}, /* 304 '0x00' */ + {0x20000000, 4, 32}, /* 305 ' ' */ + {0x00000000, 5, 73}, /* 306 'I' */ + {0x08000000, 5, 84}, /* 307 'T' */ + {0x10000000, 5, 67}, /* 308 'C' */ + {0x30000000, 5, 112}, /* 309 'p' */ + {0x38000000, 5, 48}, /* 310 '0' */ + {0x1c000000, 6, 72}, /* 311 'H' */ + {0x1a000000, 8, 87}, /* 312 'W' */ + {0x18800000, 9, 83}, /* 313 'S' */ + {0x1b000000, 9, 51}, /* 314 '3' */ + {0x1b800000, 9, 66}, /* 315 'B' */ + {0x18000000, 10, 49}, /* 316 '1' */ + {0x18400000, 10, 77}, /* 317 'M' */ + {0x19800000, 10, 99}, /* 318 'c' */ + {0x19000000, 11, 116}, /* 319 't' */ + {0x19200000, 11, 82}, /* 320 'R' */ + {0x19400000, 11, 70}, /* 321 'F' */ + {0x19c00000, 11, 69}, /* 322 'E' */ + {0x19e00000, 11, 65}, /* 323 'A' */ + {0x19600000, 13, 1}, /* 324 '0x01' */ + {0x19680000, 13, 108}, /* 325 'l' */ + {0x19700000, 13, 100}, /* 326 'd' */ + {0x19780000, 13, 85}, /* 327 'U' */ + /* 18 */ + {0x00000000, 2, 49}, /* 328 '1' */ + {0x80000000, 2, 55}, /* 329 '7' */ + {0x40000000, 3, 52}, /* 330 '4' */ + {0x60000000, 3, 50}, /* 331 '2' */ + {0xc0000000, 3, 51}, /* 332 '3' */ + {0xe0000000, 4, 53}, /* 333 '5' */ + {0xf0000000, 6, 54}, /* 334 '6' */ + {0xf8000000, 6, 67}, /* 335 'C' */ + {0xf4000000, 7, 57}, /* 336 '9' */ + {0xf6000000, 7, 32}, /* 337 ' ' */ + {0xfc000000, 7, 56}, /* 338 '8' */ + {0xff000000, 8, 85}, /* 339 'U' */ + {0xfe000000, 10, 71}, /* 340 'G' */ + {0xfe800000, 10, 48}, /* 341 '0' */ + {0xfe400000, 11, 1}, /* 342 '0x01' */ + {0xfe600000, 11, 87}, /* 343 'W' */ + {0xfec00000, 11, 86}, /* 344 'V' */ + {0xfee00000, 11, 83}, /* 345 'S' */ + /* 23 */ + {0x00000000, 2, 54}, /* 346 '6' */ + {0x40000000, 2, 32}, /* 347 ' ' */ + {0xc0000000, 2, 48}, /* 348 '0' */ + {0x90000000, 4, 112}, /* 349 'p' */ + {0xa0000000, 4, 0}, /* 350 '0x00' */ + {0x80000000, 5, 49}, /* 351 '1' */ + {0x88000000, 5, 97}, /* 352 'a' */ + {0xb8000000, 5, 55}, /* 353 '7' */ + {0xb0000000, 7, 45}, /* 354 '-' */ + {0xb4000000, 7, 115}, /* 355 's' */ + {0xb3000000, 8, 52}, /* 356 '4' */ + {0xb6000000, 8, 116}, /* 357 't' */ + {0xb7800000, 9, 37}, /* 358 '%' */ + {0xb2000000, 10, 56}, /* 359 '8' */ + {0xb2400000, 10, 58}, /* 360 ':' */ + {0xb2800000, 10, 53}, /* 361 '5' */ + {0xb2c00000, 10, 50}, /* 362 '2' */ + {0xb7000000, 10, 47}, /* 363 '/' */ + {0xb7600000, 11, 85}, /* 364 'U' */ + {0xb7500000, 12, 44}, /* 365 ',' */ + {0xb7400000, 13, 46}, /* 366 '.' */ + {0xb7480000, 14, 1}, /* 367 '0x01' */ + {0xb74c0000, 14, 108}, /* 368 'l' */ + /* 22 */ + {0x40000000, 2, 0}, /* 369 '0x00' */ + {0x00000000, 3, 46}, /* 370 '.' */ + {0xa0000000, 3, 48}, /* 371 '0' */ + {0xe0000000, 3, 49}, /* 372 '1' */ + {0x20000000, 4, 50}, /* 373 '2' */ + {0x30000000, 4, 32}, /* 374 ' ' */ + {0xd0000000, 4, 47}, /* 375 '/' */ + {0x90000000, 5, 56}, /* 376 '8' */ + {0xc0000000, 5, 51}, /* 377 '3' */ + {0x80000000, 6, 53}, /* 378 '5' */ + {0x84000000, 6, 115}, /* 379 's' */ + {0x88000000, 6, 54}, /* 380 '6' */ + {0x8c000000, 6, 58}, /* 381 ':' */ + {0x98000000, 6, 39}, /* 382 '\'' */ + {0xc8000000, 6, 88}, /* 383 'X' */ + {0xcc000000, 6, 57}, /* 384 '9' */ + {0x9e000000, 7, 52}, /* 385 '4' */ + {0x9d000000, 8, 45}, /* 386 '-' */ + {0x9c800000, 9, 55}, /* 387 '7' */ + {0x9c000000, 10, 41}, /* 388 ')' */ + {0x9c400000, 11, 1}, /* 389 '0x01' */ + {0x9c600000, 11, 44}, /* 390 ',' */ + /* 18 */ + {0x00000000, 1, 48}, /* 391 '0' */ + {0xc0000000, 2, 52}, /* 392 '4' */ + {0xa0000000, 3, 0}, /* 393 '0x00' */ + {0x90000000, 4, 32}, /* 394 ' ' */ + {0x80000000, 5, 58}, /* 395 ':' */ + {0x8a000000, 7, 53}, /* 396 '5' */ + {0x8e000000, 7, 47}, /* 397 '/' */ + {0x88000000, 8, 46}, /* 398 '.' */ + {0x89000000, 8, 49}, /* 399 '1' */ + {0x8c000000, 8, 87}, /* 400 'W' */ + {0x8d800000, 9, 55}, /* 401 '7' */ + {0x8d200000, 11, 51}, /* 402 '3' */ + {0x8d600000, 11, 90}, /* 403 'Z' */ + {0x8d000000, 12, 110}, /* 404 'n' */ + {0x8d100000, 12, 54}, /* 405 '6' */ + {0x8d500000, 12, 39}, /* 406 '\'' */ + {0x8d400000, 13, 1}, /* 407 '0x01' */ + {0x8d480000, 13, 115}, /* 408 's' */ + /* 19 */ + {0x00000000, 1, 32}, /* 409 ' ' */ + {0x80000000, 2, 0}, /* 410 '0x00' */ + {0xc0000000, 4, 114}, /* 411 'r' */ + {0xd0000000, 4, 47}, /* 412 '/' */ + {0xf0000000, 4, 66}, /* 413 'B' */ + {0xe0000000, 5, 48}, /* 414 '0' */ + {0xe8000000, 7, 58}, /* 415 ':' */ + {0xec000000, 7, 45}, /* 416 '-' */ + {0xea000000, 8, 49}, /* 417 '1' */ + {0xeb000000, 8, 56}, /* 418 '8' */ + {0xef000000, 8, 52}, /* 419 '4' */ + {0xee000000, 10, 54}, /* 420 '6' */ + {0xeec00000, 10, 57}, /* 421 '9' */ + {0xee600000, 11, 116}, /* 422 't' */ + {0xee800000, 11, 51}, /* 423 '3' */ + {0xee400000, 12, 1}, /* 424 '0x01' */ + {0xee500000, 12, 101}, /* 425 'e' */ + {0xeea00000, 12, 55}, /* 426 '7' */ + {0xeeb00000, 12, 53}, /* 427 '5' */ + /* 19 */ + {0x00000000, 1, 0}, /* 428 '0x00' */ + {0xc0000000, 2, 32}, /* 429 ' ' */ + {0x90000000, 4, 58}, /* 430 ':' */ + {0xb0000000, 4, 47}, /* 431 '/' */ + {0x88000000, 5, 56}, /* 432 '8' */ + {0xa8000000, 5, 46}, /* 433 '.' */ + {0x80000000, 6, 57}, /* 434 '9' */ + {0xa0000000, 6, 48}, /* 435 '0' */ + {0xa4000000, 7, 77}, /* 436 'M' */ + {0x85000000, 8, 73}, /* 437 'I' */ + {0x86000000, 8, 41}, /* 438 ')' */ + {0xa6000000, 8, 82}, /* 439 'R' */ + {0xa7000000, 8, 45}, /* 440 '-' */ + {0x84000000, 9, 87}, /* 441 'W' */ + {0x87000000, 9, 80}, /* 442 'P' */ + {0x87800000, 9, 53}, /* 443 '5' */ + {0x84c00000, 10, 50}, /* 444 '2' */ + {0x84800000, 11, 1}, /* 445 '0x01' */ + {0x84a00000, 11, 39}, /* 446 '\'' */ + /* 11 */ + {0x00000000, 1, 0}, /* 447 '0x00' */ + {0xc0000000, 2, 32}, /* 448 ' ' */ + {0xa0000000, 3, 48}, /* 449 '0' */ + {0x90000000, 4, 47}, /* 450 '/' */ + {0x84000000, 6, 45}, /* 451 '-' */ + {0x8c000000, 6, 58}, /* 452 ':' */ + {0x82000000, 7, 116}, /* 453 't' */ + {0x88000000, 7, 51}, /* 454 '3' */ + {0x8a000000, 7, 49}, /* 455 '1' */ + {0x80000000, 8, 1}, /* 456 '0x01' */ + {0x81000000, 8, 97}, /* 457 'a' */ + /* 16 */ + {0x00000000, 2, 0}, /* 458 '0x00' */ + {0x40000000, 2, 32}, /* 459 ' ' */ + {0x80000000, 2, 48}, /* 460 '0' */ + {0xe0000000, 3, 58}, /* 461 ':' */ + {0xc8000000, 5, 46}, /* 462 '.' */ + {0xd8000000, 5, 105}, /* 463 'i' */ + {0xc0000000, 6, 45}, /* 464 '-' */ + {0xd4000000, 6, 97}, /* 465 'a' */ + {0xc6000000, 7, 52}, /* 466 '4' */ + {0xd0000000, 7, 56}, /* 467 '8' */ + {0xd2000000, 7, 47}, /* 468 '/' */ + {0xc4000000, 8, 54}, /* 469 '6' */ + {0xc5800000, 9, 57}, /* 470 '9' */ + {0xc5000000, 10, 51}, /* 471 '3' */ + {0xc5400000, 11, 1}, /* 472 '0x01' */ + {0xc5600000, 11, 116}, /* 473 't' */ + /* 11 */ + {0x80000000, 1, 0}, /* 474 '0x00' */ + {0x40000000, 2, 32}, /* 475 ' ' */ + {0x00000000, 3, 48}, /* 476 '0' */ + {0x30000000, 4, 46}, /* 477 '.' */ + {0x28000000, 5, 47}, /* 478 '/' */ + {0x20000000, 7, 49}, /* 479 '1' */ + {0x24000000, 7, 53}, /* 480 '5' */ + {0x22000000, 8, 1}, /* 481 '0x01' */ + {0x23000000, 8, 52}, /* 482 '4' */ + {0x26000000, 8, 51}, /* 483 '3' */ + {0x27000000, 8, 50}, /* 484 '2' */ + /* 15 */ + {0x80000000, 1, 32}, /* 485 ' ' */ + {0x00000000, 2, 48}, /* 486 '0' */ + {0x40000000, 3, 58}, /* 487 ':' */ + {0x68000000, 5, 0}, /* 488 '0x00' */ + {0x60000000, 6, 116}, /* 489 't' */ + {0x64000000, 6, 112}, /* 490 'p' */ + {0x74000000, 6, 56}, /* 491 '8' */ + {0x78000000, 6, 46}, /* 492 '.' */ + {0x7c000000, 6, 54}, /* 493 '6' */ + {0x70000000, 7, 53}, /* 494 '5' */ + {0x72000000, 8, 57}, /* 495 '9' */ + {0x73000000, 9, 77}, /* 496 'M' */ + {0x73800000, 10, 70}, /* 497 'F' */ + {0x73c00000, 11, 1}, /* 498 '0x01' */ + {0x73e00000, 11, 99}, /* 499 'c' */ + /* 14 */ + {0x00000000, 1, 49}, /* 500 '1' */ + {0xc0000000, 2, 0}, /* 501 '0x00' */ + {0x80000000, 4, 57}, /* 502 '9' */ + {0xa0000000, 4, 46}, /* 503 '.' */ + {0x98000000, 5, 48}, /* 504 '0' */ + {0x90000000, 6, 32}, /* 505 ' ' */ + {0x94000000, 6, 56}, /* 506 '8' */ + {0xb0000000, 6, 55}, /* 507 '7' */ + {0xb4000000, 6, 47}, /* 508 '/' */ + {0xb8000000, 6, 54}, /* 509 '6' */ + {0xbe000000, 7, 58}, /* 510 ':' */ + {0xbd000000, 8, 52}, /* 511 '4' */ + {0xbc000000, 9, 1}, /* 512 '0x01' */ + {0xbc800000, 9, 51}, /* 513 '3' */ + /* 9 */ + {0x80000000, 1, 32}, /* 514 ' ' */ + {0x00000000, 2, 48}, /* 515 '0' */ + {0x60000000, 3, 46}, /* 516 '.' */ + {0x40000000, 4, 50}, /* 517 '2' */ + {0x50000000, 5, 49}, /* 518 '1' */ + {0x5c000000, 6, 51}, /* 519 '3' */ + {0x5a000000, 7, 67}, /* 520 'C' */ + {0x58000000, 8, 1}, /* 521 '0x01' */ + {0x59000000, 8, 84}, /* 522 'T' */ + /* 3 */ + {0x80000000, 1, 32}, /* 523 ' ' */ + {0x00000000, 2, 1}, /* 524 '0x01' */ + {0x40000000, 2, 46}, /* 525 '.' */ + /* 2 */ + {0x00000000, 1, 1}, /* 526 '0x01' */ + {0x80000000, 1, 1}, /* 527 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 528 '0x01' */ + {0x80000000, 1, 1}, /* 529 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 530 '0x01' */ + {0x80000000, 1, 1}, /* 531 '0x01' */ + /* 5 */ + {0x80000000, 1, 0}, /* 532 '0x00' */ + {0x40000000, 2, 32}, /* 533 ' ' */ + {0x20000000, 3, 58}, /* 534 ':' */ + {0x00000000, 4, 1}, /* 535 '0x01' */ + {0x10000000, 4, 46}, /* 536 '.' */ + /* 2 */ + {0x00000000, 1, 1}, /* 537 '0x01' */ + {0x80000000, 1, 72}, /* 538 'H' */ + /* 44 */ + {0x20000000, 3, 114}, /* 539 'r' */ + {0x40000000, 3, 32}, /* 540 ' ' */ + {0x80000000, 3, 108}, /* 541 'l' */ + {0xc0000000, 3, 110}, /* 542 'n' */ + {0x00000000, 4, 109}, /* 543 'm' */ + {0x70000000, 4, 103}, /* 544 'g' */ + {0xf0000000, 4, 100}, /* 545 'd' */ + {0x10000000, 5, 119}, /* 546 'w' */ + {0x60000000, 5, 84}, /* 547 'T' */ + {0x68000000, 5, 99}, /* 548 'c' */ + {0xa8000000, 5, 116}, /* 549 't' */ + {0xb0000000, 5, 102}, /* 550 'f' */ + {0xb8000000, 5, 105}, /* 551 'i' */ + {0xe0000000, 5, 115}, /* 552 's' */ + {0x18000000, 6, 117}, /* 553 'u' */ + {0x1c000000, 6, 0}, /* 554 '0x00' */ + {0xa4000000, 6, 82}, /* 555 'R' */ + {0xe8000000, 6, 98}, /* 556 'b' */ + {0xa2000000, 7, 118}, /* 557 'v' */ + {0xec000000, 7, 112}, /* 558 'p' */ + {0xa0000000, 8, 83}, /* 559 'S' */ + {0xee000000, 8, 77}, /* 560 'M' */ + {0xa1800000, 9, 80}, /* 561 'P' */ + {0xef800000, 9, 46}, /* 562 '.' */ + {0xa1000000, 11, 101}, /* 563 'e' */ + {0xa1200000, 11, 66}, /* 564 'B' */ + {0xa1400000, 11, 49}, /* 565 '1' */ + {0xef600000, 11, 45}, /* 566 '-' */ + {0xa1600000, 12, 107}, /* 567 'k' */ + {0xa1700000, 12, 104}, /* 568 'h' */ + {0xef000000, 12, 97}, /* 569 'a' */ + {0xef400000, 12, 121}, /* 570 'y' */ + {0xef500000, 12, 42}, /* 571 '*' */ + {0xef100000, 13, 120}, /* 572 'x' */ + {0xef180000, 13, 39}, /* 573 '\'' */ + {0xef200000, 13, 78}, /* 574 'N' */ + {0xef300000, 13, 50}, /* 575 '2' */ + {0xef280000, 14, 58}, /* 576 ':' */ + {0xef3c0000, 14, 122}, /* 577 'z' */ + {0xef2c0000, 15, 76}, /* 578 'L' */ + {0xef2e0000, 15, 70}, /* 579 'F' */ + {0xef380000, 15, 68}, /* 580 'D' */ + {0xef3a0000, 16, 1}, /* 581 '0x01' */ + {0xef3b0000, 16, 113}, /* 582 'q' */ + /* 26 */ + {0x00000000, 2, 67}, /* 583 'C' */ + {0x40000000, 2, 66}, /* 584 'B' */ + {0xa0000000, 3, 114}, /* 585 'r' */ + {0x90000000, 4, 105}, /* 586 'i' */ + {0xc0000000, 4, 111}, /* 587 'o' */ + {0xd0000000, 4, 117}, /* 588 'u' */ + {0xe0000000, 4, 97}, /* 589 'a' */ + {0xf0000000, 4, 101}, /* 590 'e' */ + {0x88000000, 5, 108}, /* 591 'l' */ + {0x80000000, 7, 0}, /* 592 '0x00' */ + {0x84000000, 7, 121}, /* 593 'y' */ + {0x82000000, 8, 79}, /* 594 'O' */ + {0x86000000, 8, 51}, /* 595 '3' */ + {0x83800000, 9, 65}, /* 596 'A' */ + {0x87000000, 9, 83}, /* 597 'S' */ + {0x83400000, 10, 58}, /* 598 ':' */ + {0x83000000, 11, 46}, /* 599 '.' */ + {0x83200000, 11, 119}, /* 600 'w' */ + {0x87a00000, 11, 104}, /* 601 'h' */ + {0x87c00000, 11, 42}, /* 602 '*' */ + {0x87e00000, 11, 32}, /* 603 ' ' */ + {0x87900000, 12, 82}, /* 604 'R' */ + {0x87800000, 13, 39}, /* 605 '\'' */ + {0x878c0000, 14, 84}, /* 606 'T' */ + {0x87880000, 15, 1}, /* 607 '0x01' */ + {0x878a0000, 15, 52}, /* 608 '4' */ + /* 31 */ + {0x00000000, 2, 111}, /* 609 'o' */ + {0x40000000, 2, 32}, /* 610 ' ' */ + {0x80000000, 3, 108}, /* 611 'l' */ + {0xc0000000, 3, 104}, /* 612 'h' */ + {0xa0000000, 4, 114}, /* 613 'r' */ + {0xe0000000, 4, 97}, /* 614 'a' */ + {0xb0000000, 5, 105}, /* 615 'i' */ + {0xb8000000, 5, 101}, /* 616 'e' */ + {0xf0000000, 6, 117}, /* 617 'u' */ + {0xf4000000, 6, 66}, /* 618 'B' */ + {0xf8000000, 7, 121}, /* 619 'y' */ + {0xfc000000, 7, 33}, /* 620 '!' */ + {0xfb000000, 8, 46}, /* 621 '.' */ + {0xfa000000, 9, 119}, /* 622 'w' */ + {0xfe000000, 9, 0}, /* 623 '0x00' */ + {0xff000000, 9, 83}, /* 624 'S' */ + {0xff800000, 9, 84}, /* 625 'T' */ + {0xfac00000, 10, 50}, /* 626 '2' */ + {0xfec00000, 10, 73}, /* 627 'I' */ + {0xfa800000, 11, 52}, /* 628 '4' */ + {0xfaa00000, 11, 42}, /* 629 '*' */ + {0xfea00000, 11, 68}, /* 630 'D' */ + {0xfe800000, 12, 85}, /* 631 'U' */ + {0xfe900000, 13, 39}, /* 632 '\'' */ + {0xfe980000, 14, 110}, /* 633 'n' */ + {0xfe9c0000, 15, 122}, /* 634 'z' */ + {0xfe9e0000, 17, 79}, /* 635 'O' */ + {0xfe9e8000, 17, 69}, /* 636 'E' */ + {0xfe9f0000, 17, 65}, /* 637 'A' */ + {0xfe9f8000, 18, 1}, /* 638 '0x01' */ + {0xfe9fc000, 18, 115}, /* 639 's' */ + /* 28 */ + {0x40000000, 2, 111}, /* 640 'o' */ + {0x80000000, 2, 97}, /* 641 'a' */ + {0x00000000, 3, 114}, /* 642 'r' */ + {0xc0000000, 3, 101}, /* 643 'e' */ + {0xe0000000, 3, 105}, /* 644 'i' */ + {0x20000000, 5, 116}, /* 645 't' */ + {0x38000000, 5, 117}, /* 646 'u' */ + {0x2c000000, 6, 32}, /* 647 ' ' */ + {0x2a000000, 7, 74}, /* 648 'J' */ + {0x30000000, 7, 121}, /* 649 'y' */ + {0x34000000, 7, 0}, /* 650 '0x00' */ + {0x36000000, 7, 73}, /* 651 'I' */ + {0x33000000, 8, 58}, /* 652 ':' */ + {0x28800000, 9, 42}, /* 653 '*' */ + {0x29000000, 9, 45}, /* 654 '-' */ + {0x29800000, 9, 38}, /* 655 '&' */ + {0x32000000, 9, 39}, /* 656 '\'' */ + {0x28000000, 10, 65}, /* 657 'A' */ + {0x28400000, 10, 104}, /* 658 'h' */ + {0x32a00000, 11, 78}, /* 659 'N' */ + {0x32c00000, 11, 86}, /* 660 'V' */ + {0x32e00000, 12, 68}, /* 661 'D' */ + {0x32f00000, 12, 119}, /* 662 'w' */ + {0x32800000, 13, 79}, /* 663 'O' */ + {0x32880000, 13, 69}, /* 664 'E' */ + {0x32980000, 13, 100}, /* 665 'd' */ + {0x32900000, 14, 1}, /* 666 '0x01' */ + {0x32940000, 14, 84}, /* 667 'T' */ + /* 45 */ + {0x00000000, 2, 109}, /* 668 'm' */ + {0x60000000, 3, 118}, /* 669 'v' */ + {0xa0000000, 3, 110}, /* 670 'n' */ + {0xe0000000, 3, 97}, /* 671 'a' */ + {0x40000000, 4, 69}, /* 672 'E' */ + {0x80000000, 4, 0}, /* 673 '0x00' */ + {0xd0000000, 4, 120}, /* 674 'x' */ + {0x98000000, 5, 100}, /* 675 'd' */ + {0xc8000000, 5, 108}, /* 676 'l' */ + {0x50000000, 6, 52}, /* 677 '4' */ + {0x54000000, 6, 121}, /* 678 'y' */ + {0x58000000, 6, 117}, /* 679 'u' */ + {0x90000000, 6, 114}, /* 680 'r' */ + {0xc0000000, 6, 105}, /* 681 'i' */ + {0x5e000000, 7, 115}, /* 682 's' */ + {0x94000000, 7, 70}, /* 683 'F' */ + {0xc4000000, 7, 88}, /* 684 'X' */ + {0x96000000, 8, 82}, /* 685 'R' */ + {0xc7000000, 8, 32}, /* 686 ' ' */ + {0x5d000000, 9, 103}, /* 687 'g' */ + {0x97800000, 9, 58}, /* 688 ':' */ + {0xc6000000, 9, 84}, /* 689 'T' */ + {0xc6800000, 9, 39}, /* 690 '\'' */ + {0x5c400000, 10, 99}, /* 691 'c' */ + {0x5cc00000, 10, 113}, /* 692 'q' */ + {0x5d800000, 10, 101}, /* 693 'e' */ + {0x5dc00000, 10, 67}, /* 694 'C' */ + {0x97000000, 10, 112}, /* 695 'p' */ + {0x5c000000, 11, 45}, /* 696 '-' */ + {0x5ca00000, 11, 90}, /* 697 'Z' */ + {0x97600000, 11, 116}, /* 698 't' */ + {0x5c200000, 12, 83}, /* 699 'S' */ + {0x5c300000, 12, 46}, /* 700 '.' */ + {0x97500000, 12, 87}, /* 701 'W' */ + {0x5c800000, 13, 33}, /* 702 '!' */ + {0x97400000, 13, 111}, /* 703 'o' */ + {0x5c880000, 14, 102}, /* 704 'f' */ + {0x5c8c0000, 14, 85}, /* 705 'U' */ + {0x5c900000, 14, 78}, /* 706 'N' */ + {0x5c940000, 14, 77}, /* 707 'M' */ + {0x5c980000, 14, 76}, /* 708 'L' */ + {0x5c9c0000, 14, 65}, /* 709 'A' */ + {0x974c0000, 14, 68}, /* 710 'D' */ + {0x97480000, 15, 1}, /* 711 '0x01' */ + {0x974a0000, 15, 119}, /* 712 'w' */ + /* 26 */ + {0x00000000, 2, 105}, /* 713 'i' */ + {0x80000000, 2, 97}, /* 714 'a' */ + {0x60000000, 3, 114}, /* 715 'r' */ + {0xc0000000, 3, 117}, /* 716 'u' */ + {0xe0000000, 3, 111}, /* 717 'o' */ + {0x40000000, 4, 101}, /* 718 'e' */ + {0x58000000, 5, 108}, /* 719 'l' */ + {0x50000000, 7, 65}, /* 720 'A' */ + {0x54000000, 7, 79}, /* 721 'O' */ + {0x52000000, 8, 32}, /* 722 ' ' */ + {0x53000000, 9, 104}, /* 723 'h' */ + {0x53800000, 9, 116}, /* 724 't' */ + {0x56800000, 9, 102}, /* 725 'f' */ + {0x57800000, 9, 76}, /* 726 'L' */ + {0x56400000, 10, 0}, /* 727 '0x00' */ + {0x57000000, 11, 106}, /* 728 'j' */ + {0x57200000, 11, 73}, /* 729 'I' */ + {0x57400000, 11, 46}, /* 730 '.' */ + {0x57600000, 11, 49}, /* 731 '1' */ + {0x56000000, 12, 77}, /* 732 'M' */ + {0x56200000, 12, 42}, /* 733 '*' */ + {0x56300000, 12, 75}, /* 734 'K' */ + {0x56100000, 13, 121}, /* 735 'y' */ + {0x561c0000, 14, 72}, /* 736 'H' */ + {0x56180000, 15, 1}, /* 737 '0x01' */ + {0x561a0000, 15, 33}, /* 738 '!' */ + /* 25 */ + {0x80000000, 2, 114}, /* 739 'r' */ + {0x20000000, 3, 77}, /* 740 'M' */ + {0x40000000, 3, 97}, /* 741 'a' */ + {0x60000000, 3, 111}, /* 742 'o' */ + {0xc0000000, 3, 105}, /* 743 'i' */ + {0xe0000000, 3, 101}, /* 744 'e' */ + {0x08000000, 5, 117}, /* 745 'u' */ + {0x10000000, 5, 88}, /* 746 'X' */ + {0x04000000, 6, 104}, /* 747 'h' */ + {0x1c000000, 6, 108}, /* 748 'l' */ + {0x02000000, 7, 121}, /* 749 'y' */ + {0x18000000, 7, 119}, /* 750 'w' */ + {0x00000000, 8, 58}, /* 751 ':' */ + {0x1b000000, 8, 67}, /* 752 'C' */ + {0x01800000, 9, 0}, /* 753 '0x00' */ + {0x1a000000, 9, 45}, /* 754 '-' */ + {0x1a800000, 10, 80}, /* 755 'P' */ + {0x1ac00000, 10, 32}, /* 756 ' ' */ + {0x01000000, 11, 39}, /* 757 '\'' */ + {0x01400000, 11, 65}, /* 758 'A' */ + {0x01200000, 12, 85}, /* 759 'U' */ + {0x01600000, 12, 84}, /* 760 'T' */ + {0x01700000, 12, 52}, /* 761 '4' */ + {0x01300000, 13, 1}, /* 762 '0x01' */ + {0x01380000, 13, 89}, /* 763 'Y' */ + /* 19 */ + {0x00000000, 1, 111}, /* 764 'o' */ + {0x80000000, 3, 97}, /* 765 'a' */ + {0xa0000000, 3, 105}, /* 766 'i' */ + {0xc0000000, 3, 101}, /* 767 'e' */ + {0xe0000000, 4, 117}, /* 768 'u' */ + {0xf0000000, 5, 82}, /* 769 'R' */ + {0xf8000000, 6, 65}, /* 770 'A' */ + {0xfc000000, 7, 46}, /* 771 '.' */ + {0xfe800000, 9, 121}, /* 772 'y' */ + {0xff000000, 9, 83}, /* 773 'S' */ + {0xff800000, 10, 69}, /* 774 'E' */ + {0xffc00000, 10, 114}, /* 775 'r' */ + {0xfe000000, 11, 0}, /* 776 '0x00' */ + {0xfe400000, 11, 76}, /* 777 'L' */ + {0xfe600000, 11, 77}, /* 778 'M' */ + {0xfe300000, 12, 119}, /* 779 'w' */ + {0xfe280000, 13, 68}, /* 780 'D' */ + {0xfe200000, 14, 1}, /* 781 '0x01' */ + {0xfe240000, 14, 73}, /* 782 'I' */ + /* 41 */ + {0x00000000, 1, 84}, /* 783 'T' */ + {0x80000000, 3, 115}, /* 784 's' */ + {0xa0000000, 3, 110}, /* 785 'n' */ + {0xd0000000, 4, 116}, /* 786 't' */ + {0xc8000000, 5, 32}, /* 787 ' ' */ + {0xe8000000, 5, 39}, /* 788 '\'' */ + {0xf8000000, 5, 114}, /* 789 'r' */ + {0xc0000000, 6, 73}, /* 790 'I' */ + {0xc4000000, 6, 0}, /* 791 '0x00' */ + {0xe4000000, 6, 109}, /* 792 'm' */ + {0xe0000000, 7, 100}, /* 793 'd' */ + {0xe2000000, 7, 78}, /* 794 'N' */ + {0xf2000000, 7, 122}, /* 795 'z' */ + {0xf4000000, 7, 46}, /* 796 '.' */ + {0xf0000000, 8, 97}, /* 797 'a' */ + {0xf1000000, 8, 89}, /* 798 'Y' */ + {0xf6000000, 9, 83}, /* 799 'S' */ + {0xf7000000, 9, 99}, /* 800 'c' */ + {0xf6a00000, 11, 68}, /* 801 'D' */ + {0xf6c00000, 11, 102}, /* 802 'f' */ + {0xf7800000, 11, 108}, /* 803 'l' */ + {0xf7e00000, 11, 121}, /* 804 'y' */ + {0xf6800000, 12, 86}, /* 805 'V' */ + {0xf6e00000, 12, 111}, /* 806 'o' */ + {0xf7b00000, 12, 70}, /* 807 'F' */ + {0xf6900000, 13, 44}, /* 808 ',' */ + {0xf6980000, 13, 65}, /* 809 'A' */ + {0xf6f00000, 13, 79}, /* 810 'O' */ + {0xf7a80000, 13, 103}, /* 811 'g' */ + {0xf7c00000, 13, 67}, /* 812 'C' */ + {0xf7c80000, 13, 58}, /* 813 ':' */ + {0xf7d80000, 13, 118}, /* 814 'v' */ + {0xf6f80000, 14, 112}, /* 815 'p' */ + {0xf6fc0000, 14, 69}, /* 816 'E' */ + {0xf7a00000, 14, 66}, /* 817 'B' */ + {0xf7d00000, 14, 107}, /* 818 'k' */ + {0xf7d40000, 14, 98}, /* 819 'b' */ + {0xf7a40000, 16, 1}, /* 820 '0x01' */ + {0xf7a50000, 16, 82}, /* 821 'R' */ + {0xf7a60000, 16, 76}, /* 822 'L' */ + {0xf7a70000, 16, 71}, /* 823 'G' */ + /* 16 */ + {0x00000000, 2, 97}, /* 824 'a' */ + {0x40000000, 2, 117}, /* 825 'u' */ + {0xc0000000, 2, 101}, /* 826 'e' */ + {0xa0000000, 3, 111}, /* 827 'o' */ + {0x90000000, 4, 105}, /* 828 'i' */ + {0x80000000, 5, 32}, /* 829 ' ' */ + {0x88000000, 6, 75}, /* 830 'K' */ + {0x8e000000, 7, 0}, /* 831 '0x00' */ + {0x8c800000, 9, 115}, /* 832 's' */ + {0x8d000000, 9, 70}, /* 833 'F' */ + {0x8c000000, 10, 86}, /* 834 'V' */ + {0x8c400000, 10, 39}, /* 835 '\'' */ + {0x8dc00000, 10, 102}, /* 836 'f' */ + {0x8da00000, 11, 71}, /* 837 'G' */ + {0x8d800000, 12, 1}, /* 838 '0x01' */ + {0x8d900000, 12, 68}, /* 839 'D' */ + /* 26 */ + {0x40000000, 2, 105}, /* 840 'i' */ + {0xc0000000, 2, 121}, /* 841 'y' */ + {0x20000000, 3, 101}, /* 842 'e' */ + {0xa0000000, 3, 32}, /* 843 ' ' */ + {0x00000000, 4, 97}, /* 844 'a' */ + {0x80000000, 4, 111}, /* 845 'o' */ + {0x10000000, 5, 0}, /* 846 '0x00' */ + {0x18000000, 5, 114}, /* 847 'r' */ + {0x94000000, 6, 116}, /* 848 't' */ + {0x98000000, 6, 110}, /* 849 'n' */ + {0x9c000000, 6, 83}, /* 850 'S' */ + {0x93000000, 8, 71}, /* 851 'G' */ + {0x90000000, 9, 45}, /* 852 '-' */ + {0x91800000, 9, 79}, /* 853 'O' */ + {0x92000000, 9, 104}, /* 854 'h' */ + {0x92800000, 9, 119}, /* 855 'w' */ + {0x90800000, 10, 49}, /* 856 '1' */ + {0x90c00000, 10, 39}, /* 857 '\'' */ + {0x91600000, 11, 117}, /* 858 'u' */ + {0x91000000, 12, 84}, /* 859 'T' */ + {0x91100000, 12, 78}, /* 860 'N' */ + {0x91200000, 12, 58}, /* 861 ':' */ + {0x91300000, 12, 46}, /* 862 '.' */ + {0x91400000, 12, 44}, /* 863 ',' */ + {0x91500000, 13, 1}, /* 864 '0x01' */ + {0x91580000, 13, 108}, /* 865 'l' */ + /* 19 */ + {0x00000000, 2, 97}, /* 866 'a' */ + {0x80000000, 2, 111}, /* 867 'o' */ + {0xc0000000, 2, 105}, /* 868 'i' */ + {0x40000000, 3, 101}, /* 869 'e' */ + {0x70000000, 4, 117}, /* 870 'u' */ + {0x68000000, 5, 75}, /* 871 'K' */ + {0x60000000, 7, 108}, /* 872 'l' */ + {0x64000000, 7, 65}, /* 873 'A' */ + {0x66000000, 7, 32}, /* 874 ' ' */ + {0x63000000, 8, 121}, /* 875 'y' */ + {0x62000000, 10, 76}, /* 876 'L' */ + {0x62400000, 10, 73}, /* 877 'I' */ + {0x62800000, 11, 67}, /* 878 'C' */ + {0x62a00000, 11, 46}, /* 879 '.' */ + {0x62e00000, 11, 0}, /* 880 '0x00' */ + {0x62d00000, 12, 39}, /* 881 '\'' */ + {0x62c00000, 13, 69}, /* 882 'E' */ + {0x62c80000, 14, 1}, /* 883 '0x01' */ + {0x62cc0000, 14, 89}, /* 884 'Y' */ + /* 29 */ + {0x40000000, 2, 97}, /* 885 'a' */ + {0x80000000, 2, 111}, /* 886 'o' */ + {0x00000000, 3, 101}, /* 887 'e' */ + {0xe0000000, 3, 105}, /* 888 'i' */ + {0x20000000, 4, 84}, /* 889 'T' */ + {0xc0000000, 4, 121}, /* 890 'y' */ + {0xd0000000, 4, 117}, /* 891 'u' */ + {0x30000000, 5, 0}, /* 892 '0x00' */ + {0x3c000000, 6, 99}, /* 893 'c' */ + {0x39000000, 8, 114}, /* 894 'r' */ + {0x3a000000, 8, 69}, /* 895 'E' */ + {0x3b800000, 9, 70}, /* 896 'F' */ + {0x38400000, 10, 90}, /* 897 'Z' */ + {0x38c00000, 10, 32}, /* 898 ' ' */ + {0x3b000000, 10, 49}, /* 899 '1' */ + {0x3b400000, 10, 73}, /* 900 'I' */ + {0x38200000, 11, 104}, /* 901 'h' */ + {0x38800000, 11, 67}, /* 902 'C' */ + {0x38100000, 12, 81}, /* 903 'Q' */ + {0x38a00000, 12, 75}, /* 904 'K' */ + {0x38b00000, 13, 80}, /* 905 'P' */ + {0x38000000, 14, 58}, /* 906 ':' */ + {0x38040000, 14, 46}, /* 907 '.' */ + {0x38080000, 14, 39}, /* 908 '\'' */ + {0x38b80000, 14, 77}, /* 909 'M' */ + {0x380c0000, 15, 1}, /* 910 '0x01' */ + {0x380e0000, 15, 119}, /* 911 'w' */ + {0x38bc0000, 15, 83}, /* 912 'S' */ + {0x38be0000, 15, 82}, /* 913 'R' */ + /* 22 */ + {0x80000000, 1, 101}, /* 914 'e' */ + {0x00000000, 2, 111}, /* 915 'o' */ + {0x60000000, 3, 105}, /* 916 'i' */ + {0x50000000, 4, 97}, /* 917 'a' */ + {0x48000000, 5, 117}, /* 918 'u' */ + {0x40000000, 6, 67}, /* 919 'C' */ + {0x44000000, 8, 69}, /* 920 'E' */ + {0x46000000, 8, 70}, /* 921 'F' */ + {0x47000000, 9, 66}, /* 922 'B' */ + {0x47800000, 9, 72}, /* 923 'H' */ + {0x45800000, 10, 89}, /* 924 'Y' */ + {0x45000000, 11, 71}, /* 925 'G' */ + {0x45200000, 11, 39}, /* 926 '\'' */ + {0x45600000, 11, 73}, /* 927 'I' */ + {0x45c00000, 11, 65}, /* 928 'A' */ + {0x45400000, 12, 77}, /* 929 'M' */ + {0x45e00000, 12, 32}, /* 930 ' ' */ + {0x45f00000, 12, 0}, /* 931 '0x00' */ + {0x45500000, 13, 84}, /* 932 'T' */ + {0x45580000, 14, 46}, /* 933 '.' */ + {0x455c0000, 15, 1}, /* 934 '0x01' */ + {0x455e0000, 15, 90}, /* 935 'Z' */ + /* 44 */ + {0x00000000, 3, 39}, /* 936 '\'' */ + {0x40000000, 3, 102}, /* 937 'f' */ + {0xc0000000, 3, 117}, /* 938 'u' */ + {0xe0000000, 3, 110}, /* 939 'n' */ + {0x20000000, 4, 77}, /* 940 'M' */ + {0x30000000, 4, 108}, /* 941 'l' */ + {0x90000000, 4, 109}, /* 942 'm' */ + {0x68000000, 5, 114}, /* 943 'r' */ + {0x70000000, 5, 100}, /* 944 'd' */ + {0x80000000, 5, 112}, /* 945 'p' */ + {0xa0000000, 5, 104}, /* 946 'h' */ + {0xb0000000, 5, 0}, /* 947 '0x00' */ + {0x64000000, 6, 83}, /* 948 'S' */ + {0x78000000, 6, 122}, /* 949 'z' */ + {0x7c000000, 6, 98}, /* 950 'b' */ + {0x8c000000, 6, 118}, /* 951 'v' */ + {0xa8000000, 6, 119}, /* 952 'w' */ + {0xac000000, 6, 85}, /* 953 'U' */ + {0xb8000000, 7, 84}, /* 954 'T' */ + {0xba000000, 7, 79}, /* 955 'O' */ + {0xbc000000, 7, 75}, /* 956 'K' */ + {0x61000000, 8, 67}, /* 957 'C' */ + {0x62000000, 8, 120}, /* 958 'x' */ + {0x63000000, 8, 46}, /* 959 '.' */ + {0x89000000, 8, 116}, /* 960 't' */ + {0x8b000000, 8, 32}, /* 961 ' ' */ + {0xbe000000, 8, 115}, /* 962 's' */ + {0xbf000000, 8, 78}, /* 963 'N' */ + {0x60800000, 9, 103}, /* 964 'g' */ + {0x88000000, 9, 45}, /* 965 '-' */ + {0x8a800000, 9, 97}, /* 966 'a' */ + {0x88800000, 10, 105}, /* 967 'i' */ + {0x88c00000, 10, 101}, /* 968 'e' */ + {0x8a400000, 10, 111}, /* 969 'o' */ + {0x60000000, 11, 65}, /* 970 'A' */ + {0x60200000, 11, 106}, /* 971 'j' */ + {0x60400000, 11, 99}, /* 972 'c' */ + {0x8a000000, 11, 50}, /* 973 '2' */ + {0x60700000, 12, 82}, /* 974 'R' */ + {0x8a200000, 12, 80}, /* 975 'P' */ + {0x8a300000, 12, 58}, /* 976 ':' */ + {0x60600000, 13, 69}, /* 977 'E' */ + {0x60680000, 14, 1}, /* 978 '0x01' */ + {0x606c0000, 14, 76}, /* 979 'L' */ + /* 28 */ + {0x40000000, 2, 114}, /* 980 'r' */ + {0x80000000, 2, 108}, /* 981 'l' */ + {0x00000000, 3, 101}, /* 982 'e' */ + {0x20000000, 3, 97}, /* 983 'a' */ + {0xe0000000, 3, 111}, /* 984 'o' */ + {0xd0000000, 4, 105}, /* 985 'i' */ + {0xc0000000, 6, 68}, /* 986 'D' */ + {0xc4000000, 6, 117}, /* 987 'u' */ + {0xcc000000, 6, 104}, /* 988 'h' */ + {0xc8000000, 8, 32}, /* 989 ' ' */ + {0xca000000, 8, 50}, /* 990 '2' */ + {0xc9000000, 9, 72}, /* 991 'H' */ + {0xc9800000, 9, 77}, /* 992 'M' */ + {0xcb000000, 9, 83}, /* 993 'S' */ + {0xcb800000, 11, 58}, /* 994 ':' */ + {0xcba00000, 11, 42}, /* 995 '*' */ + {0xcbd00000, 12, 115}, /* 996 's' */ + {0xcbc80000, 13, 73}, /* 997 'I' */ + {0xcbe00000, 13, 0}, /* 998 '0x00' */ + {0xcbe80000, 13, 71}, /* 999 'G' */ + {0xcbf00000, 13, 39}, /* 1000 '\'' */ + {0xcbf80000, 14, 121}, /* 1001 'y' */ + {0xcbc00000, 15, 89}, /* 1002 'Y' */ + {0xcbc20000, 15, 76}, /* 1003 'L' */ + {0xcbc40000, 15, 67}, /* 1004 'C' */ + {0xcbc60000, 15, 1}, /* 1005 '0x01' */ + {0xcbfc0000, 15, 79}, /* 1006 'O' */ + {0xcbfe0000, 15, 46}, /* 1007 '.' */ + /* 8 */ + {0x80000000, 1, 117}, /* 1008 'u' */ + {0x00000000, 3, 73}, /* 1009 'I' */ + {0x20000000, 3, 0}, /* 1010 '0x00' */ + {0x40000000, 3, 86}, /* 1011 'V' */ + {0x70000000, 4, 32}, /* 1012 ' ' */ + {0x68000000, 5, 67}, /* 1013 'C' */ + {0x60000000, 6, 1}, /* 1014 '0x01' */ + {0x64000000, 6, 39}, /* 1015 '\'' */ + /* 23 */ + {0x00000000, 2, 97}, /* 1016 'a' */ + {0x40000000, 2, 111}, /* 1017 'o' */ + {0xc0000000, 2, 101}, /* 1018 'e' */ + {0x80000000, 3, 105}, /* 1019 'i' */ + {0xb0000000, 4, 117}, /* 1020 'u' */ + {0xa8000000, 5, 69}, /* 1021 'E' */ + {0xa0000000, 6, 68}, /* 1022 'D' */ + {0xa6000000, 7, 0}, /* 1023 '0x00' */ + {0xa5000000, 8, 104}, /* 1024 'h' */ + {0xa4000000, 10, 73}, /* 1025 'I' */ + {0xa4800000, 10, 121}, /* 1026 'y' */ + {0xa4c00000, 10, 110}, /* 1027 'n' */ + {0xa4600000, 12, 32}, /* 1028 ' ' */ + {0xa4400000, 13, 39}, /* 1029 '\'' */ + {0xa4580000, 13, 83}, /* 1030 'S' */ + {0xa4700000, 13, 78}, /* 1031 'N' */ + {0xa4480000, 14, 66}, /* 1032 'B' */ + {0xa44c0000, 14, 46}, /* 1033 '.' */ + {0xa4500000, 14, 38}, /* 1034 '&' */ + {0xa4780000, 14, 84}, /* 1035 'T' */ + {0xa47c0000, 14, 49}, /* 1036 '1' */ + {0xa4540000, 15, 1}, /* 1037 '0x01' */ + {0xa4560000, 15, 67}, /* 1038 'C' */ + /* 39 */ + {0x20000000, 3, 111}, /* 1039 'o' */ + {0x40000000, 3, 112}, /* 1040 'p' */ + {0x60000000, 3, 117}, /* 1041 'u' */ + {0xc0000000, 3, 104}, /* 1042 'h' */ + {0xe0000000, 3, 116}, /* 1043 't' */ + {0x10000000, 4, 97}, /* 1044 'a' */ + {0x90000000, 4, 101}, /* 1045 'e' */ + {0xb0000000, 4, 99}, /* 1046 'c' */ + {0x00000000, 5, 110}, /* 1047 'n' */ + {0x88000000, 5, 105}, /* 1048 'i' */ + {0xa8000000, 5, 107}, /* 1049 'k' */ + {0x0c000000, 6, 119}, /* 1050 'w' */ + {0xa0000000, 6, 109}, /* 1051 'm' */ + {0x0a000000, 7, 65}, /* 1052 'A' */ + {0x84000000, 7, 108}, /* 1053 'l' */ + {0xa4000000, 7, 113}, /* 1054 'q' */ + {0xa6000000, 7, 77}, /* 1055 'M' */ + {0x08000000, 8, 50}, /* 1056 '2' */ + {0x09000000, 8, 80}, /* 1057 'P' */ + {0x80000000, 8, 79}, /* 1058 'O' */ + {0x82000000, 8, 73}, /* 1059 'I' */ + {0x83000000, 8, 32}, /* 1060 ' ' */ + {0x87000000, 8, 0}, /* 1061 '0x00' */ + {0x81000000, 9, 121}, /* 1062 'y' */ + {0x86000000, 9, 69}, /* 1063 'E' */ + {0x81c00000, 10, 63}, /* 1064 '?' */ + {0x86c00000, 10, 72}, /* 1065 'H' */ + {0x81800000, 11, 66}, /* 1066 'B' */ + {0x86800000, 11, 103}, /* 1067 'g' */ + {0x81b00000, 12, 114}, /* 1068 'r' */ + {0x86a00000, 12, 42}, /* 1069 '*' */ + {0x86b00000, 13, 51}, /* 1070 '3' */ + {0x86b80000, 13, 46}, /* 1071 '.' */ + {0x81a00000, 14, 53}, /* 1072 '5' */ + {0x81a80000, 14, 58}, /* 1073 ':' */ + {0x81ac0000, 14, 49}, /* 1074 '1' */ + {0x81a40000, 15, 67}, /* 1075 'C' */ + {0x81a60000, 16, 1}, /* 1076 '0x01' */ + {0x81a70000, 16, 89}, /* 1077 'Y' */ + /* 33 */ + {0x00000000, 1, 104}, /* 1078 'h' */ + {0xa0000000, 3, 111}, /* 1079 'o' */ + {0xe0000000, 3, 86}, /* 1080 'V' */ + {0x80000000, 4, 101}, /* 1081 'e' */ + {0x90000000, 4, 114}, /* 1082 'r' */ + {0xc0000000, 5, 97}, /* 1083 'a' */ + {0xd0000000, 5, 119}, /* 1084 'w' */ + {0xcc000000, 6, 105}, /* 1085 'i' */ + {0xda000000, 7, 79}, /* 1086 'O' */ + {0xde000000, 7, 72}, /* 1087 'H' */ + {0xc9000000, 8, 121}, /* 1088 'y' */ + {0xca000000, 8, 77}, /* 1089 'M' */ + {0xd8000000, 8, 46}, /* 1090 '.' */ + {0xdc000000, 8, 117}, /* 1091 'u' */ + {0xdd000000, 8, 87}, /* 1092 'W' */ + {0xc8800000, 9, 80}, /* 1093 'P' */ + {0xcb000000, 9, 58}, /* 1094 ':' */ + {0xcb800000, 9, 52}, /* 1095 '4' */ + {0xd9800000, 9, 73}, /* 1096 'I' */ + {0xd9000000, 10, 32}, /* 1097 ' ' */ + {0xd9400000, 10, 0}, /* 1098 '0x00' */ + {0xc8400000, 11, 88}, /* 1099 'X' */ + {0xc8600000, 11, 115}, /* 1100 's' */ + {0xc8000000, 12, 84}, /* 1101 'T' */ + {0xc8100000, 12, 83}, /* 1102 'S' */ + {0xc8200000, 12, 66}, /* 1103 'B' */ + {0xc8300000, 13, 85}, /* 1104 'U' */ + {0xc8380000, 14, 65}, /* 1105 'A' */ + {0xc83c0000, 16, 67}, /* 1106 'C' */ + {0xc83d0000, 16, 42}, /* 1107 '*' */ + {0xc83f0000, 16, 78}, /* 1108 'N' */ + {0xc83e0000, 17, 1}, /* 1109 '0x01' */ + {0xc83e8000, 17, 89}, /* 1110 'Y' */ + /* 23 */ + {0x00000000, 1, 110}, /* 1111 'n' */ + {0x80000000, 2, 112}, /* 1112 'p' */ + {0xd0000000, 4, 75}, /* 1113 'K' */ + {0xf0000000, 4, 108}, /* 1114 'l' */ + {0xc0000000, 5, 82}, /* 1115 'R' */ + {0xe0000000, 5, 83}, /* 1116 'S' */ + {0xcc000000, 6, 69}, /* 1117 'E' */ + {0xec000000, 6, 115}, /* 1118 's' */ + {0xca000000, 7, 103}, /* 1119 'g' */ + {0xea000000, 7, 84}, /* 1120 'T' */ + {0xc9000000, 8, 32}, /* 1121 ' ' */ + {0xc8000000, 9, 45}, /* 1122 '-' */ + {0xc8800000, 9, 114}, /* 1123 'r' */ + {0xe8000000, 9, 50}, /* 1124 '2' */ + {0xe8800000, 9, 109}, /* 1125 'm' */ + {0xe9800000, 9, 0}, /* 1126 '0x00' */ + {0xe9000000, 10, 46}, /* 1127 '.' */ + {0xe9400000, 11, 99}, /* 1128 'c' */ + {0xe9600000, 12, 107}, /* 1129 'k' */ + {0xe9700000, 14, 1}, /* 1130 '0x01' */ + {0xe9740000, 14, 122}, /* 1131 'z' */ + {0xe9780000, 14, 116}, /* 1132 't' */ + {0xe97c0000, 14, 66}, /* 1133 'B' */ + /* 21 */ + {0x80000000, 1, 32}, /* 1134 ' ' */ + {0x00000000, 3, 58}, /* 1135 ':' */ + {0x60000000, 3, 105}, /* 1136 'i' */ + {0x20000000, 4, 101}, /* 1137 'e' */ + {0x30000000, 4, 97}, /* 1138 'a' */ + {0x40000000, 4, 51}, /* 1139 '3' */ + {0x54000000, 6, 67}, /* 1140 'C' */ + {0x5c000000, 6, 0}, /* 1141 '0x00' */ + {0x50000000, 7, 39}, /* 1142 '\'' */ + {0x52000000, 7, 52}, /* 1143 '4' */ + {0x5a000000, 7, 111}, /* 1144 'o' */ + {0x59000000, 8, 73}, /* 1145 'I' */ + {0x58000000, 10, 115}, /* 1146 's' */ + {0x58400000, 10, 68}, /* 1147 'D' */ + {0x58800000, 10, 46}, /* 1148 '.' */ + {0x58c00000, 11, 56}, /* 1149 '8' */ + {0x58e80000, 13, 117}, /* 1150 'u' */ + {0x58f00000, 13, 114}, /* 1151 'r' */ + {0x58f80000, 13, 66}, /* 1152 'B' */ + {0x58e00000, 14, 1}, /* 1153 '0x01' */ + {0x58e40000, 14, 69}, /* 1154 'E' */ + /* 18 */ + {0x40000000, 2, 111}, /* 1155 'o' */ + {0xc0000000, 2, 101}, /* 1156 'e' */ + {0x20000000, 3, 104}, /* 1157 'h' */ + {0x80000000, 3, 97}, /* 1158 'a' */ + {0xa0000000, 3, 105}, /* 1159 'i' */ + {0x00000000, 5, 46}, /* 1160 '.' */ + {0x10000000, 5, 79}, /* 1161 'O' */ + {0x18000000, 5, 114}, /* 1162 'r' */ + {0x0c000000, 6, 121}, /* 1163 'y' */ + {0x08000000, 7, 117}, /* 1164 'u' */ + {0x0a000000, 8, 0}, /* 1165 '0x00' */ + {0x0b800000, 9, 65}, /* 1166 'A' */ + {0x0b200000, 11, 89}, /* 1167 'Y' */ + {0x0b400000, 11, 84}, /* 1168 'T' */ + {0x0b600000, 11, 32}, /* 1169 ' ' */ + {0x0b000000, 12, 73}, /* 1170 'I' */ + {0x0b100000, 13, 1}, /* 1171 '0x01' */ + {0x0b180000, 13, 108}, /* 1172 'l' */ + /* 14 */ + {0x00000000, 2, 0}, /* 1173 '0x00' */ + {0x80000000, 2, 32}, /* 1174 ' ' */ + {0xc0000000, 2, 116}, /* 1175 't' */ + {0x40000000, 3, 84}, /* 1176 'T' */ + {0x70000000, 4, 99}, /* 1177 'c' */ + {0x68000000, 5, 109}, /* 1178 'm' */ + {0x64000000, 6, 85}, /* 1179 'U' */ + {0x60000000, 8, 97}, /* 1180 'a' */ + {0x61000000, 8, 88}, /* 1181 'X' */ + {0x62000000, 8, 45}, /* 1182 '-' */ + {0x63000000, 9, 120}, /* 1183 'x' */ + {0x63c00000, 10, 57}, /* 1184 '9' */ + {0x63800000, 11, 1}, /* 1185 '0x01' */ + {0x63a00000, 11, 105}, /* 1186 'i' */ + /* 19 */ + {0x80000000, 1, 111}, /* 1187 'o' */ + {0x40000000, 2, 101}, /* 1188 'e' */ + {0x00000000, 3, 117}, /* 1189 'u' */ + {0x30000000, 4, 32}, /* 1190 ' ' */ + {0x20000000, 5, 118}, /* 1191 'v' */ + {0x28000000, 6, 97}, /* 1192 'a' */ + {0x2e000000, 8, 80}, /* 1193 'P' */ + {0x2f000000, 8, 39}, /* 1194 '\'' */ + {0x2c000000, 9, 110}, /* 1195 'n' */ + {0x2d800000, 9, 114}, /* 1196 'r' */ + {0x2c800000, 10, 68}, /* 1197 'D' */ + {0x2cc00000, 11, 119}, /* 1198 'w' */ + {0x2ce00000, 11, 115}, /* 1199 's' */ + {0x2d000000, 11, 82}, /* 1200 'R' */ + {0x2d200000, 11, 76}, /* 1201 'L' */ + {0x2d400000, 11, 0}, /* 1202 '0x00' */ + {0x2d600000, 12, 67}, /* 1203 'C' */ + {0x2d700000, 13, 1}, /* 1204 '0x01' */ + {0x2d780000, 13, 78}, /* 1205 'N' */ + /* 11 */ + {0x80000000, 1, 111}, /* 1206 'o' */ + {0x00000000, 2, 97}, /* 1207 'a' */ + {0x40000000, 3, 105}, /* 1208 'i' */ + {0x60000000, 5, 79}, /* 1209 'O' */ + {0x68000000, 5, 117}, /* 1210 'u' */ + {0x70000000, 5, 101}, /* 1211 'e' */ + {0x78000000, 6, 32}, /* 1212 ' ' */ + {0x7e000000, 7, 0}, /* 1213 '0x00' */ + {0x7d000000, 8, 58}, /* 1214 ':' */ + {0x7c000000, 9, 1}, /* 1215 '0x01' */ + {0x7c800000, 9, 45}, /* 1216 '-' */ + /* 2 */ + {0x00000000, 1, 1}, /* 1217 '0x01' */ + {0x80000000, 1, 1}, /* 1218 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 1219 '0x01' */ + {0x80000000, 1, 120}, /* 1220 'x' */ + /* 2 */ + {0x00000000, 1, 1}, /* 1221 '0x01' */ + {0x80000000, 1, 1}, /* 1222 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 1223 '0x01' */ + {0x80000000, 1, 1}, /* 1224 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 1225 '0x01' */ + {0x80000000, 1, 1}, /* 1226 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 1227 '0x01' */ + {0x80000000, 1, 1}, /* 1228 '0x01' */ + /* 39 */ + {0x20000000, 3, 114}, /* 1229 'r' */ + {0x60000000, 3, 116}, /* 1230 't' */ + {0x80000000, 3, 108}, /* 1231 'l' */ + {0xc0000000, 3, 110}, /* 1232 'n' */ + {0x10000000, 4, 109}, /* 1233 'm' */ + {0x40000000, 4, 99}, /* 1234 'c' */ + {0xa0000000, 4, 115}, /* 1235 's' */ + {0xe0000000, 4, 121}, /* 1236 'y' */ + {0xb0000000, 5, 32}, /* 1237 ' ' */ + {0xb8000000, 5, 100}, /* 1238 'd' */ + {0xf0000000, 5, 105}, /* 1239 'i' */ + {0xf8000000, 5, 107}, /* 1240 'k' */ + {0x08000000, 6, 98}, /* 1241 'b' */ + {0x0c000000, 6, 0}, /* 1242 '0x00' */ + {0x58000000, 6, 112}, /* 1243 'p' */ + {0x5c000000, 6, 103}, /* 1244 'g' */ + {0x00000000, 7, 101}, /* 1245 'e' */ + {0x02000000, 7, 39}, /* 1246 '\'' */ + {0x06000000, 7, 119}, /* 1247 'w' */ + {0x52000000, 7, 117}, /* 1248 'u' */ + {0x54000000, 7, 122}, /* 1249 'z' */ + {0x56000000, 7, 118}, /* 1250 'v' */ + {0x05000000, 8, 102}, /* 1251 'f' */ + {0x51000000, 8, 104}, /* 1252 'h' */ + {0x04800000, 9, 58}, /* 1253 ':' */ + {0x04000000, 10, 33}, /* 1254 '!' */ + {0x50000000, 10, 111}, /* 1255 'o' */ + {0x50400000, 10, 120}, /* 1256 'x' */ + {0x04400000, 11, 45}, /* 1257 '-' */ + {0x04600000, 11, 97}, /* 1258 'a' */ + {0x50a00000, 11, 46}, /* 1259 '.' */ + {0x50c00000, 11, 78}, /* 1260 'N' */ + {0x50e00000, 11, 44}, /* 1261 ',' */ + {0x50800000, 12, 113}, /* 1262 'q' */ + {0x50900000, 13, 106}, /* 1263 'j' */ + {0x509c0000, 14, 63}, /* 1264 '?' */ + {0x509a0000, 15, 74}, /* 1265 'J' */ + {0x50980000, 16, 1}, /* 1266 '0x01' */ + {0x50990000, 16, 85}, /* 1267 'U' */ + /* 24 */ + {0x00000000, 3, 114}, /* 1268 'r' */ + {0x20000000, 3, 111}, /* 1269 'o' */ + {0x40000000, 3, 101}, /* 1270 'e' */ + {0x60000000, 3, 97}, /* 1271 'a' */ + {0x80000000, 3, 105}, /* 1272 'i' */ + {0xb0000000, 4, 117}, /* 1273 'u' */ + {0xc0000000, 4, 121}, /* 1274 'y' */ + {0xd0000000, 4, 108}, /* 1275 'l' */ + {0xf0000000, 4, 32}, /* 1276 ' ' */ + {0xa8000000, 5, 115}, /* 1277 's' */ + {0xe0000000, 5, 98}, /* 1278 'b' */ + {0xe8000000, 5, 0}, /* 1279 '0x00' */ + {0xa0000000, 6, 104}, /* 1280 'h' */ + {0xa4000000, 7, 51}, /* 1281 '3' */ + {0xa7000000, 8, 39}, /* 1282 '\'' */ + {0xa6400000, 10, 116}, /* 1283 't' */ + {0xa6800000, 10, 106}, /* 1284 'j' */ + {0xa6000000, 11, 110}, /* 1285 'n' */ + {0xa6200000, 11, 100}, /* 1286 'd' */ + {0xa6e00000, 11, 119}, /* 1287 'w' */ + {0xa6d00000, 12, 109}, /* 1288 'm' */ + {0xa6c80000, 13, 46}, /* 1289 '.' */ + {0xa6c00000, 14, 1}, /* 1290 '0x01' */ + {0xa6c40000, 14, 58}, /* 1291 ':' */ + /* 37 */ + {0x00000000, 2, 107}, /* 1292 'k' */ + {0x40000000, 3, 111}, /* 1293 'o' */ + {0x80000000, 3, 104}, /* 1294 'h' */ + {0xc0000000, 3, 116}, /* 1295 't' */ + {0xe0000000, 3, 101}, /* 1296 'e' */ + {0x70000000, 4, 114}, /* 1297 'r' */ + {0xa0000000, 5, 32}, /* 1298 ' ' */ + {0xb0000000, 5, 105}, /* 1299 'i' */ + {0xb8000000, 5, 97}, /* 1300 'a' */ + {0x60000000, 6, 108}, /* 1301 'l' */ + {0x64000000, 6, 121}, /* 1302 'y' */ + {0x68000000, 6, 115}, /* 1303 's' */ + {0x6c000000, 6, 0}, /* 1304 '0x00' */ + {0xa8000000, 7, 99}, /* 1305 'c' */ + {0xae000000, 7, 117}, /* 1306 'u' */ + {0xaa000000, 8, 58}, /* 1307 ':' */ + {0xab000000, 8, 80}, /* 1308 'P' */ + {0xac800000, 9, 68}, /* 1309 'D' */ + {0xad000000, 10, 71}, /* 1310 'G' */ + {0xad800000, 10, 98}, /* 1311 'b' */ + {0xac000000, 11, 76}, /* 1312 'L' */ + {0xac200000, 11, 75}, /* 1313 'K' */ + {0xac600000, 11, 65}, /* 1314 'A' */ + {0xad400000, 11, 113}, /* 1315 'q' */ + {0xadc00000, 11, 46}, /* 1316 '.' */ + {0xade00000, 11, 67}, /* 1317 'C' */ + {0xac400000, 12, 110}, /* 1318 'n' */ + {0xac500000, 12, 39}, /* 1319 '\'' */ + {0xad600000, 13, 66}, /* 1320 'B' */ + {0xad680000, 13, 73}, /* 1321 'I' */ + {0xad740000, 14, 102}, /* 1322 'f' */ + {0xad780000, 14, 56}, /* 1323 '8' */ + {0xad700000, 15, 77}, /* 1324 'M' */ + {0xad720000, 15, 1}, /* 1325 '0x01' */ + {0xad7e0000, 15, 70}, /* 1326 'F' */ + {0xad7c0000, 16, 119}, /* 1327 'w' */ + {0xad7d0000, 16, 81}, /* 1328 'Q' */ + /* 36 */ + {0xc0000000, 2, 32}, /* 1329 ' ' */ + {0x20000000, 3, 101}, /* 1330 'e' */ + {0x80000000, 3, 0}, /* 1331 '0x00' */ + {0xa0000000, 3, 97}, /* 1332 'a' */ + {0x10000000, 4, 121}, /* 1333 'y' */ + {0x40000000, 4, 105}, /* 1334 'i' */ + {0x60000000, 4, 115}, /* 1335 's' */ + {0x00000000, 5, 111}, /* 1336 'o' */ + {0x50000000, 5, 100}, /* 1337 'd' */ + {0x0c000000, 6, 117}, /* 1338 'u' */ + {0x58000000, 6, 114}, /* 1339 'r' */ + {0x5c000000, 6, 108}, /* 1340 'l' */ + {0x74000000, 6, 118}, /* 1341 'v' */ + {0x78000000, 6, 103}, /* 1342 'g' */ + {0x08000000, 7, 39}, /* 1343 '\'' */ + {0x7e000000, 7, 46}, /* 1344 '.' */ + {0x0a000000, 8, 58}, /* 1345 ':' */ + {0x0b000000, 8, 104}, /* 1346 'h' */ + {0x70000000, 8, 99}, /* 1347 'c' */ + {0x72000000, 8, 110}, /* 1348 'n' */ + {0x73000000, 8, 119}, /* 1349 'w' */ + {0x71000000, 9, 63}, /* 1350 '?' */ + {0x7c000000, 9, 33}, /* 1351 '!' */ + {0x7c800000, 9, 45}, /* 1352 '-' */ + {0x7d000000, 9, 102}, /* 1353 'f' */ + {0x71c00000, 10, 109}, /* 1354 'm' */ + {0x7d800000, 10, 44}, /* 1355 ',' */ + {0x7dc00000, 11, 116}, /* 1356 't' */ + {0x7de00000, 11, 98}, /* 1357 'b' */ + {0x71900000, 12, 41}, /* 1358 ')' */ + {0x71a00000, 12, 47}, /* 1359 '/' */ + {0x71b00000, 12, 107}, /* 1360 'k' */ + {0x71880000, 13, 112}, /* 1361 'p' */ + {0x71840000, 14, 122}, /* 1362 'z' */ + {0x71800000, 15, 1}, /* 1363 '0x01' */ + {0x71820000, 15, 52}, /* 1364 '4' */ + /* 42 */ + {0x40000000, 2, 32}, /* 1365 ' ' */ + {0x00000000, 3, 115}, /* 1366 's' */ + {0xa0000000, 3, 114}, /* 1367 'r' */ + {0x20000000, 4, 116}, /* 1368 't' */ + {0x90000000, 4, 110}, /* 1369 'n' */ + {0xc0000000, 4, 0}, /* 1370 '0x00' */ + {0xe0000000, 4, 97}, /* 1371 'a' */ + {0xf0000000, 4, 119}, /* 1372 'w' */ + {0x80000000, 5, 108}, /* 1373 'l' */ + {0xd8000000, 5, 101}, /* 1374 'e' */ + {0x38000000, 6, 109}, /* 1375 'm' */ + {0x88000000, 6, 99}, /* 1376 'c' */ + {0x8c000000, 6, 100}, /* 1377 'd' */ + {0x34000000, 7, 105}, /* 1378 'i' */ + {0x36000000, 7, 112}, /* 1379 'p' */ + {0x3c000000, 7, 98}, /* 1380 'b' */ + {0xd0000000, 7, 118}, /* 1381 'v' */ + {0xd6000000, 7, 121}, /* 1382 'y' */ + {0x30000000, 8, 103}, /* 1383 'g' */ + {0x31000000, 8, 102}, /* 1384 'f' */ + {0x32000000, 8, 120}, /* 1385 'x' */ + {0x3e000000, 8, 107}, /* 1386 'k' */ + {0x3f000000, 8, 58}, /* 1387 ':' */ + {0xd3000000, 8, 111}, /* 1388 'o' */ + {0xd4000000, 8, 39}, /* 1389 '\'' */ + {0x33800000, 9, 104}, /* 1390 'h' */ + {0xd2800000, 9, 46}, /* 1391 '.' */ + {0x33000000, 10, 80}, /* 1392 'P' */ + {0x33400000, 10, 66}, /* 1393 'B' */ + {0xd2000000, 10, 44}, /* 1394 ',' */ + {0xd5000000, 10, 86}, /* 1395 'V' */ + {0xd5400000, 10, 122}, /* 1396 'z' */ + {0xd5c00000, 10, 106}, /* 1397 'j' */ + {0xd2400000, 11, 52}, /* 1398 '4' */ + {0xd2600000, 11, 63}, /* 1399 '?' */ + {0xd5a00000, 11, 117}, /* 1400 'u' */ + {0xd5900000, 12, 45}, /* 1401 '-' */ + {0xd5880000, 13, 33}, /* 1402 '!' */ + {0xd5840000, 14, 113}, /* 1403 'q' */ + {0xd5820000, 15, 71}, /* 1404 'G' */ + {0xd5800000, 16, 1}, /* 1405 '0x01' */ + {0xd5810000, 16, 83}, /* 1406 'S' */ + /* 24 */ + {0x00000000, 1, 32}, /* 1407 ' ' */ + {0xa0000000, 3, 111}, /* 1408 'o' */ + {0x90000000, 4, 116}, /* 1409 't' */ + {0xc0000000, 4, 97}, /* 1410 'a' */ + {0xd0000000, 4, 105}, /* 1411 'i' */ + {0xf0000000, 4, 101}, /* 1412 'e' */ + {0x80000000, 5, 46}, /* 1413 '.' */ + {0xe0000000, 5, 114}, /* 1414 'r' */ + {0xe8000000, 5, 102}, /* 1415 'f' */ + {0x88000000, 6, 0}, /* 1416 '0x00' */ + {0x8d000000, 8, 121}, /* 1417 'y' */ + {0x8f000000, 8, 117}, /* 1418 'u' */ + {0x8c000000, 9, 39}, /* 1419 '\'' */ + {0x8e800000, 9, 108}, /* 1420 'l' */ + {0x8cc00000, 10, 110}, /* 1421 'n' */ + {0x8e000000, 10, 103}, /* 1422 'g' */ + {0x8c800000, 11, 99}, /* 1423 'c' */ + {0x8e400000, 11, 45}, /* 1424 '-' */ + {0x8ca00000, 12, 44}, /* 1425 ',' */ + {0x8cb00000, 12, 115}, /* 1426 's' */ + {0x8e700000, 12, 58}, /* 1427 ':' */ + {0x8e680000, 13, 107}, /* 1428 'k' */ + {0x8e600000, 14, 1}, /* 1429 '0x01' */ + {0x8e640000, 14, 98}, /* 1430 'b' */ + /* 33 */ + {0x00000000, 2, 104}, /* 1431 'h' */ + {0x80000000, 2, 32}, /* 1432 ' ' */ + {0x40000000, 3, 0}, /* 1433 '0x00' */ + {0x60000000, 3, 101}, /* 1434 'e' */ + {0xc0000000, 4, 105}, /* 1435 'i' */ + {0xe0000000, 5, 58}, /* 1436 ':' */ + {0xe8000000, 5, 114}, /* 1437 'r' */ + {0xf8000000, 5, 97}, /* 1438 'a' */ + {0xd0000000, 6, 115}, /* 1439 's' */ + {0xdc000000, 6, 108}, /* 1440 'l' */ + {0xf4000000, 6, 117}, /* 1441 'u' */ + {0xd6000000, 7, 98}, /* 1442 'b' */ + {0xd8000000, 7, 103}, /* 1443 'g' */ + {0xda000000, 7, 111}, /* 1444 'o' */ + {0xf2000000, 7, 110}, /* 1445 'n' */ + {0xd4000000, 8, 50}, /* 1446 '2' */ + {0xf0000000, 8, 33}, /* 1447 '!' */ + {0xf1800000, 9, 100}, /* 1448 'd' */ + {0xd5000000, 10, 46}, /* 1449 '.' */ + {0xd5400000, 10, 44}, /* 1450 ',' */ + {0xd5800000, 10, 39}, /* 1451 '\'' */ + {0xd5c00000, 10, 116}, /* 1452 't' */ + {0xf1400000, 10, 121}, /* 1453 'y' */ + {0xf1000000, 11, 119}, /* 1454 'w' */ + {0xf1300000, 12, 109}, /* 1455 'm' */ + {0xf12c0000, 14, 63}, /* 1456 '?' */ + {0xf1200000, 15, 112}, /* 1457 'p' */ + {0xf1220000, 15, 102}, /* 1458 'f' */ + {0xf1240000, 15, 64}, /* 1459 '@' */ + {0xf1260000, 15, 45}, /* 1460 '-' */ + {0xf12a0000, 15, 59}, /* 1461 ';' */ + {0xf1280000, 16, 1}, /* 1462 '0x01' */ + {0xf1290000, 16, 122}, /* 1463 'z' */ + /* 31 */ + {0x00000000, 1, 101}, /* 1464 'e' */ + {0xa0000000, 3, 111}, /* 1465 'o' */ + {0x90000000, 4, 105}, /* 1466 'i' */ + {0xc0000000, 4, 97}, /* 1467 'a' */ + {0xe0000000, 4, 32}, /* 1468 ' ' */ + {0xf0000000, 4, 116}, /* 1469 't' */ + {0xd0000000, 5, 114}, /* 1470 'r' */ + {0xd8000000, 5, 0}, /* 1471 '0x00' */ + {0x80000000, 6, 98}, /* 1472 'b' */ + {0x84000000, 6, 117}, /* 1473 'u' */ + {0x88000000, 8, 119}, /* 1474 'w' */ + {0x89000000, 8, 100}, /* 1475 'd' */ + {0x8a000000, 8, 110}, /* 1476 'n' */ + {0x8b000000, 8, 121}, /* 1477 'y' */ + {0x8c000000, 8, 33}, /* 1478 '!' */ + {0x8d000000, 8, 108}, /* 1479 'l' */ + {0x8f000000, 8, 46}, /* 1480 '.' */ + {0x8e000000, 9, 39}, /* 1481 '\'' */ + {0x8e800000, 10, 115}, /* 1482 's' */ + {0x8ec00000, 11, 109}, /* 1483 'm' */ + {0x8ef00000, 12, 58}, /* 1484 ':' */ + {0x8ee00000, 14, 102}, /* 1485 'f' */ + {0x8ee40000, 14, 63}, /* 1486 '?' */ + {0x8ee80000, 14, 99}, /* 1487 'c' */ + {0x8eec0000, 16, 118}, /* 1488 'v' */ + {0x8eed0000, 16, 113}, /* 1489 'q' */ + {0x8eee0000, 16, 103}, /* 1490 'g' */ + {0x8eef0000, 18, 104}, /* 1491 'h' */ + {0x8eef4000, 18, 1}, /* 1492 '0x01' */ + {0x8eef8000, 18, 44}, /* 1493 ',' */ + {0x8eefc000, 18, 42}, /* 1494 '*' */ + /* 35 */ + {0x40000000, 2, 110}, /* 1495 'n' */ + {0x00000000, 3, 99}, /* 1496 'c' */ + {0x90000000, 4, 111}, /* 1497 'o' */ + {0xa0000000, 4, 108}, /* 1498 'l' */ + {0xc0000000, 4, 103}, /* 1499 'g' */ + {0xd0000000, 4, 115}, /* 1500 's' */ + {0xe0000000, 4, 116}, /* 1501 't' */ + {0xf0000000, 4, 101}, /* 1502 'e' */ + {0x28000000, 5, 97}, /* 1503 'a' */ + {0x30000000, 5, 118}, /* 1504 'v' */ + {0x80000000, 5, 114}, /* 1505 'r' */ + {0x88000000, 5, 100}, /* 1506 'd' */ + {0xb0000000, 5, 109}, /* 1507 'm' */ + {0x20000000, 6, 112}, /* 1508 'p' */ + {0x38000000, 6, 32}, /* 1509 ' ' */ + {0xbc000000, 6, 102}, /* 1510 'f' */ + {0x3c000000, 7, 122}, /* 1511 'z' */ + {0x3e000000, 7, 0}, /* 1512 '0x00' */ + {0xb8000000, 7, 98}, /* 1513 'b' */ + {0xba000000, 7, 107}, /* 1514 'k' */ + {0x25000000, 8, 45}, /* 1515 '-' */ + {0x26000000, 8, 120}, /* 1516 'x' */ + {0x24800000, 9, 39}, /* 1517 '\'' */ + {0x27800000, 9, 113}, /* 1518 'q' */ + {0x27000000, 10, 117}, /* 1519 'u' */ + {0x27400000, 10, 105}, /* 1520 'i' */ + {0x24200000, 11, 104}, /* 1521 'h' */ + {0x24400000, 11, 58}, /* 1522 ':' */ + {0x24600000, 11, 119}, /* 1523 'w' */ + {0x24080000, 13, 44}, /* 1524 ',' */ + {0x24100000, 13, 121}, /* 1525 'y' */ + {0x24180000, 13, 47}, /* 1526 '/' */ + {0x24000000, 14, 46}, /* 1527 '.' */ + {0x24040000, 15, 1}, /* 1528 '0x01' */ + {0x24060000, 15, 106}, /* 1529 'j' */ + /* 9 */ + {0x00000000, 1, 121}, /* 1530 'y' */ + {0xc0000000, 2, 111}, /* 1531 'o' */ + {0xa0000000, 3, 101}, /* 1532 'e' */ + {0x90000000, 4, 97}, /* 1533 'a' */ + {0x88000000, 5, 117}, /* 1534 'u' */ + {0x84000000, 6, 105}, /* 1535 'i' */ + {0x80000000, 7, 0}, /* 1536 '0x00' */ + {0x82000000, 8, 1}, /* 1537 '0x01' */ + {0x83000000, 8, 32}, /* 1538 ' ' */ + /* 33 */ + {0x00000000, 2, 32}, /* 1539 ' ' */ + {0x80000000, 2, 101}, /* 1540 'e' */ + {0x40000000, 3, 105}, /* 1541 'i' */ + {0xc0000000, 3, 0}, /* 1542 '0x00' */ + {0x60000000, 4, 121}, /* 1543 'y' */ + {0x70000000, 4, 115}, /* 1544 's' */ + {0xf0000000, 4, 102}, /* 1545 'f' */ + {0xe4000000, 6, 97}, /* 1546 'a' */ + {0xe8000000, 6, 108}, /* 1547 'l' */ + {0xe2000000, 7, 58}, /* 1548 ':' */ + {0xec000000, 7, 107}, /* 1549 'k' */ + {0xe0000000, 8, 39}, /* 1550 '\'' */ + {0xef000000, 8, 46}, /* 1551 '.' */ + {0xe1800000, 9, 119}, /* 1552 'w' */ + {0xee000000, 9, 111}, /* 1553 'o' */ + {0xe1400000, 10, 104}, /* 1554 'h' */ + {0xe1000000, 11, 98}, /* 1555 'b' */ + {0xe1200000, 11, 44}, /* 1556 ',' */ + {0xeee00000, 11, 110}, /* 1557 'n' */ + {0xeea00000, 12, 63}, /* 1558 '?' */ + {0xeec00000, 12, 109}, /* 1559 'm' */ + {0xeed00000, 12, 33}, /* 1560 '!' */ + {0xee900000, 13, 117}, /* 1561 'u' */ + {0xee980000, 13, 99}, /* 1562 'c' */ + {0xeeb00000, 13, 100}, /* 1563 'd' */ + {0xeeb80000, 13, 116}, /* 1564 't' */ + {0xee840000, 14, 106}, /* 1565 'j' */ + {0xee880000, 14, 45}, /* 1566 '-' */ + {0xee800000, 15, 112}, /* 1567 'p' */ + {0xee820000, 15, 47}, /* 1568 '/' */ + {0xee8e0000, 15, 83}, /* 1569 'S' */ + {0xee8c0000, 16, 1}, /* 1570 '0x01' */ + {0xee8d0000, 16, 114}, /* 1571 'r' */ + /* 36 */ + {0x40000000, 2, 101}, /* 1572 'e' */ + {0x00000000, 3, 108}, /* 1573 'l' */ + {0xa0000000, 3, 97}, /* 1574 'a' */ + {0x30000000, 4, 121}, /* 1575 'y' */ + {0x80000000, 4, 0}, /* 1576 '0x00' */ + {0x90000000, 4, 100}, /* 1577 'd' */ + {0xc0000000, 4, 111}, /* 1578 'o' */ + {0xe0000000, 4, 105}, /* 1579 'i' */ + {0xf0000000, 4, 32}, /* 1580 ' ' */ + {0x20000000, 5, 117}, /* 1581 'u' */ + {0xd0000000, 5, 115}, /* 1582 's' */ + {0x28000000, 6, 116}, /* 1583 't' */ + {0x2c000000, 6, 109}, /* 1584 'm' */ + {0xda000000, 7, 107}, /* 1585 'k' */ + {0xd8000000, 8, 102}, /* 1586 'f' */ + {0xdc000000, 8, 98}, /* 1587 'b' */ + {0xde000000, 8, 39}, /* 1588 '\'' */ + {0xdf000000, 8, 99}, /* 1589 'c' */ + {0xd9800000, 9, 118}, /* 1590 'v' */ + {0xdd000000, 9, 58}, /* 1591 ':' */ + {0xd9400000, 10, 46}, /* 1592 '.' */ + {0xdd800000, 10, 119}, /* 1593 'w' */ + {0xd9000000, 11, 122}, /* 1594 'z' */ + {0xdde00000, 11, 112}, /* 1595 'p' */ + {0xd9200000, 12, 104}, /* 1596 'h' */ + {0xd9300000, 12, 42}, /* 1597 '*' */ + {0xddc00000, 13, 103}, /* 1598 'g' */ + {0xddc80000, 13, 44}, /* 1599 ',' */ + {0xddd00000, 14, 114}, /* 1600 'r' */ + {0xddd40000, 14, 110}, /* 1601 'n' */ + {0xdddc0000, 14, 45}, /* 1602 '-' */ + {0xddd80000, 15, 33}, /* 1603 '!' */ + {0xdddb0000, 16, 63}, /* 1604 '?' */ + {0xddda8000, 17, 67}, /* 1605 'C' */ + {0xddda0000, 18, 1}, /* 1606 '0x01' */ + {0xddda4000, 18, 106}, /* 1607 'j' */ + /* 25 */ + {0x80000000, 2, 101}, /* 1608 'e' */ + {0x20000000, 3, 109}, /* 1609 'm' */ + {0x60000000, 3, 32}, /* 1610 ' ' */ + {0xe0000000, 3, 97}, /* 1611 'a' */ + {0x00000000, 4, 105}, /* 1612 'i' */ + {0x10000000, 4, 0}, /* 1613 '0x00' */ + {0x40000000, 4, 121}, /* 1614 'y' */ + {0xd0000000, 4, 112}, /* 1615 'p' */ + {0x50000000, 5, 98}, /* 1616 'b' */ + {0xc0000000, 5, 111}, /* 1617 'o' */ + {0xc8000000, 6, 110}, /* 1618 'n' */ + {0xcc000000, 6, 115}, /* 1619 's' */ + {0x58000000, 7, 108}, /* 1620 'l' */ + {0x5c000000, 7, 102}, /* 1621 'f' */ + {0x5a000000, 8, 58}, /* 1622 ':' */ + {0x5e000000, 8, 52}, /* 1623 '4' */ + {0x5b000000, 9, 104}, /* 1624 'h' */ + {0x5f000000, 9, 119}, /* 1625 'w' */ + {0x5bc00000, 10, 39}, /* 1626 '\'' */ + {0x5f800000, 10, 114}, /* 1627 'r' */ + {0x5fc00000, 10, 117}, /* 1628 'u' */ + {0x5ba00000, 11, 46}, /* 1629 '.' */ + {0x5b900000, 12, 107}, /* 1630 'k' */ + {0x5b800000, 13, 1}, /* 1631 '0x01' */ + {0x5b880000, 13, 100}, /* 1632 'd' */ + /* 40 */ + {0x00000000, 3, 105}, /* 1633 'i' */ + {0x80000000, 3, 103}, /* 1634 'g' */ + {0xa0000000, 3, 32}, /* 1635 ' ' */ + {0xc0000000, 3, 100}, /* 1636 'd' */ + {0x30000000, 4, 97}, /* 1637 'a' */ + {0x40000000, 4, 115}, /* 1638 's' */ + {0x60000000, 4, 101}, /* 1639 'e' */ + {0xe0000000, 4, 0}, /* 1640 '0x00' */ + {0xf0000000, 4, 116}, /* 1641 't' */ + {0x70000000, 5, 99}, /* 1642 'c' */ + {0x78000000, 5, 110}, /* 1643 'n' */ + {0x28000000, 6, 121}, /* 1644 'y' */ + {0x50000000, 6, 39}, /* 1645 '\'' */ + {0x54000000, 6, 107}, /* 1646 'k' */ + {0x5c000000, 6, 111}, /* 1647 'o' */ + {0x20000000, 7, 114}, /* 1648 'r' */ + {0x26000000, 7, 102}, /* 1649 'f' */ + {0x2c000000, 7, 117}, /* 1650 'u' */ + {0x2e000000, 7, 106}, /* 1651 'j' */ + {0x22000000, 8, 118}, /* 1652 'v' */ + {0x24000000, 8, 45}, /* 1653 '-' */ + {0x25000000, 8, 46}, /* 1654 '.' */ + {0x58000000, 8, 108}, /* 1655 'l' */ + {0x5a000000, 8, 120}, /* 1656 'x' */ + {0x5b000000, 8, 58}, /* 1657 ':' */ + {0x23800000, 9, 44}, /* 1658 ',' */ + {0x59800000, 9, 109}, /* 1659 'm' */ + {0x23000000, 10, 33}, /* 1660 '!' */ + {0x23400000, 11, 122}, /* 1661 'z' */ + {0x59200000, 11, 63}, /* 1662 '?' */ + {0x59400000, 11, 104}, /* 1663 'h' */ + {0x59600000, 11, 98}, /* 1664 'b' */ + {0x23600000, 12, 66}, /* 1665 'B' */ + {0x23700000, 12, 42}, /* 1666 '*' */ + {0x59000000, 12, 119}, /* 1667 'w' */ + {0x59180000, 13, 113}, /* 1668 'q' */ + {0x59140000, 14, 112}, /* 1669 'p' */ + {0x59100000, 15, 59}, /* 1670 ';' */ + {0x59120000, 16, 47}, /* 1671 '/' */ + {0x59130000, 16, 1}, /* 1672 '0x01' */ + /* 42 */ + {0x00000000, 2, 114}, /* 1673 'r' */ + {0xc0000000, 3, 110}, /* 1674 'n' */ + {0x40000000, 4, 102}, /* 1675 'f' */ + {0x50000000, 4, 32}, /* 1676 ' ' */ + {0x60000000, 4, 119}, /* 1677 'w' */ + {0x80000000, 4, 111}, /* 1678 'o' */ + {0xb0000000, 4, 117}, /* 1679 'u' */ + {0x78000000, 5, 116}, /* 1680 't' */ + {0x90000000, 5, 99}, /* 1681 'c' */ + {0xa0000000, 5, 112}, /* 1682 'p' */ + {0xa8000000, 5, 100}, /* 1683 'd' */ + {0xe0000000, 5, 109}, /* 1684 'm' */ + {0xf0000000, 5, 108}, /* 1685 'l' */ + {0x70000000, 6, 97}, /* 1686 'a' */ + {0x74000000, 6, 98}, /* 1687 'b' */ + {0x98000000, 6, 121}, /* 1688 'y' */ + {0x9c000000, 6, 0}, /* 1689 '0x00' */ + {0xe8000000, 6, 115}, /* 1690 's' */ + {0xec000000, 6, 107}, /* 1691 'k' */ + {0xfa000000, 7, 118}, /* 1692 'v' */ + {0xfc000000, 7, 103}, /* 1693 'g' */ + {0xff000000, 8, 105}, /* 1694 'i' */ + {0xf8800000, 9, 104}, /* 1695 'h' */ + {0xf9000000, 9, 33}, /* 1696 '!' */ + {0xfe000000, 9, 101}, /* 1697 'e' */ + {0xfe800000, 9, 106}, /* 1698 'j' */ + {0xf9800000, 10, 39}, /* 1699 '\'' */ + {0xf8200000, 11, 63}, /* 1700 '?' */ + {0xf8400000, 11, 58}, /* 1701 ':' */ + {0xf9c00000, 11, 122}, /* 1702 'z' */ + {0xf9e00000, 11, 120}, /* 1703 'x' */ + {0xf8000000, 12, 74}, /* 1704 'J' */ + {0xf8600000, 12, 46}, /* 1705 '.' */ + {0xf8700000, 12, 45}, /* 1706 '-' */ + {0xf8100000, 14, 52}, /* 1707 '4' */ + {0xf8180000, 14, 44}, /* 1708 ',' */ + {0xf81c0000, 14, 71}, /* 1709 'G' */ + {0xf8160000, 15, 41}, /* 1710 ')' */ + {0xf8140000, 16, 83}, /* 1711 'S' */ + {0xf8150000, 17, 68}, /* 1712 'D' */ + {0xf8158000, 18, 1}, /* 1713 '0x01' */ + {0xf815c000, 18, 113}, /* 1714 'q' */ + /* 28 */ + {0x00000000, 2, 101}, /* 1715 'e' */ + {0x40000000, 3, 0}, /* 1716 '0x00' */ + {0x80000000, 3, 105}, /* 1717 'i' */ + {0xc0000000, 3, 111}, /* 1718 'o' */ + {0x60000000, 4, 115}, /* 1719 's' */ + {0xa0000000, 4, 32}, /* 1720 ' ' */ + {0xe0000000, 4, 112}, /* 1721 'p' */ + {0x70000000, 5, 108}, /* 1722 'l' */ + {0x78000000, 5, 114}, /* 1723 'r' */ + {0xb0000000, 5, 104}, /* 1724 'h' */ + {0xf0000000, 5, 97}, /* 1725 'a' */ + {0xb8000000, 6, 116}, /* 1726 't' */ + {0xbc000000, 6, 39}, /* 1727 '\'' */ + {0xf8000000, 7, 100}, /* 1728 'd' */ + {0xfa000000, 7, 109}, /* 1729 'm' */ + {0xfc000000, 7, 121}, /* 1730 'y' */ + {0xfe800000, 9, 58}, /* 1731 ':' */ + {0xff800000, 9, 33}, /* 1732 '!' */ + {0xff000000, 10, 119}, /* 1733 'w' */ + {0xff400000, 10, 117}, /* 1734 'u' */ + {0xfe000000, 11, 98}, /* 1735 'b' */ + {0xfe400000, 11, 45}, /* 1736 '-' */ + {0xfe600000, 11, 46}, /* 1737 '.' */ + {0xfe300000, 12, 110}, /* 1738 'n' */ + {0xfe280000, 13, 107}, /* 1739 'k' */ + {0xfe240000, 14, 44}, /* 1740 ',' */ + {0xfe200000, 15, 1}, /* 1741 '0x01' */ + {0xfe220000, 15, 99}, /* 1742 'c' */ + /* 5 */ + {0x80000000, 1, 117}, /* 1743 'u' */ + {0x40000000, 2, 0}, /* 1744 '0x00' */ + {0x20000000, 3, 58}, /* 1745 ':' */ + {0x00000000, 4, 1}, /* 1746 '0x01' */ + {0x10000000, 4, 39}, /* 1747 '\'' */ + /* 40 */ + {0x00000000, 3, 32}, /* 1748 ' ' */ + {0x60000000, 3, 105}, /* 1749 'i' */ + {0xa0000000, 3, 101}, /* 1750 'e' */ + {0x30000000, 4, 121}, /* 1751 'y' */ + {0x40000000, 4, 100}, /* 1752 'd' */ + {0x80000000, 4, 115}, /* 1753 's' */ + {0x90000000, 4, 116}, /* 1754 't' */ + {0xc0000000, 4, 97}, /* 1755 'a' */ + {0xd0000000, 4, 0}, /* 1756 '0x00' */ + {0xf0000000, 4, 111}, /* 1757 'o' */ + {0x58000000, 5, 110}, /* 1758 'n' */ + {0xe8000000, 5, 108}, /* 1759 'l' */ + {0x24000000, 6, 107}, /* 1760 'k' */ + {0x28000000, 6, 114}, /* 1761 'r' */ + {0x2c000000, 6, 109}, /* 1762 'm' */ + {0x54000000, 6, 117}, /* 1763 'u' */ + {0xe4000000, 6, 103}, /* 1764 'g' */ + {0x20000000, 7, 39}, /* 1765 '\'' */ + {0x52000000, 7, 99}, /* 1766 'c' */ + {0xe2000000, 7, 58}, /* 1767 ':' */ + {0x22000000, 8, 102}, /* 1768 'f' */ + {0x23000000, 8, 46}, /* 1769 '.' */ + {0x51000000, 8, 98}, /* 1770 'b' */ + {0xe0000000, 8, 118}, /* 1771 'v' */ + {0x50000000, 9, 44}, /* 1772 ',' */ + {0x50800000, 9, 112}, /* 1773 'p' */ + {0xe1000000, 9, 119}, /* 1774 'w' */ + {0xe1c00000, 10, 106}, /* 1775 'j' */ + {0xe1800000, 11, 45}, /* 1776 '-' */ + {0xe1a00000, 12, 104}, /* 1777 'h' */ + {0xe1b00000, 13, 71}, /* 1778 'G' */ + {0xe1b80000, 14, 113}, /* 1779 'q' */ + {0xe1be0000, 15, 83}, /* 1780 'S' */ + {0xe1bc0000, 16, 33}, /* 1781 '!' */ + {0xe1bd0000, 18, 42}, /* 1782 '*' */ + {0xe1bd8000, 18, 84}, /* 1783 'T' */ + {0xe1bd4000, 19, 1}, /* 1784 '0x01' */ + {0xe1bd6000, 19, 69}, /* 1785 'E' */ + {0xe1bdc000, 19, 49}, /* 1786 '1' */ + {0xe1bde000, 19, 47}, /* 1787 '/' */ + /* 37 */ + {0x80000000, 2, 32}, /* 1788 ' ' */ + {0xc0000000, 2, 0}, /* 1789 '0x00' */ + {0x60000000, 3, 116}, /* 1790 't' */ + {0x00000000, 4, 115}, /* 1791 's' */ + {0x20000000, 4, 105}, /* 1792 'i' */ + {0x30000000, 4, 104}, /* 1793 'h' */ + {0x18000000, 5, 59}, /* 1794 ';' */ + {0x50000000, 5, 101}, /* 1795 'e' */ + {0x44000000, 6, 111}, /* 1796 'o' */ + {0x4c000000, 6, 99}, /* 1797 'c' */ + {0x58000000, 6, 58}, /* 1798 ':' */ + {0x10000000, 7, 46}, /* 1799 '.' */ + {0x12000000, 7, 33}, /* 1800 '!' */ + {0x16000000, 7, 121}, /* 1801 'y' */ + {0x40000000, 7, 112}, /* 1802 'p' */ + {0x48000000, 7, 97}, /* 1803 'a' */ + {0x5e000000, 7, 117}, /* 1804 'u' */ + {0x14000000, 8, 44}, /* 1805 ',' */ + {0x15000000, 8, 102}, /* 1806 'f' */ + {0x43000000, 8, 39}, /* 1807 '\'' */ + {0x4b000000, 8, 110}, /* 1808 'n' */ + {0x5c000000, 8, 108}, /* 1809 'l' */ + {0x5d000000, 8, 114}, /* 1810 'r' */ + {0x42800000, 9, 107}, /* 1811 'k' */ + {0x4a000000, 9, 100}, /* 1812 'd' */ + {0x42400000, 10, 109}, /* 1813 'm' */ + {0x4ac00000, 10, 98}, /* 1814 'b' */ + {0x42000000, 11, 63}, /* 1815 '?' */ + {0x42200000, 11, 119}, /* 1816 'w' */ + {0x4a800000, 11, 103}, /* 1817 'g' */ + {0x4aa00000, 12, 113}, /* 1818 'q' */ + {0x4ab40000, 14, 69}, /* 1819 'E' */ + {0x4ab80000, 14, 45}, /* 1820 '-' */ + {0x4ab00000, 15, 1}, /* 1821 '0x01' */ + {0x4ab20000, 15, 41}, /* 1822 ')' */ + {0x4abc0000, 15, 87}, /* 1823 'W' */ + {0x4abe0000, 15, 49}, /* 1824 '1' */ + /* 39 */ + {0x00000000, 3, 105}, /* 1825 'i' */ + {0x60000000, 3, 0}, /* 1826 '0x00' */ + {0x80000000, 3, 32}, /* 1827 ' ' */ + {0xe0000000, 3, 104}, /* 1828 'h' */ + {0x20000000, 4, 97}, /* 1829 'a' */ + {0x40000000, 4, 114}, /* 1830 'r' */ + {0xa0000000, 4, 115}, /* 1831 's' */ + {0xb0000000, 4, 111}, /* 1832 'o' */ + {0xd0000000, 4, 101}, /* 1833 'e' */ + {0x38000000, 5, 116}, /* 1834 't' */ + {0x50000000, 5, 121}, /* 1835 'y' */ + {0xc0000000, 5, 117}, /* 1836 'u' */ + {0x58000000, 6, 109}, /* 1837 'm' */ + {0xc8000000, 6, 99}, /* 1838 'c' */ + {0xcc000000, 6, 108}, /* 1839 'l' */ + {0x30000000, 7, 39}, /* 1840 '\'' */ + {0x34000000, 7, 58}, /* 1841 ':' */ + {0x32000000, 8, 119}, /* 1842 'w' */ + {0x36000000, 8, 33}, /* 1843 '!' */ + {0x5c000000, 8, 46}, /* 1844 '.' */ + {0x5d000000, 8, 98}, /* 1845 'b' */ + {0x5e000000, 8, 69}, /* 1846 'E' */ + {0x5f000000, 8, 102}, /* 1847 'f' */ + {0x33000000, 9, 63}, /* 1848 '?' */ + {0x37000000, 9, 110}, /* 1849 'n' */ + {0x33800000, 10, 122}, /* 1850 'z' */ + {0x37800000, 10, 100}, /* 1851 'd' */ + {0x33e00000, 11, 44}, /* 1852 ',' */ + {0x37c00000, 11, 80}, /* 1853 'P' */ + {0x33c00000, 12, 118}, /* 1854 'v' */ + {0x33d00000, 12, 45}, /* 1855 '-' */ + {0x37e00000, 12, 41}, /* 1856 ')' */ + {0x37f00000, 13, 103}, /* 1857 'g' */ + {0x37f80000, 14, 1}, /* 1858 '0x01' */ + {0x37fc0000, 15, 83}, /* 1859 'S' */ + {0x37ff0000, 16, 52}, /* 1860 '4' */ + {0x37fe0000, 17, 107}, /* 1861 'k' */ + {0x37fe8000, 18, 106}, /* 1862 'j' */ + {0x37fec000, 18, 112}, /* 1863 'p' */ + /* 34 */ + {0x00000000, 2, 114}, /* 1864 'r' */ + {0x80000000, 3, 115}, /* 1865 's' */ + {0xe0000000, 3, 110}, /* 1866 'n' */ + {0x40000000, 4, 101}, /* 1867 'e' */ + {0x50000000, 4, 109}, /* 1868 'm' */ + {0xc0000000, 4, 116}, /* 1869 't' */ + {0x60000000, 5, 99}, /* 1870 'c' */ + {0x68000000, 5, 103}, /* 1871 'g' */ + {0x70000000, 5, 98}, /* 1872 'b' */ + {0xa0000000, 5, 112}, /* 1873 'p' */ + {0xa8000000, 5, 105}, /* 1874 'i' */ + {0xb0000000, 5, 108}, /* 1875 'l' */ + {0xd0000000, 5, 100}, /* 1876 'd' */ + {0xd8000000, 5, 97}, /* 1877 'a' */ + {0x78000000, 6, 0}, /* 1878 '0x00' */ + {0xb8000000, 6, 121}, /* 1879 'y' */ + {0x7c000000, 7, 122}, /* 1880 'z' */ + {0xbc000000, 7, 32}, /* 1881 ' ' */ + {0x7f000000, 8, 39}, /* 1882 '\'' */ + {0xbe000000, 8, 45}, /* 1883 '-' */ + {0x7e000000, 9, 107}, /* 1884 'k' */ + {0xbf800000, 9, 58}, /* 1885 ':' */ + {0x7e800000, 10, 102}, /* 1886 'f' */ + {0x7ec00000, 10, 44}, /* 1887 ',' */ + {0xbf000000, 10, 119}, /* 1888 'w' */ + {0xbf400000, 12, 118}, /* 1889 'v' */ + {0xbf500000, 12, 120}, /* 1890 'x' */ + {0xbf700000, 12, 111}, /* 1891 'o' */ + {0xbf600000, 13, 106}, /* 1892 'j' */ + {0xbf680000, 14, 117}, /* 1893 'u' */ + {0xbf6c0000, 15, 46}, /* 1894 '.' */ + {0xbf6f0000, 16, 104}, /* 1895 'h' */ + {0xbf6e0000, 17, 63}, /* 1896 '?' */ + {0xbf6e8000, 17, 1}, /* 1897 '0x01' */ + /* 11 */ + {0x80000000, 1, 101}, /* 1898 'e' */ + {0x40000000, 2, 105}, /* 1899 'i' */ + {0x20000000, 3, 97}, /* 1900 'a' */ + {0x10000000, 4, 111}, /* 1901 'o' */ + {0x00000000, 5, 32}, /* 1902 ' ' */ + {0x0c000000, 6, 0}, /* 1903 '0x00' */ + {0x08000000, 7, 121}, /* 1904 'y' */ + {0x0b000000, 8, 115}, /* 1905 's' */ + {0x0a800000, 9, 114}, /* 1906 'r' */ + {0x0a000000, 10, 1}, /* 1907 '0x01' */ + {0x0a400000, 10, 46}, /* 1908 '.' */ + /* 31 */ + {0x00000000, 1, 115}, /* 1909 's' */ + {0x80000000, 3, 32}, /* 1910 ' ' */ + {0xc0000000, 3, 0}, /* 1911 '0x00' */ + {0xb0000000, 4, 105}, /* 1912 'i' */ + {0xe0000000, 4, 111}, /* 1913 'o' */ + {0xa0000000, 5, 97}, /* 1914 'a' */ + {0xf0000000, 5, 110}, /* 1915 'n' */ + {0xf8000000, 5, 101}, /* 1916 'e' */ + {0xae000000, 7, 121}, /* 1917 'y' */ + {0xa8000000, 8, 109}, /* 1918 'm' */ + {0xab000000, 8, 100}, /* 1919 'd' */ + {0xad000000, 8, 108}, /* 1920 'l' */ + {0xa9800000, 9, 98}, /* 1921 'b' */ + {0xaa000000, 9, 107}, /* 1922 'k' */ + {0xaa800000, 9, 114}, /* 1923 'r' */ + {0xa9000000, 10, 106}, /* 1924 'j' */ + {0xac400000, 10, 44}, /* 1925 ',' */ + {0xacc00000, 10, 104}, /* 1926 'h' */ + {0xa9600000, 11, 45}, /* 1927 '-' */ + {0xac000000, 11, 99}, /* 1928 'c' */ + {0xac200000, 11, 102}, /* 1929 'f' */ + {0xaca00000, 11, 112}, /* 1930 'p' */ + {0xa9400000, 12, 103}, /* 1931 'g' */ + {0xac800000, 12, 116}, /* 1932 't' */ + {0xa9500000, 13, 46}, /* 1933 '.' */ + {0xa9580000, 13, 58}, /* 1934 ':' */ + {0xac980000, 13, 113}, /* 1935 'q' */ + {0xac940000, 14, 39}, /* 1936 '\'' */ + {0xac920000, 15, 63}, /* 1937 '?' */ + {0xac900000, 16, 1}, /* 1938 '0x01' */ + {0xac910000, 16, 66}, /* 1939 'B' */ + /* 20 */ + {0x00000000, 2, 112}, /* 1940 'p' */ + {0x80000000, 2, 32}, /* 1941 ' ' */ + {0xc0000000, 2, 116}, /* 1942 't' */ + {0x60000000, 4, 0}, /* 1943 '0x00' */ + {0x40000000, 5, 111}, /* 1944 'o' */ + {0x50000000, 5, 99}, /* 1945 'c' */ + {0x70000000, 5, 105}, /* 1946 'i' */ + {0x78000000, 5, 109}, /* 1947 'm' */ + {0x48000000, 6, 101}, /* 1948 'e' */ + {0x58000000, 6, 121}, /* 1949 'y' */ + {0x4c000000, 7, 117}, /* 1950 'u' */ + {0x4e000000, 7, 102}, /* 1951 'f' */ + {0x5e000000, 7, 44}, /* 1952 ',' */ + {0x5c000000, 9, 103}, /* 1953 'g' */ + {0x5c800000, 9, 97}, /* 1954 'a' */ + {0x5d800000, 9, 57}, /* 1955 '9' */ + {0x5d400000, 10, 39}, /* 1956 '\'' */ + {0x5d200000, 11, 120}, /* 1957 'x' */ + {0x5d000000, 12, 1}, /* 1958 '0x01' */ + {0x5d100000, 12, 115}, /* 1959 's' */ + /* 36 */ + {0x00000000, 1, 32}, /* 1960 ' ' */ + {0xc0000000, 2, 0}, /* 1961 '0x00' */ + {0x88000000, 5, 111}, /* 1962 'o' */ + {0x90000000, 5, 115}, /* 1963 's' */ + {0xa0000000, 5, 97}, /* 1964 'a' */ + {0xb0000000, 5, 108}, /* 1965 'l' */ + {0xb8000000, 5, 58}, /* 1966 ':' */ + {0x98000000, 6, 100}, /* 1967 'd' */ + {0x82000000, 7, 110}, /* 1968 'n' */ + {0x84000000, 7, 116}, /* 1969 't' */ + {0xa8000000, 7, 39}, /* 1970 '\'' */ + {0xaa000000, 7, 98}, /* 1971 'b' */ + {0xae000000, 7, 46}, /* 1972 '.' */ + {0x80000000, 8, 105}, /* 1973 'i' */ + {0x86000000, 8, 44}, /* 1974 ',' */ + {0x87000000, 8, 112}, /* 1975 'p' */ + {0x9c000000, 8, 109}, /* 1976 'm' */ + {0x9e000000, 8, 99}, /* 1977 'c' */ + {0xac000000, 8, 119}, /* 1978 'w' */ + {0xad000000, 8, 101}, /* 1979 'e' */ + {0x81000000, 9, 63}, /* 1980 '?' */ + {0x81800000, 9, 102}, /* 1981 'f' */ + {0x9d000000, 9, 114}, /* 1982 'r' */ + {0x9d800000, 9, 103}, /* 1983 'g' */ + {0x9f000000, 10, 122}, /* 1984 'z' */ + {0x9f800000, 10, 45}, /* 1985 '-' */ + {0x9fc00000, 10, 84}, /* 1986 'T' */ + {0x9f400000, 12, 50}, /* 1987 '2' */ + {0x9f600000, 12, 33}, /* 1988 '!' */ + {0x9f700000, 12, 107}, /* 1989 'k' */ + {0x9f500000, 13, 118}, /* 1990 'v' */ + {0x9f580000, 14, 121}, /* 1991 'y' */ + {0x9f5c0000, 15, 104}, /* 1992 'h' */ + {0x9f5f0000, 16, 106}, /* 1993 'j' */ + {0x9f5e0000, 17, 1}, /* 1994 '0x01' */ + {0x9f5e8000, 17, 41}, /* 1995 ')' */ + /* 21 */ + {0x00000000, 2, 122}, /* 1996 'z' */ + {0x40000000, 2, 0}, /* 1997 '0x00' */ + {0xa0000000, 3, 105}, /* 1998 'i' */ + {0x80000000, 4, 121}, /* 1999 'y' */ + {0x90000000, 4, 101}, /* 2000 'e' */ + {0xc0000000, 4, 119}, /* 2001 'w' */ + {0xd0000000, 4, 32}, /* 2002 ' ' */ + {0xe0000000, 4, 108}, /* 2003 'l' */ + {0xf0000000, 5, 97}, /* 2004 'a' */ + {0xf8000000, 6, 111}, /* 2005 'o' */ + {0xfc000000, 8, 109}, /* 2006 'm' */ + {0xfd000000, 8, 58}, /* 2007 ':' */ + {0xff000000, 8, 99}, /* 2008 'c' */ + {0xfe000000, 9, 44}, /* 2009 ',' */ + {0xfec00000, 10, 98}, /* 2010 'b' */ + {0xfe800000, 11, 117}, /* 2011 'u' */ + {0xfeb00000, 12, 33}, /* 2012 '!' */ + {0xfea00000, 14, 1}, /* 2013 '0x01' */ + {0xfea40000, 14, 116}, /* 2014 't' */ + {0xfea80000, 14, 104}, /* 2015 'h' */ + {0xfeac0000, 14, 63}, /* 2016 '?' */ + /* 2 */ + {0x00000000, 1, 1}, /* 2017 '0x01' */ + {0x80000000, 1, 1}, /* 2018 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 2019 '0x01' */ + {0x80000000, 1, 1}, /* 2020 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 2021 '0x01' */ + {0x80000000, 1, 1}, /* 2022 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 2023 '0x01' */ + {0x80000000, 1, 1}, /* 2024 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 2025 '0x01' */ + {0x80000000, 1, 1} /* 2026 '0x01' */ }; unsigned fsat_index_1[] = { - 0, /* 0 */ - 51, /* 1 */ - 53, /* 2 */ - 53, /* 3 */ - 55, /* 4 */ - 57, /* 5 */ - 59, /* 6 */ - 61, /* 7 */ - 63, /* 8 */ - 65, /* 9 */ - 67, /* 10 */ - 69, /* 11 */ - 71, /* 12 */ - 73, /* 13 */ - 75, /* 14 */ - 77, /* 15 */ - 79, /* 16 */ - 81, /* 17 */ - 83, /* 18 */ - 85, /* 19 */ - 87, /* 20 */ - 89, /* 21 */ - 91, /* 22 */ - 93, /* 23 */ - 95, /* 24 */ - 97, /* 25 */ - 99, /* 26 */ - 101, /* 27 */ - 103, /* 28 */ - 105, /* 29 */ - 107, /* 30 */ - 109, /* 31 */ - 111, /* 32 */ - 181, /* 33 */ - 188, /* 34 */ - 191, /* 35 */ - 193, /* 36 */ - 195, /* 37 */ - 198, /* 38 */ - 202, /* 39 */ - 234, /* 40 */ - 246, /* 41 */ - 249, /* 42 */ - 260, /* 43 */ - 262, /* 44 */ - 266, /* 45 */ - 303, /* 46 */ - 328, /* 47 */ - 346, /* 48 */ - 369, /* 49 */ - 391, /* 50 */ - 409, /* 51 */ - 428, /* 52 */ - 447, /* 53 */ - 458, /* 54 */ - 474, /* 55 */ - 485, /* 56 */ - 500, /* 57 */ - 514, /* 58 */ - 523, /* 59 */ - 526, /* 60 */ - 528, /* 61 */ - 530, /* 62 */ - 532, /* 63 */ - 537, /* 64 */ - 539, /* 65 */ - 583, /* 66 */ - 609, /* 67 */ - 640, /* 68 */ - 668, /* 69 */ - 713, /* 70 */ - 739, /* 71 */ - 764, /* 72 */ - 783, /* 73 */ - 824, /* 74 */ - 840, /* 75 */ - 866, /* 76 */ - 885, /* 77 */ - 914, /* 78 */ - 936, /* 79 */ - 980, /* 80 */ - 1008, /* 81 */ - 1016, /* 82 */ - 1039, /* 83 */ - 1078, /* 84 */ - 1111, /* 85 */ - 1134, /* 86 */ - 1155, /* 87 */ - 1173, /* 88 */ - 1187, /* 89 */ - 1206, /* 90 */ - 1217, /* 91 */ - 1219, /* 92 */ - 1221, /* 93 */ - 1223, /* 94 */ - 1225, /* 95 */ - 1227, /* 96 */ - 1229, /* 97 */ - 1268, /* 98 */ - 1292, /* 99 */ - 1329, /* 100 */ - 1365, /* 101 */ - 1407, /* 102 */ - 1431, /* 103 */ - 1464, /* 104 */ - 1495, /* 105 */ - 1530, /* 106 */ - 1539, /* 107 */ - 1572, /* 108 */ - 1608, /* 109 */ - 1633, /* 110 */ - 1673, /* 111 */ - 1715, /* 112 */ - 1743, /* 113 */ - 1748, /* 114 */ - 1788, /* 115 */ - 1825, /* 116 */ - 1864, /* 117 */ - 1898, /* 118 */ - 1909, /* 119 */ - 1940, /* 120 */ - 1960, /* 121 */ - 1996, /* 122 */ - 2017, /* 123 */ - 2019, /* 124 */ - 2021, /* 125 */ - 2023, /* 126 */ - 2025, /* 127 */ - 2027 /* 128 */ + 0, /* 0 */ + 51, /* 1 */ + 53, /* 2 */ + 53, /* 3 */ + 55, /* 4 */ + 57, /* 5 */ + 59, /* 6 */ + 61, /* 7 */ + 63, /* 8 */ + 65, /* 9 */ + 67, /* 10 */ + 69, /* 11 */ + 71, /* 12 */ + 73, /* 13 */ + 75, /* 14 */ + 77, /* 15 */ + 79, /* 16 */ + 81, /* 17 */ + 83, /* 18 */ + 85, /* 19 */ + 87, /* 20 */ + 89, /* 21 */ + 91, /* 22 */ + 93, /* 23 */ + 95, /* 24 */ + 97, /* 25 */ + 99, /* 26 */ + 101, /* 27 */ + 103, /* 28 */ + 105, /* 29 */ + 107, /* 30 */ + 109, /* 31 */ + 111, /* 32 */ + 181, /* 33 */ + 188, /* 34 */ + 191, /* 35 */ + 193, /* 36 */ + 195, /* 37 */ + 198, /* 38 */ + 202, /* 39 */ + 234, /* 40 */ + 246, /* 41 */ + 249, /* 42 */ + 260, /* 43 */ + 262, /* 44 */ + 266, /* 45 */ + 303, /* 46 */ + 328, /* 47 */ + 346, /* 48 */ + 369, /* 49 */ + 391, /* 50 */ + 409, /* 51 */ + 428, /* 52 */ + 447, /* 53 */ + 458, /* 54 */ + 474, /* 55 */ + 485, /* 56 */ + 500, /* 57 */ + 514, /* 58 */ + 523, /* 59 */ + 526, /* 60 */ + 528, /* 61 */ + 530, /* 62 */ + 532, /* 63 */ + 537, /* 64 */ + 539, /* 65 */ + 583, /* 66 */ + 609, /* 67 */ + 640, /* 68 */ + 668, /* 69 */ + 713, /* 70 */ + 739, /* 71 */ + 764, /* 72 */ + 783, /* 73 */ + 824, /* 74 */ + 840, /* 75 */ + 866, /* 76 */ + 885, /* 77 */ + 914, /* 78 */ + 936, /* 79 */ + 980, /* 80 */ + 1008, /* 81 */ + 1016, /* 82 */ + 1039, /* 83 */ + 1078, /* 84 */ + 1111, /* 85 */ + 1134, /* 86 */ + 1155, /* 87 */ + 1173, /* 88 */ + 1187, /* 89 */ + 1206, /* 90 */ + 1217, /* 91 */ + 1219, /* 92 */ + 1221, /* 93 */ + 1223, /* 94 */ + 1225, /* 95 */ + 1227, /* 96 */ + 1229, /* 97 */ + 1268, /* 98 */ + 1292, /* 99 */ + 1329, /* 100 */ + 1365, /* 101 */ + 1407, /* 102 */ + 1431, /* 103 */ + 1464, /* 104 */ + 1495, /* 105 */ + 1530, /* 106 */ + 1539, /* 107 */ + 1572, /* 108 */ + 1608, /* 109 */ + 1633, /* 110 */ + 1673, /* 111 */ + 1715, /* 112 */ + 1743, /* 113 */ + 1748, /* 114 */ + 1788, /* 115 */ + 1825, /* 116 */ + 1864, /* 117 */ + 1898, /* 118 */ + 1909, /* 119 */ + 1940, /* 120 */ + 1960, /* 121 */ + 1996, /* 122 */ + 2017, /* 123 */ + 2019, /* 124 */ + 2021, /* 125 */ + 2023, /* 126 */ + 2025, /* 127 */ + 2027 /* 128 */ }; struct fsattab fsat_table_2[] = { - /* 51 */ - { 0x40000000, 3, 65}, /* 0 'A' */ - { 0x80000000, 3, 67}, /* 1 'C' */ - { 0xe0000000, 3, 84}, /* 2 'T' */ - { 0x10000000, 4, 74}, /* 3 'J' */ - { 0x30000000, 4, 68}, /* 4 'D' */ - { 0xa0000000, 4, 83}, /* 5 'S' */ - { 0x00000000, 5, 72}, /* 6 'H' */ - { 0x20000000, 5, 73}, /* 7 'I' */ - { 0x28000000, 5, 82}, /* 8 'R' */ - { 0x68000000, 5, 70}, /* 9 'F' */ - { 0x70000000, 5, 46}, /* 10 '.' */ - { 0x78000000, 5, 87}, /* 11 'W' */ - { 0xb8000000, 5, 77}, /* 12 'M' */ - { 0xc0000000, 5, 66}, /* 13 'B' */ - { 0xc8000000, 5, 80}, /* 14 'P' */ - { 0xd8000000, 5, 78}, /* 15 'N' */ - { 0x08000000, 6, 79}, /* 16 'O' */ - { 0x64000000, 6, 91}, /* 17 '[' */ - { 0xb4000000, 6, 76}, /* 18 'L' */ - { 0xd4000000, 6, 69}, /* 19 'E' */ - { 0x0c000000, 7, 75}, /* 20 'K' */ - { 0xd0000000, 7, 89}, /* 21 'Y' */ - { 0xd2000000, 7, 71}, /* 22 'G' */ - { 0x0e000000, 8, 50}, /* 23 '2' */ - { 0x60000000, 8, 112}, /* 24 'p' */ - { 0x61000000, 8, 98}, /* 25 'b' */ - { 0x62000000, 8, 85}, /* 26 'U' */ - { 0x63000000, 8, 40}, /* 27 '(' */ - { 0xb0000000, 8, 49}, /* 28 '1' */ - { 0xb3000000, 8, 86}, /* 29 'V' */ - { 0x0f000000, 9, 81}, /* 30 'Q' */ - { 0xb1000000, 9, 51}, /* 31 '3' */ - { 0x0f800000, 10, 57}, /* 32 '9' */ - { 0x0fc00000, 10, 56}, /* 33 '8' */ - { 0xb1800000, 10, 54}, /* 34 '6' */ - { 0xb1c00000, 10, 53}, /* 35 '5' */ - { 0xb2000000, 10, 90}, /* 36 'Z' */ - { 0xb2400000, 10, 55}, /* 37 '7' */ - { 0xb2800000, 10, 52}, /* 38 '4' */ - { 0xb2e00000, 12, 88}, /* 39 'X' */ - { 0xb2f00000, 12, 32}, /* 40 ' ' */ - { 0xb2c80000, 13, 119}, /* 41 'w' */ - { 0xb2d00000, 13, 39}, /* 42 '\'' */ - { 0xb2d80000, 13, 34}, /* 43 '\"' */ - { 0xb2c00000, 14, 116}, /* 44 't' */ - { 0xb2c40000, 15, 97}, /* 45 'a' */ - { 0xb2c60000, 16, 96}, /* 46 '`' */ - { 0xb2c70000, 17, 1}, /* 47 '0x01' */ - { 0xb2c78000, 17, 109}, /* 48 'm' */ - { 0x00000000, 1, 1}, /* 49 '0x01' */ - { 0x80000000, 1, 1}, /* 50 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 51 '0x01' */ - { 0x80000000, 1, 1}, /* 52 '0x01' */ - /* 0 */ - /* 2 */ - { 0x00000000, 1, 1}, /* 53 '0x01' */ - { 0x80000000, 1, 1}, /* 54 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 55 '0x01' */ - { 0x80000000, 1, 1}, /* 56 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 57 '0x01' */ - { 0x80000000, 1, 1}, /* 58 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 59 '0x01' */ - { 0x80000000, 1, 1}, /* 60 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 61 '0x01' */ - { 0x80000000, 1, 1}, /* 62 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 63 '0x01' */ - { 0x80000000, 1, 1}, /* 64 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 65 '0x01' */ - { 0x80000000, 1, 1}, /* 66 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 67 '0x01' */ - { 0x80000000, 1, 1}, /* 68 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 69 '0x01' */ - { 0x80000000, 1, 1}, /* 70 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 71 '0x01' */ - { 0x80000000, 1, 1}, /* 72 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 73 '0x01' */ - { 0x80000000, 1, 1}, /* 74 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 75 '0x01' */ - { 0x80000000, 1, 1}, /* 76 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 77 '0x01' */ - { 0x80000000, 1, 1}, /* 78 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 79 '0x01' */ - { 0x80000000, 1, 1}, /* 80 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 81 '0x01' */ - { 0x80000000, 1, 1}, /* 82 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 83 '0x01' */ - { 0x80000000, 1, 1}, /* 84 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 85 '0x01' */ - { 0x80000000, 1, 1}, /* 86 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 87 '0x01' */ - { 0x80000000, 1, 1}, /* 88 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 89 '0x01' */ - { 0x80000000, 1, 1}, /* 90 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 91 '0x01' */ - { 0x80000000, 1, 1}, /* 92 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 93 '0x01' */ - { 0x80000000, 1, 1}, /* 94 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 95 '0x01' */ - { 0x80000000, 1, 1}, /* 96 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 97 '0x01' */ - { 0x80000000, 1, 1}, /* 98 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 99 '0x01' */ - { 0x80000000, 1, 1}, /* 100 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 101 '0x01' */ - { 0x80000000, 1, 1}, /* 102 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 103 '0x01' */ - { 0x80000000, 1, 1}, /* 104 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 105 '0x01' */ - { 0x80000000, 1, 1}, /* 106 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 107 '0x01' */ - { 0x80000000, 1, 1}, /* 108 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 109 '0x01' */ - { 0x80000000, 1, 1}, /* 110 '0x01' */ - /* 80 */ - { 0x40000000, 3, 97}, /* 111 'a' */ - { 0x80000000, 3, 116}, /* 112 't' */ - { 0x10000000, 4, 111}, /* 113 'o' */ - { 0x20000000, 4, 115}, /* 114 's' */ - { 0x30000000, 5, 100}, /* 115 'd' */ - { 0x60000000, 5, 91}, /* 116 '[' */ - { 0x78000000, 5, 112}, /* 117 'p' */ - { 0xa8000000, 5, 98}, /* 118 'b' */ - { 0xc8000000, 5, 99}, /* 119 'c' */ - { 0xd0000000, 5, 104}, /* 120 'h' */ - { 0xe0000000, 5, 119}, /* 121 'w' */ - { 0xe8000000, 5, 105}, /* 122 'i' */ - { 0xf8000000, 5, 102}, /* 123 'f' */ - { 0x00000000, 6, 65}, /* 124 'A' */ - { 0x0c000000, 6, 77}, /* 125 'M' */ - { 0x3c000000, 6, 101}, /* 126 'e' */ - { 0x70000000, 6, 66}, /* 127 'B' */ - { 0x74000000, 6, 67}, /* 128 'C' */ - { 0xa0000000, 6, 84}, /* 129 'T' */ - { 0xb4000000, 6, 83}, /* 130 'S' */ - { 0xb8000000, 6, 103}, /* 131 'g' */ - { 0xc0000000, 6, 114}, /* 132 'r' */ - { 0xd8000000, 6, 110}, /* 133 'n' */ - { 0xdc000000, 6, 108}, /* 134 'l' */ - { 0xf4000000, 6, 109}, /* 135 'm' */ - { 0x06000000, 7, 118}, /* 136 'v' */ - { 0x08000000, 7, 71}, /* 137 'G' */ - { 0x0a000000, 7, 78}, /* 138 'N' */ - { 0x3a000000, 7, 121}, /* 139 'y' */ - { 0x6a000000, 7, 72}, /* 140 'H' */ - { 0x6e000000, 7, 76}, /* 141 'L' */ - { 0xa4000000, 7, 74}, /* 142 'J' */ - { 0xa6000000, 7, 70}, /* 143 'F' */ - { 0xb2000000, 7, 82}, /* 144 'R' */ - { 0xbc000000, 7, 117}, /* 145 'u' */ - { 0xc4000000, 7, 68}, /* 146 'D' */ - { 0xc6000000, 7, 87}, /* 147 'W' */ - { 0xf2000000, 7, 80}, /* 148 'P' */ - { 0x04000000, 8, 107}, /* 149 'k' */ - { 0x05000000, 8, 79}, /* 150 'O' */ - { 0x68000000, 8, 45}, /* 151 '-' */ - { 0x6d000000, 8, 49}, /* 152 '1' */ - { 0xb1000000, 8, 75}, /* 153 'K' */ - { 0xbe000000, 8, 106}, /* 154 'j' */ - { 0xf0000000, 8, 73}, /* 155 'I' */ - { 0xf1000000, 8, 69}, /* 156 'E' */ - { 0x39000000, 9, 113}, /* 157 'q' */ - { 0x39800000, 9, 85}, /* 158 'U' */ - { 0x69000000, 9, 86}, /* 159 'V' */ - { 0x6c000000, 9, 89}, /* 160 'Y' */ - { 0x6c800000, 9, 32}, /* 161 ' ' */ - { 0xb0800000, 9, 50}, /* 162 '2' */ - { 0xbf000000, 9, 0}, /* 163 '0x00' */ - { 0x38000000, 10, 51}, /* 164 '3' */ - { 0x38400000, 10, 56}, /* 165 '8' */ - { 0x38800000, 10, 54}, /* 166 '6' */ - { 0x69c00000, 10, 53}, /* 167 '5' */ - { 0xb0000000, 10, 40}, /* 168 '(' */ - { 0xbf800000, 10, 55}, /* 169 '7' */ - { 0x38c00000, 11, 48}, /* 170 '0' */ - { 0x69800000, 11, 39}, /* 171 '\'' */ - { 0x69a00000, 11, 57}, /* 172 '9' */ - { 0xb0400000, 11, 90}, /* 173 'Z' */ - { 0xbfc00000, 11, 52}, /* 174 '4' */ - { 0xbfe00000, 11, 81}, /* 175 'Q' */ - { 0x38f00000, 12, 88}, /* 176 'X' */ - { 0xb0600000, 13, 1}, /* 177 '0x01' */ - { 0xb0680000, 13, 46}, /* 178 '.' */ - { 0xb0700000, 13, 38}, /* 179 '&' */ - { 0x38e00000, 14, 92}, /* 180 '\\' */ - { 0x38e80000, 14, 64}, /* 181 '@' */ - { 0x38ec0000, 14, 96}, /* 182 '`' */ - { 0xb0780000, 14, 34}, /* 183 '\"' */ - { 0xb07c0000, 14, 122}, /* 184 'z' */ - { 0x38e60000, 15, 36}, /* 185 '$' */ - { 0x38e40000, 16, 43}, /* 186 '+' */ - { 0x38e58000, 17, 120}, /* 187 'x' */ - { 0x38e54000, 18, 93}, /* 188 ']' */ - { 0x38e50000, 19, 47}, /* 189 '/' */ - { 0x38e52000, 19, 63}, /* 190 '?' */ - /* 13 */ - { 0x80000000, 1, 32}, /* 191 ' ' */ - { 0x40000000, 2, 0}, /* 192 '0x00' */ - { 0x20000000, 3, 46}, /* 193 '.' */ - { 0x00000000, 4, 58}, /* 194 ':' */ - { 0x18000000, 5, 91}, /* 195 '[' */ - { 0x12000000, 7, 34}, /* 196 '\"' */ - { 0x14000000, 7, 47}, /* 197 '/' */ - { 0x16000000, 7, 33}, /* 198 '!' */ - { 0x10000000, 8, 41}, /* 199 ')' */ - { 0x11000000, 9, 39}, /* 200 '\'' */ - { 0x11c00000, 10, 63}, /* 201 '?' */ - { 0x11800000, 11, 1}, /* 202 '0x01' */ - { 0x11a00000, 11, 93}, /* 203 ']' */ - /* 36 */ - { 0xc0000000, 2, 32}, /* 204 ' ' */ - { 0x20000000, 3, 46}, /* 205 '.' */ - { 0x00000000, 4, 112}, /* 206 'p' */ - { 0x50000000, 4, 66}, /* 207 'B' */ - { 0x70000000, 4, 84}, /* 208 'T' */ - { 0x80000000, 4, 105}, /* 209 'i' */ - { 0x10000000, 5, 102}, /* 210 'f' */ - { 0x18000000, 5, 87}, /* 211 'W' */ - { 0x40000000, 5, 83}, /* 212 'S' */ - { 0x60000000, 5, 116}, /* 213 't' */ - { 0x68000000, 5, 67}, /* 214 'C' */ - { 0xa0000000, 5, 0}, /* 215 '0x00' */ - { 0xb8000000, 5, 44}, /* 216 ',' */ - { 0x48000000, 6, 74}, /* 217 'J' */ - { 0x90000000, 6, 109}, /* 218 'm' */ - { 0xa8000000, 6, 110}, /* 219 'n' */ - { 0xac000000, 6, 73}, /* 220 'I' */ - { 0x4c000000, 7, 69}, /* 221 'E' */ - { 0x4e000000, 7, 68}, /* 222 'D' */ - { 0x94000000, 7, 119}, /* 223 'w' */ - { 0x96000000, 7, 103}, /* 224 'g' */ - { 0x98000000, 7, 98}, /* 225 'b' */ - { 0x9a000000, 7, 76}, /* 226 'L' */ - { 0x9c000000, 7, 45}, /* 227 '-' */ - { 0xb0000000, 7, 99}, /* 228 'c' */ - { 0xb2000000, 7, 72}, /* 229 'H' */ - { 0x9e000000, 8, 80}, /* 230 'P' */ - { 0xb4000000, 8, 114}, /* 231 'r' */ - { 0xb7000000, 8, 75}, /* 232 'K' */ - { 0x9f800000, 9, 108}, /* 233 'l' */ - { 0xb5000000, 9, 89}, /* 234 'Y' */ - { 0xb5800000, 9, 81}, /* 235 'Q' */ - { 0xb6000000, 9, 71}, /* 236 'G' */ - { 0xb6800000, 9, 65}, /* 237 'A' */ - { 0x9f000000, 10, 1}, /* 238 '0x01' */ - { 0x9f400000, 10, 97}, /* 239 'a' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 240 '0x01' */ - { 0x80000000, 1, 1}, /* 241 '0x01' */ - /* 8 */ - { 0x00000000, 1, 49}, /* 242 '1' */ - { 0xc0000000, 2, 51}, /* 243 '3' */ - { 0x80000000, 3, 52}, /* 244 '4' */ - { 0xb0000000, 4, 50}, /* 245 '2' */ - { 0xa8000000, 5, 55}, /* 246 '7' */ - { 0xa4000000, 6, 53}, /* 247 '5' */ - { 0xa0000000, 7, 1}, /* 248 '0x01' */ - { 0xa2000000, 7, 57}, /* 249 '9' */ - /* 3 */ - { 0x80000000, 1, 32}, /* 250 ' ' */ - { 0x00000000, 2, 1}, /* 251 '0x01' */ - { 0x40000000, 2, 44}, /* 252 ',' */ - /* 12 */ - { 0x80000000, 1, 32}, /* 253 ' ' */ - { 0x40000000, 2, 119}, /* 254 'w' */ - { 0x20000000, 3, 66}, /* 255 'B' */ - { 0x00000000, 4, 69}, /* 256 'E' */ - { 0x10000000, 6, 50}, /* 257 '2' */ - { 0x18000000, 6, 65}, /* 258 'A' */ - { 0x1c000000, 6, 82}, /* 259 'R' */ - { 0x14000000, 8, 79}, /* 260 'O' */ - { 0x15000000, 8, 52}, /* 261 '4' */ - { 0x17000000, 8, 74}, /* 262 'J' */ - { 0x16000000, 9, 1}, /* 263 '0x01' */ - { 0x16800000, 9, 80}, /* 264 'P' */ - /* 71 */ - { 0x80000000, 1, 115}, /* 265 's' */ - { 0x20000000, 3, 116}, /* 266 't' */ - { 0x40000000, 3, 32}, /* 267 ' ' */ - { 0x00000000, 4, 108}, /* 268 'l' */ - { 0x68000000, 5, 114}, /* 269 'r' */ - { 0x10000000, 6, 110}, /* 270 'n' */ - { 0x14000000, 6, 46}, /* 271 '.' */ - { 0x18000000, 6, 67}, /* 272 'C' */ - { 0x60000000, 6, 66}, /* 273 'B' */ - { 0x74000000, 6, 65}, /* 274 'A' */ - { 0x70000000, 7, 100}, /* 275 'd' */ - { 0x78000000, 7, 118}, /* 276 'v' */ - { 0x1c000000, 8, 83}, /* 277 'S' */ - { 0x1f000000, 8, 112}, /* 278 'p' */ - { 0x65000000, 8, 68}, /* 279 'D' */ - { 0x7b000000, 8, 105}, /* 280 'i' */ - { 0x7c000000, 8, 99}, /* 281 'c' */ - { 0x7d000000, 8, 109}, /* 282 'm' */ - { 0x7f000000, 8, 44}, /* 283 ',' */ - { 0x1d000000, 9, 102}, /* 284 'f' */ - { 0x1d800000, 9, 103}, /* 285 'g' */ - { 0x64000000, 9, 70}, /* 286 'F' */ - { 0x64800000, 9, 104}, /* 287 'h' */ - { 0x66800000, 9, 72}, /* 288 'H' */ - { 0x67000000, 9, 78}, /* 289 'N' */ - { 0x72800000, 9, 82}, /* 290 'R' */ - { 0x73000000, 9, 0}, /* 291 '0x00' */ - { 0x73800000, 9, 84}, /* 292 'T' */ - { 0x7a800000, 9, 71}, /* 293 'G' */ - { 0x7e800000, 9, 76}, /* 294 'L' */ - { 0x1e000000, 10, 111}, /* 295 'o' */ - { 0x1e400000, 10, 75}, /* 296 'K' */ - { 0x1ec00000, 10, 97}, /* 297 'a' */ - { 0x66400000, 10, 117}, /* 298 'u' */ - { 0x67c00000, 10, 79}, /* 299 'O' */ - { 0x72400000, 10, 73}, /* 300 'I' */ - { 0x7a000000, 10, 119}, /* 301 'w' */ - { 0x7a400000, 10, 98}, /* 302 'b' */ - { 0x7e400000, 10, 101}, /* 303 'e' */ - { 0x1ea00000, 11, 63}, /* 304 '?' */ - { 0x66000000, 11, 69}, /* 305 'E' */ - { 0x66200000, 11, 55}, /* 306 '7' */ - { 0x72000000, 11, 80}, /* 307 'P' */ - { 0x1e900000, 12, 87}, /* 308 'W' */ - { 0x67900000, 12, 58}, /* 309 ':' */ - { 0x67a00000, 12, 33}, /* 310 '!' */ - { 0x72300000, 12, 74}, /* 311 'J' */ - { 0x7e100000, 12, 113}, /* 312 'q' */ - { 0x7e300000, 12, 77}, /* 313 'M' */ - { 0x1e880000, 13, 86}, /* 314 'V' */ - { 0x67880000, 13, 57}, /* 315 '9' */ - { 0x67b80000, 13, 121}, /* 316 'y' */ - { 0x72200000, 13, 56}, /* 317 '8' */ - { 0x72280000, 13, 53}, /* 318 '5' */ - { 0x7e000000, 13, 54}, /* 319 '6' */ - { 0x7e280000, 13, 107}, /* 320 'k' */ - { 0x1e800000, 14, 50}, /* 321 '2' */ - { 0x1e840000, 14, 48}, /* 322 '0' */ - { 0x67840000, 14, 89}, /* 323 'Y' */ - { 0x67b00000, 14, 41}, /* 324 ')' */ - { 0x7e080000, 14, 106}, /* 325 'j' */ - { 0x7e0c0000, 14, 81}, /* 326 'Q' */ - { 0x67800000, 15, 45}, /* 327 '-' */ - { 0x67820000, 15, 39}, /* 328 '\'' */ - { 0x67b60000, 15, 122}, /* 329 'z' */ - { 0x7e200000, 15, 88}, /* 330 'X' */ - { 0x7e220000, 15, 85}, /* 331 'U' */ - { 0x7e240000, 15, 52}, /* 332 '4' */ - { 0x7e260000, 15, 51}, /* 333 '3' */ - { 0x67b40000, 16, 1}, /* 334 '0x01' */ - { 0x67b50000, 16, 49}, /* 335 '1' */ - /* 55 */ - { 0x40000000, 2, 49}, /* 336 '1' */ - { 0x00000000, 3, 80}, /* 337 'P' */ - { 0xa0000000, 3, 116}, /* 338 't' */ - { 0x80000000, 4, 50}, /* 339 '2' */ - { 0xd0000000, 4, 53}, /* 340 '5' */ - { 0xe0000000, 4, 78}, /* 341 'N' */ - { 0x38000000, 5, 84}, /* 342 'T' */ - { 0x90000000, 5, 112}, /* 343 'p' */ - { 0xf8000000, 5, 99}, /* 344 'c' */ - { 0x24000000, 6, 97}, /* 345 'a' */ - { 0x28000000, 6, 83}, /* 346 'S' */ - { 0x30000000, 6, 82}, /* 347 'R' */ - { 0x9c000000, 6, 101}, /* 348 'e' */ - { 0xf0000000, 6, 74}, /* 349 'J' */ - { 0xf4000000, 6, 65}, /* 350 'A' */ - { 0x2c000000, 7, 68}, /* 351 'D' */ - { 0x36000000, 7, 75}, /* 352 'K' */ - { 0x98000000, 7, 118}, /* 353 'v' */ - { 0x9a000000, 7, 115}, /* 354 's' */ - { 0xc0000000, 7, 98}, /* 355 'b' */ - { 0xc4000000, 7, 71}, /* 356 'G' */ - { 0xc6000000, 7, 56}, /* 357 '8' */ - { 0xc8000000, 7, 77}, /* 358 'M' */ - { 0xca000000, 7, 72}, /* 359 'H' */ - { 0xcc000000, 7, 67}, /* 360 'C' */ - { 0x20000000, 8, 109}, /* 361 'm' */ - { 0x22000000, 8, 111}, /* 362 'o' */ - { 0x23000000, 8, 69}, /* 363 'E' */ - { 0x2e000000, 8, 87}, /* 364 'W' */ - { 0xc3000000, 8, 103}, /* 365 'g' */ - { 0xce000000, 8, 76}, /* 366 'L' */ - { 0x21000000, 9, 100}, /* 367 'd' */ - { 0x2f800000, 9, 85}, /* 368 'U' */ - { 0x34000000, 9, 70}, /* 369 'F' */ - { 0x35000000, 9, 102}, /* 370 'f' */ - { 0xc2000000, 9, 119}, /* 371 'w' */ - { 0xc2800000, 9, 66}, /* 372 'B' */ - { 0xcf800000, 9, 110}, /* 373 'n' */ - { 0x21800000, 10, 108}, /* 374 'l' */ - { 0x21c00000, 10, 57}, /* 375 '9' */ - { 0x2f000000, 10, 52}, /* 376 '4' */ - { 0x2f400000, 10, 73}, /* 377 'I' */ - { 0x34800000, 10, 51}, /* 378 '3' */ - { 0x35c00000, 10, 104}, /* 379 'h' */ - { 0xcf400000, 10, 105}, /* 380 'i' */ - { 0x34c00000, 11, 90}, /* 381 'Z' */ - { 0x34e00000, 11, 86}, /* 382 'V' */ - { 0x35800000, 11, 32}, /* 383 ' ' */ - { 0xcf000000, 11, 107}, /* 384 'k' */ - { 0x35b00000, 12, 79}, /* 385 'O' */ - { 0xcf200000, 12, 39}, /* 386 '\'' */ - { 0x35a00000, 13, 1}, /* 387 '0x01' */ - { 0x35a80000, 13, 117}, /* 388 'u' */ - { 0xcf300000, 13, 88}, /* 389 'X' */ - { 0xcf380000, 13, 55}, /* 390 '7' */ - /* 12 */ - { 0x00000000, 1, 32}, /* 391 ' ' */ - { 0xc0000000, 2, 46}, /* 392 '.' */ - { 0xa0000000, 3, 0}, /* 393 '0x00' */ - { 0x90000000, 4, 44}, /* 394 ',' */ - { 0x80000000, 5, 58}, /* 395 ':' */ - { 0x8c000000, 6, 59}, /* 396 ';' */ - { 0x8a000000, 7, 33}, /* 397 '!' */ - { 0x89000000, 8, 40}, /* 398 '(' */ - { 0x88000000, 10, 1}, /* 399 '0x01' */ - { 0x88400000, 10, 111}, /* 400 'o' */ - { 0x88800000, 10, 63}, /* 401 '?' */ - { 0x88c00000, 10, 41}, /* 402 ')' */ - /* 13 */ - { 0x00000000, 1, 42}, /* 403 '*' */ - { 0x80000000, 3, 115}, /* 404 's' */ - { 0xa0000000, 3, 32}, /* 405 ' ' */ - { 0xc0000000, 4, 109}, /* 406 'm' */ - { 0xe0000000, 4, 116}, /* 407 't' */ - { 0xd0000000, 5, 103}, /* 408 'g' */ - { 0xd8000000, 5, 107}, /* 409 'k' */ - { 0xf8000000, 5, 100}, /* 410 'd' */ - { 0xf4000000, 6, 121}, /* 411 'y' */ - { 0xf2000000, 7, 101}, /* 412 'e' */ - { 0xf0000000, 8, 105}, /* 413 'i' */ - { 0xf1000000, 9, 1}, /* 414 '0x01' */ - { 0xf1800000, 9, 110}, /* 415 'n' */ - /* 3 */ - { 0x80000000, 1, 110}, /* 416 'n' */ - { 0x00000000, 2, 1}, /* 417 '0x01' */ - { 0x40000000, 2, 32}, /* 418 ' ' */ - /* 20 */ - { 0x80000000, 1, 32}, /* 419 ' ' */ - { 0x40000000, 2, 83}, /* 420 'S' */ - { 0x20000000, 3, 48}, /* 421 '0' */ - { 0x10000000, 4, 65}, /* 422 'A' */ - { 0x00000000, 5, 53}, /* 423 '5' */ - { 0x0c000000, 7, 98}, /* 424 'b' */ - { 0x0e000000, 7, 51}, /* 425 '3' */ - { 0x08000000, 8, 50}, /* 426 '2' */ - { 0x09000000, 8, 34}, /* 427 '\"' */ - { 0x0b000000, 8, 49}, /* 428 '1' */ - { 0x0a000000, 10, 81}, /* 429 'Q' */ - { 0x0a800000, 10, 39}, /* 430 '\'' */ - { 0x0ae00000, 11, 52}, /* 431 '4' */ - { 0x0a400000, 12, 84}, /* 432 'T' */ - { 0x0a500000, 12, 66}, /* 433 'B' */ - { 0x0a600000, 12, 55}, /* 434 '7' */ - { 0x0a700000, 12, 54}, /* 435 '6' */ - { 0x0ac00000, 12, 0}, /* 436 '0x00' */ - { 0x0ad00000, 13, 1}, /* 437 '0x01' */ - { 0x0ad80000, 13, 105}, /* 438 'i' */ - /* 64 */ - { 0x00000000, 2, 32}, /* 439 ' ' */ - { 0x40000000, 4, 116}, /* 440 't' */ - { 0x50000000, 4, 98}, /* 441 'b' */ - { 0x60000000, 4, 119}, /* 442 'w' */ - { 0x70000000, 4, 117}, /* 443 'u' */ - { 0x90000000, 4, 111}, /* 444 'o' */ - { 0xa0000000, 4, 115}, /* 445 's' */ - { 0xb0000000, 4, 102}, /* 446 'f' */ - { 0x80000000, 5, 99}, /* 447 'c' */ - { 0xd8000000, 5, 108}, /* 448 'l' */ - { 0xe8000000, 5, 100}, /* 449 'd' */ - { 0x88000000, 6, 57}, /* 450 '9' */ - { 0xc0000000, 6, 104}, /* 451 'h' */ - { 0xc8000000, 6, 49}, /* 452 '1' */ - { 0xcc000000, 6, 121}, /* 453 'y' */ - { 0xd4000000, 6, 114}, /* 454 'r' */ - { 0xe0000000, 6, 97}, /* 455 'a' */ - { 0xf0000000, 6, 109}, /* 456 'm' */ - { 0xf8000000, 6, 112}, /* 457 'p' */ - { 0x8c000000, 7, 83}, /* 458 'S' */ - { 0xd0000000, 7, 101}, /* 459 'e' */ - { 0xd2000000, 7, 105}, /* 460 'i' */ - { 0xf6000000, 7, 110}, /* 461 'n' */ - { 0x8e000000, 8, 67}, /* 462 'C' */ - { 0xc5000000, 8, 87}, /* 463 'W' */ - { 0xc7000000, 8, 103}, /* 464 'g' */ - { 0xe5000000, 8, 74}, /* 465 'J' */ - { 0xe6000000, 8, 68}, /* 466 'D' */ - { 0xf5000000, 8, 50}, /* 467 '2' */ - { 0xfc000000, 8, 55}, /* 468 '7' */ - { 0xfe000000, 8, 71}, /* 469 'G' */ - { 0xff000000, 8, 79}, /* 470 'O' */ - { 0x8f800000, 9, 72}, /* 471 'H' */ - { 0xc4000000, 9, 65}, /* 472 'A' */ - { 0xc6000000, 9, 54}, /* 473 '6' */ - { 0xc6800000, 9, 66}, /* 474 'B' */ - { 0xe7800000, 9, 77}, /* 475 'M' */ - { 0xf4000000, 9, 69}, /* 476 'E' */ - { 0xf4800000, 9, 76}, /* 477 'L' */ - { 0xfd000000, 9, 85}, /* 478 'U' */ - { 0xfd800000, 9, 107}, /* 479 'k' */ - { 0x8f000000, 10, 70}, /* 480 'F' */ - { 0xc4800000, 10, 106}, /* 481 'j' */ - { 0xc4c00000, 10, 80}, /* 482 'P' */ - { 0xe4400000, 10, 113}, /* 483 'q' */ - { 0xe4800000, 10, 53}, /* 484 '5' */ - { 0xe4c00000, 10, 84}, /* 485 'T' */ - { 0xe7400000, 10, 73}, /* 486 'I' */ - { 0x8f600000, 11, 75}, /* 487 'K' */ - { 0xe4000000, 11, 118}, /* 488 'v' */ - { 0xe4200000, 11, 90}, /* 489 'Z' */ - { 0xe7200000, 11, 78}, /* 490 'N' */ - { 0x8f500000, 12, 82}, /* 491 'R' */ - { 0xe7100000, 12, 89}, /* 492 'Y' */ - { 0x8f480000, 13, 48}, /* 493 '0' */ - { 0x8f400000, 14, 52}, /* 494 '4' */ - { 0x8f440000, 14, 122}, /* 495 'z' */ - { 0xe7040000, 14, 86}, /* 496 'V' */ - { 0xe7080000, 14, 51}, /* 497 '3' */ - { 0xe70c0000, 14, 56}, /* 498 '8' */ - { 0xe7020000, 15, 81}, /* 499 'Q' */ - { 0xe7000000, 16, 39}, /* 500 '\'' */ - { 0xe7010000, 17, 1}, /* 501 '0x01' */ - { 0xe7018000, 17, 120}, /* 502 'x' */ - /* 65 */ - { 0x80000000, 1, 32}, /* 503 ' ' */ - { 0x40000000, 2, 0}, /* 504 '0x00' */ - { 0x30000000, 4, 46}, /* 505 '.' */ - { 0x10000000, 5, 105}, /* 506 'i' */ - { 0x20000000, 5, 48}, /* 507 '0' */ - { 0x28000000, 5, 99}, /* 508 'c' */ - { 0x04000000, 6, 117}, /* 509 'u' */ - { 0x00000000, 7, 97}, /* 510 'a' */ - { 0x02000000, 7, 91}, /* 511 '[' */ - { 0x1a000000, 7, 51}, /* 512 '3' */ - { 0x08000000, 8, 52}, /* 513 '4' */ - { 0x0e000000, 8, 72}, /* 514 'H' */ - { 0x18000000, 8, 83}, /* 515 'S' */ - { 0x19000000, 8, 87}, /* 516 'W' */ - { 0x1c000000, 8, 111}, /* 517 'o' */ - { 0x1e000000, 8, 49}, /* 518 '1' */ - { 0x0a000000, 9, 53}, /* 519 '5' */ - { 0x0a800000, 9, 76}, /* 520 'L' */ - { 0x0b800000, 9, 112}, /* 521 'p' */ - { 0x0c000000, 9, 84}, /* 522 'T' */ - { 0x0c800000, 9, 65}, /* 523 'A' */ - { 0x0d000000, 9, 77}, /* 524 'M' */ - { 0x0f000000, 9, 67}, /* 525 'C' */ - { 0x0f800000, 9, 50}, /* 526 '2' */ - { 0x1d800000, 9, 68}, /* 527 'D' */ - { 0x1f000000, 9, 66}, /* 528 'B' */ - { 0x09000000, 10, 78}, /* 529 'N' */ - { 0x09800000, 10, 116}, /* 530 't' */ - { 0x09c00000, 10, 74}, /* 531 'J' */ - { 0x0b400000, 10, 82}, /* 532 'R' */ - { 0x0dc00000, 10, 80}, /* 533 'P' */ - { 0x1d400000, 10, 115}, /* 534 's' */ - { 0x1fc00000, 10, 73}, /* 535 'I' */ - { 0x0b000000, 11, 114}, /* 536 'r' */ - { 0x0d800000, 11, 86}, /* 537 'V' */ - { 0x1d000000, 11, 119}, /* 538 'w' */ - { 0x1d200000, 11, 70}, /* 539 'F' */ - { 0x1fa00000, 11, 71}, /* 540 'G' */ - { 0x09400000, 12, 69}, /* 541 'E' */ - { 0x09500000, 12, 58}, /* 542 ':' */ - { 0x0b200000, 12, 104}, /* 543 'h' */ - { 0x0da00000, 12, 44}, /* 544 ',' */ - { 0x1f800000, 12, 39}, /* 545 '\'' */ - { 0x09680000, 13, 98}, /* 546 'b' */ - { 0x09700000, 13, 75}, /* 547 'K' */ - { 0x09780000, 13, 89}, /* 548 'Y' */ - { 0x0b380000, 13, 79}, /* 549 'O' */ - { 0x0db00000, 13, 45}, /* 550 '-' */ - { 0x1f900000, 13, 102}, /* 551 'f' */ - { 0x1f980000, 13, 40}, /* 552 '(' */ - { 0x0b300000, 14, 34}, /* 553 '\"' */ - { 0x0db80000, 14, 121}, /* 554 'y' */ - { 0x09600000, 15, 63}, /* 555 '?' */ - { 0x09620000, 15, 109}, /* 556 'm' */ - { 0x09640000, 15, 81}, /* 557 'Q' */ - { 0x0dbc0000, 15, 42}, /* 558 '*' */ - { 0x0dbe0000, 15, 38}, /* 559 '&' */ - { 0x09660000, 16, 85}, /* 560 'U' */ - { 0x09670000, 16, 59}, /* 561 ';' */ - { 0x0b340000, 16, 56}, /* 562 '8' */ - { 0x0b350000, 16, 54}, /* 563 '6' */ - { 0x0b370000, 16, 107}, /* 564 'k' */ - { 0x0b360000, 17, 100}, /* 565 'd' */ - { 0x0b368000, 18, 1}, /* 566 '0x01' */ - { 0x0b36c000, 18, 110}, /* 567 'n' */ - /* 51 */ - { 0x40000000, 2, 99}, /* 568 'c' */ - { 0xc0000000, 3, 49}, /* 569 '1' */ - { 0xe0000000, 3, 101}, /* 570 'e' */ - { 0x00000000, 4, 53}, /* 571 '5' */ - { 0x20000000, 4, 56}, /* 572 '8' */ - { 0x10000000, 5, 84}, /* 573 'T' */ - { 0x18000000, 5, 102}, /* 574 'f' */ - { 0x30000000, 5, 66}, /* 575 'B' */ - { 0x38000000, 5, 50}, /* 576 '2' */ - { 0x88000000, 5, 51}, /* 577 '3' */ - { 0x90000000, 5, 55}, /* 578 '7' */ - { 0xa0000000, 5, 54}, /* 579 '6' */ - { 0xb0000000, 5, 97}, /* 580 'a' */ - { 0xbc000000, 6, 52}, /* 581 '4' */ - { 0x80000000, 7, 70}, /* 582 'F' */ - { 0x84000000, 7, 115}, /* 583 's' */ - { 0x86000000, 7, 77}, /* 584 'M' */ - { 0x98000000, 7, 72}, /* 585 'H' */ - { 0x9c000000, 7, 68}, /* 586 'D' */ - { 0x9e000000, 7, 65}, /* 587 'A' */ - { 0xaa000000, 7, 83}, /* 588 'S' */ - { 0x83000000, 8, 109}, /* 589 'm' */ - { 0x9a000000, 8, 87}, /* 590 'W' */ - { 0xa8000000, 8, 71}, /* 591 'G' */ - { 0xa9000000, 8, 85}, /* 592 'U' */ - { 0xac000000, 8, 100}, /* 593 'd' */ - { 0xad000000, 8, 79}, /* 594 'O' */ - { 0xae000000, 8, 78}, /* 595 'N' */ - { 0xb9000000, 8, 67}, /* 596 'C' */ - { 0xbb000000, 8, 80}, /* 597 'P' */ - { 0x9b000000, 9, 76}, /* 598 'L' */ - { 0xaf000000, 9, 32}, /* 599 ' ' */ - { 0xaf800000, 9, 73}, /* 600 'I' */ - { 0xb8000000, 9, 69}, /* 601 'E' */ - { 0xb8800000, 9, 82}, /* 602 'R' */ - { 0xba000000, 9, 75}, /* 603 'K' */ - { 0xba800000, 9, 116}, /* 604 't' */ - { 0x82400000, 10, 74}, /* 605 'J' */ - { 0x82c00000, 10, 57}, /* 606 '9' */ - { 0x82000000, 11, 118}, /* 607 'v' */ - { 0x82200000, 11, 112}, /* 608 'p' */ - { 0x82800000, 11, 104}, /* 609 'h' */ - { 0x9ba00000, 11, 111}, /* 610 'o' */ - { 0x9bc00000, 11, 81}, /* 611 'Q' */ - { 0x9be00000, 11, 48}, /* 612 '0' */ - { 0x82a00000, 12, 108}, /* 613 'l' */ - { 0x82b00000, 12, 105}, /* 614 'i' */ - { 0x9b800000, 12, 86}, /* 615 'V' */ - { 0x9b980000, 13, 121}, /* 616 'y' */ - { 0x9b900000, 14, 1}, /* 617 '0x01' */ - { 0x9b940000, 14, 103}, /* 618 'g' */ - /* 35 */ - { 0x00000000, 1, 48}, /* 619 '0' */ - { 0xe0000000, 3, 32}, /* 620 ' ' */ - { 0x90000000, 4, 97}, /* 621 'a' */ - { 0xb0000000, 4, 112}, /* 622 'p' */ - { 0x88000000, 5, 115}, /* 623 's' */ - { 0xc0000000, 5, 46}, /* 624 '.' */ - { 0xc8000000, 5, 56}, /* 625 '8' */ - { 0xd8000000, 5, 44}, /* 626 ',' */ - { 0x80000000, 6, 52}, /* 627 '4' */ - { 0x84000000, 6, 116}, /* 628 't' */ - { 0xa4000000, 6, 53}, /* 629 '5' */ - { 0xd0000000, 6, 54}, /* 630 '6' */ - { 0xa0000000, 7, 51}, /* 631 '3' */ - { 0xa2000000, 7, 55}, /* 632 '7' */ - { 0xaa000000, 7, 93}, /* 633 ']' */ - { 0xac000000, 7, 45}, /* 634 '-' */ - { 0xae000000, 7, 49}, /* 635 '1' */ - { 0xa8000000, 8, 41}, /* 636 ')' */ - { 0xa9000000, 8, 47}, /* 637 '/' */ - { 0xd4000000, 8, 0}, /* 638 '0x00' */ - { 0xd5000000, 8, 57}, /* 639 '9' */ - { 0xd7000000, 8, 50}, /* 640 '2' */ - { 0xd6000000, 9, 37}, /* 641 '%' */ - { 0xd6800000, 10, 58}, /* 642 ':' */ - { 0xd6d00000, 12, 102}, /* 643 'f' */ - { 0xd6f00000, 12, 109}, /* 644 'm' */ - { 0xd6e00000, 13, 121}, /* 645 'y' */ - { 0xd6c40000, 14, 108}, /* 646 'l' */ - { 0xd6c80000, 14, 59}, /* 647 ';' */ - { 0xd6cc0000, 14, 39}, /* 648 '\'' */ - { 0xd6e80000, 14, 107}, /* 649 'k' */ - { 0xd6ec0000, 14, 33}, /* 650 '!' */ - { 0xd6c00000, 15, 67}, /* 651 'C' */ - { 0xd6c20000, 16, 1}, /* 652 '0x01' */ - { 0xd6c30000, 16, 74}, /* 653 'J' */ - /* 38 */ - { 0x00000000, 2, 57}, /* 654 '9' */ - { 0x80000000, 3, 49}, /* 655 '1' */ - { 0xe0000000, 3, 48}, /* 656 '0' */ - { 0x50000000, 4, 32}, /* 657 ' ' */ - { 0x70000000, 4, 50}, /* 658 '2' */ - { 0xb0000000, 4, 46}, /* 659 '.' */ - { 0xc0000000, 4, 53}, /* 660 '5' */ - { 0x40000000, 5, 54}, /* 661 '6' */ - { 0x48000000, 5, 56}, /* 662 '8' */ - { 0x68000000, 5, 47}, /* 663 '/' */ - { 0xa0000000, 5, 93}, /* 664 ']' */ - { 0xd0000000, 5, 51}, /* 665 '3' */ - { 0x64000000, 6, 55}, /* 666 '7' */ - { 0xd8000000, 6, 52}, /* 667 '4' */ - { 0x60000000, 7, 0}, /* 668 '0x00' */ - { 0x62000000, 7, 45}, /* 669 '-' */ - { 0xa8000000, 7, 41}, /* 670 ')' */ - { 0xac000000, 7, 58}, /* 671 ':' */ - { 0xae000000, 7, 115}, /* 672 's' */ - { 0xdc000000, 7, 44}, /* 673 ',' */ - { 0xde000000, 7, 120}, /* 674 'x' */ - { 0xaa000000, 8, 39}, /* 675 '\'' */ - { 0xab000000, 9, 88}, /* 676 'X' */ - { 0xabc00000, 11, 116}, /* 677 't' */ - { 0xabe00000, 11, 82}, /* 678 'R' */ - { 0xabb00000, 12, 59}, /* 679 ';' */ - { 0xab800000, 13, 112}, /* 680 'p' */ - { 0xab880000, 13, 109}, /* 681 'm' */ - { 0xab900000, 13, 33}, /* 682 '!' */ - { 0xaba80000, 13, 38}, /* 683 '&' */ - { 0xab980000, 14, 101}, /* 684 'e' */ - { 0xab9c0000, 15, 98}, /* 685 'b' */ - { 0xab9e0000, 15, 97}, /* 686 'a' */ - { 0xaba00000, 15, 68}, /* 687 'D' */ - { 0xaba20000, 15, 67}, /* 688 'C' */ - { 0xaba40000, 15, 37}, /* 689 '%' */ - { 0xaba60000, 16, 1}, /* 690 '0x01' */ - { 0xaba70000, 16, 111}, /* 691 'o' */ - /* 32 */ - { 0xc0000000, 2, 48}, /* 692 '0' */ - { 0x00000000, 3, 32}, /* 693 ' ' */ - { 0x40000000, 3, 46}, /* 694 '.' */ - { 0x80000000, 3, 53}, /* 695 '5' */ - { 0x30000000, 4, 47}, /* 696 '/' */ - { 0xb0000000, 4, 44}, /* 697 ',' */ - { 0x20000000, 5, 93}, /* 698 ']' */ - { 0x28000000, 5, 112}, /* 699 'p' */ - { 0x68000000, 5, 49}, /* 700 '1' */ - { 0xa8000000, 5, 52}, /* 701 '4' */ - { 0x60000000, 6, 54}, /* 702 '6' */ - { 0x64000000, 6, 50}, /* 703 '2' */ - { 0x70000000, 6, 58}, /* 704 ':' */ - { 0x74000000, 6, 45}, /* 705 '-' */ - { 0x7c000000, 6, 41}, /* 706 ')' */ - { 0xa0000000, 7, 0}, /* 707 '0x00' */ - { 0xa4000000, 7, 56}, /* 708 '8' */ - { 0xa6000000, 7, 57}, /* 709 '9' */ - { 0x78000000, 8, 68}, /* 710 'D' */ - { 0x79000000, 8, 51}, /* 711 '3' */ - { 0x7a000000, 8, 116}, /* 712 't' */ - { 0x7b000000, 8, 55}, /* 713 '7' */ - { 0xa2000000, 8, 110}, /* 714 'n' */ - { 0xa3000000, 9, 97}, /* 715 'a' */ - { 0xa3800000, 10, 39}, /* 716 '\'' */ - { 0xa3e00000, 11, 59}, /* 717 ';' */ - { 0xa3c00000, 12, 115}, /* 718 's' */ - { 0xa3d00000, 13, 34}, /* 719 '\"' */ - { 0xa3d80000, 15, 1}, /* 720 '0x01' */ - { 0xa3da0000, 15, 105}, /* 721 'i' */ - { 0xa3dc0000, 15, 87}, /* 722 'W' */ - { 0xa3de0000, 15, 76}, /* 723 'L' */ - /* 36 */ - { 0x00000000, 2, 32}, /* 724 ' ' */ - { 0x80000000, 2, 48}, /* 725 '0' */ - { 0xc0000000, 3, 46}, /* 726 '.' */ - { 0xe0000000, 4, 47}, /* 727 '/' */ - { 0x40000000, 5, 50}, /* 728 '2' */ - { 0x48000000, 5, 49}, /* 729 '1' */ - { 0x50000000, 5, 41}, /* 730 ')' */ - { 0x60000000, 5, 58}, /* 731 ':' */ - { 0x70000000, 5, 45}, /* 732 '-' */ - { 0xf8000000, 5, 93}, /* 733 ']' */ - { 0x58000000, 6, 68}, /* 734 'D' */ - { 0x68000000, 6, 52}, /* 735 '4' */ - { 0x6c000000, 6, 0}, /* 736 '0x00' */ - { 0x7c000000, 6, 53}, /* 737 '5' */ - { 0xf0000000, 6, 44}, /* 738 ',' */ - { 0x5c000000, 7, 55}, /* 739 '7' */ - { 0x5e000000, 7, 51}, /* 740 '3' */ - { 0x7a000000, 7, 54}, /* 741 '6' */ - { 0xf6000000, 7, 116}, /* 742 't' */ - { 0x79000000, 8, 66}, /* 743 'B' */ - { 0xf4000000, 8, 56}, /* 744 '8' */ - { 0xf5000000, 9, 57}, /* 745 '9' */ - { 0x78400000, 10, 59}, /* 746 ';' */ - { 0xf5800000, 10, 114}, /* 747 'r' */ - { 0xf5c00000, 10, 115}, /* 748 's' */ - { 0x78000000, 11, 110}, /* 749 'n' */ - { 0x78a00000, 11, 98}, /* 750 'b' */ - { 0x78c00000, 11, 39}, /* 751 '\'' */ - { 0x78e00000, 11, 65}, /* 752 'A' */ - { 0x78200000, 12, 112}, /* 753 'p' */ - { 0x78300000, 12, 101}, /* 754 'e' */ - { 0x78800000, 13, 97}, /* 755 'a' */ - { 0x78880000, 13, 38}, /* 756 '&' */ - { 0x78900000, 13, 37}, /* 757 '%' */ - { 0x78980000, 14, 1}, /* 758 '0x01' */ - { 0x789c0000, 14, 107}, /* 759 'k' */ - /* 35 */ - { 0x40000000, 2, 32}, /* 760 ' ' */ - { 0x00000000, 3, 52}, /* 761 '4' */ - { 0x80000000, 3, 46}, /* 762 '.' */ - { 0xc0000000, 3, 48}, /* 763 '0' */ - { 0x20000000, 4, 47}, /* 764 '/' */ - { 0xa0000000, 4, 53}, /* 765 '5' */ - { 0xb0000000, 4, 45}, /* 766 '-' */ - { 0x30000000, 5, 49}, /* 767 '1' */ - { 0xe8000000, 5, 93}, /* 768 ']' */ - { 0xf0000000, 5, 44}, /* 769 ',' */ - { 0x38000000, 6, 50}, /* 770 '2' */ - { 0xe4000000, 6, 56}, /* 771 '8' */ - { 0xf8000000, 6, 41}, /* 772 ')' */ - { 0x3c000000, 7, 58}, /* 773 ':' */ - { 0x3e000000, 7, 39}, /* 774 '\'' */ - { 0xe0000000, 7, 116}, /* 775 't' */ - { 0xe2000000, 7, 51}, /* 776 '3' */ - { 0xfe000000, 7, 0}, /* 777 '0x00' */ - { 0xfd000000, 8, 54}, /* 778 '6' */ - { 0xfc000000, 10, 57}, /* 779 '9' */ - { 0xfc800000, 10, 55}, /* 780 '7' */ - { 0xfc600000, 11, 67}, /* 781 'C' */ - { 0xfcc00000, 11, 59}, /* 782 ';' */ - { 0xfc500000, 12, 120}, /* 783 'x' */ - { 0xfce80000, 13, 109}, /* 784 'm' */ - { 0xfcf00000, 13, 73}, /* 785 'I' */ - { 0xfc400000, 14, 102}, /* 786 'f' */ - { 0xfc440000, 14, 101}, /* 787 'e' */ - { 0xfc480000, 14, 98}, /* 788 'b' */ - { 0xfc4c0000, 14, 76}, /* 789 'L' */ - { 0xfce00000, 14, 37}, /* 790 '%' */ - { 0xfcf80000, 14, 112}, /* 791 'p' */ - { 0xfcfc0000, 14, 99}, /* 792 'c' */ - { 0xfce40000, 15, 1}, /* 793 '0x01' */ - { 0xfce60000, 15, 105}, /* 794 'i' */ - /* 32 */ - { 0x00000000, 2, 48}, /* 795 '0' */ - { 0x80000000, 2, 32}, /* 796 ' ' */ - { 0x40000000, 3, 46}, /* 797 '.' */ - { 0x70000000, 4, 112}, /* 798 'p' */ - { 0xc0000000, 4, 53}, /* 799 '5' */ - { 0x60000000, 5, 47}, /* 800 '/' */ - { 0xd0000000, 5, 97}, /* 801 'a' */ - { 0xd8000000, 5, 45}, /* 802 '-' */ - { 0xe8000000, 5, 54}, /* 803 '6' */ - { 0x68000000, 6, 51}, /* 804 '3' */ - { 0xf0000000, 6, 50}, /* 805 '2' */ - { 0xf8000000, 6, 56}, /* 806 '8' */ - { 0xfc000000, 6, 93}, /* 807 ']' */ - { 0x6c000000, 7, 58}, /* 808 ':' */ - { 0xe0000000, 7, 41}, /* 809 ')' */ - { 0xe2000000, 7, 115}, /* 810 's' */ - { 0xe6000000, 7, 44}, /* 811 ',' */ - { 0xf4000000, 7, 55}, /* 812 '7' */ - { 0xf6000000, 7, 57}, /* 813 '9' */ - { 0x6e000000, 8, 52}, /* 814 '4' */ - { 0xe4000000, 8, 0}, /* 815 '0x00' */ - { 0xe5000000, 8, 116}, /* 816 't' */ - { 0x6f800000, 10, 99}, /* 817 'c' */ - { 0x6fc00000, 10, 49}, /* 818 '1' */ - { 0x6f200000, 11, 59}, /* 819 ';' */ - { 0x6f600000, 11, 109}, /* 820 'm' */ - { 0x6f000000, 12, 101}, /* 821 'e' */ - { 0x6f100000, 12, 39}, /* 822 '\'' */ - { 0x6f500000, 12, 107}, /* 823 'k' */ - { 0x6f480000, 13, 108}, /* 824 'l' */ - { 0x6f400000, 14, 1}, /* 825 '0x01' */ - { 0x6f440000, 14, 102}, /* 826 'f' */ - /* 33 */ - { 0x00000000, 2, 32}, /* 827 ' ' */ - { 0x80000000, 2, 46}, /* 828 '.' */ - { 0xe0000000, 3, 48}, /* 829 '0' */ - { 0x50000000, 4, 93}, /* 830 ']' */ - { 0x48000000, 5, 49}, /* 831 '1' */ - { 0x60000000, 5, 55}, /* 832 '7' */ - { 0x70000000, 5, 41}, /* 833 ')' */ - { 0xc0000000, 5, 44}, /* 834 ',' */ - { 0xc8000000, 5, 58}, /* 835 ':' */ - { 0xd0000000, 5, 47}, /* 836 '/' */ - { 0x44000000, 6, 45}, /* 837 '-' */ - { 0x68000000, 6, 53}, /* 838 '5' */ - { 0x6c000000, 6, 52}, /* 839 '4' */ - { 0x7c000000, 6, 56}, /* 840 '8' */ - { 0xdc000000, 6, 116}, /* 841 't' */ - { 0x40000000, 7, 54}, /* 842 '6' */ - { 0x78000000, 7, 51}, /* 843 '3' */ - { 0x7a000000, 7, 50}, /* 844 '2' */ - { 0xda000000, 7, 57}, /* 845 '9' */ - { 0x42000000, 8, 0}, /* 846 '0x00' */ - { 0x43000000, 8, 43}, /* 847 '+' */ - { 0xd8000000, 8, 39}, /* 848 '\'' */ - { 0xd9400000, 10, 97}, /* 849 'a' */ - { 0xd9800000, 10, 63}, /* 850 '?' */ - { 0xd9000000, 11, 109}, /* 851 'm' */ - { 0xd9200000, 11, 101}, /* 852 'e' */ - { 0xd9c00000, 11, 59}, /* 853 ';' */ - { 0xd9e00000, 13, 102}, /* 854 'f' */ - { 0xd9e80000, 13, 98}, /* 855 'b' */ - { 0xd9f00000, 13, 77}, /* 856 'M' */ - { 0xd9f80000, 14, 34}, /* 857 '\"' */ - { 0xd9fc0000, 15, 1}, /* 858 '0x01' */ - { 0xd9fe0000, 15, 105}, /* 859 'i' */ - /* 31 */ - { 0xc0000000, 2, 46}, /* 860 '.' */ - { 0x20000000, 3, 32}, /* 861 ' ' */ - { 0x60000000, 3, 48}, /* 862 '0' */ - { 0xa0000000, 3, 45}, /* 863 '-' */ - { 0x00000000, 4, 56}, /* 864 '8' */ - { 0x40000000, 4, 55}, /* 865 '7' */ - { 0x90000000, 4, 93}, /* 866 ']' */ - { 0x50000000, 5, 47}, /* 867 '/' */ - { 0x14000000, 6, 54}, /* 868 '6' */ - { 0x18000000, 6, 50}, /* 869 '2' */ - { 0x1c000000, 6, 49}, /* 870 '1' */ - { 0x5c000000, 6, 116}, /* 871 't' */ - { 0x80000000, 6, 57}, /* 872 '9' */ - { 0x88000000, 6, 41}, /* 873 ')' */ - { 0x8c000000, 6, 53}, /* 874 '5' */ - { 0x12000000, 7, 51}, /* 875 '3' */ - { 0x5a000000, 7, 44}, /* 876 ',' */ - { 0x84000000, 7, 97}, /* 877 'a' */ - { 0x86000000, 7, 52}, /* 878 '4' */ - { 0x10000000, 8, 0}, /* 879 '0x00' */ - { 0x58000000, 8, 58}, /* 880 ':' */ - { 0x59000000, 8, 112}, /* 881 'p' */ - { 0x11400000, 10, 82}, /* 882 'R' */ - { 0x11800000, 10, 59}, /* 883 ';' */ - { 0x11000000, 11, 39}, /* 884 '\'' */ - { 0x11e00000, 11, 109}, /* 885 'm' */ - { 0x11300000, 12, 102}, /* 886 'f' */ - { 0x11c00000, 12, 65}, /* 887 'A' */ - { 0x11d00000, 12, 63}, /* 888 '?' */ - { 0x11200000, 13, 1}, /* 889 '0x01' */ - { 0x11280000, 13, 115}, /* 890 's' */ - /* 31 */ - { 0x40000000, 2, 32}, /* 891 ' ' */ - { 0x00000000, 3, 52}, /* 892 '4' */ - { 0xc0000000, 3, 46}, /* 893 '.' */ - { 0x30000000, 4, 48}, /* 894 '0' */ - { 0x80000000, 4, 57}, /* 895 '9' */ - { 0x90000000, 4, 55}, /* 896 '7' */ - { 0xb0000000, 4, 56}, /* 897 '8' */ - { 0xe0000000, 4, 49}, /* 898 '1' */ - { 0x20000000, 5, 47}, /* 899 '/' */ - { 0xa0000000, 5, 51}, /* 900 '3' */ - { 0xf0000000, 5, 53}, /* 901 '5' */ - { 0xa8000000, 6, 41}, /* 902 ')' */ - { 0xf8000000, 6, 54}, /* 903 '6' */ - { 0xfc000000, 6, 93}, /* 904 ']' */ - { 0x28000000, 7, 58}, /* 905 ':' */ - { 0x2a000000, 7, 44}, /* 906 ',' */ - { 0xae000000, 7, 116}, /* 907 't' */ - { 0x2c000000, 8, 112}, /* 908 'p' */ - { 0x2d000000, 8, 45}, /* 909 '-' */ - { 0x2f000000, 8, 97}, /* 910 'a' */ - { 0xac000000, 8, 99}, /* 911 'c' */ - { 0xad000000, 8, 50}, /* 912 '2' */ - { 0x2e800000, 9, 0}, /* 913 '0x00' */ - { 0x2e400000, 10, 59}, /* 914 ';' */ - { 0x2e000000, 12, 108}, /* 915 'l' */ - { 0x2e100000, 12, 39}, /* 916 '\'' */ - { 0x2e200000, 13, 102}, /* 917 'f' */ - { 0x2e280000, 13, 68}, /* 918 'D' */ - { 0x2e300000, 13, 65}, /* 919 'A' */ - { 0x2e380000, 14, 1}, /* 920 '0x01' */ - { 0x2e3c0000, 14, 105}, /* 921 'i' */ - /* 28 */ - { 0x00000000, 3, 53}, /* 922 '5' */ - { 0x20000000, 3, 93}, /* 923 ']' */ - { 0xe0000000, 3, 57}, /* 924 '9' */ - { 0x50000000, 4, 48}, /* 925 '0' */ - { 0x60000000, 4, 46}, /* 926 '.' */ - { 0x70000000, 4, 45}, /* 927 '-' */ - { 0x80000000, 4, 52}, /* 928 '4' */ - { 0x90000000, 4, 56}, /* 929 '8' */ - { 0xb0000000, 4, 54}, /* 930 '6' */ - { 0xc0000000, 4, 32}, /* 931 ' ' */ - { 0xd0000000, 4, 55}, /* 932 '7' */ - { 0x40000000, 5, 50}, /* 933 '2' */ - { 0xa0000000, 5, 51}, /* 934 '3' */ - { 0x48000000, 6, 49}, /* 935 '1' */ - { 0x4c000000, 6, 47}, /* 936 '/' */ - { 0xa8000000, 6, 116}, /* 937 't' */ - { 0xae000000, 7, 41}, /* 938 ')' */ - { 0xac000000, 8, 58}, /* 939 ':' */ - { 0xad000000, 9, 44}, /* 940 ',' */ - { 0xad800000, 11, 112}, /* 941 'p' */ - { 0xada00000, 11, 59}, /* 942 ';' */ - { 0xade00000, 11, 0}, /* 943 '0x00' */ - { 0xadc00000, 13, 110}, /* 944 'n' */ - { 0xadc80000, 13, 109}, /* 945 'm' */ - { 0xadd00000, 13, 97}, /* 946 'a' */ - { 0xaddc0000, 14, 101}, /* 947 'e' */ - { 0xadd80000, 15, 1}, /* 948 '0x01' */ - { 0xadda0000, 15, 107}, /* 949 'k' */ - /* 9 */ - { 0x80000000, 1, 32}, /* 950 ' ' */ - { 0x40000000, 2, 48}, /* 951 '0' */ - { 0x20000000, 3, 51}, /* 952 '3' */ - { 0x08000000, 5, 49}, /* 953 '1' */ - { 0x10000000, 5, 84}, /* 954 'T' */ - { 0x18000000, 5, 67}, /* 955 'C' */ - { 0x04000000, 6, 52}, /* 956 '4' */ - { 0x00000000, 7, 1}, /* 957 '0x01' */ - { 0x02000000, 7, 53}, /* 958 '5' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 959 '0x01' */ - { 0x80000000, 1, 32}, /* 960 ' ' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 961 '0x01' */ - { 0x80000000, 1, 1}, /* 962 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 963 '0x01' */ - { 0x80000000, 1, 1}, /* 964 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 965 '0x01' */ - { 0x80000000, 1, 1}, /* 966 '0x01' */ - /* 12 */ - { 0x80000000, 1, 32}, /* 967 ' ' */ - { 0x40000000, 2, 0}, /* 968 '0x00' */ - { 0x00000000, 3, 58}, /* 969 ':' */ - { 0x20000000, 5, 33}, /* 970 '!' */ - { 0x30000000, 5, 91}, /* 971 '[' */ - { 0x38000000, 5, 46}, /* 972 '.' */ - { 0x28000000, 6, 59}, /* 973 ';' */ - { 0x2c000000, 7, 39}, /* 974 '\'' */ - { 0x2f000000, 8, 44}, /* 975 ',' */ - { 0x2e800000, 9, 47}, /* 976 '/' */ - { 0x2e000000, 10, 1}, /* 977 '0x01' */ - { 0x2e400000, 10, 81}, /* 978 'Q' */ - /* 6 */ - { 0x00000000, 1, 107}, /* 979 'k' */ - { 0x80000000, 2, 32}, /* 980 ' ' */ - { 0xe0000000, 3, 84}, /* 981 'T' */ - { 0xd0000000, 4, 98}, /* 982 'b' */ - { 0xc0000000, 5, 1}, /* 983 '0x01' */ - { 0xc8000000, 5, 72}, /* 984 'H' */ - /* 58 */ - { 0x40000000, 2, 32}, /* 985 ' ' */ - { 0xc0000000, 3, 68}, /* 986 'D' */ - { 0xe0000000, 3, 110}, /* 987 'n' */ - { 0x00000000, 4, 115}, /* 988 's' */ - { 0x10000000, 4, 109}, /* 989 'm' */ - { 0x20000000, 4, 100}, /* 990 'd' */ - { 0x80000000, 4, 114}, /* 991 'r' */ - { 0xb0000000, 4, 108}, /* 992 'l' */ - { 0x30000000, 5, 99}, /* 993 'c' */ - { 0x90000000, 5, 117}, /* 994 'u' */ - { 0xa0000000, 5, 103}, /* 995 'g' */ - { 0x3c000000, 6, 98}, /* 996 'b' */ - { 0x9c000000, 6, 116}, /* 997 't' */ - { 0xac000000, 6, 102}, /* 998 'f' */ - { 0xa8000000, 7, 119}, /* 999 'w' */ - { 0xaa000000, 7, 105}, /* 1000 'i' */ - { 0x99000000, 8, 118}, /* 1001 'v' */ - { 0x9b000000, 8, 112}, /* 1002 'p' */ - { 0x39000000, 9, 104}, /* 1003 'h' */ - { 0x3a000000, 9, 46}, /* 1004 '.' */ - { 0x3b800000, 9, 66}, /* 1005 'B' */ - { 0x9a000000, 9, 113}, /* 1006 'q' */ - { 0x38000000, 10, 67}, /* 1007 'C' */ - { 0x38800000, 10, 44}, /* 1008 ',' */ - { 0x39800000, 10, 121}, /* 1009 'y' */ - { 0x3a800000, 10, 83}, /* 1010 'S' */ - { 0x3b000000, 10, 107}, /* 1011 'k' */ - { 0x3b400000, 10, 84}, /* 1012 'T' */ - { 0x98400000, 10, 82}, /* 1013 'R' */ - { 0x98800000, 10, 70}, /* 1014 'F' */ - { 0x98c00000, 10, 122}, /* 1015 'z' */ - { 0x9ac00000, 10, 97}, /* 1016 'a' */ - { 0x38400000, 11, 80}, /* 1017 'P' */ - { 0x38c00000, 11, 45}, /* 1018 '-' */ - { 0x3ac00000, 11, 65}, /* 1019 'A' */ - { 0x3ae00000, 11, 73}, /* 1020 'I' */ - { 0x98200000, 11, 101}, /* 1021 'e' */ - { 0x9a800000, 11, 78}, /* 1022 'N' */ - { 0x9aa00000, 11, 120}, /* 1023 'x' */ - { 0x38600000, 12, 88}, /* 1024 'X' */ - { 0x38700000, 12, 75}, /* 1025 'K' */ - { 0x38e00000, 12, 51}, /* 1026 '3' */ - { 0x38f00000, 12, 38}, /* 1027 '&' */ - { 0x39d00000, 12, 77}, /* 1028 'M' */ - { 0x39f00000, 12, 89}, /* 1029 'Y' */ - { 0x39c00000, 13, 76}, /* 1030 'L' */ - { 0x39c80000, 13, 87}, /* 1031 'W' */ - { 0x39e00000, 13, 42}, /* 1032 '*' */ - { 0x98000000, 13, 111}, /* 1033 'o' */ - { 0x98080000, 13, 49}, /* 1034 '1' */ - { 0x98100000, 13, 39}, /* 1035 '\'' */ - { 0x98180000, 13, 58}, /* 1036 ':' */ - { 0x39e80000, 14, 106}, /* 1037 'j' */ - { 0x39ec0000, 15, 71}, /* 1038 'G' */ - { 0x39ee0000, 16, 79}, /* 1039 'O' */ - { 0x39ef0000, 17, 52}, /* 1040 '4' */ - { 0x39ef8000, 18, 1}, /* 1041 '0x01' */ - { 0x39efc000, 18, 69}, /* 1042 'E' */ - /* 40 */ - { 0x00000000, 2, 67}, /* 1043 'C' */ - { 0x40000000, 3, 97}, /* 1044 'a' */ - { 0xa0000000, 3, 114}, /* 1045 'r' */ - { 0xc0000000, 3, 101}, /* 1046 'e' */ - { 0xe0000000, 3, 66}, /* 1047 'B' */ - { 0x70000000, 4, 105}, /* 1048 'i' */ - { 0x80000000, 4, 117}, /* 1049 'u' */ - { 0x90000000, 4, 111}, /* 1050 'o' */ - { 0x68000000, 5, 108}, /* 1051 'l' */ - { 0x60000000, 8, 84}, /* 1052 'T' */ - { 0x61000000, 8, 46}, /* 1053 '.' */ - { 0x63000000, 8, 121}, /* 1054 'y' */ - { 0x64000000, 8, 73}, /* 1055 'I' */ - { 0x66000000, 8, 104}, /* 1056 'h' */ - { 0x67000000, 8, 32}, /* 1057 ' ' */ - { 0x62000000, 9, 65}, /* 1058 'A' */ - { 0x62800000, 10, 79}, /* 1059 'O' */ - { 0x62c00000, 11, 58}, /* 1060 ':' */ - { 0x65000000, 11, 38}, /* 1061 '&' */ - { 0x65200000, 11, 51}, /* 1062 '3' */ - { 0x65400000, 11, 106}, /* 1063 'j' */ - { 0x65600000, 11, 77}, /* 1064 'M' */ - { 0x65c00000, 11, 68}, /* 1065 'D' */ - { 0x62f00000, 12, 87}, /* 1066 'W' */ - { 0x65800000, 12, 42}, /* 1067 '*' */ - { 0x65a00000, 12, 44}, /* 1068 ',' */ - { 0x65b00000, 12, 49}, /* 1069 '1' */ - { 0x65e00000, 12, 1}, /* 1070 '0x01' */ - { 0x65f00000, 12, 80}, /* 1071 'P' */ - { 0x62e00000, 13, 69}, /* 1072 'E' */ - { 0x65980000, 13, 82}, /* 1073 'R' */ - { 0x62ec0000, 14, 119}, /* 1074 'w' */ - { 0x62e80000, 15, 45}, /* 1075 '-' */ - { 0x65920000, 15, 85}, /* 1076 'U' */ - { 0x65940000, 15, 83}, /* 1077 'S' */ - { 0x65960000, 15, 70}, /* 1078 'F' */ - { 0x62ea0000, 16, 88}, /* 1079 'X' */ - { 0x62eb0000, 16, 86}, /* 1080 'V' */ - { 0x65900000, 16, 81}, /* 1081 'Q' */ - { 0x65910000, 16, 52}, /* 1082 '4' */ - /* 47 */ - { 0x00000000, 2, 104}, /* 1083 'h' */ - { 0x60000000, 3, 66}, /* 1084 'B' */ - { 0x80000000, 3, 97}, /* 1085 'a' */ - { 0xc0000000, 3, 111}, /* 1086 'o' */ - { 0x50000000, 4, 114}, /* 1087 'r' */ - { 0xa0000000, 4, 46}, /* 1088 '.' */ - { 0xe0000000, 4, 32}, /* 1089 ' ' */ - { 0xf0000000, 4, 108}, /* 1090 'l' */ - { 0x40000000, 5, 39}, /* 1091 '\'' */ - { 0xb8000000, 5, 105}, /* 1092 'i' */ - { 0x4c000000, 6, 101}, /* 1093 'e' */ - { 0xb4000000, 6, 117}, /* 1094 'u' */ - { 0x4a000000, 7, 121}, /* 1095 'y' */ - { 0xb2000000, 7, 44}, /* 1096 ',' */ - { 0x49000000, 8, 73}, /* 1097 'I' */ - { 0x48000000, 9, 65}, /* 1098 'A' */ - { 0xb0000000, 10, 67}, /* 1099 'C' */ - { 0xb0400000, 10, 68}, /* 1100 'D' */ - { 0xb0c00000, 10, 0}, /* 1101 '0x00' */ - { 0xb1000000, 10, 83}, /* 1102 'S' */ - { 0xb1400000, 10, 84}, /* 1103 'T' */ - { 0xb1c00000, 10, 71}, /* 1104 'G' */ - { 0x48800000, 11, 42}, /* 1105 '*' */ - { 0x48e00000, 11, 119}, /* 1106 'w' */ - { 0xb1a00000, 11, 74}, /* 1107 'J' */ - { 0x48a00000, 12, 82}, /* 1108 'R' */ - { 0x48c00000, 12, 50}, /* 1109 '2' */ - { 0x48d00000, 12, 85}, /* 1110 'U' */ - { 0xb0800000, 12, 63}, /* 1111 '?' */ - { 0xb0a00000, 12, 79}, /* 1112 'O' */ - { 0xb0b00000, 12, 72}, /* 1113 'H' */ - { 0xb1800000, 12, 69}, /* 1114 'E' */ - { 0x48b00000, 13, 122}, /* 1115 'z' */ - { 0xb0980000, 13, 45}, /* 1116 '-' */ - { 0xb1980000, 13, 115}, /* 1117 's' */ - { 0x48bc0000, 14, 49}, /* 1118 '1' */ - { 0xb0940000, 14, 33}, /* 1119 '!' */ - { 0xb1900000, 14, 80}, /* 1120 'P' */ - { 0x48ba0000, 15, 110}, /* 1121 'n' */ - { 0xb0900000, 15, 75}, /* 1122 'K' */ - { 0xb0920000, 15, 55}, /* 1123 '7' */ - { 0xb1960000, 15, 52}, /* 1124 '4' */ - { 0x48b80000, 16, 58}, /* 1125 ':' */ - { 0xb1940000, 16, 70}, /* 1126 'F' */ - { 0xb1950000, 16, 41}, /* 1127 ')' */ - { 0x48b90000, 17, 1}, /* 1128 '0x01' */ - { 0x48b98000, 17, 98}, /* 1129 'b' */ - /* 47 */ - { 0x00000000, 2, 97}, /* 1130 'a' */ - { 0x40000000, 2, 44}, /* 1131 ',' */ - { 0x80000000, 3, 114}, /* 1132 'r' */ - { 0xa0000000, 3, 111}, /* 1133 'o' */ - { 0xc0000000, 3, 101}, /* 1134 'e' */ - { 0xe0000000, 4, 105}, /* 1135 'i' */ - { 0xfc000000, 6, 117}, /* 1136 'u' */ - { 0xf2000000, 7, 32}, /* 1137 ' ' */ - { 0xf6000000, 7, 39}, /* 1138 '\'' */ - { 0xf0000000, 8, 46}, /* 1139 '.' */ - { 0xf1000000, 8, 93}, /* 1140 ']' */ - { 0xfa000000, 8, 121}, /* 1141 'y' */ - { 0xf5000000, 9, 119}, /* 1142 'w' */ - { 0xf5800000, 9, 87}, /* 1143 'W' */ - { 0xf8800000, 9, 78}, /* 1144 'N' */ - { 0xf9000000, 9, 67}, /* 1145 'C' */ - { 0xfb800000, 9, 74}, /* 1146 'J' */ - { 0xf4800000, 10, 104}, /* 1147 'h' */ - { 0xf8000000, 10, 116}, /* 1148 't' */ - { 0xf9c00000, 10, 73}, /* 1149 'I' */ - { 0xfb400000, 10, 58}, /* 1150 ':' */ - { 0xf4200000, 11, 77}, /* 1151 'M' */ - { 0xf4400000, 11, 38}, /* 1152 '&' */ - { 0xf4600000, 11, 86}, /* 1153 'V' */ - { 0xf8400000, 11, 45}, /* 1154 '-' */ - { 0xf8600000, 11, 71}, /* 1155 'G' */ - { 0xf9800000, 11, 79}, /* 1156 'O' */ - { 0xf9a00000, 11, 65}, /* 1157 'A' */ - { 0xfb200000, 11, 83}, /* 1158 'S' */ - { 0xf4000000, 12, 70}, /* 1159 'F' */ - { 0xf4c00000, 12, 42}, /* 1160 '*' */ - { 0xf4d00000, 12, 115}, /* 1161 's' */ - { 0xf4f00000, 12, 100}, /* 1162 'd' */ - { 0xfb000000, 12, 118}, /* 1163 'v' */ - { 0xf4e00000, 13, 109}, /* 1164 'm' */ - { 0xf4e80000, 13, 106}, /* 1165 'j' */ - { 0xfb100000, 13, 1}, /* 1166 '0x01' */ - { 0xfb180000, 13, 84}, /* 1167 'T' */ - { 0xf4180000, 14, 57}, /* 1168 '9' */ - { 0xf4100000, 15, 41}, /* 1169 ')' */ - { 0xf4160000, 15, 69}, /* 1170 'E' */ - { 0xf41c0000, 15, 56}, /* 1171 '8' */ - { 0xf41e0000, 15, 55}, /* 1172 '7' */ - { 0xf4120000, 16, 85}, /* 1173 'U' */ - { 0xf4130000, 16, 82}, /* 1174 'R' */ - { 0xf4140000, 16, 66}, /* 1175 'B' */ - { 0xf4150000, 16, 52}, /* 1176 '4' */ - /* 54 */ - { 0x00000000, 3, 112}, /* 1177 'p' */ - { 0x40000000, 3, 97}, /* 1178 'a' */ - { 0x60000000, 3, 110}, /* 1179 'n' */ - { 0xc0000000, 3, 108}, /* 1180 'l' */ - { 0x90000000, 4, 109}, /* 1181 'm' */ - { 0xa0000000, 4, 120}, /* 1182 'x' */ - { 0xe0000000, 4, 118}, /* 1183 'v' */ - { 0xf0000000, 4, 100}, /* 1184 'd' */ - { 0x20000000, 5, 115}, /* 1185 's' */ - { 0x30000000, 5, 114}, /* 1186 'r' */ - { 0x38000000, 5, 117}, /* 1187 'u' */ - { 0x80000000, 5, 69}, /* 1188 'E' */ - { 0x88000000, 5, 32}, /* 1189 ' ' */ - { 0x28000000, 6, 46}, /* 1190 '.' */ - { 0x2c000000, 6, 105}, /* 1191 'i' */ - { 0xb4000000, 6, 58}, /* 1192 ':' */ - { 0xb0000000, 7, 121}, /* 1193 'y' */ - { 0xb2000000, 7, 116}, /* 1194 't' */ - { 0xb8000000, 7, 103}, /* 1195 'g' */ - { 0xbc000000, 7, 52}, /* 1196 '4' */ - { 0xbb000000, 9, 119}, /* 1197 'w' */ - { 0xbe000000, 9, 99}, /* 1198 'c' */ - { 0xbf000000, 9, 98}, /* 1199 'b' */ - { 0xba800000, 10, 82}, /* 1200 'R' */ - { 0xbac00000, 10, 70}, /* 1201 'F' */ - { 0xbbc00000, 10, 67}, /* 1202 'C' */ - { 0xba200000, 11, 107}, /* 1203 'k' */ - { 0xba400000, 11, 102}, /* 1204 'f' */ - { 0xba600000, 11, 111}, /* 1205 'o' */ - { 0xbb800000, 11, 85}, /* 1206 'U' */ - { 0xbba00000, 11, 76}, /* 1207 'L' */ - { 0xbea00000, 11, 101}, /* 1208 'e' */ - { 0xbec00000, 11, 78}, /* 1209 'N' */ - { 0xbf800000, 11, 104}, /* 1210 'h' */ - { 0xbfa00000, 11, 73}, /* 1211 'I' */ - { 0xbfe00000, 11, 68}, /* 1212 'D' */ - { 0xbe800000, 12, 77}, /* 1213 'M' */ - { 0xbef00000, 12, 39}, /* 1214 '\'' */ - { 0xbfc00000, 12, 50}, /* 1215 '2' */ - { 0xbfd00000, 12, 45}, /* 1216 '-' */ - { 0xba180000, 13, 113}, /* 1217 'q' */ - { 0xbe900000, 13, 79}, /* 1218 'O' */ - { 0xbe980000, 13, 65}, /* 1219 'A' */ - { 0xbee80000, 13, 90}, /* 1220 'Z' */ - { 0xba000000, 14, 87}, /* 1221 'W' */ - { 0xba040000, 14, 83}, /* 1222 'S' */ - { 0xba080000, 14, 72}, /* 1223 'H' */ - { 0xba0c0000, 14, 57}, /* 1224 '9' */ - { 0xba100000, 14, 41}, /* 1225 ')' */ - { 0xbee00000, 14, 84}, /* 1226 'T' */ - { 0xbee40000, 14, 44}, /* 1227 ',' */ - { 0xba140000, 15, 80}, /* 1228 'P' */ - { 0xba160000, 16, 1}, /* 1229 '0x01' */ - { 0xba170000, 16, 122}, /* 1230 'z' */ - /* 36 */ - { 0x00000000, 2, 111}, /* 1231 'o' */ - { 0x80000000, 2, 114}, /* 1232 'r' */ - { 0x40000000, 3, 101}, /* 1233 'e' */ - { 0xc0000000, 3, 105}, /* 1234 'i' */ - { 0xe0000000, 3, 97}, /* 1235 'a' */ - { 0x60000000, 4, 108}, /* 1236 'l' */ - { 0x70000000, 5, 117}, /* 1237 'u' */ - { 0x78000000, 7, 32}, /* 1238 ' ' */ - { 0x7a000000, 7, 79}, /* 1239 'O' */ - { 0x7d000000, 8, 65}, /* 1240 'A' */ - { 0x7f000000, 8, 66}, /* 1241 'B' */ - { 0x7e000000, 9, 102}, /* 1242 'f' */ - { 0x7c000000, 10, 46}, /* 1243 '.' */ - { 0x7cc00000, 10, 76}, /* 1244 'L' */ - { 0x7c400000, 11, 77}, /* 1245 'M' */ - { 0x7c600000, 11, 69}, /* 1246 'E' */ - { 0x7ca00000, 11, 84}, /* 1247 'T' */ - { 0x7ea00000, 11, 67}, /* 1248 'C' */ - { 0x7ec00000, 11, 87}, /* 1249 'W' */ - { 0x7c800000, 12, 58}, /* 1250 ':' */ - { 0x7e800000, 12, 85}, /* 1251 'U' */ - { 0x7e900000, 12, 39}, /* 1252 '\'' */ - { 0x7ef00000, 12, 49}, /* 1253 '1' */ - { 0x7c900000, 13, 121}, /* 1254 'y' */ - { 0x7c980000, 13, 44}, /* 1255 ',' */ - { 0x7ee00000, 14, 45}, /* 1256 '-' */ - { 0x7ee80000, 14, 73}, /* 1257 'I' */ - { 0x7ee60000, 15, 104}, /* 1258 'h' */ - { 0x7ee40000, 16, 42}, /* 1259 '*' */ - { 0x7ee50000, 16, 75}, /* 1260 'K' */ - { 0x7eec0000, 16, 70}, /* 1261 'F' */ - { 0x7eed0000, 16, 1}, /* 1262 '0x01' */ - { 0x7eee0000, 17, 88}, /* 1263 'X' */ - { 0x7eee8000, 17, 82}, /* 1264 'R' */ - { 0x7eef0000, 17, 59}, /* 1265 ';' */ - { 0x7eef8000, 17, 52}, /* 1266 '4' */ - /* 37 */ - { 0x00000000, 2, 114}, /* 1267 'r' */ - { 0x40000000, 2, 97}, /* 1268 'a' */ - { 0xa0000000, 3, 111}, /* 1269 'o' */ - { 0xc0000000, 3, 101}, /* 1270 'e' */ - { 0x90000000, 4, 117}, /* 1271 'u' */ - { 0xf0000000, 4, 105}, /* 1272 'i' */ - { 0x88000000, 5, 110}, /* 1273 'n' */ - { 0xe8000000, 5, 108}, /* 1274 'l' */ - { 0x80000000, 6, 88}, /* 1275 'X' */ - { 0xe0000000, 7, 121}, /* 1276 'y' */ - { 0xe2000000, 7, 32}, /* 1277 ' ' */ - { 0xe6000000, 7, 119}, /* 1278 'w' */ - { 0x85000000, 8, 52}, /* 1279 '4' */ - { 0x87000000, 8, 80}, /* 1280 'P' */ - { 0xe5000000, 8, 104}, /* 1281 'h' */ - { 0x84000000, 9, 45}, /* 1282 '-' */ - { 0x86000000, 9, 67}, /* 1283 'C' */ - { 0xe4800000, 9, 77}, /* 1284 'M' */ - { 0x86800000, 10, 66}, /* 1285 'B' */ - { 0xe4000000, 10, 46}, /* 1286 '.' */ - { 0xe4400000, 10, 73}, /* 1287 'I' */ - { 0x84800000, 11, 59}, /* 1288 ';' */ - { 0x84a00000, 11, 44}, /* 1289 ',' */ - { 0x84c00000, 11, 65}, /* 1290 'A' */ - { 0x84e00000, 11, 78}, /* 1291 'N' */ - { 0x86e00000, 11, 58}, /* 1292 ':' */ - { 0x86c00000, 13, 79}, /* 1293 'O' */ - { 0x86c80000, 13, 76}, /* 1294 'L' */ - { 0x86d80000, 14, 98}, /* 1295 'b' */ - { 0x86d00000, 15, 75}, /* 1296 'K' */ - { 0x86d20000, 15, 50}, /* 1297 '2' */ - { 0x86d40000, 15, 49}, /* 1298 '1' */ - { 0x86d60000, 15, 39}, /* 1299 '\'' */ - { 0x86dc0000, 16, 1}, /* 1300 '0x01' */ - { 0x86dd0000, 16, 109}, /* 1301 'm' */ - { 0x86de0000, 16, 84}, /* 1302 'T' */ - { 0x86df0000, 16, 83}, /* 1303 'S' */ - /* 32 */ - { 0x00000000, 2, 101}, /* 1304 'e' */ - { 0x40000000, 2, 97}, /* 1305 'a' */ - { 0x80000000, 2, 111}, /* 1306 'o' */ - { 0xc0000000, 3, 105}, /* 1307 'i' */ - { 0xf0000000, 4, 117}, /* 1308 'u' */ - { 0xe0000000, 5, 82}, /* 1309 'R' */ - { 0xe8000000, 7, 80}, /* 1310 'P' */ - { 0xec000000, 7, 121}, /* 1311 'y' */ - { 0xeb000000, 8, 73}, /* 1312 'I' */ - { 0xee000000, 9, 81}, /* 1313 'Q' */ - { 0xee800000, 9, 77}, /* 1314 'M' */ - { 0xef000000, 9, 65}, /* 1315 'A' */ - { 0xef800000, 9, 32}, /* 1316 ' ' */ - { 0xea000000, 10, 83}, /* 1317 'S' */ - { 0xea400000, 10, 46}, /* 1318 '.' */ - { 0xeaa00000, 11, 71}, /* 1319 'G' */ - { 0xeac00000, 11, 41}, /* 1320 ')' */ - { 0xea900000, 12, 69}, /* 1321 'E' */ - { 0xeae00000, 13, 79}, /* 1322 'O' */ - { 0xeae80000, 13, 76}, /* 1323 'L' */ - { 0xea800000, 14, 49}, /* 1324 '1' */ - { 0xea840000, 14, 38}, /* 1325 '&' */ - { 0xeaf00000, 14, 72}, /* 1326 'H' */ - { 0xeaf40000, 14, 119}, /* 1327 'w' */ - { 0xeaf80000, 14, 118}, /* 1328 'v' */ - { 0xea880000, 15, 88}, /* 1329 'X' */ - { 0xea8a0000, 15, 87}, /* 1330 'W' */ - { 0xea8c0000, 15, 68}, /* 1331 'D' */ - { 0xeafc0000, 15, 115}, /* 1332 's' */ - { 0xeafe0000, 15, 70}, /* 1333 'F' */ - { 0xea8e0000, 16, 1}, /* 1334 '0x01' */ - { 0xea8f0000, 16, 114}, /* 1335 'r' */ - /* 52 */ - { 0x00000000, 1, 110}, /* 1336 'n' */ - { 0xc0000000, 3, 116}, /* 1337 't' */ - { 0x90000000, 4, 115}, /* 1338 's' */ - { 0xf0000000, 4, 114}, /* 1339 'r' */ - { 0x80000000, 5, 84}, /* 1340 'T' */ - { 0xa8000000, 5, 97}, /* 1341 'a' */ - { 0xe0000000, 5, 32}, /* 1342 ' ' */ - { 0x88000000, 6, 99}, /* 1343 'c' */ - { 0xa4000000, 6, 109}, /* 1344 'm' */ - { 0xb0000000, 6, 122}, /* 1345 'z' */ - { 0xb4000000, 6, 46}, /* 1346 '.' */ - { 0xbc000000, 6, 100}, /* 1347 'd' */ - { 0xec000000, 6, 73}, /* 1348 'I' */ - { 0x8e000000, 7, 39}, /* 1349 '\'' */ - { 0xba000000, 7, 108}, /* 1350 'l' */ - { 0xa0000000, 8, 65}, /* 1351 'A' */ - { 0xa1000000, 8, 118}, /* 1352 'v' */ - { 0xb9000000, 8, 86}, /* 1353 'V' */ - { 0xe9000000, 8, 102}, /* 1354 'f' */ - { 0xeb000000, 8, 111}, /* 1355 'o' */ - { 0x8c800000, 9, 67}, /* 1356 'C' */ - { 0x8d000000, 9, 80}, /* 1357 'P' */ - { 0xa2000000, 9, 119}, /* 1358 'w' */ - { 0xa3000000, 9, 58}, /* 1359 ':' */ - { 0xb8000000, 9, 112}, /* 1360 'p' */ - { 0xe8000000, 9, 82}, /* 1361 'R' */ - { 0xe8800000, 9, 44}, /* 1362 ',' */ - { 0xea800000, 9, 89}, /* 1363 'Y' */ - { 0x8c000000, 10, 69}, /* 1364 'E' */ - { 0x8c400000, 10, 54}, /* 1365 '6' */ - { 0x8dc00000, 10, 113}, /* 1366 'q' */ - { 0xa2c00000, 10, 121}, /* 1367 'y' */ - { 0xa3800000, 10, 77}, /* 1368 'M' */ - { 0xea000000, 10, 103}, /* 1369 'g' */ - { 0xea400000, 10, 68}, /* 1370 'D' */ - { 0x8d800000, 11, 101}, /* 1371 'e' */ - { 0x8da00000, 11, 53}, /* 1372 '5' */ - { 0xa2800000, 11, 83}, /* 1373 'S' */ - { 0xa2a00000, 11, 57}, /* 1374 '9' */ - { 0xa3e00000, 11, 70}, /* 1375 'F' */ - { 0xb8800000, 11, 98}, /* 1376 'b' */ - { 0xb8c00000, 11, 45}, /* 1377 '-' */ - { 0xb8e00000, 11, 76}, /* 1378 'L' */ - { 0xa3c00000, 12, 66}, /* 1379 'B' */ - { 0xa3d00000, 12, 41}, /* 1380 ')' */ - { 0xb8a00000, 13, 78}, /* 1381 'N' */ - { 0xb8a80000, 13, 81}, /* 1382 'Q' */ - { 0xb8b00000, 13, 107}, /* 1383 'k' */ - { 0xb8bc0000, 14, 79}, /* 1384 'O' */ - { 0xb8ba0000, 15, 63}, /* 1385 '?' */ - { 0xb8b80000, 16, 1}, /* 1386 '0x01' */ - { 0xb8b90000, 16, 104}, /* 1387 'h' */ - /* 29 */ - { 0x00000000, 2, 101}, /* 1388 'e' */ - { 0x80000000, 2, 97}, /* 1389 'a' */ - { 0xc0000000, 2, 111}, /* 1390 'o' */ - { 0x60000000, 3, 117}, /* 1391 'u' */ - { 0x50000000, 4, 105}, /* 1392 'i' */ - { 0x40000000, 5, 32}, /* 1393 ' ' */ - { 0x4c000000, 7, 68}, /* 1394 'D' */ - { 0x4e000000, 7, 46}, /* 1395 '.' */ - { 0x49000000, 8, 114}, /* 1396 'r' */ - { 0x4b000000, 9, 115}, /* 1397 's' */ - { 0x48000000, 10, 77}, /* 1398 'M' */ - { 0x48800000, 10, 74}, /* 1399 'J' */ - { 0x48c00000, 10, 44}, /* 1400 ',' */ - { 0x4a000000, 10, 66}, /* 1401 'B' */ - { 0x4a400000, 10, 45}, /* 1402 '-' */ - { 0x4a800000, 10, 86}, /* 1403 'V' */ - { 0x4b800000, 10, 75}, /* 1404 'K' */ - { 0x4bc00000, 10, 84}, /* 1405 'T' */ - { 0x48400000, 11, 67}, /* 1406 'C' */ - { 0x4ac00000, 11, 110}, /* 1407 'n' */ - { 0x48600000, 12, 33}, /* 1408 '!' */ - { 0x48700000, 13, 119}, /* 1409 'w' */ - { 0x48780000, 13, 82}, /* 1410 'R' */ - { 0x4ae00000, 13, 70}, /* 1411 'F' */ - { 0x4af00000, 13, 55}, /* 1412 '7' */ - { 0x4af80000, 13, 39}, /* 1413 '\'' */ - { 0x4ae80000, 14, 71}, /* 1414 'G' */ - { 0x4aec0000, 15, 1}, /* 1415 '0x01' */ - { 0x4aee0000, 15, 76}, /* 1416 'L' */ - /* 40 */ - { 0x00000000, 2, 105}, /* 1417 'i' */ - { 0x40000000, 2, 97}, /* 1418 'a' */ - { 0x80000000, 2, 101}, /* 1419 'e' */ - { 0xf0000000, 4, 121}, /* 1420 'y' */ - { 0xc0000000, 5, 110}, /* 1421 'n' */ - { 0xc8000000, 5, 111}, /* 1422 'o' */ - { 0xd8000000, 5, 114}, /* 1423 'r' */ - { 0xe8000000, 5, 32}, /* 1424 ' ' */ - { 0xd0000000, 6, 39}, /* 1425 '\'' */ - { 0xe0000000, 6, 117}, /* 1426 'u' */ - { 0xd6000000, 7, 46}, /* 1427 '.' */ - { 0xe6000000, 7, 108}, /* 1428 'l' */ - { 0xe5000000, 8, 104}, /* 1429 'h' */ - { 0xd4000000, 9, 84}, /* 1430 'T' */ - { 0xd5800000, 9, 71}, /* 1431 'G' */ - { 0xe4800000, 9, 44}, /* 1432 ',' */ - { 0xd5000000, 10, 119}, /* 1433 'w' */ - { 0xd4800000, 11, 53}, /* 1434 '5' */ - { 0xd4a00000, 11, 52}, /* 1435 '4' */ - { 0xd4c00000, 11, 65}, /* 1436 'A' */ - { 0xd5400000, 11, 51}, /* 1437 '3' */ - { 0xe4000000, 11, 50}, /* 1438 '2' */ - { 0xe4600000, 11, 77}, /* 1439 'M' */ - { 0xd4e00000, 12, 45}, /* 1440 '-' */ - { 0xd5600000, 12, 58}, /* 1441 ':' */ - { 0xd5700000, 12, 33}, /* 1442 '!' */ - { 0xe4200000, 12, 41}, /* 1443 ')' */ - { 0xe4500000, 12, 83}, /* 1444 'S' */ - { 0xd4f00000, 13, 86}, /* 1445 'V' */ - { 0xe4300000, 13, 54}, /* 1446 '6' */ - { 0xe4380000, 13, 49}, /* 1447 '1' */ - { 0xd4fc0000, 14, 76}, /* 1448 'L' */ - { 0xe4400000, 14, 73}, /* 1449 'I' */ - { 0xe4440000, 14, 63}, /* 1450 '?' */ - { 0xd4f80000, 15, 1}, /* 1451 '0x01' */ - { 0xd4fa0000, 15, 118}, /* 1452 'v' */ - { 0xe4480000, 15, 107}, /* 1453 'k' */ - { 0xe44a0000, 15, 89}, /* 1454 'Y' */ - { 0xe44c0000, 15, 78}, /* 1455 'N' */ - { 0xe44e0000, 15, 69}, /* 1456 'E' */ - /* 36 */ - { 0x00000000, 2, 105}, /* 1457 'i' */ - { 0x80000000, 2, 111}, /* 1458 'o' */ - { 0x60000000, 3, 93}, /* 1459 ']' */ - { 0xc0000000, 3, 101}, /* 1460 'e' */ - { 0xe0000000, 3, 97}, /* 1461 'a' */ - { 0x40000000, 4, 117}, /* 1462 'u' */ - { 0x50000000, 6, 108}, /* 1463 'l' */ - { 0x54000000, 6, 65}, /* 1464 'A' */ - { 0x5c000000, 6, 121}, /* 1465 'y' */ - { 0x5b000000, 8, 32}, /* 1466 ' ' */ - { 0x58000000, 9, 73}, /* 1467 'I' */ - { 0x58800000, 9, 82}, /* 1468 'R' */ - { 0x5a800000, 9, 44}, /* 1469 ',' */ - { 0x59000000, 10, 79}, /* 1470 'O' */ - { 0x59400000, 10, 39}, /* 1471 '\'' */ - { 0x59a00000, 11, 46}, /* 1472 '.' */ - { 0x59c00000, 11, 67}, /* 1473 'C' */ - { 0x59e00000, 11, 89}, /* 1474 'Y' */ - { 0x5a200000, 11, 70}, /* 1475 'F' */ - { 0x5a400000, 11, 76}, /* 1476 'L' */ - { 0x59900000, 12, 116}, /* 1477 't' */ - { 0x5a100000, 12, 71}, /* 1478 'G' */ - { 0x5a700000, 12, 83}, /* 1479 'S' */ - { 0x59880000, 13, 104}, /* 1480 'h' */ - { 0x5a080000, 13, 87}, /* 1481 'W' */ - { 0x5a600000, 13, 74}, /* 1482 'J' */ - { 0x59800000, 14, 69}, /* 1483 'E' */ - { 0x5a040000, 14, 34}, /* 1484 '\"' */ - { 0x5a6c0000, 14, 0}, /* 1485 '0x00' */ - { 0x59840000, 15, 84}, /* 1486 'T' */ - { 0x59860000, 15, 80}, /* 1487 'P' */ - { 0x5a000000, 15, 68}, /* 1488 'D' */ - { 0x5a020000, 15, 55}, /* 1489 '7' */ - { 0x5a6a0000, 15, 106}, /* 1490 'j' */ - { 0x5a680000, 16, 1}, /* 1491 '0x01' */ - { 0x5a690000, 16, 85}, /* 1492 'U' */ - /* 47 */ - { 0x00000000, 2, 111}, /* 1493 'o' */ - { 0xc0000000, 2, 97}, /* 1494 'a' */ - { 0x60000000, 3, 101}, /* 1495 'e' */ - { 0xa0000000, 3, 105}, /* 1496 'i' */ - { 0x50000000, 4, 99}, /* 1497 'c' */ - { 0x90000000, 4, 117}, /* 1498 'u' */ - { 0x48000000, 5, 121}, /* 1499 'y' */ - { 0x88000000, 5, 114}, /* 1500 'r' */ - { 0x80000000, 6, 83}, /* 1501 'S' */ - { 0x84000000, 6, 80}, /* 1502 'P' */ - { 0x42000000, 7, 32}, /* 1503 ' ' */ - { 0x41000000, 8, 67}, /* 1504 'C' */ - { 0x46000000, 8, 70}, /* 1505 'F' */ - { 0x40000000, 9, 49}, /* 1506 '1' */ - { 0x44000000, 9, 104}, /* 1507 'h' */ - { 0x45000000, 9, 73}, /* 1508 'I' */ - { 0x47000000, 9, 84}, /* 1509 'T' */ - { 0x47800000, 9, 88}, /* 1510 'X' */ - { 0x40800000, 10, 65}, /* 1511 'A' */ - { 0x44800000, 10, 122}, /* 1512 'z' */ - { 0x44c00000, 11, 102}, /* 1513 'f' */ - { 0x45c00000, 11, 46}, /* 1514 '.' */ - { 0x40c00000, 12, 90}, /* 1515 'Z' */ - { 0x40d00000, 12, 75}, /* 1516 'K' */ - { 0x40e00000, 12, 66}, /* 1517 'B' */ - { 0x44f00000, 12, 115}, /* 1518 's' */ - { 0x45800000, 12, 82}, /* 1519 'R' */ - { 0x45900000, 12, 87}, /* 1520 'W' */ - { 0x45a00000, 12, 79}, /* 1521 'O' */ - { 0x40f00000, 13, 44}, /* 1522 ',' */ - { 0x40f80000, 13, 39}, /* 1523 '\'' */ - { 0x45b80000, 13, 68}, /* 1524 'D' */ - { 0x45e00000, 13, 52}, /* 1525 '4' */ - { 0x45f00000, 13, 69}, /* 1526 'E' */ - { 0x44e00000, 14, 109}, /* 1527 'm' */ - { 0x44e40000, 14, 74}, /* 1528 'J' */ - { 0x44e80000, 14, 1}, /* 1529 '0x01' */ - { 0x45e80000, 14, 108}, /* 1530 'l' */ - { 0x45ec0000, 14, 45}, /* 1531 '-' */ - { 0x45f80000, 14, 41}, /* 1532 ')' */ - { 0x45fc0000, 14, 119}, /* 1533 'w' */ - { 0x44ec0000, 15, 116}, /* 1534 't' */ - { 0x44ee0000, 15, 86}, /* 1535 'V' */ - { 0x45b00000, 15, 81}, /* 1536 'Q' */ - { 0x45b20000, 15, 78}, /* 1537 'N' */ - { 0x45b40000, 15, 54}, /* 1538 '6' */ - { 0x45b60000, 15, 50}, /* 1539 '2' */ - /* 35 */ - { 0x00000000, 2, 97}, /* 1540 'a' */ - { 0x80000000, 2, 111}, /* 1541 'o' */ - { 0xc0000000, 2, 101}, /* 1542 'e' */ - { 0x60000000, 3, 105}, /* 1543 'i' */ - { 0x50000000, 5, 117}, /* 1544 'u' */ - { 0x58000000, 5, 69}, /* 1545 'E' */ - { 0x48000000, 6, 65}, /* 1546 'A' */ - { 0x44000000, 7, 121}, /* 1547 'y' */ - { 0x4c000000, 7, 103}, /* 1548 'g' */ - { 0x41000000, 8, 66}, /* 1549 'B' */ - { 0x42000000, 8, 73}, /* 1550 'I' */ - { 0x46000000, 8, 70}, /* 1551 'F' */ - { 0x47000000, 8, 32}, /* 1552 ' ' */ - { 0x40000000, 9, 41}, /* 1553 ')' */ - { 0x40800000, 9, 39}, /* 1554 '\'' */ - { 0x43800000, 9, 89}, /* 1555 'Y' */ - { 0x4e000000, 9, 76}, /* 1556 'L' */ - { 0x4e800000, 9, 72}, /* 1557 'H' */ - { 0x43000000, 10, 67}, /* 1558 'C' */ - { 0x4f000000, 10, 87}, /* 1559 'W' */ - { 0x4f800000, 10, 78}, /* 1560 'N' */ - { 0x4fc00000, 10, 84}, /* 1561 'T' */ - { 0x43500000, 12, 77}, /* 1562 'M' */ - { 0x43700000, 12, 79}, /* 1563 'O' */ - { 0x4f400000, 12, 44}, /* 1564 ',' */ - { 0x4f500000, 12, 74}, /* 1565 'J' */ - { 0x4f700000, 12, 104}, /* 1566 'h' */ - { 0x43400000, 13, 68}, /* 1567 'D' */ - { 0x43480000, 13, 46}, /* 1568 '.' */ - { 0x4f600000, 13, 88}, /* 1569 'X' */ - { 0x4f680000, 13, 1}, /* 1570 '0x01' */ - { 0x43600000, 14, 107}, /* 1571 'k' */ - { 0x43640000, 14, 90}, /* 1572 'Z' */ - { 0x43680000, 14, 81}, /* 1573 'Q' */ - { 0x436c0000, 14, 71}, /* 1574 'G' */ - /* 59 */ - { 0xe0000000, 3, 110}, /* 1575 'n' */ - { 0x00000000, 4, 115}, /* 1576 's' */ - { 0x10000000, 4, 78}, /* 1577 'N' */ - { 0x30000000, 4, 122}, /* 1578 'z' */ - { 0x40000000, 4, 114}, /* 1579 'r' */ - { 0x80000000, 4, 117}, /* 1580 'u' */ - { 0xa0000000, 4, 112}, /* 1581 'p' */ - { 0xb0000000, 4, 108}, /* 1582 'l' */ - { 0xd0000000, 4, 39}, /* 1583 '\'' */ - { 0x28000000, 5, 85}, /* 1584 'U' */ - { 0x58000000, 5, 104}, /* 1585 'h' */ - { 0x70000000, 5, 102}, /* 1586 'f' */ - { 0x78000000, 5, 119}, /* 1587 'w' */ - { 0x90000000, 5, 46}, /* 1588 '.' */ - { 0xc0000000, 5, 32}, /* 1589 ' ' */ - { 0x20000000, 6, 111}, /* 1590 'o' */ - { 0x24000000, 6, 74}, /* 1591 'J' */ - { 0x50000000, 6, 98}, /* 1592 'b' */ - { 0x54000000, 6, 109}, /* 1593 'm' */ - { 0x64000000, 6, 72}, /* 1594 'H' */ - { 0x68000000, 6, 79}, /* 1595 'O' */ - { 0x6c000000, 6, 118}, /* 1596 'v' */ - { 0x9c000000, 6, 99}, /* 1597 'c' */ - { 0xcc000000, 6, 120}, /* 1598 'x' */ - { 0x9a000000, 7, 100}, /* 1599 'd' */ - { 0xc8000000, 7, 97}, /* 1600 'a' */ - { 0x61000000, 8, 116}, /* 1601 't' */ - { 0x62000000, 8, 107}, /* 1602 'k' */ - { 0x98000000, 8, 103}, /* 1603 'g' */ - { 0xca000000, 8, 82}, /* 1604 'R' */ - { 0x60000000, 9, 75}, /* 1605 'K' */ - { 0x99000000, 9, 105}, /* 1606 'i' */ - { 0xcb800000, 9, 86}, /* 1607 'V' */ - { 0x60c00000, 10, 50}, /* 1608 '2' */ - { 0x63400000, 10, 83}, /* 1609 'S' */ - { 0x63800000, 10, 66}, /* 1610 'B' */ - { 0x99800000, 10, 87}, /* 1611 'W' */ - { 0x99c00000, 10, 45}, /* 1612 '-' */ - { 0x60800000, 11, 44}, /* 1613 ',' */ - { 0x63000000, 11, 106}, /* 1614 'j' */ - { 0x63200000, 11, 76}, /* 1615 'L' */ - { 0x63e00000, 11, 73}, /* 1616 'I' */ - { 0xcb200000, 11, 65}, /* 1617 'A' */ - { 0xcb600000, 11, 67}, /* 1618 'C' */ - { 0x60a00000, 12, 58}, /* 1619 ':' */ - { 0x63c00000, 12, 101}, /* 1620 'e' */ - { 0xcb000000, 12, 121}, /* 1621 'y' */ - { 0xcb100000, 12, 47}, /* 1622 '/' */ - { 0xcb400000, 12, 77}, /* 1623 'M' */ - { 0x60b00000, 13, 33}, /* 1624 '!' */ - { 0x63d80000, 13, 80}, /* 1625 'P' */ - { 0xcb580000, 13, 70}, /* 1626 'F' */ - { 0x60b80000, 14, 69}, /* 1627 'E' */ - { 0x60bc0000, 14, 68}, /* 1628 'D' */ - { 0x63d00000, 14, 56}, /* 1629 '8' */ - { 0x63d40000, 14, 52}, /* 1630 '4' */ - { 0xcb540000, 14, 84}, /* 1631 'T' */ - { 0xcb500000, 15, 1}, /* 1632 '0x01' */ - { 0xcb520000, 15, 113}, /* 1633 'q' */ - /* 39 */ - { 0xc0000000, 2, 97}, /* 1634 'a' */ - { 0x00000000, 3, 105}, /* 1635 'i' */ - { 0x40000000, 3, 101}, /* 1636 'e' */ - { 0x60000000, 3, 108}, /* 1637 'l' */ - { 0x80000000, 3, 111}, /* 1638 'o' */ - { 0xa0000000, 3, 114}, /* 1639 'r' */ - { 0x20000000, 4, 104}, /* 1640 'h' */ - { 0x3c000000, 6, 117}, /* 1641 'u' */ - { 0x34000000, 7, 67}, /* 1642 'C' */ - { 0x38000000, 7, 46}, /* 1643 '.' */ - { 0x3a000000, 7, 32}, /* 1644 ' ' */ - { 0x30000000, 8, 66}, /* 1645 'B' */ - { 0x32000000, 8, 68}, /* 1646 'D' */ - { 0x37000000, 8, 115}, /* 1647 's' */ - { 0x31800000, 9, 79}, /* 1648 'O' */ - { 0x33800000, 9, 44}, /* 1649 ',' */ - { 0x31400000, 10, 121}, /* 1650 'y' */ - { 0x33000000, 10, 77}, /* 1651 'M' */ - { 0x36000000, 10, 69}, /* 1652 'E' */ - { 0x36400000, 10, 39}, /* 1653 '\'' */ - { 0x36c00000, 10, 51}, /* 1654 '3' */ - { 0x31200000, 11, 84}, /* 1655 'T' */ - { 0x31000000, 12, 76}, /* 1656 'L' */ - { 0x31100000, 12, 71}, /* 1657 'G' */ - { 0x33400000, 12, 42}, /* 1658 '*' */ - { 0x33600000, 12, 65}, /* 1659 'A' */ - { 0x33700000, 12, 83}, /* 1660 'S' */ - { 0x36800000, 12, 119}, /* 1661 'w' */ - { 0x36900000, 12, 70}, /* 1662 'F' */ - { 0x33580000, 13, 74}, /* 1663 'J' */ - { 0x36a00000, 13, 102}, /* 1664 'f' */ - { 0x36a80000, 13, 82}, /* 1665 'R' */ - { 0x36b80000, 13, 116}, /* 1666 't' */ - { 0x33500000, 14, 86}, /* 1667 'V' */ - { 0x36b00000, 14, 89}, /* 1668 'Y' */ - { 0x36b40000, 14, 73}, /* 1669 'I' */ - { 0x33560000, 15, 38}, /* 1670 '&' */ - { 0x33540000, 16, 1}, /* 1671 '0x01' */ - { 0x33550000, 16, 41}, /* 1672 ')' */ - /* 13 */ - { 0x80000000, 1, 117}, /* 1673 'u' */ - { 0x00000000, 2, 86}, /* 1674 'V' */ - { 0x60000000, 3, 32}, /* 1675 ' ' */ - { 0x50000000, 4, 46}, /* 1676 '.' */ - { 0x40000000, 5, 97}, /* 1677 'a' */ - { 0x48000000, 7, 119}, /* 1678 'w' */ - { 0x4c000000, 7, 69}, /* 1679 'E' */ - { 0x4e000000, 7, 67}, /* 1680 'C' */ - { 0x4b000000, 8, 38}, /* 1681 '&' */ - { 0x4a800000, 9, 39}, /* 1682 '\'' */ - { 0x4a000000, 10, 84}, /* 1683 'T' */ - { 0x4a400000, 11, 1}, /* 1684 '0x01' */ - { 0x4a600000, 11, 115}, /* 1685 's' */ - /* 37 */ - { 0x40000000, 2, 97}, /* 1686 'a' */ - { 0xc0000000, 2, 111}, /* 1687 'o' */ - { 0x80000000, 3, 105}, /* 1688 'i' */ - { 0xa0000000, 3, 101}, /* 1689 'e' */ - { 0x00000000, 4, 112}, /* 1690 'p' */ - { 0x30000000, 4, 117}, /* 1691 'u' */ - { 0x18000000, 5, 69}, /* 1692 'E' */ - { 0x20000000, 5, 104}, /* 1693 'h' */ - { 0x10000000, 6, 32}, /* 1694 ' ' */ - { 0x28000000, 6, 121}, /* 1695 'y' */ - { 0x14000000, 8, 68}, /* 1696 'D' */ - { 0x16000000, 8, 46}, /* 1697 '.' */ - { 0x2c000000, 8, 84}, /* 1698 'T' */ - { 0x2e000000, 8, 83}, /* 1699 'S' */ - { 0x15000000, 9, 70}, /* 1700 'F' */ - { 0x2d000000, 9, 66}, /* 1701 'B' */ - { 0x2d800000, 9, 110}, /* 1702 'n' */ - { 0x2f800000, 9, 65}, /* 1703 'A' */ - { 0x15800000, 10, 119}, /* 1704 'w' */ - { 0x17000000, 10, 78}, /* 1705 'N' */ - { 0x17400000, 10, 38}, /* 1706 '&' */ - { 0x17800000, 10, 86}, /* 1707 'V' */ - { 0x17c00000, 10, 72}, /* 1708 'H' */ - { 0x2f400000, 10, 39}, /* 1709 '\'' */ - { 0x15c00000, 11, 116}, /* 1710 't' */ - { 0x15e00000, 11, 73}, /* 1711 'I' */ - { 0x2f000000, 12, 67}, /* 1712 'C' */ - { 0x2f200000, 12, 79}, /* 1713 'O' */ - { 0x2f100000, 14, 44}, /* 1714 ',' */ - { 0x2f140000, 14, 115}, /* 1715 's' */ - { 0x2f180000, 14, 85}, /* 1716 'U' */ - { 0x2f1c0000, 14, 77}, /* 1717 'M' */ - { 0x2f300000, 14, 45}, /* 1718 '-' */ - { 0x2f340000, 14, 1}, /* 1719 '0x01' */ - { 0x2f3c0000, 14, 58}, /* 1720 ':' */ - { 0x2f380000, 15, 50}, /* 1721 '2' */ - { 0x2f3a0000, 15, 82}, /* 1722 'R' */ - /* 59 */ - { 0x80000000, 1, 93}, /* 1723 ']' */ - { 0x00000000, 4, 97}, /* 1724 'a' */ - { 0x20000000, 4, 104}, /* 1725 'h' */ - { 0x70000000, 4, 116}, /* 1726 't' */ - { 0x10000000, 5, 112}, /* 1727 'p' */ - { 0x18000000, 5, 44}, /* 1728 ',' */ - { 0x30000000, 5, 76}, /* 1729 'L' */ - { 0x40000000, 5, 105}, /* 1730 'i' */ - { 0x48000000, 5, 117}, /* 1731 'u' */ - { 0x50000000, 5, 111}, /* 1732 'o' */ - { 0x58000000, 5, 99}, /* 1733 'c' */ - { 0x60000000, 5, 101}, /* 1734 'e' */ - { 0x3c000000, 6, 107}, /* 1735 'k' */ - { 0x38000000, 7, 119}, /* 1736 'w' */ - { 0x6a000000, 7, 32}, /* 1737 ' ' */ - { 0x6e000000, 7, 109}, /* 1738 'm' */ - { 0x3a000000, 8, 113}, /* 1739 'q' */ - { 0x68000000, 8, 77}, /* 1740 'M' */ - { 0x69000000, 8, 110}, /* 1741 'n' */ - { 0x6c000000, 8, 108}, /* 1742 'l' */ - { 0x3b000000, 9, 80}, /* 1743 'P' */ - { 0x6d800000, 9, 121}, /* 1744 'y' */ - { 0x3b800000, 10, 65}, /* 1745 'A' */ - { 0x6d200000, 11, 46}, /* 1746 '.' */ - { 0x3bd00000, 12, 114}, /* 1747 'r' */ - { 0x3be00000, 12, 83}, /* 1748 'S' */ - { 0x3bf00000, 12, 87}, /* 1749 'W' */ - { 0x6d000000, 12, 67}, /* 1750 'C' */ - { 0x6d500000, 12, 69}, /* 1751 'E' */ - { 0x6d600000, 12, 118}, /* 1752 'v' */ - { 0x6d180000, 13, 1}, /* 1753 '0x01' */ - { 0x6d400000, 13, 73}, /* 1754 'I' */ - { 0x6d780000, 13, 103}, /* 1755 'g' */ - { 0x3bc00000, 14, 42}, /* 1756 '*' */ - { 0x3bc80000, 14, 52}, /* 1757 '4' */ - { 0x3bcc0000, 14, 49}, /* 1758 '1' */ - { 0x6d100000, 14, 79}, /* 1759 'O' */ - { 0x6d480000, 14, 0}, /* 1760 '0x00' */ - { 0x6d700000, 14, 122}, /* 1761 'z' */ - { 0x6d160000, 15, 66}, /* 1762 'B' */ - { 0x6d740000, 15, 72}, /* 1763 'H' */ - { 0x6d760000, 15, 84}, /* 1764 'T' */ - { 0x3bc40000, 16, 71}, /* 1765 'G' */ - { 0x3bc60000, 16, 125}, /* 1766 '}' */ - { 0x3bc70000, 16, 68}, /* 1767 'D' */ - { 0x6d140000, 16, 45}, /* 1768 '-' */ - { 0x6d4c0000, 16, 51}, /* 1769 '3' */ - { 0x6d4d0000, 16, 50}, /* 1770 '2' */ - { 0x3bc50000, 17, 39}, /* 1771 '\'' */ - { 0x3bc58000, 17, 63}, /* 1772 '?' */ - { 0x6d4e8000, 17, 115}, /* 1773 's' */ - { 0x6d4f0000, 17, 106}, /* 1774 'j' */ - { 0x6d4f8000, 17, 98}, /* 1775 'b' */ - { 0x6d150000, 18, 82}, /* 1776 'R' */ - { 0x6d154000, 18, 75}, /* 1777 'K' */ - { 0x6d158000, 18, 74}, /* 1778 'J' */ - { 0x6d15c000, 18, 70}, /* 1779 'F' */ - { 0x6d4e0000, 18, 58}, /* 1780 ':' */ - { 0x6d4e4000, 18, 41}, /* 1781 ')' */ - /* 44 */ - { 0x00000000, 1, 104}, /* 1782 'h' */ - { 0x80000000, 3, 111}, /* 1783 'o' */ - { 0xa0000000, 4, 86}, /* 1784 'V' */ - { 0xb0000000, 4, 119}, /* 1785 'w' */ - { 0xc0000000, 4, 114}, /* 1786 'r' */ - { 0xf0000000, 4, 101}, /* 1787 'e' */ - { 0xd0000000, 5, 97}, /* 1788 'a' */ - { 0xd8000000, 5, 105}, /* 1789 'i' */ - { 0xe0000000, 5, 117}, /* 1790 'u' */ - { 0xe8000000, 7, 72}, /* 1791 'H' */ - { 0xec000000, 7, 87}, /* 1792 'W' */ - { 0xea000000, 8, 32}, /* 1793 ' ' */ - { 0xeb000000, 8, 121}, /* 1794 'y' */ - { 0xee800000, 9, 77}, /* 1795 'M' */ - { 0xef800000, 9, 120}, /* 1796 'x' */ - { 0xee000000, 10, 83}, /* 1797 'S' */ - { 0xee400000, 11, 65}, /* 1798 'A' */ - { 0xef200000, 11, 115}, /* 1799 's' */ - { 0xef600000, 11, 74}, /* 1800 'J' */ - { 0xee700000, 12, 88}, /* 1801 'X' */ - { 0xef000000, 12, 46}, /* 1802 '.' */ - { 0xee680000, 13, 45}, /* 1803 '-' */ - { 0xef180000, 13, 76}, /* 1804 'L' */ - { 0xef400000, 13, 67}, /* 1805 'C' */ - { 0xef580000, 13, 99}, /* 1806 'c' */ - { 0xee600000, 14, 84}, /* 1807 'T' */ - { 0xee640000, 14, 85}, /* 1808 'U' */ - { 0xef140000, 14, 52}, /* 1809 '4' */ - { 0xef480000, 14, 79}, /* 1810 'O' */ - { 0xef120000, 15, 71}, /* 1811 'G' */ - { 0xef4c0000, 15, 69}, /* 1812 'E' */ - { 0xef4e0000, 15, 44}, /* 1813 ',' */ - { 0xef540000, 15, 39}, /* 1814 '\'' */ - { 0xef110000, 16, 59}, /* 1815 ';' */ - { 0xef500000, 16, 80}, /* 1816 'P' */ - { 0xef510000, 16, 49}, /* 1817 '1' */ - { 0xef520000, 16, 1}, /* 1818 '0x01' */ - { 0xef570000, 16, 68}, /* 1819 'D' */ - { 0xef100000, 17, 58}, /* 1820 ':' */ - { 0xef108000, 17, 42}, /* 1821 '*' */ - { 0xef530000, 17, 82}, /* 1822 'R' */ - { 0xef538000, 17, 78}, /* 1823 'N' */ - { 0xef560000, 17, 73}, /* 1824 'I' */ - { 0xef568000, 17, 66}, /* 1825 'B' */ - /* 45 */ - { 0x00000000, 2, 75}, /* 1826 'K' */ - { 0x80000000, 2, 110}, /* 1827 'n' */ - { 0x60000000, 3, 83}, /* 1828 'S' */ - { 0xc0000000, 3, 112}, /* 1829 'p' */ - { 0xf0000000, 4, 108}, /* 1830 'l' */ - { 0x50000000, 5, 115}, /* 1831 's' */ - { 0x58000000, 5, 114}, /* 1832 'r' */ - { 0xe8000000, 5, 82}, /* 1833 'R' */ - { 0x40000000, 6, 103}, /* 1834 'g' */ - { 0xe0000000, 6, 32}, /* 1835 ' ' */ - { 0x4e000000, 7, 46}, /* 1836 '.' */ - { 0xe4000000, 7, 109}, /* 1837 'm' */ - { 0x44000000, 8, 107}, /* 1838 'k' */ - { 0x45000000, 8, 116}, /* 1839 't' */ - { 0x46000000, 8, 69}, /* 1840 'E' */ - { 0x47000000, 8, 45}, /* 1841 '-' */ - { 0x48000000, 8, 70}, /* 1842 'F' */ - { 0x4c000000, 8, 50}, /* 1843 '2' */ - { 0xe6000000, 8, 99}, /* 1844 'c' */ - { 0xe7000000, 8, 78}, /* 1845 'N' */ - { 0x49000000, 9, 102}, /* 1846 'f' */ - { 0x49800000, 9, 56}, /* 1847 '8' */ - { 0x4a000000, 9, 44}, /* 1848 ',' */ - { 0x4b800000, 9, 90}, /* 1849 'Z' */ - { 0x4a800000, 10, 104}, /* 1850 'h' */ - { 0x4d000000, 10, 105}, /* 1851 'i' */ - { 0x4d400000, 10, 119}, /* 1852 'w' */ - { 0x4d800000, 10, 97}, /* 1853 'a' */ - { 0x4ac00000, 11, 98}, /* 1854 'b' */ - { 0x4ae00000, 11, 68}, /* 1855 'D' */ - { 0x4dc00000, 11, 33}, /* 1856 '!' */ - { 0x4b000000, 12, 101}, /* 1857 'e' */ - { 0x4b100000, 12, 86}, /* 1858 'V' */ - { 0x4b200000, 12, 80}, /* 1859 'P' */ - { 0x4b300000, 12, 73}, /* 1860 'I' */ - { 0x4b400000, 12, 66}, /* 1861 'B' */ - { 0x4b500000, 12, 65}, /* 1862 'A' */ - { 0x4df00000, 12, 100}, /* 1863 'd' */ - { 0x4b600000, 13, 72}, /* 1864 'H' */ - { 0x4b680000, 13, 67}, /* 1865 'C' */ - { 0x4b700000, 13, 58}, /* 1866 ':' */ - { 0x4b780000, 13, 41}, /* 1867 ')' */ - { 0x4de80000, 13, 122}, /* 1868 'z' */ - { 0x4de00000, 14, 1}, /* 1869 '0x01' */ - { 0x4de40000, 14, 84}, /* 1870 'T' */ - /* 38 */ - { 0x40000000, 2, 32}, /* 1871 ' ' */ - { 0xc0000000, 2, 105}, /* 1872 'i' */ - { 0x00000000, 3, 46}, /* 1873 '.' */ - { 0x20000000, 3, 97}, /* 1874 'a' */ - { 0xa0000000, 3, 101}, /* 1875 'e' */ - { 0x88000000, 5, 67}, /* 1876 'C' */ - { 0x98000000, 5, 111}, /* 1877 'o' */ - { 0x82000000, 7, 70}, /* 1878 'F' */ - { 0x86000000, 7, 73}, /* 1879 'I' */ - { 0x81000000, 8, 49}, /* 1880 '1' */ - { 0x85000000, 8, 52}, /* 1881 '4' */ - { 0x90000000, 8, 114}, /* 1882 'r' */ - { 0x92000000, 8, 69}, /* 1883 'E' */ - { 0x93000000, 8, 115}, /* 1884 's' */ - { 0x95000000, 8, 39}, /* 1885 '\'' */ - { 0x96000000, 8, 58}, /* 1886 ':' */ - { 0x97000000, 8, 108}, /* 1887 'l' */ - { 0x80800000, 9, 47}, /* 1888 '/' */ - { 0x84800000, 9, 45}, /* 1889 '-' */ - { 0x91000000, 9, 68}, /* 1890 'D' */ - { 0x91800000, 9, 117}, /* 1891 'u' */ - { 0x94800000, 9, 44}, /* 1892 ',' */ - { 0x80000000, 10, 54}, /* 1893 '6' */ - { 0x80400000, 10, 50}, /* 1894 '2' */ - { 0x84000000, 10, 53}, /* 1895 '5' */ - { 0x94000000, 10, 59}, /* 1896 ';' */ - { 0x94400000, 11, 1}, /* 1897 '0x01' */ - { 0x84400000, 12, 55}, /* 1898 '7' */ - { 0x94600000, 12, 51}, /* 1899 '3' */ - { 0x84500000, 13, 57}, /* 1900 '9' */ - { 0x84580000, 13, 121}, /* 1901 'y' */ - { 0x84600000, 13, 80}, /* 1902 'P' */ - { 0x84680000, 13, 72}, /* 1903 'H' */ - { 0x84700000, 13, 65}, /* 1904 'A' */ - { 0x84780000, 13, 56}, /* 1905 '8' */ - { 0x94780000, 13, 87}, /* 1906 'W' */ - { 0x94700000, 14, 102}, /* 1907 'f' */ - { 0x94740000, 14, 66}, /* 1908 'B' */ - /* 30 */ - { 0x00000000, 2, 104}, /* 1909 'h' */ - { 0x80000000, 2, 105}, /* 1910 'i' */ - { 0x60000000, 3, 97}, /* 1911 'a' */ - { 0xc0000000, 3, 111}, /* 1912 'o' */ - { 0xe0000000, 3, 101}, /* 1913 'e' */ - { 0x40000000, 4, 114}, /* 1914 'r' */ - { 0x58000000, 5, 79}, /* 1915 'O' */ - { 0x52000000, 7, 32}, /* 1916 ' ' */ - { 0x54000000, 7, 121}, /* 1917 'y' */ - { 0x50000000, 9, 66}, /* 1918 'B' */ - { 0x50800000, 9, 46}, /* 1919 '.' */ - { 0x56000000, 9, 73}, /* 1920 'I' */ - { 0x57000000, 9, 87}, /* 1921 'W' */ - { 0x57800000, 9, 65}, /* 1922 'A' */ - { 0x51000000, 10, 39}, /* 1923 '\'' */ - { 0x51400000, 10, 77}, /* 1924 'M' */ - { 0x51c00000, 10, 84}, /* 1925 'T' */ - { 0x51800000, 11, 50}, /* 1926 '2' */ - { 0x51a00000, 11, 58}, /* 1927 ':' */ - { 0x56800000, 11, 72}, /* 1928 'H' */ - { 0x56c00000, 11, 86}, /* 1929 'V' */ - { 0x56a00000, 12, 108}, /* 1930 'l' */ - { 0x56e00000, 12, 115}, /* 1931 's' */ - { 0x56f00000, 12, 44}, /* 1932 ',' */ - { 0x56b80000, 13, 117}, /* 1933 'u' */ - { 0x56b00000, 15, 53}, /* 1934 '5' */ - { 0x56b20000, 15, 41}, /* 1935 ')' */ - { 0x56b60000, 15, 69}, /* 1936 'E' */ - { 0x56b40000, 16, 1}, /* 1937 '0x01' */ - { 0x56b50000, 16, 109}, /* 1938 'm' */ - /* 24 */ - { 0x80000000, 1, 32}, /* 1939 ' ' */ - { 0x00000000, 3, 97}, /* 1940 'a' */ - { 0x20000000, 4, 122}, /* 1941 'z' */ - { 0x30000000, 4, 109}, /* 1942 'm' */ - { 0x70000000, 4, 116}, /* 1943 't' */ - { 0x48000000, 5, 85}, /* 1944 'U' */ - { 0x50000000, 5, 45}, /* 1945 '-' */ - { 0x58000000, 5, 101}, /* 1946 'e' */ - { 0x60000000, 6, 117}, /* 1947 'u' */ - { 0x64000000, 6, 73}, /* 1948 'I' */ - { 0x6c000000, 6, 44}, /* 1949 ',' */ - { 0x44000000, 7, 86}, /* 1950 'V' */ - { 0x68000000, 7, 53}, /* 1951 '5' */ - { 0x6a000000, 7, 46}, /* 1952 '.' */ - { 0x40000000, 8, 83}, /* 1953 'S' */ - { 0x42000000, 8, 58}, /* 1954 ':' */ - { 0x46000000, 8, 99}, /* 1955 'c' */ - { 0x47000000, 8, 105}, /* 1956 'i' */ - { 0x41000000, 9, 57}, /* 1957 '9' */ - { 0x41800000, 9, 39}, /* 1958 '\'' */ - { 0x43800000, 9, 88}, /* 1959 'X' */ - { 0x43000000, 10, 41}, /* 1960 ')' */ - { 0x43400000, 11, 1}, /* 1961 '0x01' */ - { 0x43600000, 11, 121}, /* 1962 'y' */ - /* 24 */ - { 0x80000000, 1, 111}, /* 1963 'o' */ - { 0x00000000, 2, 101}, /* 1964 'e' */ - { 0x40000000, 3, 117}, /* 1965 'u' */ - { 0x60000000, 5, 97}, /* 1966 'a' */ - { 0x70000000, 5, 118}, /* 1967 'v' */ - { 0x78000000, 5, 32}, /* 1968 ' ' */ - { 0x68000000, 7, 110}, /* 1969 'n' */ - { 0x6a000000, 8, 114}, /* 1970 'r' */ - { 0x6d000000, 8, 79}, /* 1971 'O' */ - { 0x6f000000, 8, 105}, /* 1972 'i' */ - { 0x6b800000, 9, 78}, /* 1973 'N' */ - { 0x6c000000, 9, 76}, /* 1974 'L' */ - { 0x6c800000, 9, 115}, /* 1975 's' */ - { 0x6e800000, 9, 109}, /* 1976 'm' */ - { 0x6b000000, 10, 46}, /* 1977 '.' */ - { 0x6b400000, 10, 77}, /* 1978 'M' */ - { 0x6e400000, 10, 80}, /* 1979 'P' */ - { 0x6e100000, 12, 82}, /* 1980 'R' */ - { 0x6e200000, 12, 50}, /* 1981 '2' */ - { 0x6e000000, 13, 45}, /* 1982 '-' */ - { 0x6e300000, 13, 67}, /* 1983 'C' */ - { 0x6e380000, 13, 44}, /* 1984 ',' */ - { 0x6e080000, 14, 1}, /* 1985 '0x01' */ - { 0x6e0c0000, 14, 100}, /* 1986 'd' */ - /* 18 */ - { 0x40000000, 2, 97}, /* 1987 'a' */ - { 0x80000000, 2, 101}, /* 1988 'e' */ - { 0xc0000000, 2, 111}, /* 1989 'o' */ - { 0x20000000, 4, 122}, /* 1990 'z' */ - { 0x30000000, 4, 105}, /* 1991 'i' */ - { 0x08000000, 5, 90}, /* 1992 'Z' */ - { 0x10000000, 5, 32}, /* 1993 ' ' */ - { 0x18000000, 5, 117}, /* 1994 'u' */ - { 0x04000000, 7, 79}, /* 1995 'O' */ - { 0x06000000, 7, 46}, /* 1996 '.' */ - { 0x00000000, 8, 121}, /* 1997 'y' */ - { 0x01000000, 8, 52}, /* 1998 '4' */ - { 0x02000000, 8, 44}, /* 1999 ',' */ - { 0x03000000, 10, 102}, /* 2000 'f' */ - { 0x03400000, 10, 45}, /* 2001 '-' */ - { 0x03800000, 10, 0}, /* 2002 '0x00' */ - { 0x03c00000, 11, 1}, /* 2003 '0x01' */ - { 0x03e00000, 11, 108}, /* 2004 'l' */ - /* 34 */ - { 0x80000000, 1, 83}, /* 2005 'S' */ - { 0x40000000, 2, 65}, /* 2006 'A' */ - { 0x00000000, 4, 50}, /* 2007 '2' */ - { 0x20000000, 4, 82}, /* 2008 'R' */ - { 0x30000000, 4, 49}, /* 2009 '1' */ - { 0x14000000, 6, 110}, /* 2010 'n' */ - { 0x18000000, 6, 109}, /* 2011 'm' */ - { 0x1e000000, 7, 108}, /* 2012 'l' */ - { 0x13000000, 8, 114}, /* 2013 'r' */ - { 0x1d000000, 8, 98}, /* 2014 'b' */ - { 0x10800000, 9, 67}, /* 2015 'C' */ - { 0x11000000, 9, 102}, /* 2016 'f' */ - { 0x12800000, 9, 77}, /* 2017 'M' */ - { 0x1c800000, 9, 99}, /* 2018 'c' */ - { 0x10400000, 10, 0}, /* 2019 '0x00' */ - { 0x11c00000, 10, 75}, /* 2020 'K' */ - { 0x12000000, 10, 72}, /* 2021 'H' */ - { 0x1c400000, 10, 84}, /* 2022 'T' */ - { 0x10000000, 11, 74}, /* 2023 'J' */ - { 0x10200000, 11, 66}, /* 2024 'B' */ - { 0x11a00000, 11, 90}, /* 2025 'Z' */ - { 0x12600000, 11, 80}, /* 2026 'P' */ - { 0x1c000000, 11, 76}, /* 2027 'L' */ - { 0x11800000, 12, 70}, /* 2028 'F' */ - { 0x12500000, 12, 73}, /* 2029 'I' */ - { 0x1c300000, 12, 78}, /* 2030 'N' */ - { 0x11900000, 13, 115}, /* 2031 's' */ - { 0x11980000, 13, 86}, /* 2032 'V' */ - { 0x12400000, 13, 85}, /* 2033 'U' */ - { 0x12480000, 13, 71}, /* 2034 'G' */ - { 0x1c280000, 13, 68}, /* 2035 'D' */ - { 0x1c200000, 14, 79}, /* 2036 'O' */ - { 0x1c240000, 15, 1}, /* 2037 '0x01' */ - { 0x1c260000, 15, 87}, /* 2038 'W' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 2039 '0x01' */ - { 0x80000000, 1, 120}, /* 2040 'x' */ - /* 9 */ - { 0x80000000, 1, 0}, /* 2041 '0x00' */ - { 0x40000000, 2, 32}, /* 2042 ' ' */ - { 0x20000000, 3, 46}, /* 2043 '.' */ - { 0x10000000, 4, 91}, /* 2044 '[' */ - { 0x08000000, 5, 58}, /* 2045 ':' */ - { 0x04000000, 6, 44}, /* 2046 ',' */ - { 0x02000000, 7, 59}, /* 2047 ';' */ - { 0x00000000, 8, 1}, /* 2048 '0x01' */ - { 0x01000000, 8, 93}, /* 2049 ']' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 2050 '0x01' */ - { 0x80000000, 1, 1}, /* 2051 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 2052 '0x01' */ - { 0x80000000, 1, 1}, /* 2053 '0x01' */ - /* 31 */ - { 0x20000000, 3, 119}, /* 2054 'w' */ - { 0x60000000, 3, 72}, /* 2055 'H' */ - { 0xc0000000, 3, 80}, /* 2056 'P' */ - { 0xe0000000, 3, 70}, /* 2057 'F' */ - { 0x50000000, 4, 110}, /* 2058 'n' */ - { 0xb0000000, 4, 68}, /* 2059 'D' */ - { 0x08000000, 5, 115}, /* 2060 's' */ - { 0x10000000, 5, 65}, /* 2061 'A' */ - { 0x48000000, 5, 116}, /* 2062 't' */ - { 0x80000000, 5, 103}, /* 2063 'g' */ - { 0x98000000, 5, 99}, /* 2064 'c' */ - { 0x00000000, 6, 87}, /* 2065 'W' */ - { 0x04000000, 6, 114}, /* 2066 'r' */ - { 0x18000000, 6, 101}, /* 2067 'e' */ - { 0x1c000000, 6, 67}, /* 2068 'C' */ - { 0x8c000000, 6, 108}, /* 2069 'l' */ - { 0x90000000, 6, 104}, /* 2070 'h' */ - { 0x94000000, 6, 71}, /* 2071 'G' */ - { 0xa4000000, 6, 66}, /* 2072 'B' */ - { 0xa8000000, 6, 84}, /* 2073 'T' */ - { 0xac000000, 6, 83}, /* 2074 'S' */ - { 0x40000000, 7, 111}, /* 2075 'o' */ - { 0x42000000, 7, 100}, /* 2076 'd' */ - { 0x44000000, 7, 98}, /* 2077 'b' */ - { 0x46000000, 7, 82}, /* 2078 'R' */ - { 0x88000000, 7, 79}, /* 2079 'O' */ - { 0x8a000000, 7, 76}, /* 2080 'L' */ - { 0xa2000000, 7, 102}, /* 2081 'f' */ - { 0xa0000000, 8, 74}, /* 2082 'J' */ - { 0xa1000000, 9, 1}, /* 2083 '0x01' */ - { 0xa1800000, 9, 77}, /* 2084 'M' */ - /* 51 */ - { 0x40000000, 2, 110}, /* 2085 'n' */ - { 0x20000000, 3, 114}, /* 2086 'r' */ - { 0xa0000000, 3, 116}, /* 2087 't' */ - { 0x00000000, 4, 109}, /* 2088 'm' */ - { 0x90000000, 4, 115}, /* 2089 's' */ - { 0xe0000000, 4, 32}, /* 2090 ' ' */ - { 0xf0000000, 4, 108}, /* 2091 'l' */ - { 0x18000000, 5, 100}, /* 2092 'd' */ - { 0x80000000, 5, 105}, /* 2093 'i' */ - { 0xc0000000, 5, 121}, /* 2094 'y' */ - { 0xd0000000, 5, 99}, /* 2095 'c' */ - { 0x10000000, 6, 112}, /* 2096 'p' */ - { 0x88000000, 6, 117}, /* 2097 'u' */ - { 0x8c000000, 6, 118}, /* 2098 'v' */ - { 0xcc000000, 6, 103}, /* 2099 'g' */ - { 0xd8000000, 6, 98}, /* 2100 'b' */ - { 0xdc000000, 6, 107}, /* 2101 'k' */ - { 0x14000000, 7, 119}, /* 2102 'w' */ - { 0x17000000, 8, 122}, /* 2103 'z' */ - { 0xc8000000, 8, 46}, /* 2104 '.' */ - { 0xcb000000, 8, 102}, /* 2105 'f' */ - { 0x16000000, 9, 44}, /* 2106 ',' */ - { 0x16800000, 9, 39}, /* 2107 '\'' */ - { 0xc9800000, 9, 101}, /* 2108 'e' */ - { 0xca800000, 9, 104}, /* 2109 'h' */ - { 0xca400000, 10, 120}, /* 2110 'x' */ - { 0xc9000000, 11, 97}, /* 2111 'a' */ - { 0xc9200000, 11, 45}, /* 2112 '-' */ - { 0xc9600000, 11, 106}, /* 2113 'j' */ - { 0xca000000, 11, 58}, /* 2114 ':' */ - { 0xca200000, 11, 111}, /* 2115 'o' */ - { 0xc9400000, 12, 113}, /* 2116 'q' */ - { 0xc9500000, 14, 33}, /* 2117 '!' */ - { 0xc95c0000, 14, 63}, /* 2118 '?' */ - { 0xc9540000, 16, 1}, /* 2119 '0x01' */ - { 0xc9560000, 16, 59}, /* 2120 ';' */ - { 0xc9570000, 16, 41}, /* 2121 ')' */ - { 0xc9590000, 16, 47}, /* 2122 '/' */ - { 0xc95b0000, 16, 64}, /* 2123 '@' */ - { 0xc9550000, 17, 74}, /* 2124 'J' */ - { 0xc9558000, 17, 93}, /* 2125 ']' */ - { 0xc95a0000, 17, 78}, /* 2126 'N' */ - { 0xc95a8000, 17, 76}, /* 2127 'L' */ - { 0xc9580000, 18, 82}, /* 2128 'R' */ - { 0xc9584000, 18, 83}, /* 2129 'S' */ - { 0xc9588000, 18, 86}, /* 2130 'V' */ - { 0xc958c000, 20, 91}, /* 2131 '[' */ - { 0xc958e000, 20, 80}, /* 2132 'P' */ - { 0xc958f000, 20, 0}, /* 2133 '0x00' */ - { 0xc958d000, 21, 87}, /* 2134 'W' */ - { 0xc958d800, 21, 49}, /* 2135 '1' */ - /* 39 */ - { 0x00000000, 2, 101}, /* 2136 'e' */ - { 0x40000000, 3, 117}, /* 2137 'u' */ - { 0x60000000, 3, 97}, /* 2138 'a' */ - { 0x80000000, 3, 121}, /* 2139 'y' */ - { 0xa0000000, 3, 111}, /* 2140 'o' */ - { 0xc0000000, 4, 108}, /* 2141 'l' */ - { 0xe0000000, 4, 114}, /* 2142 'r' */ - { 0xf0000000, 4, 105}, /* 2143 'i' */ - { 0xd0000000, 6, 115}, /* 2144 's' */ - { 0xd8000000, 6, 32}, /* 2145 ' ' */ - { 0xdc000000, 6, 98}, /* 2146 'b' */ - { 0xd5000000, 8, 99}, /* 2147 'c' */ - { 0xd4000000, 9, 106}, /* 2148 'j' */ - { 0xd6000000, 9, 44}, /* 2149 ',' */ - { 0xd6800000, 9, 46}, /* 2150 '.' */ - { 0xd4c00000, 10, 39}, /* 2151 '\'' */ - { 0xd7c00000, 10, 116}, /* 2152 't' */ - { 0xd4a00000, 11, 58}, /* 2153 ':' */ - { 0xd7000000, 11, 119}, /* 2154 'w' */ - { 0xd7200000, 11, 100}, /* 2155 'd' */ - { 0xd7400000, 11, 104}, /* 2156 'h' */ - { 0xd7600000, 11, 38}, /* 2157 '&' */ - { 0xd7a00000, 11, 45}, /* 2158 '-' */ - { 0xd7800000, 12, 109}, /* 2159 'm' */ - { 0xd7900000, 12, 110}, /* 2160 'n' */ - { 0xd4800000, 13, 63}, /* 2161 '?' */ - { 0xd4900000, 13, 118}, /* 2162 'v' */ - { 0xd4880000, 14, 102}, /* 2163 'f' */ - { 0xd49c0000, 14, 112}, /* 2164 'p' */ - { 0xd48e0000, 15, 59}, /* 2165 ';' */ - { 0xd49a0000, 15, 68}, /* 2166 'D' */ - { 0xd48c0000, 16, 47}, /* 2167 '/' */ - { 0xd4990000, 16, 64}, /* 2168 '@' */ - { 0xd48d0000, 17, 88}, /* 2169 'X' */ - { 0xd48d8000, 17, 34}, /* 2170 '\"' */ - { 0xd4988000, 17, 107}, /* 2171 'k' */ - { 0xd4980000, 18, 0}, /* 2172 '0x00' */ - { 0xd4984000, 19, 1}, /* 2173 '0x01' */ - { 0xd4986000, 19, 33}, /* 2174 '!' */ - /* 57 */ - { 0x00000000, 2, 111}, /* 2175 'o' */ - { 0x60000000, 3, 97}, /* 2176 'a' */ - { 0x80000000, 3, 101}, /* 2177 'e' */ - { 0xc0000000, 3, 104}, /* 2178 'h' */ - { 0x40000000, 4, 105}, /* 2179 'i' */ - { 0x50000000, 4, 108}, /* 2180 'l' */ - { 0xb0000000, 4, 107}, /* 2181 'k' */ - { 0xf0000000, 4, 116}, /* 2182 't' */ - { 0xa0000000, 5, 117}, /* 2183 'u' */ - { 0xa8000000, 5, 114}, /* 2184 'r' */ - { 0xe0000000, 5, 32}, /* 2185 ' ' */ - { 0xe8000000, 7, 121}, /* 2186 'y' */ - { 0xea000000, 7, 99}, /* 2187 'c' */ - { 0xed000000, 8, 115}, /* 2188 's' */ - { 0xee000000, 8, 46}, /* 2189 '.' */ - { 0xef800000, 9, 44}, /* 2190 ',' */ - { 0xec400000, 10, 71}, /* 2191 'G' */ - { 0xec200000, 11, 110}, /* 2192 'n' */ - { 0xecc00000, 11, 68}, /* 2193 'D' */ - { 0xef000000, 11, 75}, /* 2194 'K' */ - { 0xef600000, 11, 67}, /* 2195 'C' */ - { 0xec000000, 12, 58}, /* 2196 ':' */ - { 0xec900000, 12, 45}, /* 2197 '-' */ - { 0xeca00000, 12, 65}, /* 2198 'A' */ - { 0xece00000, 12, 76}, /* 2199 'L' */ - { 0xecf00000, 12, 39}, /* 2200 '\'' */ - { 0xef200000, 12, 100}, /* 2201 'd' */ - { 0xef400000, 12, 113}, /* 2202 'q' */ - { 0xef500000, 12, 73}, /* 2203 'I' */ - { 0xec800000, 13, 78}, /* 2204 'N' */ - { 0xec880000, 13, 122}, /* 2205 'z' */ - { 0xef380000, 13, 70}, /* 2206 'F' */ - { 0xec140000, 14, 119}, /* 2207 'w' */ - { 0xec1c0000, 14, 69}, /* 2208 'E' */ - { 0xecb00000, 14, 63}, /* 2209 '?' */ - { 0xef300000, 14, 77}, /* 2210 'M' */ - { 0xef340000, 14, 83}, /* 2211 'S' */ - { 0xec100000, 15, 98}, /* 2212 'b' */ - { 0xec120000, 15, 1}, /* 2213 '0x01' */ - { 0xec180000, 15, 33}, /* 2214 '!' */ - { 0xecb40000, 15, 81}, /* 2215 'Q' */ - { 0xecb60000, 15, 80}, /* 2216 'P' */ - { 0xecb80000, 15, 59}, /* 2217 ';' */ - { 0xecbc0000, 15, 66}, /* 2218 'B' */ - { 0xec1b0000, 16, 86}, /* 2219 'V' */ - { 0xecbb0000, 16, 109}, /* 2220 'm' */ - { 0xecbe0000, 16, 47}, /* 2221 '/' */ - { 0xec1a8000, 17, 41}, /* 2222 ')' */ - { 0xecba0000, 17, 85}, /* 2223 'U' */ - { 0xecbf0000, 17, 87}, /* 2224 'W' */ - { 0xec1a0000, 18, 112}, /* 2225 'p' */ - { 0xec1a4000, 18, 72}, /* 2226 'H' */ - { 0xecba8000, 18, 0}, /* 2227 '0x00' */ - { 0xecbf8000, 18, 82}, /* 2228 'R' */ - { 0xecbfc000, 18, 84}, /* 2229 'T' */ - { 0xecbac000, 19, 93}, /* 2230 ']' */ - { 0xecbae000, 19, 91}, /* 2231 '[' */ - /* 46 */ - { 0x00000000, 1, 32}, /* 2232 ' ' */ - { 0xa0000000, 3, 101}, /* 2233 'e' */ - { 0xc0000000, 4, 97}, /* 2234 'a' */ - { 0xe0000000, 4, 105}, /* 2235 'i' */ - { 0x88000000, 5, 46}, /* 2236 '.' */ - { 0x98000000, 5, 111}, /* 2237 'o' */ - { 0xd8000000, 5, 114}, /* 2238 'r' */ - { 0xf8000000, 5, 115}, /* 2239 's' */ - { 0x84000000, 6, 100}, /* 2240 'd' */ - { 0x94000000, 6, 108}, /* 2241 'l' */ - { 0xd0000000, 6, 117}, /* 2242 'u' */ - { 0xf4000000, 6, 121}, /* 2243 'y' */ - { 0x92000000, 7, 45}, /* 2244 '-' */ - { 0xd6000000, 7, 118}, /* 2245 'v' */ - { 0xf0000000, 7, 103}, /* 2246 'g' */ - { 0xf2000000, 7, 44}, /* 2247 ',' */ - { 0x80000000, 8, 104}, /* 2248 'h' */ - { 0x81000000, 8, 58}, /* 2249 ':' */ - { 0x82000000, 8, 109}, /* 2250 'm' */ - { 0x90000000, 8, 119}, /* 2251 'w' */ - { 0x91000000, 8, 110}, /* 2252 'n' */ - { 0xd5000000, 8, 39}, /* 2253 '\'' */ - { 0x83800000, 9, 102}, /* 2254 'f' */ - { 0xd4400000, 10, 63}, /* 2255 '?' */ - { 0xd4800000, 10, 98}, /* 2256 'b' */ - { 0xd4c00000, 10, 99}, /* 2257 'c' */ - { 0x83000000, 11, 33}, /* 2258 '!' */ - { 0xd4000000, 11, 112}, /* 2259 'p' */ - { 0xd4200000, 11, 116}, /* 2260 't' */ - { 0x83200000, 12, 0}, /* 2261 '0x00' */ - { 0x83300000, 12, 41}, /* 2262 ')' */ - { 0x83400000, 12, 107}, /* 2263 'k' */ - { 0x83500000, 12, 59}, /* 2264 ';' */ - { 0x83700000, 12, 47}, /* 2265 '/' */ - { 0x83680000, 14, 34}, /* 2266 '\"' */ - { 0x836c0000, 14, 106}, /* 2267 'j' */ - { 0x83600000, 15, 122}, /* 2268 'z' */ - { 0x83660000, 15, 113}, /* 2269 'q' */ - { 0x83630000, 16, 64}, /* 2270 '@' */ - { 0x83640000, 16, 1}, /* 2271 '0x01' */ - { 0x83628000, 17, 67}, /* 2272 'C' */ - { 0x83650000, 17, 93}, /* 2273 ']' */ - { 0x83620000, 18, 90}, /* 2274 'Z' */ - { 0x83624000, 18, 91}, /* 2275 '[' */ - { 0x83658000, 18, 84}, /* 2276 'T' */ - { 0x8365c000, 18, 96}, /* 2277 '`' */ - /* 61 */ - { 0x80000000, 2, 32}, /* 2278 ' ' */ - { 0x40000000, 3, 115}, /* 2279 's' */ - { 0xc0000000, 3, 114}, /* 2280 'r' */ - { 0x00000000, 4, 100}, /* 2281 'd' */ - { 0x30000000, 4, 97}, /* 2282 'a' */ - { 0xf0000000, 4, 110}, /* 2283 'n' */ - { 0x10000000, 5, 99}, /* 2284 'c' */ - { 0x60000000, 5, 101}, /* 2285 'e' */ - { 0x68000000, 5, 119}, /* 2286 'w' */ - { 0x78000000, 5, 116}, /* 2287 't' */ - { 0xe0000000, 5, 108}, /* 2288 'l' */ - { 0x18000000, 6, 120}, /* 2289 'x' */ - { 0x20000000, 6, 118}, /* 2290 'v' */ - { 0x24000000, 6, 105}, /* 2291 'i' */ - { 0x28000000, 6, 121}, /* 2292 'y' */ - { 0x70000000, 6, 109}, /* 2293 'm' */ - { 0xe8000000, 6, 46}, /* 2294 '.' */ - { 0x1c000000, 7, 102}, /* 2295 'f' */ - { 0x2e000000, 7, 98}, /* 2296 'b' */ - { 0x74000000, 7, 44}, /* 2297 ',' */ - { 0xec000000, 7, 112}, /* 2298 'p' */ - { 0x1e000000, 8, 45}, /* 2299 '-' */ - { 0x1f000000, 8, 104}, /* 2300 'h' */ - { 0x2c000000, 8, 107}, /* 2301 'k' */ - { 0x76000000, 8, 39}, /* 2302 '\'' */ - { 0xee000000, 8, 103}, /* 2303 'g' */ - { 0xef000000, 8, 111}, /* 2304 'o' */ - { 0x2d800000, 9, 58}, /* 2305 ':' */ - { 0x2d000000, 10, 41}, /* 2306 ')' */ - { 0x2d400000, 10, 113}, /* 2307 'q' */ - { 0x77400000, 10, 63}, /* 2308 '?' */ - { 0x77800000, 10, 117}, /* 2309 'u' */ - { 0x77000000, 11, 122}, /* 2310 'z' */ - { 0x77c00000, 11, 33}, /* 2311 '!' */ - { 0x77e00000, 12, 0}, /* 2312 '0x00' */ - { 0x77f00000, 12, 106}, /* 2313 'j' */ - { 0x77300000, 13, 47}, /* 2314 '/' */ - { 0x77240000, 14, 52}, /* 2315 '4' */ - { 0x77280000, 14, 66}, /* 2316 'B' */ - { 0x77380000, 14, 93}, /* 2317 ']' */ - { 0x773c0000, 14, 59}, /* 2318 ';' */ - { 0x77200000, 15, 34}, /* 2319 '\"' */ - { 0x77230000, 16, 68}, /* 2320 'D' */ - { 0x772c0000, 16, 1}, /* 2321 '0x01' */ - { 0x772e0000, 16, 64}, /* 2322 '@' */ - { 0x77220000, 17, 84}, /* 2323 'T' */ - { 0x77228000, 17, 67}, /* 2324 'C' */ - { 0x772d8000, 17, 91}, /* 2325 '[' */ - { 0x772f8000, 17, 76}, /* 2326 'L' */ - { 0x772d0000, 18, 86}, /* 2327 'V' */ - { 0x772d4000, 18, 71}, /* 2328 'G' */ - { 0x772f0000, 18, 49}, /* 2329 '1' */ - { 0x772f5000, 20, 69}, /* 2330 'E' */ - { 0x772f4000, 21, 50}, /* 2331 '2' */ - { 0x772f4800, 21, 78}, /* 2332 'N' */ - { 0x772f6000, 21, 70}, /* 2333 'F' */ - { 0x772f6800, 21, 65}, /* 2334 'A' */ - { 0x772f7000, 22, 92}, /* 2335 '\\' */ - { 0x772f7400, 22, 80}, /* 2336 'P' */ - { 0x772f7800, 22, 77}, /* 2337 'M' */ - { 0x772f7c00, 22, 72}, /* 2338 'H' */ - /* 35 */ - { 0x00000000, 2, 111}, /* 2339 'o' */ - { 0x80000000, 2, 32}, /* 2340 ' ' */ - { 0x40000000, 3, 105}, /* 2341 'i' */ - { 0xc0000000, 3, 114}, /* 2342 'r' */ - { 0x70000000, 4, 97}, /* 2343 'a' */ - { 0xe0000000, 4, 101}, /* 2344 'e' */ - { 0x60000000, 5, 116}, /* 2345 't' */ - { 0xf0000000, 5, 117}, /* 2346 'u' */ - { 0xf8000000, 5, 102}, /* 2347 'f' */ - { 0x6c000000, 6, 108}, /* 2348 'l' */ - { 0x68000000, 8, 115}, /* 2349 's' */ - { 0x69000000, 8, 121}, /* 2350 'y' */ - { 0x6b000000, 9, 46}, /* 2351 '.' */ - { 0x6a000000, 10, 63}, /* 2352 '?' */ - { 0x6ac00000, 10, 44}, /* 2353 ',' */ - { 0x6bc00000, 10, 45}, /* 2354 '-' */ - { 0x6a600000, 11, 58}, /* 2355 ':' */ - { 0x6a800000, 11, 39}, /* 2356 '\'' */ - { 0x6aa00000, 11, 103}, /* 2357 'g' */ - { 0x6a400000, 12, 109}, /* 2358 'm' */ - { 0x6b800000, 12, 1}, /* 2359 '0x01' */ - { 0x6ba00000, 12, 98}, /* 2360 'b' */ - { 0x6bb00000, 12, 110}, /* 2361 'n' */ - { 0x6a580000, 13, 99}, /* 2362 'c' */ - { 0x6b900000, 13, 33}, /* 2363 '!' */ - { 0x6b980000, 14, 41}, /* 2364 ')' */ - { 0x6b9c0000, 14, 119}, /* 2365 'w' */ - { 0x6a520000, 15, 112}, /* 2366 'p' */ - { 0x6a540000, 15, 47}, /* 2367 '/' */ - { 0x6a500000, 16, 104}, /* 2368 'h' */ - { 0x6a560000, 16, 59}, /* 2369 ';' */ - { 0x6a510000, 17, 0}, /* 2370 '0x00' */ - { 0x6a518000, 17, 100}, /* 2371 'd' */ - { 0x6a570000, 17, 107}, /* 2372 'k' */ - { 0x6a578000, 17, 118}, /* 2373 'v' */ - /* 40 */ - { 0xc0000000, 2, 32}, /* 2374 ' ' */ - { 0x00000000, 3, 97}, /* 2375 'a' */ - { 0x40000000, 3, 104}, /* 2376 'h' */ - { 0xa0000000, 3, 101}, /* 2377 'e' */ - { 0x30000000, 4, 117}, /* 2378 'u' */ - { 0x60000000, 4, 114}, /* 2379 'r' */ - { 0x80000000, 4, 105}, /* 2380 'i' */ - { 0x70000000, 5, 108}, /* 2381 'l' */ - { 0x90000000, 5, 115}, /* 2382 's' */ - { 0x98000000, 5, 111}, /* 2383 'o' */ - { 0x24000000, 6, 44}, /* 2384 ',' */ - { 0x28000000, 6, 110}, /* 2385 'n' */ - { 0x78000000, 6, 103}, /* 2386 'g' */ - { 0x7c000000, 6, 46}, /* 2387 '.' */ - { 0x2c000000, 7, 121}, /* 2388 'y' */ - { 0x21000000, 8, 39}, /* 2389 '\'' */ - { 0x22000000, 8, 45}, /* 2390 '-' */ - { 0x23000000, 8, 58}, /* 2391 ':' */ - { 0x20000000, 9, 100}, /* 2392 'd' */ - { 0x2e800000, 9, 98}, /* 2393 'b' */ - { 0x2f000000, 9, 116}, /* 2394 't' */ - { 0x2f800000, 9, 119}, /* 2395 'w' */ - { 0x20800000, 10, 63}, /* 2396 '?' */ - { 0x20c00000, 10, 109}, /* 2397 'm' */ - { 0x2e200000, 11, 33}, /* 2398 '!' */ - { 0x2e600000, 11, 102}, /* 2399 'f' */ - { 0x2e100000, 12, 59}, /* 2400 ';' */ - { 0x2e500000, 12, 0}, /* 2401 '0x00' */ - { 0x2e000000, 13, 107}, /* 2402 'k' */ - { 0x2e400000, 13, 112}, /* 2403 'p' */ - { 0x2e080000, 14, 41}, /* 2404 ')' */ - { 0x2e0c0000, 14, 34}, /* 2405 '\"' */ - { 0x2e4a0000, 15, 99}, /* 2406 'c' */ - { 0x2e4e0000, 15, 47}, /* 2407 '/' */ - { 0x2e480000, 16, 1}, /* 2408 '0x01' */ - { 0x2e4c0000, 16, 93}, /* 2409 ']' */ - { 0x2e4d0000, 16, 122}, /* 2410 'z' */ - { 0x2e490000, 17, 96}, /* 2411 '`' */ - { 0x2e498000, 18, 118}, /* 2412 'v' */ - { 0x2e49c000, 18, 64}, /* 2413 '@' */ - /* 41 */ - { 0x00000000, 1, 101}, /* 2414 'e' */ - { 0x80000000, 3, 111}, /* 2415 'o' */ - { 0xa0000000, 3, 105}, /* 2416 'i' */ - { 0xc0000000, 3, 32}, /* 2417 ' ' */ - { 0xf0000000, 4, 97}, /* 2418 'a' */ - { 0xe4000000, 6, 114}, /* 2419 'r' */ - { 0xec000000, 6, 116}, /* 2420 't' */ - { 0xe1000000, 8, 121}, /* 2421 'y' */ - { 0xe3000000, 8, 108}, /* 2422 'l' */ - { 0xe8000000, 8, 46}, /* 2423 '.' */ - { 0xe9000000, 8, 110}, /* 2424 'n' */ - { 0xeb000000, 8, 117}, /* 2425 'u' */ - { 0xe0000000, 9, 100}, /* 2426 'd' */ - { 0xe2000000, 9, 115}, /* 2427 's' */ - { 0xea000000, 9, 44}, /* 2428 ',' */ - { 0xe0c00000, 10, 119}, /* 2429 'w' */ - { 0xe2800000, 10, 39}, /* 2430 '\'' */ - { 0xe2c00000, 10, 45}, /* 2431 '-' */ - { 0xeaa00000, 11, 109}, /* 2432 'm' */ - { 0xeac00000, 11, 58}, /* 2433 ':' */ - { 0xeae00000, 11, 98}, /* 2434 'b' */ - { 0xe0900000, 12, 99}, /* 2435 'c' */ - { 0xe0b00000, 12, 63}, /* 2436 '?' */ - { 0xea800000, 12, 33}, /* 2437 '!' */ - { 0xe0800000, 13, 41}, /* 2438 ')' */ - { 0xe0a00000, 13, 104}, /* 2439 'h' */ - { 0xe0a80000, 13, 107}, /* 2440 'k' */ - { 0xea980000, 13, 102}, /* 2441 'f' */ - { 0xea940000, 14, 103}, /* 2442 'g' */ - { 0xe0880000, 15, 112}, /* 2443 'p' */ - { 0xe08a0000, 15, 59}, /* 2444 ';' */ - { 0xe08c0000, 15, 47}, /* 2445 '/' */ - { 0xe08e0000, 15, 0}, /* 2446 '0x00' */ - { 0xea920000, 15, 118}, /* 2447 'v' */ - { 0xea900000, 16, 113}, /* 2448 'q' */ - { 0xea910000, 17, 1}, /* 2449 '0x01' */ - { 0xea918000, 18, 34}, /* 2450 '\"' */ - { 0xea91c000, 20, 122}, /* 2451 'z' */ - { 0xea91d000, 20, 106}, /* 2452 'j' */ - { 0xea91e000, 20, 93}, /* 2453 ']' */ - { 0xea91f000, 20, 42}, /* 2454 '*' */ - /* 44 */ - { 0x80000000, 2, 110}, /* 2455 'n' */ - { 0x00000000, 3, 116}, /* 2456 't' */ - { 0x40000000, 3, 115}, /* 2457 's' */ - { 0x30000000, 4, 108}, /* 2458 'l' */ - { 0xc0000000, 4, 111}, /* 2459 'o' */ - { 0xd0000000, 4, 99}, /* 2460 'c' */ - { 0xf0000000, 4, 101}, /* 2461 'e' */ - { 0x20000000, 5, 97}, /* 2462 'a' */ - { 0x60000000, 5, 109}, /* 2463 'm' */ - { 0x68000000, 5, 100}, /* 2464 'd' */ - { 0x70000000, 5, 118}, /* 2465 'v' */ - { 0xe0000000, 5, 103}, /* 2466 'g' */ - { 0xe8000000, 5, 114}, /* 2467 'r' */ - { 0x28000000, 6, 112}, /* 2468 'p' */ - { 0x78000000, 6, 102}, /* 2469 'f' */ - { 0x2c000000, 7, 122}, /* 2470 'z' */ - { 0x7c000000, 7, 32}, /* 2471 ' ' */ - { 0x2f000000, 8, 98}, /* 2472 'b' */ - { 0x7e000000, 8, 107}, /* 2473 'k' */ - { 0x2e000000, 9, 45}, /* 2474 '-' */ - { 0x2e800000, 9, 120}, /* 2475 'x' */ - { 0x7f000000, 10, 117}, /* 2476 'u' */ - { 0x7f800000, 10, 113}, /* 2477 'q' */ - { 0x7f400000, 11, 46}, /* 2478 '.' */ - { 0x7fc00000, 11, 44}, /* 2479 ',' */ - { 0x7f700000, 12, 119}, /* 2480 'w' */ - { 0x7ff00000, 12, 39}, /* 2481 '\'' */ - { 0x7f680000, 13, 105}, /* 2482 'i' */ - { 0x7fe80000, 13, 106}, /* 2483 'j' */ - { 0x7f640000, 14, 58}, /* 2484 ':' */ - { 0x7fe00000, 14, 104}, /* 2485 'h' */ - { 0x7f600000, 15, 47}, /* 2486 '/' */ - { 0x7fe60000, 15, 121}, /* 2487 'y' */ - { 0x7f630000, 16, 63}, /* 2488 '?' */ - { 0x7fe40000, 16, 80}, /* 2489 'P' */ - { 0x7f628000, 17, 82}, /* 2490 'R' */ - { 0x7fe58000, 17, 33}, /* 2491 '!' */ - { 0x7fe50000, 18, 41}, /* 2492 ')' */ - { 0x7fe54000, 18, 83}, /* 2493 'S' */ - { 0x7f620000, 19, 0}, /* 2494 '0x00' */ - { 0x7f622000, 19, 67}, /* 2495 'C' */ - { 0x7f624000, 19, 1}, /* 2496 '0x01' */ - { 0x7f626000, 20, 68}, /* 2497 'D' */ - { 0x7f627000, 20, 59}, /* 2498 ';' */ - /* 14 */ - { 0x00000000, 1, 111}, /* 2499 'o' */ - { 0xc0000000, 2, 117}, /* 2500 'u' */ - { 0xa0000000, 3, 97}, /* 2501 'a' */ - { 0x90000000, 4, 101}, /* 2502 'e' */ - { 0x80000000, 5, 105}, /* 2503 'i' */ - { 0x8c000000, 6, 121}, /* 2504 'y' */ - { 0x8a000000, 7, 32}, /* 2505 ' ' */ - { 0x89000000, 8, 46}, /* 2506 '.' */ - { 0x88000000, 9, 39}, /* 2507 '\'' */ - { 0x88c00000, 10, 116}, /* 2508 't' */ - { 0x88800000, 11, 110}, /* 2509 'n' */ - { 0x88b00000, 12, 115}, /* 2510 's' */ - { 0x88a00000, 13, 1}, /* 2511 '0x01' */ - { 0x88a80000, 13, 104}, /* 2512 'h' */ - /* 40 */ - { 0x80000000, 2, 32}, /* 2513 ' ' */ - { 0xc0000000, 2, 101}, /* 2514 'e' */ - { 0x00000000, 3, 115}, /* 2515 's' */ - { 0x60000000, 3, 105}, /* 2516 'i' */ - { 0x20000000, 4, 46}, /* 2517 '.' */ - { 0x48000000, 5, 121}, /* 2518 'y' */ - { 0x30000000, 6, 39}, /* 2519 '\'' */ - { 0x34000000, 6, 97}, /* 2520 'a' */ - { 0x38000000, 6, 112}, /* 2521 'p' */ - { 0x3c000000, 6, 44}, /* 2522 ',' */ - { 0x50000000, 6, 108}, /* 2523 'l' */ - { 0x54000000, 6, 102}, /* 2524 'f' */ - { 0x58000000, 6, 110}, /* 2525 'n' */ - { 0x40000000, 7, 47}, /* 2526 '/' */ - { 0x44000000, 7, 45}, /* 2527 '-' */ - { 0x46000000, 7, 111}, /* 2528 'o' */ - { 0x5d000000, 8, 58}, /* 2529 ':' */ - { 0x43800000, 9, 98}, /* 2530 'b' */ - { 0x5c000000, 9, 119}, /* 2531 'w' */ - { 0x5c800000, 9, 109}, /* 2532 'm' */ - { 0x5e000000, 9, 104}, /* 2533 'h' */ - { 0x5f000000, 9, 117}, /* 2534 'u' */ - { 0x5f800000, 9, 107}, /* 2535 'k' */ - { 0x42000000, 10, 114}, /* 2536 'r' */ - { 0x42400000, 10, 1}, /* 2537 '0x01' */ - { 0x42800000, 10, 63}, /* 2538 '?' */ - { 0x43000000, 10, 116}, /* 2539 't' */ - { 0x43400000, 10, 103}, /* 2540 'g' */ - { 0x5ec00000, 10, 100}, /* 2541 'd' */ - { 0x42c00000, 11, 106}, /* 2542 'j' */ - { 0x42e00000, 12, 41}, /* 2543 ')' */ - { 0x5e800000, 12, 59}, /* 2544 ';' */ - { 0x5e900000, 12, 99}, /* 2545 'c' */ - { 0x5ea00000, 12, 83}, /* 2546 'S' */ - { 0x42f00000, 13, 118}, /* 2547 'v' */ - { 0x42f80000, 13, 82}, /* 2548 'R' */ - { 0x5eb00000, 13, 33}, /* 2549 '!' */ - { 0x5eb80000, 14, 64}, /* 2550 '@' */ - { 0x5ebc0000, 15, 34}, /* 2551 '\"' */ - { 0x5ebe0000, 15, 0}, /* 2552 '0x00' */ - /* 43 */ - { 0x40000000, 3, 97}, /* 2553 'a' */ - { 0x60000000, 3, 105}, /* 2554 'i' */ - { 0x80000000, 3, 108}, /* 2555 'l' */ - { 0xc0000000, 3, 101}, /* 2556 'e' */ - { 0xe0000000, 3, 32}, /* 2557 ' ' */ - { 0x00000000, 4, 117}, /* 2558 'u' */ - { 0x10000000, 4, 100}, /* 2559 'd' */ - { 0x20000000, 4, 121}, /* 2560 'y' */ - { 0xb0000000, 4, 111}, /* 2561 'o' */ - { 0xa0000000, 5, 115}, /* 2562 's' */ - { 0x30000000, 6, 46}, /* 2563 '.' */ - { 0x38000000, 6, 116}, /* 2564 't' */ - { 0x34000000, 7, 118}, /* 2565 'v' */ - { 0x3c000000, 7, 102}, /* 2566 'f' */ - { 0xa8000000, 7, 109}, /* 2567 'm' */ - { 0xaa000000, 7, 107}, /* 2568 'k' */ - { 0xac000000, 7, 112}, /* 2569 'p' */ - { 0x37000000, 8, 99}, /* 2570 'c' */ - { 0x3e000000, 8, 45}, /* 2571 '-' */ - { 0xaf000000, 8, 44}, /* 2572 ',' */ - { 0x36800000, 9, 58}, /* 2573 ':' */ - { 0x3f800000, 9, 98}, /* 2574 'b' */ - { 0xae000000, 9, 39}, /* 2575 '\'' */ - { 0x36000000, 10, 114}, /* 2576 'r' */ - { 0x36400000, 10, 104}, /* 2577 'h' */ - { 0x3f000000, 10, 110}, /* 2578 'n' */ - { 0x3f400000, 10, 103}, /* 2579 'g' */ - { 0xaec00000, 10, 119}, /* 2580 'w' */ - { 0xae800000, 11, 63}, /* 2581 '?' */ - { 0xaea00000, 13, 33}, /* 2582 '!' */ - { 0xaeb00000, 13, 122}, /* 2583 'z' */ - { 0xaeac0000, 14, 47}, /* 2584 '/' */ - { 0xaea80000, 15, 59}, /* 2585 ';' */ - { 0xaeb80000, 15, 69}, /* 2586 'E' */ - { 0xaeba0000, 15, 42}, /* 2587 '*' */ - { 0xaebe0000, 15, 0}, /* 2588 '0x00' */ - { 0xaeab0000, 16, 1}, /* 2589 '0x01' */ - { 0xaebc0000, 16, 41}, /* 2590 ')' */ - { 0xaeaa0000, 17, 64}, /* 2591 '@' */ - { 0xaeaa8000, 17, 106}, /* 2592 'j' */ - { 0xaebd0000, 17, 34}, /* 2593 '\"' */ - { 0xaebd8000, 18, 91}, /* 2594 '[' */ - { 0xaebdc000, 18, 93}, /* 2595 ']' */ - /* 40 */ - { 0x00000000, 2, 97}, /* 2596 'a' */ - { 0x40000000, 2, 101}, /* 2597 'e' */ - { 0xe0000000, 3, 32}, /* 2598 ' ' */ - { 0x90000000, 4, 112}, /* 2599 'p' */ - { 0xb0000000, 4, 111}, /* 2600 'o' */ - { 0xc0000000, 4, 105}, /* 2601 'i' */ - { 0x80000000, 5, 46}, /* 2602 '.' */ - { 0x88000000, 5, 115}, /* 2603 's' */ - { 0xd0000000, 5, 117}, /* 2604 'u' */ - { 0xd8000000, 5, 109}, /* 2605 'm' */ - { 0xa4000000, 6, 121}, /* 2606 'y' */ - { 0xac000000, 6, 98}, /* 2607 'b' */ - { 0xa0000000, 7, 44}, /* 2608 ',' */ - { 0xa8000000, 7, 47}, /* 2609 '/' */ - { 0xa2000000, 8, 93}, /* 2610 ']' */ - { 0xa3000000, 9, 58}, /* 2611 ':' */ - { 0xaa000000, 9, 39}, /* 2612 '\'' */ - { 0xa3c00000, 10, 114}, /* 2613 'r' */ - { 0xaac00000, 10, 102}, /* 2614 'f' */ - { 0xab000000, 10, 108}, /* 2615 'l' */ - { 0xab800000, 10, 110}, /* 2616 'n' */ - { 0xa3800000, 11, 63}, /* 2617 '?' */ - { 0xa3a00000, 11, 33}, /* 2618 '!' */ - { 0xaa800000, 11, 0}, /* 2619 '0x00' */ - { 0xaaa00000, 11, 119}, /* 2620 'w' */ - { 0xab600000, 11, 104}, /* 2621 'h' */ - { 0xabc00000, 11, 45}, /* 2622 '-' */ - { 0xabe00000, 12, 52}, /* 2623 '4' */ - { 0xab500000, 13, 116}, /* 2624 't' */ - { 0xab580000, 13, 64}, /* 2625 '@' */ - { 0xabf00000, 13, 59}, /* 2626 ';' */ - { 0xabf80000, 13, 99}, /* 2627 'c' */ - { 0xab400000, 14, 41}, /* 2628 ')' */ - { 0xab440000, 14, 1}, /* 2629 '0x01' */ - { 0xab4c0000, 14, 100}, /* 2630 'd' */ - { 0xab4a0000, 15, 103}, /* 2631 'g' */ - { 0xab480000, 17, 91}, /* 2632 '[' */ - { 0xab488000, 17, 118}, /* 2633 'v' */ - { 0xab490000, 17, 107}, /* 2634 'k' */ - { 0xab498000, 17, 122}, /* 2635 'z' */ - /* 44 */ - { 0x40000000, 2, 32}, /* 2636 ' ' */ - { 0x20000000, 3, 116}, /* 2637 't' */ - { 0x80000000, 3, 103}, /* 2638 'g' */ - { 0xe0000000, 3, 100}, /* 2639 'd' */ - { 0x00000000, 4, 115}, /* 2640 's' */ - { 0xa0000000, 4, 97}, /* 2641 'a' */ - { 0xd0000000, 4, 101}, /* 2642 'e' */ - { 0xb0000000, 5, 99}, /* 2643 'c' */ - { 0xc0000000, 5, 105}, /* 2644 'i' */ - { 0x1c000000, 6, 46}, /* 2645 '.' */ - { 0xbc000000, 6, 110}, /* 2646 'n' */ - { 0xcc000000, 6, 111}, /* 2647 'o' */ - { 0x12000000, 7, 117}, /* 2648 'u' */ - { 0x16000000, 7, 118}, /* 2649 'v' */ - { 0x18000000, 7, 102}, /* 2650 'f' */ - { 0xb8000000, 7, 107}, /* 2651 'k' */ - { 0xba000000, 7, 39}, /* 2652 '\'' */ - { 0xc8000000, 7, 121}, /* 2653 'y' */ - { 0xca000000, 7, 44}, /* 2654 ',' */ - { 0x10000000, 8, 109}, /* 2655 'm' */ - { 0x14000000, 8, 108}, /* 2656 'l' */ - { 0x15000000, 8, 45}, /* 2657 '-' */ - { 0x11800000, 9, 119}, /* 2658 'w' */ - { 0x1a800000, 9, 58}, /* 2659 ':' */ - { 0x11400000, 10, 122}, /* 2660 'z' */ - { 0x1a000000, 10, 104}, /* 2661 'h' */ - { 0x1b000000, 10, 98}, /* 2662 'b' */ - { 0x1b400000, 10, 106}, /* 2663 'j' */ - { 0x1b800000, 10, 114}, /* 2664 'r' */ - { 0x11000000, 11, 112}, /* 2665 'p' */ - { 0x1a600000, 11, 120}, /* 2666 'x' */ - { 0x1be00000, 11, 63}, /* 2667 '?' */ - { 0x11300000, 12, 59}, /* 2668 ';' */ - { 0x1a500000, 12, 41}, /* 2669 ')' */ - { 0x1bc00000, 12, 33}, /* 2670 '!' */ - { 0x1bd00000, 12, 113}, /* 2671 'q' */ - { 0x11200000, 13, 47}, /* 2672 '/' */ - { 0x11280000, 13, 0}, /* 2673 '0x00' */ - { 0x1a400000, 13, 1}, /* 2674 '0x01' */ - { 0x1a480000, 14, 66}, /* 2675 'B' */ - { 0x1a4c0000, 16, 93}, /* 2676 ']' */ - { 0x1a4d0000, 16, 34}, /* 2677 '\"' */ - { 0x1a4e0000, 16, 64}, /* 2678 '@' */ - { 0x1a4f0000, 16, 42}, /* 2679 '*' */ - /* 48 */ - { 0x20000000, 3, 117}, /* 2680 'u' */ - { 0x60000000, 3, 32}, /* 2681 ' ' */ - { 0x80000000, 3, 114}, /* 2682 'r' */ - { 0xe0000000, 3, 110}, /* 2683 'n' */ - { 0x00000000, 4, 108}, /* 2684 'l' */ - { 0xc0000000, 4, 109}, /* 2685 'm' */ - { 0xd0000000, 4, 102}, /* 2686 'f' */ - { 0x10000000, 5, 118}, /* 2687 'v' */ - { 0x40000000, 5, 115}, /* 2688 's' */ - { 0x48000000, 5, 112}, /* 2689 'p' */ - { 0xa0000000, 5, 116}, /* 2690 't' */ - { 0xa8000000, 5, 111}, /* 2691 'o' */ - { 0xb8000000, 5, 119}, /* 2692 'w' */ - { 0x18000000, 6, 107}, /* 2693 'k' */ - { 0x1c000000, 6, 105}, /* 2694 'i' */ - { 0x50000000, 6, 103}, /* 2695 'g' */ - { 0x5c000000, 6, 99}, /* 2696 'c' */ - { 0xb4000000, 6, 100}, /* 2697 'd' */ - { 0x56000000, 7, 101}, /* 2698 'e' */ - { 0x58000000, 7, 121}, /* 2699 'y' */ - { 0x5a000000, 7, 97}, /* 2700 'a' */ - { 0xb2000000, 7, 98}, /* 2701 'b' */ - { 0x55000000, 8, 104}, /* 2702 'h' */ - { 0xb0000000, 8, 46}, /* 2703 '.' */ - { 0x54000000, 9, 45}, /* 2704 '-' */ - { 0x54800000, 9, 44}, /* 2705 ',' */ - { 0xb1400000, 10, 39}, /* 2706 '\'' */ - { 0xb1c00000, 10, 120}, /* 2707 'x' */ - { 0xb1200000, 11, 58}, /* 2708 ':' */ - { 0xb1a00000, 11, 122}, /* 2709 'z' */ - { 0xb1100000, 12, 63}, /* 2710 '?' */ - { 0xb1900000, 12, 106}, /* 2711 'j' */ - { 0xb1000000, 13, 33}, /* 2712 '!' */ - { 0xb1880000, 13, 113}, /* 2713 'q' */ - { 0xb1080000, 14, 74}, /* 2714 'J' */ - { 0xb1800000, 14, 47}, /* 2715 '/' */ - { 0xb1840000, 14, 41}, /* 2716 ')' */ - { 0xb10d0000, 16, 59}, /* 2717 ';' */ - { 0xb10e0000, 16, 71}, /* 2718 'G' */ - { 0xb10c0000, 17, 34}, /* 2719 '\"' */ - { 0xb10f0000, 17, 1}, /* 2720 '0x01' */ - { 0xb10c8000, 18, 93}, /* 2721 ']' */ - { 0xb10cc000, 18, 64}, /* 2722 '@' */ - { 0xb10f8000, 19, 52}, /* 2723 '4' */ - { 0xb10fa000, 19, 0}, /* 2724 '0x00' */ - { 0xb10fc000, 19, 66}, /* 2725 'B' */ - { 0xb10fe000, 20, 79}, /* 2726 'O' */ - { 0xb10ff000, 20, 67}, /* 2727 'C' */ - /* 39 */ - { 0x20000000, 3, 108}, /* 2728 'l' */ - { 0x40000000, 3, 32}, /* 2729 ' ' */ - { 0x60000000, 3, 111}, /* 2730 'o' */ - { 0xa0000000, 3, 114}, /* 2731 'r' */ - { 0xe0000000, 3, 101}, /* 2732 'e' */ - { 0x00000000, 4, 112}, /* 2733 'p' */ - { 0xc0000000, 4, 97}, /* 2734 'a' */ - { 0xd0000000, 4, 105}, /* 2735 'i' */ - { 0x18000000, 5, 116}, /* 2736 't' */ - { 0x80000000, 5, 117}, /* 2737 'u' */ - { 0x88000000, 5, 104}, /* 2738 'h' */ - { 0x90000000, 5, 115}, /* 2739 's' */ - { 0x14000000, 6, 109}, /* 2740 'm' */ - { 0x12000000, 7, 100}, /* 2741 'd' */ - { 0x9a000000, 7, 121}, /* 2742 'y' */ - { 0x9c000000, 7, 46}, /* 2743 '.' */ - { 0x9e000000, 7, 44}, /* 2744 ',' */ - { 0x10000000, 8, 45}, /* 2745 '-' */ - { 0x11800000, 9, 63}, /* 2746 '?' */ - { 0x98800000, 9, 58}, /* 2747 ':' */ - { 0x99000000, 10, 39}, /* 2748 '\'' */ - { 0x99400000, 10, 93}, /* 2749 ']' */ - { 0x99800000, 10, 43}, /* 2750 '+' */ - { 0x99c00000, 10, 98}, /* 2751 'b' */ - { 0x11200000, 11, 102}, /* 2752 'f' */ - { 0x11400000, 11, 107}, /* 2753 'k' */ - { 0x11600000, 11, 33}, /* 2754 '!' */ - { 0x98200000, 11, 99}, /* 2755 'c' */ - { 0x98400000, 11, 110}, /* 2756 'n' */ - { 0x98600000, 11, 119}, /* 2757 'w' */ - { 0x11000000, 12, 0}, /* 2758 '0x00' */ - { 0x11100000, 12, 59}, /* 2759 ';' */ - { 0x98100000, 12, 47}, /* 2760 '/' */ - { 0x98080000, 13, 103}, /* 2761 'g' */ - { 0x98040000, 14, 41}, /* 2762 ')' */ - { 0x98020000, 15, 34}, /* 2763 '\"' */ - { 0x98010000, 16, 83}, /* 2764 'S' */ - { 0x98000000, 17, 1}, /* 2765 '0x01' */ - { 0x98008000, 17, 66}, /* 2766 'B' */ - /* 13 */ - { 0x80000000, 1, 117}, /* 2767 'u' */ - { 0x00000000, 3, 44}, /* 2768 ',' */ - { 0x20000000, 3, 46}, /* 2769 '.' */ - { 0x60000000, 3, 32}, /* 2770 ' ' */ - { 0x48000000, 5, 98}, /* 2771 'b' */ - { 0x50000000, 5, 39}, /* 2772 '\'' */ - { 0x58000000, 5, 105}, /* 2773 'i' */ - { 0x44000000, 6, 97}, /* 2774 'a' */ - { 0x40000000, 8, 63}, /* 2775 '?' */ - { 0x41000000, 8, 58}, /* 2776 ':' */ - { 0x43000000, 8, 41}, /* 2777 ')' */ - { 0x42000000, 9, 1}, /* 2778 '0x01' */ - { 0x42800000, 9, 119}, /* 2779 'w' */ - /* 47 */ - { 0x00000000, 3, 97}, /* 2780 'a' */ - { 0x20000000, 3, 111}, /* 2781 'o' */ - { 0x80000000, 3, 105}, /* 2782 'i' */ - { 0xc0000000, 3, 32}, /* 2783 ' ' */ - { 0xe0000000, 3, 101}, /* 2784 'e' */ - { 0x40000000, 4, 115}, /* 2785 's' */ - { 0x50000000, 4, 116}, /* 2786 't' */ - { 0x70000000, 5, 100}, /* 2787 'd' */ - { 0xa0000000, 5, 110}, /* 2788 'n' */ - { 0xa8000000, 5, 121}, /* 2789 'y' */ - { 0x68000000, 6, 117}, /* 2790 'u' */ - { 0x6c000000, 6, 109}, /* 2791 'm' */ - { 0x7c000000, 6, 107}, /* 2792 'k' */ - { 0xb4000000, 6, 108}, /* 2793 'l' */ - { 0xb8000000, 6, 46}, /* 2794 '.' */ - { 0xbc000000, 6, 114}, /* 2795 'r' */ - { 0x60000000, 7, 102}, /* 2796 'f' */ - { 0x64000000, 7, 44}, /* 2797 ',' */ - { 0x66000000, 7, 118}, /* 2798 'v' */ - { 0xb0000000, 7, 99}, /* 2799 'c' */ - { 0xb2000000, 7, 103}, /* 2800 'g' */ - { 0x63000000, 8, 39}, /* 2801 '\'' */ - { 0x78000000, 8, 45}, /* 2802 '-' */ - { 0x79000000, 8, 98}, /* 2803 'b' */ - { 0x7b000000, 8, 112}, /* 2804 'p' */ - { 0x62800000, 9, 58}, /* 2805 ':' */ - { 0x7a000000, 9, 119}, /* 2806 'w' */ - { 0x7a800000, 10, 63}, /* 2807 '?' */ - { 0x7ac00000, 10, 104}, /* 2808 'h' */ - { 0x62400000, 11, 33}, /* 2809 '!' */ - { 0x62100000, 12, 113}, /* 2810 'q' */ - { 0x62200000, 12, 106}, /* 2811 'j' */ - { 0x62300000, 12, 0}, /* 2812 '0x00' */ - { 0x62600000, 12, 47}, /* 2813 '/' */ - { 0x62080000, 13, 59}, /* 2814 ';' */ - { 0x62780000, 13, 41}, /* 2815 ')' */ - { 0x62700000, 14, 56}, /* 2816 '8' */ - { 0x62740000, 14, 122}, /* 2817 'z' */ - { 0x62020000, 15, 34}, /* 2818 '\"' */ - { 0x62060000, 15, 93}, /* 2819 ']' */ - { 0x62000000, 16, 84}, /* 2820 'T' */ - { 0x62040000, 16, 120}, /* 2821 'x' */ - { 0x62050000, 16, 1}, /* 2822 '0x01' */ - { 0x62018000, 17, 90}, /* 2823 'Z' */ - { 0x62010000, 18, 42}, /* 2824 '*' */ - { 0x62014000, 19, 68}, /* 2825 'D' */ - { 0x62016000, 19, 66}, /* 2826 'B' */ - /* 45 */ - { 0x00000000, 1, 32}, /* 2827 ' ' */ - { 0xa0000000, 3, 116}, /* 2828 't' */ - { 0x80000000, 4, 46}, /* 2829 '.' */ - { 0xe0000000, 4, 101}, /* 2830 'e' */ - { 0x98000000, 5, 44}, /* 2831 ',' */ - { 0xc0000000, 5, 111}, /* 2832 'o' */ - { 0xc8000000, 5, 115}, /* 2833 's' */ - { 0xf0000000, 5, 104}, /* 2834 'h' */ - { 0xf8000000, 5, 105}, /* 2835 'i' */ - { 0x94000000, 6, 99}, /* 2836 'c' */ - { 0xd0000000, 6, 117}, /* 2837 'u' */ - { 0xd8000000, 6, 112}, /* 2838 'p' */ - { 0xde000000, 7, 97}, /* 2839 'a' */ - { 0x91000000, 8, 110}, /* 2840 'n' */ - { 0x93000000, 8, 109}, /* 2841 'm' */ - { 0xd4000000, 8, 121}, /* 2842 'y' */ - { 0xd6000000, 8, 58}, /* 2843 ':' */ - { 0xdc000000, 8, 108}, /* 2844 'l' */ - { 0xdd000000, 8, 107}, /* 2845 'k' */ - { 0x90800000, 9, 98}, /* 2846 'b' */ - { 0x92000000, 9, 102}, /* 2847 'f' */ - { 0xd5000000, 9, 119}, /* 2848 'w' */ - { 0xd7800000, 9, 39}, /* 2849 '\'' */ - { 0x90000000, 10, 33}, /* 2850 '!' */ - { 0x90400000, 10, 103}, /* 2851 'g' */ - { 0x92800000, 10, 114}, /* 2852 'r' */ - { 0xd5800000, 10, 63}, /* 2853 '?' */ - { 0xd5c00000, 10, 45}, /* 2854 '-' */ - { 0xd7400000, 10, 113}, /* 2855 'q' */ - { 0xd7200000, 11, 100}, /* 2856 'd' */ - { 0x92c00000, 12, 47}, /* 2857 '/' */ - { 0x92d00000, 12, 41}, /* 2858 ')' */ - { 0x92f00000, 12, 0}, /* 2859 '0x00' */ - { 0xd7000000, 12, 93}, /* 2860 ']' */ - { 0xd7100000, 12, 59}, /* 2861 ';' */ - { 0x92e80000, 13, 118}, /* 2862 'v' */ - { 0x92e20000, 15, 34}, /* 2863 '\"' */ - { 0x92e60000, 15, 122}, /* 2864 'z' */ - { 0x92e00000, 16, 106}, /* 2865 'j' */ - { 0x92e10000, 16, 1}, /* 2866 '0x01' */ - { 0x92e40000, 16, 91}, /* 2867 '[' */ - { 0x92e58000, 17, 64}, /* 2868 '@' */ - { 0x92e54000, 18, 84}, /* 2869 'T' */ - { 0x92e50000, 19, 120}, /* 2870 'x' */ - { 0x92e52000, 19, 96}, /* 2871 '`' */ - /* 49 */ - { 0x80000000, 2, 104}, /* 2872 'h' */ - { 0x00000000, 3, 105}, /* 2873 'i' */ - { 0x40000000, 3, 111}, /* 2874 'o' */ - { 0x60000000, 3, 101}, /* 2875 'e' */ - { 0xe0000000, 3, 32}, /* 2876 ' ' */ - { 0x20000000, 4, 97}, /* 2877 'a' */ - { 0x30000000, 5, 117}, /* 2878 'u' */ - { 0xc8000000, 5, 114}, /* 2879 'r' */ - { 0xd8000000, 5, 115}, /* 2880 's' */ - { 0x3c000000, 6, 46}, /* 2881 '.' */ - { 0xc4000000, 6, 116}, /* 2882 't' */ - { 0xd0000000, 6, 121}, /* 2883 'y' */ - { 0x3a000000, 7, 99}, /* 2884 'c' */ - { 0xc2000000, 7, 108}, /* 2885 'l' */ - { 0x39000000, 8, 45}, /* 2886 '-' */ - { 0xc0000000, 8, 118}, /* 2887 'v' */ - { 0xc1000000, 8, 109}, /* 2888 'm' */ - { 0xd5000000, 8, 119}, /* 2889 'w' */ - { 0xd6000000, 8, 44}, /* 2890 ',' */ - { 0xd7000000, 8, 39}, /* 2891 '\'' */ - { 0x38000000, 9, 110}, /* 2892 'n' */ - { 0x38c00000, 10, 63}, /* 2893 '?' */ - { 0xd4400000, 10, 98}, /* 2894 'b' */ - { 0xd4800000, 10, 58}, /* 2895 ':' */ - { 0x38800000, 11, 33}, /* 2896 '!' */ - { 0xd4000000, 11, 122}, /* 2897 'z' */ - { 0xd4c00000, 11, 100}, /* 2898 'd' */ - { 0xd4e00000, 11, 102}, /* 2899 'f' */ - { 0xd4200000, 12, 120}, /* 2900 'x' */ - { 0x38a00000, 13, 103}, /* 2901 'g' */ - { 0x38a80000, 13, 59}, /* 2902 ';' */ - { 0xd4300000, 13, 112}, /* 2903 'p' */ - { 0x38b00000, 14, 80}, /* 2904 'P' */ - { 0x38b40000, 14, 0}, /* 2905 '0x00' */ - { 0x38bc0000, 14, 41}, /* 2906 ')' */ - { 0xd4380000, 14, 47}, /* 2907 '/' */ - { 0xd43c0000, 14, 107}, /* 2908 'k' */ - { 0x38b80000, 16, 64}, /* 2909 '@' */ - { 0x38ba0000, 16, 69}, /* 2910 'E' */ - { 0x38b98000, 17, 93}, /* 2911 ']' */ - { 0x38bb8000, 17, 34}, /* 2912 '\"' */ - { 0x38b90000, 18, 70}, /* 2913 'F' */ - { 0x38bb0000, 18, 1}, /* 2914 '0x01' */ - { 0x38b94000, 19, 106}, /* 2915 'j' */ - { 0x38bb4000, 19, 49}, /* 2916 '1' */ - { 0x38bb6000, 19, 91}, /* 2917 '[' */ - { 0x38b96000, 20, 92}, /* 2918 '\\' */ - { 0x38b97000, 21, 75}, /* 2919 'K' */ - { 0x38b97800, 21, 67}, /* 2920 'C' */ - /* 43 */ - { 0x60000000, 3, 116}, /* 2921 't' */ - { 0xa0000000, 3, 110}, /* 2922 'n' */ - { 0xc0000000, 3, 115}, /* 2923 's' */ - { 0xe0000000, 3, 114}, /* 2924 'r' */ - { 0x10000000, 4, 100}, /* 2925 'd' */ - { 0x20000000, 4, 101}, /* 2926 'e' */ - { 0x50000000, 4, 108}, /* 2927 'l' */ - { 0x80000000, 4, 112}, /* 2928 'p' */ - { 0x00000000, 5, 98}, /* 2929 'b' */ - { 0x08000000, 5, 32}, /* 2930 ' ' */ - { 0x30000000, 5, 105}, /* 2931 'i' */ - { 0x40000000, 5, 97}, /* 2932 'a' */ - { 0x48000000, 5, 103}, /* 2933 'g' */ - { 0x90000000, 5, 99}, /* 2934 'c' */ - { 0x98000000, 5, 109}, /* 2935 'm' */ - { 0x38000000, 7, 121}, /* 2936 'y' */ - { 0x3a000000, 8, 122}, /* 2937 'z' */ - { 0x3c000000, 8, 39}, /* 2938 '\'' */ - { 0x3e000000, 8, 102}, /* 2939 'f' */ - { 0x3f000000, 8, 107}, /* 2940 'k' */ - { 0x3d000000, 9, 44}, /* 2941 ',' */ - { 0x3b400000, 10, 45}, /* 2942 '-' */ - { 0x3b800000, 10, 111}, /* 2943 'o' */ - { 0x3d800000, 10, 46}, /* 2944 '.' */ - { 0x3dc00000, 10, 120}, /* 2945 'x' */ - { 0x3b000000, 11, 119}, /* 2946 'w' */ - { 0x3bc00000, 11, 58}, /* 2947 ':' */ - { 0x3b200000, 12, 113}, /* 2948 'q' */ - { 0x3be00000, 12, 104}, /* 2949 'h' */ - { 0x3bf00000, 12, 118}, /* 2950 'v' */ - { 0x3b300000, 13, 106}, /* 2951 'j' */ - { 0x3b380000, 15, 117}, /* 2952 'u' */ - { 0x3b3a0000, 15, 63}, /* 2953 '?' */ - { 0x3b3e0000, 16, 47}, /* 2954 '/' */ - { 0x3b3f0000, 16, 33}, /* 2955 '!' */ - { 0x3b3c8000, 17, 1}, /* 2956 '0x01' */ - { 0x3b3c0000, 18, 92}, /* 2957 '\\' */ - { 0x3b3c4000, 18, 0}, /* 2958 '0x00' */ - { 0x3b3d0000, 18, 59}, /* 2959 ';' */ - { 0x3b3d8000, 18, 74}, /* 2960 'J' */ - { 0x3b3dc000, 18, 41}, /* 2961 ')' */ - { 0x3b3d4000, 19, 84}, /* 2962 'T' */ - { 0x3b3d6000, 19, 93}, /* 2963 ']' */ - /* 26 */ - { 0x80000000, 1, 101}, /* 2964 'e' */ - { 0x40000000, 2, 105}, /* 2965 'i' */ - { 0x00000000, 3, 97}, /* 2966 'a' */ - { 0x30000000, 4, 111}, /* 2967 'o' */ - { 0x28000000, 5, 46}, /* 2968 '.' */ - { 0x24000000, 6, 32}, /* 2969 ' ' */ - { 0x21000000, 8, 39}, /* 2970 '\'' */ - { 0x23000000, 8, 121}, /* 2971 'y' */ - { 0x20000000, 9, 117}, /* 2972 'u' */ - { 0x22000000, 9, 115}, /* 2973 's' */ - { 0x22800000, 10, 114}, /* 2974 'r' */ - { 0x20800000, 11, 45}, /* 2975 '-' */ - { 0x20c00000, 11, 44}, /* 2976 ',' */ - { 0x22c00000, 11, 110}, /* 2977 'n' */ - { 0x20a00000, 12, 103}, /* 2978 'g' */ - { 0x20b00000, 12, 118}, /* 2979 'v' */ - { 0x20f00000, 12, 108}, /* 2980 'l' */ - { 0x22e00000, 12, 64}, /* 2981 '@' */ - { 0x22f00000, 12, 58}, /* 2982 ':' */ - { 0x20e80000, 13, 107}, /* 2983 'k' */ - { 0x20e00000, 14, 98}, /* 2984 'b' */ - { 0x20e40000, 15, 116}, /* 2985 't' */ - { 0x20e60000, 16, 100}, /* 2986 'd' */ - { 0x20e70000, 17, 47}, /* 2987 '/' */ - { 0x20e78000, 18, 1}, /* 2988 '0x01' */ - { 0x20e7c000, 18, 49}, /* 2989 '1' */ - /* 39 */ - { 0x00000000, 2, 105}, /* 2990 'i' */ - { 0x60000000, 3, 101}, /* 2991 'e' */ - { 0x80000000, 3, 32}, /* 2992 ' ' */ - { 0xa0000000, 3, 115}, /* 2993 's' */ - { 0xc0000000, 3, 104}, /* 2994 'h' */ - { 0x50000000, 4, 97}, /* 2995 'a' */ - { 0xf0000000, 4, 111}, /* 2996 'o' */ - { 0x40000000, 5, 46}, /* 2997 '.' */ - { 0x48000000, 5, 119}, /* 2998 'w' */ - { 0xe0000000, 5, 110}, /* 2999 'n' */ - { 0xec000000, 7, 114}, /* 3000 'r' */ - { 0xea000000, 8, 44}, /* 3001 ',' */ - { 0xeb000000, 8, 108}, /* 3002 'l' */ - { 0xef000000, 8, 121}, /* 3003 'y' */ - { 0xe9000000, 9, 99}, /* 3004 'c' */ - { 0xee800000, 9, 98}, /* 3005 'b' */ - { 0xe8800000, 10, 58}, /* 3006 ':' */ - { 0xe9800000, 10, 109}, /* 3007 'm' */ - { 0xe9c00000, 10, 39}, /* 3008 '\'' */ - { 0xee000000, 10, 100}, /* 3009 'd' */ - { 0xe8000000, 11, 102}, /* 3010 'f' */ - { 0xe8200000, 11, 93}, /* 3011 ']' */ - { 0xe8400000, 11, 33}, /* 3012 '!' */ - { 0xe8e00000, 11, 107}, /* 3013 'k' */ - { 0xee400000, 11, 45}, /* 3014 '-' */ - { 0xe8700000, 12, 103}, /* 3015 'g' */ - { 0xe8c00000, 12, 63}, /* 3016 '?' */ - { 0xe8d00000, 12, 116}, /* 3017 't' */ - { 0xee700000, 12, 112}, /* 3018 'p' */ - { 0xe8600000, 13, 0}, /* 3019 '0x00' */ - { 0xe8680000, 13, 117}, /* 3020 'u' */ - { 0xee680000, 13, 41}, /* 3021 ')' */ - { 0xee640000, 14, 106}, /* 3022 'j' */ - { 0xee620000, 15, 113}, /* 3023 'q' */ - { 0xee600000, 16, 47}, /* 3024 '/' */ - { 0xee610000, 17, 59}, /* 3025 ';' */ - { 0xee61c000, 18, 91}, /* 3026 '[' */ - { 0xee618000, 19, 1}, /* 3027 '0x01' */ - { 0xee61a000, 19, 66}, /* 3028 'B' */ - /* 39 */ - { 0x40000000, 2, 112}, /* 3029 'p' */ - { 0xc0000000, 2, 116}, /* 3030 't' */ - { 0xa0000000, 3, 32}, /* 3031 ' ' */ - { 0x00000000, 4, 105}, /* 3032 'i' */ - { 0x20000000, 4, 97}, /* 3033 'a' */ - { 0x80000000, 4, 99}, /* 3034 'c' */ - { 0x10000000, 5, 117}, /* 3035 'u' */ - { 0x38000000, 5, 101}, /* 3036 'e' */ - { 0x98000000, 5, 45}, /* 3037 '-' */ - { 0x18000000, 6, 102}, /* 3038 'f' */ - { 0x34000000, 6, 111}, /* 3039 'o' */ - { 0x90000000, 6, 46}, /* 3040 '.' */ - { 0x1c000000, 7, 44}, /* 3041 ',' */ - { 0x1e000000, 7, 109}, /* 3042 'm' */ - { 0x32000000, 7, 121}, /* 3043 'y' */ - { 0x31000000, 8, 57}, /* 3044 '9' */ - { 0x95000000, 8, 39}, /* 3045 '\'' */ - { 0x96000000, 8, 113}, /* 3046 'q' */ - { 0x30000000, 9, 115}, /* 3047 's' */ - { 0x94000000, 9, 58}, /* 3048 ':' */ - { 0x97000000, 9, 104}, /* 3049 'h' */ - { 0x30c00000, 10, 63}, /* 3050 '?' */ - { 0x94800000, 10, 108}, /* 3051 'l' */ - { 0x97800000, 10, 119}, /* 3052 'w' */ - { 0x30800000, 11, 65}, /* 3053 'A' */ - { 0x94c00000, 11, 120}, /* 3054 'x' */ - { 0x94e00000, 11, 98}, /* 3055 'b' */ - { 0x97e00000, 11, 41}, /* 3056 ')' */ - { 0x30b00000, 12, 47}, /* 3057 '/' */ - { 0x30a00000, 13, 52}, /* 3058 '4' */ - { 0x30a80000, 13, 33}, /* 3059 '!' */ - { 0x97c00000, 13, 103}, /* 3060 'g' */ - { 0x97c80000, 13, 0}, /* 3061 '0x00' */ - { 0x97d80000, 13, 59}, /* 3062 ';' */ - { 0x97d20000, 15, 118}, /* 3063 'v' */ - { 0x97d40000, 15, 70}, /* 3064 'F' */ - { 0x97d60000, 15, 69}, /* 3065 'E' */ - { 0x97d00000, 16, 1}, /* 3066 '0x01' */ - { 0x97d10000, 16, 67}, /* 3067 'C' */ - /* 45 */ - { 0x80000000, 1, 32}, /* 3068 ' ' */ - { 0x00000000, 3, 111}, /* 3069 'o' */ - { 0x30000000, 4, 115}, /* 3070 's' */ - { 0x50000000, 4, 46}, /* 3071 '.' */ - { 0x48000000, 5, 44}, /* 3072 ',' */ - { 0x60000000, 5, 101}, /* 3073 'e' */ - { 0x70000000, 5, 39}, /* 3074 '\'' */ - { 0x24000000, 6, 97}, /* 3075 'a' */ - { 0x28000000, 6, 105}, /* 3076 'i' */ - { 0x2c000000, 6, 100}, /* 3077 'd' */ - { 0x44000000, 6, 110}, /* 3078 'n' */ - { 0x6c000000, 6, 58}, /* 3079 ':' */ - { 0x7c000000, 6, 108}, /* 3080 'l' */ - { 0x20000000, 7, 119}, /* 3081 'w' */ - { 0x68000000, 7, 116}, /* 3082 't' */ - { 0x6a000000, 7, 109}, /* 3083 'm' */ - { 0x7a000000, 7, 45}, /* 3084 '-' */ - { 0x23000000, 8, 98}, /* 3085 'b' */ - { 0x40000000, 8, 63}, /* 3086 '?' */ - { 0x41000000, 8, 114}, /* 3087 'r' */ - { 0x42000000, 8, 112}, /* 3088 'p' */ - { 0x43000000, 8, 102}, /* 3089 'f' */ - { 0x79000000, 8, 99}, /* 3090 'c' */ - { 0x22400000, 10, 59}, /* 3091 ';' */ - { 0x22800000, 10, 74}, /* 3092 'J' */ - { 0x78000000, 10, 104}, /* 3093 'h' */ - { 0x78400000, 10, 33}, /* 3094 '!' */ - { 0x78c00000, 10, 103}, /* 3095 'g' */ - { 0x22000000, 11, 41}, /* 3096 ')' */ - { 0x22e00000, 11, 47}, /* 3097 '/' */ - { 0x78a00000, 11, 93}, /* 3098 ']' */ - { 0x22300000, 12, 107}, /* 3099 'k' */ - { 0x22c00000, 12, 1}, /* 3100 '0x01' */ - { 0x22d00000, 12, 117}, /* 3101 'u' */ - { 0x78900000, 12, 0}, /* 3102 '0x00' */ - { 0x22200000, 13, 122}, /* 3103 'z' */ - { 0x78880000, 13, 34}, /* 3104 '\"' */ - { 0x222c0000, 14, 106}, /* 3105 'j' */ - { 0x78840000, 14, 50}, /* 3106 '2' */ - { 0x22280000, 15, 121}, /* 3107 'y' */ - { 0x222a0000, 15, 120}, /* 3108 'x' */ - { 0x78800000, 16, 118}, /* 3109 'v' */ - { 0x78810000, 16, 84}, /* 3110 'T' */ - { 0x78820000, 16, 69}, /* 3111 'E' */ - { 0x78830000, 16, 80}, /* 3112 'P' */ - /* 37 */ - { 0x80000000, 2, 101}, /* 3113 'e' */ - { 0x20000000, 3, 97}, /* 3114 'a' */ - { 0x60000000, 3, 122}, /* 3115 'z' */ - { 0xc0000000, 3, 32}, /* 3116 ' ' */ - { 0xe0000000, 3, 105}, /* 3117 'i' */ - { 0x10000000, 4, 108}, /* 3118 'l' */ - { 0x40000000, 4, 121}, /* 3119 'y' */ - { 0x50000000, 5, 111}, /* 3120 'o' */ - { 0x00000000, 6, 99}, /* 3121 'c' */ - { 0x08000000, 6, 44}, /* 3122 ',' */ - { 0x0c000000, 6, 46}, /* 3123 '.' */ - { 0x58000000, 6, 119}, /* 3124 'w' */ - { 0x04000000, 7, 39}, /* 3125 '\'' */ - { 0x06000000, 8, 58}, /* 3126 ':' */ - { 0x07000000, 8, 116}, /* 3127 't' */ - { 0x5d000000, 8, 109}, /* 3128 'm' */ - { 0x5c000000, 9, 107}, /* 3129 'k' */ - { 0x5e000000, 9, 45}, /* 3130 '-' */ - { 0x5e800000, 9, 117}, /* 3131 'u' */ - { 0x5f800000, 9, 98}, /* 3132 'b' */ - { 0x5c800000, 11, 115}, /* 3133 's' */ - { 0x5ca00000, 11, 47}, /* 3134 '/' */ - { 0x5ce00000, 11, 100}, /* 3135 'd' */ - { 0x5f200000, 11, 112}, /* 3136 'p' */ - { 0x5f600000, 11, 63}, /* 3137 '?' */ - { 0x5cc00000, 12, 104}, /* 3138 'h' */ - { 0x5f000000, 12, 64}, /* 3139 '@' */ - { 0x5f400000, 12, 41}, /* 3140 ')' */ - { 0x5cd00000, 13, 33}, /* 3141 '!' */ - { 0x5f180000, 13, 118}, /* 3142 'v' */ - { 0x5f500000, 13, 103}, /* 3143 'g' */ - { 0x5cd80000, 14, 102}, /* 3144 'f' */ - { 0x5cdc0000, 14, 114}, /* 3145 'r' */ - { 0x5f100000, 14, 113}, /* 3146 'q' */ - { 0x5f140000, 14, 110}, /* 3147 'n' */ - { 0x5f580000, 14, 1}, /* 3148 '0x01' */ - { 0x5f5c0000, 14, 93}, /* 3149 ']' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 3150 '0x01' */ - { 0x80000000, 1, 1}, /* 3151 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 3152 '0x01' */ - { 0x80000000, 1, 1}, /* 3153 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 3154 '0x01' */ - { 0x80000000, 1, 0}, /* 3155 '0x00' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 3156 '0x01' */ - { 0x80000000, 1, 1}, /* 3157 '0x01' */ - /* 2 */ - { 0x00000000, 1, 1}, /* 3158 '0x01' */ - { 0x80000000, 1, 1} /* 3159 '0x01' */ + /* 51 */ + {0x40000000, 3, 65}, /* 0 'A' */ + {0x80000000, 3, 67}, /* 1 'C' */ + {0xe0000000, 3, 84}, /* 2 'T' */ + {0x10000000, 4, 74}, /* 3 'J' */ + {0x30000000, 4, 68}, /* 4 'D' */ + {0xa0000000, 4, 83}, /* 5 'S' */ + {0x00000000, 5, 72}, /* 6 'H' */ + {0x20000000, 5, 73}, /* 7 'I' */ + {0x28000000, 5, 82}, /* 8 'R' */ + {0x68000000, 5, 70}, /* 9 'F' */ + {0x70000000, 5, 46}, /* 10 '.' */ + {0x78000000, 5, 87}, /* 11 'W' */ + {0xb8000000, 5, 77}, /* 12 'M' */ + {0xc0000000, 5, 66}, /* 13 'B' */ + {0xc8000000, 5, 80}, /* 14 'P' */ + {0xd8000000, 5, 78}, /* 15 'N' */ + {0x08000000, 6, 79}, /* 16 'O' */ + {0x64000000, 6, 91}, /* 17 '[' */ + {0xb4000000, 6, 76}, /* 18 'L' */ + {0xd4000000, 6, 69}, /* 19 'E' */ + {0x0c000000, 7, 75}, /* 20 'K' */ + {0xd0000000, 7, 89}, /* 21 'Y' */ + {0xd2000000, 7, 71}, /* 22 'G' */ + {0x0e000000, 8, 50}, /* 23 '2' */ + {0x60000000, 8, 112}, /* 24 'p' */ + {0x61000000, 8, 98}, /* 25 'b' */ + {0x62000000, 8, 85}, /* 26 'U' */ + {0x63000000, 8, 40}, /* 27 '(' */ + {0xb0000000, 8, 49}, /* 28 '1' */ + {0xb3000000, 8, 86}, /* 29 'V' */ + {0x0f000000, 9, 81}, /* 30 'Q' */ + {0xb1000000, 9, 51}, /* 31 '3' */ + {0x0f800000, 10, 57}, /* 32 '9' */ + {0x0fc00000, 10, 56}, /* 33 '8' */ + {0xb1800000, 10, 54}, /* 34 '6' */ + {0xb1c00000, 10, 53}, /* 35 '5' */ + {0xb2000000, 10, 90}, /* 36 'Z' */ + {0xb2400000, 10, 55}, /* 37 '7' */ + {0xb2800000, 10, 52}, /* 38 '4' */ + {0xb2e00000, 12, 88}, /* 39 'X' */ + {0xb2f00000, 12, 32}, /* 40 ' ' */ + {0xb2c80000, 13, 119}, /* 41 'w' */ + {0xb2d00000, 13, 39}, /* 42 '\'' */ + {0xb2d80000, 13, 34}, /* 43 '\"' */ + {0xb2c00000, 14, 116}, /* 44 't' */ + {0xb2c40000, 15, 97}, /* 45 'a' */ + {0xb2c60000, 16, 96}, /* 46 '`' */ + {0xb2c70000, 17, 1}, /* 47 '0x01' */ + {0xb2c78000, 17, 109}, /* 48 'm' */ + {0x00000000, 1, 1}, /* 49 '0x01' */ + {0x80000000, 1, 1}, /* 50 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 51 '0x01' */ + {0x80000000, 1, 1}, /* 52 '0x01' */ + /* 0 */ + /* 2 */ + {0x00000000, 1, 1}, /* 53 '0x01' */ + {0x80000000, 1, 1}, /* 54 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 55 '0x01' */ + {0x80000000, 1, 1}, /* 56 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 57 '0x01' */ + {0x80000000, 1, 1}, /* 58 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 59 '0x01' */ + {0x80000000, 1, 1}, /* 60 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 61 '0x01' */ + {0x80000000, 1, 1}, /* 62 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 63 '0x01' */ + {0x80000000, 1, 1}, /* 64 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 65 '0x01' */ + {0x80000000, 1, 1}, /* 66 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 67 '0x01' */ + {0x80000000, 1, 1}, /* 68 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 69 '0x01' */ + {0x80000000, 1, 1}, /* 70 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 71 '0x01' */ + {0x80000000, 1, 1}, /* 72 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 73 '0x01' */ + {0x80000000, 1, 1}, /* 74 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 75 '0x01' */ + {0x80000000, 1, 1}, /* 76 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 77 '0x01' */ + {0x80000000, 1, 1}, /* 78 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 79 '0x01' */ + {0x80000000, 1, 1}, /* 80 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 81 '0x01' */ + {0x80000000, 1, 1}, /* 82 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 83 '0x01' */ + {0x80000000, 1, 1}, /* 84 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 85 '0x01' */ + {0x80000000, 1, 1}, /* 86 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 87 '0x01' */ + {0x80000000, 1, 1}, /* 88 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 89 '0x01' */ + {0x80000000, 1, 1}, /* 90 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 91 '0x01' */ + {0x80000000, 1, 1}, /* 92 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 93 '0x01' */ + {0x80000000, 1, 1}, /* 94 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 95 '0x01' */ + {0x80000000, 1, 1}, /* 96 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 97 '0x01' */ + {0x80000000, 1, 1}, /* 98 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 99 '0x01' */ + {0x80000000, 1, 1}, /* 100 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 101 '0x01' */ + {0x80000000, 1, 1}, /* 102 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 103 '0x01' */ + {0x80000000, 1, 1}, /* 104 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 105 '0x01' */ + {0x80000000, 1, 1}, /* 106 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 107 '0x01' */ + {0x80000000, 1, 1}, /* 108 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 109 '0x01' */ + {0x80000000, 1, 1}, /* 110 '0x01' */ + /* 80 */ + {0x40000000, 3, 97}, /* 111 'a' */ + {0x80000000, 3, 116}, /* 112 't' */ + {0x10000000, 4, 111}, /* 113 'o' */ + {0x20000000, 4, 115}, /* 114 's' */ + {0x30000000, 5, 100}, /* 115 'd' */ + {0x60000000, 5, 91}, /* 116 '[' */ + {0x78000000, 5, 112}, /* 117 'p' */ + {0xa8000000, 5, 98}, /* 118 'b' */ + {0xc8000000, 5, 99}, /* 119 'c' */ + {0xd0000000, 5, 104}, /* 120 'h' */ + {0xe0000000, 5, 119}, /* 121 'w' */ + {0xe8000000, 5, 105}, /* 122 'i' */ + {0xf8000000, 5, 102}, /* 123 'f' */ + {0x00000000, 6, 65}, /* 124 'A' */ + {0x0c000000, 6, 77}, /* 125 'M' */ + {0x3c000000, 6, 101}, /* 126 'e' */ + {0x70000000, 6, 66}, /* 127 'B' */ + {0x74000000, 6, 67}, /* 128 'C' */ + {0xa0000000, 6, 84}, /* 129 'T' */ + {0xb4000000, 6, 83}, /* 130 'S' */ + {0xb8000000, 6, 103}, /* 131 'g' */ + {0xc0000000, 6, 114}, /* 132 'r' */ + {0xd8000000, 6, 110}, /* 133 'n' */ + {0xdc000000, 6, 108}, /* 134 'l' */ + {0xf4000000, 6, 109}, /* 135 'm' */ + {0x06000000, 7, 118}, /* 136 'v' */ + {0x08000000, 7, 71}, /* 137 'G' */ + {0x0a000000, 7, 78}, /* 138 'N' */ + {0x3a000000, 7, 121}, /* 139 'y' */ + {0x6a000000, 7, 72}, /* 140 'H' */ + {0x6e000000, 7, 76}, /* 141 'L' */ + {0xa4000000, 7, 74}, /* 142 'J' */ + {0xa6000000, 7, 70}, /* 143 'F' */ + {0xb2000000, 7, 82}, /* 144 'R' */ + {0xbc000000, 7, 117}, /* 145 'u' */ + {0xc4000000, 7, 68}, /* 146 'D' */ + {0xc6000000, 7, 87}, /* 147 'W' */ + {0xf2000000, 7, 80}, /* 148 'P' */ + {0x04000000, 8, 107}, /* 149 'k' */ + {0x05000000, 8, 79}, /* 150 'O' */ + {0x68000000, 8, 45}, /* 151 '-' */ + {0x6d000000, 8, 49}, /* 152 '1' */ + {0xb1000000, 8, 75}, /* 153 'K' */ + {0xbe000000, 8, 106}, /* 154 'j' */ + {0xf0000000, 8, 73}, /* 155 'I' */ + {0xf1000000, 8, 69}, /* 156 'E' */ + {0x39000000, 9, 113}, /* 157 'q' */ + {0x39800000, 9, 85}, /* 158 'U' */ + {0x69000000, 9, 86}, /* 159 'V' */ + {0x6c000000, 9, 89}, /* 160 'Y' */ + {0x6c800000, 9, 32}, /* 161 ' ' */ + {0xb0800000, 9, 50}, /* 162 '2' */ + {0xbf000000, 9, 0}, /* 163 '0x00' */ + {0x38000000, 10, 51}, /* 164 '3' */ + {0x38400000, 10, 56}, /* 165 '8' */ + {0x38800000, 10, 54}, /* 166 '6' */ + {0x69c00000, 10, 53}, /* 167 '5' */ + {0xb0000000, 10, 40}, /* 168 '(' */ + {0xbf800000, 10, 55}, /* 169 '7' */ + {0x38c00000, 11, 48}, /* 170 '0' */ + {0x69800000, 11, 39}, /* 171 '\'' */ + {0x69a00000, 11, 57}, /* 172 '9' */ + {0xb0400000, 11, 90}, /* 173 'Z' */ + {0xbfc00000, 11, 52}, /* 174 '4' */ + {0xbfe00000, 11, 81}, /* 175 'Q' */ + {0x38f00000, 12, 88}, /* 176 'X' */ + {0xb0600000, 13, 1}, /* 177 '0x01' */ + {0xb0680000, 13, 46}, /* 178 '.' */ + {0xb0700000, 13, 38}, /* 179 '&' */ + {0x38e00000, 14, 92}, /* 180 '\\' */ + {0x38e80000, 14, 64}, /* 181 '@' */ + {0x38ec0000, 14, 96}, /* 182 '`' */ + {0xb0780000, 14, 34}, /* 183 '\"' */ + {0xb07c0000, 14, 122}, /* 184 'z' */ + {0x38e60000, 15, 36}, /* 185 '$' */ + {0x38e40000, 16, 43}, /* 186 '+' */ + {0x38e58000, 17, 120}, /* 187 'x' */ + {0x38e54000, 18, 93}, /* 188 ']' */ + {0x38e50000, 19, 47}, /* 189 '/' */ + {0x38e52000, 19, 63}, /* 190 '?' */ + /* 13 */ + {0x80000000, 1, 32}, /* 191 ' ' */ + {0x40000000, 2, 0}, /* 192 '0x00' */ + {0x20000000, 3, 46}, /* 193 '.' */ + {0x00000000, 4, 58}, /* 194 ':' */ + {0x18000000, 5, 91}, /* 195 '[' */ + {0x12000000, 7, 34}, /* 196 '\"' */ + {0x14000000, 7, 47}, /* 197 '/' */ + {0x16000000, 7, 33}, /* 198 '!' */ + {0x10000000, 8, 41}, /* 199 ')' */ + {0x11000000, 9, 39}, /* 200 '\'' */ + {0x11c00000, 10, 63}, /* 201 '?' */ + {0x11800000, 11, 1}, /* 202 '0x01' */ + {0x11a00000, 11, 93}, /* 203 ']' */ + /* 36 */ + {0xc0000000, 2, 32}, /* 204 ' ' */ + {0x20000000, 3, 46}, /* 205 '.' */ + {0x00000000, 4, 112}, /* 206 'p' */ + {0x50000000, 4, 66}, /* 207 'B' */ + {0x70000000, 4, 84}, /* 208 'T' */ + {0x80000000, 4, 105}, /* 209 'i' */ + {0x10000000, 5, 102}, /* 210 'f' */ + {0x18000000, 5, 87}, /* 211 'W' */ + {0x40000000, 5, 83}, /* 212 'S' */ + {0x60000000, 5, 116}, /* 213 't' */ + {0x68000000, 5, 67}, /* 214 'C' */ + {0xa0000000, 5, 0}, /* 215 '0x00' */ + {0xb8000000, 5, 44}, /* 216 ',' */ + {0x48000000, 6, 74}, /* 217 'J' */ + {0x90000000, 6, 109}, /* 218 'm' */ + {0xa8000000, 6, 110}, /* 219 'n' */ + {0xac000000, 6, 73}, /* 220 'I' */ + {0x4c000000, 7, 69}, /* 221 'E' */ + {0x4e000000, 7, 68}, /* 222 'D' */ + {0x94000000, 7, 119}, /* 223 'w' */ + {0x96000000, 7, 103}, /* 224 'g' */ + {0x98000000, 7, 98}, /* 225 'b' */ + {0x9a000000, 7, 76}, /* 226 'L' */ + {0x9c000000, 7, 45}, /* 227 '-' */ + {0xb0000000, 7, 99}, /* 228 'c' */ + {0xb2000000, 7, 72}, /* 229 'H' */ + {0x9e000000, 8, 80}, /* 230 'P' */ + {0xb4000000, 8, 114}, /* 231 'r' */ + {0xb7000000, 8, 75}, /* 232 'K' */ + {0x9f800000, 9, 108}, /* 233 'l' */ + {0xb5000000, 9, 89}, /* 234 'Y' */ + {0xb5800000, 9, 81}, /* 235 'Q' */ + {0xb6000000, 9, 71}, /* 236 'G' */ + {0xb6800000, 9, 65}, /* 237 'A' */ + {0x9f000000, 10, 1}, /* 238 '0x01' */ + {0x9f400000, 10, 97}, /* 239 'a' */ + /* 2 */ + {0x00000000, 1, 1}, /* 240 '0x01' */ + {0x80000000, 1, 1}, /* 241 '0x01' */ + /* 8 */ + {0x00000000, 1, 49}, /* 242 '1' */ + {0xc0000000, 2, 51}, /* 243 '3' */ + {0x80000000, 3, 52}, /* 244 '4' */ + {0xb0000000, 4, 50}, /* 245 '2' */ + {0xa8000000, 5, 55}, /* 246 '7' */ + {0xa4000000, 6, 53}, /* 247 '5' */ + {0xa0000000, 7, 1}, /* 248 '0x01' */ + {0xa2000000, 7, 57}, /* 249 '9' */ + /* 3 */ + {0x80000000, 1, 32}, /* 250 ' ' */ + {0x00000000, 2, 1}, /* 251 '0x01' */ + {0x40000000, 2, 44}, /* 252 ',' */ + /* 12 */ + {0x80000000, 1, 32}, /* 253 ' ' */ + {0x40000000, 2, 119}, /* 254 'w' */ + {0x20000000, 3, 66}, /* 255 'B' */ + {0x00000000, 4, 69}, /* 256 'E' */ + {0x10000000, 6, 50}, /* 257 '2' */ + {0x18000000, 6, 65}, /* 258 'A' */ + {0x1c000000, 6, 82}, /* 259 'R' */ + {0x14000000, 8, 79}, /* 260 'O' */ + {0x15000000, 8, 52}, /* 261 '4' */ + {0x17000000, 8, 74}, /* 262 'J' */ + {0x16000000, 9, 1}, /* 263 '0x01' */ + {0x16800000, 9, 80}, /* 264 'P' */ + /* 71 */ + {0x80000000, 1, 115}, /* 265 's' */ + {0x20000000, 3, 116}, /* 266 't' */ + {0x40000000, 3, 32}, /* 267 ' ' */ + {0x00000000, 4, 108}, /* 268 'l' */ + {0x68000000, 5, 114}, /* 269 'r' */ + {0x10000000, 6, 110}, /* 270 'n' */ + {0x14000000, 6, 46}, /* 271 '.' */ + {0x18000000, 6, 67}, /* 272 'C' */ + {0x60000000, 6, 66}, /* 273 'B' */ + {0x74000000, 6, 65}, /* 274 'A' */ + {0x70000000, 7, 100}, /* 275 'd' */ + {0x78000000, 7, 118}, /* 276 'v' */ + {0x1c000000, 8, 83}, /* 277 'S' */ + {0x1f000000, 8, 112}, /* 278 'p' */ + {0x65000000, 8, 68}, /* 279 'D' */ + {0x7b000000, 8, 105}, /* 280 'i' */ + {0x7c000000, 8, 99}, /* 281 'c' */ + {0x7d000000, 8, 109}, /* 282 'm' */ + {0x7f000000, 8, 44}, /* 283 ',' */ + {0x1d000000, 9, 102}, /* 284 'f' */ + {0x1d800000, 9, 103}, /* 285 'g' */ + {0x64000000, 9, 70}, /* 286 'F' */ + {0x64800000, 9, 104}, /* 287 'h' */ + {0x66800000, 9, 72}, /* 288 'H' */ + {0x67000000, 9, 78}, /* 289 'N' */ + {0x72800000, 9, 82}, /* 290 'R' */ + {0x73000000, 9, 0}, /* 291 '0x00' */ + {0x73800000, 9, 84}, /* 292 'T' */ + {0x7a800000, 9, 71}, /* 293 'G' */ + {0x7e800000, 9, 76}, /* 294 'L' */ + {0x1e000000, 10, 111}, /* 295 'o' */ + {0x1e400000, 10, 75}, /* 296 'K' */ + {0x1ec00000, 10, 97}, /* 297 'a' */ + {0x66400000, 10, 117}, /* 298 'u' */ + {0x67c00000, 10, 79}, /* 299 'O' */ + {0x72400000, 10, 73}, /* 300 'I' */ + {0x7a000000, 10, 119}, /* 301 'w' */ + {0x7a400000, 10, 98}, /* 302 'b' */ + {0x7e400000, 10, 101}, /* 303 'e' */ + {0x1ea00000, 11, 63}, /* 304 '?' */ + {0x66000000, 11, 69}, /* 305 'E' */ + {0x66200000, 11, 55}, /* 306 '7' */ + {0x72000000, 11, 80}, /* 307 'P' */ + {0x1e900000, 12, 87}, /* 308 'W' */ + {0x67900000, 12, 58}, /* 309 ':' */ + {0x67a00000, 12, 33}, /* 310 '!' */ + {0x72300000, 12, 74}, /* 311 'J' */ + {0x7e100000, 12, 113}, /* 312 'q' */ + {0x7e300000, 12, 77}, /* 313 'M' */ + {0x1e880000, 13, 86}, /* 314 'V' */ + {0x67880000, 13, 57}, /* 315 '9' */ + {0x67b80000, 13, 121}, /* 316 'y' */ + {0x72200000, 13, 56}, /* 317 '8' */ + {0x72280000, 13, 53}, /* 318 '5' */ + {0x7e000000, 13, 54}, /* 319 '6' */ + {0x7e280000, 13, 107}, /* 320 'k' */ + {0x1e800000, 14, 50}, /* 321 '2' */ + {0x1e840000, 14, 48}, /* 322 '0' */ + {0x67840000, 14, 89}, /* 323 'Y' */ + {0x67b00000, 14, 41}, /* 324 ')' */ + {0x7e080000, 14, 106}, /* 325 'j' */ + {0x7e0c0000, 14, 81}, /* 326 'Q' */ + {0x67800000, 15, 45}, /* 327 '-' */ + {0x67820000, 15, 39}, /* 328 '\'' */ + {0x67b60000, 15, 122}, /* 329 'z' */ + {0x7e200000, 15, 88}, /* 330 'X' */ + {0x7e220000, 15, 85}, /* 331 'U' */ + {0x7e240000, 15, 52}, /* 332 '4' */ + {0x7e260000, 15, 51}, /* 333 '3' */ + {0x67b40000, 16, 1}, /* 334 '0x01' */ + {0x67b50000, 16, 49}, /* 335 '1' */ + /* 55 */ + {0x40000000, 2, 49}, /* 336 '1' */ + {0x00000000, 3, 80}, /* 337 'P' */ + {0xa0000000, 3, 116}, /* 338 't' */ + {0x80000000, 4, 50}, /* 339 '2' */ + {0xd0000000, 4, 53}, /* 340 '5' */ + {0xe0000000, 4, 78}, /* 341 'N' */ + {0x38000000, 5, 84}, /* 342 'T' */ + {0x90000000, 5, 112}, /* 343 'p' */ + {0xf8000000, 5, 99}, /* 344 'c' */ + {0x24000000, 6, 97}, /* 345 'a' */ + {0x28000000, 6, 83}, /* 346 'S' */ + {0x30000000, 6, 82}, /* 347 'R' */ + {0x9c000000, 6, 101}, /* 348 'e' */ + {0xf0000000, 6, 74}, /* 349 'J' */ + {0xf4000000, 6, 65}, /* 350 'A' */ + {0x2c000000, 7, 68}, /* 351 'D' */ + {0x36000000, 7, 75}, /* 352 'K' */ + {0x98000000, 7, 118}, /* 353 'v' */ + {0x9a000000, 7, 115}, /* 354 's' */ + {0xc0000000, 7, 98}, /* 355 'b' */ + {0xc4000000, 7, 71}, /* 356 'G' */ + {0xc6000000, 7, 56}, /* 357 '8' */ + {0xc8000000, 7, 77}, /* 358 'M' */ + {0xca000000, 7, 72}, /* 359 'H' */ + {0xcc000000, 7, 67}, /* 360 'C' */ + {0x20000000, 8, 109}, /* 361 'm' */ + {0x22000000, 8, 111}, /* 362 'o' */ + {0x23000000, 8, 69}, /* 363 'E' */ + {0x2e000000, 8, 87}, /* 364 'W' */ + {0xc3000000, 8, 103}, /* 365 'g' */ + {0xce000000, 8, 76}, /* 366 'L' */ + {0x21000000, 9, 100}, /* 367 'd' */ + {0x2f800000, 9, 85}, /* 368 'U' */ + {0x34000000, 9, 70}, /* 369 'F' */ + {0x35000000, 9, 102}, /* 370 'f' */ + {0xc2000000, 9, 119}, /* 371 'w' */ + {0xc2800000, 9, 66}, /* 372 'B' */ + {0xcf800000, 9, 110}, /* 373 'n' */ + {0x21800000, 10, 108}, /* 374 'l' */ + {0x21c00000, 10, 57}, /* 375 '9' */ + {0x2f000000, 10, 52}, /* 376 '4' */ + {0x2f400000, 10, 73}, /* 377 'I' */ + {0x34800000, 10, 51}, /* 378 '3' */ + {0x35c00000, 10, 104}, /* 379 'h' */ + {0xcf400000, 10, 105}, /* 380 'i' */ + {0x34c00000, 11, 90}, /* 381 'Z' */ + {0x34e00000, 11, 86}, /* 382 'V' */ + {0x35800000, 11, 32}, /* 383 ' ' */ + {0xcf000000, 11, 107}, /* 384 'k' */ + {0x35b00000, 12, 79}, /* 385 'O' */ + {0xcf200000, 12, 39}, /* 386 '\'' */ + {0x35a00000, 13, 1}, /* 387 '0x01' */ + {0x35a80000, 13, 117}, /* 388 'u' */ + {0xcf300000, 13, 88}, /* 389 'X' */ + {0xcf380000, 13, 55}, /* 390 '7' */ + /* 12 */ + {0x00000000, 1, 32}, /* 391 ' ' */ + {0xc0000000, 2, 46}, /* 392 '.' */ + {0xa0000000, 3, 0}, /* 393 '0x00' */ + {0x90000000, 4, 44}, /* 394 ',' */ + {0x80000000, 5, 58}, /* 395 ':' */ + {0x8c000000, 6, 59}, /* 396 ';' */ + {0x8a000000, 7, 33}, /* 397 '!' */ + {0x89000000, 8, 40}, /* 398 '(' */ + {0x88000000, 10, 1}, /* 399 '0x01' */ + {0x88400000, 10, 111}, /* 400 'o' */ + {0x88800000, 10, 63}, /* 401 '?' */ + {0x88c00000, 10, 41}, /* 402 ')' */ + /* 13 */ + {0x00000000, 1, 42}, /* 403 '*' */ + {0x80000000, 3, 115}, /* 404 's' */ + {0xa0000000, 3, 32}, /* 405 ' ' */ + {0xc0000000, 4, 109}, /* 406 'm' */ + {0xe0000000, 4, 116}, /* 407 't' */ + {0xd0000000, 5, 103}, /* 408 'g' */ + {0xd8000000, 5, 107}, /* 409 'k' */ + {0xf8000000, 5, 100}, /* 410 'd' */ + {0xf4000000, 6, 121}, /* 411 'y' */ + {0xf2000000, 7, 101}, /* 412 'e' */ + {0xf0000000, 8, 105}, /* 413 'i' */ + {0xf1000000, 9, 1}, /* 414 '0x01' */ + {0xf1800000, 9, 110}, /* 415 'n' */ + /* 3 */ + {0x80000000, 1, 110}, /* 416 'n' */ + {0x00000000, 2, 1}, /* 417 '0x01' */ + {0x40000000, 2, 32}, /* 418 ' ' */ + /* 20 */ + {0x80000000, 1, 32}, /* 419 ' ' */ + {0x40000000, 2, 83}, /* 420 'S' */ + {0x20000000, 3, 48}, /* 421 '0' */ + {0x10000000, 4, 65}, /* 422 'A' */ + {0x00000000, 5, 53}, /* 423 '5' */ + {0x0c000000, 7, 98}, /* 424 'b' */ + {0x0e000000, 7, 51}, /* 425 '3' */ + {0x08000000, 8, 50}, /* 426 '2' */ + {0x09000000, 8, 34}, /* 427 '\"' */ + {0x0b000000, 8, 49}, /* 428 '1' */ + {0x0a000000, 10, 81}, /* 429 'Q' */ + {0x0a800000, 10, 39}, /* 430 '\'' */ + {0x0ae00000, 11, 52}, /* 431 '4' */ + {0x0a400000, 12, 84}, /* 432 'T' */ + {0x0a500000, 12, 66}, /* 433 'B' */ + {0x0a600000, 12, 55}, /* 434 '7' */ + {0x0a700000, 12, 54}, /* 435 '6' */ + {0x0ac00000, 12, 0}, /* 436 '0x00' */ + {0x0ad00000, 13, 1}, /* 437 '0x01' */ + {0x0ad80000, 13, 105}, /* 438 'i' */ + /* 64 */ + {0x00000000, 2, 32}, /* 439 ' ' */ + {0x40000000, 4, 116}, /* 440 't' */ + {0x50000000, 4, 98}, /* 441 'b' */ + {0x60000000, 4, 119}, /* 442 'w' */ + {0x70000000, 4, 117}, /* 443 'u' */ + {0x90000000, 4, 111}, /* 444 'o' */ + {0xa0000000, 4, 115}, /* 445 's' */ + {0xb0000000, 4, 102}, /* 446 'f' */ + {0x80000000, 5, 99}, /* 447 'c' */ + {0xd8000000, 5, 108}, /* 448 'l' */ + {0xe8000000, 5, 100}, /* 449 'd' */ + {0x88000000, 6, 57}, /* 450 '9' */ + {0xc0000000, 6, 104}, /* 451 'h' */ + {0xc8000000, 6, 49}, /* 452 '1' */ + {0xcc000000, 6, 121}, /* 453 'y' */ + {0xd4000000, 6, 114}, /* 454 'r' */ + {0xe0000000, 6, 97}, /* 455 'a' */ + {0xf0000000, 6, 109}, /* 456 'm' */ + {0xf8000000, 6, 112}, /* 457 'p' */ + {0x8c000000, 7, 83}, /* 458 'S' */ + {0xd0000000, 7, 101}, /* 459 'e' */ + {0xd2000000, 7, 105}, /* 460 'i' */ + {0xf6000000, 7, 110}, /* 461 'n' */ + {0x8e000000, 8, 67}, /* 462 'C' */ + {0xc5000000, 8, 87}, /* 463 'W' */ + {0xc7000000, 8, 103}, /* 464 'g' */ + {0xe5000000, 8, 74}, /* 465 'J' */ + {0xe6000000, 8, 68}, /* 466 'D' */ + {0xf5000000, 8, 50}, /* 467 '2' */ + {0xfc000000, 8, 55}, /* 468 '7' */ + {0xfe000000, 8, 71}, /* 469 'G' */ + {0xff000000, 8, 79}, /* 470 'O' */ + {0x8f800000, 9, 72}, /* 471 'H' */ + {0xc4000000, 9, 65}, /* 472 'A' */ + {0xc6000000, 9, 54}, /* 473 '6' */ + {0xc6800000, 9, 66}, /* 474 'B' */ + {0xe7800000, 9, 77}, /* 475 'M' */ + {0xf4000000, 9, 69}, /* 476 'E' */ + {0xf4800000, 9, 76}, /* 477 'L' */ + {0xfd000000, 9, 85}, /* 478 'U' */ + {0xfd800000, 9, 107}, /* 479 'k' */ + {0x8f000000, 10, 70}, /* 480 'F' */ + {0xc4800000, 10, 106}, /* 481 'j' */ + {0xc4c00000, 10, 80}, /* 482 'P' */ + {0xe4400000, 10, 113}, /* 483 'q' */ + {0xe4800000, 10, 53}, /* 484 '5' */ + {0xe4c00000, 10, 84}, /* 485 'T' */ + {0xe7400000, 10, 73}, /* 486 'I' */ + {0x8f600000, 11, 75}, /* 487 'K' */ + {0xe4000000, 11, 118}, /* 488 'v' */ + {0xe4200000, 11, 90}, /* 489 'Z' */ + {0xe7200000, 11, 78}, /* 490 'N' */ + {0x8f500000, 12, 82}, /* 491 'R' */ + {0xe7100000, 12, 89}, /* 492 'Y' */ + {0x8f480000, 13, 48}, /* 493 '0' */ + {0x8f400000, 14, 52}, /* 494 '4' */ + {0x8f440000, 14, 122}, /* 495 'z' */ + {0xe7040000, 14, 86}, /* 496 'V' */ + {0xe7080000, 14, 51}, /* 497 '3' */ + {0xe70c0000, 14, 56}, /* 498 '8' */ + {0xe7020000, 15, 81}, /* 499 'Q' */ + {0xe7000000, 16, 39}, /* 500 '\'' */ + {0xe7010000, 17, 1}, /* 501 '0x01' */ + {0xe7018000, 17, 120}, /* 502 'x' */ + /* 65 */ + {0x80000000, 1, 32}, /* 503 ' ' */ + {0x40000000, 2, 0}, /* 504 '0x00' */ + {0x30000000, 4, 46}, /* 505 '.' */ + {0x10000000, 5, 105}, /* 506 'i' */ + {0x20000000, 5, 48}, /* 507 '0' */ + {0x28000000, 5, 99}, /* 508 'c' */ + {0x04000000, 6, 117}, /* 509 'u' */ + {0x00000000, 7, 97}, /* 510 'a' */ + {0x02000000, 7, 91}, /* 511 '[' */ + {0x1a000000, 7, 51}, /* 512 '3' */ + {0x08000000, 8, 52}, /* 513 '4' */ + {0x0e000000, 8, 72}, /* 514 'H' */ + {0x18000000, 8, 83}, /* 515 'S' */ + {0x19000000, 8, 87}, /* 516 'W' */ + {0x1c000000, 8, 111}, /* 517 'o' */ + {0x1e000000, 8, 49}, /* 518 '1' */ + {0x0a000000, 9, 53}, /* 519 '5' */ + {0x0a800000, 9, 76}, /* 520 'L' */ + {0x0b800000, 9, 112}, /* 521 'p' */ + {0x0c000000, 9, 84}, /* 522 'T' */ + {0x0c800000, 9, 65}, /* 523 'A' */ + {0x0d000000, 9, 77}, /* 524 'M' */ + {0x0f000000, 9, 67}, /* 525 'C' */ + {0x0f800000, 9, 50}, /* 526 '2' */ + {0x1d800000, 9, 68}, /* 527 'D' */ + {0x1f000000, 9, 66}, /* 528 'B' */ + {0x09000000, 10, 78}, /* 529 'N' */ + {0x09800000, 10, 116}, /* 530 't' */ + {0x09c00000, 10, 74}, /* 531 'J' */ + {0x0b400000, 10, 82}, /* 532 'R' */ + {0x0dc00000, 10, 80}, /* 533 'P' */ + {0x1d400000, 10, 115}, /* 534 's' */ + {0x1fc00000, 10, 73}, /* 535 'I' */ + {0x0b000000, 11, 114}, /* 536 'r' */ + {0x0d800000, 11, 86}, /* 537 'V' */ + {0x1d000000, 11, 119}, /* 538 'w' */ + {0x1d200000, 11, 70}, /* 539 'F' */ + {0x1fa00000, 11, 71}, /* 540 'G' */ + {0x09400000, 12, 69}, /* 541 'E' */ + {0x09500000, 12, 58}, /* 542 ':' */ + {0x0b200000, 12, 104}, /* 543 'h' */ + {0x0da00000, 12, 44}, /* 544 ',' */ + {0x1f800000, 12, 39}, /* 545 '\'' */ + {0x09680000, 13, 98}, /* 546 'b' */ + {0x09700000, 13, 75}, /* 547 'K' */ + {0x09780000, 13, 89}, /* 548 'Y' */ + {0x0b380000, 13, 79}, /* 549 'O' */ + {0x0db00000, 13, 45}, /* 550 '-' */ + {0x1f900000, 13, 102}, /* 551 'f' */ + {0x1f980000, 13, 40}, /* 552 '(' */ + {0x0b300000, 14, 34}, /* 553 '\"' */ + {0x0db80000, 14, 121}, /* 554 'y' */ + {0x09600000, 15, 63}, /* 555 '?' */ + {0x09620000, 15, 109}, /* 556 'm' */ + {0x09640000, 15, 81}, /* 557 'Q' */ + {0x0dbc0000, 15, 42}, /* 558 '*' */ + {0x0dbe0000, 15, 38}, /* 559 '&' */ + {0x09660000, 16, 85}, /* 560 'U' */ + {0x09670000, 16, 59}, /* 561 ';' */ + {0x0b340000, 16, 56}, /* 562 '8' */ + {0x0b350000, 16, 54}, /* 563 '6' */ + {0x0b370000, 16, 107}, /* 564 'k' */ + {0x0b360000, 17, 100}, /* 565 'd' */ + {0x0b368000, 18, 1}, /* 566 '0x01' */ + {0x0b36c000, 18, 110}, /* 567 'n' */ + /* 51 */ + {0x40000000, 2, 99}, /* 568 'c' */ + {0xc0000000, 3, 49}, /* 569 '1' */ + {0xe0000000, 3, 101}, /* 570 'e' */ + {0x00000000, 4, 53}, /* 571 '5' */ + {0x20000000, 4, 56}, /* 572 '8' */ + {0x10000000, 5, 84}, /* 573 'T' */ + {0x18000000, 5, 102}, /* 574 'f' */ + {0x30000000, 5, 66}, /* 575 'B' */ + {0x38000000, 5, 50}, /* 576 '2' */ + {0x88000000, 5, 51}, /* 577 '3' */ + {0x90000000, 5, 55}, /* 578 '7' */ + {0xa0000000, 5, 54}, /* 579 '6' */ + {0xb0000000, 5, 97}, /* 580 'a' */ + {0xbc000000, 6, 52}, /* 581 '4' */ + {0x80000000, 7, 70}, /* 582 'F' */ + {0x84000000, 7, 115}, /* 583 's' */ + {0x86000000, 7, 77}, /* 584 'M' */ + {0x98000000, 7, 72}, /* 585 'H' */ + {0x9c000000, 7, 68}, /* 586 'D' */ + {0x9e000000, 7, 65}, /* 587 'A' */ + {0xaa000000, 7, 83}, /* 588 'S' */ + {0x83000000, 8, 109}, /* 589 'm' */ + {0x9a000000, 8, 87}, /* 590 'W' */ + {0xa8000000, 8, 71}, /* 591 'G' */ + {0xa9000000, 8, 85}, /* 592 'U' */ + {0xac000000, 8, 100}, /* 593 'd' */ + {0xad000000, 8, 79}, /* 594 'O' */ + {0xae000000, 8, 78}, /* 595 'N' */ + {0xb9000000, 8, 67}, /* 596 'C' */ + {0xbb000000, 8, 80}, /* 597 'P' */ + {0x9b000000, 9, 76}, /* 598 'L' */ + {0xaf000000, 9, 32}, /* 599 ' ' */ + {0xaf800000, 9, 73}, /* 600 'I' */ + {0xb8000000, 9, 69}, /* 601 'E' */ + {0xb8800000, 9, 82}, /* 602 'R' */ + {0xba000000, 9, 75}, /* 603 'K' */ + {0xba800000, 9, 116}, /* 604 't' */ + {0x82400000, 10, 74}, /* 605 'J' */ + {0x82c00000, 10, 57}, /* 606 '9' */ + {0x82000000, 11, 118}, /* 607 'v' */ + {0x82200000, 11, 112}, /* 608 'p' */ + {0x82800000, 11, 104}, /* 609 'h' */ + {0x9ba00000, 11, 111}, /* 610 'o' */ + {0x9bc00000, 11, 81}, /* 611 'Q' */ + {0x9be00000, 11, 48}, /* 612 '0' */ + {0x82a00000, 12, 108}, /* 613 'l' */ + {0x82b00000, 12, 105}, /* 614 'i' */ + {0x9b800000, 12, 86}, /* 615 'V' */ + {0x9b980000, 13, 121}, /* 616 'y' */ + {0x9b900000, 14, 1}, /* 617 '0x01' */ + {0x9b940000, 14, 103}, /* 618 'g' */ + /* 35 */ + {0x00000000, 1, 48}, /* 619 '0' */ + {0xe0000000, 3, 32}, /* 620 ' ' */ + {0x90000000, 4, 97}, /* 621 'a' */ + {0xb0000000, 4, 112}, /* 622 'p' */ + {0x88000000, 5, 115}, /* 623 's' */ + {0xc0000000, 5, 46}, /* 624 '.' */ + {0xc8000000, 5, 56}, /* 625 '8' */ + {0xd8000000, 5, 44}, /* 626 ',' */ + {0x80000000, 6, 52}, /* 627 '4' */ + {0x84000000, 6, 116}, /* 628 't' */ + {0xa4000000, 6, 53}, /* 629 '5' */ + {0xd0000000, 6, 54}, /* 630 '6' */ + {0xa0000000, 7, 51}, /* 631 '3' */ + {0xa2000000, 7, 55}, /* 632 '7' */ + {0xaa000000, 7, 93}, /* 633 ']' */ + {0xac000000, 7, 45}, /* 634 '-' */ + {0xae000000, 7, 49}, /* 635 '1' */ + {0xa8000000, 8, 41}, /* 636 ')' */ + {0xa9000000, 8, 47}, /* 637 '/' */ + {0xd4000000, 8, 0}, /* 638 '0x00' */ + {0xd5000000, 8, 57}, /* 639 '9' */ + {0xd7000000, 8, 50}, /* 640 '2' */ + {0xd6000000, 9, 37}, /* 641 '%' */ + {0xd6800000, 10, 58}, /* 642 ':' */ + {0xd6d00000, 12, 102}, /* 643 'f' */ + {0xd6f00000, 12, 109}, /* 644 'm' */ + {0xd6e00000, 13, 121}, /* 645 'y' */ + {0xd6c40000, 14, 108}, /* 646 'l' */ + {0xd6c80000, 14, 59}, /* 647 ';' */ + {0xd6cc0000, 14, 39}, /* 648 '\'' */ + {0xd6e80000, 14, 107}, /* 649 'k' */ + {0xd6ec0000, 14, 33}, /* 650 '!' */ + {0xd6c00000, 15, 67}, /* 651 'C' */ + {0xd6c20000, 16, 1}, /* 652 '0x01' */ + {0xd6c30000, 16, 74}, /* 653 'J' */ + /* 38 */ + {0x00000000, 2, 57}, /* 654 '9' */ + {0x80000000, 3, 49}, /* 655 '1' */ + {0xe0000000, 3, 48}, /* 656 '0' */ + {0x50000000, 4, 32}, /* 657 ' ' */ + {0x70000000, 4, 50}, /* 658 '2' */ + {0xb0000000, 4, 46}, /* 659 '.' */ + {0xc0000000, 4, 53}, /* 660 '5' */ + {0x40000000, 5, 54}, /* 661 '6' */ + {0x48000000, 5, 56}, /* 662 '8' */ + {0x68000000, 5, 47}, /* 663 '/' */ + {0xa0000000, 5, 93}, /* 664 ']' */ + {0xd0000000, 5, 51}, /* 665 '3' */ + {0x64000000, 6, 55}, /* 666 '7' */ + {0xd8000000, 6, 52}, /* 667 '4' */ + {0x60000000, 7, 0}, /* 668 '0x00' */ + {0x62000000, 7, 45}, /* 669 '-' */ + {0xa8000000, 7, 41}, /* 670 ')' */ + {0xac000000, 7, 58}, /* 671 ':' */ + {0xae000000, 7, 115}, /* 672 's' */ + {0xdc000000, 7, 44}, /* 673 ',' */ + {0xde000000, 7, 120}, /* 674 'x' */ + {0xaa000000, 8, 39}, /* 675 '\'' */ + {0xab000000, 9, 88}, /* 676 'X' */ + {0xabc00000, 11, 116}, /* 677 't' */ + {0xabe00000, 11, 82}, /* 678 'R' */ + {0xabb00000, 12, 59}, /* 679 ';' */ + {0xab800000, 13, 112}, /* 680 'p' */ + {0xab880000, 13, 109}, /* 681 'm' */ + {0xab900000, 13, 33}, /* 682 '!' */ + {0xaba80000, 13, 38}, /* 683 '&' */ + {0xab980000, 14, 101}, /* 684 'e' */ + {0xab9c0000, 15, 98}, /* 685 'b' */ + {0xab9e0000, 15, 97}, /* 686 'a' */ + {0xaba00000, 15, 68}, /* 687 'D' */ + {0xaba20000, 15, 67}, /* 688 'C' */ + {0xaba40000, 15, 37}, /* 689 '%' */ + {0xaba60000, 16, 1}, /* 690 '0x01' */ + {0xaba70000, 16, 111}, /* 691 'o' */ + /* 32 */ + {0xc0000000, 2, 48}, /* 692 '0' */ + {0x00000000, 3, 32}, /* 693 ' ' */ + {0x40000000, 3, 46}, /* 694 '.' */ + {0x80000000, 3, 53}, /* 695 '5' */ + {0x30000000, 4, 47}, /* 696 '/' */ + {0xb0000000, 4, 44}, /* 697 ',' */ + {0x20000000, 5, 93}, /* 698 ']' */ + {0x28000000, 5, 112}, /* 699 'p' */ + {0x68000000, 5, 49}, /* 700 '1' */ + {0xa8000000, 5, 52}, /* 701 '4' */ + {0x60000000, 6, 54}, /* 702 '6' */ + {0x64000000, 6, 50}, /* 703 '2' */ + {0x70000000, 6, 58}, /* 704 ':' */ + {0x74000000, 6, 45}, /* 705 '-' */ + {0x7c000000, 6, 41}, /* 706 ')' */ + {0xa0000000, 7, 0}, /* 707 '0x00' */ + {0xa4000000, 7, 56}, /* 708 '8' */ + {0xa6000000, 7, 57}, /* 709 '9' */ + {0x78000000, 8, 68}, /* 710 'D' */ + {0x79000000, 8, 51}, /* 711 '3' */ + {0x7a000000, 8, 116}, /* 712 't' */ + {0x7b000000, 8, 55}, /* 713 '7' */ + {0xa2000000, 8, 110}, /* 714 'n' */ + {0xa3000000, 9, 97}, /* 715 'a' */ + {0xa3800000, 10, 39}, /* 716 '\'' */ + {0xa3e00000, 11, 59}, /* 717 ';' */ + {0xa3c00000, 12, 115}, /* 718 's' */ + {0xa3d00000, 13, 34}, /* 719 '\"' */ + {0xa3d80000, 15, 1}, /* 720 '0x01' */ + {0xa3da0000, 15, 105}, /* 721 'i' */ + {0xa3dc0000, 15, 87}, /* 722 'W' */ + {0xa3de0000, 15, 76}, /* 723 'L' */ + /* 36 */ + {0x00000000, 2, 32}, /* 724 ' ' */ + {0x80000000, 2, 48}, /* 725 '0' */ + {0xc0000000, 3, 46}, /* 726 '.' */ + {0xe0000000, 4, 47}, /* 727 '/' */ + {0x40000000, 5, 50}, /* 728 '2' */ + {0x48000000, 5, 49}, /* 729 '1' */ + {0x50000000, 5, 41}, /* 730 ')' */ + {0x60000000, 5, 58}, /* 731 ':' */ + {0x70000000, 5, 45}, /* 732 '-' */ + {0xf8000000, 5, 93}, /* 733 ']' */ + {0x58000000, 6, 68}, /* 734 'D' */ + {0x68000000, 6, 52}, /* 735 '4' */ + {0x6c000000, 6, 0}, /* 736 '0x00' */ + {0x7c000000, 6, 53}, /* 737 '5' */ + {0xf0000000, 6, 44}, /* 738 ',' */ + {0x5c000000, 7, 55}, /* 739 '7' */ + {0x5e000000, 7, 51}, /* 740 '3' */ + {0x7a000000, 7, 54}, /* 741 '6' */ + {0xf6000000, 7, 116}, /* 742 't' */ + {0x79000000, 8, 66}, /* 743 'B' */ + {0xf4000000, 8, 56}, /* 744 '8' */ + {0xf5000000, 9, 57}, /* 745 '9' */ + {0x78400000, 10, 59}, /* 746 ';' */ + {0xf5800000, 10, 114}, /* 747 'r' */ + {0xf5c00000, 10, 115}, /* 748 's' */ + {0x78000000, 11, 110}, /* 749 'n' */ + {0x78a00000, 11, 98}, /* 750 'b' */ + {0x78c00000, 11, 39}, /* 751 '\'' */ + {0x78e00000, 11, 65}, /* 752 'A' */ + {0x78200000, 12, 112}, /* 753 'p' */ + {0x78300000, 12, 101}, /* 754 'e' */ + {0x78800000, 13, 97}, /* 755 'a' */ + {0x78880000, 13, 38}, /* 756 '&' */ + {0x78900000, 13, 37}, /* 757 '%' */ + {0x78980000, 14, 1}, /* 758 '0x01' */ + {0x789c0000, 14, 107}, /* 759 'k' */ + /* 35 */ + {0x40000000, 2, 32}, /* 760 ' ' */ + {0x00000000, 3, 52}, /* 761 '4' */ + {0x80000000, 3, 46}, /* 762 '.' */ + {0xc0000000, 3, 48}, /* 763 '0' */ + {0x20000000, 4, 47}, /* 764 '/' */ + {0xa0000000, 4, 53}, /* 765 '5' */ + {0xb0000000, 4, 45}, /* 766 '-' */ + {0x30000000, 5, 49}, /* 767 '1' */ + {0xe8000000, 5, 93}, /* 768 ']' */ + {0xf0000000, 5, 44}, /* 769 ',' */ + {0x38000000, 6, 50}, /* 770 '2' */ + {0xe4000000, 6, 56}, /* 771 '8' */ + {0xf8000000, 6, 41}, /* 772 ')' */ + {0x3c000000, 7, 58}, /* 773 ':' */ + {0x3e000000, 7, 39}, /* 774 '\'' */ + {0xe0000000, 7, 116}, /* 775 't' */ + {0xe2000000, 7, 51}, /* 776 '3' */ + {0xfe000000, 7, 0}, /* 777 '0x00' */ + {0xfd000000, 8, 54}, /* 778 '6' */ + {0xfc000000, 10, 57}, /* 779 '9' */ + {0xfc800000, 10, 55}, /* 780 '7' */ + {0xfc600000, 11, 67}, /* 781 'C' */ + {0xfcc00000, 11, 59}, /* 782 ';' */ + {0xfc500000, 12, 120}, /* 783 'x' */ + {0xfce80000, 13, 109}, /* 784 'm' */ + {0xfcf00000, 13, 73}, /* 785 'I' */ + {0xfc400000, 14, 102}, /* 786 'f' */ + {0xfc440000, 14, 101}, /* 787 'e' */ + {0xfc480000, 14, 98}, /* 788 'b' */ + {0xfc4c0000, 14, 76}, /* 789 'L' */ + {0xfce00000, 14, 37}, /* 790 '%' */ + {0xfcf80000, 14, 112}, /* 791 'p' */ + {0xfcfc0000, 14, 99}, /* 792 'c' */ + {0xfce40000, 15, 1}, /* 793 '0x01' */ + {0xfce60000, 15, 105}, /* 794 'i' */ + /* 32 */ + {0x00000000, 2, 48}, /* 795 '0' */ + {0x80000000, 2, 32}, /* 796 ' ' */ + {0x40000000, 3, 46}, /* 797 '.' */ + {0x70000000, 4, 112}, /* 798 'p' */ + {0xc0000000, 4, 53}, /* 799 '5' */ + {0x60000000, 5, 47}, /* 800 '/' */ + {0xd0000000, 5, 97}, /* 801 'a' */ + {0xd8000000, 5, 45}, /* 802 '-' */ + {0xe8000000, 5, 54}, /* 803 '6' */ + {0x68000000, 6, 51}, /* 804 '3' */ + {0xf0000000, 6, 50}, /* 805 '2' */ + {0xf8000000, 6, 56}, /* 806 '8' */ + {0xfc000000, 6, 93}, /* 807 ']' */ + {0x6c000000, 7, 58}, /* 808 ':' */ + {0xe0000000, 7, 41}, /* 809 ')' */ + {0xe2000000, 7, 115}, /* 810 's' */ + {0xe6000000, 7, 44}, /* 811 ',' */ + {0xf4000000, 7, 55}, /* 812 '7' */ + {0xf6000000, 7, 57}, /* 813 '9' */ + {0x6e000000, 8, 52}, /* 814 '4' */ + {0xe4000000, 8, 0}, /* 815 '0x00' */ + {0xe5000000, 8, 116}, /* 816 't' */ + {0x6f800000, 10, 99}, /* 817 'c' */ + {0x6fc00000, 10, 49}, /* 818 '1' */ + {0x6f200000, 11, 59}, /* 819 ';' */ + {0x6f600000, 11, 109}, /* 820 'm' */ + {0x6f000000, 12, 101}, /* 821 'e' */ + {0x6f100000, 12, 39}, /* 822 '\'' */ + {0x6f500000, 12, 107}, /* 823 'k' */ + {0x6f480000, 13, 108}, /* 824 'l' */ + {0x6f400000, 14, 1}, /* 825 '0x01' */ + {0x6f440000, 14, 102}, /* 826 'f' */ + /* 33 */ + {0x00000000, 2, 32}, /* 827 ' ' */ + {0x80000000, 2, 46}, /* 828 '.' */ + {0xe0000000, 3, 48}, /* 829 '0' */ + {0x50000000, 4, 93}, /* 830 ']' */ + {0x48000000, 5, 49}, /* 831 '1' */ + {0x60000000, 5, 55}, /* 832 '7' */ + {0x70000000, 5, 41}, /* 833 ')' */ + {0xc0000000, 5, 44}, /* 834 ',' */ + {0xc8000000, 5, 58}, /* 835 ':' */ + {0xd0000000, 5, 47}, /* 836 '/' */ + {0x44000000, 6, 45}, /* 837 '-' */ + {0x68000000, 6, 53}, /* 838 '5' */ + {0x6c000000, 6, 52}, /* 839 '4' */ + {0x7c000000, 6, 56}, /* 840 '8' */ + {0xdc000000, 6, 116}, /* 841 't' */ + {0x40000000, 7, 54}, /* 842 '6' */ + {0x78000000, 7, 51}, /* 843 '3' */ + {0x7a000000, 7, 50}, /* 844 '2' */ + {0xda000000, 7, 57}, /* 845 '9' */ + {0x42000000, 8, 0}, /* 846 '0x00' */ + {0x43000000, 8, 43}, /* 847 '+' */ + {0xd8000000, 8, 39}, /* 848 '\'' */ + {0xd9400000, 10, 97}, /* 849 'a' */ + {0xd9800000, 10, 63}, /* 850 '?' */ + {0xd9000000, 11, 109}, /* 851 'm' */ + {0xd9200000, 11, 101}, /* 852 'e' */ + {0xd9c00000, 11, 59}, /* 853 ';' */ + {0xd9e00000, 13, 102}, /* 854 'f' */ + {0xd9e80000, 13, 98}, /* 855 'b' */ + {0xd9f00000, 13, 77}, /* 856 'M' */ + {0xd9f80000, 14, 34}, /* 857 '\"' */ + {0xd9fc0000, 15, 1}, /* 858 '0x01' */ + {0xd9fe0000, 15, 105}, /* 859 'i' */ + /* 31 */ + {0xc0000000, 2, 46}, /* 860 '.' */ + {0x20000000, 3, 32}, /* 861 ' ' */ + {0x60000000, 3, 48}, /* 862 '0' */ + {0xa0000000, 3, 45}, /* 863 '-' */ + {0x00000000, 4, 56}, /* 864 '8' */ + {0x40000000, 4, 55}, /* 865 '7' */ + {0x90000000, 4, 93}, /* 866 ']' */ + {0x50000000, 5, 47}, /* 867 '/' */ + {0x14000000, 6, 54}, /* 868 '6' */ + {0x18000000, 6, 50}, /* 869 '2' */ + {0x1c000000, 6, 49}, /* 870 '1' */ + {0x5c000000, 6, 116}, /* 871 't' */ + {0x80000000, 6, 57}, /* 872 '9' */ + {0x88000000, 6, 41}, /* 873 ')' */ + {0x8c000000, 6, 53}, /* 874 '5' */ + {0x12000000, 7, 51}, /* 875 '3' */ + {0x5a000000, 7, 44}, /* 876 ',' */ + {0x84000000, 7, 97}, /* 877 'a' */ + {0x86000000, 7, 52}, /* 878 '4' */ + {0x10000000, 8, 0}, /* 879 '0x00' */ + {0x58000000, 8, 58}, /* 880 ':' */ + {0x59000000, 8, 112}, /* 881 'p' */ + {0x11400000, 10, 82}, /* 882 'R' */ + {0x11800000, 10, 59}, /* 883 ';' */ + {0x11000000, 11, 39}, /* 884 '\'' */ + {0x11e00000, 11, 109}, /* 885 'm' */ + {0x11300000, 12, 102}, /* 886 'f' */ + {0x11c00000, 12, 65}, /* 887 'A' */ + {0x11d00000, 12, 63}, /* 888 '?' */ + {0x11200000, 13, 1}, /* 889 '0x01' */ + {0x11280000, 13, 115}, /* 890 's' */ + /* 31 */ + {0x40000000, 2, 32}, /* 891 ' ' */ + {0x00000000, 3, 52}, /* 892 '4' */ + {0xc0000000, 3, 46}, /* 893 '.' */ + {0x30000000, 4, 48}, /* 894 '0' */ + {0x80000000, 4, 57}, /* 895 '9' */ + {0x90000000, 4, 55}, /* 896 '7' */ + {0xb0000000, 4, 56}, /* 897 '8' */ + {0xe0000000, 4, 49}, /* 898 '1' */ + {0x20000000, 5, 47}, /* 899 '/' */ + {0xa0000000, 5, 51}, /* 900 '3' */ + {0xf0000000, 5, 53}, /* 901 '5' */ + {0xa8000000, 6, 41}, /* 902 ')' */ + {0xf8000000, 6, 54}, /* 903 '6' */ + {0xfc000000, 6, 93}, /* 904 ']' */ + {0x28000000, 7, 58}, /* 905 ':' */ + {0x2a000000, 7, 44}, /* 906 ',' */ + {0xae000000, 7, 116}, /* 907 't' */ + {0x2c000000, 8, 112}, /* 908 'p' */ + {0x2d000000, 8, 45}, /* 909 '-' */ + {0x2f000000, 8, 97}, /* 910 'a' */ + {0xac000000, 8, 99}, /* 911 'c' */ + {0xad000000, 8, 50}, /* 912 '2' */ + {0x2e800000, 9, 0}, /* 913 '0x00' */ + {0x2e400000, 10, 59}, /* 914 ';' */ + {0x2e000000, 12, 108}, /* 915 'l' */ + {0x2e100000, 12, 39}, /* 916 '\'' */ + {0x2e200000, 13, 102}, /* 917 'f' */ + {0x2e280000, 13, 68}, /* 918 'D' */ + {0x2e300000, 13, 65}, /* 919 'A' */ + {0x2e380000, 14, 1}, /* 920 '0x01' */ + {0x2e3c0000, 14, 105}, /* 921 'i' */ + /* 28 */ + {0x00000000, 3, 53}, /* 922 '5' */ + {0x20000000, 3, 93}, /* 923 ']' */ + {0xe0000000, 3, 57}, /* 924 '9' */ + {0x50000000, 4, 48}, /* 925 '0' */ + {0x60000000, 4, 46}, /* 926 '.' */ + {0x70000000, 4, 45}, /* 927 '-' */ + {0x80000000, 4, 52}, /* 928 '4' */ + {0x90000000, 4, 56}, /* 929 '8' */ + {0xb0000000, 4, 54}, /* 930 '6' */ + {0xc0000000, 4, 32}, /* 931 ' ' */ + {0xd0000000, 4, 55}, /* 932 '7' */ + {0x40000000, 5, 50}, /* 933 '2' */ + {0xa0000000, 5, 51}, /* 934 '3' */ + {0x48000000, 6, 49}, /* 935 '1' */ + {0x4c000000, 6, 47}, /* 936 '/' */ + {0xa8000000, 6, 116}, /* 937 't' */ + {0xae000000, 7, 41}, /* 938 ')' */ + {0xac000000, 8, 58}, /* 939 ':' */ + {0xad000000, 9, 44}, /* 940 ',' */ + {0xad800000, 11, 112}, /* 941 'p' */ + {0xada00000, 11, 59}, /* 942 ';' */ + {0xade00000, 11, 0}, /* 943 '0x00' */ + {0xadc00000, 13, 110}, /* 944 'n' */ + {0xadc80000, 13, 109}, /* 945 'm' */ + {0xadd00000, 13, 97}, /* 946 'a' */ + {0xaddc0000, 14, 101}, /* 947 'e' */ + {0xadd80000, 15, 1}, /* 948 '0x01' */ + {0xadda0000, 15, 107}, /* 949 'k' */ + /* 9 */ + {0x80000000, 1, 32}, /* 950 ' ' */ + {0x40000000, 2, 48}, /* 951 '0' */ + {0x20000000, 3, 51}, /* 952 '3' */ + {0x08000000, 5, 49}, /* 953 '1' */ + {0x10000000, 5, 84}, /* 954 'T' */ + {0x18000000, 5, 67}, /* 955 'C' */ + {0x04000000, 6, 52}, /* 956 '4' */ + {0x00000000, 7, 1}, /* 957 '0x01' */ + {0x02000000, 7, 53}, /* 958 '5' */ + /* 2 */ + {0x00000000, 1, 1}, /* 959 '0x01' */ + {0x80000000, 1, 32}, /* 960 ' ' */ + /* 2 */ + {0x00000000, 1, 1}, /* 961 '0x01' */ + {0x80000000, 1, 1}, /* 962 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 963 '0x01' */ + {0x80000000, 1, 1}, /* 964 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 965 '0x01' */ + {0x80000000, 1, 1}, /* 966 '0x01' */ + /* 12 */ + {0x80000000, 1, 32}, /* 967 ' ' */ + {0x40000000, 2, 0}, /* 968 '0x00' */ + {0x00000000, 3, 58}, /* 969 ':' */ + {0x20000000, 5, 33}, /* 970 '!' */ + {0x30000000, 5, 91}, /* 971 '[' */ + {0x38000000, 5, 46}, /* 972 '.' */ + {0x28000000, 6, 59}, /* 973 ';' */ + {0x2c000000, 7, 39}, /* 974 '\'' */ + {0x2f000000, 8, 44}, /* 975 ',' */ + {0x2e800000, 9, 47}, /* 976 '/' */ + {0x2e000000, 10, 1}, /* 977 '0x01' */ + {0x2e400000, 10, 81}, /* 978 'Q' */ + /* 6 */ + {0x00000000, 1, 107}, /* 979 'k' */ + {0x80000000, 2, 32}, /* 980 ' ' */ + {0xe0000000, 3, 84}, /* 981 'T' */ + {0xd0000000, 4, 98}, /* 982 'b' */ + {0xc0000000, 5, 1}, /* 983 '0x01' */ + {0xc8000000, 5, 72}, /* 984 'H' */ + /* 58 */ + {0x40000000, 2, 32}, /* 985 ' ' */ + {0xc0000000, 3, 68}, /* 986 'D' */ + {0xe0000000, 3, 110}, /* 987 'n' */ + {0x00000000, 4, 115}, /* 988 's' */ + {0x10000000, 4, 109}, /* 989 'm' */ + {0x20000000, 4, 100}, /* 990 'd' */ + {0x80000000, 4, 114}, /* 991 'r' */ + {0xb0000000, 4, 108}, /* 992 'l' */ + {0x30000000, 5, 99}, /* 993 'c' */ + {0x90000000, 5, 117}, /* 994 'u' */ + {0xa0000000, 5, 103}, /* 995 'g' */ + {0x3c000000, 6, 98}, /* 996 'b' */ + {0x9c000000, 6, 116}, /* 997 't' */ + {0xac000000, 6, 102}, /* 998 'f' */ + {0xa8000000, 7, 119}, /* 999 'w' */ + {0xaa000000, 7, 105}, /* 1000 'i' */ + {0x99000000, 8, 118}, /* 1001 'v' */ + {0x9b000000, 8, 112}, /* 1002 'p' */ + {0x39000000, 9, 104}, /* 1003 'h' */ + {0x3a000000, 9, 46}, /* 1004 '.' */ + {0x3b800000, 9, 66}, /* 1005 'B' */ + {0x9a000000, 9, 113}, /* 1006 'q' */ + {0x38000000, 10, 67}, /* 1007 'C' */ + {0x38800000, 10, 44}, /* 1008 ',' */ + {0x39800000, 10, 121}, /* 1009 'y' */ + {0x3a800000, 10, 83}, /* 1010 'S' */ + {0x3b000000, 10, 107}, /* 1011 'k' */ + {0x3b400000, 10, 84}, /* 1012 'T' */ + {0x98400000, 10, 82}, /* 1013 'R' */ + {0x98800000, 10, 70}, /* 1014 'F' */ + {0x98c00000, 10, 122}, /* 1015 'z' */ + {0x9ac00000, 10, 97}, /* 1016 'a' */ + {0x38400000, 11, 80}, /* 1017 'P' */ + {0x38c00000, 11, 45}, /* 1018 '-' */ + {0x3ac00000, 11, 65}, /* 1019 'A' */ + {0x3ae00000, 11, 73}, /* 1020 'I' */ + {0x98200000, 11, 101}, /* 1021 'e' */ + {0x9a800000, 11, 78}, /* 1022 'N' */ + {0x9aa00000, 11, 120}, /* 1023 'x' */ + {0x38600000, 12, 88}, /* 1024 'X' */ + {0x38700000, 12, 75}, /* 1025 'K' */ + {0x38e00000, 12, 51}, /* 1026 '3' */ + {0x38f00000, 12, 38}, /* 1027 '&' */ + {0x39d00000, 12, 77}, /* 1028 'M' */ + {0x39f00000, 12, 89}, /* 1029 'Y' */ + {0x39c00000, 13, 76}, /* 1030 'L' */ + {0x39c80000, 13, 87}, /* 1031 'W' */ + {0x39e00000, 13, 42}, /* 1032 '*' */ + {0x98000000, 13, 111}, /* 1033 'o' */ + {0x98080000, 13, 49}, /* 1034 '1' */ + {0x98100000, 13, 39}, /* 1035 '\'' */ + {0x98180000, 13, 58}, /* 1036 ':' */ + {0x39e80000, 14, 106}, /* 1037 'j' */ + {0x39ec0000, 15, 71}, /* 1038 'G' */ + {0x39ee0000, 16, 79}, /* 1039 'O' */ + {0x39ef0000, 17, 52}, /* 1040 '4' */ + {0x39ef8000, 18, 1}, /* 1041 '0x01' */ + {0x39efc000, 18, 69}, /* 1042 'E' */ + /* 40 */ + {0x00000000, 2, 67}, /* 1043 'C' */ + {0x40000000, 3, 97}, /* 1044 'a' */ + {0xa0000000, 3, 114}, /* 1045 'r' */ + {0xc0000000, 3, 101}, /* 1046 'e' */ + {0xe0000000, 3, 66}, /* 1047 'B' */ + {0x70000000, 4, 105}, /* 1048 'i' */ + {0x80000000, 4, 117}, /* 1049 'u' */ + {0x90000000, 4, 111}, /* 1050 'o' */ + {0x68000000, 5, 108}, /* 1051 'l' */ + {0x60000000, 8, 84}, /* 1052 'T' */ + {0x61000000, 8, 46}, /* 1053 '.' */ + {0x63000000, 8, 121}, /* 1054 'y' */ + {0x64000000, 8, 73}, /* 1055 'I' */ + {0x66000000, 8, 104}, /* 1056 'h' */ + {0x67000000, 8, 32}, /* 1057 ' ' */ + {0x62000000, 9, 65}, /* 1058 'A' */ + {0x62800000, 10, 79}, /* 1059 'O' */ + {0x62c00000, 11, 58}, /* 1060 ':' */ + {0x65000000, 11, 38}, /* 1061 '&' */ + {0x65200000, 11, 51}, /* 1062 '3' */ + {0x65400000, 11, 106}, /* 1063 'j' */ + {0x65600000, 11, 77}, /* 1064 'M' */ + {0x65c00000, 11, 68}, /* 1065 'D' */ + {0x62f00000, 12, 87}, /* 1066 'W' */ + {0x65800000, 12, 42}, /* 1067 '*' */ + {0x65a00000, 12, 44}, /* 1068 ',' */ + {0x65b00000, 12, 49}, /* 1069 '1' */ + {0x65e00000, 12, 1}, /* 1070 '0x01' */ + {0x65f00000, 12, 80}, /* 1071 'P' */ + {0x62e00000, 13, 69}, /* 1072 'E' */ + {0x65980000, 13, 82}, /* 1073 'R' */ + {0x62ec0000, 14, 119}, /* 1074 'w' */ + {0x62e80000, 15, 45}, /* 1075 '-' */ + {0x65920000, 15, 85}, /* 1076 'U' */ + {0x65940000, 15, 83}, /* 1077 'S' */ + {0x65960000, 15, 70}, /* 1078 'F' */ + {0x62ea0000, 16, 88}, /* 1079 'X' */ + {0x62eb0000, 16, 86}, /* 1080 'V' */ + {0x65900000, 16, 81}, /* 1081 'Q' */ + {0x65910000, 16, 52}, /* 1082 '4' */ + /* 47 */ + {0x00000000, 2, 104}, /* 1083 'h' */ + {0x60000000, 3, 66}, /* 1084 'B' */ + {0x80000000, 3, 97}, /* 1085 'a' */ + {0xc0000000, 3, 111}, /* 1086 'o' */ + {0x50000000, 4, 114}, /* 1087 'r' */ + {0xa0000000, 4, 46}, /* 1088 '.' */ + {0xe0000000, 4, 32}, /* 1089 ' ' */ + {0xf0000000, 4, 108}, /* 1090 'l' */ + {0x40000000, 5, 39}, /* 1091 '\'' */ + {0xb8000000, 5, 105}, /* 1092 'i' */ + {0x4c000000, 6, 101}, /* 1093 'e' */ + {0xb4000000, 6, 117}, /* 1094 'u' */ + {0x4a000000, 7, 121}, /* 1095 'y' */ + {0xb2000000, 7, 44}, /* 1096 ',' */ + {0x49000000, 8, 73}, /* 1097 'I' */ + {0x48000000, 9, 65}, /* 1098 'A' */ + {0xb0000000, 10, 67}, /* 1099 'C' */ + {0xb0400000, 10, 68}, /* 1100 'D' */ + {0xb0c00000, 10, 0}, /* 1101 '0x00' */ + {0xb1000000, 10, 83}, /* 1102 'S' */ + {0xb1400000, 10, 84}, /* 1103 'T' */ + {0xb1c00000, 10, 71}, /* 1104 'G' */ + {0x48800000, 11, 42}, /* 1105 '*' */ + {0x48e00000, 11, 119}, /* 1106 'w' */ + {0xb1a00000, 11, 74}, /* 1107 'J' */ + {0x48a00000, 12, 82}, /* 1108 'R' */ + {0x48c00000, 12, 50}, /* 1109 '2' */ + {0x48d00000, 12, 85}, /* 1110 'U' */ + {0xb0800000, 12, 63}, /* 1111 '?' */ + {0xb0a00000, 12, 79}, /* 1112 'O' */ + {0xb0b00000, 12, 72}, /* 1113 'H' */ + {0xb1800000, 12, 69}, /* 1114 'E' */ + {0x48b00000, 13, 122}, /* 1115 'z' */ + {0xb0980000, 13, 45}, /* 1116 '-' */ + {0xb1980000, 13, 115}, /* 1117 's' */ + {0x48bc0000, 14, 49}, /* 1118 '1' */ + {0xb0940000, 14, 33}, /* 1119 '!' */ + {0xb1900000, 14, 80}, /* 1120 'P' */ + {0x48ba0000, 15, 110}, /* 1121 'n' */ + {0xb0900000, 15, 75}, /* 1122 'K' */ + {0xb0920000, 15, 55}, /* 1123 '7' */ + {0xb1960000, 15, 52}, /* 1124 '4' */ + {0x48b80000, 16, 58}, /* 1125 ':' */ + {0xb1940000, 16, 70}, /* 1126 'F' */ + {0xb1950000, 16, 41}, /* 1127 ')' */ + {0x48b90000, 17, 1}, /* 1128 '0x01' */ + {0x48b98000, 17, 98}, /* 1129 'b' */ + /* 47 */ + {0x00000000, 2, 97}, /* 1130 'a' */ + {0x40000000, 2, 44}, /* 1131 ',' */ + {0x80000000, 3, 114}, /* 1132 'r' */ + {0xa0000000, 3, 111}, /* 1133 'o' */ + {0xc0000000, 3, 101}, /* 1134 'e' */ + {0xe0000000, 4, 105}, /* 1135 'i' */ + {0xfc000000, 6, 117}, /* 1136 'u' */ + {0xf2000000, 7, 32}, /* 1137 ' ' */ + {0xf6000000, 7, 39}, /* 1138 '\'' */ + {0xf0000000, 8, 46}, /* 1139 '.' */ + {0xf1000000, 8, 93}, /* 1140 ']' */ + {0xfa000000, 8, 121}, /* 1141 'y' */ + {0xf5000000, 9, 119}, /* 1142 'w' */ + {0xf5800000, 9, 87}, /* 1143 'W' */ + {0xf8800000, 9, 78}, /* 1144 'N' */ + {0xf9000000, 9, 67}, /* 1145 'C' */ + {0xfb800000, 9, 74}, /* 1146 'J' */ + {0xf4800000, 10, 104}, /* 1147 'h' */ + {0xf8000000, 10, 116}, /* 1148 't' */ + {0xf9c00000, 10, 73}, /* 1149 'I' */ + {0xfb400000, 10, 58}, /* 1150 ':' */ + {0xf4200000, 11, 77}, /* 1151 'M' */ + {0xf4400000, 11, 38}, /* 1152 '&' */ + {0xf4600000, 11, 86}, /* 1153 'V' */ + {0xf8400000, 11, 45}, /* 1154 '-' */ + {0xf8600000, 11, 71}, /* 1155 'G' */ + {0xf9800000, 11, 79}, /* 1156 'O' */ + {0xf9a00000, 11, 65}, /* 1157 'A' */ + {0xfb200000, 11, 83}, /* 1158 'S' */ + {0xf4000000, 12, 70}, /* 1159 'F' */ + {0xf4c00000, 12, 42}, /* 1160 '*' */ + {0xf4d00000, 12, 115}, /* 1161 's' */ + {0xf4f00000, 12, 100}, /* 1162 'd' */ + {0xfb000000, 12, 118}, /* 1163 'v' */ + {0xf4e00000, 13, 109}, /* 1164 'm' */ + {0xf4e80000, 13, 106}, /* 1165 'j' */ + {0xfb100000, 13, 1}, /* 1166 '0x01' */ + {0xfb180000, 13, 84}, /* 1167 'T' */ + {0xf4180000, 14, 57}, /* 1168 '9' */ + {0xf4100000, 15, 41}, /* 1169 ')' */ + {0xf4160000, 15, 69}, /* 1170 'E' */ + {0xf41c0000, 15, 56}, /* 1171 '8' */ + {0xf41e0000, 15, 55}, /* 1172 '7' */ + {0xf4120000, 16, 85}, /* 1173 'U' */ + {0xf4130000, 16, 82}, /* 1174 'R' */ + {0xf4140000, 16, 66}, /* 1175 'B' */ + {0xf4150000, 16, 52}, /* 1176 '4' */ + /* 54 */ + {0x00000000, 3, 112}, /* 1177 'p' */ + {0x40000000, 3, 97}, /* 1178 'a' */ + {0x60000000, 3, 110}, /* 1179 'n' */ + {0xc0000000, 3, 108}, /* 1180 'l' */ + {0x90000000, 4, 109}, /* 1181 'm' */ + {0xa0000000, 4, 120}, /* 1182 'x' */ + {0xe0000000, 4, 118}, /* 1183 'v' */ + {0xf0000000, 4, 100}, /* 1184 'd' */ + {0x20000000, 5, 115}, /* 1185 's' */ + {0x30000000, 5, 114}, /* 1186 'r' */ + {0x38000000, 5, 117}, /* 1187 'u' */ + {0x80000000, 5, 69}, /* 1188 'E' */ + {0x88000000, 5, 32}, /* 1189 ' ' */ + {0x28000000, 6, 46}, /* 1190 '.' */ + {0x2c000000, 6, 105}, /* 1191 'i' */ + {0xb4000000, 6, 58}, /* 1192 ':' */ + {0xb0000000, 7, 121}, /* 1193 'y' */ + {0xb2000000, 7, 116}, /* 1194 't' */ + {0xb8000000, 7, 103}, /* 1195 'g' */ + {0xbc000000, 7, 52}, /* 1196 '4' */ + {0xbb000000, 9, 119}, /* 1197 'w' */ + {0xbe000000, 9, 99}, /* 1198 'c' */ + {0xbf000000, 9, 98}, /* 1199 'b' */ + {0xba800000, 10, 82}, /* 1200 'R' */ + {0xbac00000, 10, 70}, /* 1201 'F' */ + {0xbbc00000, 10, 67}, /* 1202 'C' */ + {0xba200000, 11, 107}, /* 1203 'k' */ + {0xba400000, 11, 102}, /* 1204 'f' */ + {0xba600000, 11, 111}, /* 1205 'o' */ + {0xbb800000, 11, 85}, /* 1206 'U' */ + {0xbba00000, 11, 76}, /* 1207 'L' */ + {0xbea00000, 11, 101}, /* 1208 'e' */ + {0xbec00000, 11, 78}, /* 1209 'N' */ + {0xbf800000, 11, 104}, /* 1210 'h' */ + {0xbfa00000, 11, 73}, /* 1211 'I' */ + {0xbfe00000, 11, 68}, /* 1212 'D' */ + {0xbe800000, 12, 77}, /* 1213 'M' */ + {0xbef00000, 12, 39}, /* 1214 '\'' */ + {0xbfc00000, 12, 50}, /* 1215 '2' */ + {0xbfd00000, 12, 45}, /* 1216 '-' */ + {0xba180000, 13, 113}, /* 1217 'q' */ + {0xbe900000, 13, 79}, /* 1218 'O' */ + {0xbe980000, 13, 65}, /* 1219 'A' */ + {0xbee80000, 13, 90}, /* 1220 'Z' */ + {0xba000000, 14, 87}, /* 1221 'W' */ + {0xba040000, 14, 83}, /* 1222 'S' */ + {0xba080000, 14, 72}, /* 1223 'H' */ + {0xba0c0000, 14, 57}, /* 1224 '9' */ + {0xba100000, 14, 41}, /* 1225 ')' */ + {0xbee00000, 14, 84}, /* 1226 'T' */ + {0xbee40000, 14, 44}, /* 1227 ',' */ + {0xba140000, 15, 80}, /* 1228 'P' */ + {0xba160000, 16, 1}, /* 1229 '0x01' */ + {0xba170000, 16, 122}, /* 1230 'z' */ + /* 36 */ + {0x00000000, 2, 111}, /* 1231 'o' */ + {0x80000000, 2, 114}, /* 1232 'r' */ + {0x40000000, 3, 101}, /* 1233 'e' */ + {0xc0000000, 3, 105}, /* 1234 'i' */ + {0xe0000000, 3, 97}, /* 1235 'a' */ + {0x60000000, 4, 108}, /* 1236 'l' */ + {0x70000000, 5, 117}, /* 1237 'u' */ + {0x78000000, 7, 32}, /* 1238 ' ' */ + {0x7a000000, 7, 79}, /* 1239 'O' */ + {0x7d000000, 8, 65}, /* 1240 'A' */ + {0x7f000000, 8, 66}, /* 1241 'B' */ + {0x7e000000, 9, 102}, /* 1242 'f' */ + {0x7c000000, 10, 46}, /* 1243 '.' */ + {0x7cc00000, 10, 76}, /* 1244 'L' */ + {0x7c400000, 11, 77}, /* 1245 'M' */ + {0x7c600000, 11, 69}, /* 1246 'E' */ + {0x7ca00000, 11, 84}, /* 1247 'T' */ + {0x7ea00000, 11, 67}, /* 1248 'C' */ + {0x7ec00000, 11, 87}, /* 1249 'W' */ + {0x7c800000, 12, 58}, /* 1250 ':' */ + {0x7e800000, 12, 85}, /* 1251 'U' */ + {0x7e900000, 12, 39}, /* 1252 '\'' */ + {0x7ef00000, 12, 49}, /* 1253 '1' */ + {0x7c900000, 13, 121}, /* 1254 'y' */ + {0x7c980000, 13, 44}, /* 1255 ',' */ + {0x7ee00000, 14, 45}, /* 1256 '-' */ + {0x7ee80000, 14, 73}, /* 1257 'I' */ + {0x7ee60000, 15, 104}, /* 1258 'h' */ + {0x7ee40000, 16, 42}, /* 1259 '*' */ + {0x7ee50000, 16, 75}, /* 1260 'K' */ + {0x7eec0000, 16, 70}, /* 1261 'F' */ + {0x7eed0000, 16, 1}, /* 1262 '0x01' */ + {0x7eee0000, 17, 88}, /* 1263 'X' */ + {0x7eee8000, 17, 82}, /* 1264 'R' */ + {0x7eef0000, 17, 59}, /* 1265 ';' */ + {0x7eef8000, 17, 52}, /* 1266 '4' */ + /* 37 */ + {0x00000000, 2, 114}, /* 1267 'r' */ + {0x40000000, 2, 97}, /* 1268 'a' */ + {0xa0000000, 3, 111}, /* 1269 'o' */ + {0xc0000000, 3, 101}, /* 1270 'e' */ + {0x90000000, 4, 117}, /* 1271 'u' */ + {0xf0000000, 4, 105}, /* 1272 'i' */ + {0x88000000, 5, 110}, /* 1273 'n' */ + {0xe8000000, 5, 108}, /* 1274 'l' */ + {0x80000000, 6, 88}, /* 1275 'X' */ + {0xe0000000, 7, 121}, /* 1276 'y' */ + {0xe2000000, 7, 32}, /* 1277 ' ' */ + {0xe6000000, 7, 119}, /* 1278 'w' */ + {0x85000000, 8, 52}, /* 1279 '4' */ + {0x87000000, 8, 80}, /* 1280 'P' */ + {0xe5000000, 8, 104}, /* 1281 'h' */ + {0x84000000, 9, 45}, /* 1282 '-' */ + {0x86000000, 9, 67}, /* 1283 'C' */ + {0xe4800000, 9, 77}, /* 1284 'M' */ + {0x86800000, 10, 66}, /* 1285 'B' */ + {0xe4000000, 10, 46}, /* 1286 '.' */ + {0xe4400000, 10, 73}, /* 1287 'I' */ + {0x84800000, 11, 59}, /* 1288 ';' */ + {0x84a00000, 11, 44}, /* 1289 ',' */ + {0x84c00000, 11, 65}, /* 1290 'A' */ + {0x84e00000, 11, 78}, /* 1291 'N' */ + {0x86e00000, 11, 58}, /* 1292 ':' */ + {0x86c00000, 13, 79}, /* 1293 'O' */ + {0x86c80000, 13, 76}, /* 1294 'L' */ + {0x86d80000, 14, 98}, /* 1295 'b' */ + {0x86d00000, 15, 75}, /* 1296 'K' */ + {0x86d20000, 15, 50}, /* 1297 '2' */ + {0x86d40000, 15, 49}, /* 1298 '1' */ + {0x86d60000, 15, 39}, /* 1299 '\'' */ + {0x86dc0000, 16, 1}, /* 1300 '0x01' */ + {0x86dd0000, 16, 109}, /* 1301 'm' */ + {0x86de0000, 16, 84}, /* 1302 'T' */ + {0x86df0000, 16, 83}, /* 1303 'S' */ + /* 32 */ + {0x00000000, 2, 101}, /* 1304 'e' */ + {0x40000000, 2, 97}, /* 1305 'a' */ + {0x80000000, 2, 111}, /* 1306 'o' */ + {0xc0000000, 3, 105}, /* 1307 'i' */ + {0xf0000000, 4, 117}, /* 1308 'u' */ + {0xe0000000, 5, 82}, /* 1309 'R' */ + {0xe8000000, 7, 80}, /* 1310 'P' */ + {0xec000000, 7, 121}, /* 1311 'y' */ + {0xeb000000, 8, 73}, /* 1312 'I' */ + {0xee000000, 9, 81}, /* 1313 'Q' */ + {0xee800000, 9, 77}, /* 1314 'M' */ + {0xef000000, 9, 65}, /* 1315 'A' */ + {0xef800000, 9, 32}, /* 1316 ' ' */ + {0xea000000, 10, 83}, /* 1317 'S' */ + {0xea400000, 10, 46}, /* 1318 '.' */ + {0xeaa00000, 11, 71}, /* 1319 'G' */ + {0xeac00000, 11, 41}, /* 1320 ')' */ + {0xea900000, 12, 69}, /* 1321 'E' */ + {0xeae00000, 13, 79}, /* 1322 'O' */ + {0xeae80000, 13, 76}, /* 1323 'L' */ + {0xea800000, 14, 49}, /* 1324 '1' */ + {0xea840000, 14, 38}, /* 1325 '&' */ + {0xeaf00000, 14, 72}, /* 1326 'H' */ + {0xeaf40000, 14, 119}, /* 1327 'w' */ + {0xeaf80000, 14, 118}, /* 1328 'v' */ + {0xea880000, 15, 88}, /* 1329 'X' */ + {0xea8a0000, 15, 87}, /* 1330 'W' */ + {0xea8c0000, 15, 68}, /* 1331 'D' */ + {0xeafc0000, 15, 115}, /* 1332 's' */ + {0xeafe0000, 15, 70}, /* 1333 'F' */ + {0xea8e0000, 16, 1}, /* 1334 '0x01' */ + {0xea8f0000, 16, 114}, /* 1335 'r' */ + /* 52 */ + {0x00000000, 1, 110}, /* 1336 'n' */ + {0xc0000000, 3, 116}, /* 1337 't' */ + {0x90000000, 4, 115}, /* 1338 's' */ + {0xf0000000, 4, 114}, /* 1339 'r' */ + {0x80000000, 5, 84}, /* 1340 'T' */ + {0xa8000000, 5, 97}, /* 1341 'a' */ + {0xe0000000, 5, 32}, /* 1342 ' ' */ + {0x88000000, 6, 99}, /* 1343 'c' */ + {0xa4000000, 6, 109}, /* 1344 'm' */ + {0xb0000000, 6, 122}, /* 1345 'z' */ + {0xb4000000, 6, 46}, /* 1346 '.' */ + {0xbc000000, 6, 100}, /* 1347 'd' */ + {0xec000000, 6, 73}, /* 1348 'I' */ + {0x8e000000, 7, 39}, /* 1349 '\'' */ + {0xba000000, 7, 108}, /* 1350 'l' */ + {0xa0000000, 8, 65}, /* 1351 'A' */ + {0xa1000000, 8, 118}, /* 1352 'v' */ + {0xb9000000, 8, 86}, /* 1353 'V' */ + {0xe9000000, 8, 102}, /* 1354 'f' */ + {0xeb000000, 8, 111}, /* 1355 'o' */ + {0x8c800000, 9, 67}, /* 1356 'C' */ + {0x8d000000, 9, 80}, /* 1357 'P' */ + {0xa2000000, 9, 119}, /* 1358 'w' */ + {0xa3000000, 9, 58}, /* 1359 ':' */ + {0xb8000000, 9, 112}, /* 1360 'p' */ + {0xe8000000, 9, 82}, /* 1361 'R' */ + {0xe8800000, 9, 44}, /* 1362 ',' */ + {0xea800000, 9, 89}, /* 1363 'Y' */ + {0x8c000000, 10, 69}, /* 1364 'E' */ + {0x8c400000, 10, 54}, /* 1365 '6' */ + {0x8dc00000, 10, 113}, /* 1366 'q' */ + {0xa2c00000, 10, 121}, /* 1367 'y' */ + {0xa3800000, 10, 77}, /* 1368 'M' */ + {0xea000000, 10, 103}, /* 1369 'g' */ + {0xea400000, 10, 68}, /* 1370 'D' */ + {0x8d800000, 11, 101}, /* 1371 'e' */ + {0x8da00000, 11, 53}, /* 1372 '5' */ + {0xa2800000, 11, 83}, /* 1373 'S' */ + {0xa2a00000, 11, 57}, /* 1374 '9' */ + {0xa3e00000, 11, 70}, /* 1375 'F' */ + {0xb8800000, 11, 98}, /* 1376 'b' */ + {0xb8c00000, 11, 45}, /* 1377 '-' */ + {0xb8e00000, 11, 76}, /* 1378 'L' */ + {0xa3c00000, 12, 66}, /* 1379 'B' */ + {0xa3d00000, 12, 41}, /* 1380 ')' */ + {0xb8a00000, 13, 78}, /* 1381 'N' */ + {0xb8a80000, 13, 81}, /* 1382 'Q' */ + {0xb8b00000, 13, 107}, /* 1383 'k' */ + {0xb8bc0000, 14, 79}, /* 1384 'O' */ + {0xb8ba0000, 15, 63}, /* 1385 '?' */ + {0xb8b80000, 16, 1}, /* 1386 '0x01' */ + {0xb8b90000, 16, 104}, /* 1387 'h' */ + /* 29 */ + {0x00000000, 2, 101}, /* 1388 'e' */ + {0x80000000, 2, 97}, /* 1389 'a' */ + {0xc0000000, 2, 111}, /* 1390 'o' */ + {0x60000000, 3, 117}, /* 1391 'u' */ + {0x50000000, 4, 105}, /* 1392 'i' */ + {0x40000000, 5, 32}, /* 1393 ' ' */ + {0x4c000000, 7, 68}, /* 1394 'D' */ + {0x4e000000, 7, 46}, /* 1395 '.' */ + {0x49000000, 8, 114}, /* 1396 'r' */ + {0x4b000000, 9, 115}, /* 1397 's' */ + {0x48000000, 10, 77}, /* 1398 'M' */ + {0x48800000, 10, 74}, /* 1399 'J' */ + {0x48c00000, 10, 44}, /* 1400 ',' */ + {0x4a000000, 10, 66}, /* 1401 'B' */ + {0x4a400000, 10, 45}, /* 1402 '-' */ + {0x4a800000, 10, 86}, /* 1403 'V' */ + {0x4b800000, 10, 75}, /* 1404 'K' */ + {0x4bc00000, 10, 84}, /* 1405 'T' */ + {0x48400000, 11, 67}, /* 1406 'C' */ + {0x4ac00000, 11, 110}, /* 1407 'n' */ + {0x48600000, 12, 33}, /* 1408 '!' */ + {0x48700000, 13, 119}, /* 1409 'w' */ + {0x48780000, 13, 82}, /* 1410 'R' */ + {0x4ae00000, 13, 70}, /* 1411 'F' */ + {0x4af00000, 13, 55}, /* 1412 '7' */ + {0x4af80000, 13, 39}, /* 1413 '\'' */ + {0x4ae80000, 14, 71}, /* 1414 'G' */ + {0x4aec0000, 15, 1}, /* 1415 '0x01' */ + {0x4aee0000, 15, 76}, /* 1416 'L' */ + /* 40 */ + {0x00000000, 2, 105}, /* 1417 'i' */ + {0x40000000, 2, 97}, /* 1418 'a' */ + {0x80000000, 2, 101}, /* 1419 'e' */ + {0xf0000000, 4, 121}, /* 1420 'y' */ + {0xc0000000, 5, 110}, /* 1421 'n' */ + {0xc8000000, 5, 111}, /* 1422 'o' */ + {0xd8000000, 5, 114}, /* 1423 'r' */ + {0xe8000000, 5, 32}, /* 1424 ' ' */ + {0xd0000000, 6, 39}, /* 1425 '\'' */ + {0xe0000000, 6, 117}, /* 1426 'u' */ + {0xd6000000, 7, 46}, /* 1427 '.' */ + {0xe6000000, 7, 108}, /* 1428 'l' */ + {0xe5000000, 8, 104}, /* 1429 'h' */ + {0xd4000000, 9, 84}, /* 1430 'T' */ + {0xd5800000, 9, 71}, /* 1431 'G' */ + {0xe4800000, 9, 44}, /* 1432 ',' */ + {0xd5000000, 10, 119}, /* 1433 'w' */ + {0xd4800000, 11, 53}, /* 1434 '5' */ + {0xd4a00000, 11, 52}, /* 1435 '4' */ + {0xd4c00000, 11, 65}, /* 1436 'A' */ + {0xd5400000, 11, 51}, /* 1437 '3' */ + {0xe4000000, 11, 50}, /* 1438 '2' */ + {0xe4600000, 11, 77}, /* 1439 'M' */ + {0xd4e00000, 12, 45}, /* 1440 '-' */ + {0xd5600000, 12, 58}, /* 1441 ':' */ + {0xd5700000, 12, 33}, /* 1442 '!' */ + {0xe4200000, 12, 41}, /* 1443 ')' */ + {0xe4500000, 12, 83}, /* 1444 'S' */ + {0xd4f00000, 13, 86}, /* 1445 'V' */ + {0xe4300000, 13, 54}, /* 1446 '6' */ + {0xe4380000, 13, 49}, /* 1447 '1' */ + {0xd4fc0000, 14, 76}, /* 1448 'L' */ + {0xe4400000, 14, 73}, /* 1449 'I' */ + {0xe4440000, 14, 63}, /* 1450 '?' */ + {0xd4f80000, 15, 1}, /* 1451 '0x01' */ + {0xd4fa0000, 15, 118}, /* 1452 'v' */ + {0xe4480000, 15, 107}, /* 1453 'k' */ + {0xe44a0000, 15, 89}, /* 1454 'Y' */ + {0xe44c0000, 15, 78}, /* 1455 'N' */ + {0xe44e0000, 15, 69}, /* 1456 'E' */ + /* 36 */ + {0x00000000, 2, 105}, /* 1457 'i' */ + {0x80000000, 2, 111}, /* 1458 'o' */ + {0x60000000, 3, 93}, /* 1459 ']' */ + {0xc0000000, 3, 101}, /* 1460 'e' */ + {0xe0000000, 3, 97}, /* 1461 'a' */ + {0x40000000, 4, 117}, /* 1462 'u' */ + {0x50000000, 6, 108}, /* 1463 'l' */ + {0x54000000, 6, 65}, /* 1464 'A' */ + {0x5c000000, 6, 121}, /* 1465 'y' */ + {0x5b000000, 8, 32}, /* 1466 ' ' */ + {0x58000000, 9, 73}, /* 1467 'I' */ + {0x58800000, 9, 82}, /* 1468 'R' */ + {0x5a800000, 9, 44}, /* 1469 ',' */ + {0x59000000, 10, 79}, /* 1470 'O' */ + {0x59400000, 10, 39}, /* 1471 '\'' */ + {0x59a00000, 11, 46}, /* 1472 '.' */ + {0x59c00000, 11, 67}, /* 1473 'C' */ + {0x59e00000, 11, 89}, /* 1474 'Y' */ + {0x5a200000, 11, 70}, /* 1475 'F' */ + {0x5a400000, 11, 76}, /* 1476 'L' */ + {0x59900000, 12, 116}, /* 1477 't' */ + {0x5a100000, 12, 71}, /* 1478 'G' */ + {0x5a700000, 12, 83}, /* 1479 'S' */ + {0x59880000, 13, 104}, /* 1480 'h' */ + {0x5a080000, 13, 87}, /* 1481 'W' */ + {0x5a600000, 13, 74}, /* 1482 'J' */ + {0x59800000, 14, 69}, /* 1483 'E' */ + {0x5a040000, 14, 34}, /* 1484 '\"' */ + {0x5a6c0000, 14, 0}, /* 1485 '0x00' */ + {0x59840000, 15, 84}, /* 1486 'T' */ + {0x59860000, 15, 80}, /* 1487 'P' */ + {0x5a000000, 15, 68}, /* 1488 'D' */ + {0x5a020000, 15, 55}, /* 1489 '7' */ + {0x5a6a0000, 15, 106}, /* 1490 'j' */ + {0x5a680000, 16, 1}, /* 1491 '0x01' */ + {0x5a690000, 16, 85}, /* 1492 'U' */ + /* 47 */ + {0x00000000, 2, 111}, /* 1493 'o' */ + {0xc0000000, 2, 97}, /* 1494 'a' */ + {0x60000000, 3, 101}, /* 1495 'e' */ + {0xa0000000, 3, 105}, /* 1496 'i' */ + {0x50000000, 4, 99}, /* 1497 'c' */ + {0x90000000, 4, 117}, /* 1498 'u' */ + {0x48000000, 5, 121}, /* 1499 'y' */ + {0x88000000, 5, 114}, /* 1500 'r' */ + {0x80000000, 6, 83}, /* 1501 'S' */ + {0x84000000, 6, 80}, /* 1502 'P' */ + {0x42000000, 7, 32}, /* 1503 ' ' */ + {0x41000000, 8, 67}, /* 1504 'C' */ + {0x46000000, 8, 70}, /* 1505 'F' */ + {0x40000000, 9, 49}, /* 1506 '1' */ + {0x44000000, 9, 104}, /* 1507 'h' */ + {0x45000000, 9, 73}, /* 1508 'I' */ + {0x47000000, 9, 84}, /* 1509 'T' */ + {0x47800000, 9, 88}, /* 1510 'X' */ + {0x40800000, 10, 65}, /* 1511 'A' */ + {0x44800000, 10, 122}, /* 1512 'z' */ + {0x44c00000, 11, 102}, /* 1513 'f' */ + {0x45c00000, 11, 46}, /* 1514 '.' */ + {0x40c00000, 12, 90}, /* 1515 'Z' */ + {0x40d00000, 12, 75}, /* 1516 'K' */ + {0x40e00000, 12, 66}, /* 1517 'B' */ + {0x44f00000, 12, 115}, /* 1518 's' */ + {0x45800000, 12, 82}, /* 1519 'R' */ + {0x45900000, 12, 87}, /* 1520 'W' */ + {0x45a00000, 12, 79}, /* 1521 'O' */ + {0x40f00000, 13, 44}, /* 1522 ',' */ + {0x40f80000, 13, 39}, /* 1523 '\'' */ + {0x45b80000, 13, 68}, /* 1524 'D' */ + {0x45e00000, 13, 52}, /* 1525 '4' */ + {0x45f00000, 13, 69}, /* 1526 'E' */ + {0x44e00000, 14, 109}, /* 1527 'm' */ + {0x44e40000, 14, 74}, /* 1528 'J' */ + {0x44e80000, 14, 1}, /* 1529 '0x01' */ + {0x45e80000, 14, 108}, /* 1530 'l' */ + {0x45ec0000, 14, 45}, /* 1531 '-' */ + {0x45f80000, 14, 41}, /* 1532 ')' */ + {0x45fc0000, 14, 119}, /* 1533 'w' */ + {0x44ec0000, 15, 116}, /* 1534 't' */ + {0x44ee0000, 15, 86}, /* 1535 'V' */ + {0x45b00000, 15, 81}, /* 1536 'Q' */ + {0x45b20000, 15, 78}, /* 1537 'N' */ + {0x45b40000, 15, 54}, /* 1538 '6' */ + {0x45b60000, 15, 50}, /* 1539 '2' */ + /* 35 */ + {0x00000000, 2, 97}, /* 1540 'a' */ + {0x80000000, 2, 111}, /* 1541 'o' */ + {0xc0000000, 2, 101}, /* 1542 'e' */ + {0x60000000, 3, 105}, /* 1543 'i' */ + {0x50000000, 5, 117}, /* 1544 'u' */ + {0x58000000, 5, 69}, /* 1545 'E' */ + {0x48000000, 6, 65}, /* 1546 'A' */ + {0x44000000, 7, 121}, /* 1547 'y' */ + {0x4c000000, 7, 103}, /* 1548 'g' */ + {0x41000000, 8, 66}, /* 1549 'B' */ + {0x42000000, 8, 73}, /* 1550 'I' */ + {0x46000000, 8, 70}, /* 1551 'F' */ + {0x47000000, 8, 32}, /* 1552 ' ' */ + {0x40000000, 9, 41}, /* 1553 ')' */ + {0x40800000, 9, 39}, /* 1554 '\'' */ + {0x43800000, 9, 89}, /* 1555 'Y' */ + {0x4e000000, 9, 76}, /* 1556 'L' */ + {0x4e800000, 9, 72}, /* 1557 'H' */ + {0x43000000, 10, 67}, /* 1558 'C' */ + {0x4f000000, 10, 87}, /* 1559 'W' */ + {0x4f800000, 10, 78}, /* 1560 'N' */ + {0x4fc00000, 10, 84}, /* 1561 'T' */ + {0x43500000, 12, 77}, /* 1562 'M' */ + {0x43700000, 12, 79}, /* 1563 'O' */ + {0x4f400000, 12, 44}, /* 1564 ',' */ + {0x4f500000, 12, 74}, /* 1565 'J' */ + {0x4f700000, 12, 104}, /* 1566 'h' */ + {0x43400000, 13, 68}, /* 1567 'D' */ + {0x43480000, 13, 46}, /* 1568 '.' */ + {0x4f600000, 13, 88}, /* 1569 'X' */ + {0x4f680000, 13, 1}, /* 1570 '0x01' */ + {0x43600000, 14, 107}, /* 1571 'k' */ + {0x43640000, 14, 90}, /* 1572 'Z' */ + {0x43680000, 14, 81}, /* 1573 'Q' */ + {0x436c0000, 14, 71}, /* 1574 'G' */ + /* 59 */ + {0xe0000000, 3, 110}, /* 1575 'n' */ + {0x00000000, 4, 115}, /* 1576 's' */ + {0x10000000, 4, 78}, /* 1577 'N' */ + {0x30000000, 4, 122}, /* 1578 'z' */ + {0x40000000, 4, 114}, /* 1579 'r' */ + {0x80000000, 4, 117}, /* 1580 'u' */ + {0xa0000000, 4, 112}, /* 1581 'p' */ + {0xb0000000, 4, 108}, /* 1582 'l' */ + {0xd0000000, 4, 39}, /* 1583 '\'' */ + {0x28000000, 5, 85}, /* 1584 'U' */ + {0x58000000, 5, 104}, /* 1585 'h' */ + {0x70000000, 5, 102}, /* 1586 'f' */ + {0x78000000, 5, 119}, /* 1587 'w' */ + {0x90000000, 5, 46}, /* 1588 '.' */ + {0xc0000000, 5, 32}, /* 1589 ' ' */ + {0x20000000, 6, 111}, /* 1590 'o' */ + {0x24000000, 6, 74}, /* 1591 'J' */ + {0x50000000, 6, 98}, /* 1592 'b' */ + {0x54000000, 6, 109}, /* 1593 'm' */ + {0x64000000, 6, 72}, /* 1594 'H' */ + {0x68000000, 6, 79}, /* 1595 'O' */ + {0x6c000000, 6, 118}, /* 1596 'v' */ + {0x9c000000, 6, 99}, /* 1597 'c' */ + {0xcc000000, 6, 120}, /* 1598 'x' */ + {0x9a000000, 7, 100}, /* 1599 'd' */ + {0xc8000000, 7, 97}, /* 1600 'a' */ + {0x61000000, 8, 116}, /* 1601 't' */ + {0x62000000, 8, 107}, /* 1602 'k' */ + {0x98000000, 8, 103}, /* 1603 'g' */ + {0xca000000, 8, 82}, /* 1604 'R' */ + {0x60000000, 9, 75}, /* 1605 'K' */ + {0x99000000, 9, 105}, /* 1606 'i' */ + {0xcb800000, 9, 86}, /* 1607 'V' */ + {0x60c00000, 10, 50}, /* 1608 '2' */ + {0x63400000, 10, 83}, /* 1609 'S' */ + {0x63800000, 10, 66}, /* 1610 'B' */ + {0x99800000, 10, 87}, /* 1611 'W' */ + {0x99c00000, 10, 45}, /* 1612 '-' */ + {0x60800000, 11, 44}, /* 1613 ',' */ + {0x63000000, 11, 106}, /* 1614 'j' */ + {0x63200000, 11, 76}, /* 1615 'L' */ + {0x63e00000, 11, 73}, /* 1616 'I' */ + {0xcb200000, 11, 65}, /* 1617 'A' */ + {0xcb600000, 11, 67}, /* 1618 'C' */ + {0x60a00000, 12, 58}, /* 1619 ':' */ + {0x63c00000, 12, 101}, /* 1620 'e' */ + {0xcb000000, 12, 121}, /* 1621 'y' */ + {0xcb100000, 12, 47}, /* 1622 '/' */ + {0xcb400000, 12, 77}, /* 1623 'M' */ + {0x60b00000, 13, 33}, /* 1624 '!' */ + {0x63d80000, 13, 80}, /* 1625 'P' */ + {0xcb580000, 13, 70}, /* 1626 'F' */ + {0x60b80000, 14, 69}, /* 1627 'E' */ + {0x60bc0000, 14, 68}, /* 1628 'D' */ + {0x63d00000, 14, 56}, /* 1629 '8' */ + {0x63d40000, 14, 52}, /* 1630 '4' */ + {0xcb540000, 14, 84}, /* 1631 'T' */ + {0xcb500000, 15, 1}, /* 1632 '0x01' */ + {0xcb520000, 15, 113}, /* 1633 'q' */ + /* 39 */ + {0xc0000000, 2, 97}, /* 1634 'a' */ + {0x00000000, 3, 105}, /* 1635 'i' */ + {0x40000000, 3, 101}, /* 1636 'e' */ + {0x60000000, 3, 108}, /* 1637 'l' */ + {0x80000000, 3, 111}, /* 1638 'o' */ + {0xa0000000, 3, 114}, /* 1639 'r' */ + {0x20000000, 4, 104}, /* 1640 'h' */ + {0x3c000000, 6, 117}, /* 1641 'u' */ + {0x34000000, 7, 67}, /* 1642 'C' */ + {0x38000000, 7, 46}, /* 1643 '.' */ + {0x3a000000, 7, 32}, /* 1644 ' ' */ + {0x30000000, 8, 66}, /* 1645 'B' */ + {0x32000000, 8, 68}, /* 1646 'D' */ + {0x37000000, 8, 115}, /* 1647 's' */ + {0x31800000, 9, 79}, /* 1648 'O' */ + {0x33800000, 9, 44}, /* 1649 ',' */ + {0x31400000, 10, 121}, /* 1650 'y' */ + {0x33000000, 10, 77}, /* 1651 'M' */ + {0x36000000, 10, 69}, /* 1652 'E' */ + {0x36400000, 10, 39}, /* 1653 '\'' */ + {0x36c00000, 10, 51}, /* 1654 '3' */ + {0x31200000, 11, 84}, /* 1655 'T' */ + {0x31000000, 12, 76}, /* 1656 'L' */ + {0x31100000, 12, 71}, /* 1657 'G' */ + {0x33400000, 12, 42}, /* 1658 '*' */ + {0x33600000, 12, 65}, /* 1659 'A' */ + {0x33700000, 12, 83}, /* 1660 'S' */ + {0x36800000, 12, 119}, /* 1661 'w' */ + {0x36900000, 12, 70}, /* 1662 'F' */ + {0x33580000, 13, 74}, /* 1663 'J' */ + {0x36a00000, 13, 102}, /* 1664 'f' */ + {0x36a80000, 13, 82}, /* 1665 'R' */ + {0x36b80000, 13, 116}, /* 1666 't' */ + {0x33500000, 14, 86}, /* 1667 'V' */ + {0x36b00000, 14, 89}, /* 1668 'Y' */ + {0x36b40000, 14, 73}, /* 1669 'I' */ + {0x33560000, 15, 38}, /* 1670 '&' */ + {0x33540000, 16, 1}, /* 1671 '0x01' */ + {0x33550000, 16, 41}, /* 1672 ')' */ + /* 13 */ + {0x80000000, 1, 117}, /* 1673 'u' */ + {0x00000000, 2, 86}, /* 1674 'V' */ + {0x60000000, 3, 32}, /* 1675 ' ' */ + {0x50000000, 4, 46}, /* 1676 '.' */ + {0x40000000, 5, 97}, /* 1677 'a' */ + {0x48000000, 7, 119}, /* 1678 'w' */ + {0x4c000000, 7, 69}, /* 1679 'E' */ + {0x4e000000, 7, 67}, /* 1680 'C' */ + {0x4b000000, 8, 38}, /* 1681 '&' */ + {0x4a800000, 9, 39}, /* 1682 '\'' */ + {0x4a000000, 10, 84}, /* 1683 'T' */ + {0x4a400000, 11, 1}, /* 1684 '0x01' */ + {0x4a600000, 11, 115}, /* 1685 's' */ + /* 37 */ + {0x40000000, 2, 97}, /* 1686 'a' */ + {0xc0000000, 2, 111}, /* 1687 'o' */ + {0x80000000, 3, 105}, /* 1688 'i' */ + {0xa0000000, 3, 101}, /* 1689 'e' */ + {0x00000000, 4, 112}, /* 1690 'p' */ + {0x30000000, 4, 117}, /* 1691 'u' */ + {0x18000000, 5, 69}, /* 1692 'E' */ + {0x20000000, 5, 104}, /* 1693 'h' */ + {0x10000000, 6, 32}, /* 1694 ' ' */ + {0x28000000, 6, 121}, /* 1695 'y' */ + {0x14000000, 8, 68}, /* 1696 'D' */ + {0x16000000, 8, 46}, /* 1697 '.' */ + {0x2c000000, 8, 84}, /* 1698 'T' */ + {0x2e000000, 8, 83}, /* 1699 'S' */ + {0x15000000, 9, 70}, /* 1700 'F' */ + {0x2d000000, 9, 66}, /* 1701 'B' */ + {0x2d800000, 9, 110}, /* 1702 'n' */ + {0x2f800000, 9, 65}, /* 1703 'A' */ + {0x15800000, 10, 119}, /* 1704 'w' */ + {0x17000000, 10, 78}, /* 1705 'N' */ + {0x17400000, 10, 38}, /* 1706 '&' */ + {0x17800000, 10, 86}, /* 1707 'V' */ + {0x17c00000, 10, 72}, /* 1708 'H' */ + {0x2f400000, 10, 39}, /* 1709 '\'' */ + {0x15c00000, 11, 116}, /* 1710 't' */ + {0x15e00000, 11, 73}, /* 1711 'I' */ + {0x2f000000, 12, 67}, /* 1712 'C' */ + {0x2f200000, 12, 79}, /* 1713 'O' */ + {0x2f100000, 14, 44}, /* 1714 ',' */ + {0x2f140000, 14, 115}, /* 1715 's' */ + {0x2f180000, 14, 85}, /* 1716 'U' */ + {0x2f1c0000, 14, 77}, /* 1717 'M' */ + {0x2f300000, 14, 45}, /* 1718 '-' */ + {0x2f340000, 14, 1}, /* 1719 '0x01' */ + {0x2f3c0000, 14, 58}, /* 1720 ':' */ + {0x2f380000, 15, 50}, /* 1721 '2' */ + {0x2f3a0000, 15, 82}, /* 1722 'R' */ + /* 59 */ + {0x80000000, 1, 93}, /* 1723 ']' */ + {0x00000000, 4, 97}, /* 1724 'a' */ + {0x20000000, 4, 104}, /* 1725 'h' */ + {0x70000000, 4, 116}, /* 1726 't' */ + {0x10000000, 5, 112}, /* 1727 'p' */ + {0x18000000, 5, 44}, /* 1728 ',' */ + {0x30000000, 5, 76}, /* 1729 'L' */ + {0x40000000, 5, 105}, /* 1730 'i' */ + {0x48000000, 5, 117}, /* 1731 'u' */ + {0x50000000, 5, 111}, /* 1732 'o' */ + {0x58000000, 5, 99}, /* 1733 'c' */ + {0x60000000, 5, 101}, /* 1734 'e' */ + {0x3c000000, 6, 107}, /* 1735 'k' */ + {0x38000000, 7, 119}, /* 1736 'w' */ + {0x6a000000, 7, 32}, /* 1737 ' ' */ + {0x6e000000, 7, 109}, /* 1738 'm' */ + {0x3a000000, 8, 113}, /* 1739 'q' */ + {0x68000000, 8, 77}, /* 1740 'M' */ + {0x69000000, 8, 110}, /* 1741 'n' */ + {0x6c000000, 8, 108}, /* 1742 'l' */ + {0x3b000000, 9, 80}, /* 1743 'P' */ + {0x6d800000, 9, 121}, /* 1744 'y' */ + {0x3b800000, 10, 65}, /* 1745 'A' */ + {0x6d200000, 11, 46}, /* 1746 '.' */ + {0x3bd00000, 12, 114}, /* 1747 'r' */ + {0x3be00000, 12, 83}, /* 1748 'S' */ + {0x3bf00000, 12, 87}, /* 1749 'W' */ + {0x6d000000, 12, 67}, /* 1750 'C' */ + {0x6d500000, 12, 69}, /* 1751 'E' */ + {0x6d600000, 12, 118}, /* 1752 'v' */ + {0x6d180000, 13, 1}, /* 1753 '0x01' */ + {0x6d400000, 13, 73}, /* 1754 'I' */ + {0x6d780000, 13, 103}, /* 1755 'g' */ + {0x3bc00000, 14, 42}, /* 1756 '*' */ + {0x3bc80000, 14, 52}, /* 1757 '4' */ + {0x3bcc0000, 14, 49}, /* 1758 '1' */ + {0x6d100000, 14, 79}, /* 1759 'O' */ + {0x6d480000, 14, 0}, /* 1760 '0x00' */ + {0x6d700000, 14, 122}, /* 1761 'z' */ + {0x6d160000, 15, 66}, /* 1762 'B' */ + {0x6d740000, 15, 72}, /* 1763 'H' */ + {0x6d760000, 15, 84}, /* 1764 'T' */ + {0x3bc40000, 16, 71}, /* 1765 'G' */ + {0x3bc60000, 16, 125}, /* 1766 '}' */ + {0x3bc70000, 16, 68}, /* 1767 'D' */ + {0x6d140000, 16, 45}, /* 1768 '-' */ + {0x6d4c0000, 16, 51}, /* 1769 '3' */ + {0x6d4d0000, 16, 50}, /* 1770 '2' */ + {0x3bc50000, 17, 39}, /* 1771 '\'' */ + {0x3bc58000, 17, 63}, /* 1772 '?' */ + {0x6d4e8000, 17, 115}, /* 1773 's' */ + {0x6d4f0000, 17, 106}, /* 1774 'j' */ + {0x6d4f8000, 17, 98}, /* 1775 'b' */ + {0x6d150000, 18, 82}, /* 1776 'R' */ + {0x6d154000, 18, 75}, /* 1777 'K' */ + {0x6d158000, 18, 74}, /* 1778 'J' */ + {0x6d15c000, 18, 70}, /* 1779 'F' */ + {0x6d4e0000, 18, 58}, /* 1780 ':' */ + {0x6d4e4000, 18, 41}, /* 1781 ')' */ + /* 44 */ + {0x00000000, 1, 104}, /* 1782 'h' */ + {0x80000000, 3, 111}, /* 1783 'o' */ + {0xa0000000, 4, 86}, /* 1784 'V' */ + {0xb0000000, 4, 119}, /* 1785 'w' */ + {0xc0000000, 4, 114}, /* 1786 'r' */ + {0xf0000000, 4, 101}, /* 1787 'e' */ + {0xd0000000, 5, 97}, /* 1788 'a' */ + {0xd8000000, 5, 105}, /* 1789 'i' */ + {0xe0000000, 5, 117}, /* 1790 'u' */ + {0xe8000000, 7, 72}, /* 1791 'H' */ + {0xec000000, 7, 87}, /* 1792 'W' */ + {0xea000000, 8, 32}, /* 1793 ' ' */ + {0xeb000000, 8, 121}, /* 1794 'y' */ + {0xee800000, 9, 77}, /* 1795 'M' */ + {0xef800000, 9, 120}, /* 1796 'x' */ + {0xee000000, 10, 83}, /* 1797 'S' */ + {0xee400000, 11, 65}, /* 1798 'A' */ + {0xef200000, 11, 115}, /* 1799 's' */ + {0xef600000, 11, 74}, /* 1800 'J' */ + {0xee700000, 12, 88}, /* 1801 'X' */ + {0xef000000, 12, 46}, /* 1802 '.' */ + {0xee680000, 13, 45}, /* 1803 '-' */ + {0xef180000, 13, 76}, /* 1804 'L' */ + {0xef400000, 13, 67}, /* 1805 'C' */ + {0xef580000, 13, 99}, /* 1806 'c' */ + {0xee600000, 14, 84}, /* 1807 'T' */ + {0xee640000, 14, 85}, /* 1808 'U' */ + {0xef140000, 14, 52}, /* 1809 '4' */ + {0xef480000, 14, 79}, /* 1810 'O' */ + {0xef120000, 15, 71}, /* 1811 'G' */ + {0xef4c0000, 15, 69}, /* 1812 'E' */ + {0xef4e0000, 15, 44}, /* 1813 ',' */ + {0xef540000, 15, 39}, /* 1814 '\'' */ + {0xef110000, 16, 59}, /* 1815 ';' */ + {0xef500000, 16, 80}, /* 1816 'P' */ + {0xef510000, 16, 49}, /* 1817 '1' */ + {0xef520000, 16, 1}, /* 1818 '0x01' */ + {0xef570000, 16, 68}, /* 1819 'D' */ + {0xef100000, 17, 58}, /* 1820 ':' */ + {0xef108000, 17, 42}, /* 1821 '*' */ + {0xef530000, 17, 82}, /* 1822 'R' */ + {0xef538000, 17, 78}, /* 1823 'N' */ + {0xef560000, 17, 73}, /* 1824 'I' */ + {0xef568000, 17, 66}, /* 1825 'B' */ + /* 45 */ + {0x00000000, 2, 75}, /* 1826 'K' */ + {0x80000000, 2, 110}, /* 1827 'n' */ + {0x60000000, 3, 83}, /* 1828 'S' */ + {0xc0000000, 3, 112}, /* 1829 'p' */ + {0xf0000000, 4, 108}, /* 1830 'l' */ + {0x50000000, 5, 115}, /* 1831 's' */ + {0x58000000, 5, 114}, /* 1832 'r' */ + {0xe8000000, 5, 82}, /* 1833 'R' */ + {0x40000000, 6, 103}, /* 1834 'g' */ + {0xe0000000, 6, 32}, /* 1835 ' ' */ + {0x4e000000, 7, 46}, /* 1836 '.' */ + {0xe4000000, 7, 109}, /* 1837 'm' */ + {0x44000000, 8, 107}, /* 1838 'k' */ + {0x45000000, 8, 116}, /* 1839 't' */ + {0x46000000, 8, 69}, /* 1840 'E' */ + {0x47000000, 8, 45}, /* 1841 '-' */ + {0x48000000, 8, 70}, /* 1842 'F' */ + {0x4c000000, 8, 50}, /* 1843 '2' */ + {0xe6000000, 8, 99}, /* 1844 'c' */ + {0xe7000000, 8, 78}, /* 1845 'N' */ + {0x49000000, 9, 102}, /* 1846 'f' */ + {0x49800000, 9, 56}, /* 1847 '8' */ + {0x4a000000, 9, 44}, /* 1848 ',' */ + {0x4b800000, 9, 90}, /* 1849 'Z' */ + {0x4a800000, 10, 104}, /* 1850 'h' */ + {0x4d000000, 10, 105}, /* 1851 'i' */ + {0x4d400000, 10, 119}, /* 1852 'w' */ + {0x4d800000, 10, 97}, /* 1853 'a' */ + {0x4ac00000, 11, 98}, /* 1854 'b' */ + {0x4ae00000, 11, 68}, /* 1855 'D' */ + {0x4dc00000, 11, 33}, /* 1856 '!' */ + {0x4b000000, 12, 101}, /* 1857 'e' */ + {0x4b100000, 12, 86}, /* 1858 'V' */ + {0x4b200000, 12, 80}, /* 1859 'P' */ + {0x4b300000, 12, 73}, /* 1860 'I' */ + {0x4b400000, 12, 66}, /* 1861 'B' */ + {0x4b500000, 12, 65}, /* 1862 'A' */ + {0x4df00000, 12, 100}, /* 1863 'd' */ + {0x4b600000, 13, 72}, /* 1864 'H' */ + {0x4b680000, 13, 67}, /* 1865 'C' */ + {0x4b700000, 13, 58}, /* 1866 ':' */ + {0x4b780000, 13, 41}, /* 1867 ')' */ + {0x4de80000, 13, 122}, /* 1868 'z' */ + {0x4de00000, 14, 1}, /* 1869 '0x01' */ + {0x4de40000, 14, 84}, /* 1870 'T' */ + /* 38 */ + {0x40000000, 2, 32}, /* 1871 ' ' */ + {0xc0000000, 2, 105}, /* 1872 'i' */ + {0x00000000, 3, 46}, /* 1873 '.' */ + {0x20000000, 3, 97}, /* 1874 'a' */ + {0xa0000000, 3, 101}, /* 1875 'e' */ + {0x88000000, 5, 67}, /* 1876 'C' */ + {0x98000000, 5, 111}, /* 1877 'o' */ + {0x82000000, 7, 70}, /* 1878 'F' */ + {0x86000000, 7, 73}, /* 1879 'I' */ + {0x81000000, 8, 49}, /* 1880 '1' */ + {0x85000000, 8, 52}, /* 1881 '4' */ + {0x90000000, 8, 114}, /* 1882 'r' */ + {0x92000000, 8, 69}, /* 1883 'E' */ + {0x93000000, 8, 115}, /* 1884 's' */ + {0x95000000, 8, 39}, /* 1885 '\'' */ + {0x96000000, 8, 58}, /* 1886 ':' */ + {0x97000000, 8, 108}, /* 1887 'l' */ + {0x80800000, 9, 47}, /* 1888 '/' */ + {0x84800000, 9, 45}, /* 1889 '-' */ + {0x91000000, 9, 68}, /* 1890 'D' */ + {0x91800000, 9, 117}, /* 1891 'u' */ + {0x94800000, 9, 44}, /* 1892 ',' */ + {0x80000000, 10, 54}, /* 1893 '6' */ + {0x80400000, 10, 50}, /* 1894 '2' */ + {0x84000000, 10, 53}, /* 1895 '5' */ + {0x94000000, 10, 59}, /* 1896 ';' */ + {0x94400000, 11, 1}, /* 1897 '0x01' */ + {0x84400000, 12, 55}, /* 1898 '7' */ + {0x94600000, 12, 51}, /* 1899 '3' */ + {0x84500000, 13, 57}, /* 1900 '9' */ + {0x84580000, 13, 121}, /* 1901 'y' */ + {0x84600000, 13, 80}, /* 1902 'P' */ + {0x84680000, 13, 72}, /* 1903 'H' */ + {0x84700000, 13, 65}, /* 1904 'A' */ + {0x84780000, 13, 56}, /* 1905 '8' */ + {0x94780000, 13, 87}, /* 1906 'W' */ + {0x94700000, 14, 102}, /* 1907 'f' */ + {0x94740000, 14, 66}, /* 1908 'B' */ + /* 30 */ + {0x00000000, 2, 104}, /* 1909 'h' */ + {0x80000000, 2, 105}, /* 1910 'i' */ + {0x60000000, 3, 97}, /* 1911 'a' */ + {0xc0000000, 3, 111}, /* 1912 'o' */ + {0xe0000000, 3, 101}, /* 1913 'e' */ + {0x40000000, 4, 114}, /* 1914 'r' */ + {0x58000000, 5, 79}, /* 1915 'O' */ + {0x52000000, 7, 32}, /* 1916 ' ' */ + {0x54000000, 7, 121}, /* 1917 'y' */ + {0x50000000, 9, 66}, /* 1918 'B' */ + {0x50800000, 9, 46}, /* 1919 '.' */ + {0x56000000, 9, 73}, /* 1920 'I' */ + {0x57000000, 9, 87}, /* 1921 'W' */ + {0x57800000, 9, 65}, /* 1922 'A' */ + {0x51000000, 10, 39}, /* 1923 '\'' */ + {0x51400000, 10, 77}, /* 1924 'M' */ + {0x51c00000, 10, 84}, /* 1925 'T' */ + {0x51800000, 11, 50}, /* 1926 '2' */ + {0x51a00000, 11, 58}, /* 1927 ':' */ + {0x56800000, 11, 72}, /* 1928 'H' */ + {0x56c00000, 11, 86}, /* 1929 'V' */ + {0x56a00000, 12, 108}, /* 1930 'l' */ + {0x56e00000, 12, 115}, /* 1931 's' */ + {0x56f00000, 12, 44}, /* 1932 ',' */ + {0x56b80000, 13, 117}, /* 1933 'u' */ + {0x56b00000, 15, 53}, /* 1934 '5' */ + {0x56b20000, 15, 41}, /* 1935 ')' */ + {0x56b60000, 15, 69}, /* 1936 'E' */ + {0x56b40000, 16, 1}, /* 1937 '0x01' */ + {0x56b50000, 16, 109}, /* 1938 'm' */ + /* 24 */ + {0x80000000, 1, 32}, /* 1939 ' ' */ + {0x00000000, 3, 97}, /* 1940 'a' */ + {0x20000000, 4, 122}, /* 1941 'z' */ + {0x30000000, 4, 109}, /* 1942 'm' */ + {0x70000000, 4, 116}, /* 1943 't' */ + {0x48000000, 5, 85}, /* 1944 'U' */ + {0x50000000, 5, 45}, /* 1945 '-' */ + {0x58000000, 5, 101}, /* 1946 'e' */ + {0x60000000, 6, 117}, /* 1947 'u' */ + {0x64000000, 6, 73}, /* 1948 'I' */ + {0x6c000000, 6, 44}, /* 1949 ',' */ + {0x44000000, 7, 86}, /* 1950 'V' */ + {0x68000000, 7, 53}, /* 1951 '5' */ + {0x6a000000, 7, 46}, /* 1952 '.' */ + {0x40000000, 8, 83}, /* 1953 'S' */ + {0x42000000, 8, 58}, /* 1954 ':' */ + {0x46000000, 8, 99}, /* 1955 'c' */ + {0x47000000, 8, 105}, /* 1956 'i' */ + {0x41000000, 9, 57}, /* 1957 '9' */ + {0x41800000, 9, 39}, /* 1958 '\'' */ + {0x43800000, 9, 88}, /* 1959 'X' */ + {0x43000000, 10, 41}, /* 1960 ')' */ + {0x43400000, 11, 1}, /* 1961 '0x01' */ + {0x43600000, 11, 121}, /* 1962 'y' */ + /* 24 */ + {0x80000000, 1, 111}, /* 1963 'o' */ + {0x00000000, 2, 101}, /* 1964 'e' */ + {0x40000000, 3, 117}, /* 1965 'u' */ + {0x60000000, 5, 97}, /* 1966 'a' */ + {0x70000000, 5, 118}, /* 1967 'v' */ + {0x78000000, 5, 32}, /* 1968 ' ' */ + {0x68000000, 7, 110}, /* 1969 'n' */ + {0x6a000000, 8, 114}, /* 1970 'r' */ + {0x6d000000, 8, 79}, /* 1971 'O' */ + {0x6f000000, 8, 105}, /* 1972 'i' */ + {0x6b800000, 9, 78}, /* 1973 'N' */ + {0x6c000000, 9, 76}, /* 1974 'L' */ + {0x6c800000, 9, 115}, /* 1975 's' */ + {0x6e800000, 9, 109}, /* 1976 'm' */ + {0x6b000000, 10, 46}, /* 1977 '.' */ + {0x6b400000, 10, 77}, /* 1978 'M' */ + {0x6e400000, 10, 80}, /* 1979 'P' */ + {0x6e100000, 12, 82}, /* 1980 'R' */ + {0x6e200000, 12, 50}, /* 1981 '2' */ + {0x6e000000, 13, 45}, /* 1982 '-' */ + {0x6e300000, 13, 67}, /* 1983 'C' */ + {0x6e380000, 13, 44}, /* 1984 ',' */ + {0x6e080000, 14, 1}, /* 1985 '0x01' */ + {0x6e0c0000, 14, 100}, /* 1986 'd' */ + /* 18 */ + {0x40000000, 2, 97}, /* 1987 'a' */ + {0x80000000, 2, 101}, /* 1988 'e' */ + {0xc0000000, 2, 111}, /* 1989 'o' */ + {0x20000000, 4, 122}, /* 1990 'z' */ + {0x30000000, 4, 105}, /* 1991 'i' */ + {0x08000000, 5, 90}, /* 1992 'Z' */ + {0x10000000, 5, 32}, /* 1993 ' ' */ + {0x18000000, 5, 117}, /* 1994 'u' */ + {0x04000000, 7, 79}, /* 1995 'O' */ + {0x06000000, 7, 46}, /* 1996 '.' */ + {0x00000000, 8, 121}, /* 1997 'y' */ + {0x01000000, 8, 52}, /* 1998 '4' */ + {0x02000000, 8, 44}, /* 1999 ',' */ + {0x03000000, 10, 102}, /* 2000 'f' */ + {0x03400000, 10, 45}, /* 2001 '-' */ + {0x03800000, 10, 0}, /* 2002 '0x00' */ + {0x03c00000, 11, 1}, /* 2003 '0x01' */ + {0x03e00000, 11, 108}, /* 2004 'l' */ + /* 34 */ + {0x80000000, 1, 83}, /* 2005 'S' */ + {0x40000000, 2, 65}, /* 2006 'A' */ + {0x00000000, 4, 50}, /* 2007 '2' */ + {0x20000000, 4, 82}, /* 2008 'R' */ + {0x30000000, 4, 49}, /* 2009 '1' */ + {0x14000000, 6, 110}, /* 2010 'n' */ + {0x18000000, 6, 109}, /* 2011 'm' */ + {0x1e000000, 7, 108}, /* 2012 'l' */ + {0x13000000, 8, 114}, /* 2013 'r' */ + {0x1d000000, 8, 98}, /* 2014 'b' */ + {0x10800000, 9, 67}, /* 2015 'C' */ + {0x11000000, 9, 102}, /* 2016 'f' */ + {0x12800000, 9, 77}, /* 2017 'M' */ + {0x1c800000, 9, 99}, /* 2018 'c' */ + {0x10400000, 10, 0}, /* 2019 '0x00' */ + {0x11c00000, 10, 75}, /* 2020 'K' */ + {0x12000000, 10, 72}, /* 2021 'H' */ + {0x1c400000, 10, 84}, /* 2022 'T' */ + {0x10000000, 11, 74}, /* 2023 'J' */ + {0x10200000, 11, 66}, /* 2024 'B' */ + {0x11a00000, 11, 90}, /* 2025 'Z' */ + {0x12600000, 11, 80}, /* 2026 'P' */ + {0x1c000000, 11, 76}, /* 2027 'L' */ + {0x11800000, 12, 70}, /* 2028 'F' */ + {0x12500000, 12, 73}, /* 2029 'I' */ + {0x1c300000, 12, 78}, /* 2030 'N' */ + {0x11900000, 13, 115}, /* 2031 's' */ + {0x11980000, 13, 86}, /* 2032 'V' */ + {0x12400000, 13, 85}, /* 2033 'U' */ + {0x12480000, 13, 71}, /* 2034 'G' */ + {0x1c280000, 13, 68}, /* 2035 'D' */ + {0x1c200000, 14, 79}, /* 2036 'O' */ + {0x1c240000, 15, 1}, /* 2037 '0x01' */ + {0x1c260000, 15, 87}, /* 2038 'W' */ + /* 2 */ + {0x00000000, 1, 1}, /* 2039 '0x01' */ + {0x80000000, 1, 120}, /* 2040 'x' */ + /* 9 */ + {0x80000000, 1, 0}, /* 2041 '0x00' */ + {0x40000000, 2, 32}, /* 2042 ' ' */ + {0x20000000, 3, 46}, /* 2043 '.' */ + {0x10000000, 4, 91}, /* 2044 '[' */ + {0x08000000, 5, 58}, /* 2045 ':' */ + {0x04000000, 6, 44}, /* 2046 ',' */ + {0x02000000, 7, 59}, /* 2047 ';' */ + {0x00000000, 8, 1}, /* 2048 '0x01' */ + {0x01000000, 8, 93}, /* 2049 ']' */ + /* 2 */ + {0x00000000, 1, 1}, /* 2050 '0x01' */ + {0x80000000, 1, 1}, /* 2051 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 2052 '0x01' */ + {0x80000000, 1, 1}, /* 2053 '0x01' */ + /* 31 */ + {0x20000000, 3, 119}, /* 2054 'w' */ + {0x60000000, 3, 72}, /* 2055 'H' */ + {0xc0000000, 3, 80}, /* 2056 'P' */ + {0xe0000000, 3, 70}, /* 2057 'F' */ + {0x50000000, 4, 110}, /* 2058 'n' */ + {0xb0000000, 4, 68}, /* 2059 'D' */ + {0x08000000, 5, 115}, /* 2060 's' */ + {0x10000000, 5, 65}, /* 2061 'A' */ + {0x48000000, 5, 116}, /* 2062 't' */ + {0x80000000, 5, 103}, /* 2063 'g' */ + {0x98000000, 5, 99}, /* 2064 'c' */ + {0x00000000, 6, 87}, /* 2065 'W' */ + {0x04000000, 6, 114}, /* 2066 'r' */ + {0x18000000, 6, 101}, /* 2067 'e' */ + {0x1c000000, 6, 67}, /* 2068 'C' */ + {0x8c000000, 6, 108}, /* 2069 'l' */ + {0x90000000, 6, 104}, /* 2070 'h' */ + {0x94000000, 6, 71}, /* 2071 'G' */ + {0xa4000000, 6, 66}, /* 2072 'B' */ + {0xa8000000, 6, 84}, /* 2073 'T' */ + {0xac000000, 6, 83}, /* 2074 'S' */ + {0x40000000, 7, 111}, /* 2075 'o' */ + {0x42000000, 7, 100}, /* 2076 'd' */ + {0x44000000, 7, 98}, /* 2077 'b' */ + {0x46000000, 7, 82}, /* 2078 'R' */ + {0x88000000, 7, 79}, /* 2079 'O' */ + {0x8a000000, 7, 76}, /* 2080 'L' */ + {0xa2000000, 7, 102}, /* 2081 'f' */ + {0xa0000000, 8, 74}, /* 2082 'J' */ + {0xa1000000, 9, 1}, /* 2083 '0x01' */ + {0xa1800000, 9, 77}, /* 2084 'M' */ + /* 51 */ + {0x40000000, 2, 110}, /* 2085 'n' */ + {0x20000000, 3, 114}, /* 2086 'r' */ + {0xa0000000, 3, 116}, /* 2087 't' */ + {0x00000000, 4, 109}, /* 2088 'm' */ + {0x90000000, 4, 115}, /* 2089 's' */ + {0xe0000000, 4, 32}, /* 2090 ' ' */ + {0xf0000000, 4, 108}, /* 2091 'l' */ + {0x18000000, 5, 100}, /* 2092 'd' */ + {0x80000000, 5, 105}, /* 2093 'i' */ + {0xc0000000, 5, 121}, /* 2094 'y' */ + {0xd0000000, 5, 99}, /* 2095 'c' */ + {0x10000000, 6, 112}, /* 2096 'p' */ + {0x88000000, 6, 117}, /* 2097 'u' */ + {0x8c000000, 6, 118}, /* 2098 'v' */ + {0xcc000000, 6, 103}, /* 2099 'g' */ + {0xd8000000, 6, 98}, /* 2100 'b' */ + {0xdc000000, 6, 107}, /* 2101 'k' */ + {0x14000000, 7, 119}, /* 2102 'w' */ + {0x17000000, 8, 122}, /* 2103 'z' */ + {0xc8000000, 8, 46}, /* 2104 '.' */ + {0xcb000000, 8, 102}, /* 2105 'f' */ + {0x16000000, 9, 44}, /* 2106 ',' */ + {0x16800000, 9, 39}, /* 2107 '\'' */ + {0xc9800000, 9, 101}, /* 2108 'e' */ + {0xca800000, 9, 104}, /* 2109 'h' */ + {0xca400000, 10, 120}, /* 2110 'x' */ + {0xc9000000, 11, 97}, /* 2111 'a' */ + {0xc9200000, 11, 45}, /* 2112 '-' */ + {0xc9600000, 11, 106}, /* 2113 'j' */ + {0xca000000, 11, 58}, /* 2114 ':' */ + {0xca200000, 11, 111}, /* 2115 'o' */ + {0xc9400000, 12, 113}, /* 2116 'q' */ + {0xc9500000, 14, 33}, /* 2117 '!' */ + {0xc95c0000, 14, 63}, /* 2118 '?' */ + {0xc9540000, 16, 1}, /* 2119 '0x01' */ + {0xc9560000, 16, 59}, /* 2120 ';' */ + {0xc9570000, 16, 41}, /* 2121 ')' */ + {0xc9590000, 16, 47}, /* 2122 '/' */ + {0xc95b0000, 16, 64}, /* 2123 '@' */ + {0xc9550000, 17, 74}, /* 2124 'J' */ + {0xc9558000, 17, 93}, /* 2125 ']' */ + {0xc95a0000, 17, 78}, /* 2126 'N' */ + {0xc95a8000, 17, 76}, /* 2127 'L' */ + {0xc9580000, 18, 82}, /* 2128 'R' */ + {0xc9584000, 18, 83}, /* 2129 'S' */ + {0xc9588000, 18, 86}, /* 2130 'V' */ + {0xc958c000, 20, 91}, /* 2131 '[' */ + {0xc958e000, 20, 80}, /* 2132 'P' */ + {0xc958f000, 20, 0}, /* 2133 '0x00' */ + {0xc958d000, 21, 87}, /* 2134 'W' */ + {0xc958d800, 21, 49}, /* 2135 '1' */ + /* 39 */ + {0x00000000, 2, 101}, /* 2136 'e' */ + {0x40000000, 3, 117}, /* 2137 'u' */ + {0x60000000, 3, 97}, /* 2138 'a' */ + {0x80000000, 3, 121}, /* 2139 'y' */ + {0xa0000000, 3, 111}, /* 2140 'o' */ + {0xc0000000, 4, 108}, /* 2141 'l' */ + {0xe0000000, 4, 114}, /* 2142 'r' */ + {0xf0000000, 4, 105}, /* 2143 'i' */ + {0xd0000000, 6, 115}, /* 2144 's' */ + {0xd8000000, 6, 32}, /* 2145 ' ' */ + {0xdc000000, 6, 98}, /* 2146 'b' */ + {0xd5000000, 8, 99}, /* 2147 'c' */ + {0xd4000000, 9, 106}, /* 2148 'j' */ + {0xd6000000, 9, 44}, /* 2149 ',' */ + {0xd6800000, 9, 46}, /* 2150 '.' */ + {0xd4c00000, 10, 39}, /* 2151 '\'' */ + {0xd7c00000, 10, 116}, /* 2152 't' */ + {0xd4a00000, 11, 58}, /* 2153 ':' */ + {0xd7000000, 11, 119}, /* 2154 'w' */ + {0xd7200000, 11, 100}, /* 2155 'd' */ + {0xd7400000, 11, 104}, /* 2156 'h' */ + {0xd7600000, 11, 38}, /* 2157 '&' */ + {0xd7a00000, 11, 45}, /* 2158 '-' */ + {0xd7800000, 12, 109}, /* 2159 'm' */ + {0xd7900000, 12, 110}, /* 2160 'n' */ + {0xd4800000, 13, 63}, /* 2161 '?' */ + {0xd4900000, 13, 118}, /* 2162 'v' */ + {0xd4880000, 14, 102}, /* 2163 'f' */ + {0xd49c0000, 14, 112}, /* 2164 'p' */ + {0xd48e0000, 15, 59}, /* 2165 ';' */ + {0xd49a0000, 15, 68}, /* 2166 'D' */ + {0xd48c0000, 16, 47}, /* 2167 '/' */ + {0xd4990000, 16, 64}, /* 2168 '@' */ + {0xd48d0000, 17, 88}, /* 2169 'X' */ + {0xd48d8000, 17, 34}, /* 2170 '\"' */ + {0xd4988000, 17, 107}, /* 2171 'k' */ + {0xd4980000, 18, 0}, /* 2172 '0x00' */ + {0xd4984000, 19, 1}, /* 2173 '0x01' */ + {0xd4986000, 19, 33}, /* 2174 '!' */ + /* 57 */ + {0x00000000, 2, 111}, /* 2175 'o' */ + {0x60000000, 3, 97}, /* 2176 'a' */ + {0x80000000, 3, 101}, /* 2177 'e' */ + {0xc0000000, 3, 104}, /* 2178 'h' */ + {0x40000000, 4, 105}, /* 2179 'i' */ + {0x50000000, 4, 108}, /* 2180 'l' */ + {0xb0000000, 4, 107}, /* 2181 'k' */ + {0xf0000000, 4, 116}, /* 2182 't' */ + {0xa0000000, 5, 117}, /* 2183 'u' */ + {0xa8000000, 5, 114}, /* 2184 'r' */ + {0xe0000000, 5, 32}, /* 2185 ' ' */ + {0xe8000000, 7, 121}, /* 2186 'y' */ + {0xea000000, 7, 99}, /* 2187 'c' */ + {0xed000000, 8, 115}, /* 2188 's' */ + {0xee000000, 8, 46}, /* 2189 '.' */ + {0xef800000, 9, 44}, /* 2190 ',' */ + {0xec400000, 10, 71}, /* 2191 'G' */ + {0xec200000, 11, 110}, /* 2192 'n' */ + {0xecc00000, 11, 68}, /* 2193 'D' */ + {0xef000000, 11, 75}, /* 2194 'K' */ + {0xef600000, 11, 67}, /* 2195 'C' */ + {0xec000000, 12, 58}, /* 2196 ':' */ + {0xec900000, 12, 45}, /* 2197 '-' */ + {0xeca00000, 12, 65}, /* 2198 'A' */ + {0xece00000, 12, 76}, /* 2199 'L' */ + {0xecf00000, 12, 39}, /* 2200 '\'' */ + {0xef200000, 12, 100}, /* 2201 'd' */ + {0xef400000, 12, 113}, /* 2202 'q' */ + {0xef500000, 12, 73}, /* 2203 'I' */ + {0xec800000, 13, 78}, /* 2204 'N' */ + {0xec880000, 13, 122}, /* 2205 'z' */ + {0xef380000, 13, 70}, /* 2206 'F' */ + {0xec140000, 14, 119}, /* 2207 'w' */ + {0xec1c0000, 14, 69}, /* 2208 'E' */ + {0xecb00000, 14, 63}, /* 2209 '?' */ + {0xef300000, 14, 77}, /* 2210 'M' */ + {0xef340000, 14, 83}, /* 2211 'S' */ + {0xec100000, 15, 98}, /* 2212 'b' */ + {0xec120000, 15, 1}, /* 2213 '0x01' */ + {0xec180000, 15, 33}, /* 2214 '!' */ + {0xecb40000, 15, 81}, /* 2215 'Q' */ + {0xecb60000, 15, 80}, /* 2216 'P' */ + {0xecb80000, 15, 59}, /* 2217 ';' */ + {0xecbc0000, 15, 66}, /* 2218 'B' */ + {0xec1b0000, 16, 86}, /* 2219 'V' */ + {0xecbb0000, 16, 109}, /* 2220 'm' */ + {0xecbe0000, 16, 47}, /* 2221 '/' */ + {0xec1a8000, 17, 41}, /* 2222 ')' */ + {0xecba0000, 17, 85}, /* 2223 'U' */ + {0xecbf0000, 17, 87}, /* 2224 'W' */ + {0xec1a0000, 18, 112}, /* 2225 'p' */ + {0xec1a4000, 18, 72}, /* 2226 'H' */ + {0xecba8000, 18, 0}, /* 2227 '0x00' */ + {0xecbf8000, 18, 82}, /* 2228 'R' */ + {0xecbfc000, 18, 84}, /* 2229 'T' */ + {0xecbac000, 19, 93}, /* 2230 ']' */ + {0xecbae000, 19, 91}, /* 2231 '[' */ + /* 46 */ + {0x00000000, 1, 32}, /* 2232 ' ' */ + {0xa0000000, 3, 101}, /* 2233 'e' */ + {0xc0000000, 4, 97}, /* 2234 'a' */ + {0xe0000000, 4, 105}, /* 2235 'i' */ + {0x88000000, 5, 46}, /* 2236 '.' */ + {0x98000000, 5, 111}, /* 2237 'o' */ + {0xd8000000, 5, 114}, /* 2238 'r' */ + {0xf8000000, 5, 115}, /* 2239 's' */ + {0x84000000, 6, 100}, /* 2240 'd' */ + {0x94000000, 6, 108}, /* 2241 'l' */ + {0xd0000000, 6, 117}, /* 2242 'u' */ + {0xf4000000, 6, 121}, /* 2243 'y' */ + {0x92000000, 7, 45}, /* 2244 '-' */ + {0xd6000000, 7, 118}, /* 2245 'v' */ + {0xf0000000, 7, 103}, /* 2246 'g' */ + {0xf2000000, 7, 44}, /* 2247 ',' */ + {0x80000000, 8, 104}, /* 2248 'h' */ + {0x81000000, 8, 58}, /* 2249 ':' */ + {0x82000000, 8, 109}, /* 2250 'm' */ + {0x90000000, 8, 119}, /* 2251 'w' */ + {0x91000000, 8, 110}, /* 2252 'n' */ + {0xd5000000, 8, 39}, /* 2253 '\'' */ + {0x83800000, 9, 102}, /* 2254 'f' */ + {0xd4400000, 10, 63}, /* 2255 '?' */ + {0xd4800000, 10, 98}, /* 2256 'b' */ + {0xd4c00000, 10, 99}, /* 2257 'c' */ + {0x83000000, 11, 33}, /* 2258 '!' */ + {0xd4000000, 11, 112}, /* 2259 'p' */ + {0xd4200000, 11, 116}, /* 2260 't' */ + {0x83200000, 12, 0}, /* 2261 '0x00' */ + {0x83300000, 12, 41}, /* 2262 ')' */ + {0x83400000, 12, 107}, /* 2263 'k' */ + {0x83500000, 12, 59}, /* 2264 ';' */ + {0x83700000, 12, 47}, /* 2265 '/' */ + {0x83680000, 14, 34}, /* 2266 '\"' */ + {0x836c0000, 14, 106}, /* 2267 'j' */ + {0x83600000, 15, 122}, /* 2268 'z' */ + {0x83660000, 15, 113}, /* 2269 'q' */ + {0x83630000, 16, 64}, /* 2270 '@' */ + {0x83640000, 16, 1}, /* 2271 '0x01' */ + {0x83628000, 17, 67}, /* 2272 'C' */ + {0x83650000, 17, 93}, /* 2273 ']' */ + {0x83620000, 18, 90}, /* 2274 'Z' */ + {0x83624000, 18, 91}, /* 2275 '[' */ + {0x83658000, 18, 84}, /* 2276 'T' */ + {0x8365c000, 18, 96}, /* 2277 '`' */ + /* 61 */ + {0x80000000, 2, 32}, /* 2278 ' ' */ + {0x40000000, 3, 115}, /* 2279 's' */ + {0xc0000000, 3, 114}, /* 2280 'r' */ + {0x00000000, 4, 100}, /* 2281 'd' */ + {0x30000000, 4, 97}, /* 2282 'a' */ + {0xf0000000, 4, 110}, /* 2283 'n' */ + {0x10000000, 5, 99}, /* 2284 'c' */ + {0x60000000, 5, 101}, /* 2285 'e' */ + {0x68000000, 5, 119}, /* 2286 'w' */ + {0x78000000, 5, 116}, /* 2287 't' */ + {0xe0000000, 5, 108}, /* 2288 'l' */ + {0x18000000, 6, 120}, /* 2289 'x' */ + {0x20000000, 6, 118}, /* 2290 'v' */ + {0x24000000, 6, 105}, /* 2291 'i' */ + {0x28000000, 6, 121}, /* 2292 'y' */ + {0x70000000, 6, 109}, /* 2293 'm' */ + {0xe8000000, 6, 46}, /* 2294 '.' */ + {0x1c000000, 7, 102}, /* 2295 'f' */ + {0x2e000000, 7, 98}, /* 2296 'b' */ + {0x74000000, 7, 44}, /* 2297 ',' */ + {0xec000000, 7, 112}, /* 2298 'p' */ + {0x1e000000, 8, 45}, /* 2299 '-' */ + {0x1f000000, 8, 104}, /* 2300 'h' */ + {0x2c000000, 8, 107}, /* 2301 'k' */ + {0x76000000, 8, 39}, /* 2302 '\'' */ + {0xee000000, 8, 103}, /* 2303 'g' */ + {0xef000000, 8, 111}, /* 2304 'o' */ + {0x2d800000, 9, 58}, /* 2305 ':' */ + {0x2d000000, 10, 41}, /* 2306 ')' */ + {0x2d400000, 10, 113}, /* 2307 'q' */ + {0x77400000, 10, 63}, /* 2308 '?' */ + {0x77800000, 10, 117}, /* 2309 'u' */ + {0x77000000, 11, 122}, /* 2310 'z' */ + {0x77c00000, 11, 33}, /* 2311 '!' */ + {0x77e00000, 12, 0}, /* 2312 '0x00' */ + {0x77f00000, 12, 106}, /* 2313 'j' */ + {0x77300000, 13, 47}, /* 2314 '/' */ + {0x77240000, 14, 52}, /* 2315 '4' */ + {0x77280000, 14, 66}, /* 2316 'B' */ + {0x77380000, 14, 93}, /* 2317 ']' */ + {0x773c0000, 14, 59}, /* 2318 ';' */ + {0x77200000, 15, 34}, /* 2319 '\"' */ + {0x77230000, 16, 68}, /* 2320 'D' */ + {0x772c0000, 16, 1}, /* 2321 '0x01' */ + {0x772e0000, 16, 64}, /* 2322 '@' */ + {0x77220000, 17, 84}, /* 2323 'T' */ + {0x77228000, 17, 67}, /* 2324 'C' */ + {0x772d8000, 17, 91}, /* 2325 '[' */ + {0x772f8000, 17, 76}, /* 2326 'L' */ + {0x772d0000, 18, 86}, /* 2327 'V' */ + {0x772d4000, 18, 71}, /* 2328 'G' */ + {0x772f0000, 18, 49}, /* 2329 '1' */ + {0x772f5000, 20, 69}, /* 2330 'E' */ + {0x772f4000, 21, 50}, /* 2331 '2' */ + {0x772f4800, 21, 78}, /* 2332 'N' */ + {0x772f6000, 21, 70}, /* 2333 'F' */ + {0x772f6800, 21, 65}, /* 2334 'A' */ + {0x772f7000, 22, 92}, /* 2335 '\\' */ + {0x772f7400, 22, 80}, /* 2336 'P' */ + {0x772f7800, 22, 77}, /* 2337 'M' */ + {0x772f7c00, 22, 72}, /* 2338 'H' */ + /* 35 */ + {0x00000000, 2, 111}, /* 2339 'o' */ + {0x80000000, 2, 32}, /* 2340 ' ' */ + {0x40000000, 3, 105}, /* 2341 'i' */ + {0xc0000000, 3, 114}, /* 2342 'r' */ + {0x70000000, 4, 97}, /* 2343 'a' */ + {0xe0000000, 4, 101}, /* 2344 'e' */ + {0x60000000, 5, 116}, /* 2345 't' */ + {0xf0000000, 5, 117}, /* 2346 'u' */ + {0xf8000000, 5, 102}, /* 2347 'f' */ + {0x6c000000, 6, 108}, /* 2348 'l' */ + {0x68000000, 8, 115}, /* 2349 's' */ + {0x69000000, 8, 121}, /* 2350 'y' */ + {0x6b000000, 9, 46}, /* 2351 '.' */ + {0x6a000000, 10, 63}, /* 2352 '?' */ + {0x6ac00000, 10, 44}, /* 2353 ',' */ + {0x6bc00000, 10, 45}, /* 2354 '-' */ + {0x6a600000, 11, 58}, /* 2355 ':' */ + {0x6a800000, 11, 39}, /* 2356 '\'' */ + {0x6aa00000, 11, 103}, /* 2357 'g' */ + {0x6a400000, 12, 109}, /* 2358 'm' */ + {0x6b800000, 12, 1}, /* 2359 '0x01' */ + {0x6ba00000, 12, 98}, /* 2360 'b' */ + {0x6bb00000, 12, 110}, /* 2361 'n' */ + {0x6a580000, 13, 99}, /* 2362 'c' */ + {0x6b900000, 13, 33}, /* 2363 '!' */ + {0x6b980000, 14, 41}, /* 2364 ')' */ + {0x6b9c0000, 14, 119}, /* 2365 'w' */ + {0x6a520000, 15, 112}, /* 2366 'p' */ + {0x6a540000, 15, 47}, /* 2367 '/' */ + {0x6a500000, 16, 104}, /* 2368 'h' */ + {0x6a560000, 16, 59}, /* 2369 ';' */ + {0x6a510000, 17, 0}, /* 2370 '0x00' */ + {0x6a518000, 17, 100}, /* 2371 'd' */ + {0x6a570000, 17, 107}, /* 2372 'k' */ + {0x6a578000, 17, 118}, /* 2373 'v' */ + /* 40 */ + {0xc0000000, 2, 32}, /* 2374 ' ' */ + {0x00000000, 3, 97}, /* 2375 'a' */ + {0x40000000, 3, 104}, /* 2376 'h' */ + {0xa0000000, 3, 101}, /* 2377 'e' */ + {0x30000000, 4, 117}, /* 2378 'u' */ + {0x60000000, 4, 114}, /* 2379 'r' */ + {0x80000000, 4, 105}, /* 2380 'i' */ + {0x70000000, 5, 108}, /* 2381 'l' */ + {0x90000000, 5, 115}, /* 2382 's' */ + {0x98000000, 5, 111}, /* 2383 'o' */ + {0x24000000, 6, 44}, /* 2384 ',' */ + {0x28000000, 6, 110}, /* 2385 'n' */ + {0x78000000, 6, 103}, /* 2386 'g' */ + {0x7c000000, 6, 46}, /* 2387 '.' */ + {0x2c000000, 7, 121}, /* 2388 'y' */ + {0x21000000, 8, 39}, /* 2389 '\'' */ + {0x22000000, 8, 45}, /* 2390 '-' */ + {0x23000000, 8, 58}, /* 2391 ':' */ + {0x20000000, 9, 100}, /* 2392 'd' */ + {0x2e800000, 9, 98}, /* 2393 'b' */ + {0x2f000000, 9, 116}, /* 2394 't' */ + {0x2f800000, 9, 119}, /* 2395 'w' */ + {0x20800000, 10, 63}, /* 2396 '?' */ + {0x20c00000, 10, 109}, /* 2397 'm' */ + {0x2e200000, 11, 33}, /* 2398 '!' */ + {0x2e600000, 11, 102}, /* 2399 'f' */ + {0x2e100000, 12, 59}, /* 2400 ';' */ + {0x2e500000, 12, 0}, /* 2401 '0x00' */ + {0x2e000000, 13, 107}, /* 2402 'k' */ + {0x2e400000, 13, 112}, /* 2403 'p' */ + {0x2e080000, 14, 41}, /* 2404 ')' */ + {0x2e0c0000, 14, 34}, /* 2405 '\"' */ + {0x2e4a0000, 15, 99}, /* 2406 'c' */ + {0x2e4e0000, 15, 47}, /* 2407 '/' */ + {0x2e480000, 16, 1}, /* 2408 '0x01' */ + {0x2e4c0000, 16, 93}, /* 2409 ']' */ + {0x2e4d0000, 16, 122}, /* 2410 'z' */ + {0x2e490000, 17, 96}, /* 2411 '`' */ + {0x2e498000, 18, 118}, /* 2412 'v' */ + {0x2e49c000, 18, 64}, /* 2413 '@' */ + /* 41 */ + {0x00000000, 1, 101}, /* 2414 'e' */ + {0x80000000, 3, 111}, /* 2415 'o' */ + {0xa0000000, 3, 105}, /* 2416 'i' */ + {0xc0000000, 3, 32}, /* 2417 ' ' */ + {0xf0000000, 4, 97}, /* 2418 'a' */ + {0xe4000000, 6, 114}, /* 2419 'r' */ + {0xec000000, 6, 116}, /* 2420 't' */ + {0xe1000000, 8, 121}, /* 2421 'y' */ + {0xe3000000, 8, 108}, /* 2422 'l' */ + {0xe8000000, 8, 46}, /* 2423 '.' */ + {0xe9000000, 8, 110}, /* 2424 'n' */ + {0xeb000000, 8, 117}, /* 2425 'u' */ + {0xe0000000, 9, 100}, /* 2426 'd' */ + {0xe2000000, 9, 115}, /* 2427 's' */ + {0xea000000, 9, 44}, /* 2428 ',' */ + {0xe0c00000, 10, 119}, /* 2429 'w' */ + {0xe2800000, 10, 39}, /* 2430 '\'' */ + {0xe2c00000, 10, 45}, /* 2431 '-' */ + {0xeaa00000, 11, 109}, /* 2432 'm' */ + {0xeac00000, 11, 58}, /* 2433 ':' */ + {0xeae00000, 11, 98}, /* 2434 'b' */ + {0xe0900000, 12, 99}, /* 2435 'c' */ + {0xe0b00000, 12, 63}, /* 2436 '?' */ + {0xea800000, 12, 33}, /* 2437 '!' */ + {0xe0800000, 13, 41}, /* 2438 ')' */ + {0xe0a00000, 13, 104}, /* 2439 'h' */ + {0xe0a80000, 13, 107}, /* 2440 'k' */ + {0xea980000, 13, 102}, /* 2441 'f' */ + {0xea940000, 14, 103}, /* 2442 'g' */ + {0xe0880000, 15, 112}, /* 2443 'p' */ + {0xe08a0000, 15, 59}, /* 2444 ';' */ + {0xe08c0000, 15, 47}, /* 2445 '/' */ + {0xe08e0000, 15, 0}, /* 2446 '0x00' */ + {0xea920000, 15, 118}, /* 2447 'v' */ + {0xea900000, 16, 113}, /* 2448 'q' */ + {0xea910000, 17, 1}, /* 2449 '0x01' */ + {0xea918000, 18, 34}, /* 2450 '\"' */ + {0xea91c000, 20, 122}, /* 2451 'z' */ + {0xea91d000, 20, 106}, /* 2452 'j' */ + {0xea91e000, 20, 93}, /* 2453 ']' */ + {0xea91f000, 20, 42}, /* 2454 '*' */ + /* 44 */ + {0x80000000, 2, 110}, /* 2455 'n' */ + {0x00000000, 3, 116}, /* 2456 't' */ + {0x40000000, 3, 115}, /* 2457 's' */ + {0x30000000, 4, 108}, /* 2458 'l' */ + {0xc0000000, 4, 111}, /* 2459 'o' */ + {0xd0000000, 4, 99}, /* 2460 'c' */ + {0xf0000000, 4, 101}, /* 2461 'e' */ + {0x20000000, 5, 97}, /* 2462 'a' */ + {0x60000000, 5, 109}, /* 2463 'm' */ + {0x68000000, 5, 100}, /* 2464 'd' */ + {0x70000000, 5, 118}, /* 2465 'v' */ + {0xe0000000, 5, 103}, /* 2466 'g' */ + {0xe8000000, 5, 114}, /* 2467 'r' */ + {0x28000000, 6, 112}, /* 2468 'p' */ + {0x78000000, 6, 102}, /* 2469 'f' */ + {0x2c000000, 7, 122}, /* 2470 'z' */ + {0x7c000000, 7, 32}, /* 2471 ' ' */ + {0x2f000000, 8, 98}, /* 2472 'b' */ + {0x7e000000, 8, 107}, /* 2473 'k' */ + {0x2e000000, 9, 45}, /* 2474 '-' */ + {0x2e800000, 9, 120}, /* 2475 'x' */ + {0x7f000000, 10, 117}, /* 2476 'u' */ + {0x7f800000, 10, 113}, /* 2477 'q' */ + {0x7f400000, 11, 46}, /* 2478 '.' */ + {0x7fc00000, 11, 44}, /* 2479 ',' */ + {0x7f700000, 12, 119}, /* 2480 'w' */ + {0x7ff00000, 12, 39}, /* 2481 '\'' */ + {0x7f680000, 13, 105}, /* 2482 'i' */ + {0x7fe80000, 13, 106}, /* 2483 'j' */ + {0x7f640000, 14, 58}, /* 2484 ':' */ + {0x7fe00000, 14, 104}, /* 2485 'h' */ + {0x7f600000, 15, 47}, /* 2486 '/' */ + {0x7fe60000, 15, 121}, /* 2487 'y' */ + {0x7f630000, 16, 63}, /* 2488 '?' */ + {0x7fe40000, 16, 80}, /* 2489 'P' */ + {0x7f628000, 17, 82}, /* 2490 'R' */ + {0x7fe58000, 17, 33}, /* 2491 '!' */ + {0x7fe50000, 18, 41}, /* 2492 ')' */ + {0x7fe54000, 18, 83}, /* 2493 'S' */ + {0x7f620000, 19, 0}, /* 2494 '0x00' */ + {0x7f622000, 19, 67}, /* 2495 'C' */ + {0x7f624000, 19, 1}, /* 2496 '0x01' */ + {0x7f626000, 20, 68}, /* 2497 'D' */ + {0x7f627000, 20, 59}, /* 2498 ';' */ + /* 14 */ + {0x00000000, 1, 111}, /* 2499 'o' */ + {0xc0000000, 2, 117}, /* 2500 'u' */ + {0xa0000000, 3, 97}, /* 2501 'a' */ + {0x90000000, 4, 101}, /* 2502 'e' */ + {0x80000000, 5, 105}, /* 2503 'i' */ + {0x8c000000, 6, 121}, /* 2504 'y' */ + {0x8a000000, 7, 32}, /* 2505 ' ' */ + {0x89000000, 8, 46}, /* 2506 '.' */ + {0x88000000, 9, 39}, /* 2507 '\'' */ + {0x88c00000, 10, 116}, /* 2508 't' */ + {0x88800000, 11, 110}, /* 2509 'n' */ + {0x88b00000, 12, 115}, /* 2510 's' */ + {0x88a00000, 13, 1}, /* 2511 '0x01' */ + {0x88a80000, 13, 104}, /* 2512 'h' */ + /* 40 */ + {0x80000000, 2, 32}, /* 2513 ' ' */ + {0xc0000000, 2, 101}, /* 2514 'e' */ + {0x00000000, 3, 115}, /* 2515 's' */ + {0x60000000, 3, 105}, /* 2516 'i' */ + {0x20000000, 4, 46}, /* 2517 '.' */ + {0x48000000, 5, 121}, /* 2518 'y' */ + {0x30000000, 6, 39}, /* 2519 '\'' */ + {0x34000000, 6, 97}, /* 2520 'a' */ + {0x38000000, 6, 112}, /* 2521 'p' */ + {0x3c000000, 6, 44}, /* 2522 ',' */ + {0x50000000, 6, 108}, /* 2523 'l' */ + {0x54000000, 6, 102}, /* 2524 'f' */ + {0x58000000, 6, 110}, /* 2525 'n' */ + {0x40000000, 7, 47}, /* 2526 '/' */ + {0x44000000, 7, 45}, /* 2527 '-' */ + {0x46000000, 7, 111}, /* 2528 'o' */ + {0x5d000000, 8, 58}, /* 2529 ':' */ + {0x43800000, 9, 98}, /* 2530 'b' */ + {0x5c000000, 9, 119}, /* 2531 'w' */ + {0x5c800000, 9, 109}, /* 2532 'm' */ + {0x5e000000, 9, 104}, /* 2533 'h' */ + {0x5f000000, 9, 117}, /* 2534 'u' */ + {0x5f800000, 9, 107}, /* 2535 'k' */ + {0x42000000, 10, 114}, /* 2536 'r' */ + {0x42400000, 10, 1}, /* 2537 '0x01' */ + {0x42800000, 10, 63}, /* 2538 '?' */ + {0x43000000, 10, 116}, /* 2539 't' */ + {0x43400000, 10, 103}, /* 2540 'g' */ + {0x5ec00000, 10, 100}, /* 2541 'd' */ + {0x42c00000, 11, 106}, /* 2542 'j' */ + {0x42e00000, 12, 41}, /* 2543 ')' */ + {0x5e800000, 12, 59}, /* 2544 ';' */ + {0x5e900000, 12, 99}, /* 2545 'c' */ + {0x5ea00000, 12, 83}, /* 2546 'S' */ + {0x42f00000, 13, 118}, /* 2547 'v' */ + {0x42f80000, 13, 82}, /* 2548 'R' */ + {0x5eb00000, 13, 33}, /* 2549 '!' */ + {0x5eb80000, 14, 64}, /* 2550 '@' */ + {0x5ebc0000, 15, 34}, /* 2551 '\"' */ + {0x5ebe0000, 15, 0}, /* 2552 '0x00' */ + /* 43 */ + {0x40000000, 3, 97}, /* 2553 'a' */ + {0x60000000, 3, 105}, /* 2554 'i' */ + {0x80000000, 3, 108}, /* 2555 'l' */ + {0xc0000000, 3, 101}, /* 2556 'e' */ + {0xe0000000, 3, 32}, /* 2557 ' ' */ + {0x00000000, 4, 117}, /* 2558 'u' */ + {0x10000000, 4, 100}, /* 2559 'd' */ + {0x20000000, 4, 121}, /* 2560 'y' */ + {0xb0000000, 4, 111}, /* 2561 'o' */ + {0xa0000000, 5, 115}, /* 2562 's' */ + {0x30000000, 6, 46}, /* 2563 '.' */ + {0x38000000, 6, 116}, /* 2564 't' */ + {0x34000000, 7, 118}, /* 2565 'v' */ + {0x3c000000, 7, 102}, /* 2566 'f' */ + {0xa8000000, 7, 109}, /* 2567 'm' */ + {0xaa000000, 7, 107}, /* 2568 'k' */ + {0xac000000, 7, 112}, /* 2569 'p' */ + {0x37000000, 8, 99}, /* 2570 'c' */ + {0x3e000000, 8, 45}, /* 2571 '-' */ + {0xaf000000, 8, 44}, /* 2572 ',' */ + {0x36800000, 9, 58}, /* 2573 ':' */ + {0x3f800000, 9, 98}, /* 2574 'b' */ + {0xae000000, 9, 39}, /* 2575 '\'' */ + {0x36000000, 10, 114}, /* 2576 'r' */ + {0x36400000, 10, 104}, /* 2577 'h' */ + {0x3f000000, 10, 110}, /* 2578 'n' */ + {0x3f400000, 10, 103}, /* 2579 'g' */ + {0xaec00000, 10, 119}, /* 2580 'w' */ + {0xae800000, 11, 63}, /* 2581 '?' */ + {0xaea00000, 13, 33}, /* 2582 '!' */ + {0xaeb00000, 13, 122}, /* 2583 'z' */ + {0xaeac0000, 14, 47}, /* 2584 '/' */ + {0xaea80000, 15, 59}, /* 2585 ';' */ + {0xaeb80000, 15, 69}, /* 2586 'E' */ + {0xaeba0000, 15, 42}, /* 2587 '*' */ + {0xaebe0000, 15, 0}, /* 2588 '0x00' */ + {0xaeab0000, 16, 1}, /* 2589 '0x01' */ + {0xaebc0000, 16, 41}, /* 2590 ')' */ + {0xaeaa0000, 17, 64}, /* 2591 '@' */ + {0xaeaa8000, 17, 106}, /* 2592 'j' */ + {0xaebd0000, 17, 34}, /* 2593 '\"' */ + {0xaebd8000, 18, 91}, /* 2594 '[' */ + {0xaebdc000, 18, 93}, /* 2595 ']' */ + /* 40 */ + {0x00000000, 2, 97}, /* 2596 'a' */ + {0x40000000, 2, 101}, /* 2597 'e' */ + {0xe0000000, 3, 32}, /* 2598 ' ' */ + {0x90000000, 4, 112}, /* 2599 'p' */ + {0xb0000000, 4, 111}, /* 2600 'o' */ + {0xc0000000, 4, 105}, /* 2601 'i' */ + {0x80000000, 5, 46}, /* 2602 '.' */ + {0x88000000, 5, 115}, /* 2603 's' */ + {0xd0000000, 5, 117}, /* 2604 'u' */ + {0xd8000000, 5, 109}, /* 2605 'm' */ + {0xa4000000, 6, 121}, /* 2606 'y' */ + {0xac000000, 6, 98}, /* 2607 'b' */ + {0xa0000000, 7, 44}, /* 2608 ',' */ + {0xa8000000, 7, 47}, /* 2609 '/' */ + {0xa2000000, 8, 93}, /* 2610 ']' */ + {0xa3000000, 9, 58}, /* 2611 ':' */ + {0xaa000000, 9, 39}, /* 2612 '\'' */ + {0xa3c00000, 10, 114}, /* 2613 'r' */ + {0xaac00000, 10, 102}, /* 2614 'f' */ + {0xab000000, 10, 108}, /* 2615 'l' */ + {0xab800000, 10, 110}, /* 2616 'n' */ + {0xa3800000, 11, 63}, /* 2617 '?' */ + {0xa3a00000, 11, 33}, /* 2618 '!' */ + {0xaa800000, 11, 0}, /* 2619 '0x00' */ + {0xaaa00000, 11, 119}, /* 2620 'w' */ + {0xab600000, 11, 104}, /* 2621 'h' */ + {0xabc00000, 11, 45}, /* 2622 '-' */ + {0xabe00000, 12, 52}, /* 2623 '4' */ + {0xab500000, 13, 116}, /* 2624 't' */ + {0xab580000, 13, 64}, /* 2625 '@' */ + {0xabf00000, 13, 59}, /* 2626 ';' */ + {0xabf80000, 13, 99}, /* 2627 'c' */ + {0xab400000, 14, 41}, /* 2628 ')' */ + {0xab440000, 14, 1}, /* 2629 '0x01' */ + {0xab4c0000, 14, 100}, /* 2630 'd' */ + {0xab4a0000, 15, 103}, /* 2631 'g' */ + {0xab480000, 17, 91}, /* 2632 '[' */ + {0xab488000, 17, 118}, /* 2633 'v' */ + {0xab490000, 17, 107}, /* 2634 'k' */ + {0xab498000, 17, 122}, /* 2635 'z' */ + /* 44 */ + {0x40000000, 2, 32}, /* 2636 ' ' */ + {0x20000000, 3, 116}, /* 2637 't' */ + {0x80000000, 3, 103}, /* 2638 'g' */ + {0xe0000000, 3, 100}, /* 2639 'd' */ + {0x00000000, 4, 115}, /* 2640 's' */ + {0xa0000000, 4, 97}, /* 2641 'a' */ + {0xd0000000, 4, 101}, /* 2642 'e' */ + {0xb0000000, 5, 99}, /* 2643 'c' */ + {0xc0000000, 5, 105}, /* 2644 'i' */ + {0x1c000000, 6, 46}, /* 2645 '.' */ + {0xbc000000, 6, 110}, /* 2646 'n' */ + {0xcc000000, 6, 111}, /* 2647 'o' */ + {0x12000000, 7, 117}, /* 2648 'u' */ + {0x16000000, 7, 118}, /* 2649 'v' */ + {0x18000000, 7, 102}, /* 2650 'f' */ + {0xb8000000, 7, 107}, /* 2651 'k' */ + {0xba000000, 7, 39}, /* 2652 '\'' */ + {0xc8000000, 7, 121}, /* 2653 'y' */ + {0xca000000, 7, 44}, /* 2654 ',' */ + {0x10000000, 8, 109}, /* 2655 'm' */ + {0x14000000, 8, 108}, /* 2656 'l' */ + {0x15000000, 8, 45}, /* 2657 '-' */ + {0x11800000, 9, 119}, /* 2658 'w' */ + {0x1a800000, 9, 58}, /* 2659 ':' */ + {0x11400000, 10, 122}, /* 2660 'z' */ + {0x1a000000, 10, 104}, /* 2661 'h' */ + {0x1b000000, 10, 98}, /* 2662 'b' */ + {0x1b400000, 10, 106}, /* 2663 'j' */ + {0x1b800000, 10, 114}, /* 2664 'r' */ + {0x11000000, 11, 112}, /* 2665 'p' */ + {0x1a600000, 11, 120}, /* 2666 'x' */ + {0x1be00000, 11, 63}, /* 2667 '?' */ + {0x11300000, 12, 59}, /* 2668 ';' */ + {0x1a500000, 12, 41}, /* 2669 ')' */ + {0x1bc00000, 12, 33}, /* 2670 '!' */ + {0x1bd00000, 12, 113}, /* 2671 'q' */ + {0x11200000, 13, 47}, /* 2672 '/' */ + {0x11280000, 13, 0}, /* 2673 '0x00' */ + {0x1a400000, 13, 1}, /* 2674 '0x01' */ + {0x1a480000, 14, 66}, /* 2675 'B' */ + {0x1a4c0000, 16, 93}, /* 2676 ']' */ + {0x1a4d0000, 16, 34}, /* 2677 '\"' */ + {0x1a4e0000, 16, 64}, /* 2678 '@' */ + {0x1a4f0000, 16, 42}, /* 2679 '*' */ + /* 48 */ + {0x20000000, 3, 117}, /* 2680 'u' */ + {0x60000000, 3, 32}, /* 2681 ' ' */ + {0x80000000, 3, 114}, /* 2682 'r' */ + {0xe0000000, 3, 110}, /* 2683 'n' */ + {0x00000000, 4, 108}, /* 2684 'l' */ + {0xc0000000, 4, 109}, /* 2685 'm' */ + {0xd0000000, 4, 102}, /* 2686 'f' */ + {0x10000000, 5, 118}, /* 2687 'v' */ + {0x40000000, 5, 115}, /* 2688 's' */ + {0x48000000, 5, 112}, /* 2689 'p' */ + {0xa0000000, 5, 116}, /* 2690 't' */ + {0xa8000000, 5, 111}, /* 2691 'o' */ + {0xb8000000, 5, 119}, /* 2692 'w' */ + {0x18000000, 6, 107}, /* 2693 'k' */ + {0x1c000000, 6, 105}, /* 2694 'i' */ + {0x50000000, 6, 103}, /* 2695 'g' */ + {0x5c000000, 6, 99}, /* 2696 'c' */ + {0xb4000000, 6, 100}, /* 2697 'd' */ + {0x56000000, 7, 101}, /* 2698 'e' */ + {0x58000000, 7, 121}, /* 2699 'y' */ + {0x5a000000, 7, 97}, /* 2700 'a' */ + {0xb2000000, 7, 98}, /* 2701 'b' */ + {0x55000000, 8, 104}, /* 2702 'h' */ + {0xb0000000, 8, 46}, /* 2703 '.' */ + {0x54000000, 9, 45}, /* 2704 '-' */ + {0x54800000, 9, 44}, /* 2705 ',' */ + {0xb1400000, 10, 39}, /* 2706 '\'' */ + {0xb1c00000, 10, 120}, /* 2707 'x' */ + {0xb1200000, 11, 58}, /* 2708 ':' */ + {0xb1a00000, 11, 122}, /* 2709 'z' */ + {0xb1100000, 12, 63}, /* 2710 '?' */ + {0xb1900000, 12, 106}, /* 2711 'j' */ + {0xb1000000, 13, 33}, /* 2712 '!' */ + {0xb1880000, 13, 113}, /* 2713 'q' */ + {0xb1080000, 14, 74}, /* 2714 'J' */ + {0xb1800000, 14, 47}, /* 2715 '/' */ + {0xb1840000, 14, 41}, /* 2716 ')' */ + {0xb10d0000, 16, 59}, /* 2717 ';' */ + {0xb10e0000, 16, 71}, /* 2718 'G' */ + {0xb10c0000, 17, 34}, /* 2719 '\"' */ + {0xb10f0000, 17, 1}, /* 2720 '0x01' */ + {0xb10c8000, 18, 93}, /* 2721 ']' */ + {0xb10cc000, 18, 64}, /* 2722 '@' */ + {0xb10f8000, 19, 52}, /* 2723 '4' */ + {0xb10fa000, 19, 0}, /* 2724 '0x00' */ + {0xb10fc000, 19, 66}, /* 2725 'B' */ + {0xb10fe000, 20, 79}, /* 2726 'O' */ + {0xb10ff000, 20, 67}, /* 2727 'C' */ + /* 39 */ + {0x20000000, 3, 108}, /* 2728 'l' */ + {0x40000000, 3, 32}, /* 2729 ' ' */ + {0x60000000, 3, 111}, /* 2730 'o' */ + {0xa0000000, 3, 114}, /* 2731 'r' */ + {0xe0000000, 3, 101}, /* 2732 'e' */ + {0x00000000, 4, 112}, /* 2733 'p' */ + {0xc0000000, 4, 97}, /* 2734 'a' */ + {0xd0000000, 4, 105}, /* 2735 'i' */ + {0x18000000, 5, 116}, /* 2736 't' */ + {0x80000000, 5, 117}, /* 2737 'u' */ + {0x88000000, 5, 104}, /* 2738 'h' */ + {0x90000000, 5, 115}, /* 2739 's' */ + {0x14000000, 6, 109}, /* 2740 'm' */ + {0x12000000, 7, 100}, /* 2741 'd' */ + {0x9a000000, 7, 121}, /* 2742 'y' */ + {0x9c000000, 7, 46}, /* 2743 '.' */ + {0x9e000000, 7, 44}, /* 2744 ',' */ + {0x10000000, 8, 45}, /* 2745 '-' */ + {0x11800000, 9, 63}, /* 2746 '?' */ + {0x98800000, 9, 58}, /* 2747 ':' */ + {0x99000000, 10, 39}, /* 2748 '\'' */ + {0x99400000, 10, 93}, /* 2749 ']' */ + {0x99800000, 10, 43}, /* 2750 '+' */ + {0x99c00000, 10, 98}, /* 2751 'b' */ + {0x11200000, 11, 102}, /* 2752 'f' */ + {0x11400000, 11, 107}, /* 2753 'k' */ + {0x11600000, 11, 33}, /* 2754 '!' */ + {0x98200000, 11, 99}, /* 2755 'c' */ + {0x98400000, 11, 110}, /* 2756 'n' */ + {0x98600000, 11, 119}, /* 2757 'w' */ + {0x11000000, 12, 0}, /* 2758 '0x00' */ + {0x11100000, 12, 59}, /* 2759 ';' */ + {0x98100000, 12, 47}, /* 2760 '/' */ + {0x98080000, 13, 103}, /* 2761 'g' */ + {0x98040000, 14, 41}, /* 2762 ')' */ + {0x98020000, 15, 34}, /* 2763 '\"' */ + {0x98010000, 16, 83}, /* 2764 'S' */ + {0x98000000, 17, 1}, /* 2765 '0x01' */ + {0x98008000, 17, 66}, /* 2766 'B' */ + /* 13 */ + {0x80000000, 1, 117}, /* 2767 'u' */ + {0x00000000, 3, 44}, /* 2768 ',' */ + {0x20000000, 3, 46}, /* 2769 '.' */ + {0x60000000, 3, 32}, /* 2770 ' ' */ + {0x48000000, 5, 98}, /* 2771 'b' */ + {0x50000000, 5, 39}, /* 2772 '\'' */ + {0x58000000, 5, 105}, /* 2773 'i' */ + {0x44000000, 6, 97}, /* 2774 'a' */ + {0x40000000, 8, 63}, /* 2775 '?' */ + {0x41000000, 8, 58}, /* 2776 ':' */ + {0x43000000, 8, 41}, /* 2777 ')' */ + {0x42000000, 9, 1}, /* 2778 '0x01' */ + {0x42800000, 9, 119}, /* 2779 'w' */ + /* 47 */ + {0x00000000, 3, 97}, /* 2780 'a' */ + {0x20000000, 3, 111}, /* 2781 'o' */ + {0x80000000, 3, 105}, /* 2782 'i' */ + {0xc0000000, 3, 32}, /* 2783 ' ' */ + {0xe0000000, 3, 101}, /* 2784 'e' */ + {0x40000000, 4, 115}, /* 2785 's' */ + {0x50000000, 4, 116}, /* 2786 't' */ + {0x70000000, 5, 100}, /* 2787 'd' */ + {0xa0000000, 5, 110}, /* 2788 'n' */ + {0xa8000000, 5, 121}, /* 2789 'y' */ + {0x68000000, 6, 117}, /* 2790 'u' */ + {0x6c000000, 6, 109}, /* 2791 'm' */ + {0x7c000000, 6, 107}, /* 2792 'k' */ + {0xb4000000, 6, 108}, /* 2793 'l' */ + {0xb8000000, 6, 46}, /* 2794 '.' */ + {0xbc000000, 6, 114}, /* 2795 'r' */ + {0x60000000, 7, 102}, /* 2796 'f' */ + {0x64000000, 7, 44}, /* 2797 ',' */ + {0x66000000, 7, 118}, /* 2798 'v' */ + {0xb0000000, 7, 99}, /* 2799 'c' */ + {0xb2000000, 7, 103}, /* 2800 'g' */ + {0x63000000, 8, 39}, /* 2801 '\'' */ + {0x78000000, 8, 45}, /* 2802 '-' */ + {0x79000000, 8, 98}, /* 2803 'b' */ + {0x7b000000, 8, 112}, /* 2804 'p' */ + {0x62800000, 9, 58}, /* 2805 ':' */ + {0x7a000000, 9, 119}, /* 2806 'w' */ + {0x7a800000, 10, 63}, /* 2807 '?' */ + {0x7ac00000, 10, 104}, /* 2808 'h' */ + {0x62400000, 11, 33}, /* 2809 '!' */ + {0x62100000, 12, 113}, /* 2810 'q' */ + {0x62200000, 12, 106}, /* 2811 'j' */ + {0x62300000, 12, 0}, /* 2812 '0x00' */ + {0x62600000, 12, 47}, /* 2813 '/' */ + {0x62080000, 13, 59}, /* 2814 ';' */ + {0x62780000, 13, 41}, /* 2815 ')' */ + {0x62700000, 14, 56}, /* 2816 '8' */ + {0x62740000, 14, 122}, /* 2817 'z' */ + {0x62020000, 15, 34}, /* 2818 '\"' */ + {0x62060000, 15, 93}, /* 2819 ']' */ + {0x62000000, 16, 84}, /* 2820 'T' */ + {0x62040000, 16, 120}, /* 2821 'x' */ + {0x62050000, 16, 1}, /* 2822 '0x01' */ + {0x62018000, 17, 90}, /* 2823 'Z' */ + {0x62010000, 18, 42}, /* 2824 '*' */ + {0x62014000, 19, 68}, /* 2825 'D' */ + {0x62016000, 19, 66}, /* 2826 'B' */ + /* 45 */ + {0x00000000, 1, 32}, /* 2827 ' ' */ + {0xa0000000, 3, 116}, /* 2828 't' */ + {0x80000000, 4, 46}, /* 2829 '.' */ + {0xe0000000, 4, 101}, /* 2830 'e' */ + {0x98000000, 5, 44}, /* 2831 ',' */ + {0xc0000000, 5, 111}, /* 2832 'o' */ + {0xc8000000, 5, 115}, /* 2833 's' */ + {0xf0000000, 5, 104}, /* 2834 'h' */ + {0xf8000000, 5, 105}, /* 2835 'i' */ + {0x94000000, 6, 99}, /* 2836 'c' */ + {0xd0000000, 6, 117}, /* 2837 'u' */ + {0xd8000000, 6, 112}, /* 2838 'p' */ + {0xde000000, 7, 97}, /* 2839 'a' */ + {0x91000000, 8, 110}, /* 2840 'n' */ + {0x93000000, 8, 109}, /* 2841 'm' */ + {0xd4000000, 8, 121}, /* 2842 'y' */ + {0xd6000000, 8, 58}, /* 2843 ':' */ + {0xdc000000, 8, 108}, /* 2844 'l' */ + {0xdd000000, 8, 107}, /* 2845 'k' */ + {0x90800000, 9, 98}, /* 2846 'b' */ + {0x92000000, 9, 102}, /* 2847 'f' */ + {0xd5000000, 9, 119}, /* 2848 'w' */ + {0xd7800000, 9, 39}, /* 2849 '\'' */ + {0x90000000, 10, 33}, /* 2850 '!' */ + {0x90400000, 10, 103}, /* 2851 'g' */ + {0x92800000, 10, 114}, /* 2852 'r' */ + {0xd5800000, 10, 63}, /* 2853 '?' */ + {0xd5c00000, 10, 45}, /* 2854 '-' */ + {0xd7400000, 10, 113}, /* 2855 'q' */ + {0xd7200000, 11, 100}, /* 2856 'd' */ + {0x92c00000, 12, 47}, /* 2857 '/' */ + {0x92d00000, 12, 41}, /* 2858 ')' */ + {0x92f00000, 12, 0}, /* 2859 '0x00' */ + {0xd7000000, 12, 93}, /* 2860 ']' */ + {0xd7100000, 12, 59}, /* 2861 ';' */ + {0x92e80000, 13, 118}, /* 2862 'v' */ + {0x92e20000, 15, 34}, /* 2863 '\"' */ + {0x92e60000, 15, 122}, /* 2864 'z' */ + {0x92e00000, 16, 106}, /* 2865 'j' */ + {0x92e10000, 16, 1}, /* 2866 '0x01' */ + {0x92e40000, 16, 91}, /* 2867 '[' */ + {0x92e58000, 17, 64}, /* 2868 '@' */ + {0x92e54000, 18, 84}, /* 2869 'T' */ + {0x92e50000, 19, 120}, /* 2870 'x' */ + {0x92e52000, 19, 96}, /* 2871 '`' */ + /* 49 */ + {0x80000000, 2, 104}, /* 2872 'h' */ + {0x00000000, 3, 105}, /* 2873 'i' */ + {0x40000000, 3, 111}, /* 2874 'o' */ + {0x60000000, 3, 101}, /* 2875 'e' */ + {0xe0000000, 3, 32}, /* 2876 ' ' */ + {0x20000000, 4, 97}, /* 2877 'a' */ + {0x30000000, 5, 117}, /* 2878 'u' */ + {0xc8000000, 5, 114}, /* 2879 'r' */ + {0xd8000000, 5, 115}, /* 2880 's' */ + {0x3c000000, 6, 46}, /* 2881 '.' */ + {0xc4000000, 6, 116}, /* 2882 't' */ + {0xd0000000, 6, 121}, /* 2883 'y' */ + {0x3a000000, 7, 99}, /* 2884 'c' */ + {0xc2000000, 7, 108}, /* 2885 'l' */ + {0x39000000, 8, 45}, /* 2886 '-' */ + {0xc0000000, 8, 118}, /* 2887 'v' */ + {0xc1000000, 8, 109}, /* 2888 'm' */ + {0xd5000000, 8, 119}, /* 2889 'w' */ + {0xd6000000, 8, 44}, /* 2890 ',' */ + {0xd7000000, 8, 39}, /* 2891 '\'' */ + {0x38000000, 9, 110}, /* 2892 'n' */ + {0x38c00000, 10, 63}, /* 2893 '?' */ + {0xd4400000, 10, 98}, /* 2894 'b' */ + {0xd4800000, 10, 58}, /* 2895 ':' */ + {0x38800000, 11, 33}, /* 2896 '!' */ + {0xd4000000, 11, 122}, /* 2897 'z' */ + {0xd4c00000, 11, 100}, /* 2898 'd' */ + {0xd4e00000, 11, 102}, /* 2899 'f' */ + {0xd4200000, 12, 120}, /* 2900 'x' */ + {0x38a00000, 13, 103}, /* 2901 'g' */ + {0x38a80000, 13, 59}, /* 2902 ';' */ + {0xd4300000, 13, 112}, /* 2903 'p' */ + {0x38b00000, 14, 80}, /* 2904 'P' */ + {0x38b40000, 14, 0}, /* 2905 '0x00' */ + {0x38bc0000, 14, 41}, /* 2906 ')' */ + {0xd4380000, 14, 47}, /* 2907 '/' */ + {0xd43c0000, 14, 107}, /* 2908 'k' */ + {0x38b80000, 16, 64}, /* 2909 '@' */ + {0x38ba0000, 16, 69}, /* 2910 'E' */ + {0x38b98000, 17, 93}, /* 2911 ']' */ + {0x38bb8000, 17, 34}, /* 2912 '\"' */ + {0x38b90000, 18, 70}, /* 2913 'F' */ + {0x38bb0000, 18, 1}, /* 2914 '0x01' */ + {0x38b94000, 19, 106}, /* 2915 'j' */ + {0x38bb4000, 19, 49}, /* 2916 '1' */ + {0x38bb6000, 19, 91}, /* 2917 '[' */ + {0x38b96000, 20, 92}, /* 2918 '\\' */ + {0x38b97000, 21, 75}, /* 2919 'K' */ + {0x38b97800, 21, 67}, /* 2920 'C' */ + /* 43 */ + {0x60000000, 3, 116}, /* 2921 't' */ + {0xa0000000, 3, 110}, /* 2922 'n' */ + {0xc0000000, 3, 115}, /* 2923 's' */ + {0xe0000000, 3, 114}, /* 2924 'r' */ + {0x10000000, 4, 100}, /* 2925 'd' */ + {0x20000000, 4, 101}, /* 2926 'e' */ + {0x50000000, 4, 108}, /* 2927 'l' */ + {0x80000000, 4, 112}, /* 2928 'p' */ + {0x00000000, 5, 98}, /* 2929 'b' */ + {0x08000000, 5, 32}, /* 2930 ' ' */ + {0x30000000, 5, 105}, /* 2931 'i' */ + {0x40000000, 5, 97}, /* 2932 'a' */ + {0x48000000, 5, 103}, /* 2933 'g' */ + {0x90000000, 5, 99}, /* 2934 'c' */ + {0x98000000, 5, 109}, /* 2935 'm' */ + {0x38000000, 7, 121}, /* 2936 'y' */ + {0x3a000000, 8, 122}, /* 2937 'z' */ + {0x3c000000, 8, 39}, /* 2938 '\'' */ + {0x3e000000, 8, 102}, /* 2939 'f' */ + {0x3f000000, 8, 107}, /* 2940 'k' */ + {0x3d000000, 9, 44}, /* 2941 ',' */ + {0x3b400000, 10, 45}, /* 2942 '-' */ + {0x3b800000, 10, 111}, /* 2943 'o' */ + {0x3d800000, 10, 46}, /* 2944 '.' */ + {0x3dc00000, 10, 120}, /* 2945 'x' */ + {0x3b000000, 11, 119}, /* 2946 'w' */ + {0x3bc00000, 11, 58}, /* 2947 ':' */ + {0x3b200000, 12, 113}, /* 2948 'q' */ + {0x3be00000, 12, 104}, /* 2949 'h' */ + {0x3bf00000, 12, 118}, /* 2950 'v' */ + {0x3b300000, 13, 106}, /* 2951 'j' */ + {0x3b380000, 15, 117}, /* 2952 'u' */ + {0x3b3a0000, 15, 63}, /* 2953 '?' */ + {0x3b3e0000, 16, 47}, /* 2954 '/' */ + {0x3b3f0000, 16, 33}, /* 2955 '!' */ + {0x3b3c8000, 17, 1}, /* 2956 '0x01' */ + {0x3b3c0000, 18, 92}, /* 2957 '\\' */ + {0x3b3c4000, 18, 0}, /* 2958 '0x00' */ + {0x3b3d0000, 18, 59}, /* 2959 ';' */ + {0x3b3d8000, 18, 74}, /* 2960 'J' */ + {0x3b3dc000, 18, 41}, /* 2961 ')' */ + {0x3b3d4000, 19, 84}, /* 2962 'T' */ + {0x3b3d6000, 19, 93}, /* 2963 ']' */ + /* 26 */ + {0x80000000, 1, 101}, /* 2964 'e' */ + {0x40000000, 2, 105}, /* 2965 'i' */ + {0x00000000, 3, 97}, /* 2966 'a' */ + {0x30000000, 4, 111}, /* 2967 'o' */ + {0x28000000, 5, 46}, /* 2968 '.' */ + {0x24000000, 6, 32}, /* 2969 ' ' */ + {0x21000000, 8, 39}, /* 2970 '\'' */ + {0x23000000, 8, 121}, /* 2971 'y' */ + {0x20000000, 9, 117}, /* 2972 'u' */ + {0x22000000, 9, 115}, /* 2973 's' */ + {0x22800000, 10, 114}, /* 2974 'r' */ + {0x20800000, 11, 45}, /* 2975 '-' */ + {0x20c00000, 11, 44}, /* 2976 ',' */ + {0x22c00000, 11, 110}, /* 2977 'n' */ + {0x20a00000, 12, 103}, /* 2978 'g' */ + {0x20b00000, 12, 118}, /* 2979 'v' */ + {0x20f00000, 12, 108}, /* 2980 'l' */ + {0x22e00000, 12, 64}, /* 2981 '@' */ + {0x22f00000, 12, 58}, /* 2982 ':' */ + {0x20e80000, 13, 107}, /* 2983 'k' */ + {0x20e00000, 14, 98}, /* 2984 'b' */ + {0x20e40000, 15, 116}, /* 2985 't' */ + {0x20e60000, 16, 100}, /* 2986 'd' */ + {0x20e70000, 17, 47}, /* 2987 '/' */ + {0x20e78000, 18, 1}, /* 2988 '0x01' */ + {0x20e7c000, 18, 49}, /* 2989 '1' */ + /* 39 */ + {0x00000000, 2, 105}, /* 2990 'i' */ + {0x60000000, 3, 101}, /* 2991 'e' */ + {0x80000000, 3, 32}, /* 2992 ' ' */ + {0xa0000000, 3, 115}, /* 2993 's' */ + {0xc0000000, 3, 104}, /* 2994 'h' */ + {0x50000000, 4, 97}, /* 2995 'a' */ + {0xf0000000, 4, 111}, /* 2996 'o' */ + {0x40000000, 5, 46}, /* 2997 '.' */ + {0x48000000, 5, 119}, /* 2998 'w' */ + {0xe0000000, 5, 110}, /* 2999 'n' */ + {0xec000000, 7, 114}, /* 3000 'r' */ + {0xea000000, 8, 44}, /* 3001 ',' */ + {0xeb000000, 8, 108}, /* 3002 'l' */ + {0xef000000, 8, 121}, /* 3003 'y' */ + {0xe9000000, 9, 99}, /* 3004 'c' */ + {0xee800000, 9, 98}, /* 3005 'b' */ + {0xe8800000, 10, 58}, /* 3006 ':' */ + {0xe9800000, 10, 109}, /* 3007 'm' */ + {0xe9c00000, 10, 39}, /* 3008 '\'' */ + {0xee000000, 10, 100}, /* 3009 'd' */ + {0xe8000000, 11, 102}, /* 3010 'f' */ + {0xe8200000, 11, 93}, /* 3011 ']' */ + {0xe8400000, 11, 33}, /* 3012 '!' */ + {0xe8e00000, 11, 107}, /* 3013 'k' */ + {0xee400000, 11, 45}, /* 3014 '-' */ + {0xe8700000, 12, 103}, /* 3015 'g' */ + {0xe8c00000, 12, 63}, /* 3016 '?' */ + {0xe8d00000, 12, 116}, /* 3017 't' */ + {0xee700000, 12, 112}, /* 3018 'p' */ + {0xe8600000, 13, 0}, /* 3019 '0x00' */ + {0xe8680000, 13, 117}, /* 3020 'u' */ + {0xee680000, 13, 41}, /* 3021 ')' */ + {0xee640000, 14, 106}, /* 3022 'j' */ + {0xee620000, 15, 113}, /* 3023 'q' */ + {0xee600000, 16, 47}, /* 3024 '/' */ + {0xee610000, 17, 59}, /* 3025 ';' */ + {0xee61c000, 18, 91}, /* 3026 '[' */ + {0xee618000, 19, 1}, /* 3027 '0x01' */ + {0xee61a000, 19, 66}, /* 3028 'B' */ + /* 39 */ + {0x40000000, 2, 112}, /* 3029 'p' */ + {0xc0000000, 2, 116}, /* 3030 't' */ + {0xa0000000, 3, 32}, /* 3031 ' ' */ + {0x00000000, 4, 105}, /* 3032 'i' */ + {0x20000000, 4, 97}, /* 3033 'a' */ + {0x80000000, 4, 99}, /* 3034 'c' */ + {0x10000000, 5, 117}, /* 3035 'u' */ + {0x38000000, 5, 101}, /* 3036 'e' */ + {0x98000000, 5, 45}, /* 3037 '-' */ + {0x18000000, 6, 102}, /* 3038 'f' */ + {0x34000000, 6, 111}, /* 3039 'o' */ + {0x90000000, 6, 46}, /* 3040 '.' */ + {0x1c000000, 7, 44}, /* 3041 ',' */ + {0x1e000000, 7, 109}, /* 3042 'm' */ + {0x32000000, 7, 121}, /* 3043 'y' */ + {0x31000000, 8, 57}, /* 3044 '9' */ + {0x95000000, 8, 39}, /* 3045 '\'' */ + {0x96000000, 8, 113}, /* 3046 'q' */ + {0x30000000, 9, 115}, /* 3047 's' */ + {0x94000000, 9, 58}, /* 3048 ':' */ + {0x97000000, 9, 104}, /* 3049 'h' */ + {0x30c00000, 10, 63}, /* 3050 '?' */ + {0x94800000, 10, 108}, /* 3051 'l' */ + {0x97800000, 10, 119}, /* 3052 'w' */ + {0x30800000, 11, 65}, /* 3053 'A' */ + {0x94c00000, 11, 120}, /* 3054 'x' */ + {0x94e00000, 11, 98}, /* 3055 'b' */ + {0x97e00000, 11, 41}, /* 3056 ')' */ + {0x30b00000, 12, 47}, /* 3057 '/' */ + {0x30a00000, 13, 52}, /* 3058 '4' */ + {0x30a80000, 13, 33}, /* 3059 '!' */ + {0x97c00000, 13, 103}, /* 3060 'g' */ + {0x97c80000, 13, 0}, /* 3061 '0x00' */ + {0x97d80000, 13, 59}, /* 3062 ';' */ + {0x97d20000, 15, 118}, /* 3063 'v' */ + {0x97d40000, 15, 70}, /* 3064 'F' */ + {0x97d60000, 15, 69}, /* 3065 'E' */ + {0x97d00000, 16, 1}, /* 3066 '0x01' */ + {0x97d10000, 16, 67}, /* 3067 'C' */ + /* 45 */ + {0x80000000, 1, 32}, /* 3068 ' ' */ + {0x00000000, 3, 111}, /* 3069 'o' */ + {0x30000000, 4, 115}, /* 3070 's' */ + {0x50000000, 4, 46}, /* 3071 '.' */ + {0x48000000, 5, 44}, /* 3072 ',' */ + {0x60000000, 5, 101}, /* 3073 'e' */ + {0x70000000, 5, 39}, /* 3074 '\'' */ + {0x24000000, 6, 97}, /* 3075 'a' */ + {0x28000000, 6, 105}, /* 3076 'i' */ + {0x2c000000, 6, 100}, /* 3077 'd' */ + {0x44000000, 6, 110}, /* 3078 'n' */ + {0x6c000000, 6, 58}, /* 3079 ':' */ + {0x7c000000, 6, 108}, /* 3080 'l' */ + {0x20000000, 7, 119}, /* 3081 'w' */ + {0x68000000, 7, 116}, /* 3082 't' */ + {0x6a000000, 7, 109}, /* 3083 'm' */ + {0x7a000000, 7, 45}, /* 3084 '-' */ + {0x23000000, 8, 98}, /* 3085 'b' */ + {0x40000000, 8, 63}, /* 3086 '?' */ + {0x41000000, 8, 114}, /* 3087 'r' */ + {0x42000000, 8, 112}, /* 3088 'p' */ + {0x43000000, 8, 102}, /* 3089 'f' */ + {0x79000000, 8, 99}, /* 3090 'c' */ + {0x22400000, 10, 59}, /* 3091 ';' */ + {0x22800000, 10, 74}, /* 3092 'J' */ + {0x78000000, 10, 104}, /* 3093 'h' */ + {0x78400000, 10, 33}, /* 3094 '!' */ + {0x78c00000, 10, 103}, /* 3095 'g' */ + {0x22000000, 11, 41}, /* 3096 ')' */ + {0x22e00000, 11, 47}, /* 3097 '/' */ + {0x78a00000, 11, 93}, /* 3098 ']' */ + {0x22300000, 12, 107}, /* 3099 'k' */ + {0x22c00000, 12, 1}, /* 3100 '0x01' */ + {0x22d00000, 12, 117}, /* 3101 'u' */ + {0x78900000, 12, 0}, /* 3102 '0x00' */ + {0x22200000, 13, 122}, /* 3103 'z' */ + {0x78880000, 13, 34}, /* 3104 '\"' */ + {0x222c0000, 14, 106}, /* 3105 'j' */ + {0x78840000, 14, 50}, /* 3106 '2' */ + {0x22280000, 15, 121}, /* 3107 'y' */ + {0x222a0000, 15, 120}, /* 3108 'x' */ + {0x78800000, 16, 118}, /* 3109 'v' */ + {0x78810000, 16, 84}, /* 3110 'T' */ + {0x78820000, 16, 69}, /* 3111 'E' */ + {0x78830000, 16, 80}, /* 3112 'P' */ + /* 37 */ + {0x80000000, 2, 101}, /* 3113 'e' */ + {0x20000000, 3, 97}, /* 3114 'a' */ + {0x60000000, 3, 122}, /* 3115 'z' */ + {0xc0000000, 3, 32}, /* 3116 ' ' */ + {0xe0000000, 3, 105}, /* 3117 'i' */ + {0x10000000, 4, 108}, /* 3118 'l' */ + {0x40000000, 4, 121}, /* 3119 'y' */ + {0x50000000, 5, 111}, /* 3120 'o' */ + {0x00000000, 6, 99}, /* 3121 'c' */ + {0x08000000, 6, 44}, /* 3122 ',' */ + {0x0c000000, 6, 46}, /* 3123 '.' */ + {0x58000000, 6, 119}, /* 3124 'w' */ + {0x04000000, 7, 39}, /* 3125 '\'' */ + {0x06000000, 8, 58}, /* 3126 ':' */ + {0x07000000, 8, 116}, /* 3127 't' */ + {0x5d000000, 8, 109}, /* 3128 'm' */ + {0x5c000000, 9, 107}, /* 3129 'k' */ + {0x5e000000, 9, 45}, /* 3130 '-' */ + {0x5e800000, 9, 117}, /* 3131 'u' */ + {0x5f800000, 9, 98}, /* 3132 'b' */ + {0x5c800000, 11, 115}, /* 3133 's' */ + {0x5ca00000, 11, 47}, /* 3134 '/' */ + {0x5ce00000, 11, 100}, /* 3135 'd' */ + {0x5f200000, 11, 112}, /* 3136 'p' */ + {0x5f600000, 11, 63}, /* 3137 '?' */ + {0x5cc00000, 12, 104}, /* 3138 'h' */ + {0x5f000000, 12, 64}, /* 3139 '@' */ + {0x5f400000, 12, 41}, /* 3140 ')' */ + {0x5cd00000, 13, 33}, /* 3141 '!' */ + {0x5f180000, 13, 118}, /* 3142 'v' */ + {0x5f500000, 13, 103}, /* 3143 'g' */ + {0x5cd80000, 14, 102}, /* 3144 'f' */ + {0x5cdc0000, 14, 114}, /* 3145 'r' */ + {0x5f100000, 14, 113}, /* 3146 'q' */ + {0x5f140000, 14, 110}, /* 3147 'n' */ + {0x5f580000, 14, 1}, /* 3148 '0x01' */ + {0x5f5c0000, 14, 93}, /* 3149 ']' */ + /* 2 */ + {0x00000000, 1, 1}, /* 3150 '0x01' */ + {0x80000000, 1, 1}, /* 3151 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 3152 '0x01' */ + {0x80000000, 1, 1}, /* 3153 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 3154 '0x01' */ + {0x80000000, 1, 0}, /* 3155 '0x00' */ + /* 2 */ + {0x00000000, 1, 1}, /* 3156 '0x01' */ + {0x80000000, 1, 1}, /* 3157 '0x01' */ + /* 2 */ + {0x00000000, 1, 1}, /* 3158 '0x01' */ + {0x80000000, 1, 1} /* 3159 '0x01' */ }; unsigned fsat_index_2[] = { - 0, /* 0 */ - 51, /* 1 */ - 53, /* 2 */ - 53, /* 3 */ - 55, /* 4 */ - 57, /* 5 */ - 59, /* 6 */ - 61, /* 7 */ - 63, /* 8 */ - 65, /* 9 */ - 67, /* 10 */ - 69, /* 11 */ - 71, /* 12 */ - 73, /* 13 */ - 75, /* 14 */ - 77, /* 15 */ - 79, /* 16 */ - 81, /* 17 */ - 83, /* 18 */ - 85, /* 19 */ - 87, /* 20 */ - 89, /* 21 */ - 91, /* 22 */ - 93, /* 23 */ - 95, /* 24 */ - 97, /* 25 */ - 99, /* 26 */ - 101, /* 27 */ - 103, /* 28 */ - 105, /* 29 */ - 107, /* 30 */ - 109, /* 31 */ - 111, /* 32 */ - 191, /* 33 */ - 204, /* 34 */ - 240, /* 35 */ - 242, /* 36 */ - 250, /* 37 */ - 253, /* 38 */ - 265, /* 39 */ - 336, /* 40 */ - 391, /* 41 */ - 403, /* 42 */ - 416, /* 43 */ - 419, /* 44 */ - 439, /* 45 */ - 503, /* 46 */ - 568, /* 47 */ - 619, /* 48 */ - 654, /* 49 */ - 692, /* 50 */ - 724, /* 51 */ - 760, /* 52 */ - 795, /* 53 */ - 827, /* 54 */ - 860, /* 55 */ - 891, /* 56 */ - 922, /* 57 */ - 950, /* 58 */ - 959, /* 59 */ - 961, /* 60 */ - 963, /* 61 */ - 965, /* 62 */ - 967, /* 63 */ - 979, /* 64 */ - 985, /* 65 */ - 1043, /* 66 */ - 1083, /* 67 */ - 1130, /* 68 */ - 1177, /* 69 */ - 1231, /* 70 */ - 1267, /* 71 */ - 1304, /* 72 */ - 1336, /* 73 */ - 1388, /* 74 */ - 1417, /* 75 */ - 1457, /* 76 */ - 1493, /* 77 */ - 1540, /* 78 */ - 1575, /* 79 */ - 1634, /* 80 */ - 1673, /* 81 */ - 1686, /* 82 */ - 1723, /* 83 */ - 1782, /* 84 */ - 1826, /* 85 */ - 1871, /* 86 */ - 1909, /* 87 */ - 1939, /* 88 */ - 1963, /* 89 */ - 1987, /* 90 */ - 2005, /* 91 */ - 2039, /* 92 */ - 2041, /* 93 */ - 2050, /* 94 */ - 2052, /* 95 */ - 2054, /* 96 */ - 2085, /* 97 */ - 2136, /* 98 */ - 2175, /* 99 */ - 2232, /* 100 */ - 2278, /* 101 */ - 2339, /* 102 */ - 2374, /* 103 */ - 2414, /* 104 */ - 2455, /* 105 */ - 2499, /* 106 */ - 2513, /* 107 */ - 2553, /* 108 */ - 2596, /* 109 */ - 2636, /* 110 */ - 2680, /* 111 */ - 2728, /* 112 */ - 2767, /* 113 */ - 2780, /* 114 */ - 2827, /* 115 */ - 2872, /* 116 */ - 2921, /* 117 */ - 2964, /* 118 */ - 2990, /* 119 */ - 3029, /* 120 */ - 3068, /* 121 */ - 3113, /* 122 */ - 3150, /* 123 */ - 3152, /* 124 */ - 3154, /* 125 */ - 3156, /* 126 */ - 3158, /* 127 */ - 3160 /* 128 */ + 0, /* 0 */ + 51, /* 1 */ + 53, /* 2 */ + 53, /* 3 */ + 55, /* 4 */ + 57, /* 5 */ + 59, /* 6 */ + 61, /* 7 */ + 63, /* 8 */ + 65, /* 9 */ + 67, /* 10 */ + 69, /* 11 */ + 71, /* 12 */ + 73, /* 13 */ + 75, /* 14 */ + 77, /* 15 */ + 79, /* 16 */ + 81, /* 17 */ + 83, /* 18 */ + 85, /* 19 */ + 87, /* 20 */ + 89, /* 21 */ + 91, /* 22 */ + 93, /* 23 */ + 95, /* 24 */ + 97, /* 25 */ + 99, /* 26 */ + 101, /* 27 */ + 103, /* 28 */ + 105, /* 29 */ + 107, /* 30 */ + 109, /* 31 */ + 111, /* 32 */ + 191, /* 33 */ + 204, /* 34 */ + 240, /* 35 */ + 242, /* 36 */ + 250, /* 37 */ + 253, /* 38 */ + 265, /* 39 */ + 336, /* 40 */ + 391, /* 41 */ + 403, /* 42 */ + 416, /* 43 */ + 419, /* 44 */ + 439, /* 45 */ + 503, /* 46 */ + 568, /* 47 */ + 619, /* 48 */ + 654, /* 49 */ + 692, /* 50 */ + 724, /* 51 */ + 760, /* 52 */ + 795, /* 53 */ + 827, /* 54 */ + 860, /* 55 */ + 891, /* 56 */ + 922, /* 57 */ + 950, /* 58 */ + 959, /* 59 */ + 961, /* 60 */ + 963, /* 61 */ + 965, /* 62 */ + 967, /* 63 */ + 979, /* 64 */ + 985, /* 65 */ + 1043, /* 66 */ + 1083, /* 67 */ + 1130, /* 68 */ + 1177, /* 69 */ + 1231, /* 70 */ + 1267, /* 71 */ + 1304, /* 72 */ + 1336, /* 73 */ + 1388, /* 74 */ + 1417, /* 75 */ + 1457, /* 76 */ + 1493, /* 77 */ + 1540, /* 78 */ + 1575, /* 79 */ + 1634, /* 80 */ + 1673, /* 81 */ + 1686, /* 82 */ + 1723, /* 83 */ + 1782, /* 84 */ + 1826, /* 85 */ + 1871, /* 86 */ + 1909, /* 87 */ + 1939, /* 88 */ + 1963, /* 89 */ + 1987, /* 90 */ + 2005, /* 91 */ + 2039, /* 92 */ + 2041, /* 93 */ + 2050, /* 94 */ + 2052, /* 95 */ + 2054, /* 96 */ + 2085, /* 97 */ + 2136, /* 98 */ + 2175, /* 99 */ + 2232, /* 100 */ + 2278, /* 101 */ + 2339, /* 102 */ + 2374, /* 103 */ + 2414, /* 104 */ + 2455, /* 105 */ + 2499, /* 106 */ + 2513, /* 107 */ + 2553, /* 108 */ + 2596, /* 109 */ + 2636, /* 110 */ + 2680, /* 111 */ + 2728, /* 112 */ + 2767, /* 113 */ + 2780, /* 114 */ + 2827, /* 115 */ + 2872, /* 116 */ + 2921, /* 117 */ + 2964, /* 118 */ + 2990, /* 119 */ + 3029, /* 120 */ + 3068, /* 121 */ + 3113, /* 122 */ + 3150, /* 123 */ + 3152, /* 124 */ + 3154, /* 125 */ + 3156, /* 126 */ + 3158, /* 127 */ + 3160 /* 128 */ }; -size_t freesat_huffman_decode - (char *dst, size_t* dstlen, const uint8_t *src, size_t srclen) -{ - struct fsattab *fsat_table; - unsigned int *fsat_index; - size_t p; - unsigned int value; - unsigned int byte; - unsigned int bit; - char lastch; - int found; - unsigned int bitShift; - char nextCh; - unsigned int indx; - unsigned int j; - unsigned int mask; - unsigned int maskbit; - unsigned short kk; - unsigned int b; +size_t freesat_huffman_decode(char* dst, size_t* dstlen, const uint8_t* src, size_t srclen) { + struct fsattab* fsat_table; + unsigned int* fsat_index; + size_t p; + unsigned int value; + unsigned int byte; + unsigned int bit; + char lastch; + int found; + unsigned int bitShift; + char nextCh; + unsigned int indx; + unsigned int j; + unsigned int mask; + unsigned int maskbit; + unsigned short kk; + unsigned int b; - if (src[0] != 0x1f) return -1; + if (src[0] != 0x1f) + return -1; - p = 0; - if (src[1] == 1 || src[1] == 2) { - if (src[1] == 1) { - fsat_table = fsat_table_1; - fsat_index = fsat_index_1; - } else { - fsat_table = fsat_table_2; - fsat_index = fsat_index_2; - } - value = 0; - byte = 2; - bit = 0; - while (byte < 6 && byte < srclen) { - value |= src[byte] << ((5 - byte) * 8); - byte++; - } - lastch = START; + p = 0; + if (src[1] == 1 || src[1] == 2) { + if (src[1] == 1) { + fsat_table = fsat_table_1; + fsat_index = fsat_index_1; + } else { + fsat_table = fsat_table_2; + fsat_index = fsat_index_2; + } + value = 0; + byte = 2; + bit = 0; + while (byte < 6 && byte < srclen) { + value |= src[byte] << ((5 - byte) * 8); + byte++; + } + lastch = START; - do { - found = 0; - bitShift = 0; - nextCh = STOP; - if (lastch == ESCAPE) { - found = 1; - // Encoded in the next 8 bits. - // Terminated by the first ASCII character. - nextCh = (value >> 24) & 0xff; - bitShift = 8; - if ((nextCh & 0x80) == 0) { - lastch = nextCh; - if ((nextCh < 0x20) && (nextCh != '\n')) - nextCh = ESCAPE; - } - } else { - indx = (unsigned int) lastch; - //if (src[1] == 2) - // indx |= 0x80; - for (j = fsat_index[indx]; j < fsat_index[indx + 1]; j++) { - mask = 0; - maskbit = 0x80000000; - for (kk = 0; kk < fsat_table[j].bits; kk++) { - mask |= maskbit; - maskbit >>= 1; - } - if ((value & mask) == fsat_table[j].value) { - nextCh = fsat_table[j].next; - bitShift = fsat_table[j].bits; - found = 1; - lastch = nextCh; - break; - } - } - } - if (found) { - if (nextCh != STOP && nextCh != ESCAPE) { - if (p >= *dstlen) return 0; - dst[p++] = nextCh; - } - // Shift up by the number of bits. - for (b = 0; b < bitShift; b++) { - value = (value << 1) & 0xfffffffe; - if (byte < srclen) - value |= (src[byte] >> (7 - bit)) & 1; - if (bit == 7) { - bit = 0; - byte++; - } else - bit++; - } - } else { + do { + found = 0; + bitShift = 0; + nextCh = STOP; + if (lastch == ESCAPE) { + found = 1; + // Encoded in the next 8 bits. + // Terminated by the first ASCII character. + nextCh = (value >> 24) & 0xff; + bitShift = 8; + if ((nextCh & 0x80) == 0) { + lastch = nextCh; + if ((nextCh < 0x20) && (nextCh != '\n')) + nextCh = ESCAPE; + } + } else { + indx = (unsigned int)lastch; + // if (src[1] == 2) + // indx |= 0x80; + for (j = fsat_index[indx]; j < fsat_index[indx + 1]; j++) { + mask = 0; + maskbit = 0x80000000; + for (kk = 0; kk < fsat_table[j].bits; kk++) { + mask |= maskbit; + maskbit >>= 1; + } + if ((value & mask) == fsat_table[j].value) { + nextCh = fsat_table[j].next; + bitShift = fsat_table[j].bits; + found = 1; + lastch = nextCh; + break; + } + } + } + if (found) { + if (nextCh != STOP && nextCh != ESCAPE) { + if (p >= *dstlen) + return 0; + dst[p++] = nextCh; + } + // Shift up by the number of bits. + for (b = 0; b < bitShift; b++) { + value = (value << 1) & 0xfffffffe; + if (byte < srclen) + value |= (src[byte] >> (7 - bit)) & 1; + if (bit == 7) { + bit = 0; + byte++; + } else + bit++; + } + } else { return -1; - } - } while (lastch != STOP && byte < srclen + 4); + } + } while (lastch != STOP && byte < srclen + 4); - dst[p] = '\0'; + dst[p] = '\0'; *dstlen = p; - return 0; - } else { + return 0; + } else { return -1; - } + } } diff --git a/src/esfilter.c b/src/esfilter.c index f6584cdcc..ae97626fd 100644 --- a/src/esfilter.c +++ b/src/esfilter.c @@ -29,43 +29,37 @@ struct esfilter_entry_queue esfilters[ESF_CLASS_LAST + 1]; /* * Class masks */ -uint32_t esfilterclsmask[ESF_CLASS_LAST+1] = { - 0, - ESF_MASK_VIDEO, - ESF_MASK_AUDIO, - ESF_MASK_TELETEXT, - ESF_MASK_SUBTIT, - ESF_MASK_CA, - ESF_MASK_OTHER -}; - -static const idclass_t *esfilter_classes[ESF_CLASS_LAST+1] = { - NULL, - &esfilter_class_video, - &esfilter_class_audio, - &esfilter_class_teletext, - &esfilter_class_subtit, - &esfilter_class_ca, - &esfilter_class_other -}; +uint32_t esfilterclsmask[ESF_CLASS_LAST + 1] = {0, + ESF_MASK_VIDEO, + ESF_MASK_AUDIO, + ESF_MASK_TELETEXT, + ESF_MASK_SUBTIT, + ESF_MASK_CA, + ESF_MASK_OTHER}; + +static const idclass_t* esfilter_classes[ESF_CLASS_LAST + 1] = {NULL, + &esfilter_class_video, + &esfilter_class_audio, + &esfilter_class_teletext, + &esfilter_class_subtit, + &esfilter_class_ca, + &esfilter_class_other}; /* * Class types */ static struct strtab esfilterclasstab[] = { - { "NONE", ESF_CLASS_NONE }, - { "VIDEO", ESF_CLASS_VIDEO }, - { "AUDIO", ESF_CLASS_AUDIO }, - { "TELETEXT", ESF_CLASS_TELETEXT }, - { "SUBTIT", ESF_CLASS_SUBTIT }, - { "CA", ESF_CLASS_CA }, - { "OTHER", ESF_CLASS_OTHER }, + {"NONE", ESF_CLASS_NONE}, + {"VIDEO", ESF_CLASS_VIDEO}, + {"AUDIO", ESF_CLASS_AUDIO}, + {"TELETEXT", ESF_CLASS_TELETEXT}, + {"SUBTIT", ESF_CLASS_SUBTIT}, + {"CA", ESF_CLASS_CA}, + {"OTHER", ESF_CLASS_OTHER}, }; -const char * -esfilter_class2txt(int cls) -{ +const char* esfilter_class2txt(int cls) { return val2str(cls, esfilterclasstab) ?: "INVALID"; } @@ -81,18 +75,14 @@ esfilter_txt2class(const char *s) * Action types */ -static struct strtab esfilteractiontab[] = { - { "NONE", ESFA_NONE }, - { "USE", ESFA_USE }, - { "ONE_TIME", ESFA_ONE_TIME }, - { "EXCLUSIVE", ESFA_EXCLUSIVE }, - { "EMPTY", ESFA_EMPTY }, - { "IGNORE", ESFA_IGNORE } -}; +static struct strtab esfilteractiontab[] = {{"NONE", ESFA_NONE}, + {"USE", ESFA_USE}, + {"ONE_TIME", ESFA_ONE_TIME}, + {"EXCLUSIVE", ESFA_EXCLUSIVE}, + {"EMPTY", ESFA_EMPTY}, + {"IGNORE", ESFA_IGNORE}}; -const char * -esfilter_action2txt(esfilter_action_t a) -{ +const char* esfilter_action2txt(esfilter_action_t a) { return val2str(a, esfilteractiontab) ?: "INVALID"; } @@ -108,45 +98,38 @@ esfilter_txt2action(const char *s) * Create / delete */ -static void -esfilter_reindex(esfilter_class_t cls) -{ - esfilter_t *esf; - int i = 1; +static void esfilter_reindex(esfilter_class_t cls) { + esfilter_t* esf; + int i = 1; - TAILQ_FOREACH(esf, &esfilters[cls], esf_link) + TAILQ_FOREACH (esf, &esfilters[cls], esf_link) esf->esf_save = 0; - TAILQ_FOREACH(esf, &esfilters[cls], esf_link) { + TAILQ_FOREACH (esf, &esfilters[cls], esf_link) { if (esf->esf_index != i) { esf->esf_index = i; - esf->esf_save = 1; + esf->esf_save = 1; } i++; } - TAILQ_FOREACH(esf, &esfilters[cls], esf_link) + TAILQ_FOREACH (esf, &esfilters[cls], esf_link) if (esf->esf_save) { esf->esf_save = 0; idnode_changed(&esf->esf_id); } } -static int -esfilter_cmp(esfilter_t *a, esfilter_t *b) -{ +static int esfilter_cmp(esfilter_t* a, esfilter_t* b) { return a->esf_index - b->esf_index; } -esfilter_t * -esfilter_create - (esfilter_class_t cls, const char *uuid, htsmsg_t *conf, int save) -{ - esfilter_t *esf = calloc(1, sizeof(*esf)); - const idclass_t *c = NULL; - uint32_t ct; +esfilter_t* esfilter_create(esfilter_class_t cls, const char* uuid, htsmsg_t* conf, int save) { + esfilter_t* esf = calloc(1, sizeof(*esf)); + const idclass_t* c = NULL; + uint32_t ct; lock_assert(&global_lock); - esf->esf_caid = -1; + esf->esf_caid = -1; esf->esf_caprovider = -1; if (ESF_CLASS_IS_VALID(cls)) { c = esfilter_classes[cls]; @@ -187,9 +170,7 @@ esfilter_create return esf; } -static void -esfilter_delete(esfilter_t *esf, int delconf) -{ +static void esfilter_delete(esfilter_t* esf, int delconf) { char ubuf[UUID_HEX_SIZE]; if (delconf) hts_settings_remove("esfilter/%s", idnode_uuid_as_str(&esf->esf_id, ubuf)); @@ -204,29 +185,23 @@ esfilter_delete(esfilter_t *esf, int delconf) * Class functions */ -static htsmsg_t * -esfilter_class_save(idnode_t *self, char *filename, size_t fsize) -{ - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* esfilter_class_save(idnode_t* self, char* filename, size_t fsize) { + htsmsg_t* c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(self, c); if (filename) snprintf(filename, fsize, "esfilter/%s", idnode_uuid_as_str(self, ubuf)); return c; } -static void -esfilter_class_delete(idnode_t *self) -{ - esfilter_t *esf = (esfilter_t *)self; +static void esfilter_class_delete(idnode_t* self) { + esfilter_t* esf = (esfilter_t*)self; esfilter_delete(esf, 1); } -static void -esfilter_class_moveup(idnode_t *self) -{ - esfilter_t *esf = (esfilter_t *)self; - esfilter_t *prev = TAILQ_PREV(esf, esfilter_entry_queue, esf_link); +static void esfilter_class_moveup(idnode_t* self) { + esfilter_t* esf = (esfilter_t*)self; + esfilter_t* prev = TAILQ_PREV(esf, esfilter_entry_queue, esf_link); if (prev) { TAILQ_REMOVE(&esfilters[esf->esf_class], esf, esf_link); TAILQ_INSERT_BEFORE(prev, esf, esf_link); @@ -234,11 +209,9 @@ esfilter_class_moveup(idnode_t *self) } } -static void -esfilter_class_movedown(idnode_t *self) -{ - esfilter_t *esf = (esfilter_t *)self; - esfilter_t *next = TAILQ_NEXT(esf, esf_link); +static void esfilter_class_movedown(idnode_t* self) { + esfilter_t* esf = (esfilter_t*)self; + esfilter_t* next = TAILQ_NEXT(esf, esf_link); if (next) { TAILQ_REMOVE(&esfilters[esf->esf_class], esf, esf_link); TAILQ_INSERT_AFTER(&esfilters[esf->esf_class], next, esf, esf_link); @@ -246,12 +219,10 @@ esfilter_class_movedown(idnode_t *self) } } -static const void * -esfilter_class_type_get(void *o) -{ - esfilter_t *esf = o; - htsmsg_t *l = htsmsg_create_list(); - int i; +static const void* esfilter_class_type_get(void* o) { + esfilter_t* esf = o; + htsmsg_t* l = htsmsg_create_list(); + int i; for (i = SCT_UNKNOWN; i <= SCT_LAST; i++) if ((esf->esf_type & SCT_MASK(i)) != 0) @@ -259,13 +230,11 @@ esfilter_class_type_get(void *o) return l; } -static char * -esfilter_class_type_rend (void *o, const char *lang) -{ - char *str; - htsmsg_t *l = htsmsg_create_list(); - esfilter_t *esf = o; - int i; +static char* esfilter_class_type_rend(void* o, const char* lang) { + char* str; + htsmsg_t* l = htsmsg_create_list(); + esfilter_t* esf = o; + int i; for (i = SCT_UNKNOWN; i <= SCT_LAST; i++) { if (SCT_MASK(i) & esf->esf_type) @@ -277,15 +246,13 @@ esfilter_class_type_rend (void *o, const char *lang) return str; } -static int -esfilter_class_type_set_(void *o, const void *v, esfilter_class_t cls) -{ - esfilter_t *esf = o; - htsmsg_t *types = (htsmsg_t*)v; - htsmsg_field_t *f; - uint32_t mask = 0, u32; - uint32_t vmask = esfilterclsmask[cls]; - int save; +static int esfilter_class_type_set_(void* o, const void* v, esfilter_class_t cls) { + esfilter_t* esf = o; + htsmsg_t* types = (htsmsg_t*)v; + htsmsg_field_t* f; + uint32_t mask = 0, u32; + uint32_t vmask = esfilterclsmask[cls]; + int save; HTSMSG_FOREACH(f, types) { if (!htsmsg_field_get_u32(f, &u32)) { @@ -295,37 +262,37 @@ esfilter_class_type_set_(void *o, const void *v, esfilter_class_t cls) return 0; } } - save = esf->esf_type != mask; + save = esf->esf_type != mask; esf->esf_type = mask; return save; } -static htsmsg_t * -esfilter_class_type_enum_(void *o, const char *lang, esfilter_class_t cls) -{ - uint32_t mask = esfilterclsmask[cls]; - htsmsg_t *l = htsmsg_create_list(); - const char *any = N_("ANY"); - int i; +static htsmsg_t* esfilter_class_type_enum_(void* o, const char* lang, esfilter_class_t cls) { + uint32_t mask = esfilterclsmask[cls]; + htsmsg_t* l = htsmsg_create_list(); + const char* any = N_("ANY"); + int i; for (i = SCT_UNKNOWN; i <= SCT_LAST; i++) { if (mask & SCT_MASK(i)) { - htsmsg_t *e = htsmsg_create_map(); + htsmsg_t* e = htsmsg_create_map(); htsmsg_add_u32(e, "key", i); - htsmsg_add_str(e, "val", - i == SCT_UNKNOWN ? tvh_gettext_lang(lang, any) : - streaming_component_type2txt(i)); + htsmsg_add_str(e, + "val", + i == SCT_UNKNOWN ? tvh_gettext_lang(lang, any) : streaming_component_type2txt(i)); htsmsg_add_msg(l, NULL, e); } } return l; } -#define ESFILTER_CLS(func, type) \ -static int esfilter_class_type_set_##func(void *o, const void *v) \ - { return esfilter_class_type_set_(o, v, type); } \ -static htsmsg_t * esfilter_class_type_enum_##func(void *o, const char *lang) \ - { return esfilter_class_type_enum_(o, lang, type); } +#define ESFILTER_CLS(func, type) \ + static int esfilter_class_type_set_##func(void* o, const void* v) { \ + return esfilter_class_type_set_(o, v, type); \ + } \ + static htsmsg_t* esfilter_class_type_enum_##func(void* o, const char* lang) { \ + return esfilter_class_type_enum_(o, lang, type); \ + } ESFILTER_CLS(video, ESF_CLASS_VIDEO); ESFILTER_CLS(audio, ESF_CLASS_AUDIO); @@ -334,44 +301,38 @@ ESFILTER_CLS(subtit, ESF_CLASS_SUBTIT); ESFILTER_CLS(ca, ESF_CLASS_CA); ESFILTER_CLS(other, ESF_CLASS_OTHER); -static const void * -esfilter_class_language_get(void *o) -{ - static __thread char *ret; - esfilter_t *esf = o; - ret = esf->esf_language; +static const void* esfilter_class_language_get(void* o) { + static __thread char* ret; + esfilter_t* esf = o; + ret = esf->esf_language; return &ret; } -static int -esfilter_class_language_set(void *o, const void *v) -{ - esfilter_t *esf = o; - const char *s = v; - char n[4]; - int save; +static int esfilter_class_language_set(void* o, const void* v) { + esfilter_t* esf = o; + const char* s = v; + char n[4]; + int save; strlcpy(n, s && s[0] ? lang_code_get(s) : "", 4); save = strcmp(esf->esf_language, n); strcpy(esf->esf_language, n); return save; } -static htsmsg_t * -esfilter_class_language_enum(void *o, const char *lang) -{ - htsmsg_t *l = htsmsg_create_list(); - const lang_code_t *lc = lang_codes; - const char *any = N_("ANY"); - char buf[128]; +static htsmsg_t* esfilter_class_language_enum(void* o, const char* lang) { + htsmsg_t* l = htsmsg_create_list(); + const lang_code_t* lc = lang_codes; + const char* any = N_("ANY"); + char buf[128]; while (lc->code2b) { - htsmsg_t *e; + htsmsg_t* e; if (!strcmp(lc->code2b, "und")) { e = htsmsg_create_key_val("", tvh_gettext_lang(lang, any)); } else { snprintf(buf, sizeof(buf), "%s (%s)", lc->desc, lc->code2b); - buf[sizeof(buf)-1] = '\0'; - e = htsmsg_create_key_val(lc->code2b, buf); + buf[sizeof(buf) - 1] = '\0'; + e = htsmsg_create_key_val(lc->code2b, buf); } htsmsg_add_msg(l, NULL, e); lc++; @@ -379,21 +340,17 @@ esfilter_class_language_enum(void *o, const char *lang) return l; } -static const void * -esfilter_class_service_get(void *o) -{ - static __thread char *ret; - esfilter_t *esf = o; - ret = esf->esf_service; +static const void* esfilter_class_service_get(void* o) { + static __thread char* ret; + esfilter_t* esf = o; + ret = esf->esf_service; return &ret; } -static int -esfilter_class_service_set(void *o, const void *v) -{ - esfilter_t *esf = o; - const char *s = v; - int save = 0; +static int esfilter_class_service_set(void* o, const void* v) { + esfilter_t* esf = o; + const char* s = v; + int save = 0; if (strncmp(esf->esf_service, s, UUID_HEX_SIZE)) { strlcpy(esf->esf_service, s, UUID_HEX_SIZE); save = 1; @@ -401,12 +358,10 @@ esfilter_class_service_set(void *o, const void *v) return save; } -static htsmsg_t * -esfilter_class_service_enum(void *o, const char *lang) -{ +static htsmsg_t* esfilter_class_service_enum(void* o, const char* lang) { htsmsg_t *e, *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "service/list"); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "service/list"); htsmsg_add_str(m, "event", "service"); e = htsmsg_create_map(); htsmsg_add_bool(e, "enum", 1); @@ -416,11 +371,9 @@ esfilter_class_service_enum(void *o, const char *lang) #define MAX_ITEMS 256 -static int -esfilter_build_ca_cmp(const void *_a, const void *_b) -{ - uint32_t a = *(uint32_t *)_a; - uint32_t b = *(uint32_t *)_b; +static int esfilter_build_ca_cmp(const void* _a, const void* _b) { + uint32_t a = *(uint32_t*)_a; + uint32_t b = *(uint32_t*)_b; if (a < b) return -1; if (a > b) @@ -428,23 +381,21 @@ esfilter_build_ca_cmp(const void *_a, const void *_b) return 0; } -static htsmsg_t * -esfilter_build_ca_enum(int provider) -{ - htsmsg_t *l; - uint32_t *a = alloca(sizeof(uint32_t) * MAX_ITEMS); - char buf[16], buf2[128]; - service_t *s; - elementary_stream_t *es; - caid_t *ca; - uint32_t v; - int i, count = 0; +static htsmsg_t* esfilter_build_ca_enum(int provider) { + htsmsg_t* l; + uint32_t* a = alloca(sizeof(uint32_t) * MAX_ITEMS); + char buf[16], buf2[128]; + service_t* s; + elementary_stream_t* es; + caid_t* ca; + uint32_t v; + int i, count = 0; lock_assert(&global_lock); - TAILQ_FOREACH(s, &service_all, s_all_link) { + TAILQ_FOREACH (s, &service_all, s_all_link) { tvh_mutex_lock(&s->s_stream_mutex); - TAILQ_FOREACH(es, &s->s_components.set_all, es_link) { - LIST_FOREACH(ca, &es->es_caids, link) { + TAILQ_FOREACH (es, &s->s_components.set_all, es_link) { + LIST_FOREACH (ca, &es->es_caids, link) { v = provider ? ca->providerid : ca->caid; for (i = 0; i < count; i++) if (a[i] == v) @@ -464,51 +415,41 @@ esfilter_build_ca_enum(int provider) for (i = 0; i < count; i++) { snprintf(buf, sizeof(buf), provider ? "%06x" : "%04x", a[i]); if (!provider) - snprintf(buf2, sizeof(buf2), "%04x - %s", - a[i], caid2name(a[i])); + snprintf(buf2, sizeof(buf2), "%04x - %s", a[i], caid2name(a[i])); htsmsg_add_msg(l, NULL, htsmsg_create_key_val(buf, provider ? buf : buf2)); } return l; - } -static const void * -esfilter_class_caid_get(void *o) -{ - static __thread char *ret; - static __thread char buf[16]; - esfilter_t *esf = o; +static const void* esfilter_class_caid_get(void* o) { + static __thread char* ret; + static __thread char buf[16]; + esfilter_t* esf = o; snprintf(buf, sizeof(buf), "%04x", esf->esf_caid); ret = buf; return &ret; } -static int -esfilter_class_caid_set(void *o, const void *v) -{ - esfilter_t *esf = o; - uint16_t u; - int save = 0; - u = strtol(v, NULL, 16); +static int esfilter_class_caid_set(void* o, const void* v) { + esfilter_t* esf = o; + uint16_t u; + int save = 0; + u = strtol(v, NULL, 16); if (u != esf->esf_caid) { esf->esf_caid = u; - save = 1; + save = 1; } return save; } -static htsmsg_t * -esfilter_class_caid_enum(void *o, const char *lang) -{ +static htsmsg_t* esfilter_class_caid_enum(void* o, const char* lang) { return esfilter_build_ca_enum(0); } -static const void * -esfilter_class_caprovider_get(void *o) -{ - static __thread char *ret; - static __thread char buf[16]; - esfilter_t *esf = o; +static const void* esfilter_class_caprovider_get(void* o) { + static __thread char* ret; + static __thread char buf[16]; + esfilter_t* esf = o; if (esf->esf_caprovider == -1) strcpy(buf, "ffffff"); else @@ -517,57 +458,47 @@ esfilter_class_caprovider_get(void *o) return &ret; } -static int -esfilter_class_caprovider_set(void *o, const void *v) -{ - esfilter_t *esf = o; - uint32_t u; - int save = 0; +static int esfilter_class_caprovider_set(void* o, const void* v) { + esfilter_t* esf = o; + uint32_t u; + int save = 0; if (strcmp(v, "ffffff") == 0) u = -1; else u = strtol(v, NULL, 16); if (u != esf->esf_caprovider) { esf->esf_caprovider = u; - save = 1; + save = 1; } return save; } -static htsmsg_t * -esfilter_class_caprovider_enum(void *o, const char *lang) -{ +static htsmsg_t* esfilter_class_caprovider_enum(void* o, const char* lang) { return esfilter_build_ca_enum(1); } -static const void * -esfilter_class_action_get(void *o) -{ - esfilter_t *esf = o; +static const void* esfilter_class_action_get(void* o) { + esfilter_t* esf = o; return &esf->esf_action; } -static int -esfilter_class_action_set(void *o, const void *v) -{ - esfilter_t *esf = o; - int n = *(int *)v; - int save = 0; +static int esfilter_class_action_set(void* o, const void* v) { + esfilter_t* esf = o; + int n = *(int*)v; + int save = 0; if (n >= ESFA_USE && n <= ESFA_LAST) { - save = esf->esf_action != n; + save = esf->esf_action != n; esf->esf_action = n; } return save; } -static htsmsg_t * -esfilter_class_action_enum(void *o, const char *lang) -{ - htsmsg_t *l = htsmsg_create_list(); - int i; +static htsmsg_t* esfilter_class_action_enum(void* o, const char* lang) { + htsmsg_t* l = htsmsg_create_list(); + int i; for (i = ESFA_NONE; i <= ESFA_LAST; i++) { - htsmsg_t *e = htsmsg_create_map(); + htsmsg_t* e = htsmsg_create_map(); htsmsg_add_u32(e, "key", i); htsmsg_add_str(e, "val", esfilter_action2txt(i)); htsmsg_add_msg(l, NULL, e); @@ -578,624 +509,600 @@ esfilter_class_action_enum(void *o, const char *lang) CLASS_DOC(filters) PROP_DOC(action) -const idclass_t esfilter_class = { - .ic_class = "esfilter", - .ic_caption = N_("Elementary stream filter"), - .ic_doc = tvh_doc_filters_class, - .ic_event = "esfilter", - .ic_perm_def = ACCESS_ADMIN, - .ic_save = esfilter_class_save, - .ic_delete = esfilter_class_delete, - .ic_moveup = esfilter_class_moveup, - .ic_movedown = esfilter_class_movedown, - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "class", - .name = N_("Class"), - .opts = PO_RDONLY | PO_HIDDEN | PO_DOC_NLIST, - .off = offsetof(esfilter_t, esf_class), - }, - { - .type = PT_INT, - .id = "index", - .name = N_("Index"), - .opts = PO_RDONLY | PO_HIDDEN | PO_DOC_NLIST, - .off = offsetof(esfilter_t, esf_index), - }, - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable this filter."), - .off = offsetof(esfilter_t, esf_enabled), - }, - {} - } -}; - -const idclass_t esfilter_class_video = { - .ic_super = &esfilter_class, - .ic_class = "esfilter_video", - .ic_caption = N_("Stream Filters - Video"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .islist = 1, - .id = "type", - .name = N_("Stream type"), - .desc = N_("The video stream types the filter should apply " - "to."), - .get = esfilter_class_type_get, - .set = esfilter_class_type_set_video, - .list = esfilter_class_type_enum_video, - .rend = esfilter_class_type_rend, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "language", - .name = N_("Language"), - .desc = N_("The language to which the filter should apply."), - .get = esfilter_class_language_get, - .set = esfilter_class_language_set, - .list = esfilter_class_language_enum, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "service", - .name = N_("Service"), - .desc = N_("The service to which the filter should apply. " - "Leave blank to apply the filter to all services."), - .get = esfilter_class_service_get, - .set = esfilter_class_service_set, - .list = esfilter_class_service_enum, - }, - { - .type = PT_INT, - .id = "sindex", - .name = N_("Stream index"), - .desc = N_("The logical stream index to compare. Note that " - "this index is computed using all filters." - "Example: If filter is set to AC3 audio type and " - "the language to 'eng' and there are two AC3 " - "'eng' streams in the service, the first stream " - "could be identified using number 1 and the " - "second using number 2."), - .off = offsetof(esfilter_t, esf_sindex), - }, - { - .type = PT_INT, - .id = "pid", - .name = N_("PID"), - .desc = N_("Program identification (PID) number to compare. " - "Zero means any. This comparison is processed " - "only when service comparison is active and for " - "the Conditional Access filter."), - .off = offsetof(esfilter_t, esf_pid), - }, - { - .type = PT_INT, - .id = "action", - .name = N_("Action"), - .desc = N_("The rule action defines the operation when all " - "comparisons succeed. See Help for more " - "information on what the various rules do."), - .get = esfilter_class_action_get, - .set = esfilter_class_action_set, - .list = esfilter_class_action_enum, - .opts = PO_DOC_NLIST, - .doc = prop_doc_action, - }, - { - .type = PT_BOOL, - .id = "log", - .name = N_("Log"), - .desc = N_("Write a short message to log identifying the " - "matched parameters. It is useful for debugging " - "your setup or structure of incoming streams."), - .off = offsetof(esfilter_t, esf_log), - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-format text field. Enter whatever you " - "like here."), - .off = offsetof(esfilter_t, esf_comment), - }, - {} - } -}; - -const idclass_t esfilter_class_audio = { - .ic_super = &esfilter_class, - .ic_class = "esfilter_audio", - .ic_caption = N_("Stream Filters - Audio"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .islist = 1, - .id = "type", - .name = N_("Stream type"), - .desc = N_("The audio stream types the filter should apply " - "to."), - .get = esfilter_class_type_get, - .set = esfilter_class_type_set_audio, - .list = esfilter_class_type_enum_audio, - .rend = esfilter_class_type_rend, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "language", - .name = N_("Language"), - .desc = N_("The language to which the filter should apply."), - .get = esfilter_class_language_get, - .set = esfilter_class_language_set, - .list = esfilter_class_language_enum, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "service", - .name = N_("Service"), - .desc = N_("The service the filter should apply to. " - "Leave blank to apply the filter to all " - "services."), - .get = esfilter_class_service_get, - .set = esfilter_class_service_set, - .list = esfilter_class_service_enum, - }, - { - .type = PT_INT, - .id = "sindex", - .name = N_("Stream index"), - .desc = N_("The logical stream index to compare. Note that " - "this index is computed using all filters." - "Example: If filter is set to AC3 audio type and " - "the language to 'eng' and there are two AC3 " - "'eng' streams in the service, the first stream " - "could be identified using number 1 and the " - "second using number 2."), - .off = offsetof(esfilter_t, esf_sindex), - }, - { - .type = PT_INT, - .id = "pid", - .name = N_("PID"), - .desc = N_("Program identification (PID) number to compare. " - "Zero means any. This comparison is processed " - "only when service comparison is active and for " - "the Conditional Access filter."), - .off = offsetof(esfilter_t, esf_pid), - }, - { - .type = PT_INT, - .id = "action", - .name = N_("Action"), - .desc = N_("The rule action defines the operation when all " - "comparisons succeed. See Help for more " - "information on what the various rules do."), - .get = esfilter_class_action_get, - .set = esfilter_class_action_set, - .list = esfilter_class_action_enum, - .opts = PO_DOC_NLIST, - .doc = prop_doc_action, - }, - { - .type = PT_BOOL, - .id = "log", - .name = N_("Log"), - .desc = N_("Write a short message to log identifying the " - "matched parameters. It is useful for debugging " - "your setup or structure of incoming streams."), - .off = offsetof(esfilter_t, esf_log), - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-format text field. Enter whatever you " - "like here."), - .off = offsetof(esfilter_t, esf_comment), - }, - {} - } -}; - -const idclass_t esfilter_class_teletext = { - .ic_super = &esfilter_class, - .ic_class = "esfilter_teletext", - .ic_caption = N_("Stream Filters - Teletext"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .islist = 1, - .id = "type", - .name = N_("Stream type"), - .desc = N_("Teletext stream type is only available for " - "this filter."), - .get = esfilter_class_type_get, - .set = esfilter_class_type_set_teletext, - .list = esfilter_class_type_enum_teletext, - .rend = esfilter_class_type_rend, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "language", - .name = N_("Language"), - .desc = N_("The language to which the filter should apply."), - .get = esfilter_class_language_get, - .set = esfilter_class_language_set, - .list = esfilter_class_language_enum, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "service", - .name = N_("Service"), - .desc = N_("The service the filter should apply to. " - "Leave blank to apply the filter to all " - "services."), - .get = esfilter_class_service_get, - .set = esfilter_class_service_set, - .list = esfilter_class_service_enum, - }, - { - .type = PT_INT, - .id = "sindex", - .name = N_("Stream index"), - .desc = N_("The logical stream index to compare. Note that " - "this index is computed using all filters." - "Example: If filter is set to AC3 audio type and " - "the language to 'eng' and there are two AC3 " - "'eng' streams in the service, the first stream " - "could be identified using number 1 and the " - "second using number 2."), - .off = offsetof(esfilter_t, esf_sindex), - }, - { - .type = PT_INT, - .id = "pid", - .name = N_("PID"), - .desc = N_("Program identification (PID) number to compare. " - "Zero means any. This comparison is processed " - "only when service comparison is active and for " - "the Conditional Access filter."), - .off = offsetof(esfilter_t, esf_pid), - }, - { - .type = PT_INT, - .id = "action", - .name = N_("Action"), - .desc = N_("The rule action defines the operation when all " - "comparisons succeed. See Help for more " - "information on what the various rules do."), - .get = esfilter_class_action_get, - .set = esfilter_class_action_set, - .list = esfilter_class_action_enum, - .opts = PO_DOC_NLIST, - .doc = prop_doc_action, - }, - { - .type = PT_BOOL, - .id = "log", - .name = N_("Log"), - .desc = N_("Write a short message to log identifying the " - "matched parameters. It is useful for debugging " - "your setup or structure of incoming streams."), - .off = offsetof(esfilter_t, esf_log), - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-format text field. Enter whatever you " - "like here."), - .off = offsetof(esfilter_t, esf_comment), - }, - {} - } -}; - -const idclass_t esfilter_class_subtit = { - .ic_super = &esfilter_class, - .ic_class = "esfilter_subtit", - .ic_caption = N_("Stream Filters - Subtitles"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .islist = 1, - .id = "type", - .name = N_("Stream type"), - .desc = N_("The subtitle stream types the filter should " - "apply to."), - .get = esfilter_class_type_get, - .set = esfilter_class_type_set_subtit, - .list = esfilter_class_type_enum_subtit, - .rend = esfilter_class_type_rend, - }, - { - .type = PT_STR, - .id = "language", - .name = N_("Language"), - .desc = N_("The language to which the filter should apply."), - .get = esfilter_class_language_get, - .set = esfilter_class_language_set, - .list = esfilter_class_language_enum, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "service", - .name = N_("Service"), - .desc = N_("The service the filter should apply to. " - "Leave blank to apply the filter to all " - "services."), - .get = esfilter_class_service_get, - .set = esfilter_class_service_set, - .list = esfilter_class_service_enum, - }, - { - .type = PT_INT, - .id = "sindex", - .name = N_("Stream index"), - .desc = N_("The logical stream index to compare. Note that " - "this index is computed using all filters." - "Example: If filter is set to AC3 audio type and " - "the language to 'eng' and there are two AC3 " - "'eng' streams in the service, the first stream " - "could be identified using number 1 and the " - "second using number 2."), - .off = offsetof(esfilter_t, esf_sindex), - }, - { - .type = PT_INT, - .id = "pid", - .name = N_("PID"), - .desc = N_("Program identification (PID) number to compare. " - "Zero means any. This comparison is processed " - "only when service comparison is active and for " - "the Conditional Access filter."), - .off = offsetof(esfilter_t, esf_pid), - }, - { - .type = PT_INT, - .id = "action", - .name = N_("Action"), - .desc = N_("The rule action defines the operation when all " - "comparisons succeed. See Help for more " - "information on what the various rules do."), - .get = esfilter_class_action_get, - .set = esfilter_class_action_set, - .list = esfilter_class_action_enum, - .opts = PO_DOC_NLIST, - .doc = prop_doc_action, - }, - { - .type = PT_BOOL, - .id = "log", - .name = N_("Log"), - .desc = N_("Write a short message to log identifying the " - "matched parameters. It is useful for debugging " - "your setup or structure of incoming streams."), - .off = offsetof(esfilter_t, esf_log), - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-format text field. Enter whatever you " - "like here."), - .off = offsetof(esfilter_t, esf_comment), - }, - {} - } -}; - -const idclass_t esfilter_class_ca = { - .ic_super = &esfilter_class, - .ic_class = "esfilter_ca", - .ic_caption = N_("Stream Filters - CA"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .islist = 1, - .id = "type", - .name = N_("Stream type"), - .desc = N_("The CA stream type is only available for this " - "filter."), - .get = esfilter_class_type_get, - .set = esfilter_class_type_set_ca, - .list = esfilter_class_type_enum_ca, - .rend = esfilter_class_type_rend, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "CAid", - .name = N_("CA identification"), - .desc = N_("The CAID to compare. Leave blank to apply to " - "all IDs."), - .get = esfilter_class_caid_get, - .set = esfilter_class_caid_set, - .list = esfilter_class_caid_enum, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "CAprovider", - .name = N_("CA provider"), - .desc = N_("The CA provider to compare. Leave blank to apply " - "to all providers."), - .get = esfilter_class_caprovider_get, - .set = esfilter_class_caprovider_set, - .list = esfilter_class_caprovider_enum, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "service", - .name = N_("Service"), - .desc = N_("The service the filter should apply to. " - "Leave blank to apply the filter to all " - "services."), - .get = esfilter_class_service_get, - .set = esfilter_class_service_set, - .list = esfilter_class_service_enum, - }, - { - .type = PT_INT, - .id = "sindex", - .name = N_("Stream index"), - .desc = N_("The logical stream index to compare. Note that " - "this index is computed using all filters." - "Example: If filter is set to AC3 audio type and " - "the language to 'eng' and there are two AC3 " - "'eng' streams in the service, the first stream " - "could be identified using number 1 and the " - "second using number 2."), - .off = offsetof(esfilter_t, esf_sindex), - }, - { - .type = PT_INT, - .id = "pid", - .name = N_("PID"), - .desc = N_("Program identification (PID) number to compare. " - "Zero means any. This comparison is processed " - "only when service comparison is active and for " - "the Conditional Access filter."), - .off = offsetof(esfilter_t, esf_pid), - }, - { - .type = PT_INT, - .id = "action", - .name = N_("Action"), - .desc = N_("The rule action defines the operation when all " - "comparisons succeed. See Help for more " - "information on what the various rules do."), - .get = esfilter_class_action_get, - .set = esfilter_class_action_set, - .list = esfilter_class_action_enum, - .opts = PO_DOC_NLIST, - .doc = prop_doc_action, - }, - { - .type = PT_BOOL, - .id = "log", - .name = N_("Log"), - .desc = N_("Write a short message to log identifying the " - "matched parameters. It is useful for debugging " - "your setup or structure of incoming streams."), - .off = offsetof(esfilter_t, esf_log), - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-format text field. Enter whatever you " - "like here."), - .off = offsetof(esfilter_t, esf_comment), - }, - {} - } -}; - -const idclass_t esfilter_class_other = { - .ic_super = &esfilter_class, - .ic_class = "esfilter_other", - .ic_caption = N_("Stream Filters - Other"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .islist = 1, - .id = "type", - .name = N_("Stream type"), - .desc = N_("The MPEGTS stream type is only available for " - "this filter."), - .get = esfilter_class_type_get, - .set = esfilter_class_type_set_other, - .list = esfilter_class_type_enum_other, - .rend = esfilter_class_type_rend, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "language", - .name = N_("Language"), - .desc = N_("The language to which the filter should apply."), - .get = esfilter_class_language_get, - .set = esfilter_class_language_set, - .list = esfilter_class_language_enum, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "service", - .name = N_("Service"), - .desc = N_("The service the filter should apply to. " - "Leave blank to apply the filter to all " - "services."), - .get = esfilter_class_service_get, - .set = esfilter_class_service_set, - .list = esfilter_class_service_enum, - }, - { - .type = PT_INT, - .id = "pid", - .name = N_("PID"), - .desc = N_("Program identification (PID) number to compare. " - "Zero means any. This comparison is processed " - "only when service comparison is active and for " - "the Conditional Access filter."), - .off = offsetof(esfilter_t, esf_pid), - }, - { - .type = PT_INT, - .id = "action", - .name = N_("Action"), - .desc = N_("The rule action defines the operation when all " - "comparisons succeed. See Help for more " - "information on what the various rules do."), - .get = esfilter_class_action_get, - .set = esfilter_class_action_set, - .list = esfilter_class_action_enum, - .opts = PO_DOC_NLIST, - .doc = prop_doc_action, - }, - { - .type = PT_BOOL, - .id = "log", - .name = N_("Log"), - .desc = N_("Write a short message to log identifying the " - "matched parameters. It is useful for debugging " - "your setup or structure of incoming streams."), - .off = offsetof(esfilter_t, esf_log), - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-format text field. Enter whatever you " - "like here."), - .off = offsetof(esfilter_t, esf_comment), - }, - {} - } -}; +const idclass_t esfilter_class = {.ic_class = "esfilter", + .ic_caption = N_("Elementary stream filter"), + .ic_doc = tvh_doc_filters_class, + .ic_event = "esfilter", + .ic_perm_def = ACCESS_ADMIN, + .ic_save = esfilter_class_save, + .ic_delete = esfilter_class_delete, + .ic_moveup = esfilter_class_moveup, + .ic_movedown = esfilter_class_movedown, + .ic_properties = (const property_t[]){{ + .type = PT_INT, + .id = "class", + .name = N_("Class"), + .opts = PO_RDONLY | PO_HIDDEN | PO_DOC_NLIST, + .off = offsetof(esfilter_t, esf_class), + }, + { + .type = PT_INT, + .id = "index", + .name = N_("Index"), + .opts = PO_RDONLY | PO_HIDDEN | PO_DOC_NLIST, + .off = offsetof(esfilter_t, esf_index), + }, + { + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable this filter."), + .off = offsetof(esfilter_t, esf_enabled), + }, + {}}}; + +const idclass_t esfilter_class_video = {.ic_super = &esfilter_class, + .ic_class = "esfilter_video", + .ic_caption = N_("Stream Filters - Video"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .islist = 1, + .id = "type", + .name = N_("Stream type"), + .desc = N_("The video stream types the filter should apply " + "to."), + .get = esfilter_class_type_get, + .set = esfilter_class_type_set_video, + .list = esfilter_class_type_enum_video, + .rend = esfilter_class_type_rend, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "language", + .name = N_("Language"), + .desc = N_("The language to which the filter should apply."), + .get = esfilter_class_language_get, + .set = esfilter_class_language_set, + .list = esfilter_class_language_enum, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "service", + .name = N_("Service"), + .desc = N_("The service to which the filter should apply. " + "Leave blank to apply the filter to all services."), + .get = esfilter_class_service_get, + .set = esfilter_class_service_set, + .list = esfilter_class_service_enum, + }, + { + .type = PT_INT, + .id = "sindex", + .name = N_("Stream index"), + .desc = N_("The logical stream index to compare. Note that " + "this index is computed using all filters." + "Example: If filter is set to AC3 audio type and " + "the language to 'eng' and there are two AC3 " + "'eng' streams in the service, the first stream " + "could be identified using number 1 and the " + "second using number 2."), + .off = offsetof(esfilter_t, esf_sindex), + }, + { + .type = PT_INT, + .id = "pid", + .name = N_("PID"), + .desc = N_("Program identification (PID) number to compare. " + "Zero means any. This comparison is processed " + "only when service comparison is active and for " + "the Conditional Access filter."), + .off = offsetof(esfilter_t, esf_pid), + }, + { + .type = PT_INT, + .id = "action", + .name = N_("Action"), + .desc = N_("The rule action defines the operation when all " + "comparisons succeed. See Help for more " + "information on what the various rules do."), + .get = esfilter_class_action_get, + .set = esfilter_class_action_set, + .list = esfilter_class_action_enum, + .opts = PO_DOC_NLIST, + .doc = prop_doc_action, + }, + { + .type = PT_BOOL, + .id = "log", + .name = N_("Log"), + .desc = N_("Write a short message to log identifying the " + "matched parameters. It is useful for debugging " + "your setup or structure of incoming streams."), + .off = offsetof(esfilter_t, esf_log), + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-format text field. Enter whatever you " + "like here."), + .off = offsetof(esfilter_t, esf_comment), + }, + {}}}; + +const idclass_t esfilter_class_audio = {.ic_super = &esfilter_class, + .ic_class = "esfilter_audio", + .ic_caption = N_("Stream Filters - Audio"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .islist = 1, + .id = "type", + .name = N_("Stream type"), + .desc = N_("The audio stream types the filter should apply " + "to."), + .get = esfilter_class_type_get, + .set = esfilter_class_type_set_audio, + .list = esfilter_class_type_enum_audio, + .rend = esfilter_class_type_rend, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "language", + .name = N_("Language"), + .desc = N_("The language to which the filter should apply."), + .get = esfilter_class_language_get, + .set = esfilter_class_language_set, + .list = esfilter_class_language_enum, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "service", + .name = N_("Service"), + .desc = N_("The service the filter should apply to. " + "Leave blank to apply the filter to all " + "services."), + .get = esfilter_class_service_get, + .set = esfilter_class_service_set, + .list = esfilter_class_service_enum, + }, + { + .type = PT_INT, + .id = "sindex", + .name = N_("Stream index"), + .desc = N_("The logical stream index to compare. Note that " + "this index is computed using all filters." + "Example: If filter is set to AC3 audio type and " + "the language to 'eng' and there are two AC3 " + "'eng' streams in the service, the first stream " + "could be identified using number 1 and the " + "second using number 2."), + .off = offsetof(esfilter_t, esf_sindex), + }, + { + .type = PT_INT, + .id = "pid", + .name = N_("PID"), + .desc = N_("Program identification (PID) number to compare. " + "Zero means any. This comparison is processed " + "only when service comparison is active and for " + "the Conditional Access filter."), + .off = offsetof(esfilter_t, esf_pid), + }, + { + .type = PT_INT, + .id = "action", + .name = N_("Action"), + .desc = N_("The rule action defines the operation when all " + "comparisons succeed. See Help for more " + "information on what the various rules do."), + .get = esfilter_class_action_get, + .set = esfilter_class_action_set, + .list = esfilter_class_action_enum, + .opts = PO_DOC_NLIST, + .doc = prop_doc_action, + }, + { + .type = PT_BOOL, + .id = "log", + .name = N_("Log"), + .desc = N_("Write a short message to log identifying the " + "matched parameters. It is useful for debugging " + "your setup or structure of incoming streams."), + .off = offsetof(esfilter_t, esf_log), + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-format text field. Enter whatever you " + "like here."), + .off = offsetof(esfilter_t, esf_comment), + }, + {}}}; + +const idclass_t esfilter_class_teletext = {.ic_super = &esfilter_class, + .ic_class = "esfilter_teletext", + .ic_caption = N_("Stream Filters - Teletext"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .islist = 1, + .id = "type", + .name = N_("Stream type"), + .desc = N_("Teletext stream type is only available for " + "this filter."), + .get = esfilter_class_type_get, + .set = esfilter_class_type_set_teletext, + .list = esfilter_class_type_enum_teletext, + .rend = esfilter_class_type_rend, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "language", + .name = N_("Language"), + .desc = N_("The language to which the filter should apply."), + .get = esfilter_class_language_get, + .set = esfilter_class_language_set, + .list = esfilter_class_language_enum, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "service", + .name = N_("Service"), + .desc = N_("The service the filter should apply to. " + "Leave blank to apply the filter to all " + "services."), + .get = esfilter_class_service_get, + .set = esfilter_class_service_set, + .list = esfilter_class_service_enum, + }, + { + .type = PT_INT, + .id = "sindex", + .name = N_("Stream index"), + .desc = N_("The logical stream index to compare. Note that " + "this index is computed using all filters." + "Example: If filter is set to AC3 audio type and " + "the language to 'eng' and there are two AC3 " + "'eng' streams in the service, the first stream " + "could be identified using number 1 and the " + "second using number 2."), + .off = offsetof(esfilter_t, esf_sindex), + }, + { + .type = PT_INT, + .id = "pid", + .name = N_("PID"), + .desc = N_("Program identification (PID) number to compare. " + "Zero means any. This comparison is processed " + "only when service comparison is active and for " + "the Conditional Access filter."), + .off = offsetof(esfilter_t, esf_pid), + }, + { + .type = PT_INT, + .id = "action", + .name = N_("Action"), + .desc = N_("The rule action defines the operation when all " + "comparisons succeed. See Help for more " + "information on what the various rules do."), + .get = esfilter_class_action_get, + .set = esfilter_class_action_set, + .list = esfilter_class_action_enum, + .opts = PO_DOC_NLIST, + .doc = prop_doc_action, + }, + { + .type = PT_BOOL, + .id = "log", + .name = N_("Log"), + .desc = N_("Write a short message to log identifying the " + "matched parameters. It is useful for debugging " + "your setup or structure of incoming streams."), + .off = offsetof(esfilter_t, esf_log), + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-format text field. Enter whatever you " + "like here."), + .off = offsetof(esfilter_t, esf_comment), + }, + {}}}; + +const idclass_t esfilter_class_subtit = {.ic_super = &esfilter_class, + .ic_class = "esfilter_subtit", + .ic_caption = N_("Stream Filters - Subtitles"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .islist = 1, + .id = "type", + .name = N_("Stream type"), + .desc = N_("The subtitle stream types the filter should " + "apply to."), + .get = esfilter_class_type_get, + .set = esfilter_class_type_set_subtit, + .list = esfilter_class_type_enum_subtit, + .rend = esfilter_class_type_rend, + }, + { + .type = PT_STR, + .id = "language", + .name = N_("Language"), + .desc = N_("The language to which the filter should apply."), + .get = esfilter_class_language_get, + .set = esfilter_class_language_set, + .list = esfilter_class_language_enum, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "service", + .name = N_("Service"), + .desc = N_("The service the filter should apply to. " + "Leave blank to apply the filter to all " + "services."), + .get = esfilter_class_service_get, + .set = esfilter_class_service_set, + .list = esfilter_class_service_enum, + }, + { + .type = PT_INT, + .id = "sindex", + .name = N_("Stream index"), + .desc = N_("The logical stream index to compare. Note that " + "this index is computed using all filters." + "Example: If filter is set to AC3 audio type and " + "the language to 'eng' and there are two AC3 " + "'eng' streams in the service, the first stream " + "could be identified using number 1 and the " + "second using number 2."), + .off = offsetof(esfilter_t, esf_sindex), + }, + { + .type = PT_INT, + .id = "pid", + .name = N_("PID"), + .desc = N_("Program identification (PID) number to compare. " + "Zero means any. This comparison is processed " + "only when service comparison is active and for " + "the Conditional Access filter."), + .off = offsetof(esfilter_t, esf_pid), + }, + { + .type = PT_INT, + .id = "action", + .name = N_("Action"), + .desc = N_("The rule action defines the operation when all " + "comparisons succeed. See Help for more " + "information on what the various rules do."), + .get = esfilter_class_action_get, + .set = esfilter_class_action_set, + .list = esfilter_class_action_enum, + .opts = PO_DOC_NLIST, + .doc = prop_doc_action, + }, + { + .type = PT_BOOL, + .id = "log", + .name = N_("Log"), + .desc = N_("Write a short message to log identifying the " + "matched parameters. It is useful for debugging " + "your setup or structure of incoming streams."), + .off = offsetof(esfilter_t, esf_log), + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-format text field. Enter whatever you " + "like here."), + .off = offsetof(esfilter_t, esf_comment), + }, + {}}}; + +const idclass_t esfilter_class_ca = {.ic_super = &esfilter_class, + .ic_class = "esfilter_ca", + .ic_caption = N_("Stream Filters - CA"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .islist = 1, + .id = "type", + .name = N_("Stream type"), + .desc = N_("The CA stream type is only available for this " + "filter."), + .get = esfilter_class_type_get, + .set = esfilter_class_type_set_ca, + .list = esfilter_class_type_enum_ca, + .rend = esfilter_class_type_rend, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "CAid", + .name = N_("CA identification"), + .desc = N_("The CAID to compare. Leave blank to apply to " + "all IDs."), + .get = esfilter_class_caid_get, + .set = esfilter_class_caid_set, + .list = esfilter_class_caid_enum, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "CAprovider", + .name = N_("CA provider"), + .desc = N_("The CA provider to compare. Leave blank to apply " + "to all providers."), + .get = esfilter_class_caprovider_get, + .set = esfilter_class_caprovider_set, + .list = esfilter_class_caprovider_enum, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "service", + .name = N_("Service"), + .desc = N_("The service the filter should apply to. " + "Leave blank to apply the filter to all " + "services."), + .get = esfilter_class_service_get, + .set = esfilter_class_service_set, + .list = esfilter_class_service_enum, + }, + { + .type = PT_INT, + .id = "sindex", + .name = N_("Stream index"), + .desc = N_("The logical stream index to compare. Note that " + "this index is computed using all filters." + "Example: If filter is set to AC3 audio type and " + "the language to 'eng' and there are two AC3 " + "'eng' streams in the service, the first stream " + "could be identified using number 1 and the " + "second using number 2."), + .off = offsetof(esfilter_t, esf_sindex), + }, + { + .type = PT_INT, + .id = "pid", + .name = N_("PID"), + .desc = N_("Program identification (PID) number to compare. " + "Zero means any. This comparison is processed " + "only when service comparison is active and for " + "the Conditional Access filter."), + .off = offsetof(esfilter_t, esf_pid), + }, + { + .type = PT_INT, + .id = "action", + .name = N_("Action"), + .desc = N_("The rule action defines the operation when all " + "comparisons succeed. See Help for more " + "information on what the various rules do."), + .get = esfilter_class_action_get, + .set = esfilter_class_action_set, + .list = esfilter_class_action_enum, + .opts = PO_DOC_NLIST, + .doc = prop_doc_action, + }, + { + .type = PT_BOOL, + .id = "log", + .name = N_("Log"), + .desc = N_("Write a short message to log identifying the " + "matched parameters. It is useful for debugging " + "your setup or structure of incoming streams."), + .off = offsetof(esfilter_t, esf_log), + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-format text field. Enter whatever you " + "like here."), + .off = offsetof(esfilter_t, esf_comment), + }, + {}}}; + +const idclass_t esfilter_class_other = {.ic_super = &esfilter_class, + .ic_class = "esfilter_other", + .ic_caption = N_("Stream Filters - Other"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .islist = 1, + .id = "type", + .name = N_("Stream type"), + .desc = N_("The MPEGTS stream type is only available for " + "this filter."), + .get = esfilter_class_type_get, + .set = esfilter_class_type_set_other, + .list = esfilter_class_type_enum_other, + .rend = esfilter_class_type_rend, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "language", + .name = N_("Language"), + .desc = N_("The language to which the filter should apply."), + .get = esfilter_class_language_get, + .set = esfilter_class_language_set, + .list = esfilter_class_language_enum, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "service", + .name = N_("Service"), + .desc = N_("The service the filter should apply to. " + "Leave blank to apply the filter to all " + "services."), + .get = esfilter_class_service_get, + .set = esfilter_class_service_set, + .list = esfilter_class_service_enum, + }, + { + .type = PT_INT, + .id = "pid", + .name = N_("PID"), + .desc = N_("Program identification (PID) number to compare. " + "Zero means any. This comparison is processed " + "only when service comparison is active and for " + "the Conditional Access filter."), + .off = offsetof(esfilter_t, esf_pid), + }, + { + .type = PT_INT, + .id = "action", + .name = N_("Action"), + .desc = N_("The rule action defines the operation when all " + "comparisons succeed. See Help for more " + "information on what the various rules do."), + .get = esfilter_class_action_get, + .set = esfilter_class_action_set, + .list = esfilter_class_action_enum, + .opts = PO_DOC_NLIST, + .doc = prop_doc_action, + }, + { + .type = PT_BOOL, + .id = "log", + .name = N_("Log"), + .desc = N_("Write a short message to log identifying the " + "matched parameters. It is useful for debugging " + "your setup or structure of incoming streams."), + .off = offsetof(esfilter_t, esf_log), + }, + { + .type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-format text field. Enter whatever you " + "like here."), + .off = offsetof(esfilter_t, esf_comment), + }, + {}}}; /** * Initialize */ -void -esfilter_init(void) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - int i; +void esfilter_init(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + int i; for (i = 0; i <= ESF_CLASS_LAST; i++) { TAILQ_INIT(&esfilters[i]); @@ -1216,11 +1123,9 @@ esfilter_init(void) esfilter_reindex(i); } -void -esfilter_done(void) -{ - esfilter_t *esf; - int i; +void esfilter_done(void) { + esfilter_t* esf; + int i; tvh_mutex_lock(&global_lock); for (i = 0; i <= ESF_CLASS_LAST; i++) { diff --git a/src/esfilter.h b/src/esfilter.h index 82957e3e7..ddbae02e1 100644 --- a/src/esfilter.h +++ b/src/esfilter.h @@ -33,8 +33,7 @@ typedef enum { ESF_CLASS_LAST = ESF_CLASS_OTHER } esfilter_class_t; -#define ESF_CLASS_IS_VALID(i) \ - ((i) >= ESF_CLASS_VIDEO && (i) <= ESF_CLASS_LAST) +#define ESF_CLASS_IS_VALID(i) ((i) >= ESF_CLASS_VIDEO && (i) <= ESF_CLASS_LAST) extern const idclass_t esfilter_class; extern const idclass_t esfilter_class_video; @@ -44,26 +43,22 @@ extern const idclass_t esfilter_class_subtit; extern const idclass_t esfilter_class_ca; extern const idclass_t esfilter_class_other; -#define ESF_MASK_VIDEO \ - (SCT_MASK(SCT_MPEG2VIDEO) | SCT_MASK(SCT_H264) | SCT_MASK(SCT_VP8) | \ - SCT_MASK(SCT_HEVC) | SCT_MASK(SCT_VP9) | SCT_MASK(SCT_THEORA)) +#define ESF_MASK_VIDEO \ + (SCT_MASK(SCT_MPEG2VIDEO) | SCT_MASK(SCT_H264) | SCT_MASK(SCT_VP8) | SCT_MASK(SCT_HEVC) | \ + SCT_MASK(SCT_VP9) | SCT_MASK(SCT_THEORA)) -#define ESF_MASK_AUDIO \ - (SCT_MASK(SCT_MPEG2AUDIO) | SCT_MASK(SCT_AC3) | SCT_MASK(SCT_AAC) | \ - SCT_MASK(SCT_EAC3) | SCT_MASK(SCT_MP4A) | SCT_MASK(SCT_VORBIS) | \ - SCT_MASK(SCT_OPUS) | SCT_MASK(SCT_FLAC) | SCT_MASK(SCT_AC4)) +#define ESF_MASK_AUDIO \ + (SCT_MASK(SCT_MPEG2AUDIO) | SCT_MASK(SCT_AC3) | SCT_MASK(SCT_AAC) | SCT_MASK(SCT_EAC3) | \ + SCT_MASK(SCT_MP4A) | SCT_MASK(SCT_VORBIS) | SCT_MASK(SCT_OPUS) | SCT_MASK(SCT_FLAC) | \ + SCT_MASK(SCT_AC4)) -#define ESF_MASK_TELETEXT \ - SCT_MASK(SCT_TELETEXT) +#define ESF_MASK_TELETEXT SCT_MASK(SCT_TELETEXT) -#define ESF_MASK_SUBTIT \ - (SCT_MASK(SCT_DVBSUB) | SCT_MASK(SCT_TEXTSUB)) +#define ESF_MASK_SUBTIT (SCT_MASK(SCT_DVBSUB) | SCT_MASK(SCT_TEXTSUB)) -#define ESF_MASK_CA \ - SCT_MASK(SCT_CA) +#define ESF_MASK_CA SCT_MASK(SCT_CA) -#define ESF_MASK_OTHER \ - (SCT_MASK(SCT_MPEGTS) | SCT_MASK(SCT_HBBTV) | SCT_MASK(SCT_RDS)) +#define ESF_MASK_OTHER (SCT_MASK(SCT_MPEGTS) | SCT_MASK(SCT_HBBTV) | SCT_MASK(SCT_RDS)) extern uint32_t esfilterclsmask[]; @@ -73,10 +68,10 @@ extern struct esfilter_entry_queue esfilters[]; typedef enum { ESFA_NONE = 0, - ESFA_USE, /* use this stream */ - ESFA_ONE_TIME, /* use this stream once per language */ - ESFA_EXCLUSIVE, /* use this stream exclusively */ - ESFA_EMPTY, /* use this stream when no streams were added */ + ESFA_USE, /* use this stream */ + ESFA_ONE_TIME, /* use this stream once per language */ + ESFA_EXCLUSIVE, /* use this stream exclusively */ + ESFA_EMPTY, /* use this stream when no streams were added */ ESFA_IGNORE, ESFA_LAST = ESFA_IGNORE } esfilter_action_t; @@ -85,27 +80,26 @@ typedef struct esfilter { idnode_t esf_id; TAILQ_ENTRY(esfilter) esf_link; - int esf_class; - int esf_save; - int esf_index; - int esf_enabled; + int esf_class; + int esf_save; + int esf_index; + int esf_enabled; uint32_t esf_type; - char esf_language[4]; - char esf_service[UUID_HEX_SIZE]; - int esf_sindex; - int esf_pid; + char esf_language[4]; + char esf_service[UUID_HEX_SIZE]; + int esf_sindex; + int esf_pid; uint16_t esf_caid; uint32_t esf_caprovider; - int esf_action; - int esf_log; - char *esf_comment; + int esf_action; + int esf_log; + char* esf_comment; } esfilter_t; -esfilter_t *esfilter_create - (esfilter_class_t esf_class, const char *uuid, htsmsg_t *conf, int save); +esfilter_t* esfilter_create(esfilter_class_t esf_class, const char* uuid, htsmsg_t* conf, int save); -const char * esfilter_class2txt(int cls); -const char * esfilter_action2txt(esfilter_action_t a); +const char* esfilter_class2txt(int cls); +const char* esfilter_action2txt(esfilter_action_t a); void esfilter_init(void); void esfilter_done(void); diff --git a/src/esstream.c b/src/esstream.c index 7f432da36..567d3ce5b 100644 --- a/src/esstream.c +++ b/src/esstream.c @@ -27,18 +27,17 @@ /** * */ -static void -elementary_stream_make_nicename(elementary_stream_t *st, const char *nicename) -{ +static void elementary_stream_make_nicename(elementary_stream_t* st, const char* nicename) { char buf[256]; - if(st->es_pid != -1) - snprintf(buf, sizeof(buf), "%s: %s @ #%d", - nicename, - streaming_component_type2txt(st->es_type), st->es_pid); + if (st->es_pid != -1) + snprintf(buf, + sizeof(buf), + "%s: %s @ #%d", + nicename, + streaming_component_type2txt(st->es_type), + st->es_pid); else - snprintf(buf, sizeof(buf), "%s: %s", - nicename, - streaming_component_type2txt(st->es_type)); + snprintf(buf, sizeof(buf), "%s: %s", nicename, streaming_component_type2txt(st->es_type)); free(st->es_nicename); st->es_nicename = strdup(buf); @@ -47,24 +46,21 @@ elementary_stream_make_nicename(elementary_stream_t *st, const char *nicename) /** * */ -void elementary_set_init - (elementary_set_t *set, int subsys, const char *nicename, service_t *t) -{ +void elementary_set_init(elementary_set_t* set, int subsys, const char* nicename, service_t* t) { TAILQ_INIT(&set->set_all); TAILQ_INIT(&set->set_filter); set->set_nicename = NULL; set->set_last_pid = -1; - set->set_last_es = NULL; - set->set_service = t; + set->set_last_es = NULL; + set->set_service = t; elementary_set_update_nicename(set, nicename); } /** * */ -void elementary_set_clean(elementary_set_t *set, service_t *t, int keep_nicename) -{ - elementary_stream_t *st; +void elementary_set_clean(elementary_set_t* set, service_t* t, int keep_nicename) { + elementary_stream_t* st; TAILQ_INIT(&set->set_filter); while ((st = TAILQ_FIRST(&set->set_all)) != NULL) @@ -79,84 +75,70 @@ void elementary_set_clean(elementary_set_t *set, service_t *t, int keep_nicename /** * */ -void elementary_set_update_nicename(elementary_set_t *set, const char *nicename) -{ - elementary_stream_t *st; +void elementary_set_update_nicename(elementary_set_t* set, const char* nicename) { + elementary_stream_t* st; free(set->set_nicename); set->set_nicename = nicename ? strdup(nicename) : NULL; - TAILQ_FOREACH(st, &set->set_all, es_link) + TAILQ_FOREACH (st, &set->set_all, es_link) elementary_stream_make_nicename(st, nicename); } /** * */ -static void -elementary_stream_init(elementary_stream_t *es) -{ +static void elementary_stream_init(elementary_stream_t* es) { es->es_cc = -1; } /** * */ -static void -elementary_stream_clean(elementary_stream_t *es) -{ +static void elementary_stream_clean(elementary_stream_t* es) { tvhlog_limit_reset(&es->es_cc_log); } /** * */ -void -elementary_set_clean_streams(elementary_set_t *set) -{ - elementary_stream_t *st; +void elementary_set_clean_streams(elementary_set_t* set) { + elementary_stream_t* st; - TAILQ_FOREACH(st, &set->set_all, es_link) + TAILQ_FOREACH (st, &set->set_all, es_link) elementary_stream_clean(st); } /** * */ -void -elementary_set_init_filter_streams(elementary_set_t *set) -{ - elementary_stream_t *st; +void elementary_set_init_filter_streams(elementary_set_t* set) { + elementary_stream_t* st; - TAILQ_FOREACH(st, &set->set_filter, es_filter_link) + TAILQ_FOREACH (st, &set->set_filter, es_filter_link) elementary_stream_init(st); } /** * */ -int -elementary_set_has_streams(elementary_set_t *set, int filtered) -{ - return filtered ? TAILQ_FIRST(&set->set_filter) != NULL : - TAILQ_FIRST(&set->set_all) != NULL; +int elementary_set_has_streams(elementary_set_t* set, int filtered) { + return filtered ? TAILQ_FIRST(&set->set_filter) != NULL : TAILQ_FIRST(&set->set_all) != NULL; } /** * */ -void -elementary_set_stream_destroy(elementary_set_t *set, elementary_stream_t *es) -{ - elementary_stream_t *es1; - caid_t *c; +void elementary_set_stream_destroy(elementary_set_t* set, elementary_stream_t* es) { + elementary_stream_t* es1; + caid_t* c; if (set->set_last_es == es) { set->set_last_pid = -1; - set->set_last_es = NULL; + set->set_last_es = NULL; } TAILQ_REMOVE(&set->set_all, es, es_link); - TAILQ_FOREACH(es1, &set->set_filter, es_filter_link) + TAILQ_FOREACH (es1, &set->set_filter, es_filter_link) if (es1 == es) { TAILQ_REMOVE(&set->set_filter, es, es_filter_link); break; @@ -174,14 +156,13 @@ elementary_set_stream_destroy(elementary_set_t *set, elementary_stream_t *es) /** * */ -#define ESFM_USED (1<<0) -#define ESFM_IGNORE (1<<1) - -static void -elementary_set_filter_build_add - (elementary_set_t *set, elementary_stream_t *st, - elementary_stream_t **sta, int *p) -{ +#define ESFM_USED (1 << 0) +#define ESFM_IGNORE (1 << 1) + +static void elementary_set_filter_build_add(elementary_set_t* set, + elementary_stream_t* st, + elementary_stream_t** sta, + int* p) { /* only once */ if (st->es_filter & ESFM_USED) return; @@ -194,28 +175,32 @@ elementary_set_filter_build_add /** * */ -static void -elementary_set_filter_print - (elementary_set_t *set) -{ - elementary_stream_t *st; - caid_t *ca; +static void elementary_set_filter_print(elementary_set_t* set) { + elementary_stream_t* st; + caid_t* ca; if (!tvhtrace_enabled()) return; - TAILQ_FOREACH(st, &set->set_filter, es_filter_link) { + TAILQ_FOREACH (st, &set->set_filter, es_filter_link) { if (LIST_EMPTY(&st->es_caids)) { - tvhtrace(set->set_subsys, "esfilter: \"%s\" %03d %05d %s %s", - set->set_nicename, st->es_index, st->es_pid, - streaming_component_type2txt(st->es_type), - lang_code_get(st->es_lang)); + tvhtrace(set->set_subsys, + "esfilter: \"%s\" %03d %05d %s %s", + set->set_nicename, + st->es_index, + st->es_pid, + streaming_component_type2txt(st->es_type), + lang_code_get(st->es_lang)); } else { - LIST_FOREACH(ca, &st->es_caids, link) + LIST_FOREACH (ca, &st->es_caids, link) if (ca->use) - tvhtrace(set->set_subsys, "esfilter: \"%s\" %03d %05d %s %04x %06x", - set->set_nicename, st->es_index, st->es_pid, - streaming_component_type2txt(st->es_type), - ca->caid, ca->providerid); + tvhtrace(set->set_subsys, + "esfilter: \"%s\" %03d %05d %s %04x %06x", + set->set_nicename, + st->es_index, + st->es_pid, + streaming_component_type2txt(st->es_type), + ca->caid, + ca->providerid); } } } @@ -223,16 +208,14 @@ elementary_set_filter_print /** * */ -void -elementary_set_filter_build(elementary_set_t *set) -{ - service_t *t; +void elementary_set_filter_build(elementary_set_t* set) { + service_t* t; elementary_stream_t *st, *st2, **sta; - esfilter_t *esf; - caid_t *ca, *ca2; - int i, n, p, o, exclusive, sindex; - uint32_t mask; - char service_ubuf[UUID_HEX_SIZE]; + esfilter_t* esf; + caid_t * ca, *ca2; + int i, n, p, o, exclusive, sindex; + uint32_t mask; + char service_ubuf[UUID_HEX_SIZE]; t = set->set_service; if (t == NULL) @@ -246,9 +229,9 @@ elementary_set_filter_build(elementary_set_t *set) if (!TAILQ_EMPTY(&esfilters[i])) goto filter; - TAILQ_FOREACH(st, &set->set_all, es_link) { + TAILQ_FOREACH (st, &set->set_all, es_link) { TAILQ_INSERT_TAIL(&set->set_filter, st, es_filter_link); - LIST_FOREACH(ca, &st->es_caids, link) + LIST_FOREACH (ca, &st->es_caids, link) ca->use = 1; } elementary_set_filter_print(set); @@ -256,42 +239,41 @@ elementary_set_filter_build(elementary_set_t *set) filter: n = 0; - TAILQ_FOREACH(st, &set->set_all, es_link) { + TAILQ_FOREACH (st, &set->set_all, es_link) { st->es_filter = 0; - LIST_FOREACH(ca, &st->es_caids, link) { - ca->use = 0; + LIST_FOREACH (ca, &st->es_caids, link) { + ca->use = 0; ca->filter = 0; } n++; } - sta = alloca(sizeof(elementary_stream_t *) * n); + sta = alloca(sizeof(elementary_stream_t*) * n); for (i = ESF_CLASS_VIDEO, p = 0; i <= ESF_CLASS_LAST; i++) { - o = p; + o = p; mask = esfilterclsmask[i]; if (TAILQ_EMPTY(&esfilters[i])) { - TAILQ_FOREACH(st, &set->set_all, es_link) { + TAILQ_FOREACH (st, &set->set_all, es_link) { if ((mask & SCT_MASK(st->es_type)) != 0) { elementary_set_filter_build_add(set, st, sta, &p); - LIST_FOREACH(ca, &st->es_caids, link) + LIST_FOREACH (ca, &st->es_caids, link) ca->use = 1; } } continue; } exclusive = 0; - TAILQ_FOREACH(esf, &esfilters[i], esf_link) { + TAILQ_FOREACH (esf, &esfilters[i], esf_link) { if (!esf->esf_enabled) continue; sindex = 0; - TAILQ_FOREACH(st, &set->set_all, es_link) { + TAILQ_FOREACH (st, &set->set_all, es_link) { if ((mask & SCT_MASK(st->es_type)) == 0) continue; if (esf->esf_type && (esf->esf_type & SCT_MASK(st->es_type)) == 0) continue; - if (esf->esf_language[0] && - strncmp(esf->esf_language, st->es_lang, 4)) + if (esf->esf_language[0] && strncmp(esf->esf_language, st->es_lang, 4)) continue; if (esf->esf_service[0]) { if (strcmp(esf->esf_service, service_ubuf)) @@ -304,7 +286,7 @@ filter: continue; ca = NULL; if ((esf->esf_caid != (uint16_t)-1 || esf->esf_caprovider != -1)) { - LIST_FOREACH(ca, &st->es_caids, link) { + LIST_FOREACH (ca, &st->es_caids, link) { if (esf->esf_caid != (uint16_t)-1 && ca->caid != esf->esf_caid) continue; if (esf->esf_caprovider != (uint32_t)-1 && ca->providerid != esf->esf_caprovider) @@ -318,103 +300,117 @@ filter: if (esf->esf_sindex && esf->esf_sindex != sindex) continue; if (esf->esf_log) - tvhinfo(LS_SERVICE, "esfilter: \"%s\" %s %03d %03d %05d %04x %06x %s", - t->s_nicename, esfilter_class2txt(i), st->es_index, - esf->esf_index, st->es_pid, esf->esf_caid, esf->esf_caprovider, - esfilter_action2txt(esf->esf_action)); + tvhinfo(LS_SERVICE, + "esfilter: \"%s\" %s %03d %03d %05d %04x %06x %s", + t->s_nicename, + esfilter_class2txt(i), + st->es_index, + esf->esf_index, + st->es_pid, + esf->esf_caid, + esf->esf_caprovider, + esfilter_action2txt(esf->esf_action)); switch (esf->esf_action) { - case ESFA_NONE: - break; - case ESFA_IGNORE: -ca_ignore: - if (ca == NULL) - LIST_FOREACH(ca, &st->es_caids, link) + case ESFA_NONE: + break; + case ESFA_IGNORE: + ca_ignore: + if (ca == NULL) + LIST_FOREACH (ca, &st->es_caids, link) + ca->filter |= ESFM_IGNORE; + else ca->filter |= ESFM_IGNORE; - else - ca->filter |= ESFM_IGNORE; - st->es_filter |= ESFM_IGNORE; - break; - case ESFA_ONE_TIME: - TAILQ_FOREACH(st2, &set->set_all, es_link) - if (st2->es_type == SCT_CA && (st2->es_filter & ESFM_USED) != 0) - break; - if (st2 != NULL) goto ca_ignore; - /* fall through */ - case ESFA_USE: - if (ca == NULL) - LIST_FOREACH(ca, &st->es_caids, link) + st->es_filter |= ESFM_IGNORE; + break; + case ESFA_ONE_TIME: + TAILQ_FOREACH (st2, &set->set_all, es_link) + if (st2->es_type == SCT_CA && (st2->es_filter & ESFM_USED) != 0) + break; + if (st2 != NULL) + goto ca_ignore; + /* fall through */ + case ESFA_USE: + if (ca == NULL) + LIST_FOREACH (ca, &st->es_caids, link) + ca->filter |= ESFM_USED; + else ca->filter |= ESFM_USED; - else - ca->filter |= ESFM_USED; - elementary_set_filter_build_add(set, st, sta, &p); - break; - case ESFA_EXCLUSIVE: - if (ca == NULL) - LIST_FOREACH(ca, &st->es_caids, link) - ca->use = 1; - else { - LIST_FOREACH(ca2, &st->es_caids, link) - ca2->use = 0; - ca->use = 1; - } - break; - case ESFA_EMPTY: - if (p == o) elementary_set_filter_build_add(set, st, sta, &p); - break; - default: - tvhdebug(LS_SERVICE, "Unknown esfilter action %d", esf->esf_action); - break; + break; + case ESFA_EXCLUSIVE: + if (ca == NULL) + LIST_FOREACH (ca, &st->es_caids, link) + ca->use = 1; + else { + LIST_FOREACH (ca2, &st->es_caids, link) + ca2->use = 0; + ca->use = 1; + } + break; + case ESFA_EMPTY: + if (p == o) + elementary_set_filter_build_add(set, st, sta, &p); + break; + default: + tvhdebug(LS_SERVICE, "Unknown esfilter action %d", esf->esf_action); + break; } } else { sindex++; if (esf->esf_sindex && esf->esf_sindex != sindex) continue; if (esf->esf_log) - tvhinfo(LS_SERVICE, "esfilter: \"%s\" %s %03d %03d %05d %s %s %s", - t->s_nicename, esfilter_class2txt(i), st->es_index, esf->esf_index, - st->es_pid, streaming_component_type2txt(st->es_type), - lang_code_get(st->es_lang), esfilter_action2txt(esf->esf_action)); + tvhinfo(LS_SERVICE, + "esfilter: \"%s\" %s %03d %03d %05d %s %s %s", + t->s_nicename, + esfilter_class2txt(i), + st->es_index, + esf->esf_index, + st->es_pid, + streaming_component_type2txt(st->es_type), + lang_code_get(st->es_lang), + esfilter_action2txt(esf->esf_action)); switch (esf->esf_action) { - case ESFA_NONE: - break; - case ESFA_IGNORE: -ignore: - st->es_filter |= ESFM_IGNORE; - break; - case ESFA_ONE_TIME: - TAILQ_FOREACH(st2, &set->set_all, es_link) { - if (st == st2) - continue; - if ((st2->es_filter & ESFM_USED) == 0) - continue; - if ((mask & SCT_MASK(st2->es_type)) == 0) - continue; - if (esf->esf_language[0] != '\0' && strcmp(st2->es_lang, st->es_lang)) - continue; + case ESFA_NONE: break; - } - if (st2 != NULL) goto ignore; - /* fall through */ - case ESFA_USE: - elementary_set_filter_build_add(set, st, sta, &p); - break; - case ESFA_EXCLUSIVE: - break; - case ESFA_EMPTY: - if (p == o) + case ESFA_IGNORE: + ignore: + st->es_filter |= ESFM_IGNORE; + break; + case ESFA_ONE_TIME: + TAILQ_FOREACH (st2, &set->set_all, es_link) { + if (st == st2) + continue; + if ((st2->es_filter & ESFM_USED) == 0) + continue; + if ((mask & SCT_MASK(st2->es_type)) == 0) + continue; + if (esf->esf_language[0] != '\0' && strcmp(st2->es_lang, st->es_lang)) + continue; + break; + } + if (st2 != NULL) + goto ignore; + /* fall through */ + case ESFA_USE: elementary_set_filter_build_add(set, st, sta, &p); - break; - default: - tvhdebug(LS_SERVICE, "Unknown esfilter action %d", esf->esf_action); - break; + break; + case ESFA_EXCLUSIVE: + break; + case ESFA_EMPTY: + if (p == o) + elementary_set_filter_build_add(set, st, sta, &p); + break; + default: + tvhdebug(LS_SERVICE, "Unknown esfilter action %d", esf->esf_action); + break; } } if (esf->esf_action == ESFA_EXCLUSIVE) { /* forget previous work */ while (p > o) { p--; - LIST_FOREACH(ca, &sta[p]->es_caids, link) + LIST_FOREACH (ca, &sta[p]->es_caids, link) ca->use = 0; TAILQ_REMOVE(&set->set_filter, sta[p], es_filter_link); } @@ -424,17 +420,18 @@ ignore: break; } } - if (exclusive) break; + if (exclusive) + break; } if (!exclusive) { - TAILQ_FOREACH(st, &set->set_all, es_link) { + TAILQ_FOREACH (st, &set->set_all, es_link) { if ((mask & SCT_MASK(st->es_type)) != 0 && - (st->es_filter & (ESFM_USED|ESFM_IGNORE)) == 0) { + (st->es_filter & (ESFM_USED | ESFM_IGNORE)) == 0) { elementary_set_filter_build_add(set, st, sta, &p); - LIST_FOREACH(ca, &st->es_caids, link) + LIST_FOREACH (ca, &st->es_caids, link) ca->use = 1; } else { - LIST_FOREACH(ca, &st->es_caids, link) + LIST_FOREACH (ca, &st->es_caids, link) if (ca->filter & ESFM_USED) ca->use = 1; } @@ -448,17 +445,17 @@ ignore: /** * Add a new stream to a service */ -elementary_stream_t * -elementary_stream_create_parent - (elementary_set_t *set, int pid, int parent_pid, streaming_component_type_t type) -{ - elementary_stream_t *st; - int idx = 0; - - TAILQ_FOREACH(st, &set->set_all, es_link) { - if(st->es_index > idx) +elementary_stream_t* elementary_stream_create_parent(elementary_set_t* set, + int pid, + int parent_pid, + streaming_component_type_t type) { + elementary_stream_t* st; + int idx = 0; + + TAILQ_FOREACH (st, &set->set_all, es_link) { + if (st->es_index > idx) idx = st->es_index; - if(pid != -1 && st->es_pid == pid) { + if (pid != -1 && st->es_pid == pid) { if (parent_pid >= 0 && st->es_parent_pid != parent_pid) goto create; return st; @@ -466,16 +463,16 @@ elementary_stream_create_parent } create: - st = calloc(1, sizeof(elementary_stream_t)); + st = calloc(1, sizeof(elementary_stream_t)); st->es_index = idx + 1; st->es_type = type; - st->es_cc = -1; + st->es_cc = -1; TAILQ_INSERT_TAIL(&set->set_all, st, es_link); st->es_service = set->set_service; - st->es_pid = pid; + st->es_pid = pid; st->es_parent_pid = parent_pid > 0 ? parent_pid : 0; elementary_stream_make_nicename(st, set->set_nicename); @@ -486,14 +483,12 @@ create: /** * Find an elementary stream in a service */ -elementary_stream_t * -elementary_stream_find_(elementary_set_t *set, int pid) -{ - elementary_stream_t *st; - - TAILQ_FOREACH(st, &set->set_all, es_link) { - if(st->es_pid == pid) { - set->set_last_es = st; +elementary_stream_t* elementary_stream_find_(elementary_set_t* set, int pid) { + elementary_stream_t* st; + + TAILQ_FOREACH (st, &set->set_all, es_link) { + if (st->es_pid == pid) { + set->set_last_es = st; set->set_last_pid = pid; return st; } @@ -504,13 +499,11 @@ elementary_stream_find_(elementary_set_t *set, int pid) /** * Find an elementary stream in a service with specific parent pid */ -elementary_stream_t * -elementary_stream_find_parent(elementary_set_t *set, int pid, int parent_pid) -{ - elementary_stream_t *st; +elementary_stream_t* elementary_stream_find_parent(elementary_set_t* set, int pid, int parent_pid) { + elementary_stream_t* st; - TAILQ_FOREACH(st, &set->set_all, es_link) { - if(st->es_pid == pid && st->es_parent_pid == parent_pid) + TAILQ_FOREACH (st, &set->set_all, es_link) { + if (st->es_pid == pid && st->es_parent_pid == parent_pid) return st; } return NULL; @@ -519,14 +512,12 @@ elementary_stream_find_parent(elementary_set_t *set, int pid, int parent_pid) /** * Find a first elementary stream in a service (by type) */ -elementary_stream_t * -elementary_stream_type_find - (elementary_set_t *set, streaming_component_type_t type) -{ - elementary_stream_t *st; - - TAILQ_FOREACH(st, &set->set_all, es_link) - if(st->es_type == type) +elementary_stream_t* elementary_stream_type_find(elementary_set_t* set, + streaming_component_type_t type) { + elementary_stream_t* st; + + TAILQ_FOREACH (st, &set->set_all, es_link) + if (st->es_type == type) return st; return NULL; } @@ -534,11 +525,9 @@ elementary_stream_type_find /** * */ -elementary_stream_t * -elementary_stream_type_modify(elementary_set_t *set, int pid, - streaming_component_type_t type) -{ - elementary_stream_t *es = elementary_stream_type_find(set, type); +elementary_stream_t* +elementary_stream_type_modify(elementary_set_t* set, int pid, streaming_component_type_t type) { + elementary_stream_t* es = elementary_stream_type_find(set, type); if (!es) return elementary_stream_create(set, pid, type); if (es->es_pid != pid) @@ -549,11 +538,8 @@ elementary_stream_type_modify(elementary_set_t *set, int pid, /** * */ -void -elementary_stream_type_destroy - (elementary_set_t *set, streaming_component_type_t type) -{ - elementary_stream_t *es = elementary_stream_type_find(set, type); +void elementary_stream_type_destroy(elementary_set_t* set, streaming_component_type_t type) { + elementary_stream_t* es = elementary_stream_type_find(set, type); if (es) elementary_set_stream_destroy(set, es); } @@ -561,26 +547,22 @@ elementary_stream_type_destroy /** * */ -int -elementary_stream_has_audio_or_video(elementary_set_t *set) -{ - elementary_stream_t *st; - TAILQ_FOREACH(st, &set->set_all, es_link) +int elementary_stream_has_audio_or_video(elementary_set_t* set) { + elementary_stream_t* st; + TAILQ_FOREACH (st, &set->set_all, es_link) if (SCT_ISVIDEO(st->es_type) || SCT_ISAUDIO(st->es_type)) return 1; return 0; } -int -elementary_stream_has_no_audio(elementary_set_t *set, int filtered) -{ - elementary_stream_t *st; +int elementary_stream_has_no_audio(elementary_set_t* set, int filtered) { + elementary_stream_t* st; if (filtered) { - TAILQ_FOREACH(st, &set->set_filter, es_filter_link) + TAILQ_FOREACH (st, &set->set_filter, es_filter_link) if (SCT_ISAUDIO(st->es_type)) return 0; } else { - TAILQ_FOREACH(st, &set->set_all, es_link) + TAILQ_FOREACH (st, &set->set_all, es_link) if (SCT_ISAUDIO(st->es_type)) return 0; } @@ -590,63 +572,56 @@ elementary_stream_has_no_audio(elementary_set_t *set, int filtered) /** * */ -static int -escmp(const void *A, const void *B) -{ - elementary_stream_t *a = *(elementary_stream_t **)A; - elementary_stream_t *b = *(elementary_stream_t **)B; +static int escmp(const void* A, const void* B) { + elementary_stream_t* a = *(elementary_stream_t**)A; + elementary_stream_t* b = *(elementary_stream_t**)B; return a->es_position - b->es_position; } /** * */ -void -elementary_set_sort_streams(elementary_set_t *set) -{ +void elementary_set_sort_streams(elementary_set_t* set) { elementary_stream_t *st, **v; - int num = 0, i = 0; + int num = 0, i = 0; - TAILQ_FOREACH(st, &set->set_all, es_link) + TAILQ_FOREACH (st, &set->set_all, es_link) num++; - v = alloca(num * sizeof(elementary_stream_t *)); - TAILQ_FOREACH(st, &set->set_all, es_link) + v = alloca(num * sizeof(elementary_stream_t*)); + TAILQ_FOREACH (st, &set->set_all, es_link) v[i++] = st; - qsort(v, num, sizeof(elementary_stream_t *), escmp); + qsort(v, num, sizeof(elementary_stream_t*), escmp); TAILQ_INIT(&set->set_all); - for(i = 0; i < num; i++) + for (i = 0; i < num; i++) TAILQ_INSERT_TAIL(&set->set_all, v[i], es_link); } /** * Generate a message containing info about all components */ -streaming_start_t * -elementary_stream_build_start(elementary_set_t *set) -{ - elementary_stream_t *st; - streaming_start_t *ss; - int n = 0; - - TAILQ_FOREACH(st, &set->set_filter, es_filter_link) +streaming_start_t* elementary_stream_build_start(elementary_set_t* set) { + elementary_stream_t* st; + streaming_start_t* ss; + int n = 0; + + TAILQ_FOREACH (st, &set->set_filter, es_filter_link) n++; - ss = calloc(1, sizeof(streaming_start_t) + - sizeof(streaming_start_component_t) * n); + ss = calloc(1, sizeof(streaming_start_t) + sizeof(streaming_start_component_t) * n); ss->ss_num_components = n; n = 0; - TAILQ_FOREACH(st, &set->set_filter, es_filter_link) { - streaming_start_component_t *ssc = &ss->ss_components[n++]; - *(elementary_info_t *)ssc = *(elementary_info_t *)st; + TAILQ_FOREACH (st, &set->set_filter, es_filter_link) { + streaming_start_component_t* ssc = &ss->ss_components[n++]; + *(elementary_info_t*)ssc = *(elementary_info_t*)st; } - ss->ss_pcr_pid = set->set_pcr_pid; - ss->ss_pmt_pid = set->set_pmt_pid; + ss->ss_pcr_pid = set->set_pcr_pid; + ss->ss_pmt_pid = set->set_pmt_pid; ss->ss_service_id = set->set_service_id; ss->ss_refcount = 1; @@ -656,28 +631,26 @@ elementary_stream_build_start(elementary_set_t *set) /** * Create back elementary streams from the start message. */ -elementary_set_t * -elementary_stream_create_from_start - (elementary_set_t *set, streaming_start_t *ss, size_t es_size) -{ - elementary_stream_t *st; - int n; +elementary_set_t* +elementary_stream_create_from_start(elementary_set_t* set, streaming_start_t* ss, size_t es_size) { + elementary_stream_t* st; + int n; /* we expect the empty set */ assert(TAILQ_FIRST(&set->set_all) == NULL); assert(TAILQ_FIRST(&set->set_filter) == NULL); for (n = 0; n < ss->ss_num_components; n++) { - streaming_start_component_t *ssc = &ss->ss_components[n]; - st = calloc(1, es_size ?: sizeof(*st)); - *(elementary_info_t *)st = *(elementary_info_t *)ssc; - st->es_service = set->set_service; + streaming_start_component_t* ssc = &ss->ss_components[n]; + st = calloc(1, es_size ?: sizeof(*st)); + *(elementary_info_t*)st = *(elementary_info_t*)ssc; + st->es_service = set->set_service; elementary_stream_make_nicename(st, set->set_nicename); TAILQ_INSERT_TAIL(&set->set_all, st, es_link); } - set->set_pcr_pid = ss->ss_pcr_pid; - set->set_pmt_pid = ss->ss_pmt_pid; + set->set_pcr_pid = ss->ss_pcr_pid; + set->set_pmt_pid = ss->ss_pmt_pid; set->set_service_id = ss->ss_service_id; return set; diff --git a/src/esstream.h b/src/esstream.h index 592a6933d..253005514 100644 --- a/src/esstream.h +++ b/src/esstream.h @@ -26,26 +26,26 @@ /** * */ -typedef struct service service_t; +typedef struct service service_t; typedef struct streaming_start streaming_start_t; typedef enum streaming_component_type streaming_component_type_t; -typedef struct elementary_info elementary_info_t; -typedef struct elementary_stream elementary_stream_t; -typedef struct elementary_set elementary_set_t; +typedef struct elementary_info elementary_info_t; +typedef struct elementary_stream elementary_stream_t; +typedef struct elementary_set elementary_set_t; /** * Stream component types */ enum streaming_component_type { - SCT_NONE = -1, + SCT_NONE = -1, SCT_UNKNOWN = 0, - SCT_RAW = 1, - SCT_PCR, /* MPEG-TS PCR data */ - SCT_CAT, /* MPEG-TS CAT (EMM) data */ - SCT_CA, /* MPEG-TS ECM data */ - SCT_HBBTV, /* HBBTV info */ - SCT_RDS, /* Radio Data System */ + SCT_RAW = 1, + SCT_PCR, /* MPEG-TS PCR data */ + SCT_CAT, /* MPEG-TS CAT (EMM) data */ + SCT_CA, /* MPEG-TS ECM data */ + SCT_HBBTV, /* HBBTV info */ + SCT_RDS, /* Radio Data System */ /* standard codecs */ SCT_MPEG2VIDEO, SCT_MPEG2AUDIO, @@ -53,11 +53,11 @@ enum streaming_component_type { SCT_AC3, SCT_TELETEXT, SCT_DVBSUB, - SCT_AAC, /* AAC-LATM in MPEG-TS, ADTS + AAC in packet form */ + SCT_AAC, /* AAC-LATM in MPEG-TS, ADTS + AAC in packet form */ SCT_MPEGTS, SCT_TEXTSUB, SCT_EAC3, - SCT_MP4A, /* ADTS + AAC in MPEG-TS and packet form */ + SCT_MP4A, /* ADTS + AAC in MPEG-TS and packet form */ SCT_VP8, SCT_VORBIS, SCT_HEVC, @@ -71,15 +71,14 @@ enum streaming_component_type { #define SCT_MASK(t) (1 << (t)) -#define SCT_ISVIDEO(t) ((t) == SCT_MPEG2VIDEO || (t) == SCT_H264 || \ - (t) == SCT_VP8 || (t) == SCT_HEVC || \ - (t) == SCT_VP9 || (t) == SCT_THEORA) +#define SCT_ISVIDEO(t) \ + ((t) == SCT_MPEG2VIDEO || (t) == SCT_H264 || (t) == SCT_VP8 || (t) == SCT_HEVC || \ + (t) == SCT_VP9 || (t) == SCT_THEORA) -#define SCT_ISAUDIO(t) ((t) == SCT_MPEG2AUDIO || (t) == SCT_AC3 || \ - (t) == SCT_AAC || (t) == SCT_MP4A || \ - (t) == SCT_EAC3 || (t) == SCT_VORBIS || \ - (t) == SCT_OPUS || (t) == SCT_FLAC || \ - (t) == SCT_AC4) +#define SCT_ISAUDIO(t) \ + ((t) == SCT_MPEG2AUDIO || (t) == SCT_AC3 || (t) == SCT_AAC || (t) == SCT_MP4A || \ + (t) == SCT_EAC3 || (t) == SCT_VORBIS || (t) == SCT_OPUS || (t) == SCT_FLAC || \ + (t) == SCT_AC4) #define SCT_ISAV(t) (SCT_ISVIDEO(t) || SCT_ISAUDIO(t)) @@ -89,9 +88,9 @@ enum streaming_component_type { * Stream info, one media component for a service. */ struct elementary_info { - int es_index; + int es_index; int16_t es_pid; - int es_type; + int es_type; int es_frame_duration; @@ -101,20 +100,20 @@ struct elementary_info { uint16_t es_aspect_num; uint16_t es_aspect_den; - char es_lang[4]; /* ISO 639 2B 3-letter language code */ - uint8_t es_audio_type; /* Audio type */ - uint8_t es_audio_version; /* Audio version/layer */ - uint8_t es_sri; - uint8_t es_ext_sri; + char es_lang[4]; /* ISO 639 2B 3-letter language code */ + uint8_t es_audio_type; /* Audio type */ + uint8_t es_audio_version; /* Audio version/layer */ + uint8_t es_sri; + uint8_t es_ext_sri; uint16_t es_channels; - uint8_t es_rds_uecp; /* RDS via UECP data present */ + uint8_t es_rds_uecp; /* RDS via UECP data present */ uint16_t es_composition_id; uint16_t es_ancillary_id; - uint16_t es_parent_pid; /* For subtitle streams originating from - a teletext stream. this is the pid - of the teletext stream */ + uint16_t es_parent_pid; /* For subtitle streams originating from + a teletext stream. this is the pid + of the teletext stream */ }; /** @@ -126,19 +125,19 @@ struct elementary_stream { TAILQ_ENTRY(elementary_stream) es_link; TAILQ_ENTRY(elementary_stream) es_filter_link; - uint32_t es_position; - struct service *es_service; - char *es_nicename; + uint32_t es_position; + struct service* es_service; + char* es_nicename; /* PID related */ - int8_t es_pid_opened; /* PID is opened */ - int8_t es_cc; /* Last CC */ - int8_t es_delete_me; /* Temporary flag for deleting streams */ + int8_t es_pid_opened; /* PID is opened */ + int8_t es_cc; /* Last CC */ + int8_t es_delete_me; /* Temporary flag for deleting streams */ struct caid_list es_caids; /* CA ID's on this stream */ - tvhlog_limit_t es_cc_log; /* CC error log limiter */ - uint32_t es_filter; /* Filter temporary variable */ + tvhlog_limit_t es_cc_log; /* CC error log limiter */ + uint32_t es_filter; /* Filter temporary variable */ }; /* @@ -148,58 +147,56 @@ struct elementary_set { TAILQ_HEAD(, elementary_stream) set_all; TAILQ_HEAD(, elementary_stream) set_filter; - uint16_t set_pmt_pid; /* PMT PID number */ - uint16_t set_pcr_pid; /* PCR PID number */ - uint16_t set_service_id; /* MPEG-TS DVB service ID number */ + uint16_t set_pmt_pid; /* PMT PID number */ + uint16_t set_pcr_pid; /* PCR PID number */ + uint16_t set_service_id; /* MPEG-TS DVB service ID number */ - int set_subsys; - char *set_nicename; - service_t *set_service; + int set_subsys; + char* set_nicename; + service_t* set_service; /* Cache lookups */ - uint16_t set_last_pid; - elementary_stream_t *set_last_es; + uint16_t set_last_pid; + elementary_stream_t* set_last_es; }; /* * Prototypes */ -void elementary_set_init - (elementary_set_t *set, int subsys, const char *nicename, service_t *t); -void elementary_set_clean(elementary_set_t *set, service_t *t, int keep_nicename); -void elementary_set_update_nicename(elementary_set_t *set, const char *nicename); -void elementary_set_clean_streams(elementary_set_t *set); -void elementary_set_stream_destroy(elementary_set_t *set, elementary_stream_t *es); -void elementary_set_init_filter_streams(elementary_set_t *set); -void elementary_set_filter_build(elementary_set_t *set); -elementary_stream_t *elementary_stream_create_parent - (elementary_set_t *set, int pid, int parent_pid, streaming_component_type_t type); -static inline elementary_stream_t *elementary_stream_create - (elementary_set_t *set, int pid, streaming_component_type_t type) -{ return elementary_stream_create_parent(set, pid, -1, type); } -elementary_stream_t *elementary_stream_find_(elementary_set_t *set, int pid); -elementary_stream_t *elementary_stream_type_find - (elementary_set_t *set, streaming_component_type_t type); -static inline elementary_stream_t *elementary_stream_find - (elementary_set_t *set, int pid) - { - if (set->set_last_pid != (pid)) - return elementary_stream_find_(set, pid); - else - return set->set_last_es; - } -elementary_stream_t *elementary_stream_find_parent(elementary_set_t *set, int pid, int parent_pid); -elementary_stream_t *elementary_stream_type_modify - (elementary_set_t *set, int pid, streaming_component_type_t type); -void elementary_stream_type_destroy - (elementary_set_t *set, streaming_component_type_t type); -int elementary_stream_has_audio_or_video(elementary_set_t *set); -int elementary_stream_has_no_audio(elementary_set_t *set, int filtered); -int elementary_set_has_streams(elementary_set_t *set, int filtered); -void elementary_set_sort_streams(elementary_set_t *set); -streaming_start_t *elementary_stream_build_start(elementary_set_t *set); -elementary_set_t *elementary_stream_create_from_start - (elementary_set_t *set, streaming_start_t *ss, size_t es_size); - +void elementary_set_init(elementary_set_t* set, int subsys, const char* nicename, service_t* t); +void elementary_set_clean(elementary_set_t* set, service_t* t, int keep_nicename); +void elementary_set_update_nicename(elementary_set_t* set, const char* nicename); +void elementary_set_clean_streams(elementary_set_t* set); +void elementary_set_stream_destroy(elementary_set_t* set, elementary_stream_t* es); +void elementary_set_init_filter_streams(elementary_set_t* set); +void elementary_set_filter_build(elementary_set_t* set); +elementary_stream_t* elementary_stream_create_parent(elementary_set_t* set, + int pid, + int parent_pid, + streaming_component_type_t type); +static inline elementary_stream_t* +elementary_stream_create(elementary_set_t* set, int pid, streaming_component_type_t type) { + return elementary_stream_create_parent(set, pid, -1, type); +} +elementary_stream_t* elementary_stream_find_(elementary_set_t* set, int pid); +elementary_stream_t* elementary_stream_type_find(elementary_set_t* set, + streaming_component_type_t type); +static inline elementary_stream_t* elementary_stream_find(elementary_set_t* set, int pid) { + if (set->set_last_pid != (pid)) + return elementary_stream_find_(set, pid); + else + return set->set_last_es; +} +elementary_stream_t* elementary_stream_find_parent(elementary_set_t* set, int pid, int parent_pid); +elementary_stream_t* + elementary_stream_type_modify(elementary_set_t* set, int pid, streaming_component_type_t type); +void elementary_stream_type_destroy(elementary_set_t* set, streaming_component_type_t type); +int elementary_stream_has_audio_or_video(elementary_set_t* set); +int elementary_stream_has_no_audio(elementary_set_t* set, int filtered); +int elementary_set_has_streams(elementary_set_t* set, int filtered); +void elementary_set_sort_streams(elementary_set_t* set); +streaming_start_t* elementary_stream_build_start(elementary_set_t* set); +elementary_set_t* +elementary_stream_create_from_start(elementary_set_t* set, streaming_start_t* ss, size_t es_size); #endif // ESSTREAM_H__ diff --git a/src/extra/capmt_ca.c b/src/extra/capmt_ca.c index e6e83e832..5633b2e2d 100644 --- a/src/extra/capmt_ca.c +++ b/src/extra/capmt_ca.c @@ -21,7 +21,7 @@ * Boston, MA 02110-1301 USA */ -//#define DEBUG +// #define DEBUG #if defined(__GNUC__) && !defined(__STRICT_ANSI__) @@ -49,7 +49,7 @@ #ifndef CA_SET_PID /* removed in kernel 4.14 */ typedef struct ca_pid { unsigned int pid; - int index; /* -1 == disable */ + int index; /* -1 == disable */ } ca_pid_t; #define CA_SET_PID _IOW('o', 135, struct ca_pid) #endif @@ -57,69 +57,127 @@ typedef struct ca_pid { #if defined(RTLD_NEXT) #define REAL_LIBC RTLD_NEXT #else -#define REAL_LIBC ((void *) -1L) +#define REAL_LIBC ((void*)-1L) #endif -#define PORT 9000 -#define MAX_CA 4 +#define PORT 9000 +#define MAX_CA 4 -static int cafd[MAX_CA] = {-1,-1,-1,-1}; -static int cafdc[MAX_CA] = {0,0,0,0}; +static int cafd[MAX_CA] = {-1, -1, -1, -1}; +static int cafdc[MAX_CA] = {0, 0, 0, 0}; #define MAX_INDEX 64 #define KEY_SIZE 8 -#define INFO_SIZE (2+KEY_SIZE+KEY_SIZE) +#define INFO_SIZE (2 + KEY_SIZE + KEY_SIZE) #define EVEN_OFF (2) -#define ODD_OFF (2+KEY_SIZE) +#define ODD_OFF (2 + KEY_SIZE) static unsigned char ca_info[MAX_CA][MAX_INDEX][INFO_SIZE]; -#define CA_BASE "/dev/dvb/adapter0/ca" -#define DEMUX_BASE "/dev/dvb/adapter0/demux" -#define DEMUX_MAP "/dev/dvb/adapter%d/demux0" -#define CPUINFO_BASE "/proc/cpuinfo" -#define CPUINFO_MAP "/tmp/cpuinfo" +#define CA_BASE "/dev/dvb/adapter0/ca" +#define DEMUX_BASE "/dev/dvb/adapter0/demux" +#define DEMUX_MAP "/dev/dvb/adapter%d/demux0" +#define CPUINFO_BASE "/proc/cpuinfo" +#define CPUINFO_MAP "/tmp/cpuinfo" #if 1 #define DBG(x...) -#define INF(x...) {syslog(LOG_INFO, x);} -#define ERR(x...) {syslog(LOG_ERR, x);} +#define INF(x...) \ + { syslog(LOG_INFO, x); } +#define ERR(x...) \ + { syslog(LOG_ERR, x); } #else -#define DBG(...) { printf(__VA_ARGS__); printf("\n"); } -#define INF(...) { printf(__VA_ARGS__); printf("\n"); } -#define ERR(...) { printf(__VA_ARGS__); printf("\n"); } +#define DBG(...) \ + { \ + printf(__VA_ARGS__); \ + printf("\n"); \ + } +#define INF(...) \ + { \ + printf(__VA_ARGS__); \ + printf("\n"); \ + } +#define ERR(...) \ + { \ + printf(__VA_ARGS__); \ + printf("\n"); \ + } #endif -int proginfo=0; -#define PROGINFO() {if(!proginfo){syslog(LOG_INFO,"capmt_ca.so for camd clients");proginfo=1;}} +int proginfo = 0; +#define PROGINFO() \ + { \ + if (!proginfo) { \ + syslog(LOG_INFO, "capmt_ca.so for camd clients"); \ + proginfo = 1; \ + } \ + } -int sendcw(int fd, unsigned char *buff) { - DBG(">>>>>>>> sendcw %02x%02x %02x%02x%02x%02x%02x%02x%02x%02x %02x%02x%02x%02x%02x%02x%02x%02x", buff[0], buff[1], buff[2], buff[3], buff[4], buff[5], buff[6], buff[7], buff[8], buff[9], buff[10], buff[11], buff[12], buff[13], buff[14], buff[15], buff[16], buff[17], buff[18]); - if ( send(fd,buff, 18, 0) == -1 ) { - ERR("ca.so: Send cw failed %d", errno); +int sendcw(int fd, unsigned char* buff) { + DBG(">>>>>>>> sendcw %02x%02x %02x%02x%02x%02x%02x%02x%02x%02x %02x%02x%02x%02x%02x%02x%02x%02x", + buff[0], + buff[1], + buff[2], + buff[3], + buff[4], + buff[5], + buff[6], + buff[7], + buff[8], + buff[9], + buff[10], + buff[11], + buff[12], + buff[13], + buff[14], + buff[15], + buff[16], + buff[17], + buff[18]); + if (send(fd, buff, 18, 0) == -1) { + ERR("ca.so: Send cw failed %d", errno); return 0; } // if return 1; } // sendcw -static int cactl (int fd, int cai, int request, void *argp) { - ca_descr_t *ca = (ca_descr_t *)argp; - ca_pid_t *cpd = (ca_pid_t *)argp; +static int cactl(int fd, int cai, int request, void* argp) { + ca_descr_t* ca = (ca_descr_t*)argp; + ca_pid_t* cpd = (ca_pid_t*)argp; switch (request) { case CA_SET_DESCR: - DBG(">>>>>>>> cactl CA_SET_DESCR fd %d cai %d req %d par %d idx %d %02x%02x%02x%02x%02x%02x%02x%02x", fd, cai, request, ca->parity, ca->index, ca->cw[0], ca->cw[1], ca->cw[2], ca->cw[3], ca->cw[4], ca->cw[5], ca->cw[6], ca->cw[7]); - if(ca->parity==0) - memcpy(&ca_info[cai][ca->index][EVEN_OFF],ca->cw,KEY_SIZE); // even key - else if(ca->parity==1) - memcpy(&ca_info[cai][ca->index][ODD_OFF],ca->cw,KEY_SIZE); // odd key + DBG(">>>>>>>> cactl CA_SET_DESCR fd %d cai %d req %d par %d idx %d " + "%02x%02x%02x%02x%02x%02x%02x%02x", + fd, + cai, + request, + ca->parity, + ca->index, + ca->cw[0], + ca->cw[1], + ca->cw[2], + ca->cw[3], + ca->cw[4], + ca->cw[5], + ca->cw[6], + ca->cw[7]); + if (ca->parity == 0) + memcpy(&ca_info[cai][ca->index][EVEN_OFF], ca->cw, KEY_SIZE); // even key + else if (ca->parity == 1) + memcpy(&ca_info[cai][ca->index][ODD_OFF], ca->cw, KEY_SIZE); // odd key else ERR("ca.so: Invalid parity %d in CA_SET_DESCR for ca id %d", ca->parity, cai); sendcw(fd, ca_info[cai][ca->index]); break; case CA_SET_PID: - DBG(">>>>>>>> cactl CA_SET_PID fd %d cai %d req %d (%d %04x)", fd, cai, request, cpd->index, cpd->pid); - if (cpd->index >=0 && cpd->index < MAX_INDEX) { + DBG(">>>>>>>> cactl CA_SET_PID fd %d cai %d req %d (%d %04x)", + fd, + cai, + request, + cpd->index, + cpd->pid); + if (cpd->index >= 0 && cpd->index < MAX_INDEX) { ca_info[cai][cpd->index][0] = (cpd->pid >> 0) & 0xff; - ca_info[cai][cpd->index][1] = (cpd->pid >> 8) & 0xff; + ca_info[cai][cpd->index][1] = (cpd->pid >> 8) & 0xff; } else if (cpd->index == -1) { memset(&ca_info[cai], 0, sizeof(ca_info[cai])); } else @@ -136,20 +194,20 @@ static int cactl (int fd, int cai, int request, void *argp) { break; default: DBG(">>>>>>>> cactl unhandled req %d cai %d", request, cai); - //errno = EINVAL; - //return -1; + // errno = EINVAL; + // return -1; } // switch return 0; } // cactl -/* +/* CPU Model Brcm4380 V4.2 // DM8000 Brcm7401 V0.0 // DM800 MIPS 4KEc V4.8 // DM7025 */ -static const char *cpuinfo_file = "\ +static const char* cpuinfo_file = "\ system type : ATI XILLEON HDTV SUPERTOLL\n\ processor : 0\n\ cpu model : Brcm4380 V4.2\n\ @@ -163,94 +221,96 @@ VCED exceptions : not available\n\ VCEI exceptions : not available\n\ "; -int write_cpuinfo (void) { - static FILE* (*func) (const char *, const char *) = NULL; - func = (FILE* (*) (const char *, const char *)) dlsym (REAL_LIBC, "fopen"); +int write_cpuinfo(void) { + static FILE* (*func)(const char*, const char*) = NULL; + func = (FILE * (*)(const char*, const char*)) dlsym(REAL_LIBC, "fopen"); FILE* file = func(CPUINFO_MAP, "w"); - - - if(file == NULL) { - printf("error \"%s\" opening file\n", strerror(errno)); - return -1; + + if (file == NULL) { + printf("error \"%s\" opening file\n", strerror(errno)); + return -1; } int ret = fwrite(cpuinfo_file, strlen(cpuinfo_file), 1, file); fclose(file); return 0; } -FILE *fopen(const char *path, const char *mode){ - static FILE* (*func) (const char *, const char *) = NULL; +FILE* fopen(const char* path, const char* mode) { + static FILE* (*func)(const char*, const char*) = NULL; write_cpuinfo(); - if (!func) func = (FILE* (*) (const char *, const char *)) dlsym (REAL_LIBC, "fopen"); + if (!func) + func = (FILE * (*)(const char*, const char*)) dlsym(REAL_LIBC, "fopen"); if (!strcmp(path, CPUINFO_BASE)) { INF("ca.so fopen %s mapped to %s", path, CPUINFO_MAP); - return (*func) (CPUINFO_MAP, mode); + return (*func)(CPUINFO_MAP, mode); } // if DBG(">>>>>>>> fopen %s", path); - return (*func) (path, mode); + return (*func)(path, mode); } // fopen - -int open (const char *pathname, int flags, ...) { - static int (*func) (const char *, int, mode_t) = NULL; - if (!func) func = (int (*) (const char *, int, mode_t)) dlsym (REAL_LIBC, "open"); + +int open(const char* pathname, int flags, ...) { + static int (*func)(const char*, int, mode_t) = NULL; + if (!func) + func = (int (*)(const char*, int, mode_t))dlsym(REAL_LIBC, "open"); PROGINFO(); - + va_list args; - mode_t mode; + mode_t mode; - va_start (args, flags); - mode = va_arg (args, mode_t); - va_end (args); + va_start(args, flags); + mode = va_arg(args, mode_t); + va_end(args); - if(strstr(pathname, CA_BASE)) { - int cai=pathname[strlen(CA_BASE)]-'0'; - if((cai >= 0) && (cai < MAX_CA)) { + if (strstr(pathname, CA_BASE)) { + int cai = pathname[strlen(CA_BASE)] - '0'; + if ((cai >= 0) && (cai < MAX_CA)) { DBG(">>>>>>>> open cafd[%d] flags %d %s (%d)", cai, flags, pathname, cafdc[cai]); - if(cafd[cai]==-1) { - cafd[cai] = socket(PF_INET,SOCK_DGRAM,IPPROTO_UDP); - if(cafd[cai]==-1) { + if (cafd[cai] == -1) { + cafd[cai] = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (cafd[cai] == -1) { ERR("Failed to open socket (%d)", errno); } else { struct sockaddr_in saddr; - fcntl(cafd[cai],F_SETFL,O_NONBLOCK); - bzero(&saddr,sizeof(saddr)); - saddr.sin_family = AF_INET; - saddr.sin_port = htons(PORT); + fcntl(cafd[cai], F_SETFL, O_NONBLOCK); + bzero(&saddr, sizeof(saddr)); + saddr.sin_family = AF_INET; + saddr.sin_port = htons(PORT); saddr.sin_addr.s_addr = inet_addr("127.0.0.1"); - int r = connect(cafd[cai], (struct sockaddr *) &saddr, sizeof(saddr)); - if (r<0) { + int r = connect(cafd[cai], (struct sockaddr*)&saddr, sizeof(saddr)); + if (r < 0) { ERR("Failed to connect socket (%d)", errno); close(cafd[cai]); - cafd[cai]=-1; + cafd[cai] = -1; } // if } // if } // if - if(cafd[cai]!=-1) + if (cafd[cai] != -1) cafdc[cai]++; - else + else cafdc[cai] = 0; return (cafd[cai]); - } // if + } // if } else if (strstr(pathname, DEMUX_BASE)) { - int cai=pathname[strlen(DEMUX_BASE)]-'0'; - if((cai >= 0) && (cai < MAX_CA)) { + int cai = pathname[strlen(DEMUX_BASE)] - '0'; + if ((cai >= 0) && (cai < MAX_CA)) { char dest[256]; sprintf(dest, DEMUX_MAP, cai); - int r = (*func) (dest, flags, mode); + int r = (*func)(dest, flags, mode); DBG(">>>>>>>> open %s mapped to %s fd %d", pathname, dest, r); return r; } // if } - int r = (*func) (pathname, flags, mode); + int r = (*func)(pathname, flags, mode); DBG(">>>>>>>> open %s", pathname); DBG(">>>>>>>> open fd %d", r); return r; } // open -ssize_t read(int fd, void *buf, size_t count) { +ssize_t read(int fd, void* buf, size_t count) { static ssize_t (*func)(int, void*, size_t) = NULL; - if (!func) func = (ssize_t (*)(int, void*, size_t)) dlsym( REAL_LIBC, "read"); + if (!func) + func = (ssize_t(*)(int, void*, size_t))dlsym(REAL_LIBC, "read"); DBG(">>>>>>>> read(fd=%d, buf=%x, count=%d)", fd, buf, count); @@ -260,29 +320,31 @@ ssize_t read(int fd, void *buf, size_t count) { return r; } -int ioctl (int fd, int request, void *a) { - static int (*func) (int, int, void *) = NULL; - if (!func) func = (int (*) (int, int, void *)) dlsym (REAL_LIBC, "ioctl"); +int ioctl(int fd, int request, void* a) { + static int (*func)(int, int, void*) = NULL; + if (!func) + func = (int (*)(int, int, void*))dlsym(REAL_LIBC, "ioctl"); int i; - for(i=0;i>>>>>>> close cafd[%d] (%d)", i, cafdc[i]); - if(--cafdc[i]) return 0; + if (--cafdc[i]) + return 0; cafd[i] = -1; } // if } // for - return (*func) (fd); + return (*func)(fd); } // close #endif - diff --git a/src/file.c b/src/file.c index e23036891..32e48f48e 100644 --- a/src/file.c +++ b/src/file.c @@ -18,17 +18,16 @@ #include "tvheadend.h" #include "file.h" - + #define MAX_RDBUF_SIZE 8192 -size_t file_readall ( int fd, char **outp ) -{ +size_t file_readall(int fd, char** outp) { size_t outsize = 0, totalsize = 0; - char *outbuf = NULL, *n; - int r; + char * outbuf = NULL, *n; + int r; while (1) { - if(totalsize == outsize) { + if (totalsize == outsize) { n = realloc(outbuf, outsize += MAX_RDBUF_SIZE); if (!n) { free(outbuf); @@ -38,19 +37,19 @@ size_t file_readall ( int fd, char **outp ) } r = read(fd, outbuf + totalsize, outsize - totalsize); - if(r < 1) { + if (r < 1) { if (ERRNO_AGAIN(errno)) continue; break; } totalsize += r; - } + } if (!totalsize) { free(outbuf); return 0; } - + *outp = outbuf; if (totalsize == outsize) { n = realloc(outbuf, outsize += 1); diff --git a/src/file.h b/src/file.h index 9523a9080..a66c2f74f 100644 --- a/src/file.h +++ b/src/file.h @@ -21,6 +21,6 @@ #include -size_t file_readall ( int fd, char **outbuf ); +size_t file_readall(int fd, char** outbuf); #endif /* FILE_H */ diff --git a/src/filebundle.c b/src/filebundle.c index 931357dc2..215a29760 100644 --- a/src/filebundle.c +++ b/src/filebundle.c @@ -32,36 +32,34 @@ * *************************************************************************/ /* File bundle dir handle */ -struct filebundle_dir -{ +struct filebundle_dir { fb_type type; fb_dirent dirent; union { struct { - char *root; - DIR *cur; + char* root; + DIR* cur; } d; struct { - const filebundle_entry_t *root; - const filebundle_entry_t *cur; + const filebundle_entry_t* root; + const filebundle_entry_t* cur; } b; }; }; /* File bundle file handle */ -struct filebundle_file -{ - fb_type type; - size_t size; - int gzip; - uint8_t *buf; - size_t pos; +struct filebundle_file { + fb_type type; + size_t size; + int gzip; + uint8_t* buf; + size_t pos; union { struct { - FILE *cur; + FILE* cur; } d; struct { - const filebundle_entry_t *root; + const filebundle_entry_t* root; } b; }; }; @@ -72,11 +70,10 @@ struct filebundle_file /* Get path stats */ // TODO: this could do with being more efficient -int fb_stat ( const char *path, struct filebundle_stat *st ) -{ - int ret = 1; - fb_dir *dir; - fb_file *fp; +int fb_stat(const char* path, struct filebundle_stat* st) { + int ret = 1; + fb_dir* dir; + fb_file* fp; if (*path == '/') { struct stat _st; @@ -90,13 +87,13 @@ int fb_stat ( const char *path, struct filebundle_stat *st ) st->type = dir->type; st->is_dir = 1; st->size = 0; - ret = 0; + ret = 0; fb_closedir(dir); } else if ((fp = fb_open(path, 0, 0))) { st->type = fp->type; st->is_dir = 0; st->size = fp->size; - ret = 0; + ret = 0; fb_close(fp); } return ret; @@ -107,11 +104,10 @@ int fb_stat ( const char *path, struct filebundle_stat *st ) * *************************************************************************/ /* Open directory (directly) */ -static fb_dir *_fb_opendir ( const char *root, const char *path ) -{ - DIR *dir; - char buf[512]; - fb_dir *ret = NULL; +static fb_dir* _fb_opendir(const char* root, const char* path) { + DIR* dir; + char buf[512]; + fb_dir* ret = NULL; /* Pre-pend root */ if (root) { @@ -130,9 +126,8 @@ static fb_dir *_fb_opendir ( const char *root, const char *path ) } /* Open directory */ -fb_dir *fb_opendir ( const char *path ) -{ - fb_dir *ret = NULL; +fb_dir* fb_opendir(const char* path) { + fb_dir* ret = NULL; /* In-direct (search) */ if (*path != '/') { @@ -140,13 +135,14 @@ fb_dir *fb_opendir ( const char *path ) /* Bundle */ #if ENABLE_BUNDLE char *tmp1, *tmp2, *tmp3 = NULL; - tmp1 = strdup(path); - tmp2 = strtok_r(tmp1, "/", &tmp3); - const filebundle_entry_t *fb = filebundle_root; + tmp1 = strdup(path); + tmp2 = strtok_r(tmp1, "/", &tmp3); + const filebundle_entry_t* fb = filebundle_root; while (fb && tmp2) { if (fb->type == FB_DIR && !strcmp(fb->name, tmp2)) { tmp2 = strtok_r(NULL, "/", &tmp3); - if (tmp2) fb = fb->d.child; + if (tmp2) + fb = fb->d.child; } else { fb = fb->next; } @@ -155,7 +151,7 @@ fb_dir *fb_opendir ( const char *path ) /* Found */ if (fb) { - ret = calloc(1, sizeof(fb_dir)); + ret = calloc(1, sizeof(fb_dir)); ret->type = FB_BUNDLE; ret->b.root = fb; ret->b.cur = fb->d.child; @@ -163,12 +159,14 @@ fb_dir *fb_opendir ( const char *path ) #endif /* Local */ - if (!ret) ret = _fb_opendir(tvheadend_cwd, path); + if (!ret) + ret = _fb_opendir(tvheadend_cwd, path); /* System */ - if (!ret) ret = _fb_opendir(TVHEADEND_DATADIR, path); + if (!ret) + ret = _fb_opendir(TVHEADEND_DATADIR, path); - /* Direct */ + /* Direct */ } else { ret = _fb_opendir(NULL, path); } @@ -177,8 +175,7 @@ fb_dir *fb_opendir ( const char *path ) } /* Close directory */ -void fb_closedir ( fb_dir *dir ) -{ +void fb_closedir(fb_dir* dir) { if (dir->type == FB_DIRECT) { closedir(dir->d.cur); free(dir->d.root); @@ -187,9 +184,8 @@ void fb_closedir ( fb_dir *dir ) } /* Iterate through entries */ -fb_dirent *fb_readdir ( fb_dir *dir ) -{ - fb_dirent *ret = NULL; +fb_dirent* fb_readdir(fb_dir* dir) { + fb_dirent* ret = NULL; if (dir->type == FB_BUNDLE) { if (dir->b.cur) { strlcpy(dir->dirent.name, dir->b.cur->name, sizeof(dir->dirent.name)); @@ -197,41 +193,41 @@ fb_dirent *fb_readdir ( fb_dir *dir ) dir->b.cur = dir->b.cur->next; ret = &dir->dirent; } - + } else { - struct dirent *de = readdir(dir->d.cur); + struct dirent* de = readdir(dir->d.cur); if (de) { struct stat st; - char buf[512]; + char buf[512]; snprintf(buf, sizeof(buf), "%s/%s", dir->d.root, de->d_name); strcpy(dir->dirent.name, de->d_name); dir->dirent.type = FB_UNKNOWN; if (!lstat(buf, &st)) dir->dirent.type = S_ISDIR(st.st_mode) ? FB_DIR : FB_FILE; - ret = &dir->dirent; + ret = &dir->dirent; } } return ret; } /* Get entry list */ -int fb_scandir ( const char *path, fb_dirent ***list ) -{ - int i, ret = -1; - struct dirent **de; - fb_dir *dir; +int fb_scandir(const char* path, fb_dirent*** list) { + int i, ret = -1; + struct dirent** de; + fb_dir* dir; - if (!(dir = fb_opendir(path))) return -1; + if (!(dir = fb_opendir(path))) + return -1; /* Direct */ if (dir->type == FB_DIRECT) { if ((ret = scandir(dir->d.root, &de, NULL, NULL)) > 0) { - *list = malloc(sizeof(fb_dirent*)*ret); + *list = malloc(sizeof(fb_dirent*) * ret); for (i = 0; i < ret; i++) { (*list)[i] = calloc(1, sizeof(fb_dirent)); strcpy((*list)[i]->name, de[i]->d_name); - switch(de[i]->d_type) { - case DT_DIR: + switch (de[i]->d_type) { + case DT_DIR: (*list)[i]->type = FB_DIR; break; case DT_REG: @@ -239,7 +235,7 @@ int fb_scandir ( const char *path, fb_dirent ***list ) break; default: { struct stat st; - char buf[512]; + char buf[512]; snprintf(buf, sizeof(buf), "%s/%s", dir->d.root, de[i]->d_name); if (!lstat(buf, &st)) (*list)[i]->type = S_ISDIR(st.st_mode) ? FB_DIR : FB_FILE; @@ -251,13 +247,13 @@ int fb_scandir ( const char *path, fb_dirent ***list ) free(de); } - /* Bundle */ + /* Bundle */ } else { - const filebundle_entry_t *fb; - ret = dir->b.root->d.count; - fb = dir->b.root->d.child; + const filebundle_entry_t* fb; + ret = dir->b.root->d.count; + fb = dir->b.root->d.child; *list = malloc(ret * sizeof(fb_dirent*)); - i = 0; + i = 0; while (fb) { (*list)[i] = calloc(1, sizeof(fb_dirent)); strlcpy((*list)[i]->name, fb->name, sizeof((*list)[i]->name)); @@ -282,25 +278,24 @@ int fb_scandir ( const char *path, fb_dirent ***list ) // be passed in though and will be ignored if this is not the case // Note: compress will work on EITHER type (but will be ignored for already // compressed bundles) -fb_file *fb_open2 - ( const fb_dir *dir, const char *name, int decompress, int compress ) -{ +fb_file* fb_open2(const fb_dir* dir, const char* name, int decompress, int compress) { assert(!decompress || !compress); - fb_file *ret = NULL; + fb_file* ret = NULL; /* Bundle file */ if (dir->type == FB_BUNDLE) { - const filebundle_entry_t *fb = dir->b.root->d.child; + const filebundle_entry_t* fb = dir->b.root->d.child; while (fb) { - if (!strcmp(name, fb->name)) break; + if (!strcmp(name, fb->name)) + break; fb = fb->next; } if (fb) { - ret = calloc(1, sizeof(fb_file)); - ret->type = FB_BUNDLE; - ret->size = fb->f.size; - ret->gzip = fb->f.orig != -1; - ret->b.root = fb; + ret = calloc(1, sizeof(fb_file)); + ret->type = FB_BUNDLE; + ret->size = fb->f.size; + ret->gzip = fb->f.orig != -1; + ret->b.root = fb; /* Inflate the file */ if (fb->f.orig != -1 && decompress) { @@ -319,19 +314,19 @@ fb_file *fb_open2 } } - /* Direct file */ + /* Direct file */ } else { char path[512]; snprintf(path, sizeof(path), "%s/%s", dir->d.root, name); - FILE *fp = tvh_fopen(path, "rb"); + FILE* fp = tvh_fopen(path, "rb"); if (fp) { struct stat st; if (!stat(path, &st)) { - ret = calloc(1, sizeof(fb_file)); - ret->type = FB_DIRECT; - ret->size = st.st_size; - ret->gzip = 0; - ret->d.cur = fp; + ret = calloc(1, sizeof(fb_file)); + ret->type = FB_DIRECT; + ret->size = st.st_size; + ret->gzip = 0; + ret->d.cur = fp; } else { fclose(fp); } @@ -342,26 +337,26 @@ fb_file *fb_open2 #if ENABLE_ZLIB if (ret && !ret->gzip && compress) { ret->gzip = 1; - + /* Get data */ if (ret->type == FB_BUNDLE) { - const uint8_t *data; + const uint8_t* data; data = ret->b.root->f.data; ret->buf = tvh_gzip_deflate(data, ret->size, &ret->size); } else { - uint8_t *data = malloc(ret->size); - ssize_t c = fread(data, 1, ret->size, ret->d.cur); + uint8_t* data = malloc(ret->size); + ssize_t c = fread(data, 1, ret->size, ret->d.cur); if (c == ret->size) ret->buf = tvh_gzip_deflate(data, ret->size, &ret->size); fclose(ret->d.cur); ret->d.cur = NULL; free(data); } - + /* Cleanup */ if (!ret->buf) { free(ret); - ret = NULL; + ret = NULL; } } #endif @@ -370,17 +365,16 @@ fb_file *fb_open2 } /* Open file */ -fb_file *fb_open ( const char *path, int decompress, int compress ) -{ - fb_file *ret = NULL; - fb_dir *dir = NULL; - char *tmp = strdup(path); - char *pos = strrchr(tmp, '/'); +fb_file* fb_open(const char* path, int decompress, int compress) { + fb_file* ret = NULL; + fb_dir* dir = NULL; + char* tmp = strdup(path); + char* pos = strrchr(tmp, '/'); if (!pos) { free(tmp); return NULL; } - + /* Find directory */ *pos = '\0'; dir = fb_opendir(tmp); @@ -390,15 +384,14 @@ fb_file *fb_open ( const char *path, int decompress, int compress ) } /* Open */ - ret = fb_open2(dir, pos+1, decompress, compress); + ret = fb_open2(dir, pos + 1, decompress, compress); fb_closedir(dir); free(tmp); return ret; } /* Close file */ -void fb_close ( fb_file *fp ) -{ +void fb_close(fb_file* fp) { if (fp->type == FB_DIRECT && fp->d.cur) { fclose(fp->d.cur); } @@ -408,26 +401,22 @@ void fb_close ( fb_file *fp ) } /* Get the files size */ -size_t fb_size ( fb_file *fp ) -{ +size_t fb_size(fb_file* fp) { return fp->size; } /* Check if compressed */ -int fb_gzipped ( fb_file *fp ) -{ +int fb_gzipped(fb_file* fp) { return fp->gzip; } /* Check for EOF */ -int fb_eof ( fb_file *fp ) -{ +int fb_eof(fb_file* fp) { return fp->pos >= fp->size; } /* Read some data */ -ssize_t fb_read ( fb_file *fp, void *buf, size_t count ) -{ +ssize_t fb_read(fb_file* fp, void* buf, size_t count) { if (fb_eof(fp)) { return -1; } else if (fp->buf) { @@ -448,15 +437,16 @@ ssize_t fb_read ( fb_file *fp, void *buf, size_t count ) } /* Read a line */ -char *fb_gets ( fb_file *fp, void *buf, size_t count ) -{ +char* fb_gets(fb_file* fp, void* buf, size_t count) { ssize_t c = 0, err; - while ((err = fb_read(fp, buf+c, 1)) > 0 && c < (count-1)) { + while ((err = fb_read(fp, buf + c, 1)) > 0 && c < (count - 1)) { char b = ((char*)buf)[c]; c++; - if (b == '\n' || b == '\0') break; + if (b == '\n' || b == '\0') + break; } - if (err < 0) return NULL; + if (err < 0) + return NULL; ((char*)buf)[c] = '\0'; return buf; } diff --git a/src/filebundle.h b/src/filebundle.h index 77b6edfa4..a2517ac3e 100644 --- a/src/filebundle.h +++ b/src/filebundle.h @@ -25,52 +25,40 @@ #include /* Bundle or Direct */ -typedef enum filebundle_handle_type -{ - FB_BUNDLE, - FB_DIRECT -} fb_type; +typedef enum filebundle_handle_type { FB_BUNDLE, FB_DIRECT } fb_type; /* File bundle entry type */ -enum filebundle_type -{ - FB_UNKNOWN, - FB_FILE, - FB_DIR -}; +enum filebundle_type { FB_UNKNOWN, FB_FILE, FB_DIR }; /* File bundle entry */ -typedef struct filebundle_entry -{ - enum filebundle_type type; - const char *name; - const struct filebundle_entry *next; +typedef struct filebundle_entry { + enum filebundle_type type; + const char* name; + const struct filebundle_entry* next; union { struct { - size_t count; - const struct filebundle_entry *child; + size_t count; + const struct filebundle_entry* child; } d; struct { - const uint8_t *data; - size_t size; - ssize_t orig; + const uint8_t* data; + size_t size; + ssize_t orig; } f; }; } filebundle_entry_t; /* File bundle directory entry */ -typedef struct filebundle_dirent -{ +typedef struct filebundle_dirent { char name[256]; enum filebundle_type type; } fb_dirent; /* File bundle stat */ -struct filebundle_stat -{ - fb_type type; - uint8_t is_dir; - size_t size; +struct filebundle_stat { + fb_type type; + uint8_t is_dir; + size_t size; }; /* Opaque types */ @@ -78,28 +66,28 @@ typedef struct filebundle_dir fb_dir; typedef struct filebundle_file fb_file; /* Root of bundle */ -extern const filebundle_entry_t * const filebundle_root; +extern const filebundle_entry_t* const filebundle_root; /* Miscellaneous */ -int fb_stat ( const char *path, struct filebundle_stat *st ); +int fb_stat(const char* path, struct filebundle_stat* st); /* Directory processing wrappers */ -fb_dir *fb_opendir ( const char *path ); -fb_dirent *fb_readdir ( fb_dir *fb ); -void fb_closedir ( fb_dir *fb ); -int fb_scandir ( const char *path, fb_dirent ***list ); +fb_dir* fb_opendir(const char* path); +fb_dirent* fb_readdir(fb_dir* fb); +void fb_closedir(fb_dir* fb); +int fb_scandir(const char* path, fb_dirent*** list); /* File processing wrappers */ // Note: all access is read-only // Note: decompress is only for compressed filebundles, // not direct disk access -fb_file *fb_open2 ( const fb_dir *dir, const char *name, int decompress, int compress ); -fb_file *fb_open ( const char *path, int decompress, int compress ); -void fb_close ( fb_file *fp ); -size_t fb_size ( fb_file *fp ); -int fb_gzipped ( fb_file *fp ); -int fb_eof ( fb_file *fp ); -ssize_t fb_read ( fb_file *fp, void *buf, size_t count ); -char *fb_gets ( fb_file *fp, void *buf, size_t count ); +fb_file* fb_open2(const fb_dir* dir, const char* name, int decompress, int compress); +fb_file* fb_open(const char* path, int decompress, int compress); +void fb_close(fb_file* fp); +size_t fb_size(fb_file* fp); +int fb_gzipped(fb_file* fp); +int fb_eof(fb_file* fp); +ssize_t fb_read(fb_file* fp, void* buf, size_t count); +char* fb_gets(fb_file* fp, void* buf, size_t count); #endif /* __TVH_FILE_BUNDLE_H__ */ diff --git a/src/fsmonitor.c b/src/fsmonitor.c index b8f66b632..61f4487e7 100644 --- a/src/fsmonitor.c +++ b/src/fsmonitor.c @@ -29,29 +29,25 @@ #include /* Global list of monitorer paths (and inotify FD) */ -RB_HEAD(,fsmonitor_path) fsmonitor_paths; -int fsmonitor_fd; +RB_HEAD(, fsmonitor_path) fsmonitor_paths; +int fsmonitor_fd; /* RB tree sorting of paths */ -static int -fmp_cmp ( fsmonitor_path_t *a, fsmonitor_path_t *b ) -{ +static int fmp_cmp(fsmonitor_path_t* a, fsmonitor_path_t* b) { return strcmp(a->fmp_path, b->fmp_path); } /* * Inotify thread for handling events */ -static void * -fsmonitor_thread ( void* p ) -{ - int fd, c, i; - uint8_t buf[sizeof(struct inotify_event) * 10]; - char path[1024]; - struct inotify_event *ev; - fsmonitor_path_t *fmp; - fsmonitor_link_t *fml; - fsmonitor_t *fsm; +static void* fsmonitor_thread(void* p) { + int fd, c, i; + uint8_t buf[sizeof(struct inotify_event) * 10]; + char path[1024]; + struct inotify_event* ev; + fsmonitor_path_t* fmp; + fsmonitor_link_t* fml; + fsmonitor_t* fsm; while (tvheadend_is_running()) { @@ -67,27 +63,31 @@ fsmonitor_thread ( void* p ) /* Process */ tvh_mutex_lock(&global_lock); i = 0; - while ( i < c ) { + while (i < c) { ev = (struct inotify_event*)&buf[i]; i += sizeof(struct inotify_event) + ev->len; if (i > c) break; - tvhtrace(LS_FSMONITOR, "event fd %d name %s mask %08X", - ev->wd, ev->len ? ev->name : NULL, ev->mask); + tvhtrace(LS_FSMONITOR, + "event fd %d name %s mask %08X", + ev->wd, + ev->len ? ev->name : NULL, + ev->mask); /* Find */ // TODO: make this more efficient (especially if number of // watched paths gets big) - RB_FOREACH(fmp, &fsmonitor_paths, fmp_link) + RB_FOREACH (fmp, &fsmonitor_paths, fmp_link) if (fmp->fmp_fd == ev->wd) break; - if (!fmp) continue; + if (!fmp) + continue; /* Full path */ snprintf(path, sizeof(path), "%s/%s", fmp->fmp_path, ev->name); /* Process listeners */ - LIST_FOREACH(fml, &fmp->fmp_monitors, fml_plink) { + LIST_FOREACH (fml, &fmp->fmp_monitors, fml_plink) { fsm = fml->fml_monitor; if (ev->mask & IN_CREATE && fsm->fsm_create) fsm->fsm_create(fsm, path); @@ -105,9 +105,7 @@ fsmonitor_thread ( void* p ) */ pthread_t fsmonitor_tid; -void -fsmonitor_init ( void ) -{ +void fsmonitor_init(void) { /* Intialise inotify */ atomic_set(&fsmonitor_fd, inotify_init1(IN_CLOEXEC)); tvh_thread_create(&fsmonitor_tid, NULL, fsmonitor_thread, NULL, "fsmonitor"); @@ -116,11 +114,10 @@ fsmonitor_init ( void ) /* * Stop the fsmonitor subsystem */ -void -fsmonitor_done ( void ) -{ +void fsmonitor_done(void) { int fd = atomic_exchange(&fsmonitor_fd, -1); - if (fd >= 0) blacklisted_close(fd); + if (fd >= 0) + blacklisted_close(fd); tvh_thread_kill(fsmonitor_tid, SIGTERM); pthread_join(fsmonitor_tid, NULL); } @@ -128,17 +125,15 @@ fsmonitor_done ( void ) /* * Add a new path */ -int -fsmonitor_add ( const char *path, fsmonitor_t *fsm ) -{ - int fd, mask; - fsmonitor_path_t *skel; - fsmonitor_path_t *fmp; - fsmonitor_link_t *fml; +int fsmonitor_add(const char* path, fsmonitor_t* fsm) { + int fd, mask; + fsmonitor_path_t* skel; + fsmonitor_path_t* fmp; + fsmonitor_link_t* fml; lock_assert(&global_lock); - skel = calloc(1, sizeof(fsmonitor_path_t)); + skel = calloc(1, sizeof(fsmonitor_path_t)); skel->fmp_path = (char*)path; /* Build mask */ @@ -172,29 +167,27 @@ fsmonitor_add ( const char *path, fsmonitor_t *fsm ) /* Check doesn't exist */ // TODO: could make this more efficient - LIST_FOREACH(fml, &fmp->fmp_monitors, fml_plink) + LIST_FOREACH (fml, &fmp->fmp_monitors, fml_plink) if (fml->fml_monitor == fsm) return 0; /* Add */ - fml = calloc(1, sizeof(fsmonitor_link_t)); + fml = calloc(1, sizeof(fsmonitor_link_t)); fml->fml_path = fmp; fml->fml_monitor = fsm; LIST_INSERT_HEAD(&fmp->fmp_monitors, fml, fml_plink); - LIST_INSERT_HEAD(&fsm->fsm_paths, fml, fml_mlink); + LIST_INSERT_HEAD(&fsm->fsm_paths, fml, fml_mlink); return 0; } /* * Remove an existing path */ -void -fsmonitor_del ( const char *path, fsmonitor_t *fsm ) -{ +void fsmonitor_del(const char* path, fsmonitor_t* fsm) { static fsmonitor_path_t skel; - fsmonitor_path_t *fmp; - fsmonitor_link_t *fml; - int fd; + fsmonitor_path_t* fmp; + fsmonitor_link_t* fml; + int fd; lock_assert(&global_lock); @@ -205,7 +198,7 @@ fsmonitor_del ( const char *path, fsmonitor_t *fsm ) if (fmp) { /* Find link */ - LIST_FOREACH(fml, &fmp->fmp_monitors, fml_plink) + LIST_FOREACH (fml, &fmp->fmp_monitors, fml_plink) if (fml->fml_monitor == fsm) break; @@ -231,25 +224,14 @@ fsmonitor_del ( const char *path, fsmonitor_t *fsm ) #else /* ENABLE_INOTIFY */ -void -fsmonitor_init ( void ) -{ -} +void fsmonitor_init(void) {} -void -fsmonitor_done ( void ) -{ -} +void fsmonitor_done(void) {} -int -fsmonitor_add ( const char *path, fsmonitor_t *fsm ) -{ +int fsmonitor_add(const char* path, fsmonitor_t* fsm) { return 0; // TODO: is this the right value? } -void -fsmonitor_del ( const char *path, fsmonitor_t *fsm ) -{ -} +void fsmonitor_del(const char* path, fsmonitor_t* fsm) {} #endif diff --git a/src/fsmonitor.h b/src/fsmonitor.h index d3c586a97..a1cf7d139 100644 --- a/src/fsmonitor.h +++ b/src/fsmonitor.h @@ -24,31 +24,29 @@ typedef struct fsmonitor fsmonitor_t; typedef struct fsmonitor_path fsmonitor_path_t; typedef struct fsmonitor_link fsmonitor_link_t; -struct fsmonitor_path -{ - char *fmp_path; - int fmp_fd; - RB_ENTRY(fsmonitor_path) fmp_link; - LIST_HEAD(,fsmonitor_link) fmp_monitors; +struct fsmonitor_path { + char* fmp_path; + int fmp_fd; + RB_ENTRY(fsmonitor_path) fmp_link; + LIST_HEAD(, fsmonitor_link) fmp_monitors; }; -struct fsmonitor_link -{ - LIST_ENTRY(fsmonitor_link) fml_plink; - LIST_ENTRY(fsmonitor_link) fml_mlink; - fsmonitor_path_t *fml_path; - fsmonitor_t *fml_monitor; +struct fsmonitor_link { + LIST_ENTRY(fsmonitor_link) fml_plink; + LIST_ENTRY(fsmonitor_link) fml_mlink; + fsmonitor_path_t* fml_path; + fsmonitor_t* fml_monitor; }; struct fsmonitor { - LIST_HEAD(,fsmonitor_link) fsm_paths; - void (*fsm_create) ( struct fsmonitor *fsm, const char *path ); - void (*fsm_delete) ( struct fsmonitor *fsm, const char *path ); + LIST_HEAD(, fsmonitor_link) fsm_paths; + void (*fsm_create)(struct fsmonitor* fsm, const char* path); + void (*fsm_delete)(struct fsmonitor* fsm, const char* path); }; -void fsmonitor_init ( void ); -void fsmonitor_done ( void ); -int fsmonitor_add ( const char *path, fsmonitor_t *fsm ); -void fsmonitor_del ( const char *path, fsmonitor_t *fsm ); +void fsmonitor_init(void); +void fsmonitor_done(void); +int fsmonitor_add(const char* path, fsmonitor_t* fsm); +void fsmonitor_del(const char* path, fsmonitor_t* fsm); #endif /* __FS_MONITOR_H__ */ diff --git a/src/hts_strtab.h b/src/hts_strtab.h index 16f0aa8f4..3ef1ec814 100644 --- a/src/hts_strtab.h +++ b/src/hts_strtab.h @@ -25,29 +25,26 @@ #include struct strtab { - const char *str; - int val; + const char* str; + int val; }; struct strtab_u32 { - const char *str; - uint32_t val; + const char* str; + uint32_t val; }; struct strtab_str { - const char *str; - const char *val; + const char* str; + const char* val; }; -static int str2val0(const char *str, const struct strtab tab[], int l) - __attribute((unused)); +static int str2val0(const char* str, const struct strtab tab[], int l) __attribute((unused)); -static inline int -str2val0(const char *str, const struct strtab tab[], int l) -{ +static inline int str2val0(const char* str, const struct strtab tab[], int l) { int i; - for(i = 0; i < l; i++) - if(!strcasecmp(str, tab[i].str)) + for (i = 0; i < l; i++) + if (!strcasecmp(str, tab[i].str)) return tab[i].val; return -1; @@ -55,45 +52,34 @@ str2val0(const char *str, const struct strtab tab[], int l) #define str2val(str, tab) str2val0(str, tab, sizeof(tab) / sizeof(tab[0])) +static int str2val0_def(const char* str, struct strtab tab[], int l, int def) __attribute((unused)); - -static int str2val0_def(const char *str, struct strtab tab[], int l, int def) - __attribute((unused)); - -static inline int -str2val0_def(const char *str, struct strtab tab[], int l, int def) -{ +static inline int str2val0_def(const char* str, struct strtab tab[], int l, int def) { int i; - if(str) - for(i = 0; i < l; i++) - if(!strcasecmp(str, tab[i].str)) - return tab[i].val; + if (str) + for (i = 0; i < l; i++) + if (!strcasecmp(str, tab[i].str)) + return tab[i].val; return def; } -#define str2val_def(str, tab, def) \ - str2val0_def(str, tab, sizeof(tab) / sizeof(tab[0]), def) - +#define str2val_def(str, tab, def) str2val0_def(str, tab, sizeof(tab) / sizeof(tab[0]), def) -static const char * val2str0(int val, const struct strtab tab[], int l) - __attribute__((unused)); +static const char* val2str0(int val, const struct strtab tab[], int l) __attribute__((unused)); -static inline const char * -val2str0(int val, const struct strtab tab[], int l) -{ +static inline const char* val2str0(int val, const struct strtab tab[], int l) { int i; - for(i = 0; i < l; i++) - if(tab[i].val == val) + for (i = 0; i < l; i++) + if (tab[i].val == val) return tab[i].str; return NULL; -} +} #define val2str(val, tab) val2str0(val, tab, sizeof(tab) / sizeof(tab[0])) -static inline htsmsg_t * -strtab2htsmsg0(const struct strtab tab[], int n, int i18n, const char *lang) -{ - int i; +static inline htsmsg_t* +strtab2htsmsg0(const struct strtab tab[], int n, int i18n, const char* lang) { + int i; htsmsg_t *e, *l = htsmsg_create_list(); for (i = 0; i < n; i++) { e = htsmsg_create_map(); @@ -104,12 +90,11 @@ strtab2htsmsg0(const struct strtab tab[], int n, int i18n, const char *lang) return l; } -#define strtab2htsmsg(tab,i18n,lang) strtab2htsmsg0(tab, sizeof(tab) / sizeof(tab[0]), i18n, lang) +#define strtab2htsmsg(tab, i18n, lang) strtab2htsmsg0(tab, sizeof(tab) / sizeof(tab[0]), i18n, lang) -static inline htsmsg_t * -strtab2htsmsg0_u32(const struct strtab_u32 tab[], uint32_t n, int i18n, const char *lang) -{ - uint32_t i; +static inline htsmsg_t* +strtab2htsmsg0_u32(const struct strtab_u32 tab[], uint32_t n, int i18n, const char* lang) { + uint32_t i; htsmsg_t *e, *l = htsmsg_create_list(); for (i = 0; i < n; i++) { e = htsmsg_create_map(); @@ -120,12 +105,12 @@ strtab2htsmsg0_u32(const struct strtab_u32 tab[], uint32_t n, int i18n, const ch return l; } -#define strtab2htsmsg_u32(tab,i18n,lang) strtab2htsmsg0_u32(tab, sizeof(tab) / sizeof(tab[0]), i18n, lang) +#define strtab2htsmsg_u32(tab, i18n, lang) \ + strtab2htsmsg0_u32(tab, sizeof(tab) / sizeof(tab[0]), i18n, lang) -static inline htsmsg_t * -strtab2htsmsg0_str(const struct strtab_str tab[], uint32_t n, int i18n, const char *lang) -{ - uint32_t i; +static inline htsmsg_t* +strtab2htsmsg0_str(const struct strtab_str tab[], uint32_t n, int i18n, const char* lang) { + uint32_t i; htsmsg_t *e, *l = htsmsg_create_list(); for (i = 0; i < n; i++) { e = htsmsg_create_key_val(tab[i].val, i18n ? tvh_gettext_lang(lang, tab[i].str) : tab[i].str); @@ -134,6 +119,7 @@ strtab2htsmsg0_str(const struct strtab_str tab[], uint32_t n, int i18n, const ch return l; } -#define strtab2htsmsg_str(tab,i18n,lang) strtab2htsmsg0_str(tab, sizeof(tab) / sizeof(tab[0]), i18n, lang) +#define strtab2htsmsg_str(tab, i18n, lang) \ + strtab2htsmsg0_str(tab, sizeof(tab) / sizeof(tab[0]), i18n, lang) #endif /* STRTAB_H_ */ diff --git a/src/htsbuf.c b/src/htsbuf.c index c7c9b10f8..6e02c9cc2 100644 --- a/src/htsbuf.c +++ b/src/htsbuf.c @@ -29,24 +29,19 @@ /** * */ -void -htsbuf_queue_init(htsbuf_queue_t *hq, unsigned int maxsize) -{ - if(maxsize == 0) +void htsbuf_queue_init(htsbuf_queue_t* hq, unsigned int maxsize) { + if (maxsize == 0) maxsize = INT32_MAX; TAILQ_INIT(&hq->hq_q); - hq->hq_size = 0; + hq->hq_size = 0; hq->hq_maxsize = maxsize; } - /** * */ -htsbuf_queue_t * -htsbuf_queue_alloc(unsigned int maxsize) -{ - htsbuf_queue_t *hq = malloc(sizeof(htsbuf_queue_t)); +htsbuf_queue_t* htsbuf_queue_alloc(unsigned int maxsize) { + htsbuf_queue_t* hq = malloc(sizeof(htsbuf_queue_t)); htsbuf_queue_init(hq, maxsize); return hq; } @@ -54,9 +49,7 @@ htsbuf_queue_alloc(unsigned int maxsize) /** * */ -void -htsbuf_queue_free(htsbuf_queue_t *hq) -{ +void htsbuf_queue_free(htsbuf_queue_t* hq) { htsbuf_queue_flush(hq); free(hq); } @@ -64,41 +57,34 @@ htsbuf_queue_free(htsbuf_queue_t *hq) /** * */ -void -htsbuf_data_free(htsbuf_queue_t *hq, htsbuf_data_t *hd) -{ +void htsbuf_data_free(htsbuf_queue_t* hq, htsbuf_data_t* hd) { hq->hq_size -= hd->hd_data_size - hd->hd_data_off; TAILQ_REMOVE(&hq->hq_q, hd, hd_link); free(hd->hd_data); free(hd); } - /** * */ -void -htsbuf_queue_flush(htsbuf_queue_t *hq) -{ - htsbuf_data_t *hd; +void htsbuf_queue_flush(htsbuf_queue_t* hq) { + htsbuf_data_t* hd; hq->hq_size = 0; - while((hd = TAILQ_FIRST(&hq->hq_q)) != NULL) + while ((hd = TAILQ_FIRST(&hq->hq_q)) != NULL) htsbuf_data_free(hq, hd); } /** * */ -void -htsbuf_append(htsbuf_queue_t *hq, const void *buf, size_t len) -{ - htsbuf_data_t *hd = TAILQ_LAST(&hq->hq_q, htsbuf_data_queue); - int c; +void htsbuf_append(htsbuf_queue_t* hq, const void* buf, size_t len) { + htsbuf_data_t* hd = TAILQ_LAST(&hq->hq_q, htsbuf_data_queue); + int c; hq->hq_size += len; - if(hd != NULL) { + if (hd != NULL) { /* Fill out any previous buffer */ c = MIN(hd->hd_data_size - hd->hd_data_len, len); memcpy(hd->hd_data + hd->hd_data_len, buf, c); @@ -106,55 +92,50 @@ htsbuf_append(htsbuf_queue_t *hq, const void *buf, size_t len) buf += c; len -= c; } - if(len == 0) + if (len == 0) return; - + hd = malloc(sizeof(htsbuf_data_t)); TAILQ_INSERT_TAIL(&hq->hq_q, hd, hd_link); - + c = MAX(len, 1000); /* Allocate 1000 bytes to support lots of small writes */ - hd->hd_data = malloc(c); + hd->hd_data = malloc(c); hd->hd_data_size = c; - hd->hd_data_len = len; - hd->hd_data_off = 0; + hd->hd_data_len = len; + hd->hd_data_off = 0; memcpy(hd->hd_data, buf, len); } - /** * */ -void -htsbuf_append_prealloc(htsbuf_queue_t *hq, const void *buf, size_t len) -{ - htsbuf_data_t *hd; +void htsbuf_append_prealloc(htsbuf_queue_t* hq, const void* buf, size_t len) { + htsbuf_data_t* hd; hq->hq_size += len; hd = malloc(sizeof(htsbuf_data_t)); TAILQ_INSERT_TAIL(&hq->hq_q, hd, hd_link); - - hd->hd_data = (void *)buf; + + hd->hd_data = (void*)buf; hd->hd_data_size = len; - hd->hd_data_len = len; - hd->hd_data_off = 0; + hd->hd_data_len = len; + hd->hd_data_off = 0; } /** * */ -size_t -htsbuf_read(htsbuf_queue_t *hq, void *buf, size_t len) -{ +size_t htsbuf_read(htsbuf_queue_t* hq, void* buf, size_t len) { size_t r = 0; - int c; + int c; + + htsbuf_data_t* hd; - htsbuf_data_t *hd; - - while(len > 0) { + while (len > 0) { hd = TAILQ_FIRST(&hq->hq_q); - if(hd == NULL) + if (hd == NULL) break; c = MIN(hd->hd_data_len - hd->hd_data_off, len); @@ -165,46 +146,39 @@ htsbuf_read(htsbuf_queue_t *hq, void *buf, size_t len) len -= c; hd->hd_data_off += c; hq->hq_size -= c; - if(hd->hd_data_off == hd->hd_data_len) + if (hd->hd_data_off == hd->hd_data_len) htsbuf_data_free(hq, hd); } return r; } - /** * */ -size_t -htsbuf_find(htsbuf_queue_t *hq, uint8_t v) -{ - htsbuf_data_t *hd; - int i, o = 0; - - TAILQ_FOREACH(hd, &hq->hq_q, hd_link) { - for(i = hd->hd_data_off; i < hd->hd_data_len; i++) { - if(hd->hd_data[i] == v) - return o + i - hd->hd_data_off; +size_t htsbuf_find(htsbuf_queue_t* hq, uint8_t v) { + htsbuf_data_t* hd; + int i, o = 0; + + TAILQ_FOREACH (hd, &hq->hq_q, hd_link) { + for (i = hd->hd_data_off; i < hd->hd_data_len; i++) { + if (hd->hd_data[i] == v) + return o + i - hd->hd_data_off; } o += hd->hd_data_len - hd->hd_data_off; } return -1; } - - /** * */ -size_t -htsbuf_peek(htsbuf_queue_t *hq, void *buf, size_t len) -{ +size_t htsbuf_peek(htsbuf_queue_t* hq, void* buf, size_t len) { size_t r = 0; - int c; + int c; + + htsbuf_data_t* hd = TAILQ_FIRST(&hq->hq_q); - htsbuf_data_t *hd = TAILQ_FIRST(&hq->hq_q); - - while(len > 0 && hd != NULL) { + while (len > 0 && hd != NULL) { c = MIN(hd->hd_data_len - hd->hd_data_off, len); memcpy(buf, hd->hd_data + hd->hd_data_off, c); @@ -220,16 +194,14 @@ htsbuf_peek(htsbuf_queue_t *hq, void *buf, size_t len) /** * */ -size_t -htsbuf_drop(htsbuf_queue_t *hq, size_t len) -{ - size_t r = 0; - int c; - htsbuf_data_t *hd; - - while(len > 0) { +size_t htsbuf_drop(htsbuf_queue_t* hq, size_t len) { + size_t r = 0; + int c; + htsbuf_data_t* hd; + + while (len > 0) { hd = TAILQ_FIRST(&hq->hq_q); - if(hd == NULL) + if (hd == NULL) break; c = MIN(hd->hd_data_len - hd->hd_data_off, len); @@ -237,7 +209,7 @@ htsbuf_drop(htsbuf_queue_t *hq, size_t len) hd->hd_data_off += c; hq->hq_size -= c; r += c; - if(hd->hd_data_off == hd->hd_data_len) + if (hd->hd_data_off == hd->hd_data_len) htsbuf_data_free(hq, hd); } return r; @@ -246,18 +218,16 @@ htsbuf_drop(htsbuf_queue_t *hq, size_t len) /** * Inspired by vsnprintf man page */ -void -htsbuf_vqprintf(htsbuf_queue_t *hq, const char *fmt, va_list ap0) -{ +void htsbuf_vqprintf(htsbuf_queue_t* hq, const char* fmt, va_list ap0) { // First try to format it on-stack va_list ap; - int n, size; - char buf[100], *p, *np; + int n, size; + char buf[100], *p, *np; va_copy(ap, ap0); n = vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - if(n > -1 && n < sizeof(buf)) { + if (n > -1 && n < sizeof(buf)) { htsbuf_append(hq, buf, n); return; } @@ -271,16 +241,16 @@ htsbuf_vqprintf(htsbuf_queue_t *hq, const char *fmt, va_list ap0) va_copy(ap, ap0); n = vsnprintf(p, size, fmt, ap); va_end(ap); - if(n > -1 && n < size) { + if (n > -1 && n < size) { htsbuf_append_prealloc(hq, p, n); return; } /* Else try again with more space. */ - if (n > -1) /* glibc 2.1 */ - size = n+1; /* precisely what is needed */ - else /* glibc 2.0 */ - size *= 2; /* twice the old size */ - if ((np = realloc (p, size)) == NULL) { + if (n > -1) /* glibc 2.1 */ + size = n + 1; /* precisely what is needed */ + else /* glibc 2.0 */ + size *= 2; /* twice the old size */ + if ((np = realloc(p, size)) == NULL) { free(p); abort(); } else { @@ -289,77 +259,61 @@ htsbuf_vqprintf(htsbuf_queue_t *hq, const char *fmt, va_list ap0) } } - /** * */ -void -htsbuf_qprintf(htsbuf_queue_t *hq, const char *fmt, ...) -{ +void htsbuf_qprintf(htsbuf_queue_t* hq, const char* fmt, ...) { va_list ap; va_start(ap, fmt); htsbuf_vqprintf(hq, fmt, ap); va_end(ap); } - -void -htsbuf_appendq(htsbuf_queue_t *hq, htsbuf_queue_t *src) -{ - htsbuf_data_t *hd; +void htsbuf_appendq(htsbuf_queue_t* hq, htsbuf_queue_t* src) { + htsbuf_data_t* hd; hq->hq_size += src->hq_size; src->hq_size = 0; - while((hd = TAILQ_FIRST(&src->hq_q)) != NULL) { + while ((hd = TAILQ_FIRST(&src->hq_q)) != NULL) { TAILQ_REMOVE(&src->hq_q, hd, hd_link); TAILQ_INSERT_TAIL(&hq->hq_q, hd, hd_link); } } +void htsbuf_dump_raw_stderr(htsbuf_queue_t* hq) { + htsbuf_data_t* hd; + char n = '\n'; -void -htsbuf_dump_raw_stderr(htsbuf_queue_t *hq) -{ - htsbuf_data_t *hd; - char n = '\n'; - - TAILQ_FOREACH(hd, &hq->hq_q, hd_link) { - if(write(2, hd->hd_data + hd->hd_data_off, - hd->hd_data_len - hd->hd_data_off) - != hd->hd_data_len - hd->hd_data_off) + TAILQ_FOREACH (hd, &hq->hq_q, hd_link) { + if (write(2, hd->hd_data + hd->hd_data_off, hd->hd_data_len - hd->hd_data_off) != + hd->hd_data_len - hd->hd_data_off) break; } - if(write(2, &n, 1) != 1) + if (write(2, &n, 1) != 1) return; } - -void -htsbuf_hexdump(htsbuf_queue_t *hq, const char *prefix) -{ - void *r = malloc(hq->hq_size); +void htsbuf_hexdump(htsbuf_queue_t* hq, const char* prefix) { + void* r = malloc(hq->hq_size); htsbuf_peek(hq, r, hq->hq_size); hexdump(prefix, r, hq->hq_size); free(r); } - /** * */ -void -htsbuf_append_and_escape_xml(htsbuf_queue_t *hq, const char *s) -{ - const char *c = s; - const char *e = s + strlen(s); - const char *esc = 0; - int h; - - if(e == s) +void htsbuf_append_and_escape_xml(htsbuf_queue_t* hq, const char* s) { + const char* c = s; + const char* e = s + strlen(s); + const char* esc = 0; + int h; + + if (e == s) return; - while(c': esc = ">"; break; - case '&': esc = "&"; break; - case '\'': esc = "'"; break; - case '"': esc = """; break; - default: esc = NULL; break; + switch (h) { + case '<': + esc = "<"; + break; + case '>': + esc = ">"; + break; + case '&': + esc = "&"; + break; + case '\'': + esc = "'"; + break; + case '"': + esc = """; + break; + default: + esc = NULL; + break; } - - if(esc != NULL) { + + if (esc != NULL) { htsbuf_append(hq, s, c - s - 1); htsbuf_append_str(hq, esc); s = c; @@ -415,67 +381,50 @@ htsbuf_append_and_escape_xml(htsbuf_queue_t *hq, const char *s) htsbuf_append(hq, s, c - s - 1); s = c; } - - if(c == e) { + + if (c == e) { htsbuf_append(hq, s, c - s); break; } } } - /** * */ -void -htsbuf_append_and_escape_url(htsbuf_queue_t *hq, const char *s) -{ - const char *c = s; - const char *e = s + strlen(s); - char C; - if(e == s) +void htsbuf_append_and_escape_url(htsbuf_queue_t* hq, const char* s) { + const char* c = s; + const char* e = s + strlen(s); + char C; + if (e == s) return; - while(1) { - const char *esc; - char buf[4]; + while (1) { + const char* esc; + char buf[4]; C = *c++; - + /* RFC 3986, section 3.4 */ - if((C >= '0' && C <= '9') || - (C >= 'a' && C <= 'z') || - (C >= 'A' && C <= 'Z') || - C == '/' || - C == ':' || - C == '@' || - C == '-' || - C == '.' || - C == '~' || - C == '!' || - C == '$' || - C == '\'' || - C == '(' || - C == ')' || - C == '*' || - C == ',' || - C == ';') { + if ((C >= '0' && C <= '9') || (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z') || C == '/' || + C == ':' || C == '@' || C == '-' || C == '.' || C == '~' || C == '!' || C == '$' || + C == '\'' || C == '(' || C == ')' || C == '*' || C == ',' || C == ';') { esc = NULL; } else { static const char hexchars[16] = "0123456789ABCDEF"; - buf[0] = '%'; - buf[1] = hexchars[(C >> 4) & 0xf]; - buf[2] = hexchars[C & 0xf]; - buf[3] = 0; - esc = buf; + buf[0] = '%'; + buf[1] = hexchars[(C >> 4) & 0xf]; + buf[2] = hexchars[C & 0xf]; + buf[3] = 0; + esc = buf; } - if(esc != NULL) { + if (esc != NULL) { htsbuf_append(hq, s, c - s - 1); htsbuf_append_str(hq, esc); s = c; } - - if(c == e) { + + if (c == e) { htsbuf_append(hq, s, c - s); break; } @@ -485,53 +434,39 @@ htsbuf_append_and_escape_url(htsbuf_queue_t *hq, const char *s) /** * RFC8187 (RFC5987) HTTP Header non-ASCII field encoding */ -void -htsbuf_append_and_escape_rfc8187(htsbuf_queue_t *hq, const char *s) -{ - const char *c = s; - const char *e = s + strlen(s); - char C; - if(e == s) +void htsbuf_append_and_escape_rfc8187(htsbuf_queue_t* hq, const char* s) { + const char* c = s; + const char* e = s + strlen(s); + char C; + if (e == s) return; - while(1) { - const char *esc; - char buf[4]; + while (1) { + const char* esc; + char buf[4]; C = *c++; /* RFC 8187, section 3.2.1, attr-char */ - if((C >= '0' && C <= '9') || - (C >= 'a' && C <= 'z') || - (C >= 'A' && C <= 'Z') || - C == '!' || - C == '#' || - C == '$' || - C == '&' || - C == '+' || - C == '-' || - C == '.' || - C == '^' || - C == '_' || - C == '`' || - C == '|' || - C == '~') { + if ((C >= '0' && C <= '9') || (C >= 'a' && C <= 'z') || (C >= 'A' && C <= 'Z') || C == '!' || + C == '#' || C == '$' || C == '&' || C == '+' || C == '-' || C == '.' || C == '^' || + C == '_' || C == '`' || C == '|' || C == '~') { esc = NULL; } else { static const char hexchars[16] = "0123456789ABCDEF"; - buf[0] = '%'; - buf[1] = hexchars[(C >> 4) & 0xf]; - buf[2] = hexchars[C & 0xf]; - buf[3] = 0; - esc = buf; + buf[0] = '%'; + buf[1] = hexchars[(C >> 4) & 0xf]; + buf[2] = hexchars[C & 0xf]; + buf[3] = 0; + esc = buf; } - if(esc != NULL) { + if (esc != NULL) { htsbuf_append(hq, s, c - s - 1); htsbuf_append_str(hq, esc); s = c; } - if(c == e) { + if (c == e) { htsbuf_append(hq, s, c - s); break; } @@ -541,27 +476,25 @@ htsbuf_append_and_escape_rfc8187(htsbuf_queue_t *hq, const char *s) /** * */ -void -htsbuf_append_and_escape_jsonstr(htsbuf_queue_t *hq, const char *str) -{ - const char *s = str; +void htsbuf_append_and_escape_jsonstr(htsbuf_queue_t* hq, const char* str) { + const char* s = str; htsbuf_append(hq, "\"", 1); - while(*s != 0) { - if(*s == '"' || *s == '\\' || *s == '\n' || *s == '\r' || *s == '\t') { + while (*s != 0) { + if (*s == '"' || *s == '\\' || *s == '\n' || *s == '\r' || *s == '\t') { htsbuf_append(hq, str, s - str); - if(*s == '"') - htsbuf_append(hq, "\\\"", 2); - else if(*s == '\n') - htsbuf_append(hq, "\\n", 2); - else if(*s == '\r') - htsbuf_append(hq, "\\r", 2); - else if(*s == '\t') - htsbuf_append(hq, "\\t", 2); + if (*s == '"') + htsbuf_append(hq, "\\\"", 2); + else if (*s == '\n') + htsbuf_append(hq, "\\n", 2); + else if (*s == '\r') + htsbuf_append(hq, "\\r", 2); + else if (*s == '\t') + htsbuf_append(hq, "\\t", 2); else - htsbuf_append(hq, "\\\\", 2); + htsbuf_append(hq, "\\\\", 2); s++; str = s; } else { @@ -572,15 +505,11 @@ htsbuf_append_and_escape_jsonstr(htsbuf_queue_t *hq, const char *str) htsbuf_append(hq, "\"", 1); } - - /** * */ -char * -htsbuf_to_string(htsbuf_queue_t *hq) -{ - char *r = malloc(hq->hq_size + 1); +char* htsbuf_to_string(htsbuf_queue_t* hq) { + char* r = malloc(hq->hq_size + 1); r[hq->hq_size] = 0; htsbuf_read(hq, r, hq->hq_size); return r; diff --git a/src/htsbuf.h b/src/htsbuf.h index 093299400..ba61ec231 100644 --- a/src/htsbuf.h +++ b/src/htsbuf.h @@ -24,12 +24,11 @@ #include "queue.h" - TAILQ_HEAD(htsbuf_data_queue, htsbuf_data); typedef struct htsbuf_data { TAILQ_ENTRY(htsbuf_data) hd_link; - uint8_t *hd_data; + uint8_t* hd_data; unsigned int hd_data_size; /* Size of allocation hb_data */ unsigned int hd_data_len; /* Number of valid bytes from hd_data */ unsigned int hd_data_off; /* Offset in data, used for partial writes */ @@ -37,59 +36,61 @@ typedef struct htsbuf_data { typedef struct htsbuf_queue { struct htsbuf_data_queue hq_q; - unsigned int hq_size; - unsigned int hq_maxsize; -} htsbuf_queue_t; + unsigned int hq_size; + unsigned int hq_maxsize; +} htsbuf_queue_t; -void htsbuf_queue_init(htsbuf_queue_t *hq, unsigned int maxsize); +void htsbuf_queue_init(htsbuf_queue_t* hq, unsigned int maxsize); -htsbuf_queue_t *htsbuf_queue_alloc(unsigned int maxsize); +htsbuf_queue_t* htsbuf_queue_alloc(unsigned int maxsize); -void htsbuf_queue_free(htsbuf_queue_t *hq); +void htsbuf_queue_free(htsbuf_queue_t* hq); -void htsbuf_queue_flush(htsbuf_queue_t *hq); +void htsbuf_queue_flush(htsbuf_queue_t* hq); -void htsbuf_vqprintf(htsbuf_queue_t *hq, const char *fmt, va_list ap); +void htsbuf_vqprintf(htsbuf_queue_t* hq, const char* fmt, va_list ap); -void htsbuf_qprintf(htsbuf_queue_t *hq, const char *fmt, ...) - __attribute__((format(printf,2,3))); +void htsbuf_qprintf(htsbuf_queue_t* hq, const char* fmt, ...) __attribute__((format(printf, 2, 3))); -void htsbuf_append(htsbuf_queue_t *hq, const void *buf, size_t len); +void htsbuf_append(htsbuf_queue_t* hq, const void* buf, size_t len); -void htsbuf_append_prealloc(htsbuf_queue_t *hq, const void *buf, size_t len); +void htsbuf_append_prealloc(htsbuf_queue_t* hq, const void* buf, size_t len); -static inline void htsbuf_append_str(htsbuf_queue_t *hq, const char *str) - { htsbuf_append(hq, str, strlen(str)); } +static inline void htsbuf_append_str(htsbuf_queue_t* hq, const char* str) { + htsbuf_append(hq, str, strlen(str)); +} -void htsbuf_data_free(htsbuf_queue_t *hq, htsbuf_data_t *hd); +void htsbuf_data_free(htsbuf_queue_t* hq, htsbuf_data_t* hd); -static inline int htsbuf_empty(htsbuf_queue_t *hq) { return hq->hq_size == 0; } +static inline int htsbuf_empty(htsbuf_queue_t* hq) { + return hq->hq_size == 0; +} -size_t htsbuf_read(htsbuf_queue_t *hq, void *buf, size_t len); +size_t htsbuf_read(htsbuf_queue_t* hq, void* buf, size_t len); -size_t htsbuf_peek(htsbuf_queue_t *hq, void *buf, size_t len); +size_t htsbuf_peek(htsbuf_queue_t* hq, void* buf, size_t len); -size_t htsbuf_drop(htsbuf_queue_t *hq, size_t len); +size_t htsbuf_drop(htsbuf_queue_t* hq, size_t len); -size_t htsbuf_find(htsbuf_queue_t *hq, uint8_t v); +size_t htsbuf_find(htsbuf_queue_t* hq, uint8_t v); -void htsbuf_appendq(htsbuf_queue_t *hq, htsbuf_queue_t *src); +void htsbuf_appendq(htsbuf_queue_t* hq, htsbuf_queue_t* src); -void htsbuf_append_and_escape_xml(htsbuf_queue_t *hq, const char *str); +void htsbuf_append_and_escape_xml(htsbuf_queue_t* hq, const char* str); -void htsbuf_append_and_escape_url(htsbuf_queue_t *hq, const char *s); +void htsbuf_append_and_escape_url(htsbuf_queue_t* hq, const char* s); -void htsbuf_append_and_escape_rfc8187(htsbuf_queue_t *hq, const char *s); +void htsbuf_append_and_escape_rfc8187(htsbuf_queue_t* hq, const char* s); -void htsbuf_append_and_escape_jsonstr(htsbuf_queue_t *hq, const char *s); +void htsbuf_append_and_escape_jsonstr(htsbuf_queue_t* hq, const char* s); -void htsbuf_dump_raw_stderr(htsbuf_queue_t *hq); +void htsbuf_dump_raw_stderr(htsbuf_queue_t* hq); -char *htsbuf_to_string(htsbuf_queue_t *hq); +char* htsbuf_to_string(htsbuf_queue_t* hq); struct rstr; -struct rstr *htsbuf_to_rstr(htsbuf_queue_t *hq, const char *prefix); +struct rstr* htsbuf_to_rstr(htsbuf_queue_t* hq, const char* prefix); -void htsbuf_hexdump(htsbuf_queue_t *hq, const char *prefix); +void htsbuf_hexdump(htsbuf_queue_t* hq, const char* prefix); #endif /* HTSBUF_H__ */ diff --git a/src/htsmsg.c b/src/htsmsg.c index 74a8a0300..616761281 100644 --- a/src/htsmsg.c +++ b/src/htsmsg.c @@ -30,50 +30,48 @@ #include "memoryinfo.h" #if ENABLE_SLOW_MEMORYINFO -memoryinfo_t htsmsg_memoryinfo = { .my_name = "htsmsg" }; -memoryinfo_t htsmsg_field_memoryinfo = { .my_name = "htsmsg field" }; +memoryinfo_t htsmsg_memoryinfo = {.my_name = "htsmsg"}; +memoryinfo_t htsmsg_field_memoryinfo = {.my_name = "htsmsg field"}; #endif -static void htsmsg_clear(htsmsg_t *msg); -static htsmsg_t *htsmsg_field_get_msg ( htsmsg_field_t *f, int islist ); +static void htsmsg_clear(htsmsg_t* msg); +static htsmsg_t* htsmsg_field_get_msg(htsmsg_field_t* f, int islist); /** * */ -static void -htsmsg_field_data_destroy(htsmsg_field_t *f) -{ - switch(f->hmf_type) { - case HMF_MAP: - case HMF_LIST: - htsmsg_clear(f->hmf_msg); - if(f->hmf_flags & HMF_ALLOCED) { +static void htsmsg_field_data_destroy(htsmsg_field_t* f) { + switch (f->hmf_type) { + case HMF_MAP: + case HMF_LIST: + htsmsg_clear(f->hmf_msg); + if (f->hmf_flags & HMF_ALLOCED) { #if ENABLE_SLOW_MEMORYINFO - memoryinfo_remove(&htsmsg_field_memoryinfo, sizeof(htsmsg_t)); + memoryinfo_remove(&htsmsg_field_memoryinfo, sizeof(htsmsg_t)); #endif - free(f->hmf_msg); - } - break; + free(f->hmf_msg); + } + break; - case HMF_STR: - if(f->hmf_flags & HMF_ALLOCED) { + case HMF_STR: + if (f->hmf_flags & HMF_ALLOCED) { #if ENABLE_SLOW_MEMORYINFO - memoryinfo_remove(&htsmsg_field_memoryinfo, strlen(f->hmf_str) + 1); + memoryinfo_remove(&htsmsg_field_memoryinfo, strlen(f->hmf_str) + 1); #endif - free((void *)f->hmf_str); - } - break; + free((void*)f->hmf_str); + } + break; - case HMF_BIN: - if(f->hmf_flags & HMF_ALLOCED) { + case HMF_BIN: + if (f->hmf_flags & HMF_ALLOCED) { #if ENABLE_SLOW_MEMORYINFO - memoryinfo_remove(&htsmsg_field_memoryinfo, f->hmf_binsize); + memoryinfo_remove(&htsmsg_field_memoryinfo, f->hmf_binsize); #endif - free((void *)f->hmf_bin); - } - break; - default: - break; + free((void*)f->hmf_bin); + } + break; + default: + break; } f->hmf_flags &= ~HMF_ALLOCED; } @@ -81,16 +79,13 @@ htsmsg_field_data_destroy(htsmsg_field_t *f) /** * */ -void -htsmsg_field_destroy(htsmsg_t *msg, htsmsg_field_t *f) -{ +void htsmsg_field_destroy(htsmsg_t* msg, htsmsg_field_t* f) { TAILQ_REMOVE(&msg->hm_fields, f, hmf_link); htsmsg_field_data_destroy(f); #if ENABLE_SLOW_MEMORYINFO - memoryinfo_free(&htsmsg_field_memoryinfo, - sizeof(htsmsg_field_t) + f->hmf_edata_size); + memoryinfo_free(&htsmsg_field_memoryinfo, sizeof(htsmsg_field_t) + f->hmf_edata_size); #endif free(f); } @@ -98,25 +93,21 @@ htsmsg_field_destroy(htsmsg_t *msg, htsmsg_field_t *f) /* * */ -static void -htsmsg_clear(htsmsg_t *msg) -{ - htsmsg_field_t *f; +static void htsmsg_clear(htsmsg_t* msg) { + htsmsg_field_t* f; - while((f = TAILQ_FIRST(&msg->hm_fields)) != NULL) + while ((f = TAILQ_FIRST(&msg->hm_fields)) != NULL) htsmsg_field_destroy(msg, f); } - /* * */ -htsmsg_field_t * -htsmsg_field_add(htsmsg_t *msg, const char *name, int type, int flags, size_t esize) -{ - size_t nsize; - htsmsg_field_t *f; - +htsmsg_field_t* +htsmsg_field_add(htsmsg_t* msg, const char* name, int type, int flags, size_t esize) { + size_t nsize; + htsmsg_field_t* f; + if (msg->hm_islist) { assert(name == NULL || *name == '\0'); name = NULL; @@ -138,83 +129,70 @@ htsmsg_field_add(htsmsg_t *msg, const char *name, int type, int flags, size_t es TAILQ_INSERT_TAIL(&msg->hm_fields, f, hmf_link); if (name) - strcpy((char *)f->_hmf_name, name); + strcpy((char*)f->_hmf_name, name); if (esize) { - if(type == HMF_STR) { + if (type == HMF_STR) { f->hmf_str = f->_hmf_name + nsize; - } else if(type == HMF_UUID) { - f->hmf_uuid = (uint8_t *)f->_hmf_name + nsize; - } else if(type == HMF_LIST || type == HMF_MAP) { - f->hmf_msg = (htsmsg_t *)(f->_hmf_name + nsize); - } else if(type == HMF_BIN) { - f->hmf_bin = f->_hmf_name + nsize; + } else if (type == HMF_UUID) { + f->hmf_uuid = (uint8_t*)f->_hmf_name + nsize; + } else if (type == HMF_LIST || type == HMF_MAP) { + f->hmf_msg = (htsmsg_t*)(f->_hmf_name + nsize); + } else if (type == HMF_BIN) { + f->hmf_bin = f->_hmf_name + nsize; f->hmf_binsize = esize; } } - f->hmf_type = type; + f->hmf_type = type; f->hmf_flags = flags; #if ENABLE_SLOW_MEMORYINFO f->hmf_edata_size = nsize + esize; - memoryinfo_alloc(&htsmsg_field_memoryinfo, - sizeof(htsmsg_field_t) + f->hmf_edata_size); + memoryinfo_alloc(&htsmsg_field_memoryinfo, sizeof(htsmsg_field_t) + f->hmf_edata_size); #endif return f; } - /* * */ -htsmsg_field_t * -htsmsg_field_find(const htsmsg_t *msg, const char *name) -{ - htsmsg_field_t *f; +htsmsg_field_t* htsmsg_field_find(const htsmsg_t* msg, const char* name) { + htsmsg_field_t* f; if (msg == NULL || name == NULL) return NULL; - TAILQ_FOREACH(f, &msg->hm_fields, hmf_link) { - if(!strcmp(htsmsg_field_name(f), name)) + TAILQ_FOREACH (f, &msg->hm_fields, hmf_link) { + if (!strcmp(htsmsg_field_name(f), name)) return f; } return NULL; } - /* * */ -htsmsg_field_t * -htsmsg_field_last(htsmsg_t *msg) -{ +htsmsg_field_t* htsmsg_field_last(htsmsg_t* msg) { if (msg == NULL) return NULL; return TAILQ_LAST(&msg->hm_fields, htsmsg_field_queue); } - /** * */ -int -htsmsg_delete_field(htsmsg_t *msg, const char *name) -{ - htsmsg_field_t *f; +int htsmsg_delete_field(htsmsg_t* msg, const char* name) { + htsmsg_field_t* f; - if((f = htsmsg_field_find(msg, name)) == NULL) + if ((f = htsmsg_field_find(msg, name)) == NULL) return HTSMSG_ERR_FIELD_NOT_FOUND; htsmsg_field_destroy(msg, f); return 0; } - /** * */ -int -htsmsg_is_empty(htsmsg_t *msg) -{ +int htsmsg_is_empty(htsmsg_t* msg) { if (msg == NULL) return 1; @@ -222,21 +200,18 @@ htsmsg_is_empty(htsmsg_t *msg) return TAILQ_EMPTY(&msg->hm_fields); } - /* * */ -htsmsg_t * -htsmsg_create_map(void) -{ - htsmsg_t *msg; +htsmsg_t* htsmsg_create_map(void) { + htsmsg_t* msg; msg = malloc(sizeof(htsmsg_t)); if (msg) { TAILQ_INIT(&msg->hm_fields); - msg->hm_data = NULL; + msg->hm_data = NULL; msg->hm_data_size = 0; - msg->hm_islist = 0; + msg->hm_islist = 0; #if ENABLE_SLOW_MEMORYINFO memoryinfo_alloc(&htsmsg_memoryinfo, sizeof(htsmsg_t)); #endif @@ -247,17 +222,15 @@ htsmsg_create_map(void) /* * */ -htsmsg_t * -htsmsg_create_list(void) -{ - htsmsg_t *msg; +htsmsg_t* htsmsg_create_list(void) { + htsmsg_t* msg; msg = malloc(sizeof(htsmsg_t)); if (msg) { TAILQ_INIT(&msg->hm_fields); - msg->hm_data = NULL; + msg->hm_data = NULL; msg->hm_data_size = 0; - msg->hm_islist = 1; + msg->hm_islist = 1; #if ENABLE_SLOW_MEMORYINFO memoryinfo_alloc(&htsmsg_memoryinfo, sizeof(htsmsg_t)); #endif @@ -265,14 +238,10 @@ htsmsg_create_list(void) return msg; } - - /* * */ -void -htsmsg_concat(htsmsg_t *msg, htsmsg_t *sub) -{ +void htsmsg_concat(htsmsg_t* msg, htsmsg_t* sub) { if (sub == NULL) return; assert(msg->hm_islist == sub->hm_islist); @@ -282,19 +251,16 @@ htsmsg_concat(htsmsg_t *msg, htsmsg_t *sub) htsmsg_destroy(sub); } - /* * */ -void -htsmsg_destroy(htsmsg_t *msg) -{ - if(msg == NULL) +void htsmsg_destroy(htsmsg_t* msg) { + if (msg == NULL) return; htsmsg_clear(msg); if (msg->hm_data) { - free((void *)msg->hm_data); + free((void*)msg->hm_data); #if ENABLE_SLOW_MEMORYINFO memoryinfo_free(&htsmsg_memoryinfo, msg->hm_data_size); #endif @@ -308,20 +274,16 @@ htsmsg_destroy(htsmsg_t *msg) /* * */ -void -htsmsg_add_bool(htsmsg_t *msg, const char *name, int b) -{ - htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_BOOL, 0, 0); - f->hmf_bool = !!b; +void htsmsg_add_bool(htsmsg_t* msg, const char* name, int b) { + htsmsg_field_t* f = htsmsg_field_add(msg, name, HMF_BOOL, 0, 0); + f->hmf_bool = !!b; } /* * */ -void -htsmsg_set_bool(htsmsg_t *msg, const char *name, int b) -{ - htsmsg_field_t *f = htsmsg_field_find(msg, name); +void htsmsg_set_bool(htsmsg_t* msg, const char* name, int b) { + htsmsg_field_t* f = htsmsg_field_find(msg, name); if (!f) f = htsmsg_field_add(msg, name, HMF_BOOL, 0, 0); f->hmf_bool = !!b; @@ -330,20 +292,16 @@ htsmsg_set_bool(htsmsg_t *msg, const char *name, int b) /* * */ -void -htsmsg_add_s64(htsmsg_t *msg, const char *name, int64_t s64) -{ - htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_S64, 0, 0); - f->hmf_s64 = s64; +void htsmsg_add_s64(htsmsg_t* msg, const char* name, int64_t s64) { + htsmsg_field_t* f = htsmsg_field_add(msg, name, HMF_S64, 0, 0); + f->hmf_s64 = s64; } /* * */ -int -htsmsg_set_s64(htsmsg_t *msg, const char *name, int64_t s64) -{ - htsmsg_field_t *f = htsmsg_field_find(msg, name); +int htsmsg_set_s64(htsmsg_t* msg, const char* name, int64_t s64) { + htsmsg_field_t* f = htsmsg_field_find(msg, name); if (!f) f = htsmsg_field_add(msg, name, HMF_S64, 0, 0); if (f->hmf_type != HMF_S64) @@ -352,46 +310,36 @@ htsmsg_set_s64(htsmsg_t *msg, const char *name, int64_t s64) return 0; } - /* * */ -void -htsmsg_add_dbl(htsmsg_t *msg, const char *name, double dbl) -{ - htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_DBL, 0, 0); - f->hmf_dbl = dbl; +void htsmsg_add_dbl(htsmsg_t* msg, const char* name, double dbl) { + htsmsg_field_t* f = htsmsg_field_add(msg, name, HMF_DBL, 0, 0); + f->hmf_dbl = dbl; } - /* * */ -void -htsmsg_add_str(htsmsg_t *msg, const char *name, const char *str) -{ - htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_STR, 0, strlen(str) + 1); - strcpy((char *)f->hmf_str, str); +void htsmsg_add_str(htsmsg_t* msg, const char* name, const char* str) { + htsmsg_field_t* f = htsmsg_field_add(msg, name, HMF_STR, 0, strlen(str) + 1); + strcpy((char*)f->hmf_str, str); f->hmf_flags |= HMF_INALLOCED; } /* * */ -void -htsmsg_add_str_alloc(htsmsg_t *msg, const char *name, char *str) -{ - htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_STR, 0, 0); - f->hmf_str = str; +void htsmsg_add_str_alloc(htsmsg_t* msg, const char* name, char* str) { + htsmsg_field_t* f = htsmsg_field_add(msg, name, HMF_STR, 0, 0); + f->hmf_str = str; f->hmf_flags |= HMF_ALLOCED; } /* * */ -void -htsmsg_add_str2(htsmsg_t *msg, const char *name, const char *str) -{ +void htsmsg_add_str2(htsmsg_t* msg, const char* name, const char* str) { if (msg && name && str) htsmsg_add_str(msg, name, str); } @@ -399,14 +347,12 @@ htsmsg_add_str2(htsmsg_t *msg, const char *name, const char *str) /* * */ -void -htsmsg_add_str_exclusive(htsmsg_t *msg, const char *str) -{ - htsmsg_field_t *f; +void htsmsg_add_str_exclusive(htsmsg_t* msg, const char* str) { + htsmsg_field_t* f; assert(msg->hm_islist); - TAILQ_FOREACH(f, &msg->hm_fields, hmf_link) { + TAILQ_FOREACH (f, &msg->hm_fields, hmf_link) { assert(f->hmf_type == HMF_STR); if (strcmp(f->hmf_str, str) == 0) return; @@ -418,21 +364,18 @@ htsmsg_add_str_exclusive(htsmsg_t *msg, const char *str) /* * */ -int -htsmsg_field_set_str(htsmsg_field_t *f, const char *str) -{ +int htsmsg_field_set_str(htsmsg_field_t* f, const char* str) { if (f->hmf_type != HMF_STR) return 1; if (f->hmf_flags & HMF_ALLOCED) { #if ENABLE_SLOW_MEMORYINFO memoryinfo_remove(&htsmsg_field_memoryinfo, strlen(f->hmf_str) + 1); #endif - free((void *)f->hmf_str); + free((void*)f->hmf_str); f->hmf_flags &= ~HMF_ALLOCED; - } - else if (f->hmf_flags & HMF_INALLOCED) { + } else if (f->hmf_flags & HMF_INALLOCED) { if (strlen(f->hmf_str) >= strlen(str)) { - strcpy((char *)f->hmf_str, str); + strcpy((char*)f->hmf_str, str); return 0; } f->hmf_flags &= ~HMF_INALLOCED; @@ -450,13 +393,11 @@ htsmsg_field_set_str(htsmsg_field_t *f, const char *str) /* * */ -int -htsmsg_field_set_str_force(htsmsg_field_t *f, const char *str) -{ +int htsmsg_field_set_str_force(htsmsg_field_t* f, const char* str) { if (f->hmf_type != HMF_STR) { htsmsg_field_data_destroy(f); f->hmf_type = HMF_STR; - f->hmf_str = ""; + f->hmf_str = ""; } return htsmsg_field_set_str(f, str); } @@ -464,10 +405,8 @@ htsmsg_field_set_str_force(htsmsg_field_t *f, const char *str) /* * */ -int -htsmsg_set_str(htsmsg_t *msg, const char *name, const char *str) -{ - htsmsg_field_t *f = htsmsg_field_find(msg, name); +int htsmsg_set_str(htsmsg_t* msg, const char* name, const char* str) { + htsmsg_field_t* f = htsmsg_field_find(msg, name); if (!f) { htsmsg_add_str(msg, name, str); return 0; @@ -478,9 +417,7 @@ htsmsg_set_str(htsmsg_t *msg, const char *name, const char *str) /* * */ -int -htsmsg_set_str2(htsmsg_t *msg, const char *name, const char *str) -{ +int htsmsg_set_str2(htsmsg_t* msg, const char* name, const char* str) { if (msg && name && str) return htsmsg_set_str(msg, name, str); return 1; @@ -489,21 +426,18 @@ htsmsg_set_str2(htsmsg_t *msg, const char *name, const char *str) /* * */ -int -htsmsg_field_set_bin(htsmsg_field_t *f, const void *bin, size_t len) -{ +int htsmsg_field_set_bin(htsmsg_field_t* f, const void* bin, size_t len) { if (f->hmf_type != HMF_BIN) return 1; if (f->hmf_flags & HMF_ALLOCED) { #if ENABLE_SLOW_MEMORYINFO memoryinfo_remove(&htsmsg_field_memoryinfo, f->hmf_binsize); #endif - free((void *)f->hmf_bin); + free((void*)f->hmf_bin); f->hmf_flags &= ~HMF_ALLOCED; - } - else if (f->hmf_flags & HMF_INALLOCED) { + } else if (f->hmf_flags & HMF_INALLOCED) { if (f->hmf_binsize >= len) { - memmove((void *)f->hmf_bin, bin, len); + memmove((void*)f->hmf_bin, bin, len); f->hmf_binsize = len; return 0; } @@ -514,7 +448,7 @@ htsmsg_field_set_bin(htsmsg_field_t *f, const void *bin, size_t len) return 1; f->hmf_flags |= HMF_ALLOCED; f->hmf_binsize = len; - memcpy((void *)f->hmf_bin, bin, len); + memcpy((void*)f->hmf_bin, bin, len); #if ENABLE_SLOW_MEMORYINFO memoryinfo_alloc(&htsmsg_field_memoryinfo, len); #endif @@ -524,13 +458,11 @@ htsmsg_field_set_bin(htsmsg_field_t *f, const void *bin, size_t len) /* * */ -int -htsmsg_field_set_bin_force(htsmsg_field_t *f, const void *bin, size_t len) -{ +int htsmsg_field_set_bin_force(htsmsg_field_t* f, const void* bin, size_t len) { if (f->hmf_type != HMF_BIN) { htsmsg_field_data_destroy(f); - f->hmf_type = HMF_BIN; - f->hmf_bin = NULL; + f->hmf_type = HMF_BIN; + f->hmf_bin = NULL; f->hmf_binsize = 0; } return htsmsg_field_set_bin(f, bin, len); @@ -539,43 +471,35 @@ htsmsg_field_set_bin_force(htsmsg_field_t *f, const void *bin, size_t len) /* * */ -void -htsmsg_add_bin(htsmsg_t *msg, const char *name, const void *bin, size_t len) -{ - htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_BIN, 0, len); +void htsmsg_add_bin(htsmsg_t* msg, const char* name, const void* bin, size_t len) { + htsmsg_field_t* f = htsmsg_field_add(msg, name, HMF_BIN, 0, len); f->hmf_flags |= HMF_INALLOCED; - memcpy((void *)f->hmf_bin, bin, len); + memcpy((void*)f->hmf_bin, bin, len); } /* * */ -void -htsmsg_add_bin_alloc(htsmsg_t *msg, const char *name, const void *bin, size_t len) -{ - htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_BIN, 0, 0); +void htsmsg_add_bin_alloc(htsmsg_t* msg, const char* name, const void* bin, size_t len) { + htsmsg_field_t* f = htsmsg_field_add(msg, name, HMF_BIN, 0, 0); f->hmf_flags |= HMF_ALLOCED; - f->hmf_bin = bin; + f->hmf_bin = bin; f->hmf_binsize = len; } /* * */ -void -htsmsg_add_bin_ptr(htsmsg_t *msg, const char *name, const void *bin, size_t len) -{ - htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_BIN, 0, 0); - f->hmf_bin = bin; - f->hmf_binsize = len; +void htsmsg_add_bin_ptr(htsmsg_t* msg, const char* name, const void* bin, size_t len) { + htsmsg_field_t* f = htsmsg_field_add(msg, name, HMF_BIN, 0, 0); + f->hmf_bin = bin; + f->hmf_binsize = len; } /* * */ -static int -htsmsg_field_set_uuid(htsmsg_field_t *f, tvh_uuid_t *u) -{ +static int htsmsg_field_set_uuid(htsmsg_field_t* f, tvh_uuid_t* u) { if (f->hmf_type != HMF_UUID) { htsmsg_field_data_destroy(f); f->hmf_type = HMF_UUID; @@ -584,17 +508,15 @@ htsmsg_field_set_uuid(htsmsg_field_t *f, tvh_uuid_t *u) return 1; f->hmf_flags |= HMF_ALLOCED; } - memcpy((char *)f->hmf_uuid, u->bin, UUID_BIN_SIZE); + memcpy((char*)f->hmf_uuid, u->bin, UUID_BIN_SIZE); return 0; } /* * */ -int -htsmsg_set_uuid(htsmsg_t *msg, const char *name, tvh_uuid_t *u) -{ - htsmsg_field_t *f = htsmsg_field_find(msg, name); +int htsmsg_set_uuid(htsmsg_t* msg, const char* name, tvh_uuid_t* u) { + htsmsg_field_t* f = htsmsg_field_find(msg, name); if (!f) { htsmsg_add_uuid(msg, name, u); return 0; @@ -605,26 +527,22 @@ htsmsg_set_uuid(htsmsg_t *msg, const char *name, tvh_uuid_t *u) /* * */ -void -htsmsg_add_uuid(htsmsg_t *msg, const char *name, tvh_uuid_t *u) -{ - htsmsg_field_t *f = htsmsg_field_add(msg, name, HMF_UUID, 0, UUID_BIN_SIZE); +void htsmsg_add_uuid(htsmsg_t* msg, const char* name, tvh_uuid_t* u) { + htsmsg_field_t* f = htsmsg_field_add(msg, name, HMF_UUID, 0, UUID_BIN_SIZE); f->hmf_flags |= HMF_INALLOCED; - memcpy((void *)f->hmf_uuid, u->bin, UUID_BIN_SIZE); + memcpy((void*)f->hmf_uuid, u->bin, UUID_BIN_SIZE); } /* * */ -static htsmsg_t * -htsmsg_field_set_msg(htsmsg_field_t *f, htsmsg_t *sub) -{ - htsmsg_t *m = f->hmf_msg; +static htsmsg_t* htsmsg_field_set_msg(htsmsg_field_t* f, htsmsg_t* sub) { + htsmsg_t* m = f->hmf_msg; assert(sub->hm_data == NULL); assert(f->hmf_type == HMF_LIST || f->hmf_type == HMF_MAP); - m->hm_data = NULL; + m->hm_data = NULL; m->hm_data_size = 0; - m->hm_islist = sub->hm_islist; + m->hm_islist = sub->hm_islist; TAILQ_MOVE(&m->hm_fields, &sub->hm_fields, hmf_link); htsmsg_destroy(sub); @@ -637,23 +555,18 @@ htsmsg_field_set_msg(htsmsg_field_t *f, htsmsg_t *sub) /* * */ -htsmsg_t * -htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub) -{ - htsmsg_field_t *f; +htsmsg_t* htsmsg_add_msg(htsmsg_t* msg, const char* name, htsmsg_t* sub) { + htsmsg_field_t* f; - f = htsmsg_field_add(msg, name, sub->hm_islist ? HMF_LIST : HMF_MAP, - 0, sizeof(htsmsg_t)); + f = htsmsg_field_add(msg, name, sub->hm_islist ? HMF_LIST : HMF_MAP, 0, sizeof(htsmsg_t)); return htsmsg_field_set_msg(f, sub); } /* * */ -htsmsg_t * -htsmsg_set_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub) -{ - htsmsg_field_t *f = htsmsg_field_find(msg, name); +htsmsg_t* htsmsg_set_msg(htsmsg_t* msg, const char* name, htsmsg_t* sub) { + htsmsg_field_t* f = htsmsg_field_find(msg, name); if (!f) return htsmsg_add_msg(msg, name, sub); htsmsg_field_data_destroy(f); @@ -663,18 +576,15 @@ htsmsg_set_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub) /* * */ -void -htsmsg_add_msg_extname(htsmsg_t *msg, const char *name, htsmsg_t *sub) -{ - htsmsg_t *m; - htsmsg_field_t *f; +void htsmsg_add_msg_extname(htsmsg_t* msg, const char* name, htsmsg_t* sub) { + htsmsg_t* m; + htsmsg_field_t* f; - f = htsmsg_field_add(msg, name, sub->hm_islist ? HMF_LIST : HMF_MAP, - 0, sizeof(htsmsg_t)); + f = htsmsg_field_add(msg, name, sub->hm_islist ? HMF_LIST : HMF_MAP, 0, sizeof(htsmsg_t)); m = f->hmf_msg; assert(sub->hm_data == NULL); - m->hm_data = NULL; + m->hm_data = NULL; m->hm_data_size = 0; TAILQ_MOVE(&m->hm_fields, &sub->hm_fields, hmf_link); m->hm_islist = sub->hm_islist; @@ -684,36 +594,31 @@ htsmsg_add_msg_extname(htsmsg_t *msg, const char *name, htsmsg_t *sub) /** * */ -int -htsmsg_get_s64(htsmsg_t *msg, const char *name, int64_t *s64p) -{ - htsmsg_field_t *f; +int htsmsg_get_s64(htsmsg_t* msg, const char* name, int64_t* s64p) { + htsmsg_field_t* f; - if((f = htsmsg_field_find(msg, name)) == NULL) + if ((f = htsmsg_field_find(msg, name)) == NULL) return HTSMSG_ERR_FIELD_NOT_FOUND; - + return htsmsg_field_get_s64(f, s64p); } -int -htsmsg_field_get_s64 - (htsmsg_field_t *f, int64_t *s64p) -{ - switch(f->hmf_type) { - default: - return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - case HMF_STR: - *s64p = strtoll(f->hmf_str, NULL, 0); - break; - case HMF_S64: - *s64p = f->hmf_s64; - break; - case HMF_BOOL: - *s64p = f->hmf_bool; - break; - case HMF_DBL: - *s64p = f->hmf_dbl; - break; +int htsmsg_field_get_s64(htsmsg_field_t* f, int64_t* s64p) { + switch (f->hmf_type) { + default: + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + case HMF_STR: + *s64p = strtoll(f->hmf_str, NULL, 0); + break; + case HMF_S64: + *s64p = f->hmf_s64; + break; + case HMF_BOOL: + *s64p = f->hmf_bool; + break; + case HMF_DBL: + *s64p = f->hmf_dbl; + break; } return 0; } @@ -721,53 +626,40 @@ htsmsg_field_get_s64 /** * */ -int -bool_check(const char *str) -{ +int bool_check(const char* str) { if (str && - (!strcmp(str, "yes") || - !strcmp(str, "true") || - !strcmp(str, "on") || - !strcmp(str, "1"))) + (!strcmp(str, "yes") || !strcmp(str, "true") || !strcmp(str, "on") || !strcmp(str, "1"))) return 1; return 0; } -int -htsmsg_field_get_bool - ( htsmsg_field_t *f, int *boolp ) -{ - switch(f->hmf_type) { - default: - return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - case HMF_STR: - *boolp = bool_check(f->hmf_str); - break; - case HMF_S64: - *boolp = f->hmf_s64 ? 1 : 0; - break; - case HMF_BOOL: - *boolp = f->hmf_bool; - break; +int htsmsg_field_get_bool(htsmsg_field_t* f, int* boolp) { + switch (f->hmf_type) { + default: + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + case HMF_STR: + *boolp = bool_check(f->hmf_str); + break; + case HMF_S64: + *boolp = f->hmf_s64 ? 1 : 0; + break; + case HMF_BOOL: + *boolp = f->hmf_bool; + break; } return 0; } -int -htsmsg_get_bool - (htsmsg_t *msg, const char *name, int *boolp) -{ - htsmsg_field_t *f; +int htsmsg_get_bool(htsmsg_t* msg, const char* name, int* boolp) { + htsmsg_field_t* f; - if((f = htsmsg_field_find(msg, name)) == NULL) + if ((f = htsmsg_field_find(msg, name)) == NULL) return HTSMSG_ERR_FIELD_NOT_FOUND; - + return htsmsg_field_get_bool(f, boolp); } -int -htsmsg_get_bool_or_default(htsmsg_t *msg, const char *name, int def) -{ +int htsmsg_get_bool_or_default(htsmsg_t* msg, const char* name, int def) { int ret; return htsmsg_get_bool(msg, name, &ret) ? def : ret; } @@ -775,9 +667,7 @@ htsmsg_get_bool_or_default(htsmsg_t *msg, const char *name, int def) /** * */ -int64_t -htsmsg_get_s64_or_default(htsmsg_t *msg, const char *name, int64_t def) -{ +int64_t htsmsg_get_s64_or_default(htsmsg_t* msg, const char* name, int64_t def) { int64_t s64; return htsmsg_get_s64(msg, name, &s64) ? def : s64; } @@ -785,34 +675,30 @@ htsmsg_get_s64_or_default(htsmsg_t *msg, const char *name, int64_t def) /* * */ -int -htsmsg_get_u32(htsmsg_t *msg, const char *name, uint32_t *u32p) -{ - int r; +int htsmsg_get_u32(htsmsg_t* msg, const char* name, uint32_t* u32p) { + int r; int64_t s64; - if((r = htsmsg_get_s64(msg, name, &s64)) != 0) + if ((r = htsmsg_get_s64(msg, name, &s64)) != 0) return r; - if(s64 < 0 || s64 > 0xffffffffLL) + if (s64 < 0 || s64 > 0xffffffffLL) return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - + *u32p = s64; return 0; } -int -htsmsg_field_get_u32(htsmsg_field_t *f, uint32_t *u32p) -{ - int r; +int htsmsg_field_get_u32(htsmsg_field_t* f, uint32_t* u32p) { + int r; int64_t s64; - + if ((r = htsmsg_field_get_s64(f, &s64))) return r; if (s64 < 0 || s64 > 0xffffffffL) - return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + *u32p = s64; return 0; } @@ -820,9 +706,7 @@ htsmsg_field_get_u32(htsmsg_field_t *f, uint32_t *u32p) /** * */ -int -htsmsg_get_u32_or_default(htsmsg_t *msg, const char *name, uint32_t def) -{ +int htsmsg_get_u32_or_default(htsmsg_t* msg, const char* name, uint32_t def) { uint32_t u32; return htsmsg_get_u32(msg, name, &u32) ? def : u32; } @@ -830,9 +714,7 @@ htsmsg_get_u32_or_default(htsmsg_t *msg, const char *name, uint32_t def) /** * */ -int32_t -htsmsg_get_s32_or_default(htsmsg_t *msg, const char *name, int32_t def) -{ +int32_t htsmsg_get_s32_or_default(htsmsg_t* msg, const char* name, int32_t def) { int32_t s32; return htsmsg_get_s32(msg, name, &s32) ? def : s32; } @@ -840,16 +722,14 @@ htsmsg_get_s32_or_default(htsmsg_t *msg, const char *name, int32_t def) /* * */ -int -htsmsg_get_s32(htsmsg_t *msg, const char *name, int32_t *s32p) -{ - int r; +int htsmsg_get_s32(htsmsg_t* msg, const char* name, int32_t* s32p) { + int r; int64_t s64; - if((r = htsmsg_get_s64(msg, name, &s64)) != 0) + if ((r = htsmsg_get_s64(msg, name, &s64)) != 0) return r; - if(s64 < -0x80000000LL || s64 > 0x7fffffffLL) + if (s64 < -0x80000000LL || s64 > 0x7fffffffLL) return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; *s32p = s64; @@ -859,16 +739,14 @@ htsmsg_get_s32(htsmsg_t *msg, const char *name, int32_t *s32p) /* * */ -int -htsmsg_field_get_s32(htsmsg_field_t *f, int32_t *s32p) -{ - int r; +int htsmsg_field_get_s32(htsmsg_field_t* f, int32_t* s32p) { + int r; int64_t s64; - if((r = htsmsg_field_get_s64(f, &s64)) != 0) + if ((r = htsmsg_field_get_s64(f, &s64)) != 0) return r; - if(s64 < -0x80000000LL || s64 > 0x7fffffffLL) + if (s64 < -0x80000000LL || s64 > 0x7fffffffLL) return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; *s32p = s64; @@ -878,21 +756,16 @@ htsmsg_field_get_s32(htsmsg_field_t *f, int32_t *s32p) /* * */ -int -htsmsg_get_dbl(htsmsg_t *msg, const char *name, double *dblp) -{ - htsmsg_field_t *f; +int htsmsg_get_dbl(htsmsg_t* msg, const char* name, double* dblp) { + htsmsg_field_t* f; - if((f = htsmsg_field_find(msg, name)) == NULL) + if ((f = htsmsg_field_find(msg, name)) == NULL) return HTSMSG_ERR_FIELD_NOT_FOUND; - + return htsmsg_field_get_dbl(f, dblp); } -int -htsmsg_field_get_dbl - ( htsmsg_field_t *f, double *dblp ) -{ +int htsmsg_field_get_dbl(htsmsg_field_t* f, double* dblp) { switch (f->hmf_type) { case HMF_S64: *dblp = (double)f->hmf_s64; @@ -913,31 +786,29 @@ htsmsg_field_get_dbl /** * */ -const char * -htsmsg_field_get_string(htsmsg_field_t *f) -{ +const char* htsmsg_field_get_string(htsmsg_field_t* f) { char buf[128]; - - switch(f->hmf_type) { - default: - return NULL; - case HMF_STR: - break; - case HMF_UUID: - uuid_get_hex((tvh_uuid_t *)f->hmf_uuid, buf); - htsmsg_field_set_str_force(f, buf); - break; - case HMF_BOOL: - htsmsg_field_set_str_force(f, f->hmf_bool ? "true" : "false"); - break; - case HMF_S64: - snprintf(buf, sizeof(buf), "%"PRId64, f->hmf_s64); - htsmsg_field_set_str_force(f, buf); - break; - case HMF_DBL: - snprintf(buf, sizeof(buf), "%lf", f->hmf_dbl); - htsmsg_field_set_str_force(f, buf); - break; + + switch (f->hmf_type) { + default: + return NULL; + case HMF_STR: + break; + case HMF_UUID: + uuid_get_hex((tvh_uuid_t*)f->hmf_uuid, buf); + htsmsg_field_set_str_force(f, buf); + break; + case HMF_BOOL: + htsmsg_field_set_str_force(f, f->hmf_bool ? "true" : "false"); + break; + case HMF_S64: + snprintf(buf, sizeof(buf), "%" PRId64, f->hmf_s64); + htsmsg_field_set_str_force(f, buf); + break; + case HMF_DBL: + snprintf(buf, sizeof(buf), "%lf", f->hmf_dbl); + htsmsg_field_set_str_force(f, buf); + break; } return f->hmf_str; } @@ -945,12 +816,10 @@ htsmsg_field_get_string(htsmsg_field_t *f) /* * */ -const char * -htsmsg_get_str(htsmsg_t *msg, const char *name) -{ - htsmsg_field_t *f; +const char* htsmsg_get_str(htsmsg_t* msg, const char* name) { + htsmsg_field_t* f; - if((f = htsmsg_field_find(msg, name)) == NULL) + if ((f = htsmsg_field_find(msg, name)) == NULL) return NULL; return htsmsg_field_get_string(f); } @@ -958,35 +827,33 @@ htsmsg_get_str(htsmsg_t *msg, const char *name) /** * */ -int -htsmsg_field_get_bin(htsmsg_field_t *f, const void **binp, size_t *lenp) -{ - uint8_t *p; - size_t l; - int r; +int htsmsg_field_get_bin(htsmsg_field_t* f, const void** binp, size_t* lenp) { + uint8_t* p; + size_t l; + int r; - switch(f->hmf_type) { - default: - return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - case HMF_STR: - l = strlen(f->hmf_str); - if (l % 2) - return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - l /= 2; - p = malloc(l); - if (p == NULL) + switch (f->hmf_type) { + default: return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - if (hex2bin(p, l, f->hmf_str)) { + case HMF_STR: + l = strlen(f->hmf_str); + if (l % 2) + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + l /= 2; + p = malloc(l); + if (p == NULL) + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + if (hex2bin(p, l, f->hmf_str)) { + free(p); + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + } + r = htsmsg_field_set_bin_force(f, p, l); free(p); - return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - } - r = htsmsg_field_set_bin_force(f, p, l); - free(p); - if (r) - return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - break; - case HMF_BIN: - break; + if (r) + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + break; + case HMF_BIN: + break; } *binp = f->hmf_bin; *lenp = f->hmf_binsize; @@ -996,13 +863,10 @@ htsmsg_field_get_bin(htsmsg_field_t *f, const void **binp, size_t *lenp) /* * */ -int -htsmsg_get_bin - (htsmsg_t *msg, const char *name, const void **binp, size_t *lenp) -{ - htsmsg_field_t *f; +int htsmsg_get_bin(htsmsg_t* msg, const char* name, const void** binp, size_t* lenp) { + htsmsg_field_t* f; - if((f = htsmsg_field_find(msg, name)) == NULL) + if ((f = htsmsg_field_find(msg, name)) == NULL) return HTSMSG_ERR_FIELD_NOT_FOUND; return htsmsg_field_get_bin(f, binp, lenp); @@ -1011,29 +875,27 @@ htsmsg_get_bin /** * */ -int -htsmsg_field_get_uuid(htsmsg_field_t *f, tvh_uuid_t *u) -{ - const void *p; - size_t l; - int r; - - switch(f->hmf_type) { - case HMF_UUID: - memcpy(&u->bin, f->hmf_uuid, UUID_BIN_SIZE); - break; - case HMF_BIN: - case HMF_STR: - r = htsmsg_field_get_bin(f, &p, &l); - if (r == 0) { - if (l != UUID_BIN_SIZE) - return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; - memcpy(u->bin, p, UUID_BIN_SIZE); - return 0; - } - /* Fall through */ - default: - return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; +int htsmsg_field_get_uuid(htsmsg_field_t* f, tvh_uuid_t* u) { + const void* p; + size_t l; + int r; + + switch (f->hmf_type) { + case HMF_UUID: + memcpy(&u->bin, f->hmf_uuid, UUID_BIN_SIZE); + break; + case HMF_BIN: + case HMF_STR: + r = htsmsg_field_get_bin(f, &p, &l); + if (r == 0) { + if (l != UUID_BIN_SIZE) + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; + memcpy(u->bin, p, UUID_BIN_SIZE); + return 0; + } + /* Fall through */ + default: + return HTSMSG_ERR_CONVERSION_IMPOSSIBLE; } return 0; } @@ -1041,13 +903,10 @@ htsmsg_field_get_uuid(htsmsg_field_t *f, tvh_uuid_t *u) /* * */ -int -htsmsg_get_uuid - (htsmsg_t *msg, const char *name, tvh_uuid_t *u) -{ - htsmsg_field_t *f; +int htsmsg_get_uuid(htsmsg_t* msg, const char* name, tvh_uuid_t* u) { + htsmsg_field_t* f; - if((f = htsmsg_field_find(msg, name)) == NULL) + if ((f = htsmsg_field_find(msg, name)) == NULL) return HTSMSG_ERR_FIELD_NOT_FOUND; return htsmsg_field_get_uuid(f, u); @@ -1056,34 +915,28 @@ htsmsg_get_uuid /* * */ -htsmsg_t * -htsmsg_get_map(htsmsg_t *msg, const char *name) -{ - htsmsg_field_t *f; +htsmsg_t* htsmsg_get_map(htsmsg_t* msg, const char* name) { + htsmsg_field_t* f; - if((f = htsmsg_field_find(msg, name)) == NULL) + if ((f = htsmsg_field_find(msg, name)) == NULL) return NULL; return htsmsg_field_get_map(f); } -htsmsg_t * -htsmsg_field_get_map(htsmsg_field_t *f) -{ +htsmsg_t* htsmsg_field_get_map(htsmsg_field_t* f) { return htsmsg_field_get_msg(f, 0); } /** * */ -htsmsg_t * -htsmsg_get_map_multi(htsmsg_t *msg, ...) -{ - va_list ap; - const char *n; +htsmsg_t* htsmsg_get_map_multi(htsmsg_t* msg, ...) { + va_list ap; + const char* n; va_start(ap, msg); - while(msg != NULL && (n = va_arg(ap, char *)) != NULL) + while (msg != NULL && (n = va_arg(ap, char*)) != NULL) msg = htsmsg_get_map(msg, n); va_end(ap); @@ -1093,21 +946,19 @@ htsmsg_get_map_multi(htsmsg_t *msg, ...) /** * */ -const char * -htsmsg_get_str_multi(htsmsg_t *msg, ...) -{ - va_list ap; - const char *n, *r = NULL; - htsmsg_field_t *f; +const char* htsmsg_get_str_multi(htsmsg_t* msg, ...) { + va_list ap; + const char * n, *r = NULL; + htsmsg_field_t* f; va_start(ap, msg); - while((n = va_arg(ap, char *)) != NULL) { - if((f = htsmsg_field_find(msg, n)) == NULL) + while ((n = va_arg(ap, char*)) != NULL) { + if ((f = htsmsg_field_find(msg, n)) == NULL) break; - else if(f->hmf_type == HMF_STR) { + else if (f->hmf_type == HMF_STR) { r = f->hmf_str; break; - } else if(f->hmf_type == HMF_MAP) + } else if (f->hmf_type == HMF_MAP) msg = f->hmf_msg; else break; @@ -1117,31 +968,23 @@ htsmsg_get_str_multi(htsmsg_t *msg, ...) return r; } - - /* * */ -htsmsg_t * -htsmsg_get_list(const htsmsg_t *msg, const char *name) -{ - htsmsg_field_t *f; +htsmsg_t* htsmsg_get_list(const htsmsg_t* msg, const char* name) { + htsmsg_field_t* f; - if((f = htsmsg_field_find(msg, name)) == NULL) + if ((f = htsmsg_field_find(msg, name)) == NULL) return NULL; return htsmsg_field_get_list(f); } -htsmsg_t * -htsmsg_field_get_list ( htsmsg_field_t *f ) -{ +htsmsg_t* htsmsg_field_get_list(htsmsg_field_t* f) { return htsmsg_field_get_msg(f, 1); } -static htsmsg_t * -htsmsg_field_get_msg ( htsmsg_field_t *f, int islist ) -{ +static htsmsg_t* htsmsg_field_get_msg(htsmsg_field_t* f, int islist) { htsmsg_t *m, *l; /* Deserialize JSON (will keep either list or map) */ @@ -1153,11 +996,11 @@ htsmsg_field_get_msg ( htsmsg_field_t *f, int islist ) #endif free((void*)f->hmf_str); } - l = f->hmf_msg = malloc(sizeof(htsmsg_t)); + l = f->hmf_msg = malloc(sizeof(htsmsg_t)); if (l == NULL) return NULL; - f->hmf_type = m->hm_islist ? HMF_LIST : HMF_MAP; - f->hmf_flags |= HMF_ALLOCED; + f->hmf_type = m->hm_islist ? HMF_LIST : HMF_MAP; + f->hmf_flags |= HMF_ALLOCED; l->hm_islist = m->hm_islist; l->hm_data = NULL; l->hm_data_size = 0; @@ -1175,154 +1018,144 @@ htsmsg_field_get_msg ( htsmsg_field_t *f, int islist ) /** * */ -htsmsg_t * -htsmsg_detach_submsg(htsmsg_field_t *f) -{ - htsmsg_t *m = f->hmf_msg; - htsmsg_t *r = htsmsg_create_map(); +htsmsg_t* htsmsg_detach_submsg(htsmsg_field_t* f) { + htsmsg_t* m = f->hmf_msg; + htsmsg_t* r = htsmsg_create_map(); TAILQ_MOVE(&r->hm_fields, &m->hm_fields, hmf_link); r->hm_islist = f->hmf_type == HMF_LIST; return r; } - /* * */ -static void -htsmsg_print0(htsmsg_t *msg, int indent) -{ - htsmsg_field_t *f; - int i; +static void htsmsg_print0(htsmsg_t* msg, int indent) { + htsmsg_field_t* f; + int i; - TAILQ_FOREACH(f, &msg->hm_fields, hmf_link) { + TAILQ_FOREACH (f, &msg->hm_fields, hmf_link) { - for(i = 0; i < indent; i++) printf("\t"); + for (i = 0; i < indent; i++) + printf("\t"); printf("%s (", htsmsg_field_name(f)); - switch(f->hmf_type) { - - case HMF_MAP: - printf("MAP) = {\n"); - htsmsg_print0(f->hmf_msg, indent + 1); - for(i = 0; i < indent; i++) printf("\t"); - printf("}\n"); - break; - - case HMF_LIST: - printf("LIST) = {\n"); - htsmsg_print0(f->hmf_msg, indent + 1); - for(i = 0; i < indent; i++) printf("\t"); - printf("}\n"); - break; - - case HMF_STR: - printf("STR) = \"%s\"\n", f->hmf_str); - break; - - case HMF_BIN: - printf("BIN) = ["); - for(i = 0; i < f->hmf_binsize - 1; i++) - printf("%02x.", ((uint8_t *)f->hmf_bin)[i]); - printf("%02x]\n", ((uint8_t *)f->hmf_bin)[i]); - break; - - case HMF_S64: - printf("S64) = %" PRId64 "\n", f->hmf_s64); - break; - - case HMF_BOOL: - printf("BOOL) = %s\n", f->hmf_bool ? "true" : "false"); - break; - - case HMF_DBL: - printf("DBL) = %f\n", f->hmf_dbl); - break; + switch (f->hmf_type) { + + case HMF_MAP: + printf("MAP) = {\n"); + htsmsg_print0(f->hmf_msg, indent + 1); + for (i = 0; i < indent; i++) + printf("\t"); + printf("}\n"); + break; + + case HMF_LIST: + printf("LIST) = {\n"); + htsmsg_print0(f->hmf_msg, indent + 1); + for (i = 0; i < indent; i++) + printf("\t"); + printf("}\n"); + break; + + case HMF_STR: + printf("STR) = \"%s\"\n", f->hmf_str); + break; + + case HMF_BIN: + printf("BIN) = ["); + for (i = 0; i < f->hmf_binsize - 1; i++) + printf("%02x.", ((uint8_t*)f->hmf_bin)[i]); + printf("%02x]\n", ((uint8_t*)f->hmf_bin)[i]); + break; + + case HMF_S64: + printf("S64) = %" PRId64 "\n", f->hmf_s64); + break; + + case HMF_BOOL: + printf("BOOL) = %s\n", f->hmf_bool ? "true" : "false"); + break; + + case HMF_DBL: + printf("DBL) = %f\n", f->hmf_dbl); + break; } } -} +} /* * */ -void -htsmsg_print(htsmsg_t *msg) -{ +void htsmsg_print(htsmsg_t* msg) { htsmsg_print0(msg, 0); -} +} /** * */ -static void htsmsg_copy_i(htsmsg_t *dst, const htsmsg_t *src); +static void htsmsg_copy_i(htsmsg_t* dst, const htsmsg_t* src); -static void -htsmsg_copy_f(htsmsg_t *dst, const htsmsg_field_t *f, const char *name) -{ - htsmsg_t *sub; +static void htsmsg_copy_f(htsmsg_t* dst, const htsmsg_field_t* f, const char* name) { + htsmsg_t* sub; - switch(f->hmf_type) { + switch (f->hmf_type) { - case HMF_MAP: - case HMF_LIST: - sub = f->hmf_type == HMF_LIST ? - htsmsg_create_list() : htsmsg_create_map(); - htsmsg_copy_i(sub, f->hmf_msg); - htsmsg_add_msg(dst, name, sub); - break; + case HMF_MAP: + case HMF_LIST: + sub = f->hmf_type == HMF_LIST ? htsmsg_create_list() : htsmsg_create_map(); + htsmsg_copy_i(sub, f->hmf_msg); + htsmsg_add_msg(dst, name, sub); + break; - case HMF_STR: - htsmsg_add_str(dst, name, f->hmf_str); - break; + case HMF_STR: + htsmsg_add_str(dst, name, f->hmf_str); + break; - case HMF_S64: - htsmsg_add_s64(dst, name, f->hmf_s64); - break; + case HMF_S64: + htsmsg_add_s64(dst, name, f->hmf_s64); + break; - case HMF_BOOL: - htsmsg_add_bool(dst, name, f->hmf_bool); - break; + case HMF_BOOL: + htsmsg_add_bool(dst, name, f->hmf_bool); + break; - case HMF_UUID: - htsmsg_add_uuid(dst, name, (tvh_uuid_t *)f->hmf_uuid); - break; + case HMF_UUID: + htsmsg_add_uuid(dst, name, (tvh_uuid_t*)f->hmf_uuid); + break; - case HMF_BIN: - htsmsg_add_bin(dst, name, f->hmf_bin, f->hmf_binsize); - break; + case HMF_BIN: + htsmsg_add_bin(dst, name, f->hmf_bin, f->hmf_binsize); + break; - case HMF_DBL: - htsmsg_add_dbl(dst, name, f->hmf_dbl); - break; + case HMF_DBL: + htsmsg_add_dbl(dst, name, f->hmf_dbl); + break; } } -static void -htsmsg_copy_i(htsmsg_t *dst, const htsmsg_t *src) -{ - htsmsg_field_t *f; +static void htsmsg_copy_i(htsmsg_t* dst, const htsmsg_t* src) { + htsmsg_field_t* f; - TAILQ_FOREACH(f, &src->hm_fields, hmf_link) + TAILQ_FOREACH (f, &src->hm_fields, hmf_link) htsmsg_copy_f(dst, f, htsmsg_field_name(f)); } -htsmsg_t * -htsmsg_copy(const htsmsg_t *src) -{ - htsmsg_t *dst; - if (src == NULL) return NULL; +htsmsg_t* htsmsg_copy(const htsmsg_t* src) { + htsmsg_t* dst; + if (src == NULL) + return NULL; dst = src->hm_islist ? htsmsg_create_list() : htsmsg_create_map(); htsmsg_copy_i(dst, src); return dst; } -void -htsmsg_copy_field(htsmsg_t *dst, const char *dstname, - const htsmsg_t *src, const char *srcname) -{ - htsmsg_field_t *f; +void htsmsg_copy_field(htsmsg_t* dst, + const char* dstname, + const htsmsg_t* src, + const char* srcname) { + htsmsg_field_t* f; f = htsmsg_field_find(src, srcname ?: dstname); if (f == NULL) return; @@ -1332,9 +1165,7 @@ htsmsg_copy_field(htsmsg_t *dst, const char *dstname, /** * */ -int -htsmsg_cmp(const htsmsg_t *m1, const htsmsg_t *m2) -{ +int htsmsg_cmp(const htsmsg_t* m1, const htsmsg_t* m2) { htsmsg_field_t *f1, *f2; if (m1 == NULL && m2 == NULL) @@ -1343,7 +1174,7 @@ htsmsg_cmp(const htsmsg_t *m1, const htsmsg_t *m2) return 1; f2 = TAILQ_FIRST(&m2->hm_fields); - TAILQ_FOREACH(f1, &m1->hm_fields, hmf_link) { + TAILQ_FOREACH (f1, &m1->hm_fields, hmf_link) { if (f2 == NULL) return 1; @@ -1353,40 +1184,40 @@ htsmsg_cmp(const htsmsg_t *m1, const htsmsg_t *m2) if (strcmp(htsmsg_field_name(f1), htsmsg_field_name(f2))) return 1; - switch(f1->hmf_type) { - - case HMF_MAP: - case HMF_LIST: - if (htsmsg_cmp(f1->hmf_msg, f2->hmf_msg)) - return 1; - break; - - case HMF_STR: - if (strcmp(f1->hmf_str, f2->hmf_str)) - return 1; - break; - - case HMF_S64: - if (f1->hmf_s64 != f2->hmf_s64) - return 1; - break; - - case HMF_BOOL: - if (f1->hmf_bool != f2->hmf_bool) - return 1; - break; - - case HMF_BIN: - if (f1->hmf_binsize != f2->hmf_binsize) - return 1; - if (memcmp(f1->hmf_bin, f2->hmf_bin, f1->hmf_binsize)) - return 1; - break; - - case HMF_DBL: - if (f1->hmf_dbl != f2->hmf_dbl) - return 1; - break; + switch (f1->hmf_type) { + + case HMF_MAP: + case HMF_LIST: + if (htsmsg_cmp(f1->hmf_msg, f2->hmf_msg)) + return 1; + break; + + case HMF_STR: + if (strcmp(f1->hmf_str, f2->hmf_str)) + return 1; + break; + + case HMF_S64: + if (f1->hmf_s64 != f2->hmf_s64) + return 1; + break; + + case HMF_BOOL: + if (f1->hmf_bool != f2->hmf_bool) + return 1; + break; + + case HMF_BIN: + if (f1->hmf_binsize != f2->hmf_binsize) + return 1; + if (memcmp(f1->hmf_bin, f2->hmf_bin, f1->hmf_binsize)) + return 1; + break; + + case HMF_DBL: + if (f1->hmf_dbl != f2->hmf_dbl) + return 1; + break; } f2 = TAILQ_NEXT(f2, hmf_link); @@ -1400,39 +1231,31 @@ htsmsg_cmp(const htsmsg_t *m1, const htsmsg_t *m2) /** * */ -htsmsg_t * -htsmsg_get_map_in_list(htsmsg_t *m, int num) -{ - htsmsg_field_t *f; +htsmsg_t* htsmsg_get_map_in_list(htsmsg_t* m, int num) { + htsmsg_field_t* f; HTSMSG_FOREACH(f, m) { - if(!--num) + if (!--num) return htsmsg_get_map_by_field(f); } return NULL; } - /** * */ -htsmsg_t * -htsmsg_get_map_by_field_if_name(htsmsg_field_t *f, const char *name) -{ - if(f->hmf_type != HMF_MAP) +htsmsg_t* htsmsg_get_map_by_field_if_name(htsmsg_field_t* f, const char* name) { + if (f->hmf_type != HMF_MAP) return NULL; - if(strcmp(htsmsg_field_name(f), name)) + if (strcmp(htsmsg_field_name(f), name)) return NULL; return f->hmf_msg; } - /** * */ -const char * -htsmsg_get_cdata(htsmsg_t *m, const char *field) -{ +const char* htsmsg_get_cdata(htsmsg_t* m, const char* field) { return htsmsg_get_str_multi(m, field, "cdata", NULL); } @@ -1441,23 +1264,22 @@ htsmsg_get_cdata(htsmsg_t *m, const char *field) * * Note: this will NOT work for lists of complex types */ -char * -htsmsg_list_2_csv(htsmsg_t *m, char delim, int human) -{ - int alloc, used, first = 1; - char *ret; - htsmsg_field_t *f; - char sep[3]; - const char *ssep; - if (!m->hm_islist) return NULL; - -#define REALLOC(l)\ - if ((alloc - used) < l) {\ - alloc = MAX((l)*2, alloc*2);\ - ret = realloc(ret, alloc);\ - }\ - - ret = malloc(alloc = 512); +char* htsmsg_list_2_csv(htsmsg_t* m, char delim, int human) { + int alloc, used, first = 1; + char* ret; + htsmsg_field_t* f; + char sep[3]; + const char* ssep; + if (!m->hm_islist) + return NULL; + +#define REALLOC(l) \ + if ((alloc - used) < l) { \ + alloc = MAX((l) * 2, alloc * 2); \ + ret = realloc(ret, alloc); \ + } + + ret = malloc(alloc = 512); if (ret == NULL) return NULL; *ret = 0; @@ -1474,18 +1296,18 @@ htsmsg_list_2_csv(htsmsg_t *m, char delim, int human) } else { sep[0] = delim; sep[1] = '\0'; - ssep = "\""; + ssep = "\""; } HTSMSG_FOREACH(f, m) { if (f->hmf_type == HMF_STR) { REALLOC(4 + strlen(f->hmf_str)); - used += sprintf(ret+used, "%s%s%s%s", !first ? sep : "", ssep, f->hmf_str, ssep); + used += sprintf(ret + used, "%s%s%s%s", !first ? sep : "", ssep, f->hmf_str, ssep); } else if (f->hmf_type == HMF_S64) { REALLOC(34); // max length is actually 20 chars + 2 - used += sprintf(ret+used, "%s%"PRId64, !first ? sep : "", f->hmf_s64); + used += sprintf(ret + used, "%s%" PRId64, !first ? sep : "", f->hmf_s64); } else if (f->hmf_type == HMF_BOOL) { REALLOC(12); // max length is actually 10 chars + 2 - used += sprintf(ret+used, "%s%d", !first ? sep : "", f->hmf_bool); + used += sprintf(ret + used, "%s%d", !first ? sep : "", f->hmf_bool); } else { // TODO: handle doubles free(ret); @@ -1497,16 +1319,14 @@ htsmsg_list_2_csv(htsmsg_t *m, char delim, int human) return ret; } -htsmsg_t * -htsmsg_csv_2_list(const char *str, char delim) -{ - char *tokbuf, *tok, *saveptr = NULL, *p; - const char d[2] = { delim, '\0' }; - htsmsg_t *m = htsmsg_create_list(); +htsmsg_t* htsmsg_csv_2_list(const char* str, char delim) { + char * tokbuf, *tok, *saveptr = NULL, *p; + const char d[2] = {delim, '\0'}; + htsmsg_t* m = htsmsg_create_list(); if (str) { tokbuf = strdup(str); - tok = strtok_r(tokbuf, d, &saveptr); + tok = strtok_r(tokbuf, d, &saveptr); while (tok) { if (tok[0] == '"') { p = ++tok; @@ -1535,10 +1355,8 @@ htsmsg_csv_2_list(const char *str, char delim) /* * */ -htsmsg_t * -htsmsg_create_key_val(const char *key, const char *val) -{ - htsmsg_t *r = htsmsg_create_map(); +htsmsg_t* htsmsg_create_key_val(const char* key, const char* val) { + htsmsg_t* r = htsmsg_create_map(); if (r) { htsmsg_add_str(r, "key", key); htsmsg_add_str(r, "val", val); @@ -1549,11 +1367,9 @@ htsmsg_create_key_val(const char *key, const char *val) /* * */ -int -htsmsg_is_string_in_list(htsmsg_t *list, const char *str) -{ - const char *s; - htsmsg_field_t *f; +int htsmsg_is_string_in_list(htsmsg_t* list, const char* str) { + const char* s; + htsmsg_field_t* f; if (list == NULL || !list->hm_islist) return 0; @@ -1570,11 +1386,9 @@ htsmsg_is_string_in_list(htsmsg_t *list, const char *str) /* * */ -int -htsmsg_remove_string_from_list(htsmsg_t *list, const char *str) -{ - const char *s; - htsmsg_field_t *f; +int htsmsg_remove_string_from_list(htsmsg_t* list, const char* str) { + const char* s; + htsmsg_field_t* f; if (list == NULL || !list->hm_islist) return 0; @@ -1590,24 +1404,21 @@ htsmsg_remove_string_from_list(htsmsg_t *list, const char *str) return 0; } - /* * Based on htsbuf_vqprintf, but can't easily share code since we rely * on stack allocations. -*/ -static void -htsmsg_add_str_ap(htsmsg_t *msg, const char *name, const char *fmt, va_list ap0) -{ + */ +static void htsmsg_add_str_ap(htsmsg_t* msg, const char* name, const char* fmt, va_list ap0) { // First try to format it on-stack va_list ap; - int n; - size_t size; - char buf[100], *p, *np; + int n; + size_t size; + char buf[100], *p, *np; va_copy(ap, ap0); n = vsnprintf(buf, sizeof(buf), fmt, ap); va_end(ap); - if(n > -1 && n < sizeof(buf)) { + if (n > -1 && n < sizeof(buf)) { htsmsg_add_str(msg, name, buf); return; } @@ -1617,22 +1428,22 @@ htsmsg_add_str_ap(htsmsg_t *msg, const char *name, const char *fmt, va_list ap0) p = malloc(size); while (1) { - // Try to print in the allocated space. + // Try to print in the allocated space. va_copy(ap, ap0); n = vsnprintf(p, size, fmt, ap); va_end(ap); - if(n > -1 && n < size) { + if (n > -1 && n < size) { htsmsg_add_str(msg, name, p); // Copy taken by htsmsg_add_str. - free (p); + free(p); return; } - // Else try again with more space. - if (n > -1) // glibc 2.1 - size = n+1; // precisely what is needed - else // glibc 2.0 - size *= 2; // twice the old size - if ((np = realloc (p, size)) == NULL) { + // Else try again with more space. + if (n > -1) // glibc 2.1 + size = n + 1; // precisely what is needed + else // glibc 2.0 + size *= 2; // twice the old size + if ((np = realloc(p, size)) == NULL) { free(p); abort(); } else { @@ -1641,9 +1452,7 @@ htsmsg_add_str_ap(htsmsg_t *msg, const char *name, const char *fmt, va_list ap0) } } -void -htsmsg_add_str_printf(htsmsg_t *msg, const char *name, const char *fmt, ...) -{ +void htsmsg_add_str_printf(htsmsg_t* msg, const char* name, const char* fmt, ...) { va_list ap; va_start(ap, fmt); htsmsg_add_str_ap(msg, name, fmt, ap); diff --git a/src/htsmsg.h b/src/htsmsg.h index 82787d4cc..9689391cb 100644 --- a/src/htsmsg.h +++ b/src/htsmsg.h @@ -30,7 +30,7 @@ TAILQ_HEAD(htsmsg_field_queue, htsmsg_field); typedef struct htsmsg { /** - * fields + * fields */ struct htsmsg_field_queue hm_fields; @@ -42,11 +42,10 @@ typedef struct htsmsg { /** * Data to be free'd when the message is destroyed */ - const void *hm_data; - size_t hm_data_size; + const void* hm_data; + size_t hm_data_size; } htsmsg_t; - #define HMF_MAP 1 #define HMF_S64 2 #define HMF_STR 3 @@ -61,21 +60,21 @@ typedef struct htsmsg_field { uint8_t hmf_type; uint8_t hmf_flags; -#define HMF_ALLOCED 0x1 -#define HMF_INALLOCED 0x2 -#define HMF_NONAME 0x4 +#define HMF_ALLOCED 0x1 +#define HMF_INALLOCED 0x2 +#define HMF_NONAME 0x4 union { - int64_t s64; - const char *str; - const uint8_t *uuid; + int64_t s64; + const char* str; + const uint8_t* uuid; struct { - const char *data; - size_t len; + const char* data; + size_t len; } bin; - htsmsg_t *msg; - double dbl; - int boolean; + htsmsg_t* msg; + double dbl; + int boolean; } u; #if ENABLE_SLOW_MEMORYINFO @@ -94,18 +93,17 @@ typedef struct htsmsg_field { #define hmf_bool u.boolean // backwards compat -#define htsmsg_get_map_by_field(f) htsmsg_field_get_map(f) +#define htsmsg_get_map_by_field(f) htsmsg_field_get_map(f) #define htsmsg_get_list_by_field(f) htsmsg_field_get_list(f) -#define HTSMSG_FOREACH(f, msg) TAILQ_FOREACH(f, &(msg)->hm_fields, hmf_link) +#define HTSMSG_FOREACH(f, msg) TAILQ_FOREACH (f, &(msg)->hm_fields, hmf_link) #define HTSMSG_FIRST(msg) TAILQ_FIRST(&(msg)->hm_fields) #define HTSMSG_NEXT(f) TAILQ_NEXT(f, hmf_link) /** * Aligned memory allocation */ -static inline size_t htsmsg_malloc_align(int type, size_t len) -{ +static inline size_t htsmsg_malloc_align(int type, size_t len) { if (type == HMF_LIST || type == HMF_MAP) return (len + (size_t)7) & ~(size_t)7; return len; @@ -114,138 +112,138 @@ static inline size_t htsmsg_malloc_align(int type, size_t len) /** * Get a field name */ -static inline const char *htsmsg_field_name(htsmsg_field_t *f) -{ - if (f->hmf_flags & HMF_NONAME) return ""; +static inline const char* htsmsg_field_name(htsmsg_field_t* f) { + if (f->hmf_flags & HMF_NONAME) + return ""; return f->_hmf_name; } /** * Create a new map */ -htsmsg_t *htsmsg_create_map(void); +htsmsg_t* htsmsg_create_map(void); /** * Create a new list */ -htsmsg_t *htsmsg_create_list(void); +htsmsg_t* htsmsg_create_list(void); /** * Concat msg2 to msg1 (list or map) */ -void htsmsg_concat(htsmsg_t *msg1, htsmsg_t *msg2); +void htsmsg_concat(htsmsg_t* msg1, htsmsg_t* msg2); /** * Remove a given field from a msg */ -void htsmsg_field_destroy(htsmsg_t *msg, htsmsg_field_t *f); +void htsmsg_field_destroy(htsmsg_t* msg, htsmsg_field_t* f); /** * Destroys a message (map or list) */ -void htsmsg_destroy(htsmsg_t *msg); +void htsmsg_destroy(htsmsg_t* msg); /** * Add an boolean field. */ -void htsmsg_add_bool(htsmsg_t *msg, const char *name, int b); +void htsmsg_add_bool(htsmsg_t* msg, const char* name, int b); /** * Add/update an boolean field. */ -void htsmsg_set_bool(htsmsg_t *msg, const char *name, int b); +void htsmsg_set_bool(htsmsg_t* msg, const char* name, int b); /** * Add an integer field where source is signed 64 bit. */ -void htsmsg_add_s64(htsmsg_t *msg, const char *name, int64_t s64); +void htsmsg_add_s64(htsmsg_t* msg, const char* name, int64_t s64); /** * Add/update an integer field where source is signed 64 bit. */ -int htsmsg_set_s64(htsmsg_t *msg, const char *name, int64_t s64); +int htsmsg_set_s64(htsmsg_t* msg, const char* name, int64_t s64); /** * Add an integer field where source is unsigned 32 bit. */ -static inline void -htsmsg_add_u32(htsmsg_t *msg, const char *name, uint32_t u32) - { htsmsg_add_s64(msg, name, u32); } +static inline void htsmsg_add_u32(htsmsg_t* msg, const char* name, uint32_t u32) { + htsmsg_add_s64(msg, name, u32); +} /** * Add/update an integer field */ -static inline int -htsmsg_set_u32(htsmsg_t *msg, const char *name, uint32_t u32) - { return htsmsg_set_s64(msg, name, u32); } +static inline int htsmsg_set_u32(htsmsg_t* msg, const char* name, uint32_t u32) { + return htsmsg_set_s64(msg, name, u32); +} /** * Add an integer field where source is signed 32 bit. */ -static inline void -htsmsg_add_s32(htsmsg_t *msg, const char *name, int32_t s32) - { htsmsg_add_s64(msg, name, s32); } +static inline void htsmsg_add_s32(htsmsg_t* msg, const char* name, int32_t s32) { + htsmsg_add_s64(msg, name, s32); +} /** * Add/update an integer field */ -static inline int -htsmsg_set_s32(htsmsg_t *msg, const char *name, int32_t s32) - { return htsmsg_set_s64(msg, name, s32); } +static inline int htsmsg_set_s32(htsmsg_t* msg, const char* name, int32_t s32) { + return htsmsg_set_s64(msg, name, s32); +} /** * Add a string field. */ -void htsmsg_add_str(htsmsg_t *msg, const char *name, const char *str); +void htsmsg_add_str(htsmsg_t* msg, const char* name, const char* str); /** * Add a string field (NULL check). */ -void htsmsg_add_str2(htsmsg_t *msg, const char *name, const char *str); +void htsmsg_add_str2(htsmsg_t* msg, const char* name, const char* str); /** * Add a string field (allocated using malloc). */ -void htsmsg_add_str_alloc(htsmsg_t *msg, const char *name, char *str); +void htsmsg_add_str_alloc(htsmsg_t* msg, const char* name, char* str); /** * Add a string field to a list only once. */ -void htsmsg_add_str_exclusive(htsmsg_t *msg, const char *str); +void htsmsg_add_str_exclusive(htsmsg_t* msg, const char* str); /** * Add a string using printf-style for the value. */ -void -htsmsg_add_str_printf(htsmsg_t *msg, const char *name, const char *fmt, ...) - __attribute__((format(printf,3,4)));; +void htsmsg_add_str_printf(htsmsg_t* msg, const char* name, const char* fmt, ...) + __attribute__((format(printf, 3, 4))); +; /** * Add/update a string field */ -int htsmsg_set_str(htsmsg_t *msg, const char *name, const char *str); -int htsmsg_set_str2(htsmsg_t *msg, const char *name, const char *str); +int htsmsg_set_str(htsmsg_t* msg, const char* name, const char* str); +int htsmsg_set_str2(htsmsg_t* msg, const char* name, const char* str); /** * Update a string field */ -int htsmsg_field_set_str(htsmsg_field_t *f, const char *str); -int htsmsg_field_set_str_force(htsmsg_field_t *f, const char *str); +int htsmsg_field_set_str(htsmsg_field_t* f, const char* str); +int htsmsg_field_set_str_force(htsmsg_field_t* f, const char* str); /** * Add an field where source is a list or map message. */ -htsmsg_t *htsmsg_add_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub); +htsmsg_t* htsmsg_add_msg(htsmsg_t* msg, const char* name, htsmsg_t* sub); /** * Add/update an field where source is a list or map message. */ -htsmsg_t *htsmsg_set_msg(htsmsg_t *msg, const char *name, htsmsg_t *sub); +htsmsg_t* htsmsg_set_msg(htsmsg_t* msg, const char* name, htsmsg_t* sub); /** * Add an field where source is a double */ -void htsmsg_add_dbl(htsmsg_t *msg, const char *name, double dbl); +void htsmsg_add_dbl(htsmsg_t* msg, const char* name, double dbl); /** * Add an field where source is a list or map message. @@ -253,40 +251,40 @@ void htsmsg_add_dbl(htsmsg_t *msg, const char *name, double dbl); * This function will not strdup() \p name but relies on the caller * to keep the string allocated for as long as the message is valid. */ -void htsmsg_add_msg_extname(htsmsg_t *msg, const char *name, htsmsg_t *sub); +void htsmsg_add_msg_extname(htsmsg_t* msg, const char* name, htsmsg_t* sub); /** * Update an binary field */ -int htsmsg_field_set_bin(htsmsg_field_t *f, const void *bin, size_t len); -int htsmsg_field_set_bin_force(htsmsg_field_t *f, const void *bin, size_t len); +int htsmsg_field_set_bin(htsmsg_field_t* f, const void* bin, size_t len); +int htsmsg_field_set_bin_force(htsmsg_field_t* f, const void* bin, size_t len); /** * Add an binary field. The data is copied to a inallocated storage. */ -void htsmsg_add_bin(htsmsg_t *msg, const char *name, const void *bin, size_t len); +void htsmsg_add_bin(htsmsg_t* msg, const char* name, const void* bin, size_t len); /** * Add an binary field. The passed data must be mallocated. */ -void htsmsg_add_bin_alloc(htsmsg_t *msg, const char *name, const void *bin, size_t len); +void htsmsg_add_bin_alloc(htsmsg_t* msg, const char* name, const void* bin, size_t len); /** * Add an binary field. The data is not copied, instead the caller * is responsible for keeping the data valid for as long as the message * is around. */ -void htsmsg_add_bin_ptr(htsmsg_t *msg, const char *name, const void *bin, size_t len); +void htsmsg_add_bin_ptr(htsmsg_t* msg, const char* name, const void* bin, size_t len); /** * Add/update a uuid field */ -int htsmsg_set_uuid(htsmsg_t *msg, const char *name, tvh_uuid_t *u); +int htsmsg_set_uuid(htsmsg_t* msg, const char* name, tvh_uuid_t* u); /** * Add an uuid field. */ -void htsmsg_add_uuid(htsmsg_t *msg, const char *name, tvh_uuid_t *u); +void htsmsg_add_uuid(htsmsg_t* msg, const char* name, tvh_uuid_t* u); /** * Get an integer as an unsigned 32 bit integer. @@ -295,9 +293,9 @@ void htsmsg_add_uuid(htsmsg_t *msg, const char *name, tvh_uuid_t *u); * HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or * out of range for the requested storage. */ -int htsmsg_get_u32(htsmsg_t *msg, const char *name, uint32_t *u32p); +int htsmsg_get_u32(htsmsg_t* msg, const char* name, uint32_t* u32p); -int htsmsg_field_get_u32(htsmsg_field_t *f, uint32_t *u32p); +int htsmsg_field_get_u32(htsmsg_field_t* f, uint32_t* u32p); /** * Get an integer as an signed 32 bit integer. @@ -306,9 +304,9 @@ int htsmsg_field_get_u32(htsmsg_field_t *f, uint32_t *u32p); * HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or * out of range for the requested storage. */ -int htsmsg_get_s32(htsmsg_t *msg, const char *name, int32_t *s32p); +int htsmsg_get_s32(htsmsg_t* msg, const char* name, int32_t* s32p); -int htsmsg_field_get_s32(htsmsg_field_t *f, int32_t *s32p); +int htsmsg_field_get_s32(htsmsg_field_t* f, int32_t* s32p); /** * Get an integer as an signed 64 bit integer. @@ -317,23 +315,22 @@ int htsmsg_field_get_s32(htsmsg_field_t *f, int32_t *s32p); * HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or * out of range for the requested storage. */ -int htsmsg_get_s64(htsmsg_t *msg, const char *name, int64_t *s64p); +int htsmsg_get_s64(htsmsg_t* msg, const char* name, int64_t* s64p); -int htsmsg_field_get_s64(htsmsg_field_t *f, int64_t *s64p); +int htsmsg_field_get_s64(htsmsg_field_t* f, int64_t* s64p); /* * Return the field \p name as an s64. */ -int64_t htsmsg_get_s64_or_default(htsmsg_t *msg, const char *name, int64_t def); - -int bool_check(const char *str); +int64_t htsmsg_get_s64_or_default(htsmsg_t* msg, const char* name, int64_t def); -int htsmsg_field_get_bool(htsmsg_field_t *f, int *boolp); +int bool_check(const char* str); -int htsmsg_get_bool(htsmsg_t *msg, const char *name, int *boolp); +int htsmsg_field_get_bool(htsmsg_field_t* f, int* boolp); -int htsmsg_get_bool_or_default(htsmsg_t *msg, const char *name, int def); +int htsmsg_get_bool(htsmsg_t* msg, const char* name, int* boolp); +int htsmsg_get_bool_or_default(htsmsg_t* msg, const char* name, int def); /** * Get pointer to a binary field. No copying of data is performed. @@ -346,8 +343,7 @@ int htsmsg_get_bool_or_default(htsmsg_t *msg, const char *name, int def); * @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist * HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not a binary blob. */ -int htsmsg_get_bin(htsmsg_t *msg, const char *name, const void **binp, - size_t *lenp); +int htsmsg_get_bin(htsmsg_t* msg, const char* name, const void** binp, size_t* lenp); /** * Get uuid struct from a uuid field. @@ -357,7 +353,7 @@ int htsmsg_get_bin(htsmsg_t *msg, const char *name, const void **binp, * @return HTSMSG_ERR_FIELD_NOT_FOUND - Field does not exist * HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not a binary blob. */ -int htsmsg_get_uuid(htsmsg_t *msg, const char *name, tvh_uuid_t *u); +int htsmsg_get_uuid(htsmsg_t* msg, const char* name, tvh_uuid_t* u); /** * Get a field of type 'list'. No copying is done. @@ -365,9 +361,9 @@ int htsmsg_get_uuid(htsmsg_t *msg, const char *name, tvh_uuid_t *u); * @return NULL if the field can not be found or not of list type. * Otherwise a htsmsg is returned. */ -htsmsg_t *htsmsg_get_list(const htsmsg_t *msg, const char *name); +htsmsg_t* htsmsg_get_list(const htsmsg_t* msg, const char* name); -htsmsg_t *htsmsg_field_get_list(htsmsg_field_t *f); +htsmsg_t* htsmsg_field_get_list(htsmsg_field_t* f); /** * Get a field of type 'string'. No copying is done. @@ -375,7 +371,7 @@ htsmsg_t *htsmsg_field_get_list(htsmsg_field_t *f); * @return NULL if the field can not be found or not of string type. * Otherwise a pointer to the data is returned. */ -const char *htsmsg_get_str(htsmsg_t *msg, const char *name); +const char* htsmsg_get_str(htsmsg_t* msg, const char* name); /** * Get a field of type 'map'. No copying is done. @@ -383,21 +379,19 @@ const char *htsmsg_get_str(htsmsg_t *msg, const char *name); * @return NULL if the field can not be found or not of map type. * Otherwise a htsmsg is returned. */ -htsmsg_t *htsmsg_get_map(htsmsg_t *msg, const char *name); +htsmsg_t* htsmsg_get_map(htsmsg_t* msg, const char* name); -htsmsg_t *htsmsg_field_get_map(htsmsg_field_t *f); +htsmsg_t* htsmsg_field_get_map(htsmsg_field_t* f); /** * Traverse a hierarchy of htsmsg's to find a specific child. */ -htsmsg_t *htsmsg_get_map_multi(htsmsg_t *msg, ...) - __attribute__((__sentinel__(0))); +htsmsg_t* htsmsg_get_map_multi(htsmsg_t* msg, ...) __attribute__((__sentinel__(0))); /** * Traverse a hierarchy of htsmsg's to find a specific child. */ -const char *htsmsg_get_str_multi(htsmsg_t *msg, ...) - __attribute__((__sentinel__(0))); +const char* htsmsg_get_str_multi(htsmsg_t* msg, ...) __attribute__((__sentinel__(0))); /** * Get a field of type 'double'. @@ -406,22 +400,22 @@ const char *htsmsg_get_str_multi(htsmsg_t *msg, ...) * HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or * out of range for the requested storage. */ -int htsmsg_get_dbl(htsmsg_t *msg, const char *name, double *dblp); +int htsmsg_get_dbl(htsmsg_t* msg, const char* name, double* dblp); -int htsmsg_field_get_dbl(htsmsg_field_t *f, double *dblp); +int htsmsg_field_get_dbl(htsmsg_field_t* f, double* dblp); /** * Given the field \p f, return a string if it is of type string, otherwise * return NULL */ -const char *htsmsg_field_get_string(htsmsg_field_t *f); +const char* htsmsg_field_get_string(htsmsg_field_t* f); #define htsmsg_field_get_str(f) htsmsg_field_get_string(f) /** * Given the field \p f, return a uuid if it is of type string, otherwise * return NULL */ -int htsmsg_field_get_uuid(htsmsg_field_t *f, tvh_uuid_t *u); +int htsmsg_field_get_uuid(htsmsg_field_t* f, tvh_uuid_t* u); /** * Get a field of type 'bin'. @@ -430,7 +424,7 @@ int htsmsg_field_get_uuid(htsmsg_field_t *f, tvh_uuid_t *u); * HTSMSG_ERR_CONVERSION_IMPOSSIBLE - Field is not an integer or * out of range for the requested storage. */ -int htsmsg_field_get_bin(htsmsg_field_t *f, const void **binp, size_t *lenp); +int htsmsg_field_get_bin(htsmsg_field_t* f, const void** binp, size_t* lenp); /** * Return the field \p name as an u32. @@ -438,7 +432,7 @@ int htsmsg_field_get_bin(htsmsg_field_t *f, const void **binp, size_t *lenp); * @return An unsigned 32 bit integer or NULL if the field can not be found * or if conversion is not possible. */ -int htsmsg_get_u32_or_default(htsmsg_t *msg, const char *name, uint32_t def); +int htsmsg_get_u32_or_default(htsmsg_t* msg, const char* name, uint32_t def); /** * Return the field \p name as an s32. @@ -446,18 +440,17 @@ int htsmsg_get_u32_or_default(htsmsg_t *msg, const char *name, uint32_t def); * @return A signed 32 bit integer or NULL if the field can not be found * or if conversion is not possible. */ -int32_t htsmsg_get_s32_or_default(htsmsg_t *msg, const char *name, - int32_t def); +int32_t htsmsg_get_s32_or_default(htsmsg_t* msg, const char* name, int32_t def); /** * Remove the given field called \p name from the message \p msg. */ -int htsmsg_delete_field(htsmsg_t *msg, const char *name); +int htsmsg_delete_field(htsmsg_t* msg, const char* name); /** * Is list/map empty */ -int htsmsg_is_empty(htsmsg_t *msg); +int htsmsg_is_empty(htsmsg_t* msg); /** * Detach will remove the given field (and only if it is a list or map) @@ -465,66 +458,67 @@ int htsmsg_is_empty(htsmsg_t *msg); * the the contents of the sub message will stay valid if the parent is * destroyed. The caller is responsible for freeing this new message. */ -htsmsg_t *htsmsg_detach_submsg(htsmsg_field_t *f); +htsmsg_t* htsmsg_detach_submsg(htsmsg_field_t* f); /** - * Print a message to stdout. + * Print a message to stdout. */ -void htsmsg_print(htsmsg_t *msg); +void htsmsg_print(htsmsg_t* msg); /** * Create a new field. Primarily intended for htsmsg internal functions. */ -htsmsg_field_t *htsmsg_field_add(htsmsg_t *msg, const char *name, - int type, int flags, size_t esize); +htsmsg_field_t* +htsmsg_field_add(htsmsg_t* msg, const char* name, int type, int flags, size_t esize); /** * Get a field, return NULL if it does not exist */ -htsmsg_field_t *htsmsg_field_find(const htsmsg_t *msg, const char *name); +htsmsg_field_t* htsmsg_field_find(const htsmsg_t* msg, const char* name); /** * Get a last field, return NULL if it does not exist */ -htsmsg_field_t *htsmsg_field_last(htsmsg_t *msg); +htsmsg_field_t* htsmsg_field_last(htsmsg_t* msg); /** * Clone a message. */ -htsmsg_t *htsmsg_copy(const htsmsg_t *src); +htsmsg_t* htsmsg_copy(const htsmsg_t* src); /** * Copy only one field from one htsmsg to another (with renaming). */ -void htsmsg_copy_field(htsmsg_t *dst, const char *dstname, - const htsmsg_t *src, const char *srcname); +void htsmsg_copy_field(htsmsg_t* dst, + const char* dstname, + const htsmsg_t* src, + const char* srcname); /** * Compare a message. */ -int htsmsg_cmp(const htsmsg_t *m1, const htsmsg_t *m2); - -#define HTSMSG_FOREACH(f, msg) TAILQ_FOREACH(f, &(msg)->hm_fields, hmf_link) +int htsmsg_cmp(const htsmsg_t* m1, const htsmsg_t* m2); +#define HTSMSG_FOREACH(f, msg) TAILQ_FOREACH (f, &(msg)->hm_fields, hmf_link) /** * Misc */ -htsmsg_t *htsmsg_get_map_in_list(htsmsg_t *m, int num); +htsmsg_t* htsmsg_get_map_in_list(htsmsg_t* m, int num); -htsmsg_t *htsmsg_get_map_by_field_if_name(htsmsg_field_t *f, const char *name); +htsmsg_t* htsmsg_get_map_by_field_if_name(htsmsg_field_t* f, const char* name); -const char *htsmsg_get_cdata(htsmsg_t *m, const char *field); +const char* htsmsg_get_cdata(htsmsg_t* m, const char* field); -char *htsmsg_list_2_csv(htsmsg_t *m, char delim, int human); +char* htsmsg_list_2_csv(htsmsg_t* m, char delim, int human); -htsmsg_t *htsmsg_csv_2_list(const char *str, char delim); +htsmsg_t* htsmsg_csv_2_list(const char* str, char delim); -htsmsg_t *htsmsg_create_key_val(const char *key, const char *val); +htsmsg_t* htsmsg_create_key_val(const char* key, const char* val); -int htsmsg_is_string_in_list(htsmsg_t *list, const char *str); +int htsmsg_is_string_in_list(htsmsg_t* list, const char* str); -int htsmsg_remove_string_from_list(htsmsg_t *list, const char *str); +int htsmsg_remove_string_from_list(htsmsg_t* list, const char* str); /** * diff --git a/src/htsmsg_binary.c b/src/htsmsg_binary.c index 48a1bf985..fced2509c 100644 --- a/src/htsmsg_binary.c +++ b/src/htsmsg_binary.c @@ -29,29 +29,25 @@ /* * */ -static int -htsmsg_binary_des0(htsmsg_t *msg, const uint8_t *buf, size_t len) -{ - uint_fast32_t type, namelen, datalen; - size_t tlen, nlen; - htsmsg_field_t *f; - htsmsg_t *sub; - uint64_t u64; - int i, bin = 0; - - while(len > 5) { - - type = buf[0]; - namelen = buf[1]; - datalen = (((uint_fast32_t)buf[2]) << 24) | - (((uint_fast32_t)buf[3]) << 16) | - (((uint_fast32_t)buf[4]) << 8 ) | - (((uint_fast32_t)buf[5]) ); - +static int htsmsg_binary_des0(htsmsg_t* msg, const uint8_t* buf, size_t len) { + uint_fast32_t type, namelen, datalen; + size_t tlen, nlen; + htsmsg_field_t* f; + htsmsg_t* sub; + uint64_t u64; + int i, bin = 0; + + while (len > 5) { + + type = buf[0]; + namelen = buf[1]; + datalen = (((uint_fast32_t)buf[2]) << 24) | (((uint_fast32_t)buf[3]) << 16) | + (((uint_fast32_t)buf[4]) << 8) | (((uint_fast32_t)buf[5])); + buf += 6; len -= 6; - - if(len < namelen + datalen) + + if (len < namelen + datalen) return -1; nlen = namelen ? htsmsg_malloc_align(type, namelen + 1) : 0; @@ -75,9 +71,9 @@ htsmsg_binary_des0(htsmsg_t *msg, const uint8_t *buf, size_t len) f->hmf_type = type; f->hmf_flags = 0; - if(namelen > 0) { - memcpy((char *)f->_hmf_name, buf, namelen); - ((char *)f->_hmf_name)[namelen] = 0; + if (namelen > 0) { + memcpy((char*)f->_hmf_name, buf, namelen); + ((char*)f->_hmf_name)[namelen] = 0; buf += namelen; len -= namelen; @@ -85,61 +81,61 @@ htsmsg_binary_des0(htsmsg_t *msg, const uint8_t *buf, size_t len) f->hmf_flags = HMF_NONAME; } - switch(type) { - case HMF_STR: - f->hmf_str = f->_hmf_name + nlen; - memcpy((char *)f->hmf_str, buf, datalen); - ((char *)f->hmf_str)[datalen] = 0; - f->hmf_flags |= HMF_INALLOCED; - break; - - case HMF_UUID: - f->hmf_uuid = (uint8_t *)f->_hmf_name + nlen; - memcpy((char *)f->hmf_uuid, buf, UUID_BIN_SIZE); - break; - - case HMF_BIN: - f->hmf_bin = (const void *)buf; - f->hmf_binsize = datalen; - bin = 1; - break; - - case HMF_S64: - u64 = 0; - for(i = datalen - 1; i >= 0; i--) - u64 = (u64 << 8) | buf[i]; - f->hmf_s64 = u64; - break; - - case HMF_MAP: - case HMF_LIST: - sub = f->hmf_msg = (htsmsg_t *)(f->_hmf_name + nlen); - TAILQ_INIT(&sub->hm_fields); - sub->hm_data = NULL; - sub->hm_data_size = 0; - sub->hm_islist = type == HMF_LIST; - i = htsmsg_binary_des0(sub, buf, datalen); - if (i < 0) { + switch (type) { + case HMF_STR: + f->hmf_str = f->_hmf_name + nlen; + memcpy((char*)f->hmf_str, buf, datalen); + ((char*)f->hmf_str)[datalen] = 0; + f->hmf_flags |= HMF_INALLOCED; + break; + + case HMF_UUID: + f->hmf_uuid = (uint8_t*)f->_hmf_name + nlen; + memcpy((char*)f->hmf_uuid, buf, UUID_BIN_SIZE); + break; + + case HMF_BIN: + f->hmf_bin = (const void*)buf; + f->hmf_binsize = datalen; + bin = 1; + break; + + case HMF_S64: + u64 = 0; + for (i = datalen - 1; i >= 0; i--) + u64 = (u64 << 8) | buf[i]; + f->hmf_s64 = u64; + break; + + case HMF_MAP: + case HMF_LIST: + sub = f->hmf_msg = (htsmsg_t*)(f->_hmf_name + nlen); + TAILQ_INIT(&sub->hm_fields); + sub->hm_data = NULL; + sub->hm_data_size = 0; + sub->hm_islist = type == HMF_LIST; + i = htsmsg_binary_des0(sub, buf, datalen); + if (i < 0) { +#if ENABLE_SLOW_MEMORYINFO + memoryinfo_free(&htsmsg_field_memoryinfo, tlen); +#endif + free(f); + return -1; + } + if (i > 0) + bin = 1; + break; + + case HMF_BOOL: + f->hmf_bool = datalen == 1 ? buf[0] : 0; + break; + + default: #if ENABLE_SLOW_MEMORYINFO memoryinfo_free(&htsmsg_field_memoryinfo, tlen); #endif free(f); return -1; - } - if (i > 0) - bin = 1; - break; - - case HMF_BOOL: - f->hmf_bool = datalen == 1 ? buf[0] : 0; - break; - - default: -#if ENABLE_SLOW_MEMORYINFO - memoryinfo_free(&htsmsg_field_memoryinfo, tlen); -#endif - free(f); - return -1; } TAILQ_INSERT_TAIL(&msg->hm_fields, f, hmf_link); @@ -152,27 +148,25 @@ htsmsg_binary_des0(htsmsg_t *msg, const uint8_t *buf, size_t len) /* * */ -htsmsg_t * -htsmsg_binary_deserialize0(const void *data, size_t len, const void *buf) -{ - htsmsg_t *msg; - int r; +htsmsg_t* htsmsg_binary_deserialize0(const void* data, size_t len, const void* buf) { + htsmsg_t* msg; + int r; msg = htsmsg_create_map(); - r = htsmsg_binary_des0(msg, data, len); + r = htsmsg_binary_des0(msg, data, len); if (r < 0) { - free((void *)buf); + free((void*)buf); htsmsg_destroy(msg); return NULL; } if (r > 0) { - msg->hm_data = buf; + msg->hm_data = buf; msg->hm_data_size = len; #if ENABLE_SLOW_MEMORYINFO memoryinfo_append(&htsmsg_memoryinfo, len); #endif } else { - free((void *)buf); + free((void*)buf); } return msg; } @@ -180,24 +174,22 @@ htsmsg_binary_deserialize0(const void *data, size_t len, const void *buf) /* * */ -int -htsmsg_binary_deserialize(htsmsg_t **msg, const void *data, size_t *len, const void *buf) -{ - htsmsg_t *m; - const uint8_t *p; - uint32_t l, len2; +int htsmsg_binary_deserialize(htsmsg_t** msg, const void* data, size_t* len, const void* buf) { + htsmsg_t* m; + const uint8_t* p; + uint32_t l, len2; len2 = *len; *msg = NULL; *len = 0; if (len2 < 4) { - free((void *)buf); + free((void*)buf); return -1; } p = data; l = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; if (l + 4 > len2) { - free((void *)buf); + free((void*)buf); return -1; } m = htsmsg_binary_deserialize0(data + 4, l, buf); @@ -211,47 +203,45 @@ htsmsg_binary_deserialize(htsmsg_t **msg, const void *data, size_t *len, const v /* * */ -static size_t -htsmsg_binary_count(htsmsg_t *msg) -{ - htsmsg_field_t *f; - size_t len = 0; - uint64_t u64; +static size_t htsmsg_binary_count(htsmsg_t* msg) { + htsmsg_field_t* f; + size_t len = 0; + uint64_t u64; - TAILQ_FOREACH(f, &msg->hm_fields, hmf_link) { + TAILQ_FOREACH (f, &msg->hm_fields, hmf_link) { len += 6 + strlen(htsmsg_field_name(f)); - switch(f->hmf_type) { - case HMF_MAP: - case HMF_LIST: - len += htsmsg_binary_count(f->hmf_msg); - break; - - case HMF_STR: - len += strlen(f->hmf_str); - break; - - case HMF_UUID: - len += UUID_BIN_SIZE; - break; - - case HMF_BIN: - len += f->hmf_binsize; - break; - - case HMF_S64: - u64 = f->hmf_s64; - while(u64 != 0) { - len++; - u64 = u64 >> 8; - } - break; - - case HMF_BOOL: - if (f->hmf_bool) len++; - break; - + switch (f->hmf_type) { + case HMF_MAP: + case HMF_LIST: + len += htsmsg_binary_count(f->hmf_msg); + break; + + case HMF_STR: + len += strlen(f->hmf_str); + break; + + case HMF_UUID: + len += UUID_BIN_SIZE; + break; + + case HMF_BIN: + len += f->hmf_binsize; + break; + + case HMF_S64: + u64 = f->hmf_s64; + while (u64 != 0) { + len++; + u64 = u64 >> 8; + } + break; + + case HMF_BOOL: + if (f->hmf_bool) + len++; + break; } } return len; @@ -260,94 +250,91 @@ htsmsg_binary_count(htsmsg_t *msg) /* * */ -static void -htsmsg_binary_write(htsmsg_t *msg, uint8_t *ptr) -{ - htsmsg_field_t *f; - uint64_t u64; - int l, i, namelen; - - TAILQ_FOREACH(f, &msg->hm_fields, hmf_link) { +static void htsmsg_binary_write(htsmsg_t* msg, uint8_t* ptr) { + htsmsg_field_t* f; + uint64_t u64; + int l, i, namelen; + + TAILQ_FOREACH (f, &msg->hm_fields, hmf_link) { namelen = strlen(htsmsg_field_name(f)); - *ptr++ = f->hmf_type; - *ptr++ = namelen; - - switch(f->hmf_type) { - case HMF_MAP: - case HMF_LIST: - l = htsmsg_binary_count(f->hmf_msg); - break; - - case HMF_STR: - l = strlen(f->hmf_str); - break; - - case HMF_BIN: - l = f->hmf_binsize; - break; - - case HMF_S64: - u64 = f->hmf_s64; - l = 0; - while(u64 != 0) { - l++; - u64 = u64 >> 8; - } - break; - - case HMF_BOOL: - l = f->hmf_bool ? 1 : 0; - break; - - case HMF_UUID: - l = UUID_BIN_SIZE; - break; - - default: - abort(); + *ptr++ = f->hmf_type; + *ptr++ = namelen; + + switch (f->hmf_type) { + case HMF_MAP: + case HMF_LIST: + l = htsmsg_binary_count(f->hmf_msg); + break; + + case HMF_STR: + l = strlen(f->hmf_str); + break; + + case HMF_BIN: + l = f->hmf_binsize; + break; + + case HMF_S64: + u64 = f->hmf_s64; + l = 0; + while (u64 != 0) { + l++; + u64 = u64 >> 8; + } + break; + + case HMF_BOOL: + l = f->hmf_bool ? 1 : 0; + break; + + case HMF_UUID: + l = UUID_BIN_SIZE; + break; + + default: + abort(); } - *ptr++ = l >> 24; *ptr++ = l >> 16; *ptr++ = l >> 8; *ptr++ = l; - if(namelen > 0) { + if (namelen > 0) { memcpy(ptr, f->_hmf_name, namelen); ptr += namelen; } - switch(f->hmf_type) { - case HMF_MAP: - case HMF_LIST: - htsmsg_binary_write(f->hmf_msg, ptr); - break; - - case HMF_STR: - memcpy(ptr, f->hmf_str, l); - break; - - case HMF_BIN: - memcpy(ptr, f->hmf_bin, l); - break; - - case HMF_S64: - u64 = f->hmf_s64; - for(i = 0; i < l; i++) { - ptr[i] = u64; - u64 = u64 >> 8; - } - break; - - case HMF_BOOL: - if (f->hmf_bool) - ptr[0] = 1; - break; - - case HMF_UUID: - memcpy(ptr, f->hmf_uuid, UUID_BIN_SIZE); - break; + switch (f->hmf_type) { + case HMF_MAP: + case HMF_LIST: + htsmsg_binary_write(f->hmf_msg, ptr); + break; + + case HMF_STR: + memcpy(ptr, f->hmf_str, l); + break; + + case HMF_BIN: + memcpy(ptr, f->hmf_bin, l); + break; + + case HMF_S64: + u64 = f->hmf_s64; + for (i = 0; i < l; i++) { + ptr[i] = u64; + u64 = u64 >> 8; + } + break; + + case HMF_BOOL: + if (f->hmf_bool) + ptr[0] = 1; + break; + + case HMF_UUID: + memcpy(ptr, f->hmf_uuid, UUID_BIN_SIZE); + break; } ptr += l; } @@ -356,14 +343,12 @@ htsmsg_binary_write(htsmsg_t *msg, uint8_t *ptr) /* * */ -int -htsmsg_binary_serialize0(htsmsg_t *msg, void **datap, size_t *lenp, int maxlen) -{ - size_t len; - uint8_t *data; +int htsmsg_binary_serialize0(htsmsg_t* msg, void** datap, size_t* lenp, int maxlen) { + size_t len; + uint8_t* data; len = htsmsg_binary_count(msg); - if(len > maxlen) + if (len > maxlen) return -1; data = malloc(len); @@ -377,14 +362,12 @@ htsmsg_binary_serialize0(htsmsg_t *msg, void **datap, size_t *lenp, int maxlen) /* * */ -int -htsmsg_binary_serialize(htsmsg_t *msg, void **datap, size_t *lenp, int maxlen) -{ - size_t len; - uint8_t *data; +int htsmsg_binary_serialize(htsmsg_t* msg, void** datap, size_t* lenp, int maxlen) { + size_t len; + uint8_t* data; len = htsmsg_binary_count(msg); - if(len + 4 > maxlen) + if (len + 4 > maxlen) return -1; data = malloc(len + 4); diff --git a/src/htsmsg_binary.h b/src/htsmsg_binary.h index d7d1eee79..b530b18de 100644 --- a/src/htsmsg_binary.h +++ b/src/htsmsg_binary.h @@ -24,16 +24,12 @@ /** * htsmsg_binary_deserialize */ -htsmsg_t *htsmsg_binary_deserialize0(const void *data, size_t len, - const void *buf); +htsmsg_t* htsmsg_binary_deserialize0(const void* data, size_t len, const void* buf); -int htsmsg_binary_deserialize(htsmsg_t **msg, const void *data, size_t *len, - const void *buf); +int htsmsg_binary_deserialize(htsmsg_t** msg, const void* data, size_t* len, const void* buf); -int htsmsg_binary_serialize0(htsmsg_t *msg, void **datap, size_t *lenp, - int maxlen); +int htsmsg_binary_serialize0(htsmsg_t* msg, void** datap, size_t* lenp, int maxlen); -int htsmsg_binary_serialize(htsmsg_t *msg, void **datap, size_t *lenp, - int maxlen); +int htsmsg_binary_serialize(htsmsg_t* msg, void** datap, size_t* lenp, int maxlen); #endif /* HTSMSG_BINARY_H_ */ diff --git a/src/htsmsg_binary2.c b/src/htsmsg_binary2.c index 77ddaf862..74f47e434 100644 --- a/src/htsmsg_binary2.c +++ b/src/htsmsg_binary2.c @@ -26,18 +26,18 @@ #include "htsmsg_binary2.h" #include "memoryinfo.h" -static uint32_t htsmsg_binary2_count(htsmsg_t *msg); +static uint32_t htsmsg_binary2_count(htsmsg_t* msg); /* * */ -static inline uint32_t htsmsg_binary2_get_length(uint8_t const **_p, const uint8_t *end) -{ - uint32_t r = 0; - const uint8_t *p = *_p; - uint8_t c; +static inline uint32_t htsmsg_binary2_get_length(uint8_t const** _p, const uint8_t* end) { + uint32_t r = 0; + const uint8_t* p = *_p; + uint8_t c; while (p != end) { - c = *p; p++; + c = *p; + p++; r |= c & 0x7f; if ((c & 0x80) == 0) break; @@ -47,8 +47,7 @@ static inline uint32_t htsmsg_binary2_get_length(uint8_t const **_p, const uint8 return r; } -static inline uint8_t *htsmsg_binary2_set_length(uint8_t *p, uint32_t len) -{ +static inline uint8_t* htsmsg_binary2_set_length(uint8_t* p, uint32_t len) { if (len < 0x80) { p[0] = len; return p + 1; @@ -77,8 +76,7 @@ static inline uint8_t *htsmsg_binary2_set_length(uint8_t *p, uint32_t len) } } -static inline uint32_t htsmsg_binary2_length_count(uint32_t len) -{ +static inline uint32_t htsmsg_binary2_length_count(uint32_t len) { uint32_t r; if (len == 0) return 1; @@ -90,27 +88,25 @@ static inline uint32_t htsmsg_binary2_length_count(uint32_t len) /* * */ -static int -htsmsg_binary2_des0(htsmsg_t *msg, const uint8_t *buf, uint32_t len) -{ - uint_fast32_t type, namelen, datalen; - const uint8_t *p; - uint32_t tlen, nlen; - htsmsg_field_t *f; - htsmsg_t *sub; - uint64_t u64; - int i, bin = 0; - - while(len > 2) { - - type = buf[0]; - namelen = buf[1]; - p = buf + 2; - datalen = htsmsg_binary2_get_length(&p, buf + len); - len -= p - buf; - buf = p; - - if(len < namelen + datalen) +static int htsmsg_binary2_des0(htsmsg_t* msg, const uint8_t* buf, uint32_t len) { + uint_fast32_t type, namelen, datalen; + const uint8_t* p; + uint32_t tlen, nlen; + htsmsg_field_t* f; + htsmsg_t* sub; + uint64_t u64; + int i, bin = 0; + + while (len > 2) { + + type = buf[0]; + namelen = buf[1]; + p = buf + 2; + datalen = htsmsg_binary2_get_length(&p, buf + len); + len -= p - buf; + buf = p; + + if (len < namelen + datalen) return -1; nlen = namelen ? htsmsg_malloc_align(type, namelen + 1) : 0; @@ -134,9 +130,9 @@ htsmsg_binary2_des0(htsmsg_t *msg, const uint8_t *buf, uint32_t len) f->hmf_type = type; f->hmf_flags = 0; - if(namelen > 0) { - memcpy((char *)f->_hmf_name, buf, namelen); - ((char *)f->_hmf_name)[namelen] = 0; + if (namelen > 0) { + memcpy((char*)f->_hmf_name, buf, namelen); + ((char*)f->_hmf_name)[namelen] = 0; buf += namelen; len -= namelen; @@ -144,61 +140,61 @@ htsmsg_binary2_des0(htsmsg_t *msg, const uint8_t *buf, uint32_t len) f->hmf_flags |= HMF_NONAME; } - switch(type) { - case HMF_STR: - f->hmf_str = f->_hmf_name + nlen; - memcpy((char *)f->hmf_str, buf, datalen); - ((char *)f->hmf_str)[datalen] = 0; - f->hmf_flags |= HMF_INALLOCED; - break; - - case HMF_UUID: - f->hmf_uuid = (uint8_t *)f->_hmf_name + nlen; - memcpy((char *)f->hmf_uuid, buf, UUID_BIN_SIZE); - break; - - case HMF_BIN: - f->hmf_bin = (const void *)buf; - f->hmf_binsize = datalen; - bin = 1; - break; - - case HMF_S64: - u64 = 0; - for(i = datalen - 1; i >= 0; i--) - u64 = (u64 << 8) | buf[i]; - f->hmf_s64 = u64; - break; - - case HMF_MAP: - case HMF_LIST: - sub = f->hmf_msg = (htsmsg_t *)(f->_hmf_name + nlen); - TAILQ_INIT(&sub->hm_fields); - sub->hm_data = NULL; - sub->hm_data_size = 0; - sub->hm_islist = type == HMF_LIST; - i = htsmsg_binary2_des0(sub, buf, datalen); - if (i < 0) { + switch (type) { + case HMF_STR: + f->hmf_str = f->_hmf_name + nlen; + memcpy((char*)f->hmf_str, buf, datalen); + ((char*)f->hmf_str)[datalen] = 0; + f->hmf_flags |= HMF_INALLOCED; + break; + + case HMF_UUID: + f->hmf_uuid = (uint8_t*)f->_hmf_name + nlen; + memcpy((char*)f->hmf_uuid, buf, UUID_BIN_SIZE); + break; + + case HMF_BIN: + f->hmf_bin = (const void*)buf; + f->hmf_binsize = datalen; + bin = 1; + break; + + case HMF_S64: + u64 = 0; + for (i = datalen - 1; i >= 0; i--) + u64 = (u64 << 8) | buf[i]; + f->hmf_s64 = u64; + break; + + case HMF_MAP: + case HMF_LIST: + sub = f->hmf_msg = (htsmsg_t*)(f->_hmf_name + nlen); + TAILQ_INIT(&sub->hm_fields); + sub->hm_data = NULL; + sub->hm_data_size = 0; + sub->hm_islist = type == HMF_LIST; + i = htsmsg_binary2_des0(sub, buf, datalen); + if (i < 0) { +#if ENABLE_SLOW_MEMORYINFO + memoryinfo_free(&htsmsg_field_memoryinfo, tlen); +#endif + free(f); + return -1; + } + if (i > 0) + bin = 1; + break; + + case HMF_BOOL: + f->hmf_bool = datalen == 1 ? buf[0] : 0; + break; + + default: #if ENABLE_SLOW_MEMORYINFO memoryinfo_free(&htsmsg_field_memoryinfo, tlen); #endif free(f); return -1; - } - if (i > 0) - bin = 1; - break; - - case HMF_BOOL: - f->hmf_bool = datalen == 1 ? buf[0] : 0; - break; - - default: -#if ENABLE_SLOW_MEMORYINFO - memoryinfo_free(&htsmsg_field_memoryinfo, tlen); -#endif - free(f); - return -1; } TAILQ_INSERT_TAIL(&msg->hm_fields, f, hmf_link); @@ -211,31 +207,29 @@ htsmsg_binary2_des0(htsmsg_t *msg, const uint8_t *buf, uint32_t len) /* * */ -htsmsg_t * -htsmsg_binary2_deserialize0(const void *data, size_t len, const void *buf) -{ - htsmsg_t *msg; - int r; +htsmsg_t* htsmsg_binary2_deserialize0(const void* data, size_t len, const void* buf) { + htsmsg_t* msg; + int r; if (len != (len & 0xffffffff)) { - free((void *)buf); + free((void*)buf); return NULL; } msg = htsmsg_create_map(); - r = htsmsg_binary2_des0(msg, data, len); + r = htsmsg_binary2_des0(msg, data, len); if (r < 0) { - free((void *)buf); + free((void*)buf); htsmsg_destroy(msg); return NULL; } if (r > 0) { - msg->hm_data = buf; + msg->hm_data = buf; msg->hm_data_size = len; #if ENABLE_SLOW_MEMORYINFO memoryinfo_append(&htsmsg_memoryinfo, len); #endif } else { - free((void *)buf); + free((void*)buf); } return msg; } @@ -243,27 +237,24 @@ htsmsg_binary2_deserialize0(const void *data, size_t len, const void *buf) /* * */ -int -htsmsg_binary2_deserialize - (htsmsg_t **msg, const void *data, size_t *len, const void *buf) -{ - htsmsg_t *m; - const uint8_t *p; - uint32_t l, l2; - size_t len2; +int htsmsg_binary2_deserialize(htsmsg_t** msg, const void* data, size_t* len, const void* buf) { + htsmsg_t* m; + const uint8_t* p; + uint32_t l, l2; + size_t len2; len2 = *len; *msg = NULL; *len = 0; if (len2 != (len2 & 0xffffffff) || len2 == 0) { - free((void *)buf); + free((void*)buf); return -1; } - p = data; - l = htsmsg_binary2_get_length(&p, data + len2); - l2 = l + (p - (uint8_t *)data); + p = data; + l = htsmsg_binary2_get_length(&p, data + len2); + l2 = l + (p - (uint8_t*)data); if (l2 > len2) { - free((void *)buf); + free((void*)buf); return -1; } m = htsmsg_binary2_deserialize0(p, l, buf); @@ -277,53 +268,49 @@ htsmsg_binary2_deserialize /* * */ -static uint32_t -htsmsg_binary2_field_length(htsmsg_field_t *f) -{ +static uint32_t htsmsg_binary2_field_length(htsmsg_field_t* f) { uint64_t u64; uint32_t l; - switch(f->hmf_type) { - case HMF_MAP: - case HMF_LIST: - return htsmsg_binary2_count(f->hmf_msg); + switch (f->hmf_type) { + case HMF_MAP: + case HMF_LIST: + return htsmsg_binary2_count(f->hmf_msg); - case HMF_STR: - return strlen(f->hmf_str); + case HMF_STR: + return strlen(f->hmf_str); - case HMF_UUID: - return UUID_BIN_SIZE; + case HMF_UUID: + return UUID_BIN_SIZE; - case HMF_BIN: - return f->hmf_binsize; + case HMF_BIN: + return f->hmf_binsize; - case HMF_S64: - u64 = f->hmf_s64; - l = 0; - while(u64 != 0) { - l++; - u64 >>= 8; - } - return l; + case HMF_S64: + u64 = f->hmf_s64; + l = 0; + while (u64 != 0) { + l++; + u64 >>= 8; + } + return l; - case HMF_BOOL: - return f->hmf_bool ? 1 : 0; + case HMF_BOOL: + return f->hmf_bool ? 1 : 0; - default: - abort(); + default: + abort(); } } /* * */ -static uint32_t -htsmsg_binary2_count(htsmsg_t *msg) -{ - htsmsg_field_t *f; - uint32_t len = 0, l; +static uint32_t htsmsg_binary2_count(htsmsg_t* msg) { + htsmsg_field_t* f; + uint32_t len = 0, l; - TAILQ_FOREACH(f, &msg->hm_fields, hmf_link) { + TAILQ_FOREACH (f, &msg->hm_fields, hmf_link) { l = htsmsg_binary2_field_length(f); len += 2 + htsmsg_binary2_length_count(l); len += strlen(htsmsg_field_name(f)); @@ -335,60 +322,58 @@ htsmsg_binary2_count(htsmsg_t *msg) /* * */ -static void -htsmsg_binary2_write(htsmsg_t *msg, uint8_t *ptr) -{ - htsmsg_field_t *f; - uint64_t u64; - int l, i, namelen; +static void htsmsg_binary2_write(htsmsg_t* msg, uint8_t* ptr) { + htsmsg_field_t* f; + uint64_t u64; + int l, i, namelen; - TAILQ_FOREACH(f, &msg->hm_fields, hmf_link) { + TAILQ_FOREACH (f, &msg->hm_fields, hmf_link) { namelen = strlen(htsmsg_field_name(f)); assert(namelen <= 0xff); *ptr++ = f->hmf_type; *ptr++ = namelen; - l = htsmsg_binary2_field_length(f); + l = htsmsg_binary2_field_length(f); ptr = htsmsg_binary2_set_length(ptr, l); - if(namelen > 0) { + if (namelen > 0) { memcpy(ptr, f->_hmf_name, namelen); ptr += namelen; } - switch(f->hmf_type) { - case HMF_MAP: - case HMF_LIST: - htsmsg_binary2_write(f->hmf_msg, ptr); - break; - - case HMF_STR: - memcpy(ptr, f->hmf_str, l); - break; - - case HMF_UUID: - memcpy(ptr, f->hmf_uuid, UUID_BIN_SIZE); - break; - - case HMF_BIN: - memcpy(ptr, f->hmf_bin, l); - break; - - case HMF_S64: - u64 = f->hmf_s64; - for(i = 0; i < l; i++) { - ptr[i] = u64; - u64 >>= 8; - } - break; - - case HMF_BOOL: - if (f->hmf_bool) - ptr[0] = 1; - break; - - default: - abort(); + switch (f->hmf_type) { + case HMF_MAP: + case HMF_LIST: + htsmsg_binary2_write(f->hmf_msg, ptr); + break; + + case HMF_STR: + memcpy(ptr, f->hmf_str, l); + break; + + case HMF_UUID: + memcpy(ptr, f->hmf_uuid, UUID_BIN_SIZE); + break; + + case HMF_BIN: + memcpy(ptr, f->hmf_bin, l); + break; + + case HMF_S64: + u64 = f->hmf_s64; + for (i = 0; i < l; i++) { + ptr[i] = u64; + u64 >>= 8; + } + break; + + case HMF_BOOL: + if (f->hmf_bool) + ptr[0] = 1; + break; + + default: + abort(); } ptr += l; } @@ -397,15 +382,12 @@ htsmsg_binary2_write(htsmsg_t *msg, uint8_t *ptr) /* * */ -int -htsmsg_binary2_serialize0 - (htsmsg_t *msg, void **datap, size_t *lenp, size_t maxlen) -{ +int htsmsg_binary2_serialize0(htsmsg_t* msg, void** datap, size_t* lenp, size_t maxlen) { uint32_t len; - uint8_t *data; + uint8_t* data; len = htsmsg_binary2_count(msg); - if((size_t)len > maxlen) + if ((size_t)len > maxlen) return -1; data = malloc(len); @@ -420,16 +402,13 @@ htsmsg_binary2_serialize0 /* * */ -int -htsmsg_binary2_serialize - (htsmsg_t *msg, void **datap, size_t *lenp, size_t maxlen) -{ +int htsmsg_binary2_serialize(htsmsg_t* msg, void** datap, size_t* lenp, size_t maxlen) { uint32_t len, llen; uint8_t *data, *p; - len = htsmsg_binary2_count(msg); + len = htsmsg_binary2_count(msg); llen = htsmsg_binary2_length_count(len); - if((size_t)len + (size_t)llen > maxlen) + if ((size_t)len + (size_t)llen > maxlen) return -1; data = malloc(len + llen); diff --git a/src/htsmsg_binary2.h b/src/htsmsg_binary2.h index e41eeb7ee..6a25c9731 100644 --- a/src/htsmsg_binary2.h +++ b/src/htsmsg_binary2.h @@ -21,16 +21,12 @@ #include "htsmsg.h" -htsmsg_t *htsmsg_binary2_deserialize0(const void *data, size_t len, - const void *buf); +htsmsg_t* htsmsg_binary2_deserialize0(const void* data, size_t len, const void* buf); -int htsmsg_binary2_deserialize(htsmsg_t **msg, const void *data, size_t *len, - const void *buf); +int htsmsg_binary2_deserialize(htsmsg_t** msg, const void* data, size_t* len, const void* buf); -int htsmsg_binary2_serialize0(htsmsg_t *msg, void **datap, size_t *lenp, - size_t maxlen); +int htsmsg_binary2_serialize0(htsmsg_t* msg, void** datap, size_t* lenp, size_t maxlen); -int htsmsg_binary2_serialize(htsmsg_t *msg, void **datap, size_t *lenp, - size_t maxlen); +int htsmsg_binary2_serialize(htsmsg_t* msg, void** datap, size_t* lenp, size_t maxlen); #endif /* HTSMSG_BINARY2_H_ */ diff --git a/src/htsmsg_json.c b/src/htsmsg_json.c index 28f6c585e..cfd3717d5 100644 --- a/src/htsmsg_json.c +++ b/src/htsmsg_json.c @@ -29,101 +29,93 @@ #include "misc/json.h" #include "misc/dbl.h" - /** * */ static void -htsmsg_json_write(htsmsg_t *msg, htsbuf_queue_t *hq, int isarray, - int indent, int pretty) -{ - htsmsg_field_t *f; - char buf[100]; - static const char *indentor = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; - const char *s; +htsmsg_json_write(htsmsg_t* msg, htsbuf_queue_t* hq, int isarray, int indent, int pretty) { + htsmsg_field_t* f; + char buf[100]; + static const char* indentor = "\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t"; + const char* s; htsbuf_append(hq, isarray ? "[" : "{", 1); - TAILQ_FOREACH(f, &msg->hm_fields, hmf_link) { + TAILQ_FOREACH (f, &msg->hm_fields, hmf_link) { - if(pretty) + if (pretty) htsbuf_append(hq, indentor, indent < 16 ? indent : 16); - if(!isarray) { + if (!isarray) { htsbuf_append_and_escape_jsonstr(hq, htsmsg_field_name(f)); htsbuf_append(hq, ": ", pretty ? 2 : 1); } - switch(f->hmf_type) { - case HMF_MAP: - htsmsg_json_write(f->hmf_msg, hq, 0, indent + 1, pretty); - break; - - case HMF_LIST: - htsmsg_json_write(f->hmf_msg, hq, 1, indent + 1, pretty); - break; - - case HMF_STR: - htsbuf_append_and_escape_jsonstr(hq, f->hmf_str); - break; - - case HMF_UUID: - uuid_get_hex((tvh_uuid_t *)f->hmf_uuid, buf); - htsbuf_append_and_escape_jsonstr(hq, buf); - break; - - case HMF_BIN: - htsbuf_append_and_escape_jsonstr(hq, "binary"); - break; - - case HMF_BOOL: - s = f->hmf_bool ? "true" : "false"; - htsbuf_append_str(hq, s); - break; - - case HMF_S64: - snprintf(buf, sizeof(buf), "%" PRId64, f->hmf_s64); - htsbuf_append_str(hq, buf); - break; - - case HMF_DBL: - my_double2str(buf, sizeof(buf), f->hmf_dbl); - htsbuf_append_str(hq, buf); - break; - - default: - abort(); + switch (f->hmf_type) { + case HMF_MAP: + htsmsg_json_write(f->hmf_msg, hq, 0, indent + 1, pretty); + break; + + case HMF_LIST: + htsmsg_json_write(f->hmf_msg, hq, 1, indent + 1, pretty); + break; + + case HMF_STR: + htsbuf_append_and_escape_jsonstr(hq, f->hmf_str); + break; + + case HMF_UUID: + uuid_get_hex((tvh_uuid_t*)f->hmf_uuid, buf); + htsbuf_append_and_escape_jsonstr(hq, buf); + break; + + case HMF_BIN: + htsbuf_append_and_escape_jsonstr(hq, "binary"); + break; + + case HMF_BOOL: + s = f->hmf_bool ? "true" : "false"; + htsbuf_append_str(hq, s); + break; + + case HMF_S64: + snprintf(buf, sizeof(buf), "%" PRId64, f->hmf_s64); + htsbuf_append_str(hq, buf); + break; + + case HMF_DBL: + my_double2str(buf, sizeof(buf), f->hmf_dbl); + htsbuf_append_str(hq, buf); + break; + + default: + abort(); } - if(TAILQ_NEXT(f, hmf_link)) + if (TAILQ_NEXT(f, hmf_link)) htsbuf_append(hq, ",", 1); } - - if(pretty) - htsbuf_append(hq, indentor, indent-1 < 16 ? indent-1 : 16); + + if (pretty) + htsbuf_append(hq, indentor, indent - 1 < 16 ? indent - 1 : 16); htsbuf_append(hq, isarray ? "]" : "}", 1); } /** * */ -void -htsmsg_json_serialize(htsmsg_t *msg, htsbuf_queue_t *hq, int pretty) -{ +void htsmsg_json_serialize(htsmsg_t* msg, htsbuf_queue_t* hq, int pretty) { htsmsg_json_write(msg, hq, msg->hm_islist, 2, pretty); - if(pretty) + if (pretty) htsbuf_append(hq, "\n", 1); } - /** * */ -char * -htsmsg_json_serialize_to_str(htsmsg_t *msg, int pretty) -{ +char* htsmsg_json_serialize_to_str(htsmsg_t* msg, int pretty) { htsbuf_queue_t hq; - char *str; + char* str; htsbuf_queue_init(&hq, 0); htsmsg_json_serialize(msg, &hq, pretty); str = htsbuf_to_string(&hq); @@ -131,85 +123,62 @@ htsmsg_json_serialize_to_str(htsmsg_t *msg, int pretty) return str; } - /** * */ -static void * -create_map(void *opaque) -{ +static void* create_map(void* opaque) { return htsmsg_create_map(); } -static void * -create_list(void *opaque) -{ +static void* create_list(void* opaque) { return htsmsg_create_list(); } -static void -destroy_obj(void *opaque, void *obj) -{ +static void destroy_obj(void* opaque, void* obj) { return htsmsg_destroy(obj); } -static void -add_obj(void *opaque, void *parent, const char *name, void *child) -{ +static void add_obj(void* opaque, void* parent, const char* name, void* child) { htsmsg_add_msg(parent, name, child); } -static void -add_string(void *opaque, void *parent, const char *name, char *str) -{ +static void add_string(void* opaque, void* parent, const char* name, char* str) { htsmsg_add_str(parent, name, str); free(str); } -static void -add_s64(void *opaque, void *parent, const char *name, int64_t v) -{ +static void add_s64(void* opaque, void* parent, const char* name, int64_t v) { htsmsg_add_s64(parent, name, v); } -static void -add_double(void *opaque, void *parent, const char *name, double v) -{ +static void add_double(void* opaque, void* parent, const char* name, double v) { htsmsg_add_dbl(parent, name, v); } -static void -add_bool(void *opaque, void *parent, const char *name, int v) -{ +static void add_bool(void* opaque, void* parent, const char* name, int v) { htsmsg_add_bool(parent, name, v); } -static void -add_null(void *opaque, void *parent, const char *name) -{ -} +static void add_null(void* opaque, void* parent, const char* name) {} /** * */ static const json_deserializer_t json_to_htsmsg = { - .jd_create_map = create_map, - .jd_create_list = create_list, - .jd_destroy_obj = destroy_obj, - .jd_add_obj = add_obj, - .jd_add_string = add_string, - .jd_add_s64 = add_s64, - .jd_add_double = add_double, - .jd_add_bool = add_bool, - .jd_add_null = add_null, + .jd_create_map = create_map, + .jd_create_list = create_list, + .jd_destroy_obj = destroy_obj, + .jd_add_obj = add_obj, + .jd_add_string = add_string, + .jd_add_s64 = add_s64, + .jd_add_double = add_double, + .jd_add_bool = add_bool, + .jd_add_null = add_null, }; - /** * */ -htsmsg_t * -htsmsg_json_deserialize(const char *src) -{ +htsmsg_t* htsmsg_json_deserialize(const char* src) { return json_deserialize(src, &json_to_htsmsg, NULL, NULL, 0); } diff --git a/src/htsmsg_json.h b/src/htsmsg_json.h index ae7cf4cf2..a855c1c07 100644 --- a/src/htsmsg_json.h +++ b/src/htsmsg_json.h @@ -25,13 +25,12 @@ struct rstr; /** * htsmsg_binary_deserialize */ -htsmsg_t *htsmsg_json_deserialize(const char *src); +htsmsg_t* htsmsg_json_deserialize(const char* src); -void htsmsg_json_serialize(htsmsg_t *msg, htsbuf_queue_t *hq, int pretty); +void htsmsg_json_serialize(htsmsg_t* msg, htsbuf_queue_t* hq, int pretty); -__attribute__((warn_unused_result)) -char *htsmsg_json_serialize_to_str(htsmsg_t *msg, int pretty); +__attribute__((warn_unused_result)) char* htsmsg_json_serialize_to_str(htsmsg_t* msg, int pretty); -struct rstr *htsmsg_json_serialize_to_rstr(htsmsg_t *msg, const char *prefix); +struct rstr* htsmsg_json_serialize_to_rstr(htsmsg_t* msg, const char* prefix); #endif /* HTSMSG_JSON_H_ */ diff --git a/src/htsmsg_xml.c b/src/htsmsg_xml.c index 4123e74d6..4ef3cdef3 100644 --- a/src/htsmsg_xml.c +++ b/src/htsmsg_xml.c @@ -25,7 +25,7 @@ * htsmsg's with UTF-8 encoded payloads * * Supports: Example: - * + * * Comments * Processing Instructions * CDATA ]]> @@ -42,7 +42,6 @@ * */ - #include #include #include @@ -63,10 +62,10 @@ typedef struct xmlns { LIST_ENTRY(xmlns) xmlns_global_link; LIST_ENTRY(xmlns) xmlns_scope_link; - char *xmlns_prefix; + char* xmlns_prefix; unsigned int xmlns_prefix_len; - char *xmlns_norm; + char* xmlns_norm; unsigned int xmlns_norm_len; } xmlns_t; @@ -85,32 +84,27 @@ typedef struct xmlparser { } xmlparser_t; -#define xmlerr(xp, fmt...) \ - snprintf((xp)->xp_errmsg, sizeof((xp)->xp_errmsg), fmt) - +#define xmlerr(xp, fmt...) snprintf((xp)->xp_errmsg, sizeof((xp)->xp_errmsg), fmt) typedef struct cdata_content { TAILQ_ENTRY(cdata_content) cc_link; char *cc_start, *cc_end; /* end points to byte AFTER last char */ - int cc_encoding; - char cc_buf[0]; + int cc_encoding; + char cc_buf[0]; } cdata_content_t; -static char *htsmsg_xml_parse_cd(xmlparser_t *xp, - htsmsg_t *parent, char *src); +static char* htsmsg_xml_parse_cd(xmlparser_t* xp, htsmsg_t* parent, char* src); /** * */ -static void -add_unicode(struct cdata_content_queue *ccq, int c) -{ - cdata_content_t *cc; - int r; +static void add_unicode(struct cdata_content_queue* ccq, int c) { + cdata_content_t* cc; + int r; cc = malloc(sizeof(cdata_content_t) + 6); - r = put_utf8(cc->cc_buf, c); - if(r == 0) { + r = put_utf8(cc->cc_buf, c); + if (r == 0) { free(cc); return; } @@ -124,34 +118,32 @@ add_unicode(struct cdata_content_queue *ccq, int c) /** * */ -static int -decode_character_reference(char **src) -{ - int v = 0; +static int decode_character_reference(char** src) { + int v = 0; char c; - if(**src == 'x') { + if (**src == 'x') { /* hexadecimal */ (*src)++; /* decimal */ - while(1) { + while (1) { c = **src; - switch(c) { - case '0' ... '9': - v = v * 0x10 + c - '0'; - break; - case 'a' ... 'f': - v = v * 0x10 + c - 'a' + 10; - break; - case 'A' ... 'F': - v = v * 0x10 + c - 'A' + 10; - break; - case ';': - (*src)++; - return v; - default: - return 0; + switch (c) { + case '0' ... '9': + v = v * 0x10 + c - '0'; + break; + case 'a' ... 'f': + v = v * 0x10 + c - 'a' + 10; + break; + case 'A' ... 'F': + v = v * 0x10 + c - 'A' + 10; + break; + case ';': + (*src)++; + return v; + default: + return 0; } (*src)++; } @@ -159,18 +151,18 @@ decode_character_reference(char **src) } else { /* decimal */ - while(1) { + while (1) { c = **src; - switch(c) { - case '0' ... '9': - v = v * 10 + c - '0'; - (*src)++; - break; - case ';': - (*src)++; - return v; - default: - return 0; + switch (c) { + case '0' ... '9': + v = v * 10 + c - '0'; + (*src)++; + break; + case ';': + (*src)++; + return v; + default: + return 0; } } } @@ -179,20 +171,15 @@ decode_character_reference(char **src) /** * */ -static inline int -is_xmlws(char c) -{ +static inline int is_xmlws(char c) { return c > 0 && c <= 32; // return c == 32 || c == 9 || c = 10 || c = 13; } - /** * */ -static void -xmlns_destroy(xmlns_t *ns) -{ +static void xmlns_destroy(xmlns_t* ns) { LIST_REMOVE(ns, xmlns_global_link); LIST_REMOVE(ns, xmlns_scope_link); free(ns->xmlns_prefix); @@ -203,105 +190,102 @@ xmlns_destroy(xmlns_t *ns) /** * */ -static char * -htsmsg_xml_parse_attrib - (xmlparser_t *xp, htsmsg_t *msg, char *src, - struct xmlns_list *xmlns_scope_list) -{ - char *attribname, *payload; - int attriblen, payloadlen; - char quote; - htsmsg_field_t *f; - xmlns_t *ns; +static char* htsmsg_xml_parse_attrib(xmlparser_t* xp, + htsmsg_t* msg, + char* src, + struct xmlns_list* xmlns_scope_list) { + char * attribname, *payload; + int attriblen, payloadlen; + char quote; + htsmsg_field_t* f; + xmlns_t* ns; attribname = src; /* Parse attribute name */ - while(1) { - if(*src == 0) { + while (1) { + if (*src == 0) { xmlerr(xp, "Unexpected end of file during attribute name parsing"); return NULL; } - if(is_xmlws(*src) || *src == '=') + if (is_xmlws(*src) || *src == '=') break; src++; } attriblen = src - attribname; - if(attriblen < 1 || attriblen > 65535) { + if (attriblen < 1 || attriblen > 65535) { xmlerr(xp, "Invalid attribute name"); return NULL; } - while(is_xmlws(*src)) + while (is_xmlws(*src)) src++; - if(*src != '=') { + if (*src != '=') { xmlerr(xp, "Expected '=' in attribute parsing"); return NULL; } src++; - while(is_xmlws(*src)) + while (is_xmlws(*src)) src++; - /* Parse attribute payload */ quote = *src++; - if(quote != '"' && quote != '\'') { + if (quote != '"' && quote != '\'') { xmlerr(xp, "Expected ' or \" before attribute value"); return NULL; } payload = src; - while(1) { - if(*src == 0) { + while (1) { + if (*src == 0) { xmlerr(xp, "Unexpected end of file during attribute value parsing"); return NULL; } - if(*src == quote) + if (*src == quote) break; src++; } payloadlen = src - payload; - if(payloadlen < 0 || payloadlen > 65535) { + if (payloadlen < 0 || payloadlen > 65535) { xmlerr(xp, "Invalid attribute value"); return NULL; } src++; - while(is_xmlws(*src)) + while (is_xmlws(*src)) src++; - if(xmlns_scope_list != NULL && - attriblen > 6 && !memcmp(attribname, "xmlns:", 6)) { + if (xmlns_scope_list != NULL && attriblen > 6 && !memcmp(attribname, "xmlns:", 6)) { attribname += 6; - attriblen -= 6; + attriblen -= 6; ns = malloc(sizeof(xmlns_t)); ns->xmlns_prefix = malloc(attriblen + 1); memcpy(ns->xmlns_prefix, attribname, attriblen); ns->xmlns_prefix[attriblen] = 0; - ns->xmlns_prefix_len = attriblen; + ns->xmlns_prefix_len = attriblen; ns->xmlns_norm = malloc(payloadlen + 1); memcpy(ns->xmlns_norm, payload, payloadlen); ns->xmlns_norm[payloadlen] = 0; - ns->xmlns_norm_len = payloadlen; + ns->xmlns_norm_len = payloadlen; LIST_INSERT_HEAD(&xp->xp_namespaces, ns, xmlns_global_link); - LIST_INSERT_HEAD(xmlns_scope_list, ns, xmlns_scope_link); + LIST_INSERT_HEAD(xmlns_scope_list, ns, xmlns_scope_link); return src; } - xp->xp_srcdataused = 1; + xp->xp_srcdataused = 1; attribname[attriblen] = 0; - payload[payloadlen] = 0; + payload[payloadlen] = 0; - f = htsmsg_field_add(msg, attribname, HMF_STR, 0, 0); + f = htsmsg_field_add(msg, attribname, HMF_STR, 0, 0); f->hmf_str = payload; return src; } @@ -309,60 +293,58 @@ htsmsg_xml_parse_attrib /** * */ -static char * -htsmsg_xml_parse_tag(xmlparser_t *xp, htsmsg_t *parent, char *src) -{ - htsmsg_t *m, *attrs; +static char* htsmsg_xml_parse_tag(xmlparser_t* xp, htsmsg_t* parent, char* src) { + htsmsg_t * m, *attrs; struct xmlns_list nslist; - char *tagname; - int taglen, empty = 0, i; - xmlns_t *ns; + char* tagname; + int taglen, empty = 0, i; + xmlns_t* ns; tagname = src; LIST_INIT(&nslist); - while(1) { - if(*src == 0) { + while (1) { + if (*src == 0) { xmlerr(xp, "Unexpected end of file during tag name parsing"); return NULL; } - if(is_xmlws(*src) || *src == '>' || *src == '/') + if (is_xmlws(*src) || *src == '>' || *src == '/') break; src++; } taglen = src - tagname; - if(taglen < 1 || taglen > 65535) { + if (taglen < 1 || taglen > 65535) { xmlerr(xp, "Invalid tag name"); return NULL; } attrs = htsmsg_create_map(); - while(1) { + while (1) { - while(is_xmlws(*src)) + while (is_xmlws(*src)) src++; - if(*src == 0) { + if (*src == 0) { htsmsg_destroy(attrs); xmlerr(xp, "Unexpected end of file in tag"); return NULL; } - if(src[0] == '/' && src[1] == '>') { + if (src[0] == '/' && src[1] == '>') { empty = 1; src += 2; break; } - if(*src == '>') { + if (*src == '>') { src++; break; } - if((src = htsmsg_xml_parse_attrib(xp, attrs, src, &nslist)) == NULL) { + if ((src = htsmsg_xml_parse_attrib(xp, attrs, src, &nslist)) == NULL) { htsmsg_destroy(attrs); return NULL; } @@ -370,42 +352,41 @@ htsmsg_xml_parse_tag(xmlparser_t *xp, htsmsg_t *parent, char *src) m = htsmsg_create_map(); - if(TAILQ_FIRST(&attrs->hm_fields) != NULL) { + if (TAILQ_FIRST(&attrs->hm_fields) != NULL) { htsmsg_add_msg_extname(m, "attrib", attrs); } else { htsmsg_destroy(attrs); } - if(!empty) + if (!empty) src = htsmsg_xml_parse_cd(xp, m, src); - for(i = 0; i < taglen - 1; i++) { - if(tagname[i] == ':') { + for (i = 0; i < taglen - 1; i++) { + if (tagname[i] == ':') { - LIST_FOREACH(ns, &xp->xp_namespaces, xmlns_global_link) { - if(ns->xmlns_prefix_len == i && - !memcmp(ns->xmlns_prefix, tagname, ns->xmlns_prefix_len)) { + LIST_FOREACH (ns, &xp->xp_namespaces, xmlns_global_link) { + if (ns->xmlns_prefix_len == i && !memcmp(ns->xmlns_prefix, tagname, ns->xmlns_prefix_len)) { - int llen = taglen - i - 1; - char *n = malloc(ns->xmlns_norm_len + llen + 1); + int llen = taglen - i - 1; + char* n = malloc(ns->xmlns_norm_len + llen + 1); - n[ns->xmlns_norm_len + llen] = 0; - memcpy(n, ns->xmlns_norm, ns->xmlns_norm_len); - memcpy(n + ns->xmlns_norm_len, tagname + i + 1, llen); - htsmsg_add_msg(parent, n, m); - free(n); - goto done; - } + n[ns->xmlns_norm_len + llen] = 0; + memcpy(n, ns->xmlns_norm, ns->xmlns_norm_len); + memcpy(n + ns->xmlns_norm_len, tagname + i + 1, llen); + htsmsg_add_msg(parent, n, m); + free(n); + goto done; + } } } } xp->xp_srcdataused = 1; - tagname[taglen] = 0; + tagname[taglen] = 0; htsmsg_add_msg_extname(parent, tagname, m); - done: - while((ns = LIST_FIRST(&nslist)) != NULL) +done: + while ((ns = LIST_FIRST(&nslist)) != NULL) xmlns_destroy(ns); return src; } @@ -413,28 +394,27 @@ htsmsg_xml_parse_tag(xmlparser_t *xp, htsmsg_t *parent, char *src) /** * */ -static char * -htsmsg_xml_parse_pi(xmlparser_t *xp, htsmsg_t *parent, char *src) -{ - htsmsg_t *attrs; - char *s = src; - char *piname; - int l; - - while(1) { - if(*src == 0) { - xmlerr(xp, "Unexpected end of file during parsing of " - "Processing instructions"); +static char* htsmsg_xml_parse_pi(xmlparser_t* xp, htsmsg_t* parent, char* src) { + htsmsg_t* attrs; + char* s = src; + char* piname; + int l; + + while (1) { + if (*src == 0) { + xmlerr(xp, + "Unexpected end of file during parsing of " + "Processing instructions"); return NULL; } - if(is_xmlws(*src) || *src == '?') + if (is_xmlws(*src) || *src == '?') break; src++; } l = src - s; - if(l < 1 || l > 65536) { + if (l < 1 || l > 65536) { xmlerr(xp, "Invalid 'Processing instructions' name"); return NULL; } @@ -444,31 +424,31 @@ htsmsg_xml_parse_pi(xmlparser_t *xp, htsmsg_t *parent, char *src) attrs = htsmsg_create_map(); - while(1) { + while (1) { - while(is_xmlws(*src)) + while (is_xmlws(*src)) src++; - if(*src == 0) { + if (*src == 0) { htsmsg_destroy(attrs); - xmlerr(xp, "Unexpected end of file during parsing of " - "Processing instructions"); + xmlerr(xp, + "Unexpected end of file during parsing of " + "Processing instructions"); return NULL; } - if(src[0] == '?' && src[1] == '>') { + if (src[0] == '?' && src[1] == '>') { src += 2; break; } - if((src = htsmsg_xml_parse_attrib(xp, attrs, src, NULL)) == NULL) { + if ((src = htsmsg_xml_parse_attrib(xp, attrs, src, NULL)) == NULL) { htsmsg_destroy(attrs); return NULL; } } - - if(TAILQ_FIRST(&attrs->hm_fields) != NULL && parent != NULL) { + if (TAILQ_FIRST(&attrs->hm_fields) != NULL && parent != NULL) { htsmsg_add_msg(parent, piname, attrs); } else { htsmsg_destroy(attrs); @@ -479,17 +459,15 @@ htsmsg_xml_parse_pi(xmlparser_t *xp, htsmsg_t *parent, char *src) /** * */ -static char * -xml_parse_comment(xmlparser_t *xp, char *src) -{ +static char* xml_parse_comment(xmlparser_t* xp, char* src) { /* comment */ - while(1) { - if(*src == 0) { /* EOF inside comment is invalid */ + while (1) { + if (*src == 0) { /* EOF inside comment is invalid */ xmlerr(xp, "Unexpected end of file inside a comment"); return NULL; } - if(src[0] == '-' && src[1] == '-' && src[2] == '>') + if (src[0] == '-' && src[1] == '-' && src[2] == '>') return src + 3; src++; } @@ -498,38 +476,35 @@ xml_parse_comment(xmlparser_t *xp, char *src) /** * */ -static char * -decode_label_reference - (xmlparser_t *xp, struct cdata_content_queue *ccq, char *src) -{ - char *s = src; - int l; - char *label; - - while(*src != 0 && *src != ';') +static char* decode_label_reference(xmlparser_t* xp, struct cdata_content_queue* ccq, char* src) { + char* s = src; + int l; + char* label; + + while (*src != 0 && *src != ';') src++; - if(*src == 0) { + if (*src == 0) { xmlerr(xp, "Unexpected end of file during parsing of label reference"); return NULL; } l = src - s; - if(l < 1 || l > 65535) + if (l < 1 || l > 65535) return NULL; label = alloca(l + 1); memcpy(label, s, l); label[l] = 0; src++; - if(!strcmp(label, "amp")) + if (!strcmp(label, "amp")) add_unicode(ccq, '&'); - else if(!strcmp(label, "gt")) + else if (!strcmp(label, "gt")) add_unicode(ccq, '>'); - else if(!strcmp(label, "lt")) + else if (!strcmp(label, "lt")) add_unicode(ccq, '<'); - else if(!strcmp(label, "apos")) + else if (!strcmp(label, "apos")) add_unicode(ccq, '\''); - else if(!strcmp(label, "quot")) + else if (!strcmp(label, "quot")) add_unicode(ccq, '"'); else { xmlerr(xp, "Unknown label referense: \"&%s;\"\n", label); @@ -542,102 +517,103 @@ decode_label_reference /** * */ -static char * -htsmsg_xml_parse_cd0 - (xmlparser_t *xp,struct cdata_content_queue *ccq, htsmsg_t *tags, - htsmsg_t *pis, char *src, int raw) -{ - cdata_content_t *cc = NULL; - int c; - - while(src != NULL && *src != 0) { - - if(raw && src[0] == ']' && src[1] == ']' && src[2] == '>') { - if(cc != NULL) - cc->cc_end = src; +static char* htsmsg_xml_parse_cd0(xmlparser_t* xp, + struct cdata_content_queue* ccq, + htsmsg_t* tags, + htsmsg_t* pis, + char* src, + int raw) { + cdata_content_t* cc = NULL; + int c; + + while (src != NULL && *src != 0) { + + if (raw && src[0] == ']' && src[1] == ']' && src[2] == '>') { + if (cc != NULL) + cc->cc_end = src; cc = NULL; src += 3; break; } - if(*src == '<' && !raw) { + if (*src == '<' && !raw) { - if(cc != NULL) - cc->cc_end = src; + if (cc != NULL) + cc->cc_end = src; cc = NULL; src++; - if(*src == '?') { - src++; - src = htsmsg_xml_parse_pi(xp, pis, src); - continue; + if (*src == '?') { + src++; + src = htsmsg_xml_parse_pi(xp, pis, src); + continue; } - if(src[0] == '!') { + if (src[0] == '!') { - src++; + src++; - if(src[0] == '-' && src[1] == '-') { - src = xml_parse_comment(xp, src + 2); - continue; - } + if (src[0] == '-' && src[1] == '-') { + src = xml_parse_comment(xp, src + 2); + continue; + } - if(!strncmp(src, "[CDATA[", 7)) { - src += 7; - src = htsmsg_xml_parse_cd0(xp, ccq, tags, pis, src, 1); - continue; - } - xmlerr(xp, "Unknown syntatic element: ') { - if(*src == 0) { /* EOF inside endtag */ - xmlerr(xp, "Unexpected end of file inside close tag"); - return NULL; - } - src++; - } - src++; - break; + if (*src == '/') { + /* End-tag */ + src++; + while (*src != '>') { + if (*src == 0) { /* EOF inside endtag */ + xmlerr(xp, "Unexpected end of file inside close tag"); + return NULL; + } + src++; + } + src++; + break; } src = htsmsg_xml_parse_tag(xp, tags, src); continue; } - - if(*src == '&' && !raw) { - if(cc != NULL) - cc->cc_end = src; + + if (*src == '&' && !raw) { + if (cc != NULL) + cc->cc_end = src; cc = NULL; src++; - if(*src == '#') { - src++; - /* Character reference */ - if((c = decode_character_reference(&src)) != 0) - add_unicode(ccq, c); - else { - xmlerr(xp, "Invalid character reference"); - return NULL; - } + if (*src == '#') { + src++; + /* Character reference */ + if ((c = decode_character_reference(&src)) != 0) + add_unicode(ccq, c); + else { + xmlerr(xp, "Invalid character reference"); + return NULL; + } } else { - /* Label references */ - src = decode_label_reference(xp, ccq, src); + /* Label references */ + src = decode_label_reference(xp, ccq, src); } continue; } - if(cc == NULL) { - if(*src < 32) { - src++; - continue; + if (cc == NULL) { + if (*src < 32) { + src++; + continue; } - cc = malloc(sizeof(cdata_content_t)); + cc = malloc(sizeof(cdata_content_t)); cc->cc_encoding = xp->xp_encoding; TAILQ_INSERT_TAIL(ccq, cc, cc_link); cc->cc_start = src; @@ -645,7 +621,7 @@ htsmsg_xml_parse_cd0 src++; } - if(cc != NULL) { + if (cc != NULL) { assert(src != NULL); cc->cc_end = src; } @@ -655,41 +631,39 @@ htsmsg_xml_parse_cd0 /** * */ -static char * -htsmsg_xml_parse_cd(xmlparser_t *xp, htsmsg_t *parent, char *src) -{ +static char* htsmsg_xml_parse_cd(xmlparser_t* xp, htsmsg_t* parent, char* src) { struct cdata_content_queue ccq; - htsmsg_field_t *f; - cdata_content_t *cc; - int c = 0, l, y = 0; - char *x, *body; - htsmsg_t *tags = htsmsg_create_map(); - + htsmsg_field_t* f; + cdata_content_t* cc; + int c = 0, l, y = 0; + char * x, *body; + htsmsg_t* tags = htsmsg_create_map(); + TAILQ_INIT(&ccq); src = htsmsg_xml_parse_cd0(xp, &ccq, tags, NULL, src, 0); /* Assemble body */ - TAILQ_FOREACH(cc, &ccq, cc_link) { + TAILQ_FOREACH (cc, &ccq, cc_link) { - switch(cc->cc_encoding) { - case XML_ENCODING_UTF8: - c += cc->cc_end - cc->cc_start; - y++; - break; + switch (cc->cc_encoding) { + case XML_ENCODING_UTF8: + c += cc->cc_end - cc->cc_start; + y++; + break; - case XML_ENCODING_8859_1: - l = 0; - for(x = cc->cc_start; x < cc->cc_end; x++) - l += 1 + (*x >= 0x80); + case XML_ENCODING_8859_1: + l = 0; + for (x = cc->cc_start; x < cc->cc_end; x++) + l += 1 + (*x >= 0x80); - c += l; - y += 1 + (l != cc->cc_end - cc->cc_start); - break; + c += l; + y += 1 + (l != cc->cc_end - cc->cc_start); + break; } } - if(y == 1 && c > 0) { + if (y == 1 && c > 0) { /* One segment UTF-8 (or 7bit ASCII), use data directly from source */ @@ -697,54 +671,53 @@ htsmsg_xml_parse_cd(xmlparser_t *xp, htsmsg_t *parent, char *src) assert(cc != NULL); assert(TAILQ_NEXT(cc, cc_link) == NULL); - - f = htsmsg_field_add(parent, "cdata", HMF_STR, 0, 0); - f->hmf_str = cc->cc_start; + + f = htsmsg_field_add(parent, "cdata", HMF_STR, 0, 0); + f->hmf_str = cc->cc_start; *cc->cc_end = 0; free(cc); - } else if(c > 0) { + } else if (c > 0) { body = malloc(c + 1); - c = 0; + c = 0; - while((cc = TAILQ_FIRST(&ccq)) != NULL) { + while ((cc = TAILQ_FIRST(&ccq)) != NULL) { - switch(cc->cc_encoding) { - case XML_ENCODING_UTF8: - l = cc->cc_end - cc->cc_start; - memcpy(body + c, cc->cc_start, l); - c += l; - break; + switch (cc->cc_encoding) { + case XML_ENCODING_UTF8: + l = cc->cc_end - cc->cc_start; + memcpy(body + c, cc->cc_start, l); + c += l; + break; - case XML_ENCODING_8859_1: - for(x = cc->cc_start; x < cc->cc_end; x++) - c += put_utf8(body + c, *x); - break; + case XML_ENCODING_8859_1: + for (x = cc->cc_start; x < cc->cc_end; x++) + c += put_utf8(body + c, *x); + break; } - + TAILQ_REMOVE(&ccq, cc, cc_link); free(cc); } body[c] = 0; - f = htsmsg_field_add(parent, "cdata", HMF_STR, HMF_ALLOCED, 0); + f = htsmsg_field_add(parent, "cdata", HMF_STR, HMF_ALLOCED, 0); f->hmf_str = body; } else { - while((cc = TAILQ_FIRST(&ccq)) != NULL) { + while ((cc = TAILQ_FIRST(&ccq)) != NULL) { TAILQ_REMOVE(&ccq, cc, cc_link); free(cc); } } - - if(src == NULL) { + if (src == NULL) { htsmsg_destroy(tags); return NULL; } - if(TAILQ_FIRST(&tags->hm_fields) != NULL) { + if (TAILQ_FIRST(&tags->hm_fields) != NULL) { htsmsg_add_msg_extname(parent, "tags", tags); } else { htsmsg_destroy(tags); @@ -756,50 +729,46 @@ htsmsg_xml_parse_cd(xmlparser_t *xp, htsmsg_t *parent, char *src) /** * */ -static char * -htsmsg_parse_prolog(xmlparser_t *xp, char *src) -{ - htsmsg_t *pis = htsmsg_create_map(); - htsmsg_t *xmlpi; - const char *encoding; +static char* htsmsg_parse_prolog(xmlparser_t* xp, char* src) { + htsmsg_t* pis = htsmsg_create_map(); + htsmsg_t* xmlpi; + const char* encoding; - while(src != NULL && *src != 0) { + while (src != NULL && *src != 0) { - while(is_xmlws(*src)) + while (is_xmlws(*src)) src++; - - if(!strncmp(src, "') { - src++; - break; - } - src++; + if (!strncmp(src, "') { + src++; + break; + } + src++; } continue; } break; } - if((xmlpi = htsmsg_get_map(pis, "xml")) != NULL) { + if ((xmlpi = htsmsg_get_map(pis, "xml")) != NULL) { - if((encoding = htsmsg_get_str(xmlpi, "encoding")) != NULL) { - if(!strcasecmp(encoding, "iso-8859-1") || - !strcasecmp(encoding, "iso-8859_1") || - !strcasecmp(encoding, "iso_8859-1") || - !strcasecmp(encoding, "iso_8859_1")) { - xp->xp_encoding = XML_ENCODING_8859_1; + if ((encoding = htsmsg_get_str(xmlpi, "encoding")) != NULL) { + if (!strcasecmp(encoding, "iso-8859-1") || !strcasecmp(encoding, "iso-8859_1") || + !strcasecmp(encoding, "iso_8859-1") || !strcasecmp(encoding, "iso_8859_1")) { + xp->xp_encoding = XML_ENCODING_8859_1; } } } @@ -812,33 +781,31 @@ htsmsg_parse_prolog(xmlparser_t *xp, char *src) /** * */ -htsmsg_t * -htsmsg_xml_deserialize(char *src, char *errbuf, size_t errbufsize) -{ - htsmsg_t *m; +htsmsg_t* htsmsg_xml_deserialize(char* src, char* errbuf, size_t errbufsize) { + htsmsg_t* m; xmlparser_t xp; - char *src0 = src; + char* src0 = src; memset(&xp, 0, sizeof(xp)); xp.xp_encoding = XML_ENCODING_UTF8; LIST_INIT(&xp.xp_namespaces); /* check for UTF-8 BOM */ - if(src[0] == 0xef && src[1] == 0xbb && src[2] == 0xbf) + if (src[0] == 0xef && src[1] == 0xbb && src[2] == 0xbf) memmove(src, src + 3, strlen(src) - 2); - if((src = htsmsg_parse_prolog(&xp, src)) == NULL) + if ((src = htsmsg_parse_prolog(&xp, src)) == NULL) goto err; m = htsmsg_create_map(); - if(htsmsg_xml_parse_cd(&xp, m, src) == NULL) { + if (htsmsg_xml_parse_cd(&xp, m, src) == NULL) { htsmsg_destroy(m); goto err; } - if(xp.xp_srcdataused) { - m->hm_data = src0; + if (xp.xp_srcdataused) { + m->hm_data = src0; m->hm_data_size = strlen(src0) + 1; } else { free(src0); @@ -846,12 +813,12 @@ htsmsg_xml_deserialize(char *src, char *errbuf, size_t errbufsize) return m; - err: +err: free(src0); snprintf(errbuf, errbufsize, "%s", xp.xp_errmsg); - + /* Remove any odd chars inside of errmsg */ - for ( ; *errbuf; errbuf++) + for (; *errbuf; errbuf++) if (*errbuf < ' ') *errbuf = ' '; @@ -861,11 +828,9 @@ htsmsg_xml_deserialize(char *src, char *errbuf, size_t errbufsize) /* * Get cdata string field */ -const char * -htsmsg_xml_get_cdata_str(htsmsg_t *tags, const char *name) -{ - htsmsg_t *sub; - if((sub = htsmsg_get_map(tags, name)) == NULL) +const char* htsmsg_xml_get_cdata_str(htsmsg_t* tags, const char* name) { + htsmsg_t* sub; + if ((sub = htsmsg_get_map(tags, name)) == NULL) return NULL; return htsmsg_get_str(sub, "cdata"); } @@ -873,11 +838,9 @@ htsmsg_xml_get_cdata_str(htsmsg_t *tags, const char *name) /* * Get cdata u32 field */ -int -htsmsg_xml_get_cdata_u32(htsmsg_t *tags, const char *name, uint32_t *u32) -{ - htsmsg_t *sub; - if((sub = htsmsg_get_map(tags, name)) == NULL) +int htsmsg_xml_get_cdata_u32(htsmsg_t* tags, const char* name, uint32_t* u32) { + htsmsg_t* sub; + if ((sub = htsmsg_get_map(tags, name)) == NULL) return HTSMSG_ERR_FIELD_NOT_FOUND; return htsmsg_get_u32(sub, "cdata", u32); } @@ -885,18 +848,16 @@ htsmsg_xml_get_cdata_u32(htsmsg_t *tags, const char *name, uint32_t *u32) /* * Get tag attribute */ -const char * -htsmsg_xml_get_attr_str(htsmsg_t *tag, const char *name) -{ - htsmsg_t *attr = htsmsg_get_map(tag, "attrib"); - if (attr) return htsmsg_get_str(attr, name); +const char* htsmsg_xml_get_attr_str(htsmsg_t* tag, const char* name) { + htsmsg_t* attr = htsmsg_get_map(tag, "attrib"); + if (attr) + return htsmsg_get_str(attr, name); return NULL; } -int -htsmsg_xml_get_attr_u32(htsmsg_t *tag, const char *name, uint32_t *ret) -{ - htsmsg_t *attr = htsmsg_get_map(tag, "attrib"); - if (attr) return htsmsg_get_u32(attr, name, ret); +int htsmsg_xml_get_attr_u32(htsmsg_t* tag, const char* name, uint32_t* ret) { + htsmsg_t* attr = htsmsg_get_map(tag, "attrib"); + if (attr) + return htsmsg_get_u32(attr, name, ret); return HTSMSG_ERR_FIELD_NOT_FOUND; } diff --git a/src/htsmsg_xml.h b/src/htsmsg_xml.h index c4d4f29dc..c12b2cd08 100644 --- a/src/htsmsg_xml.h +++ b/src/htsmsg_xml.h @@ -22,10 +22,10 @@ #include "htsmsg.h" #include "htsbuf.h" -htsmsg_t *htsmsg_xml_deserialize(char *src, char *errbuf, size_t errbufsize); -const char *htsmsg_xml_get_cdata_str (htsmsg_t *tags, const char *tag); -int htsmsg_xml_get_cdata_u32 (htsmsg_t *tags, const char *tag, uint32_t *u32); -const char *htsmsg_xml_get_attr_str(htsmsg_t *tag, const char *attr); -int htsmsg_xml_get_attr_u32(htsmsg_t *tag, const char *attr, uint32_t *u32); +htsmsg_t* htsmsg_xml_deserialize(char* src, char* errbuf, size_t errbufsize); +const char* htsmsg_xml_get_cdata_str(htsmsg_t* tags, const char* tag); +int htsmsg_xml_get_cdata_u32(htsmsg_t* tags, const char* tag, uint32_t* u32); +const char* htsmsg_xml_get_attr_str(htsmsg_t* tag, const char* attr); +int htsmsg_xml_get_attr_u32(htsmsg_t* tag, const char* attr, uint32_t* u32); #endif /* HTSMSG_XML_H_ */ diff --git a/src/htsp_server.c b/src/htsp_server.c index 7102a9a87..1ced2663c 100644 --- a/src/htsp_server.c +++ b/src/htsp_server.c @@ -43,7 +43,7 @@ #endif #include "settings.h" -#include "epggrab.h" //Needed to be able to test for epggrab_conf.epgdb_processparentallabels +#include "epggrab.h" //Needed to be able to test for epggrab_conf.epgdb_processparentallabels /* ************************************************************************** * Datatypes and variables @@ -53,15 +53,15 @@ static void *htsp_server, *htsp_server_2; #define HTSP_PROTO_VERSION 37 -#define HTSP_ASYNC_OFF 0x00 -#define HTSP_ASYNC_ON 0x01 -#define HTSP_ASYNC_EPG 0x02 +#define HTSP_ASYNC_OFF 0x00 +#define HTSP_ASYNC_ON 0x01 +#define HTSP_ASYNC_EPG 0x02 #define HTSP_ASYNC_EPG_INTERVAL 30 #define HTSP_PRIV_MASK (ACCESS_HTSP_STREAMING) -extern char *dvr_storage; +extern char* dvr_storage; LIST_HEAD(htsp_connection_list, htsp_connection); LIST_HEAD(htsp_subscription_list, htsp_subscription); @@ -73,15 +73,13 @@ TAILQ_HEAD(htsp_msg_q_queue, htsp_msg_q); static struct htsp_connection_list htsp_async_connections; static struct htsp_connection_list htsp_connections; -static void htsp_streaming_input(void *opaque, streaming_message_t *sm); -static htsmsg_t *htsp_streaming_input_info(void *opaque, htsmsg_t *list); -const char * _htsp_get_subscription_status(int smcode); -static void htsp_epg_send_waiting(struct htsp_connection *, int64_t mintime); +static void htsp_streaming_input(void* opaque, streaming_message_t* sm); +static htsmsg_t* htsp_streaming_input_info(void* opaque, htsmsg_t* list); +const char* _htsp_get_subscription_status(int smcode); +static void htsp_epg_send_waiting(struct htsp_connection*, int64_t mintime); -static streaming_ops_t htsp_streaming_input_ops = { - .st_cb = htsp_streaming_input, - .st_info = htsp_streaming_input_info -}; +static streaming_ops_t htsp_streaming_input_ops = {.st_cb = htsp_streaming_input, + .st_info = htsp_streaming_input_info}; /** * @@ -89,17 +87,16 @@ static streaming_ops_t htsp_streaming_input_ops = { typedef struct htsp_msg { TAILQ_ENTRY(htsp_msg) hm_link; - htsmsg_t *hm_msg; - int hm_payloadsize; /* For maintaining stats about streaming - buffer depth */ + htsmsg_t* hm_msg; + int hm_payloadsize; /* For maintaining stats about streaming + buffer depth */ - pktbuf_t *hm_pb; /* For keeping reference to packet payload. - hm_msg can contain messages that points - to packet payload so to avoid copy we - keep a reference here */ + pktbuf_t* hm_pb; /* For keeping reference to packet payload. + hm_msg can contain messages that points + to packet payload so to avoid copy we + keep a reference here */ } htsp_msg_t; - /** * */ @@ -107,9 +104,9 @@ typedef struct htsp_msg_q { struct htsp_msg_queue hmq_q; TAILQ_ENTRY(htsp_msg_q) hmq_link; - int hmq_strict_prio; /* Serve this queue 'til it's empty */ + int hmq_strict_prio; /* Serve this queue 'til it's empty */ int hmq_length; - int hmq_payload; /* Bytes of streaming payload that's enqueued */ + int hmq_payload; /* Bytes of streaming payload that's enqueued */ int hmq_dead; } htsp_msg_q_t; @@ -119,20 +116,20 @@ typedef struct htsp_msg_q { typedef struct htsp_connection { LIST_ENTRY(htsp_connection) htsp_link; - int htsp_fd; - struct sockaddr_storage *htsp_peer; + int htsp_fd; + struct sockaddr_storage* htsp_peer; uint32_t htsp_version; - char *htsp_logname; - char *htsp_peername; - char *htsp_username; - char *htsp_clientname; - char *htsp_language; // for async updates + char* htsp_logname; + char* htsp_peername; + char* htsp_username; + char* htsp_clientname; + char* htsp_language; // for async updates - int64_t htsp_epg_window; // only send async epg updates within this window (seconds) - int64_t htsp_epg_lastupdate; // last update time for async epg events - mtimer_t htsp_epg_timer; // timer for async epg updates + int64_t htsp_epg_window; // only send async epg updates within this window (seconds) + int64_t htsp_epg_lastupdate; // last update time for async epg events + mtimer_t htsp_epg_timer; // timer for async epg updates /** * Async mode @@ -150,7 +147,7 @@ typedef struct htsp_connection { struct htsp_msg_q_queue htsp_active_output_queues; tvh_mutex_t htsp_out_mutex; - tvh_cond_t htsp_out_cond; + tvh_cond_t htsp_out_cond; htsp_msg_q_t htsp_hmq_ctrl; htsp_msg_q_t htsp_hmq_epg; @@ -158,27 +155,26 @@ typedef struct htsp_connection { struct htsp_subscription_list htsp_subscriptions; struct htsp_subscription_list htsp_dead_subscriptions; - struct htsp_file_list htsp_files; - int htsp_file_id; + struct htsp_file_list htsp_files; + int htsp_file_id; - access_t *htsp_granted_access; + access_t* htsp_granted_access; uint8_t htsp_challenge[32]; } htsp_connection_t; - /** * */ typedef struct htsp_subscription { - htsp_connection_t *hs_htsp; + htsp_connection_t* hs_htsp; LIST_ENTRY(htsp_subscription) hs_link; - int hs_sid; /* Subscription ID (set by client) */ + int hs_sid; /* Subscription ID (set by client) */ - th_subscription_t *hs_s; // Temporary + th_subscription_t* hs_s; // Temporary int hs_s_bytes_out; mtimer_t hs_s_bytes_out_timer; @@ -197,7 +193,7 @@ typedef struct htsp_subscription { int hs_queue_depth; -#define NUM_FILTERED_STREAMS (64*8) +#define NUM_FILTERED_STREAMS (64 * 8) uint64_t hs_filtered_streams[8]; // one bit per stream @@ -207,17 +203,16 @@ typedef struct htsp_subscription { } htsp_subscription_t; - /** * */ typedef struct htsp_file { LIST_ENTRY(htsp_file) hf_link; - int hf_id; // ID sent to client - int hf_fd; // Our file descriptor - char *hf_path; // For logging - uint32_t hf_de_id; // Associated dvr entry - th_subscription_t *hf_subscription; + int hf_id; // ID sent to client + int hf_fd; // Our file descriptor + char* hf_path; // For logging + uint32_t hf_de_id; // Associated dvr entry + th_subscription_t* hf_subscription; } htsp_file_t; #define HTSP_DEFAULT_QUEUE_DEPTH 500000 @@ -226,12 +221,9 @@ typedef struct htsp_file { * Support routines * *************************************************************************/ -static void -htsp_trace(htsp_connection_t *htsp, int subsystem, - const char *prefix, htsmsg_t *m) -{ +static void htsp_trace(htsp_connection_t* htsp, int subsystem, const char* prefix, htsmsg_t* m) { htsbuf_queue_t q; - char *s; + char* s; htsbuf_queue_init(&q, 0); htsmsg_json_serialize(m, &q, 0); s = htsbuf_to_string(&q); @@ -240,51 +232,41 @@ htsp_trace(htsp_connection_t *htsp, int subsystem, free(s); } -static void -htsp_disable_stream(htsp_subscription_t *hs, unsigned int id) -{ - if(id < NUM_FILTERED_STREAMS) +static void htsp_disable_stream(htsp_subscription_t* hs, unsigned int id) { + if (id < NUM_FILTERED_STREAMS) hs->hs_filtered_streams[id / 64] |= 1 << (id & 63); } - -static void -htsp_enable_stream(htsp_subscription_t *hs, unsigned int id) -{ - if(id < NUM_FILTERED_STREAMS) +static void htsp_enable_stream(htsp_subscription_t* hs, unsigned int id) { + if (id < NUM_FILTERED_STREAMS) hs->hs_filtered_streams[id / 64] &= ~(1 << (id & 63)); } - -static inline int -htsp_is_stream_enabled(htsp_subscription_t *hs, unsigned int id) -{ - if(id < NUM_FILTERED_STREAMS) +static inline int htsp_is_stream_enabled(htsp_subscription_t* hs, unsigned int id) { + if (id < NUM_FILTERED_STREAMS) return !(hs->hs_filtered_streams[id / 64] & (1 << (id & 63))); return 1; } -static inline int -htsp_anonymize(htsp_connection_t *htsp) -{ +static inline int htsp_anonymize(htsp_connection_t* htsp) { return (htsp->htsp_granted_access->aa_rights & ACCESS_HTSP_ANONYMIZE) != 0; } /** * */ -static void -htsp_update_logname(htsp_connection_t *htsp) -{ +static void htsp_update_logname(htsp_connection_t* htsp) { char buf[100]; - snprintf(buf, sizeof(buf), "%s%s%s%s%s%s", - htsp->htsp_peername, - htsp->htsp_username || htsp->htsp_clientname ? " [ " : "", - htsp->htsp_username ?: "", - htsp->htsp_username && htsp->htsp_clientname ? " | " : "", - htsp->htsp_clientname ?: "", - htsp->htsp_username || htsp->htsp_clientname ? " ]" : ""); + snprintf(buf, + sizeof(buf), + "%s%s%s%s%s%s", + htsp->htsp_peername, + htsp->htsp_username || htsp->htsp_clientname ? " [ " : "", + htsp->htsp_username ?: "", + htsp->htsp_username && htsp->htsp_clientname ? " | " : "", + htsp->htsp_clientname ?: "", + htsp->htsp_username || htsp->htsp_clientname ? " ]" : ""); tvh_str_update(&htsp->htsp_logname, buf); } @@ -292,11 +274,9 @@ htsp_update_logname(htsp_connection_t *htsp) /** * */ -static void -htsp_msg_destroy(htsp_msg_t *hm) -{ +static void htsp_msg_destroy(htsp_msg_t* hm) { htsmsg_destroy(hm->hm_msg); - if(hm->hm_pb != NULL) + if (hm->hm_pb != NULL) pktbuf_ref_dec(hm->hm_pb); free(hm); } @@ -304,65 +284,61 @@ htsp_msg_destroy(htsp_msg_t *hm) /** * */ -static void -htsp_init_queue(htsp_msg_q_t *hmq, int strict_prio) -{ +static void htsp_init_queue(htsp_msg_q_t* hmq, int strict_prio) { TAILQ_INIT(&hmq->hmq_q); - hmq->hmq_length = 0; + hmq->hmq_length = 0; hmq->hmq_strict_prio = strict_prio; } /** * */ -static void -htsp_flush_queue(htsp_connection_t *htsp, htsp_msg_q_t *hmq, int dead) -{ - htsp_msg_t *hm; +static void htsp_flush_queue(htsp_connection_t* htsp, htsp_msg_q_t* hmq, int dead) { + htsp_msg_t* hm; tvh_mutex_lock(&htsp->htsp_out_mutex); - if(hmq->hmq_length) + if (hmq->hmq_length) TAILQ_REMOVE(&htsp->htsp_active_output_queues, hmq, hmq_link); - while((hm = TAILQ_FIRST(&hmq->hmq_q)) != NULL) { + while ((hm = TAILQ_FIRST(&hmq->hmq_q)) != NULL) { TAILQ_REMOVE(&hmq->hmq_q, hm, hm_link); htsp_msg_destroy(hm); } // reset - hmq->hmq_length = 0; + hmq->hmq_length = 0; hmq->hmq_payload = 0; - hmq->hmq_dead = dead; + hmq->hmq_dead = dead; tvh_mutex_unlock(&htsp->htsp_out_mutex); } /* * */ -static const char * -htsp_image(htsp_connection_t *htsp, const char *image, - char *buf, size_t buflen, int version) -{ - const char *ret = image; - const int id = imagecache_get_id(image); +static const char* +htsp_image(htsp_connection_t* htsp, const char* image, char* buf, size_t buflen, int version) { + const char* ret = image; + const int id = imagecache_get_id(image); /* Handle older clients */ if (id) { if (htsp->htsp_version < version) { struct sockaddr_storage addr; - socklen_t addrlen; - char abuf[50]; + socklen_t addrlen; + char abuf[50]; addrlen = sizeof(addr); getsockname(htsp->htsp_fd, (struct sockaddr*)&addr, &addrlen); tcp_get_str_from_ip(&addr, abuf, sizeof(abuf)); - snprintf(buf, buflen, "http://%s%s%s:%d%s/imagecache/%d", - (addr.ss_family == AF_INET6)?"[":"", - abuf, - (addr.ss_family == AF_INET6)?"]":"", - tvheadend_webui_port, - tvheadend_webroot ?: "", - id); + snprintf(buf, + buflen, + "http://%s%s%s:%d%s/imagecache/%d", + (addr.ss_family == AF_INET6) ? "[" : "", + abuf, + (addr.ss_family == AF_INET6) ? "]" : "", + tvheadend_webui_port, + tvheadend_webroot ?: "", + id); ret = buf; } else if (htsp->htsp_version < 15) { /* older clients expects '/imagecache/' */ @@ -379,10 +355,8 @@ htsp_image(htsp_connection_t *htsp, const char *image, /** * */ -static void -htsp_subscription_destroy(htsp_connection_t *htsp, htsp_subscription_t *hs) -{ - th_subscription_t *ts = hs->hs_s; +static void htsp_subscription_destroy(htsp_connection_t* htsp, htsp_subscription_t* hs) { + th_subscription_t* ts = hs->hs_s; hs->hs_s = NULL; mtimer_disarm(&hs->hs_s_bytes_out_timer); @@ -392,7 +366,7 @@ htsp_subscription_destroy(htsp_connection_t *htsp, htsp_subscription_t *hs) subscription_unsubscribe(ts, UNSUBSCRIBE_FINAL); - if(hs->hs_prch.prch_st != NULL) + if (hs->hs_prch.prch_st != NULL) profile_chain_close(&hs->hs_prch); htsp_flush_queue(htsp, &hs->hs_q, 1); @@ -401,9 +375,7 @@ htsp_subscription_destroy(htsp_connection_t *htsp, htsp_subscription_t *hs) /** * */ -static void -htsp_subscription_free(htsp_connection_t *htsp, htsp_subscription_t *hs) -{ +static void htsp_subscription_free(htsp_connection_t* htsp, htsp_subscription_t* hs) { LIST_REMOVE(hs, hs_link); htsp_flush_queue(htsp, &hs->hs_q, 1); free(hs); @@ -413,14 +385,12 @@ htsp_subscription_free(htsp_connection_t *htsp, htsp_subscription_t *hs) * */ static void -htsp_send(htsp_connection_t *htsp, htsmsg_t *m, pktbuf_t *pb, - htsp_msg_q_t *hmq, int payloadsize) -{ - htsp_msg_t *hm = malloc(sizeof(htsp_msg_t)); +htsp_send(htsp_connection_t* htsp, htsmsg_t* m, pktbuf_t* pb, htsp_msg_q_t* hmq, int payloadsize) { + htsp_msg_t* hm = malloc(sizeof(htsp_msg_t)); hm->hm_msg = m; - hm->hm_pb = pb; - if(pb != NULL) + hm->hm_pb = pb; + if (pb != NULL) pktbuf_ref_inc(pb); hm->hm_payloadsize = payloadsize; @@ -430,10 +400,10 @@ htsp_send(htsp_connection_t *htsp, htsmsg_t *m, pktbuf_t *pb, TAILQ_INSERT_TAIL(&hmq->hmq_q, hm, hm_link); - if(hmq->hmq_length == 0) { + if (hmq->hmq_length == 0) { /* Activate queue */ - if(hmq->hmq_strict_prio) { + if (hmq->hmq_strict_prio) { TAILQ_INSERT_HEAD(&htsp->htsp_active_output_queues, hmq, hmq_link); } else { TAILQ_INSERT_TAIL(&htsp->htsp_active_output_queues, hmq, hmq_link); @@ -449,12 +419,13 @@ htsp_send(htsp_connection_t *htsp, htsmsg_t *m, pktbuf_t *pb, /** * */ -static void -htsp_send_subscription(htsp_connection_t *htsp, htsmsg_t *m, pktbuf_t *pb, - htsp_subscription_t *hs, int payloadsize) -{ +static void htsp_send_subscription(htsp_connection_t* htsp, + htsmsg_t* m, + pktbuf_t* pb, + htsp_subscription_t* hs, + int payloadsize) { if (tvhtrace_enabled()) { - char buf[64]; + char buf[64]; size_t l = 0; tvh_strlcatf(buf, sizeof(buf), l, "subscription %i", hs->hs_sid); if (payloadsize) @@ -468,11 +439,9 @@ htsp_send_subscription(htsp_connection_t *htsp, htsmsg_t *m, pktbuf_t *pb, /** * */ -static void -htsp_send_message(htsp_connection_t *htsp, htsmsg_t *m, htsp_msg_q_t *hmq) -{ +static void htsp_send_message(htsp_connection_t* htsp, htsmsg_t* m, htsp_msg_q_t* hmq) { if (tvhtrace_enabled()) { - const char *qname = "answer"; + const char* qname = "answer"; if (hmq == &htsp->htsp_hmq_qstatus) qname = "status"; htsp_trace(htsp, LS_HTSP_ANS, qname, m); @@ -484,10 +453,8 @@ htsp_send_message(htsp_connection_t *htsp, htsmsg_t *m, htsp_msg_q_t *hmq) /** * Simple function to respond with an error */ -static htsmsg_t * -htsp_error(htsp_connection_t *htsp, const char *errstr) -{ - htsmsg_t *r = htsmsg_create_map(); +static htsmsg_t* htsp_error(htsp_connection_t* htsp, const char* errstr) { + htsmsg_t* r = htsmsg_create_map(); htsmsg_add_str(r, "error", tvh_gettext_lang(htsp->htsp_language, errstr)); return r; } @@ -495,10 +462,8 @@ htsp_error(htsp_connection_t *htsp, const char *errstr) /** * Simple function to respond with an success */ -static htsmsg_t * -htsp_success(void) -{ - htsmsg_t *r = htsmsg_create_map(); +static htsmsg_t* htsp_success(void) { + htsmsg_t* r = htsmsg_create_map(); htsmsg_add_u32(r, "success", 1); return r; } @@ -506,12 +471,10 @@ htsp_success(void) /** * */ -static void -htsp_reply(htsp_connection_t *htsp, htsmsg_t *in, htsmsg_t *out) -{ +static void htsp_reply(htsp_connection_t* htsp, htsmsg_t* in, htsmsg_t* out) { uint32_t seq; - if(!htsmsg_get_u32(in, "seq", &seq)) + if (!htsmsg_get_u32(in, "seq", &seq)) htsmsg_add_u32(out, "seq", seq); htsp_send_message(htsp, out, NULL); @@ -520,12 +483,10 @@ htsp_reply(htsp_connection_t *htsp, htsmsg_t *in, htsmsg_t *out) /** * Update challenge */ -static int -htsp_generate_challenge(htsp_connection_t *htsp) -{ +static int htsp_generate_challenge(htsp_connection_t* htsp) { int fd, n; - if((fd = tvh_open("/dev/urandom", O_RDONLY, 0)) < 0) + if ((fd = tvh_open("/dev/urandom", O_RDONLY, 0)) < 0) return -1; n = read(fd, &htsp->htsp_challenge, 32); @@ -536,24 +497,21 @@ htsp_generate_challenge(htsp_connection_t *htsp) /** * Check if user can access the channel */ -static inline int -htsp_user_access_channel(htsp_connection_t *htsp, channel_t *ch) -{ - if (!ch || !ch->ch_enabled || LIST_FIRST(&ch->ch_services) == NULL) /* Don't pass unplayable channels to clients */ +static inline int htsp_user_access_channel(htsp_connection_t* htsp, channel_t* ch) { + if (!ch || !ch->ch_enabled || + LIST_FIRST(&ch->ch_services) == NULL) /* Don't pass unplayable channels to clients */ return 0; if (!htsp) return 1; return channel_access(ch, htsp->htsp_granted_access, 0); } -static const char * -htsp_dvr_config_name( htsp_connection_t *htsp, const char *config_name ) -{ - dvr_config_t *cfg = NULL, *cfg2; - access_t *perm = htsp->htsp_granted_access; - htsmsg_field_t *f; - const char *uuid; - static char ubuf[UUID_HEX_SIZE]; +static const char* htsp_dvr_config_name(htsp_connection_t* htsp, const char* config_name) { + dvr_config_t * cfg = NULL, *cfg2; + access_t* perm = htsp->htsp_granted_access; + htsmsg_field_t* f; + const char* uuid; + static char ubuf[UUID_HEX_SIZE]; lock_assert(&global_lock); @@ -574,7 +532,9 @@ htsp_dvr_config_name( htsp_connection_t *htsp, const char *config_name ) } if (!cfg && perm->aa_username) - tvhinfo(LS_HTSP, "User '%s' has no valid dvr config in ACL, using default...", perm->aa_username); + tvhinfo(LS_HTSP, + "User '%s' has no valid dvr config in ACL, using default...", + perm->aa_username); return cfg ? idnode_uuid_as_str(&cfg->dvr_id, ubuf) : NULL; } @@ -587,43 +547,42 @@ htsp_dvr_config_name( htsp_connection_t *htsp, const char *config_name ) * @param add, true for new instances, false for update calls * @return the htsmsg_t config to be added or updated with idnode */ -static htsmsg_t * -htsp_serierec_convert(htsp_connection_t *htsp, htsmsg_t *in, channel_t *ch, int autorec, int add) -{ - htsmsg_t *conf,*days; - uint32_t u32; - int64_t s64; - int32_t approx_time, start, start_window, s32; - int retval; - const char *str; - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* +htsp_serierec_convert(htsp_connection_t* htsp, htsmsg_t* in, channel_t* ch, int autorec, int add) { + htsmsg_t * conf, *days; + uint32_t u32; + int64_t s64; + int32_t approx_time, start, start_window, s32; + int retval; + const char* str; + char ubuf[UUID_HEX_SIZE]; conf = htsmsg_create_map(); if (autorec) { // autorec specific if (!(retval = htsmsg_get_u32(in, "minduration", &u32)) || add) - htsmsg_add_u32(conf, "minduration", !retval ? u32 : 0); // 0 = any + htsmsg_add_u32(conf, "minduration", !retval ? u32 : 0); // 0 = any if (!(retval = htsmsg_get_u32(in, "maxduration", &u32)) || add) - htsmsg_add_u32(conf, "maxduration", !retval ? u32 : 0); // 0 = any + htsmsg_add_u32(conf, "maxduration", !retval ? u32 : 0); // 0 = any if (!(retval = htsmsg_get_u32(in, "fulltext", &u32)) || add) - htsmsg_add_u32(conf, "fulltext", !retval ? u32 : 0); // 0 = off + htsmsg_add_u32(conf, "fulltext", !retval ? u32 : 0); // 0 = off if (!(retval = htsmsg_get_u32(in, "dupDetect", &u32)) || add) htsmsg_add_u32(conf, "record", !retval ? u32 : DVR_AUTOREC_RECORD_ALL); if (!(retval = htsmsg_get_u32(in, "maxCount", &u32)) || add) - htsmsg_add_u32(conf, "maxcount", !retval ? u32 : 0); // 0 = unlimited + htsmsg_add_u32(conf, "maxcount", !retval ? u32 : 0); // 0 = unlimited if (!(retval = htsmsg_get_s64(in, "startExtra", &s64)) || add) - htsmsg_add_s64(conf, "start_extra", !retval ? (s64 < 0 ? 0 : s64) : 0); // 0 = dvr config + htsmsg_add_s64(conf, "start_extra", !retval ? (s64 < 0 ? 0 : s64) : 0); // 0 = dvr config if (!(retval = htsmsg_get_s64(in, "stopExtra", &s64)) || add) - htsmsg_add_s64(conf, "stop_extra", !retval ? (s64 < 0 ? 0 : s64) : 0); // 0 = dvr config + htsmsg_add_s64(conf, "stop_extra", !retval ? (s64 < 0 ? 0 : s64) : 0); // 0 = dvr config if ((str = htsmsg_get_str(in, "serieslinkUri")) || add) htsmsg_add_str(conf, "serieslink", str ?: ""); if (add) { // for add, stay compatible with older "approxTime - if(htsmsg_get_s32(in, "approxTime", &approx_time)) + if (htsmsg_get_s32(in, "approxTime", &approx_time)) approx_time = -1; - if(htsmsg_get_s32(in, "start", &start)) + if (htsmsg_get_s32(in, "start", &start)) start = -1; - if(htsmsg_get_s32(in, "startWindow", &start_window)) + if (htsmsg_get_s32(in, "startWindow", &start_window)) start_window = -1; if (start < 0 || start_window < 0) start = start_window = -1; @@ -636,16 +595,16 @@ htsp_serierec_convert(htsp_connection_t *htsp, htsmsg_t *in, channel_t *ch, int start_window -= 24 * 60; } htsmsg_add_s32(conf, "start", start >= 0 ? start : -1); // -1 = any time - htsmsg_add_s32(conf, "start_window", start_window >= 0 ? start_window : -1); // -1 = any duration - } - else { // for update, we don't care about "approxTime" - if(!htsmsg_get_s32(in, "start", &s32)) - htsmsg_add_s32(conf, "start", s32 >= 0 ? s32 : -1); // -1 = any time - if(!htsmsg_get_s32(in, "startWindow", &s32)) + htsmsg_add_s32(conf, + "start_window", + start_window >= 0 ? start_window : -1); // -1 = any duration + } else { // for update, we don't care about "approxTime" + if (!htsmsg_get_s32(in, "start", &s32)) + htsmsg_add_s32(conf, "start", s32 >= 0 ? s32 : -1); // -1 = any time + if (!htsmsg_get_s32(in, "startWindow", &s32)) htsmsg_add_s32(conf, "start_window", s32 >= 0 ? s32 : -1); // -1 = any duration } - } - else { //timerec specific + } else { // timerec specific if (!(retval = htsmsg_get_u32(in, "start", &u32)) || add) htsmsg_add_u32(conf, "start", !retval ? u32 : 0); if (!(retval = htsmsg_get_u32(in, "stop", &u32)) || add) @@ -658,7 +617,7 @@ htsp_serierec_convert(htsp_connection_t *htsp, htsmsg_t *in, channel_t *ch, int htsmsg_add_u32(conf, "retention", !retval ? u32 : DVR_RET_REM_DVRCONFIG); if (!(retval = htsmsg_get_u32(in, "removal", &u32)) || add) htsmsg_add_u32(conf, "removal", !retval ? u32 : DVR_RET_REM_DVRCONFIG); - if(!(retval = htsmsg_get_u32(in, "priority", &u32)) || add) + if (!(retval = htsmsg_get_u32(in, "priority", &u32)) || add) htsmsg_add_u32(conf, "pri", !retval ? u32 : DVR_PRIO_DEFAULT); if ((str = htsmsg_get_str(in, "name")) || add) htsmsg_add_str(conf, "name", str ?: ""); @@ -666,14 +625,14 @@ htsp_serierec_convert(htsp_connection_t *htsp, htsmsg_t *in, channel_t *ch, int htsmsg_add_str(conf, "comment", str ?: ""); if ((str = htsmsg_get_str(in, "directory")) || add) htsmsg_add_str(conf, "directory", str ?: ""); - if((str = htsmsg_get_str(in, "title")) || add) + if ((str = htsmsg_get_str(in, "title")) || add) htsmsg_add_str(conf, "title", str ?: ""); /* Only on creation */ if (add) { str = htsp_dvr_config_name(htsp, htsmsg_get_str(in, "configName")); htsmsg_add_str(conf, "config_name", str ?: ""); - htsmsg_add_str2(conf, "owner", htsp->htsp_granted_access->aa_username); + htsmsg_add_str2(conf, "owner", htsp->htsp_granted_access->aa_username); htsmsg_add_str2(conf, "creator", htsp->htsp_granted_access->aa_representative); } else { str = htsmsg_get_str(in, "configName"); @@ -684,13 +643,13 @@ htsp_serierec_convert(htsp_connection_t *htsp, htsmsg_t *in, channel_t *ch, int } /* Weekdays only if present */ - if(!(retval = htsmsg_get_u32(in, "daysOfWeek", &u32))) { + if (!(retval = htsmsg_get_u32(in, "daysOfWeek", &u32))) { days = htsmsg_create_list(); int i; for (i = 0; i < 7; i++) if (u32 & (1 << i)) htsmsg_add_u32(days, NULL, i + 1); - htsmsg_add_msg(conf, "weekdays", days); // not set = all days + htsmsg_add_msg(conf, "weekdays", days); // not set = all days } /* Allow channel to be cleared on update -> any channel */ @@ -704,9 +663,7 @@ htsp_serierec_convert(htsp_connection_t *htsp, htsmsg_t *in, channel_t *ch, int /* * */ -static void htsp_serialize_epnum - (htsmsg_t *out, epg_episode_num_t *epnum, const char *textname) -{ +static void htsp_serialize_epnum(htsmsg_t* out, epg_episode_num_t* epnum, const char* textname) { if (epnum->s_num) { htsmsg_add_u32(out, "seasonNumber", epnum->s_num); if (epnum->s_cnt) @@ -730,21 +687,17 @@ static void htsp_serialize_epnum * File helpers * *************************************************************************/ -static uint32_t -htsp_channel_tag_get_identifier(channel_tag_t *ct) -{ +static uint32_t htsp_channel_tag_get_identifier(channel_tag_t* ct) { static int prev = 0; if (ct->ct_htsp_id == 0) ct->ct_htsp_id = ++prev; return ct->ct_htsp_id; } -static channel_tag_t * -htsp_channel_tag_find_by_id(htsp_connection_t *htsp, uint32_t id) -{ - channel_tag_t *ct; +static channel_tag_t* htsp_channel_tag_find_by_id(htsp_connection_t* htsp, uint32_t id) { + channel_tag_t* ct; - TAILQ_FOREACH(ct, &channel_tags, ct_link) { + TAILQ_FOREACH (ct, &channel_tags, ct_link) { if (!channel_tag_access(ct, htsp->htsp_granted_access, 0)) continue; if (id == ct->ct_htsp_id) @@ -756,9 +709,8 @@ htsp_channel_tag_find_by_id(htsp_connection_t *htsp, uint32_t id) /** * */ -static htsmsg_t * -htsp_file_open(htsp_connection_t *htsp, const char *path, int fd, dvr_entry_t *de) -{ +static htsmsg_t* +htsp_file_open(htsp_connection_t* htsp, const char* path, int fd, dvr_entry_t* de) { struct stat st; if (fd <= 0) { @@ -766,32 +718,33 @@ htsp_file_open(htsp_connection_t *htsp, const char *path, int fd, dvr_entry_t *d fd = tvh_open(path, O_RDONLY, 0); tvhdebug(LS_HTSP, "Opening file %s -- %s", path, fd < 0 ? strerror(errno) : "OK"); tvh_mutex_lock(&global_lock); - if(fd == -1) + if (fd == -1) return htsp_error(htsp, N_("Unable to open file")); } - htsp_file_t *hf = calloc(1, sizeof(htsp_file_t)); - hf->hf_fd = fd; - hf->hf_id = ++htsp->htsp_file_id; - hf->hf_path = strdup(path); - hf->hf_de_id = de ? idnode_get_short_uuid(&de->de_id) : 0; + htsp_file_t* hf = calloc(1, sizeof(htsp_file_t)); + hf->hf_fd = fd; + hf->hf_id = ++htsp->htsp_file_id; + hf->hf_path = strdup(path); + hf->hf_de_id = de ? idnode_get_short_uuid(&de->de_id) : 0; if (de) { - const char *charset = de->de_config ? de->de_config->dvr_charset_id : NULL; - - hf->hf_subscription = - subscription_create_from_file("HTSP", charset, path, - htsp->htsp_peername, - htsp->htsp_granted_access->aa_representative, - htsp->htsp_clientname); + const char* charset = de->de_config ? de->de_config->dvr_charset_id : NULL; + + hf->hf_subscription = subscription_create_from_file("HTSP", + charset, + path, + htsp->htsp_peername, + htsp->htsp_granted_access->aa_representative, + htsp->htsp_clientname); } LIST_INSERT_HEAD(&htsp->htsp_files, hf, hf_link); - htsmsg_t *rep = htsmsg_create_map(); + htsmsg_t* rep = htsmsg_create_map(); htsmsg_add_u32(rep, "id", hf->hf_id); - if(!fstat(hf->hf_fd, &st)) { + if (!fstat(hf->hf_fd, &st)) { htsmsg_add_s64(rep, "size", st.st_size); htsmsg_add_s64(rep, "mtime", st.st_mtime); } @@ -802,15 +755,13 @@ htsp_file_open(htsp_connection_t *htsp, const char *path, int fd, dvr_entry_t *d /** * */ -static htsp_file_t * -htsp_file_find(const htsp_connection_t *htsp, htsmsg_t *in) -{ - htsp_file_t *hf; +static htsp_file_t* htsp_file_find(const htsp_connection_t* htsp, htsmsg_t* in) { + htsp_file_t* hf; int id = htsmsg_get_u32_or_default(in, "id", 0); - LIST_FOREACH(hf, &htsp->htsp_files, hf_link) { - if(hf->hf_id == id) + LIST_FOREACH (hf, &htsp->htsp_files, hf_link) { + if (hf->hf_id == id) return hf; } return NULL; @@ -819,9 +770,7 @@ htsp_file_find(const htsp_connection_t *htsp, htsmsg_t *in) /** * */ -static void -htsp_file_destroy(htsp_file_t *hf) -{ +static void htsp_file_destroy(htsp_file_t* hf) { tvhdebug(LS_HTSP, "Closed opened file %s", hf->hf_path); LIST_REMOVE(hf, hf_link); if (hf->hf_subscription) { @@ -834,10 +783,8 @@ htsp_file_destroy(htsp_file_t *hf) free(hf); } -static void -htsp_file_update_stats(htsp_file_t *hf, size_t len) -{ - th_subscription_t *ts = hf->hf_subscription; +static void htsp_file_update_stats(htsp_file_t* hf, size_t len) { + th_subscription_t* ts = hf->hf_subscription; if (ts) { subscription_add_bytes_in(ts, len); subscription_add_bytes_out(ts, len); @@ -851,20 +798,18 @@ htsp_file_update_stats(htsp_file_t *hf, size_t len) /** * */ -static htsmsg_t * -htsp_build_channel(channel_t *ch, const char *method, htsp_connection_t *htsp) -{ - idnode_list_mapping_t *ilm; - channel_tag_t *ct; - service_t *t; - epg_broadcast_t *now, *next = NULL; - int64_t chnum = channel_get_number(ch); - const char *icon; - char buf[512]; - - htsmsg_t *out = htsmsg_create_map(); - htsmsg_t *tags = htsmsg_create_list(); - htsmsg_t *services = htsmsg_create_list(); +static htsmsg_t* htsp_build_channel(channel_t* ch, const char* method, htsp_connection_t* htsp) { + idnode_list_mapping_t* ilm; + channel_tag_t* ct; + service_t* t; + epg_broadcast_t * now, *next = NULL; + int64_t chnum = channel_get_number(ch); + const char* icon; + char buf[512]; + + htsmsg_t* out = htsmsg_create_map(); + htsmsg_t* tags = htsmsg_create_list(); + htsmsg_t* services = htsmsg_create_list(); htsmsg_add_u32(out, "channelId", channel_get_id(ch)); htsmsg_add_u32(out, "channelNumber", channel_get_major(chnum)); @@ -880,26 +825,30 @@ htsp_build_channel(channel_t *ch, const char *method, htsp_connection_t *htsp) htsmsg_add_u32(out, "eventId", now ? now->id : 0); htsmsg_add_u32(out, "nextEventId", next ? next->id : 0); - LIST_FOREACH(ilm, &ch->ch_ctms, ilm_in2_link) { - ct = (channel_tag_t *)ilm->ilm_in1; - if(channel_tag_access(ct, htsp->htsp_granted_access, 0)) + LIST_FOREACH (ilm, &ch->ch_ctms, ilm_in2_link) { + ct = (channel_tag_t*)ilm->ilm_in1; + if (channel_tag_access(ct, htsp->htsp_granted_access, 0)) htsmsg_add_u32(tags, NULL, htsp_channel_tag_get_identifier(ct)); } - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - t = (service_t *)ilm->ilm_in1; - htsmsg_t *svcmsg = htsmsg_create_map(); + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + t = (service_t*)ilm->ilm_in1; + htsmsg_t* svcmsg = htsmsg_create_map(); htsmsg_add_str(svcmsg, "name", service_nicename(t)); /* Service type string, i.e. UHD, HD, Radio,... */ htsmsg_add_str(svcmsg, "type", service_servicetype_txt(t)); /* Service content, other = 0x00, tv = 0x01, radio = 0x02 */ - htsmsg_add_u32(svcmsg, "content", service_is_tv(t) ? 0x01 : (service_is_radio(t) ? 0x02 : 0x00)); + htsmsg_add_u32(svcmsg, + "content", + service_is_tv(t) ? 0x01 : (service_is_radio(t) ? 0x02 : 0x00)); if (service_is_encrypted(t)) { htsmsg_add_u32(svcmsg, "caid", 65535); - htsmsg_add_str(svcmsg, "caname", tvh_gettext_lang(htsp->htsp_language, N_("Encrypted service"))); + htsmsg_add_str(svcmsg, + "caname", + tvh_gettext_lang(htsp->htsp_language, N_("Encrypted service"))); } /* HbbTv */ @@ -919,14 +868,15 @@ htsp_build_channel(channel_t *ch, const char *method, htsp_connection_t *htsp) /** * */ -static htsmsg_t * -htsp_build_tag(htsp_connection_t *htsp, channel_tag_t *ct, const char *method, int include_channels) -{ - char buf[512]; - const char *icon; - idnode_list_mapping_t *ilm; - htsmsg_t *out = htsmsg_create_map(); - htsmsg_t *members = include_channels ? htsmsg_create_list() : NULL; +static htsmsg_t* htsp_build_tag(htsp_connection_t* htsp, + channel_tag_t* ct, + const char* method, + int include_channels) { + char buf[512]; + const char* icon; + idnode_list_mapping_t* ilm; + htsmsg_t* out = htsmsg_create_map(); + htsmsg_t* members = include_channels ? htsmsg_create_list() : NULL; htsmsg_add_u32(out, "tagId", htsp_channel_tag_get_identifier(ct)); htsmsg_add_u32(out, "tagIndex", ct->ct_index); @@ -937,9 +887,9 @@ htsp_build_tag(htsp_connection_t *htsp, channel_tag_t *ct, const char *method, i htsmsg_add_str(out, "tagIcon", htsp_image(htsp, icon, buf, sizeof(buf), 34)); htsmsg_add_u32(out, "tagTitledIcon", ct->ct_titled_icon); - if(members != NULL) { - LIST_FOREACH(ilm, &ct->ct_ctms, ilm_in1_link) - htsmsg_add_u32(members, NULL, channel_get_id((channel_t *)ilm->ilm_in2)); + if (members != NULL) { + LIST_FOREACH (ilm, &ct->ct_ctms, ilm_in1_link) + htsmsg_add_u32(members, NULL, channel_get_id((channel_t*)ilm->ilm_in2)); htsmsg_add_msg(out, "members", members); } @@ -950,18 +900,20 @@ htsp_build_tag(htsp_connection_t *htsp, channel_tag_t *ct, const char *method, i /** * */ -static htsmsg_t * -htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method, const char *lang, int statsonly) -{ - htsmsg_t *out = htsmsg_create_map(), *l, *m, *e, *info; - htsmsg_field_t *f; - const char *s = NULL, *error = NULL, *subscriptionError = NULL; - const char *p, *last; - int64_t fsize = -1, start, stop, size; - uint32_t u32; - char buf[512]; - char ubuf[UUID_HEX_SIZE]; - const char *str; +static htsmsg_t* htsp_build_dvrentry(htsp_connection_t* htsp, + dvr_entry_t* de, + const char* method, + const char* lang, + int statsonly) { + htsmsg_t * out = htsmsg_create_map(), *l, *m, *e, *info; + htsmsg_field_t* f; + const char * s = NULL, *error = NULL, *subscriptionError = NULL; + const char * p, *last; + int64_t fsize = -1, start, stop, size; + uint32_t u32; + char buf[512]; + char ubuf[UUID_HEX_SIZE]; + const char* str; htsmsg_add_u32(out, "id", idnode_get_short_uuid(&de->de_id)); @@ -973,7 +925,7 @@ htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method htsmsg_add_str(out, "channelName", de->de_channel_name); if (de->de_bcast) - htsmsg_add_u32(out, "eventId", de->de_bcast->id); + htsmsg_add_u32(out, "eventId", de->de_bcast->id); if (de->de_autorec) htsmsg_add_str(out, "autorecId", idnode_uuid_as_str(&de->de_autorec->dae_id, ubuf)); @@ -981,83 +933,81 @@ htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method if (de->de_timerec) htsmsg_add_str(out, "timerecId", idnode_uuid_as_str(&de->de_timerec->dte_id, ubuf)); - htsmsg_add_s64(out, "start", de->de_start); - htsmsg_add_s64(out, "stop", de->de_stop); - htsmsg_add_s64(out, "startExtra", dvr_entry_get_extra_time_pre(de)/60); - htsmsg_add_s64(out, "stopExtra", dvr_entry_get_extra_time_post(de)/60); + htsmsg_add_s64(out, "start", de->de_start); + htsmsg_add_s64(out, "stop", de->de_stop); + htsmsg_add_s64(out, "startExtra", dvr_entry_get_extra_time_pre(de) / 60); + htsmsg_add_s64(out, "stopExtra", dvr_entry_get_extra_time_post(de) / 60); if (htsp->htsp_version > 24) - htsmsg_add_u32(out, "retention", dvr_entry_get_retention_days(de)); + htsmsg_add_u32(out, "retention", dvr_entry_get_retention_days(de)); else - htsmsg_add_u32(out, "retention", dvr_entry_get_retention_days(de) == DVR_RET_ONREMOVE ? - dvr_entry_get_removal_days(de) : dvr_entry_get_retention_days(de)); + htsmsg_add_u32(out, + "retention", + dvr_entry_get_retention_days(de) == DVR_RET_ONREMOVE ? dvr_entry_get_removal_days(de) + : dvr_entry_get_retention_days(de)); - htsmsg_add_u32(out, "removal", dvr_entry_get_removal_days(de)); + htsmsg_add_u32(out, "removal", dvr_entry_get_removal_days(de)); u32 = de->de_pri; if (htsp->htsp_version < 30 && u32 > DVR_PRIO_UNIMPORTANT) u32 = de->de_config->dvr_pri; else if (u32 == DVR_PRIO_NOTSET) u32 = DVR_PRIO_NORMAL; - htsmsg_add_u32(out, "priority", u32); + htsmsg_add_u32(out, "priority", u32); htsmsg_add_u32(out, "contentType", de->de_content_type); - //To not risk breaking older clients, only - //provide the 'age rating' via HTSP if the requested - //API version if greater than 36. - if (htsp->htsp_version > 36) - { - //Having the age in the DVR entry is new, that is why - //it is processed inside the version test. + // To not risk breaking older clients, only + // provide the 'age rating' via HTSP if the requested + // API version if greater than 36. + if (htsp->htsp_version > 36) { + // Having the age in the DVR entry is new, that is why + // it is processed inside the version test. htsmsg_add_u32(out, "ageRating", de->de_age_rating); - //Only go on to add the rating label stuff if - //rating labels are enabled. - if(epggrab_conf.epgdb_processparentallabels){ - //If this is still scheduled (in the future) then send the current values, - //if not, send the 'saved' values. + // Only go on to add the rating label stuff if + // rating labels are enabled. + if (epggrab_conf.epgdb_processparentallabels) { + // If this is still scheduled (in the future) then send the current values, + // if not, send the 'saved' values. - if(de->de_sched_state == DVR_SCHEDULED){ - if(de->de_rating_label){ - if(de->de_rating_label->rl_display_label){ + if (de->de_sched_state == DVR_SCHEDULED) { + if (de->de_rating_label) { + if (de->de_rating_label->rl_display_label) { htsmsg_add_str(out, "ratingLabel", de->de_rating_label->rl_display_label); } - //If the rating icon is not null. - if(de->de_rating_label->rl_icon){ + // If the rating icon is not null. + if (de->de_rating_label->rl_icon) { str = de->de_rating_label->rl_icon; if (!strempty(str)) { str = imagecache_get_propstr(str, buf, sizeof(buf)); if (str) htsmsg_add_str(out, "ratingIcon", str); - }//END got an imagecache location - }//END icon not null + } // END got an imagecache location + } // END icon not null } - } - else - { - if(de->de_rating_label_saved){ - if(de->de_rating_label_saved){ + } else { + if (de->de_rating_label_saved) { + if (de->de_rating_label_saved) { htsmsg_add_str(out, "ratingLabel", de->de_rating_label_saved); } - if(de->de_rating_icon_saved){ + if (de->de_rating_icon_saved) { str = de->de_rating_icon_saved; if (!strempty(str)) { str = imagecache_get_propstr(str, buf, sizeof(buf)); if (str) htsmsg_add_str(out, "ratingIcon", str); - }//END got an imagecache location - }//END icon not null + } // END got an imagecache location + } // END icon not null } } - }//END processing rating labels is enabled + } // END processing rating labels is enabled } - if (de->de_sched_state == DVR_RECORDING || de->de_sched_state == DVR_COMPLETED) { - htsmsg_add_u32(out, "playcount", de->de_playcount); + htsmsg_add_u32(out, "playcount", de->de_playcount); htsmsg_add_u32(out, "playposition", de->de_playposition); } - if(de->de_title && (s = lang_str_get(de->de_title, lang))) + if (de->de_title && (s = lang_str_get(de->de_title, lang))) htsmsg_add_str(out, "title", s); if (htsp->htsp_version < 32) { if ((s = lang_str_get(de->de_desc, lang))) { @@ -1089,12 +1039,12 @@ htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method * an image from current EPG if recording does not have * an associated image. */ - const char *image = dvr_entry_get_image(de); - if(!strempty(image)) + const char* image = dvr_entry_get_image(de); + if (!strempty(image)) htsmsg_add_str(out, "image", htsp_image(htsp, image, buf, sizeof(buf), 34)); /* htsmsg camelcase to be compatible with other names */ image = de->de_fanart_image; - if(!strempty(image)) + if (!strempty(image)) htsmsg_add_str(out, "fanartImage", htsp_image(htsp, image, buf, sizeof(buf), 34)); if (de->de_copyright_year) htsmsg_add_u32(out, "copyrightYear", de->de_copyright_year); @@ -1104,7 +1054,8 @@ htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method l = htsmsg_create_list(); HTSMSG_FOREACH(f, de->de_files) { m = htsmsg_field_get_map(f); - if (m == NULL) continue; + if (m == NULL) + continue; s = last = htsmsg_get_str(m, "filename"); if (s && (p = tvh_strbegins(s, de->de_config->dvr_storage)) != NULL) { e = htsmsg_copy(m); @@ -1125,46 +1076,45 @@ htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method htsmsg_add_msg(out, "files", l); } - if(last && de->de_config) + if (last && de->de_config) if ((p = tvh_strbegins(last, de->de_config->dvr_storage))) htsmsg_add_str(out, "path", p); } - switch(de->de_sched_state) { - case DVR_SCHEDULED: - s = "scheduled"; - break; - case DVR_RECORDING: - s = "recording"; - fsize = dvr_get_filesize(de, DVR_FILESIZE_UPDATE); - if (de->de_rec_state == DVR_RS_ERROR || - (de->de_rec_state == DVR_RS_PENDING && de->de_last_error != SM_CODE_OK)) - { - error = streaming_code2txt(de->de_last_error); - subscriptionError = _htsp_get_subscription_status(de->de_last_error); - } - break; - case DVR_COMPLETED: - s = "completed"; - fsize = dvr_get_filesize(de, DVR_FILESIZE_UPDATE); - if (fsize < 0) - error = "File missing"; - else if(!dvr_entry_is_completed_ok(de)) - error = streaming_code2txt(de->de_last_error); - break; - case DVR_MISSED_TIME: - s = "missed"; - break; - case DVR_NOSTATE: - s = "invalid"; - break; + switch (de->de_sched_state) { + case DVR_SCHEDULED: + s = "scheduled"; + break; + case DVR_RECORDING: + s = "recording"; + fsize = dvr_get_filesize(de, DVR_FILESIZE_UPDATE); + if (de->de_rec_state == DVR_RS_ERROR || + (de->de_rec_state == DVR_RS_PENDING && de->de_last_error != SM_CODE_OK)) { + error = streaming_code2txt(de->de_last_error); + subscriptionError = _htsp_get_subscription_status(de->de_last_error); + } + break; + case DVR_COMPLETED: + s = "completed"; + fsize = dvr_get_filesize(de, DVR_FILESIZE_UPDATE); + if (fsize < 0) + error = "File missing"; + else if (!dvr_entry_is_completed_ok(de)) + error = streaming_code2txt(de->de_last_error); + break; + case DVR_MISSED_TIME: + s = "missed"; + break; + case DVR_NOSTATE: + s = "invalid"; + break; } if (dvr_entry_is_upcoming(de)) htsmsg_add_u32(out, "duplicate", dvr_entry_is_upcoming_nodup(de) ? 0 : 1); htsmsg_add_str(out, "state", s); - if(error) + if (error) htsmsg_add_str(out, "error", error); if (subscriptionError) htsmsg_add_str(out, "subscriptionError", subscriptionError); @@ -1181,26 +1131,28 @@ htsp_build_dvrentry(htsp_connection_t *htsp, dvr_entry_t *de, const char *method /** * */ -static htsmsg_t * -htsp_build_autorecentry(htsp_connection_t *htsp, dvr_autorec_entry_t *dae, const char *method) -{ - htsmsg_t *out = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; - int tad; - - htsmsg_add_str(out, "id", idnode_uuid_as_str(&dae->dae_id, ubuf)); - htsmsg_add_u32(out, "enabled", dae->dae_enabled >= 1 ? 1 : 0); +static htsmsg_t* +htsp_build_autorecentry(htsp_connection_t* htsp, dvr_autorec_entry_t* dae, const char* method) { + htsmsg_t* out = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; + int tad; + + htsmsg_add_str(out, "id", idnode_uuid_as_str(&dae->dae_id, ubuf)); + htsmsg_add_u32(out, "enabled", dae->dae_enabled >= 1 ? 1 : 0); htsmsg_add_u32(out, "maxDuration", dae->dae_maxduration); htsmsg_add_u32(out, "minDuration", dae->dae_minduration); if (htsp->htsp_version > 24) - htsmsg_add_u32(out, "retention", dvr_autorec_get_retention_days(dae)); + htsmsg_add_u32(out, "retention", dvr_autorec_get_retention_days(dae)); else - htsmsg_add_u32(out, "retention", dvr_autorec_get_retention_days(dae) == DVR_RET_ONREMOVE ? - dvr_autorec_get_removal_days(dae) : dvr_autorec_get_retention_days(dae)); - - htsmsg_add_u32(out, "removal", dvr_autorec_get_removal_days(dae)); - htsmsg_add_u32(out, "daysOfWeek", dae->dae_weekdays); + htsmsg_add_u32(out, + "retention", + dvr_autorec_get_retention_days(dae) == DVR_RET_ONREMOVE + ? dvr_autorec_get_removal_days(dae) + : dvr_autorec_get_retention_days(dae)); + + htsmsg_add_u32(out, "removal", dvr_autorec_get_removal_days(dae)); + htsmsg_add_u32(out, "daysOfWeek", dae->dae_weekdays); if (dae->dae_start >= 0 && dae->dae_start_window >= 0) { if (dae->dae_start > dae->dae_start_window) tad = 24 * 60 - dae->dae_start + dae->dae_start_window; @@ -1209,28 +1161,28 @@ htsp_build_autorecentry(htsp_connection_t *htsp, dvr_autorec_entry_t *dae, const } else { tad = -1; } - htsmsg_add_s32(out, "approxTime", - dae->dae_start >= 0 && tad >= 0 ? - ((dae->dae_start + tad / 2) % (24 * 60)) : -1); - htsmsg_add_s32(out, "start", dae->dae_start >= 0 ? dae->dae_start : -1); + htsmsg_add_s32(out, + "approxTime", + dae->dae_start >= 0 && tad >= 0 ? ((dae->dae_start + tad / 2) % (24 * 60)) : -1); + htsmsg_add_s32(out, "start", dae->dae_start >= 0 ? dae->dae_start : -1); htsmsg_add_s32(out, "startWindow", dae->dae_start_window >= 0 ? dae->dae_start_window : -1); - htsmsg_add_u32(out, "priority", dae->dae_pri); - htsmsg_add_s64(out, "startExtra", dvr_autorec_get_extra_time_pre(dae)); - htsmsg_add_s64(out, "stopExtra", dvr_autorec_get_extra_time_post(dae)); - htsmsg_add_u32(out, "dupDetect", dae->dae_record); - htsmsg_add_u32(out, "maxCount", dae->dae_max_count); - - if(dae->dae_title) { - htsmsg_add_str(out, "title", dae->dae_title); - htsmsg_add_u32(out, "fulltext", dae->dae_fulltext >= 1 ? 1 : 0); + htsmsg_add_u32(out, "priority", dae->dae_pri); + htsmsg_add_s64(out, "startExtra", dvr_autorec_get_extra_time_pre(dae)); + htsmsg_add_s64(out, "stopExtra", dvr_autorec_get_extra_time_post(dae)); + htsmsg_add_u32(out, "dupDetect", dae->dae_record); + htsmsg_add_u32(out, "maxCount", dae->dae_max_count); + + if (dae->dae_title) { + htsmsg_add_str(out, "title", dae->dae_title); + htsmsg_add_u32(out, "fulltext", dae->dae_fulltext >= 1 ? 1 : 0); } - htsmsg_add_str2(out, "name", dae->dae_name); - if(dae->dae_directory) + htsmsg_add_str2(out, "name", dae->dae_name); + if (dae->dae_directory) htsmsg_add_str(out, "directory", dae->dae_directory); - htsmsg_add_str2(out, "owner", dae->dae_owner); - htsmsg_add_str2(out, "creator", dae->dae_creator); - if(dae->dae_channel) - htsmsg_add_u32(out, "channel", channel_get_id(dae->dae_channel)); + htsmsg_add_str2(out, "owner", dae->dae_owner); + htsmsg_add_str2(out, "creator", dae->dae_creator); + if (dae->dae_channel) + htsmsg_add_u32(out, "channel", channel_get_id(dae->dae_channel)); if (dae->dae_serieslink_uri) htsmsg_add_str(out, "serieslinkUri", dae->dae_serieslink_uri); htsmsg_add_str(out, "method", method); @@ -1241,37 +1193,39 @@ htsp_build_autorecentry(htsp_connection_t *htsp, dvr_autorec_entry_t *dae, const /** * */ -static htsmsg_t * -htsp_build_timerecentry(htsp_connection_t *htsp, dvr_timerec_entry_t *dte, const char *method) -{ - htsmsg_t *out = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* +htsp_build_timerecentry(htsp_connection_t* htsp, dvr_timerec_entry_t* dte, const char* method) { + htsmsg_t* out = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; - htsmsg_add_str(out, "id", idnode_uuid_as_str(&dte->dte_id, ubuf)); - htsmsg_add_u32(out, "enabled", dte->dte_enabled >= 1 ? 1 : 0); - htsmsg_add_u32(out, "daysOfWeek", dte->dte_weekdays); + htsmsg_add_str(out, "id", idnode_uuid_as_str(&dte->dte_id, ubuf)); + htsmsg_add_u32(out, "enabled", dte->dte_enabled >= 1 ? 1 : 0); + htsmsg_add_u32(out, "daysOfWeek", dte->dte_weekdays); if (htsp->htsp_version > 24) - htsmsg_add_u32(out, "retention", dvr_timerec_get_retention_days(dte)); + htsmsg_add_u32(out, "retention", dvr_timerec_get_retention_days(dte)); else - htsmsg_add_u32(out, "retention", dvr_timerec_get_retention_days(dte) == DVR_RET_ONREMOVE ? - dvr_timerec_get_removal_days(dte) : dvr_timerec_get_retention_days(dte)); - - htsmsg_add_u32(out, "removal", dvr_timerec_get_removal_days(dte)); - htsmsg_add_u32(out, "priority", dte->dte_pri); - htsmsg_add_s32(out, "start", dte->dte_start); - htsmsg_add_s32(out, "stop", dte->dte_stop); - - if(dte->dte_title) - htsmsg_add_str(out, "title", dte->dte_title); - if(dte->dte_name) - htsmsg_add_str(out, "name", dte->dte_name); - if(dte->dte_directory) + htsmsg_add_u32(out, + "retention", + dvr_timerec_get_retention_days(dte) == DVR_RET_ONREMOVE + ? dvr_timerec_get_removal_days(dte) + : dvr_timerec_get_retention_days(dte)); + + htsmsg_add_u32(out, "removal", dvr_timerec_get_removal_days(dte)); + htsmsg_add_u32(out, "priority", dte->dte_pri); + htsmsg_add_s32(out, "start", dte->dte_start); + htsmsg_add_s32(out, "stop", dte->dte_stop); + + if (dte->dte_title) + htsmsg_add_str(out, "title", dte->dte_title); + if (dte->dte_name) + htsmsg_add_str(out, "name", dte->dte_name); + if (dte->dte_directory) htsmsg_add_str(out, "directory", dte->dte_directory); - htsmsg_add_str2(out, "owner", dte->dte_owner); - htsmsg_add_str2(out, "creator", dte->dte_creator); - if(dte->dte_channel) - htsmsg_add_u32(out, "channel", channel_get_id(dte->dte_channel)); + htsmsg_add_str2(out, "owner", dte->dte_owner); + htsmsg_add_str2(out, "creator", dte->dte_creator); + if (dte->dte_channel) + htsmsg_add_u32(out, "channel", channel_get_id(dte->dte_channel)); htsmsg_add_str(out, "method", method); @@ -1281,22 +1235,23 @@ htsp_build_timerecentry(htsp_connection_t *htsp, dvr_timerec_entry_t *dte, const /** * */ -static htsmsg_t * -htsp_build_event - (epg_broadcast_t *e, const char *method, const char *lang, time_t update, - htsp_connection_t *htsp ) -{ - htsmsg_t *out; - epg_broadcast_t *n; - dvr_entry_t *de; - epg_genre_t *g; +static htsmsg_t* htsp_build_event(epg_broadcast_t* e, + const char* method, + const char* lang, + time_t update, + htsp_connection_t* htsp) { + htsmsg_t* out; + epg_broadcast_t* n; + dvr_entry_t* de; + epg_genre_t* g; epg_episode_num_t epnum; - const char *str; - char buf[512]; - const int of = htsp->htsp_granted_access->aa_htsp_output_format; + const char* str; + char buf[512]; + const int of = htsp->htsp_granted_access->aa_htsp_output_format; /* Ignore? */ - if (update && e->updated <= update) return NULL; + if (update && e->updated <= update) + return NULL; out = htsmsg_create_map(); @@ -1352,45 +1307,43 @@ htsp_build_event if (e->episodelink && strncasecmp(e->episodelink->uri, "tvh://", 6)) htsmsg_add_str(out, "episodeUri", e->episodelink->uri); - if((g = LIST_FIRST(&e->genre))) { + if ((g = LIST_FIRST(&e->genre))) { uint32_t code = g->code; - if (htsp->htsp_version < 6) code = (code >> 4) & 0xF; + if (htsp->htsp_version < 6) + code = (code >> 4) & 0xF; htsmsg_add_u32(out, "contentType", code); } - if (e->age_rating){ + if (e->age_rating) { htsmsg_add_u32(out, "ageRating", e->age_rating); } - //To not risk breaking older clients, only - //provide the 'rating label' & 'rating icon' via HTSP if the requested - //version if greater than 36. - //Because this is the EPG, do not restrict the ageRating based on version, - //that field was added in a very early version. - if (htsp->htsp_version > 36) - { - //If we are processing parental labels - if(epggrab_conf.epgdb_processparentallabels) - { - //If this event had a label pointer that is not null - if (e->rating_label) - { - //If there is a 'display label' - //Do not fall-back to the 'label' because the 'display label' - //may be intentionally null. - if(e->rating_label->rl_display_label){ - htsmsg_add_str(out, "ratingLabel", e->rating_label->rl_display_label); - } - //If the rating icon is not null. - if(e->rating_label->rl_icon){ - str = e->rating_label->rl_icon; - if (!strempty(str)) { - str = imagecache_get_propstr(str, buf, sizeof(buf)); - if (str) - htsmsg_add_str(out, "ratingIcon", str); - }//END got an imagecache location - }//END icon not null - }//END rating label not null - }//END parental labels enabled. - }//END HTSP version check + // To not risk breaking older clients, only + // provide the 'rating label' & 'rating icon' via HTSP if the requested + // version if greater than 36. + // Because this is the EPG, do not restrict the ageRating based on version, + // that field was added in a very early version. + if (htsp->htsp_version > 36) { + // If we are processing parental labels + if (epggrab_conf.epgdb_processparentallabels) { + // If this event had a label pointer that is not null + if (e->rating_label) { + // If there is a 'display label' + // Do not fall-back to the 'label' because the 'display label' + // may be intentionally null. + if (e->rating_label->rl_display_label) { + htsmsg_add_str(out, "ratingLabel", e->rating_label->rl_display_label); + } + // If the rating icon is not null. + if (e->rating_label->rl_icon) { + str = e->rating_label->rl_icon; + if (!strempty(str)) { + str = imagecache_get_propstr(str, buf, sizeof(buf)); + if (str) + htsmsg_add_str(out, "ratingIcon", str); + } // END got an imagecache location + } // END icon not null + } // END rating label not null + } // END parental labels enabled. + } // END HTSP version check if (e->star_rating) htsmsg_add_u32(out, "starRating", e->star_rating); @@ -1404,7 +1357,7 @@ htsp_build_event htsmsg_add_str(out, "image", htsp_image(htsp, e->image, buf, sizeof(buf), 34)); if (e->channel) { - LIST_FOREACH(de, &e->channel->ch_dvrs, de_channel_link) { + LIST_FOREACH (de, &e->channel->ch_dvrs, de_channel_link) { if (de->de_bcast != e) continue; if (dvr_entry_verify(de, htsp->htsp_granted_access, 1)) @@ -1427,25 +1380,22 @@ htsp_build_event /** * Hello, for protocol version negotiation */ -static htsmsg_t * -htsp_method_hello(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *r; - uint32_t v; +static htsmsg_t* htsp_method_hello(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t* r; + uint32_t v; const char *name, *lang; - if(htsmsg_get_u32(in, "htspversion", &v)) + if (htsmsg_get_u32(in, "htspversion", &v)) return htsp_error(htsp, N_("Invalid arguments")); - if((name = htsmsg_get_str(in, "clientname")) == NULL) + if ((name = htsmsg_get_str(in, "clientname")) == NULL) return htsp_error(htsp, N_("Invalid arguments")); r = htsmsg_create_map(); tvh_str_update(&htsp->htsp_clientname, htsmsg_get_str(in, "clientname")); - tvhinfo(LS_HTSP, "%s: Welcomed client software: %s (HTSPv%d)", - htsp->htsp_logname, name, v); + tvhinfo(LS_HTSP, "%s: Welcomed client software: %s (HTSPv%d)", htsp->htsp_logname, name, v); htsmsg_add_u32(r, "htspversion", HTSP_PROTO_VERSION); htsmsg_add_str(r, "servername", config_get_server_name()); @@ -1471,26 +1421,35 @@ htsp_method_hello(htsp_connection_t *htsp, htsmsg_t *in) /** * Try to authenticate */ -static htsmsg_t * -htsp_method_authenticate(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *r = htsmsg_create_map(); +static htsmsg_t* htsp_method_authenticate(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t* r = htsmsg_create_map(); - if(!(htsp->htsp_granted_access->aa_rights & HTSP_PRIV_MASK)) + if (!(htsp->htsp_granted_access->aa_rights & HTSP_PRIV_MASK)) htsmsg_add_u32(r, "noaccess", 1); else if (htsp->htsp_version > 25) { - htsmsg_add_u32(r, "admin", htsp->htsp_granted_access->aa_rights & ACCESS_ADMIN ? 1 : 0); - htsmsg_add_u32(r, "streaming", htsp->htsp_granted_access->aa_rights & ACCESS_HTSP_STREAMING ? 1 : 0); - htsmsg_add_u32(r, "dvr", htsp->htsp_granted_access->aa_rights & ACCESS_HTSP_RECORDER ? 1 : 0); - htsmsg_add_u32(r, "faileddvr", htsp->htsp_granted_access->aa_rights & ACCESS_FAILED_RECORDER ? 1 : 0); - htsmsg_add_u32(r, "anonymous", htsp->htsp_granted_access->aa_rights & ACCESS_HTSP_ANONYMIZE ? 1 : 0); - htsmsg_add_u32(r, "limitall", htsp->htsp_granted_access->aa_conn_limit); - htsmsg_add_u32(r, "limitdvr", htsp->htsp_granted_access->aa_conn_limit_dvr); + htsmsg_add_u32(r, "admin", htsp->htsp_granted_access->aa_rights & ACCESS_ADMIN ? 1 : 0); + htsmsg_add_u32(r, + "streaming", + htsp->htsp_granted_access->aa_rights & ACCESS_HTSP_STREAMING ? 1 : 0); + htsmsg_add_u32(r, "dvr", htsp->htsp_granted_access->aa_rights & ACCESS_HTSP_RECORDER ? 1 : 0); + htsmsg_add_u32(r, + "faileddvr", + htsp->htsp_granted_access->aa_rights & ACCESS_FAILED_RECORDER ? 1 : 0); + htsmsg_add_u32(r, + "anonymous", + htsp->htsp_granted_access->aa_rights & ACCESS_HTSP_ANONYMIZE ? 1 : 0); + htsmsg_add_u32(r, "limitall", htsp->htsp_granted_access->aa_conn_limit); + htsmsg_add_u32(r, "limitdvr", htsp->htsp_granted_access->aa_conn_limit_dvr); htsmsg_add_u32(r, "limitstreaming", htsp->htsp_granted_access->aa_conn_limit_streaming); - htsmsg_add_u32(r, "uilevel", htsp->htsp_granted_access->aa_uilevel == UILEVEL_DEFAULT ? - config.uilevel : htsp->htsp_granted_access->aa_uilevel); - htsmsg_add_str(r, "uilanguage", htsp->htsp_granted_access->aa_lang_ui ? - htsp->htsp_granted_access->aa_lang_ui : (config.language_ui ? config.language_ui : "")); + htsmsg_add_u32(r, + "uilevel", + htsp->htsp_granted_access->aa_uilevel == UILEVEL_DEFAULT + ? config.uilevel + : htsp->htsp_granted_access->aa_uilevel); + htsmsg_add_str(r, + "uilanguage", + htsp->htsp_granted_access->aa_lang_ui ? htsp->htsp_granted_access->aa_lang_ui + : (config.language_ui ? config.language_ui : "")); } return r; @@ -1499,13 +1458,11 @@ htsp_method_authenticate(htsp_connection_t *htsp, htsmsg_t *in) /** * Try to authenticate */ -static htsmsg_t * -htsp_method_api(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *resp = NULL, *ret = htsmsg_create_map(); - htsmsg_t *args, *args2 = NULL; - const char *remain; - int r; +static htsmsg_t* htsp_method_api(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t * resp = NULL, *ret = htsmsg_create_map(); + htsmsg_t * args, *args2 = NULL; + const char* remain; + int r; tvh_mutex_unlock(&global_lock); @@ -1547,11 +1504,9 @@ htsp_method_api(htsp_connection_t *htsp, htsmsg_t *in) /** * Get total and free disk space on configured path */ -static htsmsg_t * -htsp_method_getDiskSpace(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *out; - int64_t bfree, bused, btotal; +static htsmsg_t* htsp_method_getDiskSpace(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t* out; + int64_t bfree, bused, btotal; if (dvr_get_disk_space(&bfree, &bused, &btotal)) return htsp_error(htsp, N_("Unable to stat path")); @@ -1566,22 +1521,20 @@ htsp_method_getDiskSpace(htsp_connection_t *htsp, htsmsg_t *in) /** * Get system time and diff to GMT */ -static htsmsg_t * -htsp_method_getSysTime(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *out; - struct timeval tv; +static htsmsg_t* htsp_method_getSysTime(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t* out; + struct timeval tv; struct timezone tz; - int tz_offset; - struct tm serverLocalTime; + int tz_offset; + struct tm serverLocalTime; - if(gettimeofday(&tv, &tz) == -1) + if (gettimeofday(&tv, &tz) == -1) return htsp_error(htsp, N_("Unable to get system time")); if (!localtime_r(&tv.tv_sec, &serverLocalTime)) return htsp_error(htsp, N_("Unable to get system local time")); #if defined(HAS_GMTOFF) - tz_offset = - serverLocalTime.tm_gmtoff / (60); + tz_offset = -serverLocalTime.tm_gmtoff / (60); #else // NB: This will be a day out when GMT offsets >= 13hrs or <11 hrs apply struct tm serverGmTime; @@ -1597,7 +1550,7 @@ htsp_method_getSysTime(htsp_connection_t *htsp, htsmsg_t *in) out = htsmsg_create_map(); htsmsg_add_s32(out, "time", tv.tv_sec); - htsmsg_add_s32(out, "timezone", tz_offset/60); + htsmsg_add_s32(out, "timezone", tz_offset / 60); htsmsg_add_s32(out, "gmtoffset", -tz_offset); return out; } @@ -1605,24 +1558,22 @@ htsp_method_getSysTime(htsp_connection_t *htsp, htsmsg_t *in) /** * Switch the HTSP connection into async mode */ -static htsmsg_t * -htsp_method_async(htsp_connection_t *htsp, htsmsg_t *in) -{ - channel_t *ch; - channel_tag_t *ct; - dvr_entry_t *de; - dvr_autorec_entry_t *dae; - dvr_timerec_entry_t *dte; - htsmsg_t *m; - uint32_t epg = 0; - int64_t lastUpdate = -1; - int64_t epgMaxTime = 0; - const char *lang; +static htsmsg_t* htsp_method_async(htsp_connection_t* htsp, htsmsg_t* in) { + channel_t* ch; + channel_tag_t* ct; + dvr_entry_t* de; + dvr_autorec_entry_t* dae; + dvr_timerec_entry_t* dte; + htsmsg_t* m; + uint32_t epg = 0; + int64_t lastUpdate = -1; + int64_t epgMaxTime = 0; + const char* lang; /* Get optional flags, allow updating them if already in async mode */ if (htsmsg_get_u32(in, "epg", &epg)) epg = (htsp->htsp_async_mode & HTSP_ASYNC_EPG) ? 1 : 0; - if (!htsmsg_get_s64(in, "lastUpdate", &lastUpdate)) // 0 = never + if (!htsmsg_get_s64(in, "lastUpdate", &lastUpdate)) // 0 = never htsp->htsp_epg_lastupdate = lastUpdate; else if (htsp->htsp_async_mode & HTSP_ASYNC_EPG) lastUpdate = htsp->htsp_epg_lastupdate; @@ -1630,9 +1581,9 @@ htsp_method_async(htsp_connection_t *htsp, htsmsg_t *in) if (htsp->htsp_async_mode & HTSP_ASYNC_EPG) { /* Only allow to change the window in the correct range */ if (htsp->htsp_epg_window && epgMaxTime > htsp->htsp_epg_lastupdate) - htsp->htsp_epg_window = epgMaxTime-gclk(); + htsp->htsp_epg_window = epgMaxTime - gclk(); } else if (epgMaxTime > gclk()) { - htsp->htsp_epg_window = epgMaxTime-gclk(); + htsp->htsp_epg_window = epgMaxTime - gclk(); } else { htsp->htsp_epg_window = 0; } @@ -1652,12 +1603,12 @@ htsp_method_async(htsp_connection_t *htsp, htsmsg_t *in) htsp_reply(htsp, in, htsmsg_create_map()); /* Set epg */ - if(epg) + if (epg) htsp->htsp_async_mode |= HTSP_ASYNC_EPG; else htsp->htsp_async_mode &= ~HTSP_ASYNC_EPG; - if(htsp->htsp_async_mode & HTSP_ASYNC_ON) { + if (htsp->htsp_async_mode & HTSP_ASYNC_ON) { /* Sync epg on demand */ if (epg) htsp_epg_send_waiting(htsp, lastUpdate); @@ -1667,34 +1618,36 @@ htsp_method_async(htsp_connection_t *htsp, htsmsg_t *in) htsp->htsp_async_mode |= HTSP_ASYNC_ON; /* Send all enabled and external tags */ - TAILQ_FOREACH(ct, &channel_tags, ct_link) - if(channel_tag_access(ct, htsp->htsp_granted_access, 0)) + TAILQ_FOREACH (ct, &channel_tags, ct_link) + if (channel_tag_access(ct, htsp->htsp_granted_access, 0)) htsp_send_message(htsp, htsp_build_tag(htsp, ct, "tagAdd", 0), NULL); /* Send all channels */ CHANNEL_FOREACH(ch) - if (htsp_user_access_channel(htsp,ch)) - htsp_send_message(htsp, htsp_build_channel(ch, "channelAdd", htsp), NULL); + if (htsp_user_access_channel(htsp, ch)) + htsp_send_message(htsp, htsp_build_channel(ch, "channelAdd", htsp), NULL); /* Send all enabled and external tags (now with channel mappings) */ - TAILQ_FOREACH(ct, &channel_tags, ct_link) - if(channel_tag_access(ct, htsp->htsp_granted_access, 0)) + TAILQ_FOREACH (ct, &channel_tags, ct_link) + if (channel_tag_access(ct, htsp->htsp_granted_access, 0)) htsp_send_message(htsp, htsp_build_tag(htsp, ct, "tagUpdate", 1), NULL); /* Send all autorecs */ - TAILQ_FOREACH(dae, &autorec_entries, dae_link) + TAILQ_FOREACH (dae, &autorec_entries, dae_link) if (!dvr_autorec_entry_verify(dae, htsp->htsp_granted_access, 1)) htsp_send_message(htsp, htsp_build_autorecentry(htsp, dae, "autorecEntryAdd"), NULL); /* Send all timerecs */ - TAILQ_FOREACH(dte, &timerec_entries, dte_link) + TAILQ_FOREACH (dte, &timerec_entries, dte_link) if (!dvr_timerec_entry_verify(dte, htsp->htsp_granted_access, 1)) htsp_send_message(htsp, htsp_build_timerecentry(htsp, dte, "timerecEntryAdd"), NULL); /* Send all DVR entries */ - LIST_FOREACH(de, &dvrentries, de_global_link) + LIST_FOREACH (de, &dvrentries, de_global_link) if (!dvr_entry_verify(de, htsp->htsp_granted_access, 1)) - htsp_send_message(htsp, htsp_build_dvrentry(htsp, de, "dvrEntryAdd", htsp->htsp_language, 0), NULL); + htsp_send_message(htsp, + htsp_build_dvrentry(htsp, de, "dvrEntryAdd", htsp->htsp_language, 0), + NULL); /* Send EPG updates */ if (epg) @@ -1714,11 +1667,9 @@ htsp_method_async(htsp_connection_t *htsp, htsmsg_t *in) /** * Get information about the given event */ -static htsmsg_t * -htsp_method_getChannel(htsp_connection_t *htsp, htsmsg_t *in) -{ - uint32_t channelId; - channel_t *ch = NULL; +static htsmsg_t* htsp_method_getChannel(htsp_connection_t* htsp, htsmsg_t* in) { + uint32_t channelId; + channel_t* ch = NULL; if (htsmsg_get_u32(in, "channelId", &channelId)) return htsp_error(htsp, N_("Invalid arguments")); @@ -1731,18 +1682,16 @@ htsp_method_getChannel(htsp_connection_t *htsp, htsmsg_t *in) /** * Get information about the given event */ -static htsmsg_t * -htsp_method_getEvent(htsp_connection_t *htsp, htsmsg_t *in) -{ - uint32_t eventId; - epg_broadcast_t *e; - const char *lang; - - if(htsmsg_get_u32(in, "eventId", &eventId)) +static htsmsg_t* htsp_method_getEvent(htsp_connection_t* htsp, htsmsg_t* in) { + uint32_t eventId; + epg_broadcast_t* e; + const char* lang; + + if (htsmsg_get_u32(in, "eventId", &eventId)) return htsp_error(htsp, N_("Invalid arguments")); lang = htsmsg_get_str(in, "language") ?: htsp->htsp_language; - if((e = epg_broadcast_find_by_id(eventId)) == NULL) + if ((e = epg_broadcast_find_by_id(eventId)) == NULL) return htsp_error(htsp, N_("Event does not exist")); return htsp_build_event(e, NULL, lang, 0, htsp); @@ -1752,15 +1701,13 @@ htsp_method_getEvent(htsp_connection_t *htsp, htsmsg_t *in) * Get information about the given event + * n following events */ -static htsmsg_t * -htsp_method_getEvents(htsp_connection_t *htsp, htsmsg_t *in) -{ - uint32_t u32, numFollowing; - int64_t maxTime = 0; - htsmsg_t *out, *events; - epg_broadcast_t *e = NULL; - channel_t *ch = NULL; - const char *lang; +static htsmsg_t* htsp_method_getEvents(htsp_connection_t* htsp, htsmsg_t* in) { + uint32_t u32, numFollowing; + int64_t maxTime = 0; + htsmsg_t * out, *events; + epg_broadcast_t* e = NULL; + channel_t* ch = NULL; + const char* lang; /* Optional fields */ if (!htsmsg_get_u32(in, "channelId", &u32)) @@ -1779,7 +1726,8 @@ htsp_method_getEvents(htsp_connection_t *htsp, htsmsg_t *in) /* Use event as starting point */ if (e || ch) { - if (!e) e = ch->ch_epg_now ?: ch->ch_epg_next; + if (!e) + e = ch->ch_epg_now ?: ch->ch_epg_next; if (e && !htsp_user_access_channel(htsp, e->channel)) return htsp_error(htsp, N_("User does not have access")); @@ -1787,14 +1735,17 @@ htsp_method_getEvents(htsp_connection_t *htsp, htsmsg_t *in) /* Output */ events = htsmsg_create_list(); while (e) { - if (maxTime && e->start > maxTime) break; + if (maxTime && e->start > maxTime) + break; htsmsg_add_msg(events, NULL, htsp_build_event(e, NULL, lang, 0, htsp)); - if (numFollowing == 1) break; - if (numFollowing) numFollowing--; + if (numFollowing == 1) + break; + if (numFollowing) + numFollowing--; e = epg_broadcast_get_next(e); } - /* All channels */ + /* All channels */ } else { events = htsmsg_create_list(); @@ -1802,14 +1753,16 @@ htsp_method_getEvents(htsp_connection_t *htsp, htsmsg_t *in) int num = numFollowing; if (!htsp_user_access_channel(htsp, ch)) continue; - RB_FOREACH(e, &ch->ch_epg_schedule, sched_link) { - if (maxTime && e->start > maxTime) break; + RB_FOREACH (e, &ch->ch_epg_schedule, sched_link) { + if (maxTime && e->start > maxTime) + break; htsmsg_add_msg(events, NULL, htsp_build_event(e, NULL, lang, 0, htsp)); - if (num == 1) break; - if (num) num--; + if (num == 1) + break; + if (num) + num--; } } - } /* Send */ @@ -1822,56 +1775,55 @@ htsp_method_getEvents(htsp_connection_t *htsp, htsmsg_t *in) * * do an epg query */ -static htsmsg_t * -htsp_method_epgQuery(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *out, *array; - const char *query; - int i; - uint32_t u32, full; - channel_t *ch = NULL; - channel_tag_t *ct = NULL; - epg_query_t eq; - const char *lang; - int min_duration; - int max_duration; - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* htsp_method_epgQuery(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t * out, *array; + const char* query; + int i; + uint32_t u32, full; + channel_t* ch = NULL; + channel_tag_t* ct = NULL; + epg_query_t eq; + const char* lang; + int min_duration; + int max_duration; + char ubuf[UUID_HEX_SIZE]; /* Required */ - if( (query = htsmsg_get_str(in, "query")) == NULL ) + if ((query = htsmsg_get_str(in, "query")) == NULL) return htsp_error(htsp, N_("Invalid arguments")); memset(&eq, 0, sizeof(eq)); - if(htsmsg_get_bool_or_default(in, "fulltext", 0)) + if (htsmsg_get_bool_or_default(in, "fulltext", 0)) eq.fulltext = 1; eq.stitle = strdup(query); /* Optional */ - if(!(htsmsg_get_u32(in, "channelId", &u32))) { + if (!(htsmsg_get_u32(in, "channelId", &u32))) { if (!(ch = channel_find_by_id(u32))) return htsp_error(htsp, N_("Channel does not exist")); else eq.channel = strdup(idnode_uuid_as_str(&ch->ch_id, ubuf)); } - if(!(htsmsg_get_u32(in, "tagId", &u32))) { + if (!(htsmsg_get_u32(in, "tagId", &u32))) { if (!(ct = htsp_channel_tag_find_by_id(htsp, u32))) return htsp_error(htsp, N_("Channel tag does not exist")); else eq.channel_tag = strdup(idnode_uuid_as_str(&ct->ct_id, ubuf)); } if (!htsmsg_get_u32(in, "contentType", &u32)) { - if(htsp->htsp_version < 6) u32 <<= 4; + if (htsp->htsp_version < 6) + u32 <<= 4; eq.genre_count = 1; - eq.genre = eq.genre_static; - eq.genre[0] = u32; + eq.genre = eq.genre_static; + eq.genre[0] = u32; } - lang = htsmsg_get_str(in, "language") ?: htsp->htsp_language; + lang = htsmsg_get_str(in, "language") ?: htsp->htsp_language; eq.lang = lang ? strdup(lang) : NULL; - full = htsmsg_get_u32_or_default(in, "full", 0); + full = htsmsg_get_u32_or_default(in, "full", 0); - min_duration = htsmsg_get_u32_or_default(in, "minduration", 0); - max_duration = htsmsg_get_u32_or_default(in, "maxduration", INT_MAX); + min_duration = htsmsg_get_u32_or_default(in, "minduration", 0); + max_duration = htsmsg_get_u32_or_default(in, "maxduration", INT_MAX); eq.duration.comp = EC_RG; eq.duration.val1 = min_duration; eq.duration.val2 = max_duration; @@ -1886,12 +1838,11 @@ htsp_method_epgQuery(htsp_connection_t *htsp, htsmsg_t *in) /* Create Reply */ out = htsmsg_create_map(); - if( eq.entries ) { + if (eq.entries) { array = htsmsg_create_list(); - for(i = 0; i < eq.entries; ++i) { + for (i = 0; i < eq.entries; ++i) { if (full) - htsmsg_add_msg(array, NULL, - htsp_build_event(eq.result[i], NULL, lang, 0, htsp)); + htsmsg_add_msg(array, NULL, htsp_build_event(eq.result[i], NULL, lang, 0, htsp)); else htsmsg_add_u32(array, NULL, eq.result[i]->id); } @@ -1903,13 +1854,11 @@ htsp_method_epgQuery(htsp_connection_t *htsp, htsmsg_t *in) return out; } -static htsmsg_t * -htsp_method_getEpgObject(htsp_connection_t *htsp, htsmsg_t *in) -{ - uint32_t id, u32; +static htsmsg_t* htsp_method_getEpgObject(htsp_connection_t* htsp, htsmsg_t* in) { + uint32_t id, u32; epg_object_type_t type; - epg_object_t *eo; - htsmsg_t *out; + epg_object_t* eo; + htsmsg_t* out; // TODO: should really block access based on channel, but actually // that's really hard to do here! @@ -1938,18 +1887,16 @@ htsp_method_getEpgObject(htsp_connection_t *htsp, htsmsg_t *in) /** * */ -static htsmsg_t * -htsp_method_getDvrConfigs(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *out, *l, *c; - htsmsg_field_t *f; - dvr_config_t *cfg; - const char *uuid, *s; - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* htsp_method_getDvrConfigs(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t * out, *l, *c; + htsmsg_field_t* f; + dvr_config_t* cfg; + const char * uuid, *s; + char ubuf[UUID_HEX_SIZE]; l = htsmsg_create_list(); - LIST_FOREACH(cfg, &dvrconfigs, config_link) + LIST_FOREACH (cfg, &dvrconfigs, config_link) if (cfg->dvr_enabled) { uuid = idnode_uuid_as_str(&cfg->dvr_id, ubuf); if (htsp->htsp_granted_access->aa_dvrcfgs) { @@ -1979,24 +1926,22 @@ htsp_method_getDvrConfigs(htsp_connection_t *htsp, htsmsg_t *in) /** * add a Dvrentry */ -static htsmsg_t * -htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *conf, *out; - dvr_config_t *dvr_conf; - uint32_t eventid; - epg_broadcast_t *e = NULL; - dvr_entry_t *de; +static htsmsg_t* htsp_method_addDvrEntry(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t * conf, *out; + dvr_config_t* dvr_conf; + uint32_t eventid; + epg_broadcast_t* e = NULL; + dvr_entry_t* de; dvr_entry_sched_state_t dvr_status; - const char *s, *lang; - int64_t start, stop; - uint32_t u32; - channel_t *ch = NULL; + const char * s, *lang; + int64_t start, stop; + uint32_t u32; + channel_t* ch = NULL; - if(!htsmsg_get_u32(in, "channelId", &u32)) + if (!htsmsg_get_u32(in, "channelId", &u32)) ch = channel_find_by_id(u32); - if(!htsmsg_get_u32(in, "eventId", &eventid)) { - e = epg_broadcast_find_by_id(eventid); + if (!htsmsg_get_u32(in, "eventId", &eventid)) { + e = epg_broadcast_find_by_id(eventid); ch = e ? e->channel : ch; } @@ -2024,7 +1969,7 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) htsmsg_copy_field(conf, "removal", in, NULL); htsmsg_copy_field(conf, "comment", in, NULL); - if (!(lang = htsmsg_get_str(in, "language"))) + if (!(lang = htsmsg_get_str(in, "language"))) lang = htsp->htsp_language; /* Auth */ @@ -2037,10 +1982,8 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) if (!e) { /* Required attributes */ - if (htsmsg_get_s64(in, "start", &start) || - htsmsg_get_s64(in, "stop", &stop) || - !(s = htsmsg_get_str(in, "title")) || - *s == '\0') { + if (htsmsg_get_s64(in, "start", &start) || htsmsg_get_s64(in, "stop", &stop) || + !(s = htsmsg_get_str(in, "title")) || *s == '\0') { htsmsg_destroy(conf); return htsp_error(htsp, N_("Invalid arguments")); } @@ -2061,7 +2004,7 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) if (s) lang_str_serialize_one(conf, "description", s, lang); u32 = htsmsg_get_u32_or_default(in, "ageRating", 0); - if(u32) + if (u32) htsmsg_add_u32(conf, "age_rating", u32); } @@ -2075,18 +2018,18 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) /* Create response */ out = htsmsg_create_map(); - switch(dvr_status) { - case DVR_SCHEDULED: - case DVR_RECORDING: - case DVR_MISSED_TIME: - case DVR_COMPLETED: - htsmsg_add_u32(out, "id", idnode_get_short_uuid(&de->de_id)); - htsmsg_add_u32(out, "success", 1); - break; - case DVR_NOSTATE: - htsmsg_add_str(out, "error", "Could not add dvrEntry"); - htsmsg_add_u32(out, "success", 0); - break; + switch (dvr_status) { + case DVR_SCHEDULED: + case DVR_RECORDING: + case DVR_MISSED_TIME: + case DVR_COMPLETED: + htsmsg_add_u32(out, "id", idnode_get_short_uuid(&de->de_id)); + htsmsg_add_u32(out, "success", 1); + break; + case DVR_NOSTATE: + htsmsg_add_str(out, "error", "Could not add dvrEntry"); + htsmsg_add_u32(out, "success", 0); + break; } return out; } @@ -2094,23 +2037,22 @@ htsp_method_addDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) /** * Find DVR entry */ -static dvr_entry_t * -htsp_findDvrEntry(htsp_connection_t *htsp, htsmsg_t *in, htsmsg_t **out, int readonly) -{ - uint32_t dvrEntryId; - dvr_entry_t *de; +static dvr_entry_t* +htsp_findDvrEntry(htsp_connection_t* htsp, htsmsg_t* in, htsmsg_t** out, int readonly) { + uint32_t dvrEntryId; + dvr_entry_t* de; - if(htsmsg_get_u32(in, "id", &dvrEntryId)) { + if (htsmsg_get_u32(in, "id", &dvrEntryId)) { *out = htsp_error(htsp, N_("Invalid arguments")); return NULL; } - if((de = dvr_entry_find_by_id(dvrEntryId)) == NULL) { + if ((de = dvr_entry_find_by_id(dvrEntryId)) == NULL) { *out = htsp_error(htsp, N_("DVR entry not found")); return NULL; } - if(dvr_entry_verify(de, htsp->htsp_granted_access, readonly)) { + if (dvr_entry_verify(de, htsp->htsp_granted_access, readonly)) { *out = htsp_error(htsp, N_("User does not have access")); return NULL; } @@ -2118,28 +2060,25 @@ htsp_findDvrEntry(htsp_connection_t *htsp, htsmsg_t *in, htsmsg_t **out, int rea return de; } - /** * update a Dvrentry */ -static htsmsg_t * -htsp_method_updateDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *out = NULL; - uint32_t u32; - dvr_entry_t *de; - time_t start, stop, start_extra, stop_extra, priority; - const char *dvr_config_name, *title, *subtitle, *summary, *desc, *lang; - channel_t *channel = NULL; - int enabled, retention, removal, playcount = -1, playposition = -1; - int age_rating; - ratinglabel_t *rating_label; +static htsmsg_t* htsp_method_updateDvrEntry(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t* out = NULL; + uint32_t u32; + dvr_entry_t* de; + time_t start, stop, start_extra, stop_extra, priority; + const char * dvr_config_name, *title, *subtitle, *summary, *desc, *lang; + channel_t* channel = NULL; + int enabled, retention, removal, playcount = -1, playposition = -1; + int age_rating; + ratinglabel_t* rating_label; de = htsp_findDvrEntry(htsp, in, &out, 0); if (de == NULL) return out; - if(!htsmsg_get_u32(in, "channelId", &u32)) + if (!htsmsg_get_u32(in, "channelId", &u32)) channel = channel_find_by_id(u32); if (!channel) channel = de->de_channel; @@ -2148,24 +2087,24 @@ htsp_method_updateDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) if (channel && !htsp_user_access_channel(htsp, channel)) return htsp_error(htsp, N_("User does not have access to channel")); - enabled = htsmsg_get_s64_or_default(in, "enabled", -1); + enabled = htsmsg_get_s64_or_default(in, "enabled", -1); dvr_config_name = htsp_dvr_config_name(htsp, htsmsg_get_str(in, "configName")); - start = htsmsg_get_s64_or_default(in, "start", 0); - stop = htsmsg_get_s64_or_default(in, "stop", 0); - start_extra = htsmsg_get_s64_or_default(in, "startExtra", 0); - stop_extra = htsmsg_get_s64_or_default(in, "stopExtra", 0); - retention = htsmsg_get_u32_or_default(in, "retention", DVR_RET_REM_DVRCONFIG); - removal = htsmsg_get_u32_or_default(in, "removal", DVR_RET_REM_DVRCONFIG); - priority = htsmsg_get_u32_or_default(in, "priority", DVR_PRIO_NOTSET); - age_rating = htsmsg_get_u32_or_default(in, "ageRating", 0); - rating_label = NULL; //Rating labels not supported for manually created DVR entries - title = htsmsg_get_str(in, "title"); - subtitle = htsmsg_get_str(in, "subtitle"); - summary = htsmsg_get_str(in, "summary"); - desc = htsmsg_get_str(in, "description"); - lang = htsmsg_get_str(in, "language") ?: htsp->htsp_language; - - if(!htsmsg_get_u32(in, "playcount", &u32)) { + start = htsmsg_get_s64_or_default(in, "start", 0); + stop = htsmsg_get_s64_or_default(in, "stop", 0); + start_extra = htsmsg_get_s64_or_default(in, "startExtra", 0); + stop_extra = htsmsg_get_s64_or_default(in, "stopExtra", 0); + retention = htsmsg_get_u32_or_default(in, "retention", DVR_RET_REM_DVRCONFIG); + removal = htsmsg_get_u32_or_default(in, "removal", DVR_RET_REM_DVRCONFIG); + priority = htsmsg_get_u32_or_default(in, "priority", DVR_PRIO_NOTSET); + age_rating = htsmsg_get_u32_or_default(in, "ageRating", 0); + rating_label = NULL; // Rating labels not supported for manually created DVR entries + title = htsmsg_get_str(in, "title"); + subtitle = htsmsg_get_str(in, "subtitle"); + summary = htsmsg_get_str(in, "summary"); + desc = htsmsg_get_str(in, "description"); + lang = htsmsg_get_str(in, "language") ?: htsp->htsp_language; + + if (!htsmsg_get_u32(in, "playcount", &u32)) { if (u32 > INT_MAX) u32 = HTSP_DVR_PLAYCOUNT_INCR; switch (u32) { @@ -2186,13 +2125,29 @@ htsp_method_updateDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) break; } } - if(!htsmsg_get_u32(in, "playposition", &u32)) + if (!htsmsg_get_u32(in, "playposition", &u32)) playposition = u32 > INT_MAX ? INT_MAX : u32; - de = dvr_entry_update(de, enabled, dvr_config_name, channel, title, subtitle, - summary, desc, lang, start, stop, start_extra, stop_extra, - priority, retention, removal, playcount, playposition, - age_rating, rating_label); + de = dvr_entry_update(de, + enabled, + dvr_config_name, + channel, + title, + subtitle, + summary, + desc, + lang, + start, + stop, + start_extra, + stop_extra, + priority, + retention, + removal, + playcount, + playposition, + age_rating, + rating_label); return htsp_success(); } @@ -2200,11 +2155,9 @@ htsp_method_updateDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) /** * stop a Dvrentry */ -static htsmsg_t * -htsp_method_stopDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *out = NULL; - dvr_entry_t *de; +static htsmsg_t* htsp_method_stopDvrEntry(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t* out = NULL; + dvr_entry_t* de; de = htsp_findDvrEntry(htsp, in, &out, 0); if (de == NULL) @@ -2218,11 +2171,9 @@ htsp_method_stopDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) /** * cancel a Dvrentry */ -static htsmsg_t * -htsp_method_cancelDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *out = NULL; - dvr_entry_t *de; +static htsmsg_t* htsp_method_cancelDvrEntry(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t* out = NULL; + dvr_entry_t* de; de = htsp_findDvrEntry(htsp, in, &out, 0); if (de == NULL) @@ -2236,11 +2187,9 @@ htsp_method_cancelDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) /** * delete a Dvrentry */ -static htsmsg_t * -htsp_method_deleteDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *out; - dvr_entry_t *de; +static htsmsg_t* htsp_method_deleteDvrEntry(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t* out; + dvr_entry_t* de; de = htsp_findDvrEntry(htsp, in, &out, 0); if (de == NULL) @@ -2254,19 +2203,17 @@ htsp_method_deleteDvrEntry(htsp_connection_t *htsp, htsmsg_t *in) /** * add a Dvr autorec entry */ -static htsmsg_t * -htsp_method_addAutorecEntry(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *out; - dvr_autorec_entry_t *dae; - const char *str; - uint32_t u32; - int64_t s64; - channel_t *ch = NULL; - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* htsp_method_addAutorecEntry(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t* out; + dvr_autorec_entry_t* dae; + const char* str; + uint32_t u32; + int64_t s64; + channel_t* ch = NULL; + char ubuf[UUID_HEX_SIZE]; /* Options */ - if(!(str = htsmsg_get_str(in, "title"))) + if (!(str = htsmsg_get_str(in, "title"))) return htsp_error(htsp, N_("Invalid arguments")); if (htsp->htsp_version > 24) { @@ -2274,9 +2221,8 @@ htsp_method_addAutorecEntry(htsp_connection_t *htsp, htsmsg_t *in) if (s64 >= 0) ch = channel_find_by_id((uint32_t)s64); } - } - else { - if (!htsmsg_get_u32(in, "channelId", &u32)) // not sending = any channel + } else { + if (!htsmsg_get_u32(in, "channelId", &u32)) // not sending = any channel ch = channel_find_by_id(u32); } @@ -2293,37 +2239,33 @@ htsp_method_addAutorecEntry(htsp_connection_t *htsp, htsmsg_t *in) if (dae) { htsmsg_add_str(out, "id", idnode_uuid_as_str(&dae->dae_id, ubuf)); htsmsg_add_u32(out, "success", 1); - } - else { + } else { htsmsg_add_str(out, "error", "Could not add autorec entry"); htsmsg_add_u32(out, "success", 0); } return out; } - /** * update a Dvr autorec entry */ -static htsmsg_t * -htsp_method_updateAutorecEntry(htsp_connection_t *htsp, htsmsg_t *in) -{ - const char *daeId; - dvr_autorec_entry_t *dae; - int64_t s64; - channel_t *ch = NULL; +static htsmsg_t* htsp_method_updateAutorecEntry(htsp_connection_t* htsp, htsmsg_t* in) { + const char* daeId; + dvr_autorec_entry_t* dae; + int64_t s64; + channel_t* ch = NULL; if (!(daeId = htsmsg_get_str(in, "id"))) return htsp_error(htsp, N_("Invalid arguments")); - if((dae = dvr_autorec_find_by_uuid(daeId)) == NULL) + if ((dae = dvr_autorec_find_by_uuid(daeId)) == NULL) return htsp_error(htsp, N_("Automatic schedule entry not found")); - if(dvr_autorec_entry_verify(dae, htsp->htsp_granted_access, 0)) + if (dvr_autorec_entry_verify(dae, htsp->htsp_granted_access, 0)) return htsp_error(htsp, N_("User does not have access")); /* Do we have a channel? No = keep old one */ - if (!htsmsg_get_s64(in, "channelId", &s64)) //s64 -> -1 = any channel + if (!htsmsg_get_s64(in, "channelId", &s64)) // s64 -> -1 = any channel { if (s64 >= 0) ch = channel_find_by_id((uint32_t)s64); @@ -2339,23 +2281,20 @@ htsp_method_updateAutorecEntry(htsp_connection_t *htsp, htsmsg_t *in) return htsp_success(); } - /** * delete a Dvr autorec entry */ -static htsmsg_t * -htsp_method_deleteAutorecEntry(htsp_connection_t *htsp, htsmsg_t *in) -{ - const char *daeId; - dvr_autorec_entry_t *dae; +static htsmsg_t* htsp_method_deleteAutorecEntry(htsp_connection_t* htsp, htsmsg_t* in) { + const char* daeId; + dvr_autorec_entry_t* dae; if (!(daeId = htsmsg_get_str(in, "id"))) return htsp_error(htsp, N_("Invalid arguments")); - if((dae = dvr_autorec_find_by_uuid(daeId)) == NULL) + if ((dae = dvr_autorec_find_by_uuid(daeId)) == NULL) return htsp_error(htsp, N_("Automatic schedule entry not found")); - if(dvr_autorec_entry_verify(dae, htsp->htsp_granted_access, 0)) + if (dvr_autorec_entry_verify(dae, htsp->htsp_granted_access, 0)) return htsp_error(htsp, N_("User does not have access")); autorec_destroy_by_id(daeId, 1); @@ -2366,19 +2305,17 @@ htsp_method_deleteAutorecEntry(htsp_connection_t *htsp, htsmsg_t *in) /** * add a Dvr timerec entry */ -static htsmsg_t * -htsp_method_addTimerecEntry(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *out; - dvr_timerec_entry_t *dte; - const char *str; - channel_t *ch = NULL; - uint32_t u32; - int64_t s64; - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* htsp_method_addTimerecEntry(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t* out; + dvr_timerec_entry_t* dte; + const char* str; + channel_t* ch = NULL; + uint32_t u32; + int64_t s64; + char ubuf[UUID_HEX_SIZE]; /* Options */ - if(!(str = htsmsg_get_str(in, "title"))) + if (!(str = htsmsg_get_str(in, "title"))) return htsp_error(htsp, N_("Invalid arguments")); if (htsp->htsp_version > 24) { @@ -2386,9 +2323,8 @@ htsp_method_addTimerecEntry(htsp_connection_t *htsp, htsmsg_t *in) if (s64 >= 0) ch = channel_find_by_id((uint32_t)s64); } - } - else { - if (!htsmsg_get_u32(in, "channelId", &u32)) // not sending = any channel + } else { + if (!htsmsg_get_u32(in, "channelId", &u32)) // not sending = any channel ch = channel_find_by_id(u32); } @@ -2405,8 +2341,7 @@ htsp_method_addTimerecEntry(htsp_connection_t *htsp, htsmsg_t *in) if (dte) { htsmsg_add_str(out, "id", idnode_uuid_as_str(&dte->dte_id, ubuf)); htsmsg_add_u32(out, "success", 1); - } - else { + } else { htsmsg_add_str(out, "error", "Could not add timerec entry"); htsmsg_add_u32(out, "success", 0); } @@ -2416,25 +2351,23 @@ htsp_method_addTimerecEntry(htsp_connection_t *htsp, htsmsg_t *in) /** * update a Dvr timerec entry */ -static htsmsg_t * -htsp_method_updateTimerecEntry(htsp_connection_t *htsp, htsmsg_t *in) -{ - const char *dteId; - dvr_timerec_entry_t *dte; - int64_t s64; - channel_t *ch = NULL; +static htsmsg_t* htsp_method_updateTimerecEntry(htsp_connection_t* htsp, htsmsg_t* in) { + const char* dteId; + dvr_timerec_entry_t* dte; + int64_t s64; + channel_t* ch = NULL; if (!(dteId = htsmsg_get_str(in, "id"))) return htsp_error(htsp, N_("Invalid arguments")); - if((dte = dvr_timerec_find_by_uuid(dteId)) == NULL) + if ((dte = dvr_timerec_find_by_uuid(dteId)) == NULL) return htsp_error(htsp, N_("Automatic time scheduler entry not found")); - if(dvr_timerec_entry_verify(dte, htsp->htsp_granted_access, 0)) + if (dvr_timerec_entry_verify(dte, htsp->htsp_granted_access, 0)) return htsp_error(htsp, N_("User does not have access")); /* Do we have a channel? No = keep old one */ - if (!htsmsg_get_s64(in, "channelId", &s64)) //s64 -> -1 = any channel + if (!htsmsg_get_s64(in, "channelId", &s64)) // s64 -> -1 = any channel { if (s64 >= 0) ch = channel_find_by_id((uint32_t)s64); @@ -2453,19 +2386,17 @@ htsp_method_updateTimerecEntry(htsp_connection_t *htsp, htsmsg_t *in) /** * delete a Dvr timerec entry */ -static htsmsg_t * -htsp_method_deleteTimerecEntry(htsp_connection_t *htsp, htsmsg_t *in) -{ - const char *dteId; - dvr_timerec_entry_t *dte; +static htsmsg_t* htsp_method_deleteTimerecEntry(htsp_connection_t* htsp, htsmsg_t* in) { + const char* dteId; + dvr_timerec_entry_t* dte; if (!(dteId = htsmsg_get_str(in, "id"))) return htsp_error(htsp, N_("Invalid arguments")); - if((dte = dvr_timerec_find_by_uuid(dteId)) == NULL) + if ((dte = dvr_timerec_find_by_uuid(dteId)) == NULL) return htsp_error(htsp, N_("Automatic time scheduler entry not found")); - if(dvr_timerec_entry_verify(dte, htsp->htsp_granted_access, 0)) + if (dvr_timerec_entry_verify(dte, htsp->htsp_granted_access, 0)) return htsp_error(htsp, N_("User does not have access")); timerec_destroy_by_id(dteId, 1); @@ -2490,29 +2421,27 @@ htsp_method_deleteTimerecEntry(htsp_connection_t *htsp, htsmsg_t *in) * 0=Cut, 1=Mute, 2=Scene, * 3=Commercial break. **/ -static htsmsg_t * -htsp_method_getDvrCutpoints(htsp_connection_t *htsp, htsmsg_t *in) -{ - uint32_t dvrEntryId; - dvr_entry_t *de; +static htsmsg_t* htsp_method_getDvrCutpoints(htsp_connection_t* htsp, htsmsg_t* in) { + uint32_t dvrEntryId; + dvr_entry_t* de; if (htsmsg_get_u32(in, "id", &dvrEntryId)) return htsp_error(htsp, N_("Invalid arguments")); - if((de = dvr_entry_find_by_id(dvrEntryId)) == NULL) + if ((de = dvr_entry_find_by_id(dvrEntryId)) == NULL) return htsp_error(htsp, N_("DVR schedule not found")); - if(dvr_entry_verify(de, htsp->htsp_granted_access, 1)) + if (dvr_entry_verify(de, htsp->htsp_granted_access, 1)) return htsp_error(htsp, N_("User does not have access")); - htsmsg_t *msg = htsmsg_create_map(); + htsmsg_t* msg = htsmsg_create_map(); - dvr_cutpoint_list_t *list = dvr_get_cutpoint_list(de); + dvr_cutpoint_list_t* list = dvr_get_cutpoint_list(de); if (list != NULL) { - htsmsg_t *cutpoint_list = htsmsg_create_list(); - dvr_cutpoint_t *cp; - TAILQ_FOREACH(cp, list, dc_link) { - htsmsg_t *cutpoint = htsmsg_create_map(); + htsmsg_t* cutpoint_list = htsmsg_create_list(); + dvr_cutpoint_t* cp; + TAILQ_FOREACH (cp, list, dc_link) { + htsmsg_t* cutpoint = htsmsg_create_map(); htsmsg_add_u32(cutpoint, "start", cp->dc_start_ms); htsmsg_add_u32(cutpoint, "end", cp->dc_end_ms); htsmsg_add_u32(cutpoint, "type", cp->dc_type); @@ -2531,17 +2460,15 @@ htsp_method_getDvrCutpoints(htsp_connection_t *htsp, htsmsg_t *in) /** * Request a ticket for a http url pointing to a channel or dvr */ -static htsmsg_t * -htsp_method_getTicket(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsmsg_t *out; - uint32_t id; - char path[255]; - const char *ticket = NULL; - channel_t *ch; - dvr_entry_t *de; - - if(!htsmsg_get_u32(in, "channelId", &id)) { +static htsmsg_t* htsp_method_getTicket(htsp_connection_t* htsp, htsmsg_t* in) { + htsmsg_t* out; + uint32_t id; + char path[255]; + const char* ticket = NULL; + channel_t* ch; + dvr_entry_t* de; + + if (!htsmsg_get_u32(in, "channelId", &id)) { if (!(ch = channel_find_by_id(id))) return htsp_error(htsp, N_("Channel not found")); if (!htsp_user_access_channel(htsp, ch)) @@ -2549,7 +2476,7 @@ htsp_method_getTicket(htsp_connection_t *htsp, htsmsg_t *in) snprintf(path, sizeof(path), "/stream/channelid/%d", id); ticket = access_ticket_create(path, htsp->htsp_granted_access); - } else if(!htsmsg_get_u32(in, "dvrId", &id)) { + } else if (!htsmsg_get_u32(in, "dvrId", &id)) { if (!(de = dvr_entry_find_by_id(id))) return htsp_error(htsp, N_("DVR schedule does not exist")); if (!htsp_user_access_channel(htsp, de->de_channel)) @@ -2572,9 +2499,8 @@ htsp_method_getTicket(htsp_connection_t *htsp, htsmsg_t *in) /* * */ -static void _bytes_out_cb(void *aux) -{ - htsp_subscription_t *hs = aux; +static void _bytes_out_cb(void* aux) { + htsp_subscription_t* hs = aux; if (hs->hs_s) { subscription_add_bytes_out(hs->hs_s, atomic_exchange(&hs->hs_s_bytes_out, 0)); mtimer_arm_rel(&hs->hs_s_bytes_out_timer, _bytes_out_cb, hs, ms2mono(200)); @@ -2584,23 +2510,21 @@ static void _bytes_out_cb(void *aux) /** * Request subscription for a channel */ -static htsmsg_t * -htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in) -{ - uint32_t chid, sid, weight, req90khz, timeshiftPeriod = 0; - const char *str, *profile_id; - channel_t *ch; - htsp_subscription_t *hs; - profile_t *pro; - - if(htsmsg_get_u32(in, "subscriptionId", &sid)) +static htsmsg_t* htsp_method_subscribe(htsp_connection_t* htsp, htsmsg_t* in) { + uint32_t chid, sid, weight, req90khz, timeshiftPeriod = 0; + const char * str, *profile_id; + channel_t* ch; + htsp_subscription_t* hs; + profile_t* pro; + + if (htsmsg_get_u32(in, "subscriptionId", &sid)) return htsp_error(htsp, N_("Invalid arguments")); - if(!htsmsg_get_u32(in, "channelId", &chid)) { - if((ch = channel_find_by_id(chid)) == NULL) + if (!htsmsg_get_u32(in, "channelId", &chid)) { + if ((ch = channel_find_by_id(chid)) == NULL) return htsp_error(htsp, N_("Channel does not exist")); - } else if((str = htsmsg_get_str(in, "channelName")) != NULL) { - if((ch = channel_find_by_name(str)) == NULL) + } else if ((str = htsmsg_get_str(in, "channelName")) != NULL) { + if ((ch = channel_find_by_name(str)) == NULL) return htsp_error(htsp, N_("Channel does not exist")); } else { return htsp_error(htsp, N_("Invalid arguments")); @@ -2608,13 +2532,13 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in) if (!htsp_user_access_channel(htsp, ch)) return htsp_error(htsp, N_("User does not have access")); - weight = htsmsg_get_u32_or_default(in, "weight", 0); + weight = htsmsg_get_u32_or_default(in, "weight", 0); req90khz = htsmsg_get_u32_or_default(in, "90khz", 0); profile_id = htsmsg_get_str(in, "profile"); #if ENABLE_TIMESHIFT - if(ch->ch_remote_timeshift) { + if (ch->ch_remote_timeshift) { timeshiftPeriod = ~0; } else { if (timeshift_conf.enabled) { @@ -2629,10 +2553,9 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in) hs = calloc(1, sizeof(htsp_subscription_t)); - hs->hs_htsp = htsp; - hs->hs_90khz = req90khz; - hs->hs_queue_depth = htsmsg_get_u32_or_default(in, "queueDepth", - HTSP_DEFAULT_QUEUE_DEPTH); + hs->hs_htsp = htsp; + hs->hs_90khz = req90khz; + hs->hs_queue_depth = htsmsg_get_u32_or_default(in, "queueDepth", HTSP_DEFAULT_QUEUE_DEPTH); htsp_init_queue(&hs->hs_q, 0); hs->hs_sid = sid; @@ -2646,17 +2569,20 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in) if (timeshiftPeriod == ~0) tvhdebug(LS_HTSP, "using timeshift buffer (unlimited)"); else - tvhdebug(LS_HTSP, "using timeshift buffer (%u mins)", - timeshiftPeriod / 60); + tvhdebug(LS_HTSP, "using timeshift buffer (%u mins)", timeshiftPeriod / 60); } } #endif - pro = profile_find_by_list(htsp->htsp_granted_access->aa_profiles, profile_id, - "htsp", SUBSCRIPTION_PACKET | SUBSCRIPTION_HTSP); + pro = profile_find_by_list(htsp->htsp_granted_access->aa_profiles, + profile_id, + "htsp", + SUBSCRIPTION_PACKET | SUBSCRIPTION_HTSP); profile_chain_init(&hs->hs_prch, pro, ch, 1); - if (profile_chain_work(&hs->hs_prch, &hs->hs_input, timeshiftPeriod, ch->ch_remote_timeshift ? - PROFILE_WORK_REMOTE_TS : PROFILE_WORK_NONE)) { + if (profile_chain_work(&hs->hs_prch, + &hs->hs_input, + timeshiftPeriod, + ch->ch_remote_timeshift ? PROFILE_WORK_REMOTE_TS : PROFILE_WORK_NONE)) { tvherror(LS_HTSP, "unable to create profile chain '%s'", profile_get_name(pro)); profile_chain_close(&hs->hs_prch); free(hs); @@ -2671,12 +2597,12 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in) * if we support those * */ - htsmsg_t *rep = htsmsg_create_map(); - if(req90khz) + htsmsg_t* rep = htsmsg_create_map(); + if (req90khz) htsmsg_add_u32(rep, "90khz", 1); - if(hs->hs_prch.prch_sharer->prsh_tsfix) + if (hs->hs_prch.prch_sharer->prsh_tsfix) htsmsg_add_u32(rep, "normts", 1); - if(hs->hs_s) + if (hs->hs_s) htsmsg_add_u32(rep, "weight", hs->hs_s->ths_weight >= 0 ? hs->hs_s->ths_weight : 0); #if ENABLE_TIMESHIFT @@ -2695,17 +2621,20 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in) */ LIST_INSERT_HEAD(&htsp->htsp_subscriptions, hs, hs_link); - tvhdebug(LS_HTSP, "%s - subscribe to %s using profile %s", - htsp->htsp_logname, channel_get_name(ch, channel_blank_name), - profile_get_name(pro)); - hs->hs_s = subscription_create_from_channel(&hs->hs_prch, NULL, weight, - htsp->htsp_logname, - SUBSCRIPTION_PACKET | - SUBSCRIPTION_STREAMING, - htsp->htsp_peername, - htsp->htsp_granted_access->aa_representative, - htsp->htsp_clientname, - NULL); + tvhdebug(LS_HTSP, + "%s - subscribe to %s using profile %s", + htsp->htsp_logname, + channel_get_name(ch, channel_blank_name), + profile_get_name(pro)); + hs->hs_s = subscription_create_from_channel(&hs->hs_prch, + NULL, + weight, + htsp->htsp_logname, + SUBSCRIPTION_PACKET | SUBSCRIPTION_STREAMING, + htsp->htsp_peername, + htsp->htsp_granted_access->aa_representative, + htsp->htsp_clientname, + NULL); if (hs->hs_s) mtimer_arm_rel(&hs->hs_s_bytes_out_timer, _bytes_out_cb, hs, ms2mono(200)); return NULL; @@ -2714,17 +2643,15 @@ htsp_method_subscribe(htsp_connection_t *htsp, htsmsg_t *in) /** * Request unsubscription for a channel */ -static htsmsg_t * -htsp_method_unsubscribe(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsp_subscription_t *s; - uint32_t sid; +static htsmsg_t* htsp_method_unsubscribe(htsp_connection_t* htsp, htsmsg_t* in) { + htsp_subscription_t* s; + uint32_t sid; - if(htsmsg_get_u32(in, "subscriptionId", &sid)) + if (htsmsg_get_u32(in, "subscriptionId", &sid)) return htsp_error(htsp, N_("Invalid arguments")); - LIST_FOREACH(s, &htsp->htsp_subscriptions, hs_link) - if(s->hs_sid == sid) + LIST_FOREACH (s, &htsp->htsp_subscriptions, hs_link) + if (s->hs_sid == sid) break; /* @@ -2733,7 +2660,7 @@ htsp_method_unsubscribe(htsp_connection_t *htsp, htsmsg_t *in) */ htsp_reply(htsp, in, htsmsg_create_map()); - if(s == NULL) + if (s == NULL) return NULL; /* Subscription did not exist, but we don't really care */ htsp_subscription_destroy(htsp, s); @@ -2743,22 +2670,20 @@ htsp_method_unsubscribe(htsp_connection_t *htsp, htsmsg_t *in) /** * Change weight for a subscription */ -static htsmsg_t * -htsp_method_change_weight(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsp_subscription_t *hs; - uint32_t sid, weight; +static htsmsg_t* htsp_method_change_weight(htsp_connection_t* htsp, htsmsg_t* in) { + htsp_subscription_t* hs; + uint32_t sid, weight; - if(htsmsg_get_u32(in, "subscriptionId", &sid)) + if (htsmsg_get_u32(in, "subscriptionId", &sid)) return htsp_error(htsp, N_("Invalid arguments")); weight = htsmsg_get_u32_or_default(in, "weight", 0); - LIST_FOREACH(hs, &htsp->htsp_subscriptions, hs_link) - if(hs->hs_sid == sid) + LIST_FOREACH (hs, &htsp->htsp_subscriptions, hs_link) + if (hs->hs_sid == sid) break; - if(hs == NULL) + if (hs == NULL) return htsp_error(htsp, N_("Subscription does not exist")); htsp_reply(htsp, in, htsmsg_create_map()); @@ -2770,36 +2695,37 @@ htsp_method_change_weight(htsp_connection_t *htsp, htsmsg_t *in) /** * Skip stream */ -static htsmsg_t * -htsp_method_skip(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsp_subscription_t *hs; - uint32_t sid, abs; - int64_t s64; - streaming_skip_t skip; - - if(htsmsg_get_u32(in, "subscriptionId", &sid)) +static htsmsg_t* htsp_method_skip(htsp_connection_t* htsp, htsmsg_t* in) { + htsp_subscription_t* hs; + uint32_t sid, abs; + int64_t s64; + streaming_skip_t skip; + + if (htsmsg_get_u32(in, "subscriptionId", &sid)) return htsp_error(htsp, N_("Invalid arguments")); - LIST_FOREACH(hs, &htsp->htsp_subscriptions, hs_link) - if(hs->hs_sid == sid) + LIST_FOREACH (hs, &htsp->htsp_subscriptions, hs_link) + if (hs->hs_sid == sid) break; - if(hs == NULL) + if (hs == NULL) return htsp_error(htsp, N_("Subscription does not exist")); abs = htsmsg_get_u32_or_default(in, "absolute", 0); memset(&skip, 0, sizeof(skip)); - if(!htsmsg_get_s64(in, "time", &s64)) { + if (!htsmsg_get_s64(in, "time", &s64)) { skip.type = abs ? SMT_SKIP_ABS_TIME : SMT_SKIP_REL_TIME; skip.time = hs->hs_90khz ? s64 : ts_rescale_inv(s64, 1000000); - tvhtrace(LS_HTSP_SUB, "skip: %s %"PRId64" (%s)", abs ? "abs" : "rel", - skip.time, hs->hs_90khz ? "90kHz" : "1MHz"); + tvhtrace(LS_HTSP_SUB, + "skip: %s %" PRId64 " (%s)", + abs ? "abs" : "rel", + skip.time, + hs->hs_90khz ? "90kHz" : "1MHz"); } else if (!htsmsg_get_s64(in, "size", &s64)) { skip.type = abs ? SMT_SKIP_ABS_SIZE : SMT_SKIP_REL_SIZE; skip.size = s64; - tvhtrace(LS_HTSP_SUB, "skip: %s by size %"PRId64, abs ? "abs" : "rel", s64); + tvhtrace(LS_HTSP_SUB, "skip: %s by size %" PRId64, abs ? "abs" : "rel", s64); } else { return htsp_error(htsp, N_("Invalid arguments")); } @@ -2813,23 +2739,21 @@ htsp_method_skip(htsp_connection_t *htsp, htsmsg_t *in) /* * Set stream speed */ -static htsmsg_t * -htsp_method_speed(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsp_subscription_t *hs; - uint32_t sid; - int32_t speed; - - if(htsmsg_get_u32(in, "subscriptionId", &sid)) +static htsmsg_t* htsp_method_speed(htsp_connection_t* htsp, htsmsg_t* in) { + htsp_subscription_t* hs; + uint32_t sid; + int32_t speed; + + if (htsmsg_get_u32(in, "subscriptionId", &sid)) return htsp_error(htsp, N_("Invalid arguments")); - if(htsmsg_get_s32(in, "speed", &speed)) + if (htsmsg_get_s32(in, "speed", &speed)) return htsp_error(htsp, N_("Invalid arguments")); - LIST_FOREACH(hs, &htsp->htsp_subscriptions, hs_link) - if(hs->hs_sid == sid) + LIST_FOREACH (hs, &htsp->htsp_subscriptions, hs_link) + if (hs->hs_sid == sid) break; - if(hs == NULL) + if (hs == NULL) return htsp_error(htsp, N_("Subscription does not exist")); tvhtrace(LS_HTSP_SUB, "speed: %d", speed); @@ -2842,21 +2766,19 @@ htsp_method_speed(htsp_connection_t *htsp, htsmsg_t *in) /* * Revert to live */ -static htsmsg_t * -htsp_method_live(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsp_subscription_t *hs; - uint32_t sid; - streaming_skip_t skip; - - if(htsmsg_get_u32(in, "subscriptionId", &sid)) +static htsmsg_t* htsp_method_live(htsp_connection_t* htsp, htsmsg_t* in) { + htsp_subscription_t* hs; + uint32_t sid; + streaming_skip_t skip; + + if (htsmsg_get_u32(in, "subscriptionId", &sid)) return htsp_error(htsp, N_("Invalid arguments")); - LIST_FOREACH(hs, &htsp->htsp_subscriptions, hs_link) - if(hs->hs_sid == sid) + LIST_FOREACH (hs, &htsp->htsp_subscriptions, hs_link) + if (hs->hs_sid == sid) break; - if(hs == NULL) + if (hs == NULL) return htsp_error(htsp, N_("Subscription does not exist")); memset(&skip, 0, sizeof(skip)); @@ -2871,62 +2793,56 @@ htsp_method_live(htsp_connection_t *htsp, htsmsg_t *in) /** * Change filters for a subscription */ -static htsmsg_t * -htsp_method_filter_stream(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsp_subscription_t *hs; - uint32_t sid; - htsmsg_t *l; - if(htsmsg_get_u32(in, "subscriptionId", &sid)) +static htsmsg_t* htsp_method_filter_stream(htsp_connection_t* htsp, htsmsg_t* in) { + htsp_subscription_t* hs; + uint32_t sid; + htsmsg_t* l; + if (htsmsg_get_u32(in, "subscriptionId", &sid)) return htsp_error(htsp, N_("Invalid arguments")); - LIST_FOREACH(hs, &htsp->htsp_subscriptions, hs_link) - if(hs->hs_sid == sid) + LIST_FOREACH (hs, &htsp->htsp_subscriptions, hs_link) + if (hs->hs_sid == sid) break; - if(hs == NULL) + if (hs == NULL) return htsp_error(htsp, N_("Subscription does not exist")); - if((l = htsmsg_get_list(in, "enable")) != NULL) { - htsmsg_field_t *f; + if ((l = htsmsg_get_list(in, "enable")) != NULL) { + htsmsg_field_t* f; HTSMSG_FOREACH(f, l) { - if(f->hmf_type == HMF_S64) + if (f->hmf_type == HMF_S64) htsp_enable_stream(hs, f->hmf_s64); } } - if((l = htsmsg_get_list(in, "disable")) != NULL) { - htsmsg_field_t *f; + if ((l = htsmsg_get_list(in, "disable")) != NULL) { + htsmsg_field_t* f; HTSMSG_FOREACH(f, l) { - if(f->hmf_type == HMF_S64) + if (f->hmf_type == HMF_S64) htsp_disable_stream(hs, f->hmf_s64); } } return htsmsg_create_map(); } - /** * Open file */ -static htsmsg_t * -htsp_method_file_open(htsp_connection_t *htsp, htsmsg_t *in) -{ +static htsmsg_t* htsp_method_file_open(htsp_connection_t* htsp, htsmsg_t* in) { const char *str, *s2; - const char *filename = NULL; - char buf[PATH_MAX]; + const char* filename = NULL; + char buf[PATH_MAX]; - if((str = htsmsg_get_str(in, "file")) == NULL) + if ((str = htsmsg_get_str(in, "file")) == NULL) return htsp_error(htsp, N_("Invalid arguments")); // optional leading slash if (*str == '/') str++; - if((s2 = tvh_strbegins(str, "dvr/")) != NULL || - (s2 = tvh_strbegins(str, "dvrfile/")) != NULL) { - dvr_entry_t *de = dvr_entry_find_by_id(atoi(s2)); - if(de == NULL) + if ((s2 = tvh_strbegins(str, "dvr/")) != NULL || (s2 = tvh_strbegins(str, "dvrfile/")) != NULL) { + dvr_entry_t* de = dvr_entry_find_by_id(atoi(s2)); + if (de == NULL) return htsp_error(htsp, N_("DVR schedule does not exist")); if (dvr_entry_verify(de, htsp->htsp_granted_access, 1)) @@ -2958,20 +2874,18 @@ htsp_method_file_open(htsp_connection_t *htsp, htsmsg_t *in) /** * */ -static htsmsg_t * -htsp_method_file_read(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsp_file_t *hf = htsp_file_find(htsp, in); - htsmsg_t *rep = NULL; - const char *e = NULL; - int64_t off; - int64_t size; - int fd; - - if(hf == NULL) +static htsmsg_t* htsp_method_file_read(htsp_connection_t* htsp, htsmsg_t* in) { + htsp_file_t* hf = htsp_file_find(htsp, in); + htsmsg_t* rep = NULL; + const char* e = NULL; + int64_t off; + int64_t size; + int fd; + + if (hf == NULL) return htsp_error(htsp, N_("Invalid file")); - if(htsmsg_get_s64(in, "size", &size)) + if (htsmsg_get_s64(in, "size", &size)) return htsp_error(htsp, N_("Invalid parameters")); fd = hf->hf_fd; @@ -2980,20 +2894,20 @@ htsp_method_file_read(htsp_connection_t *htsp, htsmsg_t *in) /* Seek (optional) */ if (!htsmsg_get_s64(in, "offset", &off)) - if(lseek(fd, off, SEEK_SET) != off) { + if (lseek(fd, off, SEEK_SET) != off) { e = "Seek error"; goto error; } /* Read */ - void *m = malloc(size); - if(m == NULL) { + void* m = malloc(size); + if (m == NULL) { e = N_("Not enough memory"); goto error; } int r = read(fd, m, size); - if(r < 0) { + if (r < 0) { free(m); e = N_("Read error"); goto error; @@ -3012,27 +2926,27 @@ error: /** * */ -static htsmsg_t * -htsp_method_file_close(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsp_file_t *hf = htsp_file_find(htsp, in); - uint32_t u32; - dvr_entry_t *de; - - if(hf == NULL) +static htsmsg_t* htsp_method_file_close(htsp_connection_t* htsp, htsmsg_t* in) { + htsp_file_t* hf = htsp_file_find(htsp, in); + uint32_t u32; + dvr_entry_t* de; + + if (hf == NULL) return htsp_error(htsp, N_("Invalid file")); - if (hf->hf_de_id > 0 && (de = dvr_entry_find_by_id(hf->hf_de_id))) - { + if (hf->hf_de_id > 0 && (de = dvr_entry_find_by_id(hf->hf_de_id))) { int save = 0; - /* Only allow incrementing playcount on file close, the rest can be done with "updateDvrEntry" */ - if (htsp->htsp_version < 27 || htsmsg_get_u32_or_default(in, "playcount", HTSP_DVR_PLAYCOUNT_INCR) == HTSP_DVR_PLAYCOUNT_INCR) { + /* Only allow incrementing playcount on file close, the rest can be done with "updateDvrEntry" + */ + if (htsp->htsp_version < 27 || + htsmsg_get_u32_or_default(in, "playcount", HTSP_DVR_PLAYCOUNT_INCR) == + HTSP_DVR_PLAYCOUNT_INCR) { dvr_entry_incr_playcount(de); save = 1; } - if(htsp->htsp_version >= 27 && !htsmsg_get_u32(in, "playposition", &u32)) { + if (htsp->htsp_version >= 27 && !htsmsg_get_u32(in, "playposition", &u32)) { de->de_playposition = u32; - save = 1; + save = 1; } if (save) dvr_entry_changed(de); @@ -3047,22 +2961,20 @@ htsp_method_file_close(htsp_connection_t *htsp, htsmsg_t *in) /** * */ -static htsmsg_t * -htsp_method_file_stat(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsp_file_t *hf = htsp_file_find(htsp, in); - htsmsg_t *rep; - struct stat st; - int fd; +static htsmsg_t* htsp_method_file_stat(htsp_connection_t* htsp, htsmsg_t* in) { + htsp_file_t* hf = htsp_file_find(htsp, in); + htsmsg_t* rep; + struct stat st; + int fd; - if(hf == NULL) + if (hf == NULL) return htsp_error(htsp, N_("Invalid file")); fd = hf->hf_fd; tvh_mutex_unlock(&global_lock); rep = htsmsg_create_map(); - if(!fstat(fd, &st)) { + if (!fstat(fd, &st)) { htsmsg_add_s64(rep, "size", st.st_size); htsmsg_add_s64(rep, "mtime", st.st_mtime); } @@ -3074,16 +2986,14 @@ htsp_method_file_stat(htsp_connection_t *htsp, htsmsg_t *in) /** * */ -static htsmsg_t * -htsp_method_file_seek(htsp_connection_t *htsp, htsmsg_t *in) -{ - htsp_file_t *hf = htsp_file_find(htsp, in); - htsmsg_t *rep; - const char *str; - int64_t off; - int fd, whence; - - if(hf == NULL) +static htsmsg_t* htsp_method_file_seek(htsp_connection_t* htsp, htsmsg_t* in) { + htsp_file_t* hf = htsp_file_find(htsp, in); + htsmsg_t* rep; + const char* str; + int64_t off; + int fd, whence; + + if (hf == NULL) return htsp_error(htsp, N_("Invalid file")); if (htsmsg_get_s64(in, "offset", &off)) @@ -3120,9 +3030,7 @@ htsp_method_file_seek(htsp_connection_t *htsp, htsmsg_t *in) /** * */ -static htsmsg_t * -htsp_method_getProfiles(htsp_connection_t *htsp, htsmsg_t *in) -{ +static htsmsg_t* htsp_method_getProfiles(htsp_connection_t* htsp, htsmsg_t* in) { htsmsg_t *out, *l; l = htsmsg_create_list(); @@ -3139,49 +3047,49 @@ htsp_method_getProfiles(htsp_connection_t *htsp, htsmsg_t *in) * HTSP methods */ struct { - const char *name; - htsmsg_t *(*fn)(htsp_connection_t *htsp, htsmsg_t *in); + const char* name; + htsmsg_t* (*fn)(htsp_connection_t* htsp, htsmsg_t* in); int privmask; } htsp_methods[] = { - { "hello", htsp_method_hello, ACCESS_ANONYMOUS}, - { "authenticate", htsp_method_authenticate, ACCESS_ANONYMOUS}, - { "api", htsp_method_api, ACCESS_ANONYMOUS}, - { "getDiskSpace", htsp_method_getDiskSpace, ACCESS_HTSP_STREAMING}, - { "getSysTime", htsp_method_getSysTime, ACCESS_HTSP_STREAMING}, - { "enableAsyncMetadata", htsp_method_async, ACCESS_HTSP_STREAMING}, - { "getChannel", htsp_method_getChannel, ACCESS_HTSP_STREAMING}, - { "getEvent", htsp_method_getEvent, ACCESS_HTSP_STREAMING}, - { "getEvents", htsp_method_getEvents, ACCESS_HTSP_STREAMING}, - { "epgQuery", htsp_method_epgQuery, ACCESS_HTSP_STREAMING}, - { "getEpgObject", htsp_method_getEpgObject, ACCESS_HTSP_STREAMING}, - { "getDvrConfigs", htsp_method_getDvrConfigs, ACCESS_HTSP_RECORDER}, - { "addDvrEntry", htsp_method_addDvrEntry, ACCESS_HTSP_RECORDER}, - { "updateDvrEntry", htsp_method_updateDvrEntry, ACCESS_HTSP_RECORDER}, - { "stopDvrEntry", htsp_method_stopDvrEntry, ACCESS_HTSP_RECORDER}, - { "cancelDvrEntry", htsp_method_cancelDvrEntry, ACCESS_HTSP_RECORDER}, - { "deleteDvrEntry", htsp_method_deleteDvrEntry, ACCESS_HTSP_RECORDER}, - { "addAutorecEntry", htsp_method_addAutorecEntry, ACCESS_HTSP_RECORDER}, - { "updateAutorecEntry", htsp_method_updateAutorecEntry, ACCESS_HTSP_RECORDER}, - { "deleteAutorecEntry", htsp_method_deleteAutorecEntry, ACCESS_HTSP_RECORDER}, - { "addTimerecEntry", htsp_method_addTimerecEntry, ACCESS_HTSP_RECORDER}, - { "updateTimerecEntry", htsp_method_updateTimerecEntry, ACCESS_HTSP_RECORDER}, - { "deleteTimerecEntry", htsp_method_deleteTimerecEntry, ACCESS_HTSP_RECORDER}, - { "getDvrCutpoints", htsp_method_getDvrCutpoints, ACCESS_HTSP_RECORDER}, - { "getTicket", htsp_method_getTicket, ACCESS_HTSP_STREAMING}, - { "subscribe", htsp_method_subscribe, ACCESS_HTSP_STREAMING}, - { "unsubscribe", htsp_method_unsubscribe, ACCESS_HTSP_STREAMING}, - { "subscriptionChangeWeight", htsp_method_change_weight, ACCESS_HTSP_STREAMING}, - { "subscriptionSeek", htsp_method_skip, ACCESS_HTSP_STREAMING}, - { "subscriptionSkip", htsp_method_skip, ACCESS_HTSP_STREAMING}, - { "subscriptionSpeed", htsp_method_speed, ACCESS_HTSP_STREAMING}, - { "subscriptionLive", htsp_method_live, ACCESS_HTSP_STREAMING}, - { "subscriptionFilterStream", htsp_method_filter_stream, ACCESS_HTSP_STREAMING}, - { "getProfiles", htsp_method_getProfiles, ACCESS_HTSP_STREAMING}, - { "fileOpen", htsp_method_file_open, ACCESS_HTSP_RECORDER}, - { "fileRead", htsp_method_file_read, ACCESS_HTSP_RECORDER}, - { "fileClose", htsp_method_file_close, ACCESS_HTSP_RECORDER}, - { "fileStat", htsp_method_file_stat, ACCESS_HTSP_RECORDER}, - { "fileSeek", htsp_method_file_seek, ACCESS_HTSP_RECORDER}, + {"hello", htsp_method_hello, ACCESS_ANONYMOUS}, + {"authenticate", htsp_method_authenticate, ACCESS_ANONYMOUS}, + {"api", htsp_method_api, ACCESS_ANONYMOUS}, + {"getDiskSpace", htsp_method_getDiskSpace, ACCESS_HTSP_STREAMING}, + {"getSysTime", htsp_method_getSysTime, ACCESS_HTSP_STREAMING}, + {"enableAsyncMetadata", htsp_method_async, ACCESS_HTSP_STREAMING}, + {"getChannel", htsp_method_getChannel, ACCESS_HTSP_STREAMING}, + {"getEvent", htsp_method_getEvent, ACCESS_HTSP_STREAMING}, + {"getEvents", htsp_method_getEvents, ACCESS_HTSP_STREAMING}, + {"epgQuery", htsp_method_epgQuery, ACCESS_HTSP_STREAMING}, + {"getEpgObject", htsp_method_getEpgObject, ACCESS_HTSP_STREAMING}, + {"getDvrConfigs", htsp_method_getDvrConfigs, ACCESS_HTSP_RECORDER}, + {"addDvrEntry", htsp_method_addDvrEntry, ACCESS_HTSP_RECORDER}, + {"updateDvrEntry", htsp_method_updateDvrEntry, ACCESS_HTSP_RECORDER}, + {"stopDvrEntry", htsp_method_stopDvrEntry, ACCESS_HTSP_RECORDER}, + {"cancelDvrEntry", htsp_method_cancelDvrEntry, ACCESS_HTSP_RECORDER}, + {"deleteDvrEntry", htsp_method_deleteDvrEntry, ACCESS_HTSP_RECORDER}, + {"addAutorecEntry", htsp_method_addAutorecEntry, ACCESS_HTSP_RECORDER}, + {"updateAutorecEntry", htsp_method_updateAutorecEntry, ACCESS_HTSP_RECORDER}, + {"deleteAutorecEntry", htsp_method_deleteAutorecEntry, ACCESS_HTSP_RECORDER}, + {"addTimerecEntry", htsp_method_addTimerecEntry, ACCESS_HTSP_RECORDER}, + {"updateTimerecEntry", htsp_method_updateTimerecEntry, ACCESS_HTSP_RECORDER}, + {"deleteTimerecEntry", htsp_method_deleteTimerecEntry, ACCESS_HTSP_RECORDER}, + {"getDvrCutpoints", htsp_method_getDvrCutpoints, ACCESS_HTSP_RECORDER}, + {"getTicket", htsp_method_getTicket, ACCESS_HTSP_STREAMING}, + {"subscribe", htsp_method_subscribe, ACCESS_HTSP_STREAMING}, + {"unsubscribe", htsp_method_unsubscribe, ACCESS_HTSP_STREAMING}, + {"subscriptionChangeWeight", htsp_method_change_weight, ACCESS_HTSP_STREAMING}, + {"subscriptionSeek", htsp_method_skip, ACCESS_HTSP_STREAMING}, + {"subscriptionSkip", htsp_method_skip, ACCESS_HTSP_STREAMING}, + {"subscriptionSpeed", htsp_method_speed, ACCESS_HTSP_STREAMING}, + {"subscriptionLive", htsp_method_live, ACCESS_HTSP_STREAMING}, + {"subscriptionFilterStream", htsp_method_filter_stream, ACCESS_HTSP_STREAMING}, + {"getProfiles", htsp_method_getProfiles, ACCESS_HTSP_STREAMING}, + {"fileOpen", htsp_method_file_open, ACCESS_HTSP_RECORDER}, + {"fileRead", htsp_method_file_read, ACCESS_HTSP_RECORDER}, + {"fileClose", htsp_method_file_close, ACCESS_HTSP_RECORDER}, + {"fileStat", htsp_method_file_stat, ACCESS_HTSP_RECORDER}, + {"fileSeek", htsp_method_file_seek, ACCESS_HTSP_RECORDER}, }; #define NUM_METHODS (sizeof(htsp_methods) / sizeof(htsp_methods[0])) @@ -3194,43 +3102,39 @@ struct { * */ struct htsp_verify_struct { - const uint8_t *digest; - const uint8_t *challenge; + const uint8_t* digest; + const uint8_t* challenge; }; -static int -htsp_verify_callback(void *aux, const char *passwd) -{ - struct htsp_verify_struct *v = aux; - uint8_t d[20]; +static int htsp_verify_callback(void* aux, const char* passwd) { + struct htsp_verify_struct* v = aux; + uint8_t d[20]; - if (v->digest == NULL || v->challenge == NULL) return 0; - sha1_calc(d, (uint8_t *)passwd, strlen(passwd), v->challenge, 32); + if (v->digest == NULL || v->challenge == NULL) + return 0; + sha1_calc(d, (uint8_t*)passwd, strlen(passwd), v->challenge, 32); return memcmp(d, v->digest, 20) == 0; } /** * Raise privs by field in message */ -static int -htsp_authenticate(htsp_connection_t *htsp, htsmsg_t *m) -{ +static int htsp_authenticate(htsp_connection_t* htsp, htsmsg_t* m) { struct htsp_verify_struct vs; - const char *username; - const void *digest; - size_t digestlen; - access_t *rights; - int privgain = 0; + const char* username; + const void* digest; + size_t digestlen; + access_t* rights; + int privgain = 0; - if((username = htsmsg_get_str(m, "username")) == NULL) + if ((username = htsmsg_get_str(m, "username")) == NULL) return 0; - if(!htsmsg_get_bin(m, "digest", &digest, &digestlen)) { + if (!htsmsg_get_bin(m, "digest", &digest, &digestlen)) { - vs.digest = digest; + vs.digest = digest; vs.challenge = htsp->htsp_challenge; - rights = access_get(htsp->htsp_peer, username, - htsp_verify_callback, &vs); + rights = access_get(htsp->htsp_peer, username, htsp_verify_callback, &vs); if (rights->aa_rights == 0) { tvhinfo(LS_HTSP, "%s: Unauthorized access", htsp->htsp_logname); @@ -3239,15 +3143,13 @@ htsp_authenticate(htsp_connection_t *htsp, htsmsg_t *m) } rights->aa_rights |= ACCESS_HTSP_INTERFACE; - privgain = (rights->aa_rights | - htsp->htsp_granted_access->aa_rights) != - htsp->htsp_granted_access->aa_rights; + privgain = (rights->aa_rights | htsp->htsp_granted_access->aa_rights) != + htsp->htsp_granted_access->aa_rights; - tvhinfo(LS_HTSP, "%s: Identified as user '%s'", - htsp->htsp_logname, username); + tvhinfo(LS_HTSP, "%s: Identified as user '%s'", htsp->htsp_logname, username); tvh_str_update(&htsp->htsp_username, username); htsp_update_logname(htsp); - if(privgain) + if (privgain) tvhinfo(LS_HTSP, "%s: Privileges updated", htsp->htsp_logname); access_destroy(htsp->htsp_granted_access); @@ -3258,11 +3160,9 @@ htsp_authenticate(htsp_connection_t *htsp, htsmsg_t *m) } else { - tvhinfo(LS_HTSP, "%s: Identified as user '%s' (unverified)", - htsp->htsp_logname, username); + tvhinfo(LS_HTSP, "%s: Identified as user '%s' (unverified)", htsp->htsp_logname, username); tvh_str_update(&htsp->htsp_username, username); htsp_update_logname(htsp); - } notify_reload("connections"); @@ -3273,30 +3173,28 @@ htsp_authenticate(htsp_connection_t *htsp, htsmsg_t *m) /** * timeout is in ms, 0 means infinite timeout */ -static int -htsp_read_message(htsp_connection_t *htsp, htsmsg_t **mp, int timeout) -{ - int v; +static int htsp_read_message(htsp_connection_t* htsp, htsmsg_t** mp, int timeout) { + int v; uint32_t len; - uint8_t data[4]; - void *buf; + uint8_t data[4]; + void* buf; - v = timeout ? tcp_read_timeout(htsp->htsp_fd, data, 4, timeout) : - tcp_read(htsp->htsp_fd, data, 4); + v = timeout ? tcp_read_timeout(htsp->htsp_fd, data, 4, timeout) + : tcp_read(htsp->htsp_fd, data, 4); - if(v != 0) + if (v != 0) return v; len = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]; - if(len > 1024 * 1024) + if (len > 1024 * 1024) return EMSGSIZE; - if((buf = malloc(len)) == NULL) + if ((buf = malloc(len)) == NULL) return ENOMEM; - v = timeout ? tcp_read_timeout(htsp->htsp_fd, buf, len, timeout) : - tcp_read(htsp->htsp_fd, buf, len); + v = timeout ? tcp_read_timeout(htsp->htsp_fd, buf, len, timeout) + : tcp_read(htsp->htsp_fd, buf, len); - if(v != 0) { + if (v != 0) { free(buf); return v; } @@ -3304,7 +3202,7 @@ htsp_read_message(htsp_connection_t *htsp, htsmsg_t **mp, int timeout) /* buf will be tied to the message (on success) */ /* bellow fcn calls free(buf) (on failure) */ *mp = htsmsg_binary_deserialize0(buf, len, buf); - if(*mp == NULL) + if (*mp == NULL) return EBADMSG; return 0; @@ -3313,12 +3211,10 @@ htsp_read_message(htsp_connection_t *htsp, htsmsg_t **mp, int timeout) /* * Status callback */ -static void -htsp_server_status ( void *opaque, htsmsg_t *m ) -{ - htsp_connection_t *htsp = opaque; - access_t *aa; - char buf[128]; +static void htsp_server_status(void* opaque, htsmsg_t* m) { + htsp_connection_t* htsp = opaque; + access_t* aa; + char buf[128]; htsmsg_add_str(m, "type", "HTSP"); if (htsp->htsp_username) { aa = htsp->htsp_granted_access; @@ -3333,17 +3229,15 @@ htsp_server_status ( void *opaque, htsmsg_t *m ) /** * */ -static int -htsp_read_loop(htsp_connection_t *htsp) -{ - htsmsg_t *m = NULL, *reply; - int run = 1, r = 0, i, streaming = 0; - const char *method; - void *tcp_id = NULL;; - - if(htsp_generate_challenge(htsp)) { - tvherror(LS_HTSP, "%s: Unable to generate challenge", - htsp->htsp_logname); +static int htsp_read_loop(htsp_connection_t* htsp) { + htsmsg_t * m = NULL, *reply; + int run = 1, r = 0, i, streaming = 0; + const char* method; + void* tcp_id = NULL; + ; + + if (htsp_generate_challenge(htsp)) { + tvherror(LS_HTSP, "%s: Unable to generate challenge", htsp->htsp_logname); return 1; } @@ -3352,8 +3246,10 @@ htsp_read_loop(htsp_connection_t *htsp) htsp->htsp_granted_access = access_get_by_addr(htsp->htsp_peer); htsp->htsp_granted_access->aa_rights |= ACCESS_HTSP_INTERFACE; - tcp_id = tcp_connection_launch(htsp->htsp_fd, streaming, htsp_server_status, - htsp->htsp_granted_access); + tcp_id = tcp_connection_launch(htsp->htsp_fd, + streaming, + htsp_server_status, + htsp->htsp_granted_access); tvh_mutex_unlock(&global_lock); @@ -3364,18 +3260,20 @@ htsp_read_loop(htsp_connection_t *htsp) /* Session main loop */ - while(run && tvheadend_is_running()) { -readmsg: + while (run && tvheadend_is_running()) { + readmsg: reply = NULL; - if((r = htsp_read_message(htsp, &m, 0)) != 0) + if ((r = htsp_read_message(htsp, &m, 0)) != 0) break; tvh_mutex_lock(&global_lock); if (htsp_authenticate(htsp, m)) { tcp_connection_land(tcp_id); - tcp_id = tcp_connection_launch(htsp->htsp_fd, streaming, htsp_server_status, - htsp->htsp_granted_access); + tcp_id = tcp_connection_launch(htsp->htsp_fd, + streaming, + htsp_server_status, + htsp->htsp_granted_access); if (tcp_id == NULL) { reply = htsmsg_create_map(); htsmsg_add_u32(reply, "noaccess", 1); @@ -3385,18 +3283,17 @@ readmsg: } } - if((method = htsmsg_get_str(m, "method")) != NULL) { + if ((method = htsmsg_get_str(m, "method")) != NULL) { tvhtrace(LS_HTSP, "%s - method %s", htsp->htsp_logname, method); if (tvhtrace_enabled()) htsp_trace(htsp, LS_HTSP_REQ, "request", m); - for(i = 0; i < NUM_METHODS; i++) { - if(!strcmp(method, htsp_methods[i].name)) { + for (i = 0; i < NUM_METHODS; i++) { + if (!strcmp(method, htsp_methods[i].name)) { - if((htsp->htsp_granted_access->aa_rights & - htsp_methods[i].privmask) != - htsp_methods[i].privmask) { + if ((htsp->htsp_granted_access->aa_rights & htsp_methods[i].privmask) != + htsp_methods[i].privmask) { - tvh_mutex_unlock(&global_lock); + tvh_mutex_unlock(&global_lock); /* Classic authentication failed delay */ tvh_safe_usleep(250000); @@ -3410,8 +3307,10 @@ readmsg: } else { if (!strcmp(method, "subscribe") && !streaming) { tcp_connection_land(tcp_id); - tcp_id = tcp_connection_launch(htsp->htsp_fd, 1, htsp_server_status, - htsp->htsp_granted_access); + tcp_id = tcp_connection_launch(htsp->htsp_fd, + 1, + htsp_server_status, + htsp->htsp_granted_access); if (tcp_id == NULL) { reply = htsmsg_create_map(); htsmsg_add_u32(reply, "noaccess", 1); @@ -3426,7 +3325,7 @@ readmsg: } } - if(i == NUM_METHODS) { + if (i == NUM_METHODS) { reply = htsp_error(htsp, N_("Method not found")); } @@ -3434,10 +3333,10 @@ readmsg: reply = htsp_error(htsp, N_("Invalid arguments")); } -send_reply_with_unlock: + send_reply_with_unlock: tvh_mutex_unlock(&global_lock); - if(reply != NULL) /* Methods can do all the replying inline */ + if (reply != NULL) /* Methods can do all the replying inline */ htsp_reply(htsp, m, reply); htsmsg_destroy(m); @@ -3452,21 +3351,19 @@ send_reply_with_unlock: /** * */ -static void * -htsp_write_scheduler(void *aux) -{ - htsp_connection_t *htsp = aux; - htsp_msg_q_t *hmq; - htsp_msg_t *hm; - void *dptr; - size_t dlen; - int r; +static void* htsp_write_scheduler(void* aux) { + htsp_connection_t* htsp = aux; + htsp_msg_q_t* hmq; + htsp_msg_t* hm; + void* dptr; + size_t dlen; + int r; tvh_mutex_lock(&htsp->htsp_out_mutex); - while(htsp->htsp_writer_run) { + while (htsp->htsp_writer_run) { - if((hmq = TAILQ_FIRST(&htsp->htsp_active_output_queues)) == NULL) { + if ((hmq = TAILQ_FIRST(&htsp->htsp_active_output_queues)) == NULL) { /* Nothing to be done, go to sleep */ tvh_cond_wait(&htsp->htsp_out_cond, &htsp->htsp_out_mutex); continue; @@ -3478,9 +3375,9 @@ htsp_write_scheduler(void *aux) hmq->hmq_payload -= hm->hm_payloadsize; TAILQ_REMOVE(&htsp->htsp_active_output_queues, hmq, hmq_link); - if(hmq->hmq_length) { + if (hmq->hmq_length) { /* Still messages to be sent, put back in active queues */ - if(hmq->hmq_strict_prio) { + if (hmq->hmq_strict_prio) { TAILQ_INSERT_HEAD(&htsp->htsp_active_output_queues, hmq, hmq_link); } else { TAILQ_INSERT_TAIL(&htsp->htsp_active_output_queues, hmq, hmq_link); @@ -3503,8 +3400,7 @@ htsp_write_scheduler(void *aux) tvh_mutex_lock(&htsp->htsp_out_mutex); if (r) { - tvhinfo(LS_HTSP, "%s: Write error -- %s", - htsp->htsp_logname, strerror(errno)); + tvhinfo(LS_HTSP, "%s: Write error -- %s", htsp->htsp_logname, strerror(errno)); break; } } @@ -3519,12 +3415,10 @@ htsp_write_scheduler(void *aux) * */ static void -htsp_serve(int fd, void **opaque, struct sockaddr_storage *source, - struct sockaddr_storage *self) -{ - htsp_connection_t htsp; - char buf[50]; - htsp_subscription_t *s; +htsp_serve(int fd, void** opaque, struct sockaddr_storage* source, struct sockaddr_storage* self) { + htsp_connection_t htsp; + char buf[50]; + htsp_subscription_t* s; // Note: global_lock held on entry @@ -3545,8 +3439,8 @@ htsp_serve(int fd, void **opaque, struct sockaddr_storage *source, htsp.htsp_peername = strdup(buf); htsp_update_logname(&htsp); - htsp.htsp_fd = fd; - htsp.htsp_peer = source; + htsp.htsp_fd = fd; + htsp.htsp_peer = source; htsp.htsp_writer_run = 1; tvh_mutex_init(&htsp.htsp_out_mutex, NULL); @@ -3554,8 +3448,7 @@ htsp_serve(int fd, void **opaque, struct sockaddr_storage *source, LIST_INSERT_HEAD(&htsp_connections, &htsp, htsp_link); tvh_mutex_unlock(&global_lock); - tvh_thread_create(&htsp.htsp_writer_thread, NULL, - htsp_write_scheduler, &htsp, "htsp-write"); + tvh_thread_create(&htsp.htsp_writer_thread, NULL, htsp_write_scheduler, &htsp, "htsp-write"); /** * Reader loop @@ -3572,7 +3465,7 @@ htsp_serve(int fd, void **opaque, struct sockaddr_storage *source, tvh_mutex_lock(&global_lock); /* no async notifications from now */ - if(htsp.htsp_async_mode) + if (htsp.htsp_async_mode) LIST_REMOVE(&htsp, htsp_async_link); mtimer_disarm(&htsp.htsp_epg_timer); @@ -3583,7 +3476,7 @@ htsp_serve(int fd, void **opaque, struct sockaddr_storage *source, /* Beware! Closing subscriptions will invoke a lot of callbacks down in the streaming code. So we do this as early as possible to avoid any weird lockups */ - while((s = LIST_FIRST(&htsp.htsp_subscriptions)) != NULL) + while ((s = LIST_FIRST(&htsp.htsp_subscriptions)) != NULL) htsp_subscription_destroy(&htsp, s); tvh_mutex_unlock(&global_lock); @@ -3595,21 +3488,21 @@ htsp_serve(int fd, void **opaque, struct sockaddr_storage *source, pthread_join(htsp.htsp_writer_thread, NULL); - while((s = LIST_FIRST(&htsp.htsp_dead_subscriptions)) != NULL) + while ((s = LIST_FIRST(&htsp.htsp_dead_subscriptions)) != NULL) htsp_subscription_free(&htsp, s); - htsp_msg_q_t *hmq; + htsp_msg_q_t* hmq; - TAILQ_FOREACH(hmq, &htsp.htsp_active_output_queues, hmq_link) { - htsp_msg_t *hm; - while((hm = TAILQ_FIRST(&hmq->hmq_q)) != NULL) { + TAILQ_FOREACH (hmq, &htsp.htsp_active_output_queues, hmq_link) { + htsp_msg_t* hm; + while ((hm = TAILQ_FIRST(&hmq->hmq_q)) != NULL) { TAILQ_REMOVE(&hmq->hmq_q, hm, hm_link); htsp_msg_destroy(hm); } } - htsp_file_t *hf; - while((hf = LIST_FIRST(&htsp.htsp_files)) != NULL) + htsp_file_t* hf; + while ((hf = LIST_FIRST(&htsp.htsp_files)) != NULL) htsp_file_destroy(hf); close(fd); @@ -3628,10 +3521,8 @@ htsp_serve(int fd, void **opaque, struct sockaddr_storage *source, /* * Cancel callback */ -static void -htsp_server_cancel ( void *opaque ) -{ - htsp_connection_t *htsp = opaque; +static void htsp_server_cancel(void* opaque) { + htsp_connection_t* htsp = opaque; if (htsp) shutdown(htsp->htsp_fd, SHUT_RDWR); @@ -3640,27 +3531,20 @@ htsp_server_cancel ( void *opaque ) /** * Fire up HTSP server */ -void -htsp_init(const char *bindaddr) -{ - extern int tvheadend_htsp_port_extra; - static tcp_server_ops_t ops = { - .start = htsp_serve, - .stop = NULL, - .cancel = htsp_server_cancel - }; +void htsp_init(const char* bindaddr) { + extern int tvheadend_htsp_port_extra; + static tcp_server_ops_t ops = {.start = htsp_serve, .stop = NULL, .cancel = htsp_server_cancel}; if (tvheadend_htsp_port > 0) htsp_server = tcp_server_create(LS_HTSP, "HTSP", bindaddr, tvheadend_htsp_port, &ops, NULL); if (tvheadend_htsp_port_extra > 0) - htsp_server_2 = tcp_server_create(LS_HTSP, "HTSP2", bindaddr, tvheadend_htsp_port_extra, &ops, NULL); + htsp_server_2 = + tcp_server_create(LS_HTSP, "HTSP2", bindaddr, tvheadend_htsp_port_extra, &ops, NULL); } /* * */ -void -htsp_register(void) -{ +void htsp_register(void) { if (htsp_server) tcp_server_register(htsp_server); if (htsp_server_2) @@ -3670,9 +3554,7 @@ htsp_register(void) /** * Fire down HTSP server */ -void -htsp_done(void) -{ +void htsp_done(void) { tvh_mutex_lock(&global_lock); if (htsp_server_2) tcp_server_delete(htsp_server_2); @@ -3688,13 +3570,11 @@ htsp_done(void) /** * */ -static void -htsp_async_send(htsmsg_t *m, int mode, void *aux) -{ - htsp_connection_t *htsp; +static void htsp_async_send(htsmsg_t* m, int mode, void* aux) { + htsp_connection_t* htsp; lock_assert(&global_lock); - LIST_FOREACH(htsp, &htsp_async_connections, htsp_async_link) + LIST_FOREACH (htsp, &htsp_async_connections, htsp_async_link) if (htsp->htsp_async_mode & mode) htsp_send_message(htsp, htsmsg_copy(m), NULL); htsmsg_destroy(m); @@ -3703,16 +3583,14 @@ htsp_async_send(htsmsg_t *m, int mode, void *aux) /** * */ -typedef htsmsg_t *(*http_async_send_cb_t)(htsp_connection_t *htsp, void *aux); +typedef htsmsg_t* (*http_async_send_cb_t)(htsp_connection_t* htsp, void* aux); -static void -htsp_async_send_cb(http_async_send_cb_t cb, int mode, void *aux) -{ - htsp_connection_t *htsp; - htsmsg_t *m; +static void htsp_async_send_cb(http_async_send_cb_t cb, int mode, void* aux) { + htsp_connection_t* htsp; + htsmsg_t* m; lock_assert(&global_lock); - LIST_FOREACH(htsp, &htsp_async_connections, htsp_async_link) + LIST_FOREACH (htsp, &htsp_async_connections, htsp_async_link) if (htsp->htsp_async_mode & mode) { m = cb(htsp, aux); if (m != NULL) @@ -3723,15 +3601,12 @@ htsp_async_send_cb(http_async_send_cb_t cb, int mode, void *aux) /** * Called from channel.c when a new channel is created */ -static void -_htsp_channel_update(channel_t *ch, const char *method, htsmsg_t *msg) -{ - htsp_connection_t *htsp; - LIST_FOREACH(htsp, &htsp_async_connections, htsp_async_link) { +static void _htsp_channel_update(channel_t* ch, const char* method, htsmsg_t* msg) { + htsp_connection_t* htsp; + LIST_FOREACH (htsp, &htsp_async_connections, htsp_async_link) { if (htsp->htsp_async_mode & HTSP_ASYNC_ON) - if (htsp_user_access_channel(htsp,ch)) { - htsmsg_t *m = msg ? htsmsg_copy(msg) - : htsp_build_channel(ch, method, htsp); + if (htsp_user_access_channel(htsp, ch)) { + htsmsg_t* m = msg ? htsmsg_copy(msg) : htsp_build_channel(ch, method, htsp); htsp_send_message(htsp, m, NULL); } } @@ -3744,11 +3619,9 @@ _htsp_channel_update(channel_t *ch, const char *method, htsmsg_t *msg) * * global_lock is held */ -void -htsp_channel_update_nownext(channel_t *ch) -{ +void htsp_channel_update_nownext(channel_t* ch) { epg_broadcast_t *now, *next; - htsmsg_t *m; + htsmsg_t* m; m = htsmsg_create_map(); htsmsg_add_str(m, "method", "channelUpdate"); @@ -3756,23 +3629,19 @@ htsp_channel_update_nownext(channel_t *ch) now = ch->ch_epg_now; next = ch->ch_epg_next; - htsmsg_add_u32(m, "eventId", now ? now->id : 0); + htsmsg_add_u32(m, "eventId", now ? now->id : 0); htsmsg_add_u32(m, "nextEventId", next ? next->id : 0); _htsp_channel_update(ch, NULL, m); } -void -htsp_channel_add(channel_t *ch) -{ +void htsp_channel_add(channel_t* ch) { _htsp_channel_update(ch, "channelAdd", NULL); } /** * Called from channel.c when a channel is updated */ -void -htsp_channel_update(channel_t *ch) -{ +void htsp_channel_update(channel_t* ch) { if (htsp_user_access_channel(NULL, ch)) _htsp_channel_update(ch, "channelUpdate", NULL); else // in case the channel was ever sent to the client @@ -3782,10 +3651,8 @@ htsp_channel_update(channel_t *ch) /** * Called from channel.c when a channel is deleted */ -void -htsp_channel_delete(channel_t *ch) -{ - htsmsg_t *m = htsmsg_create_map(); +void htsp_channel_delete(channel_t* ch) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_u32(m, "channelId", channel_get_id(ch)); htsmsg_add_str(m, "method", "channelDelete"); htsp_async_send(m, HTSP_ASYNC_ON, ch); @@ -3794,9 +3661,7 @@ htsp_channel_delete(channel_t *ch) /** * */ -static htsmsg_t * -htsp_tag_update_msg(htsp_connection_t *htsp, void *tag) -{ +static htsmsg_t* htsp_tag_update_msg(htsp_connection_t* htsp, void* tag) { if (!channel_tag_access(tag, htsp->htsp_granted_access, 0)) return NULL; return htsp_build_tag(htsp, tag, "tagUpdate", 1); @@ -3805,32 +3670,25 @@ htsp_tag_update_msg(htsp_connection_t *htsp, void *tag) /** * Called from channel.c when a tag is exported */ -void -htsp_tag_add(channel_tag_t *ct) -{ +void htsp_tag_add(channel_tag_t* ct) { htsp_async_send_cb(htsp_tag_update_msg, HTSP_ASYNC_ON, ct); } /** * Called from channel.c when an exported tag is changed */ -void -htsp_tag_update(channel_tag_t *ct) -{ +void htsp_tag_update(channel_tag_t* ct) { if (ct->ct_enabled && !ct->ct_internal) htsp_async_send_cb(htsp_tag_update_msg, HTSP_ASYNC_ON, ct); else // in case the tag was ever sent to the client htsp_tag_delete(ct); } - /** * Called from channel.c when an exported tag is deleted */ -void -htsp_tag_delete(channel_tag_t *ct) -{ - htsmsg_t *m = htsmsg_create_map(); +void htsp_tag_delete(channel_tag_t* ct) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_u32(m, "tagId", htsp_channel_tag_get_identifier(ct)); htsmsg_add_str(m, "method", "tagDelete"); htsp_async_send(m, HTSP_ASYNC_ON, ct); @@ -3839,15 +3697,13 @@ htsp_tag_delete(channel_tag_t *ct) /** * Called when a DVR entry is updated/added */ -static void -_htsp_dvr_entry_update(dvr_entry_t *de, const char *method, htsmsg_t *msg) -{ - htsp_connection_t *htsp; - LIST_FOREACH(htsp, &htsp_async_connections, htsp_async_link) { +static void _htsp_dvr_entry_update(dvr_entry_t* de, const char* method, htsmsg_t* msg) { + htsp_connection_t* htsp; + LIST_FOREACH (htsp, &htsp_async_connections, htsp_async_link) { if (htsp->htsp_async_mode & HTSP_ASYNC_ON) if (!dvr_entry_verify(de, htsp->htsp_granted_access, 1)) { - htsmsg_t *m = msg ? htsmsg_copy(msg) - : htsp_build_dvrentry(htsp, de, method, htsp->htsp_language, 0); + htsmsg_t* m = + msg ? htsmsg_copy(msg) : htsp_build_dvrentry(htsp, de, method, htsp->htsp_language, 0); htsp_send_message(htsp, m, NULL); } } @@ -3857,32 +3713,30 @@ _htsp_dvr_entry_update(dvr_entry_t *de, const char *method, htsmsg_t *msg) /** * Called from dvr_db.c when a DVR entry is created */ -void -htsp_dvr_entry_add(dvr_entry_t *de) -{ +void htsp_dvr_entry_add(dvr_entry_t* de) { _htsp_dvr_entry_update(de, "dvrEntryAdd", NULL); } /** * Called from dvr_db.c when a DVR entry is updated */ -void -htsp_dvr_entry_update(dvr_entry_t *de) -{ +void htsp_dvr_entry_update(dvr_entry_t* de) { _htsp_dvr_entry_update(de, "dvrEntryUpdate", NULL); } /** * Called from dvr_rec.c when a DVR entry is recording */ -void -htsp_dvr_entry_update_stats(dvr_entry_t *de) -{ - htsp_connection_t *htsp; - LIST_FOREACH(htsp, &htsp_async_connections, htsp_async_link) { - if (htsp->htsp_async_mode & HTSP_ASYNC_ON){ +void htsp_dvr_entry_update_stats(dvr_entry_t* de) { + htsp_connection_t* htsp; + LIST_FOREACH (htsp, &htsp_async_connections, htsp_async_link) { + if (htsp->htsp_async_mode & HTSP_ASYNC_ON) { if (!dvr_entry_verify(de, htsp->htsp_granted_access, 1)) { - htsmsg_t *m = htsp_build_dvrentry(htsp, de, "dvrEntryUpdate", htsp->htsp_language, htsp->htsp_version <= 25 ? 0 : 1); + htsmsg_t* m = htsp_build_dvrentry(htsp, + de, + "dvrEntryUpdate", + htsp->htsp_language, + htsp->htsp_version <= 25 ? 0 : 1); htsp_send_message(htsp, m, NULL); } } @@ -3892,10 +3746,8 @@ htsp_dvr_entry_update_stats(dvr_entry_t *de) /** * Called from dvr_db.c when a DVR entry is deleted */ -void -htsp_dvr_entry_delete(dvr_entry_t *de) -{ - htsmsg_t *m = htsmsg_create_map(); +void htsp_dvr_entry_delete(dvr_entry_t* de) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_u32(m, "id", idnode_get_short_uuid(&de->de_id)); htsmsg_add_str(m, "method", "dvrEntryDelete"); htsp_async_send(m, HTSP_ASYNC_ON, de); @@ -3905,14 +3757,12 @@ htsp_dvr_entry_delete(dvr_entry_t *de) * Called when a autorec entry is updated/added */ static void -_htsp_autorec_entry_update(dvr_autorec_entry_t *dae, const char *method, htsmsg_t *msg) -{ - htsp_connection_t *htsp; - LIST_FOREACH(htsp, &htsp_async_connections, htsp_async_link) { +_htsp_autorec_entry_update(dvr_autorec_entry_t* dae, const char* method, htsmsg_t* msg) { + htsp_connection_t* htsp; + LIST_FOREACH (htsp, &htsp_async_connections, htsp_async_link) { if (htsp->htsp_async_mode & HTSP_ASYNC_ON) { if (!dvr_autorec_entry_verify(dae, htsp->htsp_granted_access, 1)) { - htsmsg_t *m = msg ? htsmsg_copy(msg) - : htsp_build_autorecentry(htsp, dae, method); + htsmsg_t* m = msg ? htsmsg_copy(msg) : htsp_build_autorecentry(htsp, dae, method); htsp_send_message(htsp, m, NULL); } } @@ -3923,33 +3773,27 @@ _htsp_autorec_entry_update(dvr_autorec_entry_t *dae, const char *method, htsmsg_ /** * Called from dvr_autorec.c when a autorec entry is added */ -void -htsp_autorec_entry_add(dvr_autorec_entry_t *dae) -{ +void htsp_autorec_entry_add(dvr_autorec_entry_t* dae) { _htsp_autorec_entry_update(dae, "autorecEntryAdd", NULL); } /** * Called from dvr_autorec.c when a autorec entry is updated */ -void -htsp_autorec_entry_update(dvr_autorec_entry_t *dae) -{ +void htsp_autorec_entry_update(dvr_autorec_entry_t* dae) { _htsp_autorec_entry_update(dae, "autorecEntryUpdate", NULL); } /** * Called from dvr_autorec.c when a autorec entry is deleted */ -void -htsp_autorec_entry_delete(dvr_autorec_entry_t *dae) -{ +void htsp_autorec_entry_delete(dvr_autorec_entry_t* dae) { char ubuf[UUID_HEX_SIZE]; - if(dae == NULL) + if (dae == NULL) return; - htsmsg_t *m = htsmsg_create_map(); + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "id", idnode_uuid_as_str(&dae->dae_id, ubuf)); htsmsg_add_str(m, "method", "autorecEntryDelete"); htsp_async_send(m, HTSP_ASYNC_ON, dae); @@ -3959,14 +3803,12 @@ htsp_autorec_entry_delete(dvr_autorec_entry_t *dae) * Called when a timerec entry is updated/added */ static void -_htsp_timerec_entry_update(dvr_timerec_entry_t *dte, const char *method, htsmsg_t *msg) -{ - htsp_connection_t *htsp; - LIST_FOREACH(htsp, &htsp_async_connections, htsp_async_link) { +_htsp_timerec_entry_update(dvr_timerec_entry_t* dte, const char* method, htsmsg_t* msg) { + htsp_connection_t* htsp; + LIST_FOREACH (htsp, &htsp_async_connections, htsp_async_link) { if (htsp->htsp_async_mode & HTSP_ASYNC_ON) { if (!dvr_timerec_entry_verify(dte, htsp->htsp_granted_access, 1)) { - htsmsg_t *m = msg ? htsmsg_copy(msg) - : htsp_build_timerecentry(htsp, dte, method); + htsmsg_t* m = msg ? htsmsg_copy(msg) : htsp_build_timerecentry(htsp, dte, method); htsp_send_message(htsp, m, NULL); } } @@ -3977,33 +3819,27 @@ _htsp_timerec_entry_update(dvr_timerec_entry_t *dte, const char *method, htsmsg_ /** * Called from dvr_timerec.c when a timerec entry is added */ -void -htsp_timerec_entry_add(dvr_timerec_entry_t *dte) -{ +void htsp_timerec_entry_add(dvr_timerec_entry_t* dte) { _htsp_timerec_entry_update(dte, "timerecEntryAdd", NULL); } /** * Called from dvr_timerec.c when a timerec entry is updated */ -void -htsp_timerec_entry_update(dvr_timerec_entry_t *dte) -{ +void htsp_timerec_entry_update(dvr_timerec_entry_t* dte) { _htsp_timerec_entry_update(dte, "timerecEntryUpdate", NULL); } /** * Called from dvr_timerec.c when a timerec entry is deleted */ -void -htsp_timerec_entry_delete(dvr_timerec_entry_t *dte) -{ +void htsp_timerec_entry_delete(dvr_timerec_entry_t* dte) { char ubuf[UUID_HEX_SIZE]; - if(dte == NULL) + if (dte == NULL) return; - htsmsg_t *m = htsmsg_create_map(); + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "id", idnode_uuid_as_str(&dte->dte_id, ubuf)); htsmsg_add_str(m, "method", "timerecEntryDelete"); htsp_async_send(m, HTSP_ASYNC_ON, dte); @@ -4013,58 +3849,58 @@ htsp_timerec_entry_delete(dvr_timerec_entry_t *dte) * Called every "HTSP_ASYNC_EPG_INTERVAL" seconds * Keep the async epg window up to date */ -static void -htsp_epg_window_cb(void *aux) -{ - htsp_connection_t *htsp = aux; +static void htsp_epg_window_cb(void* aux) { + htsp_connection_t* htsp = aux; htsp_epg_send_waiting(htsp, htsp->htsp_epg_lastupdate); } /** * Send all waiting EPG events */ -static void -htsp_epg_send_waiting(htsp_connection_t *htsp, int64_t mintime) -{ - epg_broadcast_t *ebc; - channel_t *ch; - int64_t maxtime; +static void htsp_epg_send_waiting(htsp_connection_t* htsp, int64_t mintime) { + epg_broadcast_t* ebc; + channel_t* ch; + int64_t maxtime; - maxtime = gclk() + htsp->htsp_epg_window; + maxtime = gclk() + htsp->htsp_epg_window; htsp->htsp_epg_lastupdate = maxtime; /* Push new events */ CHANNEL_FOREACH(ch) { - if (!htsp_user_access_channel(htsp, ch)) continue; - RB_FOREACH(ebc, &ch->ch_epg_schedule, sched_link) { - if (ebc->start <= mintime) continue; - if (htsp->htsp_epg_window && ebc->start > maxtime) break; - htsmsg_t *e = htsp_build_event(ebc, "eventAdd", htsp->htsp_language, 0, htsp); - if (e) htsp_send_message(htsp, e, NULL); + if (!htsp_user_access_channel(htsp, ch)) + continue; + RB_FOREACH (ebc, &ch->ch_epg_schedule, sched_link) { + if (ebc->start <= mintime) + continue; + if (htsp->htsp_epg_window && ebc->start > maxtime) + break; + htsmsg_t* e = htsp_build_event(ebc, "eventAdd", htsp->htsp_language, 0, htsp); + if (e) + htsp_send_message(htsp, e, NULL); } } /* Keep the epg window up to date */ if (htsp->htsp_epg_window) - mtimer_arm_rel(&htsp->htsp_epg_timer, htsp_epg_window_cb, - htsp, sec2mono(HTSP_ASYNC_EPG_INTERVAL)); + mtimer_arm_rel(&htsp->htsp_epg_timer, + htsp_epg_window_cb, + htsp, + sec2mono(HTSP_ASYNC_EPG_INTERVAL)); } /** * Called when a event entry is updated/added */ -static void -_htsp_event_update(epg_broadcast_t *ebc, const char *method, htsmsg_t *msg) -{ - htsp_connection_t *htsp; - LIST_FOREACH(htsp, &htsp_async_connections, htsp_async_link) { +static void _htsp_event_update(epg_broadcast_t* ebc, const char* method, htsmsg_t* msg) { + htsp_connection_t* htsp; + LIST_FOREACH (htsp, &htsp_async_connections, htsp_async_link) { if (htsp->htsp_async_mode & HTSP_ASYNC_EPG) { /* Use last update instead of window time as we do not want to push an update * for an event we still have to send with "htsp_epg_window_cb" */ if (!htsp->htsp_epg_window || ebc->start <= htsp->htsp_epg_lastupdate) { - if (htsp_user_access_channel(htsp,ebc->channel)) { - htsmsg_t *m = msg ? htsmsg_copy(msg) - : htsp_build_event(ebc, method, htsp->htsp_language, 0, htsp); + if (htsp_user_access_channel(htsp, ebc->channel)) { + htsmsg_t* m = + msg ? htsmsg_copy(msg) : htsp_build_event(ebc, method, htsp->htsp_language, 0, htsp); htsp_send_message(htsp, m, NULL); } } @@ -4076,68 +3912,60 @@ _htsp_event_update(epg_broadcast_t *ebc, const char *method, htsmsg_t *msg) /** * Event added */ -void -htsp_event_add(epg_broadcast_t *ebc) -{ +void htsp_event_add(epg_broadcast_t* ebc) { _htsp_event_update(ebc, "eventAdd", NULL); } /** * Event updated */ -void -htsp_event_update(epg_broadcast_t *ebc) -{ +void htsp_event_update(epg_broadcast_t* ebc) { _htsp_event_update(ebc, "eventUpdate", NULL); } /** * Event deleted */ -void -htsp_event_delete(epg_broadcast_t *ebc) -{ - htsmsg_t *m = htsmsg_create_map(); +void htsp_event_delete(epg_broadcast_t* ebc) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "method", "eventDelete"); htsmsg_add_u32(m, "eventId", ebc->id); htsp_async_send(m, HTSP_ASYNC_EPG, ebc); } static const char frametypearray[PKT_NTYPES] = { - [PKT_I_FRAME] = 'I', - [PKT_P_FRAME] = 'P', - [PKT_B_FRAME] = 'B', + [PKT_I_FRAME] = 'I', + [PKT_P_FRAME] = 'P', + [PKT_B_FRAME] = 'B', }; /** * Build a htsmsg from a th_pkt and enqueue it on our HTSP service */ -static void -htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) -{ - htsmsg_t *m; - htsp_msg_t *hm; - htsp_connection_t *htsp = hs->hs_htsp; - int64_t ts; - int qlen = hs->hs_q.hmq_payload; - int video = SCT_ISVIDEO(pkt->pkt_type); - size_t payloadlen; +static void htsp_stream_deliver(htsp_subscription_t* hs, th_pkt_t* pkt) { + htsmsg_t* m; + htsp_msg_t* hm; + htsp_connection_t* htsp = hs->hs_htsp; + int64_t ts; + int qlen = hs->hs_q.hmq_payload; + int video = SCT_ISVIDEO(pkt->pkt_type); + size_t payloadlen; if (pkt->pkt_err) hs->hs_data_errors += pkt->pkt_err; - if(pkt->pkt_payload == NULL) { + if (pkt->pkt_payload == NULL) { return; } - if(!htsp_is_stream_enabled(hs, pkt->pkt_componentindex)) { + if (!htsp_is_stream_enabled(hs, pkt->pkt_componentindex)) { pkt_ref_dec(pkt); return; } - if(video && - ((qlen > hs->hs_queue_depth && pkt->v.pkt_frametype == PKT_B_FRAME) || - (qlen > hs->hs_queue_depth * 2 && pkt->v.pkt_frametype == PKT_P_FRAME) || - (qlen > hs->hs_queue_depth * 3))) { + if (video && + ((qlen > hs->hs_queue_depth && pkt->v.pkt_frametype == PKT_B_FRAME) || + (qlen > hs->hs_queue_depth * 2 && pkt->v.pkt_frametype == PKT_P_FRAME) || + (qlen > hs->hs_queue_depth * 3))) { hs->hs_dropstats[pkt->v.pkt_frametype]++; @@ -4156,12 +3984,12 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) htsmsg_add_u32(m, "stream", pkt->pkt_componentindex); htsmsg_add_u32(m, "com", pkt->pkt_commercial); - if(pkt->pkt_pts != PTS_UNSET) { + if (pkt->pkt_pts != PTS_UNSET) { int64_t pts = hs->hs_90khz ? pkt->pkt_pts : ts_rescale(pkt->pkt_pts, 1000000); htsmsg_add_s64(m, "pts", pts); } - if(pkt->pkt_dts != PTS_UNSET) { + if (pkt->pkt_dts != PTS_UNSET) { int64_t dts = hs->hs_90khz ? pkt->pkt_dts : ts_rescale(pkt->pkt_dts, 1000000); htsmsg_add_s64(m, "dts", dts); } @@ -4178,7 +4006,7 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) htsp_send_subscription(htsp, m, pkt->pkt_payload, hs, payloadlen); atomic_add(&hs->hs_s_bytes_out, payloadlen); - if(mono2sec(hs->hs_last_report) != mono2sec(mclk())) { + if (mono2sec(hs->hs_last_report) != mono2sec(mclk())) { /* Send a queue and signal status report every second */ @@ -4200,23 +4028,23 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) int64_t min_dts = PTS_UNSET; int64_t max_dts = PTS_UNSET; - TAILQ_FOREACH(hm, &hs->hs_q.hmq_q, hm_link) { - if(!hm->hm_msg) - continue; - if(htsmsg_get_s64(hm->hm_msg, "dts", &ts)) - continue; - if(ts == PTS_UNSET) - continue; - - if(min_dts == PTS_UNSET) - min_dts = ts; + TAILQ_FOREACH (hm, &hs->hs_q.hmq_q, hm_link) { + if (!hm->hm_msg) + continue; + if (htsmsg_get_s64(hm->hm_msg, "dts", &ts)) + continue; + if (ts == PTS_UNSET) + continue; + + if (min_dts == PTS_UNSET) + min_dts = ts; else - min_dts = MIN(ts, min_dts); + min_dts = MIN(ts, min_dts); - if(max_dts == PTS_UNSET) - max_dts = ts; + if (max_dts == PTS_UNSET) + max_dts = ts; else - max_dts = MAX(ts, max_dts); + max_dts = MAX(ts, max_dts); } htsmsg_add_s64(m, "delay", max_dts - min_dts); @@ -4238,20 +4066,19 @@ htsp_stream_deliver(htsp_subscription_t *hs, th_pkt_t *pkt) * Send a 'subscriptionStart' message to client informing about * delivery start and all components. */ -static void -htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss) -{ - htsmsg_t *m,*streams, *c, *sourceinfo; - const char *type; - char ubuf[UUID_HEX_SIZE]; - int i; - const source_info_t *si; +static void htsp_subscription_start(htsp_subscription_t* hs, const streaming_start_t* ss) { + htsmsg_t * m, *streams, *c, *sourceinfo; + const char* type; + char ubuf[UUID_HEX_SIZE]; + int i; + const source_info_t* si; tvhdebug(LS_HTSP, "%s - subscription start", hs->hs_htsp->htsp_logname); - for(i = 0; i < ss->ss_num_components; i++) { - const streaming_start_component_t *ssc = &ss->ss_components[i]; - if (ssc->ssc_disabled) continue; + for (i = 0; i < ss->ss_num_components; i++) { + const streaming_start_component_t* ssc = &ss->ss_components[i]; + if (ssc->ssc_disabled) + continue; if (SCT_ISVIDEO(ssc->es_type)) { if (ssc->es_width == 0 || ssc->es_height == 0) { hs->hs_wait_for_video = 1; @@ -4262,12 +4089,13 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss) } hs->hs_wait_for_video = 0; - m = htsmsg_create_map(); - streams = htsmsg_create_list(); + m = htsmsg_create_map(); + streams = htsmsg_create_list(); sourceinfo = htsmsg_create_map(); - for(i = 0; i < ss->ss_num_components; i++) { - const streaming_start_component_t *ssc = &ss->ss_components[i]; - if(ssc->ssc_disabled) continue; + for (i = 0; i < ss->ss_num_components; i++) { + const streaming_start_component_t* ssc = &ss->ss_components[i]; + if (ssc->ssc_disabled) + continue; c = htsmsg_create_map(); htsmsg_add_u32(c, "index", ssc->es_index); @@ -4276,30 +4104,30 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss) else type = streaming_component_type2txt(ssc->es_type); htsmsg_add_str(c, "type", type); - if(ssc->es_lang[0]) + if (ssc->es_lang[0]) htsmsg_add_str(c, "language", ssc->es_lang); - if(ssc->es_type == SCT_DVBSUB) { + if (ssc->es_type == SCT_DVBSUB) { htsmsg_add_u32(c, "composition_id", ssc->es_composition_id); htsmsg_add_u32(c, "ancillary_id", ssc->es_ancillary_id); } - if(SCT_ISVIDEO(ssc->es_type)) { - if(ssc->es_width) + if (SCT_ISVIDEO(ssc->es_type)) { + if (ssc->es_width) htsmsg_add_u32(c, "width", ssc->es_width); - if(ssc->es_height) + if (ssc->es_height) htsmsg_add_u32(c, "height", ssc->es_height); - if(ssc->es_frame_duration) - htsmsg_add_u32(c, "duration", hs->hs_90khz ? ssc->es_frame_duration : - ts_rescale(ssc->es_frame_duration, 1000000)); + if (ssc->es_frame_duration) + htsmsg_add_u32(c, + "duration", + hs->hs_90khz ? ssc->es_frame_duration : ts_rescale(ssc->es_frame_duration, 1000000)); if (ssc->es_aspect_num) htsmsg_add_u32(c, "aspect_num", ssc->es_aspect_num); if (ssc->es_aspect_den) htsmsg_add_u32(c, "aspect_den", ssc->es_aspect_den); } - if (SCT_ISAUDIO(ssc->es_type)) - { + if (SCT_ISAUDIO(ssc->es_type)) { htsmsg_add_u32(c, "audio_type", ssc->es_audio_type); if (ssc->es_audio_version) htsmsg_add_u32(c, "audio_version", ssc->es_audio_version); @@ -4311,8 +4139,7 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss) } if (ssc->ssc_gh) - htsmsg_add_bin_ptr(m, "meta", pktbuf_ptr(ssc->ssc_gh), - pktbuf_len(ssc->ssc_gh)); + htsmsg_add_bin_ptr(m, "meta", pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh)); htsmsg_add_msg(streams, NULL, c); } @@ -4320,23 +4147,20 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss) htsmsg_add_msg(m, "streams", streams); si = &ss->ss_si; - if(!uuid_empty(&si->si_adapter_uuid)) - htsmsg_add_str(sourceinfo, "adapter_uuid", - uuid_get_hex(&si->si_adapter_uuid, ubuf)); - if(!uuid_empty(&si->si_mux_uuid)) - htsmsg_add_str(sourceinfo, "mux_uuid", - uuid_get_hex(&si->si_mux_uuid, ubuf)); - if(!uuid_empty(&si->si_network_uuid)) - htsmsg_add_str(sourceinfo, "network_uuid", - uuid_get_hex(&si->si_network_uuid, ubuf)); + if (!uuid_empty(&si->si_adapter_uuid)) + htsmsg_add_str(sourceinfo, "adapter_uuid", uuid_get_hex(&si->si_adapter_uuid, ubuf)); + if (!uuid_empty(&si->si_mux_uuid)) + htsmsg_add_str(sourceinfo, "mux_uuid", uuid_get_hex(&si->si_mux_uuid, ubuf)); + if (!uuid_empty(&si->si_network_uuid)) + htsmsg_add_str(sourceinfo, "network_uuid", uuid_get_hex(&si->si_network_uuid, ubuf)); if (!htsp_anonymize(hs->hs_htsp)) { - htsmsg_add_str2(sourceinfo, "adapter", si->si_adapter ); - htsmsg_add_str2(sourceinfo, "mux", si->si_mux ); - htsmsg_add_str2(sourceinfo, "network", si->si_network ); + htsmsg_add_str2(sourceinfo, "adapter", si->si_adapter); + htsmsg_add_str2(sourceinfo, "mux", si->si_mux); + htsmsg_add_str2(sourceinfo, "network", si->si_network); htsmsg_add_str2(sourceinfo, "network_type", si->si_network_type); - htsmsg_add_str2(sourceinfo, "provider", si->si_provider ); - htsmsg_add_str2(sourceinfo, "service", si->si_service ); - htsmsg_add_str2(sourceinfo, "satpos", si->si_satpos ); + htsmsg_add_str2(sourceinfo, "provider", si->si_provider); + htsmsg_add_str2(sourceinfo, "service", si->si_service); + htsmsg_add_str2(sourceinfo, "satpos", si->si_satpos); } htsmsg_add_msg(m, "sourceinfo", sourceinfo); @@ -4350,17 +4174,16 @@ htsp_subscription_start(htsp_subscription_t *hs, const streaming_start_t *ss) * Send a 'subscriptionStop' stop */ static void -htsp_subscription_stop(htsp_subscription_t *hs, const char *err, const char *subscriptionErr) -{ - htsmsg_t *m = htsmsg_create_map(); +htsp_subscription_stop(htsp_subscription_t* hs, const char* err, const char* subscriptionErr) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "method", "subscriptionStop"); htsmsg_add_u32(m, "subscriptionId", hs->hs_sid); tvhdebug(LS_HTSP, "%s - subscription stop", hs->hs_htsp->htsp_logname); - if(err != NULL) + if (err != NULL) htsmsg_add_str(m, "status", err); - if(subscriptionErr != NULL) + if (subscriptionErr != NULL) htsmsg_add_str(m, "subscriptionError", subscriptionErr); htsp_send_subscription(hs->hs_htsp, m, NULL, hs, 0); @@ -4369,10 +4192,8 @@ htsp_subscription_stop(htsp_subscription_t *hs, const char *err, const char *sub /** * Send a 'subscriptionGrace' message */ -static void -htsp_subscription_grace(htsp_subscription_t *hs, int grace) -{ - htsmsg_t *m = htsmsg_create_map(); +static void htsp_subscription_grace(htsp_subscription_t* hs, int grace) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "method", "subscriptionGrace"); htsmsg_add_u32(m, "subscriptionId", hs->hs_sid); htsmsg_add_u32(m, "graceTimeout", grace); @@ -4385,16 +4206,15 @@ htsp_subscription_grace(htsp_subscription_t *hs, int grace) * Send a 'subscriptionStatus' message */ static void -htsp_subscription_status(htsp_subscription_t *hs, const char *err, const char *subscriptionErr) -{ - htsmsg_t *m = htsmsg_create_map(); +htsp_subscription_status(htsp_subscription_t* hs, const char* err, const char* subscriptionErr) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "method", "subscriptionStatus"); htsmsg_add_u32(m, "subscriptionId", hs->hs_sid); - if(err != NULL) + if (err != NULL) htsmsg_add_str(m, "status", err); - if(subscriptionErr != NULL) + if (subscriptionErr != NULL) htsmsg_add_str(m, "subscriptionError", subscriptionErr); htsp_send_subscription(hs->hs_htsp, m, NULL, hs, 0); @@ -4403,51 +4223,46 @@ htsp_subscription_status(htsp_subscription_t *hs, const char *err, const char *s /** * Convert the SM_CODE to an understandable string */ -const char * -_htsp_get_subscription_status(int smcode) -{ - switch (smcode) - { - case SM_CODE_NOT_FREE: - case SM_CODE_NO_FREE_ADAPTER: - case SM_CODE_NO_ADAPTERS: - return "noFreeAdapter"; - case SM_CODE_NO_ACCESS: - case SM_CODE_NO_DESCRAMBLER: - return "scrambled"; - case SM_CODE_NO_INPUT: - case SM_CODE_BAD_SIGNAL: - return "badSignal"; - case SM_CODE_TUNING_FAILED: - return "tuningFailed"; - case SM_CODE_SUBSCRIPTION_OVERRIDDEN: - return "subscriptionOverridden"; - case SM_CODE_MUX_NOT_ENABLED: - return "muxNotEnabled"; - case SM_CODE_INVALID_TARGET: - return "invalidTarget"; - case SM_CODE_USER_ACCESS: - return "userAccess"; - case SM_CODE_USER_LIMIT: - return "userLimit"; - case SM_CODE_WEAK_STREAM: - return "weakStream"; - case SM_CODE_NO_SPACE: - return "noDiskSpace"; - default: - return streaming_code2txt(smcode); +const char* _htsp_get_subscription_status(int smcode) { + switch (smcode) { + case SM_CODE_NOT_FREE: + case SM_CODE_NO_FREE_ADAPTER: + case SM_CODE_NO_ADAPTERS: + return "noFreeAdapter"; + case SM_CODE_NO_ACCESS: + case SM_CODE_NO_DESCRAMBLER: + return "scrambled"; + case SM_CODE_NO_INPUT: + case SM_CODE_BAD_SIGNAL: + return "badSignal"; + case SM_CODE_TUNING_FAILED: + return "tuningFailed"; + case SM_CODE_SUBSCRIPTION_OVERRIDDEN: + return "subscriptionOverridden"; + case SM_CODE_MUX_NOT_ENABLED: + return "muxNotEnabled"; + case SM_CODE_INVALID_TARGET: + return "invalidTarget"; + case SM_CODE_USER_ACCESS: + return "userAccess"; + case SM_CODE_USER_LIMIT: + return "userLimit"; + case SM_CODE_WEAK_STREAM: + return "weakStream"; + case SM_CODE_NO_SPACE: + return "noDiskSpace"; + default: + return streaming_code2txt(smcode); } } /** * */ -static void -htsp_subscription_service_status(htsp_subscription_t *hs, int status) -{ - if(status & TSS_PACKETS) { +static void htsp_subscription_service_status(htsp_subscription_t* hs, int status) { + if (status & TSS_PACKETS) { htsp_subscription_status(hs, NULL, NULL); - } else if(status & TSS_ERRORS) { + } else if (status & TSS_ERRORS) { htsp_subscription_status(hs, service_tss2text(status), NULL); } } @@ -4455,22 +4270,20 @@ htsp_subscription_service_status(htsp_subscription_t *hs, int status) /** * */ -static void -htsp_subscription_signal_status(htsp_subscription_t *hs, signal_status_t *sig) -{ - htsmsg_t *m = htsmsg_create_map(); +static void htsp_subscription_signal_status(htsp_subscription_t* hs, signal_status_t* sig) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "method", "signalStatus"); htsmsg_add_u32(m, "subscriptionId", hs->hs_sid); if (!htsp_anonymize(hs->hs_htsp)) { - htsmsg_add_str(m, "feStatus", sig->status_text); - if((sig->snr != -2) && (sig->snr_scale == SIGNAL_STATUS_SCALE_RELATIVE)) - htsmsg_add_u32(m, "feSNR", sig->snr); - if((sig->signal != -2) && (sig->signal_scale == SIGNAL_STATUS_SCALE_RELATIVE)) + htsmsg_add_str(m, "feStatus", sig->status_text); + if ((sig->snr != -2) && (sig->snr_scale == SIGNAL_STATUS_SCALE_RELATIVE)) + htsmsg_add_u32(m, "feSNR", sig->snr); + if ((sig->signal != -2) && (sig->signal_scale == SIGNAL_STATUS_SCALE_RELATIVE)) htsmsg_add_u32(m, "feSignal", sig->signal); - if(sig->ber != -2) - htsmsg_add_u32(m, "feBER", sig->ber); - if(sig->unc != -2) - htsmsg_add_u32(m, "feUNC", sig->unc); + if (sig->ber != -2) + htsmsg_add_u32(m, "feBER", sig->ber); + if (sig->unc != -2) + htsmsg_add_u32(m, "feUNC", sig->unc); } else { htsmsg_add_str(m, "feStatus", ""); } @@ -4480,16 +4293,14 @@ htsp_subscription_signal_status(htsp_subscription_t *hs, signal_status_t *sig) /** * */ -static void -htsp_subscription_descramble_info(htsp_subscription_t *hs, descramble_info_t *di) -{ +static void htsp_subscription_descramble_info(htsp_subscription_t* hs, descramble_info_t* di) { /* don't bother old clients */ if (hs->hs_htsp->htsp_version < 24) return; if (htsp_anonymize(hs->hs_htsp)) return; - htsmsg_t *m = htsmsg_create_map(); + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "method", "descrambleInfo"); htsmsg_add_u32(m, "subscriptionId", hs->hs_sid); htsmsg_add_u32(m, "pid", di->pid); @@ -4511,10 +4322,8 @@ htsp_subscription_descramble_info(htsp_subscription_t *hs, descramble_info_t *di /** * */ -static void -htsp_subscription_speed(htsp_subscription_t *hs, int speed) -{ - htsmsg_t *m = htsmsg_create_map(); +static void htsp_subscription_speed(htsp_subscription_t* hs, int speed) { + htsmsg_t* m = htsmsg_create_map(); tvhdebug(LS_HTSP, "%s - subscription speed", hs->hs_htsp->htsp_logname); htsmsg_add_str(m, "method", "subscriptionSpeed"); htsmsg_add_u32(m, "subscriptionId", hs->hs_sid); @@ -4526,18 +4335,19 @@ htsp_subscription_speed(htsp_subscription_t *hs, int speed) * */ #if ENABLE_TIMESHIFT -static void -htsp_subscription_timeshift_status(htsp_subscription_t *hs, timeshift_status_t *status) -{ - htsmsg_t *m = htsmsg_create_map(); +static void htsp_subscription_timeshift_status(htsp_subscription_t* hs, + timeshift_status_t* status) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "method", "timeshiftStatus"); htsmsg_add_u32(m, "subscriptionId", hs->hs_sid); htsmsg_add_u32(m, "full", status->full); htsmsg_add_s64(m, "shift", hs->hs_90khz ? status->shift : ts_rescale(status->shift, 1000000)); if (status->pts_start != PTS_UNSET) - htsmsg_add_s64(m, "start", hs->hs_90khz ? status->pts_start : ts_rescale(status->pts_start, 1000000)) ; + htsmsg_add_s64(m, + "start", + hs->hs_90khz ? status->pts_start : ts_rescale(status->pts_start, 1000000)); if (status->pts_end != PTS_UNSET) - htsmsg_add_s64(m, "end", hs->hs_90khz ? status->pts_end : ts_rescale(status->pts_end, 1000000)) ; + htsmsg_add_s64(m, "end", hs->hs_90khz ? status->pts_end : ts_rescale(status->pts_end, 1000000)); htsp_send_subscription(hs->hs_htsp, m, NULL, hs, 0); } #endif @@ -4545,10 +4355,8 @@ htsp_subscription_timeshift_status(htsp_subscription_t *hs, timeshift_status_t * /** * */ -static void -htsp_subscription_skip(htsp_subscription_t *hs, streaming_skip_t *skip) -{ - htsmsg_t *m = htsmsg_create_map(); +static void htsp_subscription_skip(htsp_subscription_t* hs, streaming_skip_t* skip) { + htsmsg_t* m = htsmsg_create_map(); tvhdebug(LS_HTSP, "%s - subscription skip", hs->hs_htsp->htsp_logname); htsmsg_add_str(m, "method", "subscriptionSkip"); htsmsg_add_u32(m, "subscriptionId", hs->hs_sid); @@ -4575,82 +4383,80 @@ htsp_subscription_skip(htsp_subscription_t *hs, streaming_skip_t *skip) /** * */ -static void -htsp_streaming_input(void *opaque, streaming_message_t *sm) -{ - htsp_subscription_t *hs = opaque; +static void htsp_streaming_input(void* opaque, streaming_message_t* sm) { + htsp_subscription_t* hs = opaque; + + switch (sm->sm_type) { + case SMT_PACKET: + if (hs->hs_wait_for_video) + break; + if (!hs->hs_first) + tvhdebug(LS_HTSP, "%s - first packet", hs->hs_htsp->htsp_logname); + hs->hs_first = 1; + htsp_stream_deliver(hs, sm->sm_data); + // reference is transfered + sm->sm_data = NULL; + break; + + case SMT_START: + htsp_subscription_start(hs, sm->sm_data); + break; + + case SMT_STOP: + htsp_subscription_stop(hs, + streaming_code2txt(sm->sm_code), + sm->sm_code ? _htsp_get_subscription_status(sm->sm_code) : NULL); + break; + + case SMT_GRACE: + htsp_subscription_grace(hs, sm->sm_code); + break; + + case SMT_SERVICE_STATUS: + htsp_subscription_service_status(hs, sm->sm_code); + break; + + case SMT_SIGNAL_STATUS: + htsp_subscription_signal_status(hs, sm->sm_data); + break; + + case SMT_DESCRAMBLE_INFO: + htsp_subscription_descramble_info(hs, sm->sm_data); + break; - switch(sm->sm_type) { - case SMT_PACKET: - if (hs->hs_wait_for_video) + case SMT_NOSTART: + case SMT_NOSTART_WARN: + htsp_subscription_status(hs, + streaming_code2txt(sm->sm_code), + sm->sm_code ? _htsp_get_subscription_status(sm->sm_code) : NULL); break; - if (!hs->hs_first) - tvhdebug(LS_HTSP, "%s - first packet", hs->hs_htsp->htsp_logname); - hs->hs_first = 1; - htsp_stream_deliver(hs, sm->sm_data); - // reference is transfered - sm->sm_data = NULL; - break; - - case SMT_START: - htsp_subscription_start(hs, sm->sm_data); - break; - - case SMT_STOP: - htsp_subscription_stop(hs, streaming_code2txt(sm->sm_code), - sm->sm_code ? _htsp_get_subscription_status(sm->sm_code) : NULL); - break; - - case SMT_GRACE: - htsp_subscription_grace(hs, sm->sm_code); - break; - - case SMT_SERVICE_STATUS: - htsp_subscription_service_status(hs, sm->sm_code); - break; - - case SMT_SIGNAL_STATUS: - htsp_subscription_signal_status(hs, sm->sm_data); - break; - - case SMT_DESCRAMBLE_INFO: - htsp_subscription_descramble_info(hs, sm->sm_data); - break; - - case SMT_NOSTART: - case SMT_NOSTART_WARN: - htsp_subscription_status(hs, streaming_code2txt(sm->sm_code), - sm->sm_code ? _htsp_get_subscription_status(sm->sm_code) : NULL); - break; - - case SMT_MPEGTS: - break; - - case SMT_EXIT: - abort(); - - case SMT_SKIP: - htsp_subscription_skip(hs, sm->sm_data); - break; - - case SMT_SPEED: - htsp_subscription_speed(hs, sm->sm_code); - break; - - case SMT_TIMESHIFT_STATUS: + + case SMT_MPEGTS: + break; + + case SMT_EXIT: + abort(); + + case SMT_SKIP: + htsp_subscription_skip(hs, sm->sm_data); + break; + + case SMT_SPEED: + htsp_subscription_speed(hs, sm->sm_code); + break; + + case SMT_TIMESHIFT_STATUS: #if ENABLE_TIMESHIFT - htsp_subscription_timeshift_status(hs, sm->sm_data); + htsp_subscription_timeshift_status(hs, sm->sm_data); #endif - break; + break; } streaming_msg_free(sm); } -static htsmsg_t * -htsp_streaming_input_info(void *opaque, htsmsg_t *list) -{ - char buf[512]; - htsp_subscription_t *hs = opaque; +static htsmsg_t* htsp_streaming_input_info(void* opaque, htsmsg_t* list) { + char buf[512]; + htsp_subscription_t* hs = opaque; snprintf(buf, sizeof(buf), "htsp input: %s", hs->hs_htsp->htsp_logname); htsmsg_add_str(list, NULL, buf); return list; diff --git a/src/htsp_server.h b/src/htsp_server.h index 3b6470d51..3069db3b7 100644 --- a/src/htsp_server.h +++ b/src/htsp_server.h @@ -25,39 +25,39 @@ typedef enum { HTSP_DVR_PLAYCOUNT_RESET = 0, HTSP_DVR_PLAYCOUNT_SET = 1, - HTSP_DVR_PLAYCOUNT_KEEP = INT32_MAX-1, + HTSP_DVR_PLAYCOUNT_KEEP = INT32_MAX - 1, HTSP_DVR_PLAYCOUNT_INCR = INT32_MAX } dvr_playcount_t; -void htsp_init(const char *bindaddr); +void htsp_init(const char* bindaddr); void htsp_register(void); void htsp_done(void); -void htsp_channel_update_nownext(channel_t *ch); +void htsp_channel_update_nownext(channel_t* ch); -void htsp_channel_add(channel_t *ch); -void htsp_channel_update(channel_t *ch); -void htsp_channel_delete(channel_t *ch); +void htsp_channel_add(channel_t* ch); +void htsp_channel_update(channel_t* ch); +void htsp_channel_delete(channel_t* ch); -void htsp_tag_add(channel_tag_t *ct); -void htsp_tag_update(channel_tag_t *ct); -void htsp_tag_delete(channel_tag_t *ct); +void htsp_tag_add(channel_tag_t* ct); +void htsp_tag_update(channel_tag_t* ct); +void htsp_tag_delete(channel_tag_t* ct); -void htsp_dvr_entry_add(dvr_entry_t *de); -void htsp_dvr_entry_update(dvr_entry_t *de); -void htsp_dvr_entry_update_stats(dvr_entry_t *de); -void htsp_dvr_entry_delete(dvr_entry_t *de); +void htsp_dvr_entry_add(dvr_entry_t* de); +void htsp_dvr_entry_update(dvr_entry_t* de); +void htsp_dvr_entry_update_stats(dvr_entry_t* de); +void htsp_dvr_entry_delete(dvr_entry_t* de); -void htsp_autorec_entry_add(dvr_autorec_entry_t *dae); -void htsp_autorec_entry_update(dvr_autorec_entry_t *dae); -void htsp_autorec_entry_delete(dvr_autorec_entry_t *dae); +void htsp_autorec_entry_add(dvr_autorec_entry_t* dae); +void htsp_autorec_entry_update(dvr_autorec_entry_t* dae); +void htsp_autorec_entry_delete(dvr_autorec_entry_t* dae); -void htsp_timerec_entry_add(dvr_timerec_entry_t *dte); -void htsp_timerec_entry_update(dvr_timerec_entry_t *dte); -void htsp_timerec_entry_delete(dvr_timerec_entry_t *dte); +void htsp_timerec_entry_add(dvr_timerec_entry_t* dte); +void htsp_timerec_entry_update(dvr_timerec_entry_t* dte); +void htsp_timerec_entry_delete(dvr_timerec_entry_t* dte); -void htsp_event_add(epg_broadcast_t *ebc); -void htsp_event_update(epg_broadcast_t *ebc); -void htsp_event_delete(epg_broadcast_t *ebc); +void htsp_event_add(epg_broadcast_t* ebc); +void htsp_event_update(epg_broadcast_t* ebc); +void htsp_event_delete(epg_broadcast_t* ebc); #endif /* HTSP_H_ */ diff --git a/src/htsstr.c b/src/htsstr.c index 35c10d0d3..f29d49300 100644 --- a/src/htsstr.c +++ b/src/htsstr.c @@ -22,50 +22,45 @@ #include #include "tvh_string.h" -#define MIN(a,b) ((a) < (b) ? (a) : (b)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) -char * -hts_strndup(const char *src, size_t len) -{ - char *r = malloc(len + 1); - r[len] = 0; +char* hts_strndup(const char* src, size_t len) { + char* r = malloc(len + 1); + r[len] = 0; return memcpy(r, src, len); } -char * -htsstr_unescape(char *str) { - char *s; +char* htsstr_unescape(char* str) { + char* s; - for(s = str; *s; s++) { - if(*s != '\\') + for (s = str; *s; s++) { + if (*s != '\\') continue; - if(*(s + 1) == 'b') + if (*(s + 1) == 'b') *s = '\b'; - else if(*(s + 1) == 'f') + else if (*(s + 1) == 'f') *s = '\f'; - else if(*(s + 1) == 'n') + else if (*(s + 1) == 'n') *s = '\n'; - else if(*(s + 1) == 'r') + else if (*(s + 1) == 'r') *s = '\r'; - else if(*(s + 1) == 't') + else if (*(s + 1) == 't') *s = '\t'; else *s = *(s + 1); - if(*(s + 1)) { + if (*(s + 1)) { /* shift string left, copies terminator too */ memmove(s + 1, s + 2, strlen(s + 2) + 1); } - } + } return str; } -char * -htsstr_unescape_to(const char *src, char *dst, size_t dstlen) -{ - char *res = dst; +char* htsstr_unescape_to(const char* src, char* dst, size_t dstlen) { + char* res = dst; while (*src && dstlen > 0) { if (*src == '\\') { @@ -85,11 +80,16 @@ htsstr_unescape_to(const char *src, char *dst, size_t dstlen) *dst = '\t'; else *dst = *src; - src++; dst++; dstlen--; + src++; + dst++; + dstlen--; } continue; } else { - *dst = *src; src++; dst++; dstlen--; + *dst = *src; + src++; + dst++; + dstlen--; } } if (dstlen == 0) @@ -99,9 +99,7 @@ htsstr_unescape_to(const char *src, char *dst, size_t dstlen) return res; } -const char * -htsstr_escape_find(const char *src, size_t upto_index) -{ +const char* htsstr_escape_find(const char* src, size_t upto_index) { while (upto_index && *src) { if (*src == '\\') { src++; @@ -119,35 +117,31 @@ htsstr_escape_find(const char *src, size_t upto_index) return NULL; } -static void -htsstr_argsplit_add - (char ***argv, int *argc, const char *start, const char *stop) -{ - char *s = NULL; +static void htsstr_argsplit_add(char*** argv, int* argc, const char* start, const char* stop) { + char* s = NULL; if (start) s = htsstr_unescape(hts_strndup(start, stop - start)); - *argv = realloc(*argv, sizeof((*argv)[0]) * (*argc + 1)); + *argv = realloc(*argv, sizeof((*argv)[0]) * (*argc + 1)); (*argv)[(*argc)++] = s; } -char ** -htsstr_argsplit(const char *str) { - int quote = 0; - int quote_inbetween = 0; // when quote isn't start of argument - int inarg = 0; - const char *start = NULL; - const char *s; - char **argv = NULL; - int argc = 0; +char** htsstr_argsplit(const char* str) { + int quote = 0; + int quote_inbetween = 0; // when quote isn't start of argument + int inarg = 0; + const char* start = NULL; + const char* s; + char** argv = NULL; + int argc = 0; - for(s = str; *s; s++) { - if(inarg) { - switch(*s) { + for (s = str; *s; s++) { + if (inarg) { + switch (*s) { case '\\': s++; break; case '"': - if(quote) { + if (quote) { quote = 0; if (start) { htsstr_argsplit_add(&argv, &argc, start, s); @@ -160,7 +154,7 @@ htsstr_argsplit(const char *str) { } break; case ' ': - if(quote||quote_inbetween) + if (quote || quote_inbetween) break; inarg = 0; if (start) { @@ -172,7 +166,7 @@ htsstr_argsplit(const char *str) { break; } } else { - switch(*s) { + switch (*s) { case ' ': break; case '"': @@ -188,7 +182,7 @@ htsstr_argsplit(const char *str) { } } - if(start) + if (start) htsstr_argsplit_add(&argv, &argc, start, str + strlen(str)); htsstr_argsplit_add(&argv, &argc, NULL, NULL); @@ -196,19 +190,16 @@ htsstr_argsplit(const char *str) { return argv; } -void -htsstr_argsplit_free(char **argv) { +void htsstr_argsplit_free(char** argv) { int i; - for(i = 0; argv[i]; i++) + for (i = 0; argv[i]; i++) free(argv[i]); - + free(argv); } -const char * -htsstr_substitute_find(const char *src, int first) -{ +const char* htsstr_substitute_find(const char* src, int first) { while (*src) { if (*src == '\\') { src++; @@ -221,15 +212,18 @@ htsstr_substitute_find(const char *src, int first) return NULL; } -char * -htsstr_substitute(const char *src, char *dst, size_t dstlen, - int first, htsstr_substitute_t *sub, const void *aux, - char *tmp, size_t tmplen) -{ - htsstr_substitute_t *s; - const char *p, *x, *v; - char *res = dst; - size_t l; +char* htsstr_substitute(const char* src, + char* dst, + size_t dstlen, + int first, + htsstr_substitute_t* sub, + const void* aux, + char* tmp, + size_t tmplen) { + htsstr_substitute_t* s; + const char * p, *x, *v; + char* res = dst; + size_t l; if (!dstlen) return NULL; @@ -237,15 +231,24 @@ htsstr_substitute(const char *src, char *dst, size_t dstlen, if (*src == '\\') { if (dstlen < 2) break; - *dst = '\\'; src++; dst++; dstlen--; + *dst = '\\'; + src++; + dst++; + dstlen--; if (*src) { - *dst = *src; src++; dst++; dstlen--; + *dst = *src; + src++; + dst++; + dstlen--; } continue; } if (first >= 0) { if (*src != first) { - *dst = *src; src++; dst++; dstlen--; + *dst = *src; + src++; + dst++; + dstlen--; continue; } src++; @@ -280,7 +283,8 @@ htsstr_substitute(const char *src, char *dst, size_t dstlen, *dst = *src; src++; } - dst++; dstlen--; + dst++; + dstlen--; } } if (dstlen == 0) diff --git a/src/http.c b/src/http.c index 903b26a07..bbf834fb6 100644 --- a/src/http.c +++ b/src/http.c @@ -32,77 +32,66 @@ #include #endif -void *http_server; +void* http_server; static int http_server_running; -static tvh_mutex_t http_paths_mutex = TVH_THREAD_MUTEX_INITIALIZER; +static tvh_mutex_t http_paths_mutex = TVH_THREAD_MUTEX_INITIALIZER; static http_path_list_t http_paths; static struct strtab HTTP_cmdtab[] = { - { "NONE", HTTP_CMD_NONE }, - { "GET", HTTP_CMD_GET }, - { "HEAD", HTTP_CMD_HEAD }, - { "POST", HTTP_CMD_POST }, - { "DESCRIBE", RTSP_CMD_DESCRIBE }, - { "OPTIONS", RTSP_CMD_OPTIONS }, - { "SETUP", RTSP_CMD_SETUP }, - { "PLAY", RTSP_CMD_PLAY }, - { "TEARDOWN", RTSP_CMD_TEARDOWN }, - { "PAUSE", RTSP_CMD_PAUSE }, - { "GET_PARAMETER", RTSP_CMD_GET_PARAMETER }, + {"NONE", HTTP_CMD_NONE}, + {"GET", HTTP_CMD_GET}, + {"HEAD", HTTP_CMD_HEAD}, + {"POST", HTTP_CMD_POST}, + {"DESCRIBE", RTSP_CMD_DESCRIBE}, + {"OPTIONS", RTSP_CMD_OPTIONS}, + {"SETUP", RTSP_CMD_SETUP}, + {"PLAY", RTSP_CMD_PLAY}, + {"TEARDOWN", RTSP_CMD_TEARDOWN}, + {"PAUSE", RTSP_CMD_PAUSE}, + {"GET_PARAMETER", RTSP_CMD_GET_PARAMETER}, }; - - static struct strtab HTTP_versiontab[] = { - { "HTTP/1.0", HTTP_VERSION_1_0 }, - { "HTTP/1.1", HTTP_VERSION_1_1 }, - { "RTSP/1.0", RTSP_VERSION_1_0 }, + {"HTTP/1.0", HTTP_VERSION_1_0}, + {"HTTP/1.1", HTTP_VERSION_1_1}, + {"RTSP/1.0", RTSP_VERSION_1_0}, }; /** * */ -const char * -http_cmd2str(int val) -{ +const char* http_cmd2str(int val) { return val2str(val, HTTP_cmdtab); } -int http_str2cmd(const char *str) -{ +int http_str2cmd(const char* str) { return str2val(str, HTTP_cmdtab); } -const char * -http_ver2str(int val) -{ +const char* http_ver2str(int val) { return val2str(val, HTTP_versiontab); } -int http_str2ver(const char *str) -{ +int http_str2ver(const char* str) { return str2val(str, HTTP_versiontab); } /** * */ -static int -http_resolve(http_connection_t *hc, http_path_t *_hp, - char **remainp, char **argsp) -{ - http_path_t *hp; - int n = 0, cut = 0; - char *v, *path = tvh_strdupa(hc->hc_url); - char *npath; +static int http_resolve(http_connection_t* hc, http_path_t* _hp, char** remainp, char** argsp) { + http_path_t* hp; + int n = 0, cut = 0; + char * v, *path = tvh_strdupa(hc->hc_url); + char* npath; /* Canocalize path (or at least remove excess slashes) */ - v = path; + v = path; while (*v && *v != '?') { if (*v == '/' && v[1] == '/') { - int l = strlen(v+1); - memmove(v, v+1, l); + int l = strlen(v + 1); + memmove(v, v + 1, l); v[l] = 0; n++; } else @@ -112,110 +101,113 @@ http_resolve(http_connection_t *hc, http_path_t *_hp, while (1) { tvh_mutex_lock(hc->hc_paths_mutex); - LIST_FOREACH(hp, hc->hc_paths, hp_link) { - if(!strncmp(path, hp->hp_path, hp->hp_len)) { - if(path[hp->hp_len] == 0 || - path[hp->hp_len] == '/' || - path[hp->hp_len] == '?') + LIST_FOREACH (hp, hc->hc_paths, hp_link) { + if (!strncmp(path, hp->hp_path, hp->hp_len)) { + if (path[hp->hp_len] == 0 || path[hp->hp_len] == '/' || path[hp->hp_len] == '?') break; } } if (hp) { *_hp = *hp; - hp = _hp; + hp = _hp; } tvh_mutex_unlock(hc->hc_paths_mutex); - if(hp == NULL) + if (hp == NULL) return 0; cut += hp->hp_len; - if(hp->hp_path_modify == NULL) + if (hp->hp_path_modify == NULL) break; npath = hp->hp_path_modify(hc, path, &cut); - if(npath == NULL) + if (npath == NULL) break; path = tvh_strdupa(npath); free(npath); - } v = hc->hc_url + n + cut; *remainp = NULL; - *argsp = NULL; + *argsp = NULL; - switch(*v) { - case 0: - break; + switch (*v) { + case 0: + break; - case '/': - if(v[1] == '?') { - *argsp = v + 1; + case '/': + if (v[1] == '?') { + *argsp = v + 1; + break; + } + + *remainp = v + 1; + v = strchr(v + 1, '?'); + if (v != NULL) { + *v = 0; /* terminate remaining url */ + *argsp = v + 1; + } break; - } - *remainp = v + 1; - v = strchr(v + 1, '?'); - if(v != NULL) { - *v = 0; /* terminate remaining url */ + case '?': + *v = 0; /* terminate remaining url */ *argsp = v + 1; - } - break; - - case '?': - *v = 0; /* terminate remaining url */ - *argsp = v + 1; - break; + break; - default: - return 0; + default: + return 0; } return 1; } - - /* * HTTP status code to string */ -static const char * -http_rc2str(int code) -{ - switch(code) { - case HTTP_STATUS_PSWITCH: /* 101 */ return "Switching Protocols"; - case HTTP_STATUS_OK: /* 200 */ return "OK"; - case HTTP_STATUS_PARTIAL_CONTENT: /* 206 */ return "Partial Content"; - case HTTP_STATUS_FOUND: /* 302 */ return "Found"; - case HTTP_STATUS_BAD_REQUEST: /* 400 */ return "Bad Request"; - case HTTP_STATUS_UNAUTHORIZED: /* 401 */ return "Unauthorized"; - case HTTP_STATUS_FORBIDDEN: /* 403 */ return "Forbidden"; - case HTTP_STATUS_NOT_FOUND: /* 404 */ return "Not Found"; - case HTTP_STATUS_NOT_ALLOWED: /* 405 */ return "Method Not Allowed"; - case HTTP_STATUS_UNSUPPORTED: /* 415 */ return "Unsupported Media Type"; - case HTTP_STATUS_BANDWIDTH: /* 453 */ return "Not Enough Bandwidth"; - case HTTP_STATUS_BAD_SESSION: /* 454 */ return "Session Not Found"; - case HTTP_STATUS_INTERNAL: /* 500 */ return "Internal Server Error"; - case HTTP_STATUS_HTTP_VERSION: /* 505 */ return "HTTP/RTSP Version Not Supported"; -default: - return "Unknown Code"; - break; +static const char* http_rc2str(int code) { + switch (code) { + case HTTP_STATUS_PSWITCH: /* 101 */ + return "Switching Protocols"; + case HTTP_STATUS_OK: /* 200 */ + return "OK"; + case HTTP_STATUS_PARTIAL_CONTENT: /* 206 */ + return "Partial Content"; + case HTTP_STATUS_FOUND: /* 302 */ + return "Found"; + case HTTP_STATUS_BAD_REQUEST: /* 400 */ + return "Bad Request"; + case HTTP_STATUS_UNAUTHORIZED: /* 401 */ + return "Unauthorized"; + case HTTP_STATUS_FORBIDDEN: /* 403 */ + return "Forbidden"; + case HTTP_STATUS_NOT_FOUND: /* 404 */ + return "Not Found"; + case HTTP_STATUS_NOT_ALLOWED: /* 405 */ + return "Method Not Allowed"; + case HTTP_STATUS_UNSUPPORTED: /* 415 */ + return "Unsupported Media Type"; + case HTTP_STATUS_BANDWIDTH: /* 453 */ + return "Not Enough Bandwidth"; + case HTTP_STATUS_BAD_SESSION: /* 454 */ + return "Session Not Found"; + case HTTP_STATUS_INTERNAL: /* 500 */ + return "Internal Server Error"; + case HTTP_STATUS_HTTP_VERSION: /* 505 */ + return "HTTP/RTSP Version Not Supported"; + default: + return "Unknown Code"; + break; } } -static const char *cachedays[7] = { - "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" -}; +static const char* cachedays[7] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}; -static const char *cachemonths[12] = { - "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", - "Dec" -}; +static const char* cachemonths[12] = + {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; /** * Digest authentication helpers @@ -223,51 +215,43 @@ static const char *cachemonths[12] = { typedef struct http_nonce { RB_ENTRY(http_nonce) link; mtimer_t expire; - char nonce[64]; + char nonce[64]; } http_nonce_t; static RB_HEAD(, http_nonce) http_nonces; -static int -http_nonce_cmp(const void *a, const void *b) -{ - return strcmp(((http_nonce_t *)a)->nonce, ((http_nonce_t *)b)->nonce); +static int http_nonce_cmp(const void* a, const void* b) { + return strcmp(((http_nonce_t*)a)->nonce, ((http_nonce_t*)b)->nonce); } -static void -http_nonce_timeout(void *aux) -{ - struct http_nonce *n = aux; +static void http_nonce_timeout(void* aux) { + struct http_nonce* n = aux; RB_REMOVE(&http_nonces, n, link); free(n); } -static char * -http_get_digest_hash(int algo, const char *msg) -{ +static char* http_get_digest_hash(int algo, const char* msg) { switch (algo) { - case HTTP_AUTH_ALGO_MD5: - return md5sum(msg, 1); - case HTTP_AUTH_ALGO_SHA256: - return sha256sum(msg, 1); - default: - return sha512sum256(msg, 1); + case HTTP_AUTH_ALGO_MD5: + return md5sum(msg, 1); + case HTTP_AUTH_ALGO_SHA256: + return sha256sum(msg, 1); + default: + return sha512sum256(msg, 1); } } -static int -http_get_nonce(http_connection_t *hc) -{ - struct http_nonce *n = calloc(1, sizeof(*n)); - char stamp[33], *m; - int64_t mono; - static int64_t xor; +static int http_get_nonce(http_connection_t* hc) { + struct http_nonce* n = calloc(1, sizeof(*n)); + char stamp[33], *m; + int64_t mono; + static int64_t xor ; while (1) { mono = getmonoclock(); mono ^= 0xa1687211885fcd30LL; xor ^= 0xf6e398624aa55013LL; - snprintf(stamp, sizeof(stamp), "A!*Fz32%"PRId64"%"PRId64, mono, xor); + snprintf(stamp, sizeof(stamp), "A!*Fz32%" PRId64 "%" PRId64, mono, xor); m = sha256sum_base64(stamp); if (m == NULL) { free(n); @@ -288,9 +272,7 @@ http_get_nonce(http_connection_t *hc) return 0; } -static int -http_nonce_exists(const char *nonce) -{ +static int http_nonce_exists(const char* nonce) { struct http_nonce *n, tmp; if (nonce == NULL) @@ -299,7 +281,7 @@ http_nonce_exists(const char *nonce) tvh_mutex_lock(&global_lock); n = RB_FIND(&http_nonces, &tmp, link, http_nonce_cmp); if (n) { - mtimer_arm_rel(&n->expire, http_nonce_timeout, n, sec2mono(2*60)); + mtimer_arm_rel(&n->expire, http_nonce_timeout, n, sec2mono(2 * 60)); tvh_mutex_unlock(&global_lock); return 1; } @@ -307,10 +289,8 @@ http_nonce_exists(const char *nonce) return 0; } -static char * -http_get_opaque(http_connection_t *hc, const char *realm) -{ - char *a = alloca(strlen(realm) + strlen(hc->hc_nonce) + 1); +static char* http_get_opaque(http_connection_t* hc, const char* realm) { + char* a = alloca(strlen(realm) + strlen(hc->hc_nonce) + 1); strcpy(a, realm); strcat(a, hc->hc_nonce); return sha256sum_base64(a); @@ -319,9 +299,7 @@ http_get_opaque(http_connection_t *hc, const char *realm) /** * */ -void -http_alive(http_connection_t *hc) -{ +void http_alive(http_connection_t* hc) { if (hc->hc_nonce) http_nonce_exists(hc->hc_nonce); /* update timer */ } @@ -329,11 +307,11 @@ http_alive(http_connection_t *hc) /** * */ -static void -http_auth_header - (htsbuf_queue_t *hdrs, const char *realm, const char *algo, - const char *nonce, const char *opaque) -{ +static void http_auth_header(htsbuf_queue_t* hdrs, + const char* realm, + const char* algo, + const char* nonce, + const char* opaque) { htsbuf_qprintf(hdrs, "WWW-Authenticate: Digest realm=\"%s\", qop=auth", realm); if (algo) htsbuf_qprintf(hdrs, ", algorithm=%s", algo); @@ -344,80 +322,93 @@ http_auth_header /** * Transmit a HTTP reply */ -void -http_send_header(http_connection_t *hc, int rc, const char *content, - int64_t contentlen, - const char *encoding, const char *location, - int maxage, const char *range, - const char *disposition, - http_arg_list_t *args) -{ - struct tm tm0, *tm; +void http_send_header(http_connection_t* hc, + int rc, + const char* content, + int64_t contentlen, + const char* encoding, + const char* location, + int maxage, + const char* range, + const char* disposition, + http_arg_list_t* args) { + struct tm tm0, *tm; htsbuf_queue_t hdrs; - http_arg_t *ra; - time_t t; - int sess = 0; + http_arg_t* ra; + time_t t; + int sess = 0; assert(atomic_get(&hc->hc_extra_insend) > 0); htsbuf_queue_init(&hdrs, 0); - htsbuf_qprintf(&hdrs, "%s %d %s\r\n", - http_ver2str(hc->hc_version), rc, http_rc2str(rc)); + htsbuf_qprintf(&hdrs, "%s %d %s\r\n", http_ver2str(hc->hc_version), rc, http_rc2str(rc)); - if (hc->hc_version != RTSP_VERSION_1_0){ + if (hc->hc_version != RTSP_VERSION_1_0) { htsbuf_qprintf(&hdrs, "Server: %s\r\n", config_get_http_server_name()); if (config.cors_origin && config.cors_origin[0]) { - htsbuf_qprintf(&hdrs, "Access-Control-Allow-Origin: %s\r\n%s%s%s", config.cors_origin, - "Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n", - "Access-Control-Allow-Headers: x-requested-with,authorization,content-type\r\n", - "Access-Control-Allow-Credentials: true\r\n"); + htsbuf_qprintf(&hdrs, + "Access-Control-Allow-Origin: %s\r\n%s%s%s", + config.cors_origin, + "Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n", + "Access-Control-Allow-Headers: x-requested-with,authorization,content-type\r\n", + "Access-Control-Allow-Credentials: true\r\n"); } } - - if(maxage == 0) { + + if (maxage == 0) { if (hc->hc_version != RTSP_VERSION_1_0) htsbuf_append_str(&hdrs, "Cache-Control: no-cache\r\n"); } else if (maxage > 0) { time(&t); tm = gmtime_r(&t, &tm0); - htsbuf_qprintf(&hdrs, - "Last-Modified: %s, %d %s %02d %02d:%02d:%02d GMT\r\n", - cachedays[tm->tm_wday], tm->tm_mday, - cachemonths[tm->tm_mon], tm->tm_year + 1900, - tm->tm_hour, tm->tm_min, tm->tm_sec); + htsbuf_qprintf(&hdrs, + "Last-Modified: %s, %d %s %02d %02d:%02d:%02d GMT\r\n", + cachedays[tm->tm_wday], + tm->tm_mday, + cachemonths[tm->tm_mon], + tm->tm_year + 1900, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); t += maxage; tm = gmtime_r(&t, &tm0); - htsbuf_qprintf(&hdrs, - "Expires: %s, %d %s %02d %02d:%02d:%02d GMT\r\n", - cachedays[tm->tm_wday], tm->tm_mday, - cachemonths[tm->tm_mon], tm->tm_year + 1900, - tm->tm_hour, tm->tm_min, tm->tm_sec); - + htsbuf_qprintf(&hdrs, + "Expires: %s, %d %s %02d %02d:%02d:%02d GMT\r\n", + cachedays[tm->tm_wday], + tm->tm_mday, + cachemonths[tm->tm_mon], + tm->tm_year + 1900, + tm->tm_hour, + tm->tm_min, + tm->tm_sec); + htsbuf_qprintf(&hdrs, "Cache-Control: max-age=%d\r\n", maxage); } - if(rc == HTTP_STATUS_UNAUTHORIZED) { - const char *realm = tvh_str_default(config.realm, "tvheadend"); - if (config.http_auth == HTTP_AUTH_DIGEST || - config.http_auth == HTTP_AUTH_PLAIN_DIGEST) { - char *opaque; - if (hc->hc_nonce == NULL && http_get_nonce(hc)) goto __noauth; + if (rc == HTTP_STATUS_UNAUTHORIZED) { + const char* realm = tvh_str_default(config.realm, "tvheadend"); + if (config.http_auth == HTTP_AUTH_DIGEST || config.http_auth == HTTP_AUTH_PLAIN_DIGEST) { + char* opaque; + if (hc->hc_nonce == NULL && http_get_nonce(hc)) + goto __noauth; opaque = http_get_opaque(hc, realm); - if (opaque == NULL) goto __noauth; + if (opaque == NULL) + goto __noauth; if (config.http_auth_algo != HTTP_AUTH_ALGO_MD5) - http_auth_header(&hdrs, realm, - config.http_auth_algo == HTTP_AUTH_ALGO_SHA256 ? - "SHA-256" : + http_auth_header(&hdrs, + realm, + config.http_auth_algo == HTTP_AUTH_ALGO_SHA256 ? "SHA-256" : #if OPENSSL_VERSION_NUMBER >= 0x1010101fL && !defined(LIBRESSL_VERSION_NUMBER) - "SHA-512-256", + "SHA-512-256", #else - "SHA-256", + "SHA-256", #endif - hc->hc_nonce, opaque); + hc->hc_nonce, + opaque); http_auth_header(&hdrs, realm, NULL, hc->hc_nonce, opaque); free(opaque); } else { @@ -427,45 +418,44 @@ http_send_header(http_connection_t *hc, int rc, const char *content, __noauth: if (hc->hc_version != RTSP_VERSION_1_0) - htsbuf_qprintf(&hdrs, "Connection: %s\r\n", - hc->hc_keep_alive ? "Keep-Alive" : "Close"); + htsbuf_qprintf(&hdrs, "Connection: %s\r\n", hc->hc_keep_alive ? "Keep-Alive" : "Close"); - if(encoding != NULL) + if (encoding != NULL) htsbuf_qprintf(&hdrs, "Content-Encoding: %s\r\n", encoding); - if(location != NULL) + if (location != NULL) htsbuf_qprintf(&hdrs, "Location: %s\r\n", location); - if(content != NULL) + if (content != NULL) htsbuf_qprintf(&hdrs, "Content-Type: %s\r\n", content); - if(contentlen > 0) - htsbuf_qprintf(&hdrs, "Content-Length: %"PRId64"\r\n", contentlen); - else if(contentlen == INT64_MIN) + if (contentlen > 0) + htsbuf_qprintf(&hdrs, "Content-Length: %" PRId64 "\r\n", contentlen); + else if (contentlen == INT64_MIN) htsbuf_append_str(&hdrs, "Content-Length: 0\r\n"); - if(range) { + if (range) { htsbuf_qprintf(&hdrs, "Accept-Ranges: %s\r\n", "bytes"); htsbuf_qprintf(&hdrs, "Content-Range: %s\r\n", range); } - if(disposition != NULL) + if (disposition != NULL) htsbuf_qprintf(&hdrs, "Content-Disposition: %s\r\n", disposition); - - if(hc->hc_cseq) { - htsbuf_qprintf(&hdrs, "CSeq: %"PRIu64"\r\n", hc->hc_cseq); + + if (hc->hc_cseq) { + htsbuf_qprintf(&hdrs, "CSeq: %" PRIu64 "\r\n", hc->hc_cseq); if (++hc->hc_cseq == 0) hc->hc_cseq = 1; } if (args) { - TAILQ_FOREACH(ra, args, link) { + TAILQ_FOREACH (ra, args, link) { if (strcmp(ra->key, "Session") == 0) sess = 1; htsbuf_qprintf(&hdrs, "%s: %s\r\n", ra->key, ra->val ?: ""); } } - if(hc->hc_session && !sess) + if (hc->hc_session && !sess) htsbuf_qprintf(&hdrs, "Session: %s\r\n", hc->hc_session); htsbuf_append_str(&hdrs, "\r\n"); @@ -476,15 +466,13 @@ __noauth: /* * Transmit a websocket upgrade reply */ -int -http_send_header_websocket(http_connection_t *hc, const char *protocol) -{ +int http_send_header_websocket(http_connection_t* hc, const char* protocol) { htsbuf_queue_t hdrs; - const int rc = HTTP_STATUS_PSWITCH; - uint8_t hash[20]; - const char *s; - const char *guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; - char encoded[512]; + const int rc = HTTP_STATUS_PSWITCH; + uint8_t hash[20]; + const char* s; + const char* guid = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + char encoded[512]; s = http_arg_get(&hc->hc_args, "sec-websocket-key"); if (s == NULL || strlen(s) < 10) { @@ -494,18 +482,19 @@ http_send_header_websocket(http_connection_t *hc, const char *protocol) htsbuf_queue_init(&hdrs, 0); - htsbuf_qprintf(&hdrs, "%s %d %s\r\n", - http_ver2str(hc->hc_version), rc, http_rc2str(rc)); + htsbuf_qprintf(&hdrs, "%s %d %s\r\n", http_ver2str(hc->hc_version), rc, http_rc2str(rc)); - sha1_calc(hash, (uint8_t *)s, strlen(s), (uint8_t *)guid, strlen(guid)); + sha1_calc(hash, (uint8_t*)s, strlen(s), (uint8_t*)guid, strlen(guid)); base64_encode(encoded, sizeof(encoded), hash, sizeof(hash)); - htsbuf_qprintf(&hdrs, "Upgrade: websocket\r\n" - "Connection: Upgrade\r\n" - "Sec-WebSocket-Accept: %s\r\n" - "Sec-WebSocket-Protocol: %s\r\n" - "\r\n", - encoded, protocol); + htsbuf_qprintf(&hdrs, + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Accept: %s\r\n" + "Sec-WebSocket-Protocol: %s\r\n" + "\r\n", + encoded, + protocol); http_send_begin(hc); tcp_write_queue(hc->hc_fd, &hdrs); @@ -516,18 +505,16 @@ http_send_header_websocket(http_connection_t *hc, const char *protocol) /* * */ -int -http_encoding_valid(http_connection_t *hc, const char *encoding) -{ - const char *accept; - char *tokbuf, *tok, *saveptr = NULL, *q, *s; +int http_encoding_valid(http_connection_t* hc, const char* encoding) { + const char* accept; + char * tokbuf, *tok, *saveptr = NULL, *q, *s; accept = http_arg_get(&hc->hc_args, "accept-encoding"); if (!accept) return 0; tokbuf = tvh_strdupa(accept); - tok = strtok_r(tokbuf, ",", &saveptr); + tok = strtok_r(tokbuf, ",", &saveptr); while (tok) { while (*tok == ' ') tok++; @@ -541,7 +528,8 @@ http_encoding_valid(http_connection_t *hc, const char *encoding) if ((s = strchr(tok, ' ')) != NULL) *s = '\0'; // check for matching encoding with q > 0 - if ((!strcasecmp(tok, encoding) || !strcmp(tok, "*")) && (q == NULL || strncmp(q, "q=0.000", strlen(q)))) + if ((!strcasecmp(tok, encoding) || !strcmp(tok, "*")) && + (q == NULL || strncmp(q, "q=0.000", strlen(q)))) return 1; tok = strtok_r(NULL, ",", &saveptr); } @@ -551,16 +539,14 @@ http_encoding_valid(http_connection_t *hc, const char *encoding) /** * */ -int -http_header_match(http_connection_t *hc, const char *name, const char *value) -{ +int http_header_match(http_connection_t* hc, const char* name, const char* value) { char *tokbuf, *tok, *saveptr = NULL, *q, *s; s = http_arg_get(&hc->hc_args, name); if (s == NULL) return 0; tokbuf = tvh_strdupa(s); - tok = strtok_r(tokbuf, ",", &saveptr); + tok = strtok_r(tokbuf, ",", &saveptr); while (tok) { while (*tok == ' ') tok++; @@ -584,31 +570,35 @@ http_header_match(http_connection_t *hc, const char *name, const char *value) /** * */ -static char * -http_get_header_value(const char *hdr, const char *name) -{ +static char* http_get_header_value(const char* hdr, const char* name) { char *s, *start, *val; s = tvh_strdupa(hdr); while (*s) { - while (*s && *s <= ' ') s++; + while (*s && *s <= ' ') + s++; start = s; - while (*s && *s != '=') s++; + while (*s && *s != '=') + s++; if (*s == '=') { *s = '\0'; s++; } - while (*s && *s <= ' ') s++; + while (*s && *s <= ' ') + s++; if (*s == '"') { val = ++s; - while (*s && *s != '"') s++; + while (*s && *s != '"') + s++; if (*s == '"') { *s = '\0'; s++; } - while (*s && (*s <= ' ' || *s == ',')) s++; + while (*s && (*s <= ' ' || *s == ',')) + s++; } else { val = s; - while (*s && *s != ',') s++; + while (*s && *s != ',') + s++; *s = '\0'; s++; } @@ -621,12 +611,10 @@ http_get_header_value(const char *hdr, const char *name) /** * */ -int -http_check_local_ip( http_connection_t *hc ) -{ +int http_check_local_ip(http_connection_t* hc) { if (hc->hc_local_ip == NULL) { - hc->hc_local_ip = malloc(sizeof(*hc->hc_local_ip)); - *hc->hc_local_ip = *hc->hc_self; + hc->hc_local_ip = malloc(sizeof(*hc->hc_local_ip)); + *hc->hc_local_ip = *hc->hc_self; hc->hc_is_local_ip = ip_check_is_local_address(hc->hc_peer, hc->hc_self, hc->hc_local_ip) > 0; } return hc->hc_is_local_ip; @@ -635,27 +623,28 @@ http_check_local_ip( http_connection_t *hc ) /** * Transmit a HTTP reply */ -static void -http_send_reply(http_connection_t *hc, int rc, const char *content, - const char *encoding, const char *location, int maxage) -{ - size_t size = hc->hc_reply.hq_size; - uint8_t *data = NULL; +static void http_send_reply(http_connection_t* hc, + int rc, + const char* content, + const char* encoding, + const char* location, + int maxage) { + size_t size = hc->hc_reply.hq_size; + uint8_t* data = NULL; #if ENABLE_ZLIB if (http_encoding_valid(hc, "gzip") && encoding == NULL && size > 256) { - uint8_t *data2 = (uint8_t *)htsbuf_to_string(&hc->hc_reply); - data = tvh_gzip_deflate(data2, size, &size); + uint8_t* data2 = (uint8_t*)htsbuf_to_string(&hc->hc_reply); + data = tvh_gzip_deflate(data2, size, &size); free(data2); encoding = "gzip"; } #endif http_send_begin(hc); - http_send_header(hc, rc, content, size, - encoding, location, maxage, 0, NULL, NULL); - - if(!hc->hc_no_output) { + http_send_header(hc, rc, content, size, encoding, location, maxage, 0, NULL, NULL); + + if (!hc->hc_no_output) { if (data == NULL) tcp_write_queue(hc->hc_fd, &hc->hc_reply); else @@ -666,18 +655,16 @@ http_send_reply(http_connection_t *hc, int rc, const char *content, free(data); } - /** * Send HTTP error back */ -void -http_error(http_connection_t *hc, int error) -{ - const char *errtxt = http_rc2str(error); - const char *lang; - int level; +void http_error(http_connection_t* hc, int error) { + const char* errtxt = http_rc2str(error); + const char* lang; + int level; - if (!atomic_get(&http_server_running)) return; + if (!atomic_get(&http_server_running)) + return; if (error != HTTP_STATUS_FOUND && error != HTTP_STATUS_MOVED) { level = LOG_INFO; @@ -685,30 +672,43 @@ http_error(http_connection_t *hc, int error) level = LOG_DEBUG; else if (error == HTTP_STATUS_BAD_REQUEST || error > HTTP_STATUS_UNAUTHORIZED) level = LOG_ERR; - tvhlog(level, hc->hc_subsys, "%s: %s %s (%d) %s -- %d", - hc->hc_peer_ipstr, http_ver2str(hc->hc_version), - http_cmd2str(hc->hc_cmd), hc->hc_cmd, hc->hc_url, error); + tvhlog(level, + hc->hc_subsys, + "%s: %s %s (%d) %s -- %d", + hc->hc_peer_ipstr, + http_ver2str(hc->hc_version), + http_cmd2str(hc->hc_cmd), + hc->hc_cmd, + hc->hc_url, + error); } if (hc->hc_version != RTSP_VERSION_1_0) { htsbuf_queue_flush(&hc->hc_reply); htsbuf_qprintf(&hc->hc_reply, - "\r\n" - "\r\n" - "%d %s\r\n" - "\r\n" - "

%d %s

\r\n", - error, errtxt, error, errtxt); + "\r\n" + "\r\n" + "%d %s\r\n" + "\r\n" + "

%d %s

\r\n", + error, + errtxt, + error, + errtxt); if (error == HTTP_STATUS_UNAUTHORIZED) { lang = hc->hc_access ? hc->hc_access->aa_lang_ui : NULL; - htsbuf_qprintf(&hc->hc_reply, "

%s

", - tvheadend_webroot ? tvheadend_webroot : "", - tvh_gettext_lang(lang, N_("Default login"))); - htsbuf_qprintf(&hc->hc_reply, "

%s

", - tvheadend_webroot ? tvheadend_webroot : "", - tvh_gettext_lang(lang, N_("New login"))); + htsbuf_qprintf(&hc->hc_reply, + "

%s

", + tvheadend_webroot ? tvheadend_webroot : "", + tvh_gettext_lang(lang, N_("Default login"))); + htsbuf_qprintf(&hc->hc_reply, + "

%s

", + tvheadend_webroot ? tvheadend_webroot : "", + tvh_gettext_lang(lang, N_("New login"))); } htsbuf_append_str(&hc->hc_reply, "\r\n"); @@ -719,47 +719,39 @@ http_error(http_connection_t *hc, int error) } } - /** * Send an HTTP OK, simple version for text/html */ -void -http_output_html(http_connection_t *hc) -{ - return http_send_reply(hc, HTTP_STATUS_OK, "text/html; charset=UTF-8", - NULL, NULL, 0); +void http_output_html(http_connection_t* hc) { + return http_send_reply(hc, HTTP_STATUS_OK, "text/html; charset=UTF-8", NULL, NULL, 0); } /** * Send an HTTP OK, simple version for text/html */ -void -http_output_content(http_connection_t *hc, const char *content) -{ +void http_output_content(http_connection_t* hc, const char* content) { return http_send_reply(hc, HTTP_STATUS_OK, content, NULL, NULL, 0); } - - /** * Send an HTTP REDIRECT */ -void -http_redirect(http_connection_t *hc, const char *location, - http_arg_list_t *req_args, int external) -{ - const char *loc = location; +void http_redirect(http_connection_t* hc, + const char* location, + http_arg_list_t* req_args, + int external) { + const char* loc = location; htsbuf_queue_flush(&hc->hc_reply); if (req_args) { - http_arg_t *ra; + http_arg_t* ra; htsbuf_queue_t hq; - int first = 1; + int first = 1; htsbuf_queue_init(&hq, 0); if (!external && tvheadend_webroot && location[0] == '/') htsbuf_append_str(&hq, tvheadend_webroot); htsbuf_append_str(&hq, location); - TAILQ_FOREACH(ra, req_args, link) { + TAILQ_FOREACH (ra, req_args, link) { if (!first) htsbuf_append(&hq, "&", 1); else @@ -775,40 +767,38 @@ http_redirect(http_connection_t *hc, const char *location, htsbuf_queue_flush(&hq); } else if (!external && tvheadend_webroot && location[0] == '/') { loc = malloc(strlen(location) + strlen(tvheadend_webroot) + 1); - strcpy((char *)loc, tvheadend_webroot); - strcat((char *)loc, location); + strcpy((char*)loc, tvheadend_webroot); + strcat((char*)loc, location); } htsbuf_qprintf(&hc->hc_reply, - "\r\n" - "\r\n" - "Redirect\r\n" - "\r\n" - "Please follow %s\r\n" - "\r\n", - loc, loc); + "\r\n" + "\r\n" + "Redirect\r\n" + "\r\n" + "Please follow %s\r\n" + "\r\n", + loc, + loc); http_send_reply(hc, HTTP_STATUS_FOUND, "text/html", NULL, loc, 0); if (loc != location) - free((char *)loc); + free((char*)loc); } - /** * Send an CSS @import */ -void -http_css_import(http_connection_t *hc, const char *location) -{ - const char *loc = location; +void http_css_import(http_connection_t* hc, const char* location) { + const char* loc = location; htsbuf_queue_flush(&hc->hc_reply); if (tvheadend_webroot && location[0] == '/') { loc = alloca(strlen(location) + strlen(tvheadend_webroot) + 1); - strcpy((char *)loc, tvheadend_webroot); - strcat((char *)loc, location); + strcpy((char*)loc, tvheadend_webroot); + strcat((char*)loc, location); } htsbuf_qprintf(&hc->hc_reply, "@import url('%s');\r\n", loc); @@ -819,9 +809,7 @@ http_css_import(http_connection_t *hc, const char *location) /** * */ -void -http_extra_destroy(http_connection_t *hc) -{ +void http_extra_destroy(http_connection_t* hc) { htsbuf_data_t *hd, *hd_next; tvh_mutex_lock(&hc->hc_extra_lock); @@ -838,17 +826,15 @@ http_extra_destroy(http_connection_t *hc) /** * */ -int -http_extra_flush(http_connection_t *hc) -{ - htsbuf_data_t *hd; - int r, serr = 0; +int http_extra_flush(http_connection_t* hc) { + htsbuf_data_t* hd; + int r, serr = 0; if (atomic_add(&hc->hc_extra_insend, 1) != 0) goto fin; while (1) { - r = -1; + r = -1; serr = 0; tvh_mutex_lock(&hc->hc_extra_lock); if (atomic_add(&hc->hc_extra_insend, 0) != 1) @@ -857,9 +843,10 @@ http_extra_flush(http_connection_t *hc) if (hd == NULL) goto unlock; do { - r = send(hc->hc_fd, hd->hd_data + hd->hd_data_off, - hd->hd_data_size - hd->hd_data_off, - MSG_DONTWAIT | (TAILQ_NEXT(hd, hd_link) ? MSG_MORE : 0)); + r = send(hc->hc_fd, + hd->hd_data + hd->hd_data_off, + hd->hd_data_size - hd->hd_data_off, + MSG_DONTWAIT | (TAILQ_NEXT(hd, hd_link) ? MSG_MORE : 0)); serr = errno; } while (r < 0 && serr == EINTR); if (r > 0 && r + hd->hd_data_off >= hd->hd_data_size) { @@ -869,7 +856,7 @@ http_extra_flush(http_connection_t *hc) hd->hd_data_off += r; hc->hc_extra.hq_size -= r; } -unlock: + unlock: tvh_mutex_unlock(&hc->hc_extra_lock); if (r < 0) { @@ -887,23 +874,21 @@ fin: /** * */ -int -http_extra_flush_partial(http_connection_t *hc) -{ - htsbuf_data_t *hd; - int r = 0; - unsigned int off, size; - void *data = NULL; +int http_extra_flush_partial(http_connection_t* hc) { + htsbuf_data_t* hd; + int r = 0; + unsigned int off, size; + void* data = NULL; atomic_add(&hc->hc_extra_insend, 1); tvh_mutex_lock(&hc->hc_extra_lock); hd = TAILQ_FIRST(&hc->hc_extra.hq_q); if (hd && hd->hd_data_off > 0) { - data = hd->hd_data; + data = hd->hd_data; hd->hd_data = NULL; - off = hd->hd_data_off; - size = hd->hd_data_size; + off = hd->hd_data_off; + size = hd->hd_data_size; atomic_dec(&hc->hc_extra_chunks, 1); htsbuf_data_free(&hc->hc_extra, hd); } @@ -919,11 +904,8 @@ http_extra_flush_partial(http_connection_t *hc) /** * */ -int -http_extra_send(http_connection_t *hc, const void *data, - size_t data_len, int may_discard) -{ - uint8_t *b = malloc(data_len); +int http_extra_send(http_connection_t* hc, const void* data, size_t data_len, int may_discard) { + uint8_t* b = malloc(data_len); memcpy(b, data, data_len); return http_extra_send_prealloc(hc, b, data_len, may_discard); } @@ -931,17 +913,18 @@ http_extra_send(http_connection_t *hc, const void *data, /** * */ -int -http_extra_send_prealloc(http_connection_t *hc, const void *data, - size_t data_len, int may_discard) -{ - if (data == NULL) return 0; +int http_extra_send_prealloc(http_connection_t* hc, + const void* data, + size_t data_len, + int may_discard) { + if (data == NULL) + return 0; tvh_mutex_lock(&hc->hc_extra_lock); - if (!may_discard || hc->hc_extra.hq_size <= 1024*1024) { + if (!may_discard || hc->hc_extra.hq_size <= 1024 * 1024) { atomic_add(&hc->hc_extra_chunks, 1); htsbuf_append_prealloc(&hc->hc_extra, data, data_len); } else { - free((void *)data); + free((void*)data); } tvh_mutex_unlock(&hc->hc_extra_lock); return http_extra_flush(hc); @@ -950,17 +933,13 @@ http_extra_send_prealloc(http_connection_t *hc, const void *data, /** * */ -char * -http_get_hostpath(http_connection_t *hc, char *buf, size_t buflen) -{ +char* http_get_hostpath(http_connection_t* hc, char* buf, size_t buflen) { const char *host, *proto; - host = http_arg_get(&hc->hc_args, "Host") ?: - http_arg_get(&hc->hc_args, "X-Forwarded-Host"); + host = http_arg_get(&hc->hc_args, "Host") ?: http_arg_get(&hc->hc_args, "X-Forwarded-Host"); proto = http_arg_get(&hc->hc_args, "X-Forwarded-Proto"); - snprintf(buf, buflen, "%s://%s%s", - proto ?: "http", host ?: "localhost", tvheadend_webroot ?: ""); + snprintf(buf, buflen, "%s://%s%s", proto ?: "http", host ?: "localhost", tvheadend_webroot ?: ""); return buf; } @@ -968,92 +947,83 @@ http_get_hostpath(http_connection_t *hc, char *buf, size_t buflen) /** * */ -static void -http_access_verify_ticket(http_connection_t *hc) -{ - const char *ticket_id; +static void http_access_verify_ticket(http_connection_t* hc) { + const char* ticket_id; - ticket_id = http_arg_get(&hc->hc_req_args, "ticket"); + ticket_id = http_arg_get(&hc->hc_req_args, "ticket"); hc->hc_access = access_ticket_verify2(ticket_id, hc->hc_url); if (hc->hc_access == NULL) return; hc->hc_auth_type = HC_AUTH_TICKET; - tvhinfo(hc->hc_subsys, "%s: using ticket %s for %s", - hc->hc_peer_ipstr, ticket_id, hc->hc_url); + tvhinfo(hc->hc_subsys, "%s: using ticket %s for %s", hc->hc_peer_ipstr, ticket_id, hc->hc_url); } /** * */ -static void -http_access_verify_auth(http_connection_t *hc) -{ - const char *auth_id; +static void http_access_verify_auth(http_connection_t* hc) { + const char* auth_id; - auth_id = http_arg_get(&hc->hc_req_args, "auth"); + auth_id = http_arg_get(&hc->hc_req_args, "auth"); hc->hc_access = access_get_by_auth(hc->hc_peer, auth_id); if (hc->hc_access == NULL) return; hc->hc_auth_type = HC_AUTH_PERM; - tvhinfo(hc->hc_subsys, "%s: using auth %s for %s", - hc->hc_peer_ipstr, auth_id, hc->hc_url); + tvhinfo(hc->hc_subsys, "%s: using auth %s for %s", hc->hc_peer_ipstr, auth_id, hc->hc_url); } /** * */ struct http_verify_structure { - char *password; - char *d_ha1; - char *d_all; - char *d_response; - int algo; - http_connection_t *hc; + char* password; + char* d_ha1; + char* d_all; + char* d_response; + int algo; + http_connection_t* hc; }; -static int -http_verify_callback(void *aux, const char *passwd) -{ - struct http_verify_structure *v = aux; - char ha1[512]; - char all[1024]; - char *m; - int res; - - if (v->d_ha1) { - snprintf(ha1, sizeof(ha1), "%s:%s", v->d_ha1, passwd); - m = http_get_digest_hash(v->algo, ha1); - snprintf(all, sizeof(all), "%s:%s", m, v->d_all); - free(m); - m = http_get_digest_hash(v->algo, all); - res = strcmp(m, v->d_response) == 0; - free(m); - return res; - } - if (v->password == NULL) return 0; - return strcmp(v->password, passwd) == 0; +static int http_verify_callback(void* aux, const char* passwd) { + struct http_verify_structure* v = aux; + char ha1[512]; + char all[1024]; + char* m; + int res; + + if (v->d_ha1) { + snprintf(ha1, sizeof(ha1), "%s:%s", v->d_ha1, passwd); + m = http_get_digest_hash(v->algo, ha1); + snprintf(all, sizeof(all), "%s:%s", m, v->d_all); + free(m); + m = http_get_digest_hash(v->algo, all); + res = strcmp(m, v->d_response) == 0; + free(m); + return res; + } + if (v->password == NULL) + return 0; + return strcmp(v->password, passwd) == 0; } /** * */ -static int -http_verify_prepare(http_connection_t *hc, struct http_verify_structure *v) -{ +static int http_verify_prepare(http_connection_t* hc, struct http_verify_structure* v) { memset(v, 0, sizeof(*v)); if (hc->hc_authhdr) { if (hc->hc_nonce == NULL) return -1; - const char *method = http_cmd2str(hc->hc_cmd); - char *response = http_get_header_value(hc->hc_authhdr, "response"); - char *qop = http_get_header_value(hc->hc_authhdr, "qop"); - char *uri = http_get_header_value(hc->hc_authhdr, "uri"); - char *algo1 = http_get_header_value(hc->hc_authhdr, "algorithm"); - char *realm = NULL, *nonce_count = NULL, *cnonce = NULL, *m = NULL; - char all[1024]; - int res = -1; + const char* method = http_cmd2str(hc->hc_cmd); + char* response = http_get_header_value(hc->hc_authhdr, "response"); + char* qop = http_get_header_value(hc->hc_authhdr, "qop"); + char* uri = http_get_header_value(hc->hc_authhdr, "uri"); + char* algo1 = http_get_header_value(hc->hc_authhdr, "algorithm"); + char * realm = NULL, *nonce_count = NULL, *cnonce = NULL, *m = NULL; + char all[1024]; + int res = -1; if (algo1 == NULL || strcasecmp(algo1, "MD5") == 0) { v->algo = HTTP_AUTH_ALGO_MD5; @@ -1067,7 +1037,7 @@ http_verify_prepare(http_connection_t *hc, struct http_verify_structure *v) if (qop == NULL || uri == NULL) goto end; - + if (strcasecmp(qop, "auth-int") == 0) { m = http_get_digest_hash(v->algo, hc->hc_post_data ?: ""); snprintf(all, sizeof(all), "%s:%s:%s", method, uri, m); @@ -1084,26 +1054,24 @@ http_verify_prepare(http_connection_t *hc, struct http_verify_structure *v) snprintf(all, sizeof(all), "%s:%s", hc->hc_nonce, m); goto set; } else { - realm = http_get_header_value(hc->hc_authhdr, "realm"); + realm = http_get_header_value(hc->hc_authhdr, "realm"); nonce_count = http_get_header_value(hc->hc_authhdr, "nc"); - cnonce = http_get_header_value(hc->hc_authhdr, "cnonce"); - if (realm == NULL || strcmp(realm, config.realm) || - nonce_count == NULL || cnonce == NULL) { + cnonce = http_get_header_value(hc->hc_authhdr, "cnonce"); + if (realm == NULL || strcmp(realm, config.realm) || nonce_count == NULL || cnonce == NULL) { goto end; } else { - snprintf(all, sizeof(all), "%s:%s:%s:%s:%s", - hc->hc_nonce, nonce_count, cnonce, qop, m); -set: + snprintf(all, sizeof(all), "%s:%s:%s:%s:%s", hc->hc_nonce, nonce_count, cnonce, qop, m); + set: v->d_all = strdup(all); snprintf(all, sizeof(all), "%s:%s", hc->hc_username, realm); - v->d_ha1 = strdup(all); + v->d_ha1 = strdup(all); v->d_response = response; - v->hc = hc; - response = NULL; + v->hc = hc; + response = NULL; } } res = 0; -end: + end: free(response); free(qop); free(uri); @@ -1122,9 +1090,7 @@ end: /* * */ -static void -http_verify_free(struct http_verify_structure *v) -{ +static void http_verify_free(struct http_verify_structure* v) { free(v->d_ha1); free(v->d_all); free(v->d_response); @@ -1133,11 +1099,9 @@ http_verify_free(struct http_verify_structure *v) /** * Return non-zero if no access */ -int -http_access_verify(http_connection_t *hc, int mask) -{ +int http_access_verify(http_connection_t* hc, int mask) { struct http_verify_structure v; - int r; + int r; /* quick path */ if (hc->hc_access) @@ -1157,8 +1121,7 @@ http_access_verify(http_connection_t *hc, int mask) hc->hc_access = NULL; return -1; } - hc->hc_access = access_get(hc->hc_peer, hc->hc_username, - http_verify_callback, &v); + hc->hc_access = access_get(hc->hc_peer, hc->hc_username, http_verify_callback, &v); http_verify_free(&v); if (hc->hc_access) { r = access_verify2(hc->hc_access, mask); @@ -1177,10 +1140,7 @@ http_access_verify(http_connection_t *hc, int mask) /** * Return non-zero if no access */ -int -http_access_verify_channel(http_connection_t *hc, int mask, - struct channel *ch) -{ +int http_access_verify_channel(http_connection_t* hc, int mask, struct channel* ch) { if (http_access_verify(hc, mask)) return -1; @@ -1190,9 +1150,7 @@ http_access_verify_channel(http_connection_t *hc, int mask, /** * */ -const char * -http_username(http_connection_t *hc) -{ +const char* http_username(http_connection_t* hc) { if (strempty(hc->hc_username) && hc->hc_access) return hc->hc_access->aa_username; return hc->hc_username; @@ -1201,19 +1159,14 @@ http_username(http_connection_t *hc) /** * */ -int -http_noaccess_code(http_connection_t *hc) -{ - return strempty(hc->hc_username) ? - HTTP_STATUS_UNAUTHORIZED : HTTP_STATUS_FORBIDDEN; +int http_noaccess_code(http_connection_t* hc) { + return strempty(hc->hc_username) ? HTTP_STATUS_UNAUTHORIZED : HTTP_STATUS_FORBIDDEN; } /** * */ -static int -http_websocket_valid(http_connection_t *hc) -{ +static int http_websocket_valid(http_connection_t* hc) { if (!http_header_match(hc, "connection", "upgrade") || http_arg_get(&hc->hc_args, "sec-websocket-key") == NULL) return HTTP_STATUS_UNSUPPORTED; @@ -1224,11 +1177,9 @@ http_websocket_valid(http_connection_t *hc) * Execute url callback * * Returns 1 if we should disconnect - * + * */ -static int -http_exec(http_connection_t *hc, http_path_t *hp, char *remain) -{ +static int http_exec(http_connection_t* hc, http_path_t* hp, char* remain) { int err; /* this is a special case when client probably requires authentication */ @@ -1252,10 +1203,10 @@ destroy: access_destroy(hc->hc_access); hc->hc_access = NULL; - if(err == -1) - return 1; + if (err == -1) + return 1; - if(err) + if (err) http_error(hc, err); return 0; } @@ -1263,40 +1214,39 @@ destroy: /* * Dump request */ -static void -dump_request(http_connection_t *hc) -{ - char buf[2048] = ""; - http_arg_t *ra; - int first, ptr = 0; +static void dump_request(http_connection_t* hc) { + char buf[2048] = ""; + http_arg_t* ra; + int first, ptr = 0; first = 1; - TAILQ_FOREACH(ra, &hc->hc_req_args, link) { + TAILQ_FOREACH (ra, &hc->hc_req_args, link) { tvh_strlcatf(buf, sizeof(buf), ptr, first ? "?%s=%s" : "&%s=%s", ra->key, ra->val); first = 0; } first = 1; - TAILQ_FOREACH(ra, &hc->hc_args, link) { + TAILQ_FOREACH (ra, &hc->hc_args, link) { tvh_strlcatf(buf, sizeof(buf), ptr, first ? "{{%s=%s" : ",%s=%s", ra->key, ra->val); first = 0; } if (!first) tvh_strlcatf(buf, sizeof(buf), ptr, "}}"); - tvhtrace(hc->hc_subsys, "%s %s %s%s", http_ver2str(hc->hc_version), - http_cmd2str(hc->hc_cmd), hc->hc_url, buf); + tvhtrace(hc->hc_subsys, + "%s %s %s%s", + http_ver2str(hc->hc_version), + http_cmd2str(hc->hc_cmd), + hc->hc_url, + buf); } /** * HTTP GET */ -static int -http_cmd_options(http_connection_t *hc) -{ +static int http_cmd_options(http_connection_t* hc) { http_send_begin(hc); - http_send_header(hc, HTTP_STATUS_OK, NULL, INT64_MIN, - NULL, NULL, -1, 0, NULL, NULL); + http_send_header(hc, HTTP_STATUS_OK, NULL, INT64_MIN, NULL, NULL, -1, 0, NULL, NULL); http_send_end(hc); return 0; } @@ -1304,12 +1254,10 @@ http_cmd_options(http_connection_t *hc) /** * HTTP GET */ -static int -http_cmd_get(http_connection_t *hc) -{ +static int http_cmd_get(http_connection_t* hc) { http_path_t hp; - char *remain; - char *args; + char* remain; + char* args; if (tvhtrace_enabled()) dump_request(hc); @@ -1319,36 +1267,30 @@ http_cmd_get(http_connection_t *hc) return 0; } - if(args != NULL) + if (args != NULL) http_parse_args(&hc->hc_req_args, args); return http_exec(hc, &hp, remain); } - - - - /** * Initial processing of HTTP POST * * Return non-zero if we should disconnect */ -static int -http_cmd_post(http_connection_t *hc, htsbuf_queue_t *spill) -{ +static int http_cmd_post(http_connection_t* hc, htsbuf_queue_t* spill) { http_path_t hp; - char *remain, *args, *v; + char * remain, *args, *v; /* Set keep-alive status */ v = http_arg_get(&hc->hc_args, "Content-Length"); - if(v == NULL) { + if (v == NULL) { /* No content length in POST, make us disconnect */ return -1; } hc->hc_post_len = atoi(v); - if(hc->hc_post_len > 16 * 1024 * 1024) { + if (hc->hc_post_len > 16 * 1024 * 1024) { /* Bail out if POST data > 16 Mb */ hc->hc_keep_alive = 0; return -1; @@ -1357,23 +1299,23 @@ http_cmd_post(http_connection_t *hc, htsbuf_queue_t *spill) /* Allocate space for data, we add a terminating null char to ease string processing on the content */ - hc->hc_post_data = malloc(hc->hc_post_len + 1); + hc->hc_post_data = malloc(hc->hc_post_len + 1); hc->hc_post_data[hc->hc_post_len] = 0; - if(tcp_read_data(hc->hc_fd, hc->hc_post_data, hc->hc_post_len, spill) < 0) + if (tcp_read_data(hc->hc_fd, hc->hc_post_data, hc->hc_post_len, spill) < 0) return -1; /* Parse content-type */ v = http_arg_get(&hc->hc_args, "Content-Type"); - if(v != NULL) { - char *argv[2]; - int n = http_tokenize(v, argv, 2, ';'); - if(n == 0) { + if (v != NULL) { + char* argv[2]; + int n = http_tokenize(v, argv, 2, ';'); + if (n == 0) { http_error(hc, HTTP_STATUS_BAD_REQUEST); return 0; } - if(!strcmp(argv[0], "application/x-www-form-urlencoded")) + if (!strcmp(argv[0], "application/x-www-form-urlencoded")) http_parse_args(&hc->hc_req_args, hc->hc_post_data); } @@ -1387,26 +1329,23 @@ http_cmd_post(http_connection_t *hc, htsbuf_queue_t *spill) return http_exec(hc, &hp, remain); } - /** * Process a HTTP request */ -static int -http_process_request(http_connection_t *hc, htsbuf_queue_t *spill) -{ - switch(hc->hc_cmd) { - default: - http_error(hc, HTTP_STATUS_BAD_REQUEST); - return 0; - case HTTP_CMD_OPTIONS: - return http_cmd_options(hc); - case HTTP_CMD_GET: - return http_cmd_get(hc); - case HTTP_CMD_HEAD: - hc->hc_no_output = 1; - return http_cmd_get(hc); - case HTTP_CMD_POST: - return http_cmd_post(hc, spill); +static int http_process_request(http_connection_t* hc, htsbuf_queue_t* spill) { + switch (hc->hc_cmd) { + default: + http_error(hc, HTTP_STATUS_BAD_REQUEST); + return 0; + case HTTP_CMD_OPTIONS: + return http_cmd_options(hc); + case HTTP_CMD_GET: + return http_cmd_get(hc); + case HTTP_CMD_HEAD: + hc->hc_no_output = 1; + return http_cmd_get(hc); + case HTTP_CMD_POST: + return http_cmd_post(hc, spill); } } @@ -1414,12 +1353,10 @@ http_process_request(http_connection_t *hc, htsbuf_queue_t *spill) * Process a request, extract info from headers, dispatch command and * clean up */ -static int -process_request(http_connection_t *hc, htsbuf_queue_t *spill) -{ +static int process_request(http_connection_t* hc, htsbuf_queue_t* spill) { char *v, *argv[2]; - int n, rval = -1; - char authbuf[150]; + int n, rval = -1; + char authbuf[150]; hc->hc_url_orig = tvh_strdupa(hc->hc_url); @@ -1438,54 +1375,53 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill) tcp_get_str_from_ip(hc->hc_peer, authbuf, sizeof(authbuf)); - hc->hc_peer_ipstr = tvh_strdupa(authbuf); + hc->hc_peer_ipstr = tvh_strdupa(authbuf); hc->hc_representative = hc->hc_peer_ipstr; - hc->hc_username = NULL; - hc->hc_password = NULL; - hc->hc_authhdr = NULL; - hc->hc_session = NULL; + hc->hc_username = NULL; + hc->hc_password = NULL; + hc->hc_authhdr = NULL; + hc->hc_session = NULL; /* Set keep-alive status */ v = http_arg_get(&hc->hc_args, "connection"); - switch(hc->hc_version) { - case RTSP_VERSION_1_0: - hc->hc_keep_alive = 1; - /* Extract CSeq */ - if((v = http_arg_get(&hc->hc_args, "CSeq")) != NULL) { - hc->hc_cseq = strtoll(v, NULL, 10); - } else { - hc->hc_cseq = 0; - } - free(hc->hc_session); - if ((v = http_arg_get(&hc->hc_args, "Session")) != NULL) - hc->hc_session = tvh_strdupa(v); - else - hc->hc_session = NULL; - break; + switch (hc->hc_version) { + case RTSP_VERSION_1_0: + hc->hc_keep_alive = 1; + /* Extract CSeq */ + if ((v = http_arg_get(&hc->hc_args, "CSeq")) != NULL) { + hc->hc_cseq = strtoll(v, NULL, 10); + } else { + hc->hc_cseq = 0; + } + free(hc->hc_session); + if ((v = http_arg_get(&hc->hc_args, "Session")) != NULL) + hc->hc_session = tvh_strdupa(v); + else + hc->hc_session = NULL; + break; - case HTTP_VERSION_1_0: - /* Keep-alive is default off, but can be enabled */ - hc->hc_keep_alive = v != NULL && !strcasecmp(v, "keep-alive"); - break; - - case HTTP_VERSION_1_1: - /* Keep-alive is default on, but can be disabled */ - hc->hc_keep_alive = !(v != NULL && !strcasecmp(v, "close")); - break; + case HTTP_VERSION_1_0: + /* Keep-alive is default off, but can be enabled */ + hc->hc_keep_alive = v != NULL && !strcasecmp(v, "keep-alive"); + break; + + case HTTP_VERSION_1_1: + /* Keep-alive is default on, but can be disabled */ + hc->hc_keep_alive = !(v != NULL && !strcasecmp(v, "close")); + break; } /* Extract authorization */ - if((v = http_arg_get(&hc->hc_args, "Authorization")) != NULL) { - if((n = http_tokenize(v, argv, 2, -1)) == 2) { + if ((v = http_arg_get(&hc->hc_args, "Authorization")) != NULL) { + if ((n = http_tokenize(v, argv, 2, -1)) == 2) { if (strcasecmp(argv[0], "basic") == 0) { - if (config.http_auth == HTTP_AUTH_PLAIN || - config.http_auth == HTTP_AUTH_PLAIN_DIGEST) { - n = base64_decode((uint8_t *)authbuf, argv[1], sizeof(authbuf) - 1); + if (config.http_auth == HTTP_AUTH_PLAIN || config.http_auth == HTTP_AUTH_PLAIN_DIGEST) { + n = base64_decode((uint8_t*)authbuf, argv[1], sizeof(authbuf) - 1); if (n < 0) n = 0; authbuf[n] = 0; - if((n = http_tokenize(authbuf, argv, 2, ':')) == 2) { + if ((n = http_tokenize(authbuf, argv, 2, ':')) == 2) { hc->hc_username = tvh_strdupa(argv[0]); hc->hc_password = tvh_strdupa(argv[1]); http_deescape(hc->hc_username); @@ -1500,8 +1436,7 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill) return -1; } } else if (strcasecmp(argv[0], "digest") == 0) { - if (config.http_auth == HTTP_AUTH_DIGEST || - config.http_auth == HTTP_AUTH_PLAIN_DIGEST) { + if (config.http_auth == HTTP_AUTH_DIGEST || config.http_auth == HTTP_AUTH_PLAIN_DIGEST) { v = http_get_header_value(argv[1], "nonce"); if (v == NULL || !http_nonce_exists(v)) { free(v); @@ -1509,8 +1444,8 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill) return -1; } free(hc->hc_nonce); - hc->hc_nonce = v; - v = http_get_header_value(argv[1], "username"); + hc->hc_nonce = v; + v = http_get_header_value(argv[1], "username"); hc->hc_authhdr = tvh_strdupa(argv[1]); hc->hc_username = tvh_strdupa(v); http_deescape(hc->hc_username); @@ -1529,60 +1464,50 @@ process_request(http_connection_t *hc, htsbuf_queue_t *spill) if (hc->hc_username) hc->hc_representative = hc->hc_username; - switch(hc->hc_version) { - case RTSP_VERSION_1_0: - if (tvhtrace_enabled()) - dump_request(hc); - rval = hc->hc_process(hc, spill); - break; - - case HTTP_VERSION_1_0: - case HTTP_VERSION_1_1: - if (!hc->hc_cseq) + switch (hc->hc_version) { + case RTSP_VERSION_1_0: + if (tvhtrace_enabled()) + dump_request(hc); rval = hc->hc_process(hc, spill); - else - http_error(hc, HTTP_STATUS_HTTP_VERSION); - break; + break; + + case HTTP_VERSION_1_0: + case HTTP_VERSION_1_1: + if (!hc->hc_cseq) + rval = hc->hc_process(hc, spill); + else + http_error(hc, HTTP_STATUS_HTTP_VERSION); + break; } return rval; } - - /* * Delete one argument */ -void -http_arg_remove(struct http_arg_list *list, struct http_arg *arg) -{ +void http_arg_remove(struct http_arg_list* list, struct http_arg* arg) { TAILQ_REMOVE(list, arg, link); free(arg->key); free(arg->val); free(arg); } - /* * Delete all arguments associated with a connection */ -void -http_arg_flush(http_arg_list_t *list) -{ - http_arg_t *ra; - while((ra = TAILQ_FIRST(list)) != NULL) +void http_arg_flush(http_arg_list_t* list) { + http_arg_t* ra; + while ((ra = TAILQ_FIRST(list)) != NULL) http_arg_remove(list, ra); } - /** * Find an argument associated with a connection */ -char * -http_arg_get(http_arg_list_t *list, const char *name) -{ - http_arg_t *ra; - TAILQ_FOREACH(ra, list, link) - if(!strcasecmp(ra->key, name)) +char* http_arg_get(http_arg_list_t* list, const char* name) { + http_arg_t* ra; + TAILQ_FOREACH (ra, list, link) + if (!strcasecmp(ra->key, name)) return ra->val; return NULL; } @@ -1590,14 +1515,12 @@ http_arg_get(http_arg_list_t *list, const char *name) /** * Find an argument associated with a connection and remove it */ -char * -http_arg_get_remove(struct http_arg_list *list, const char *name) -{ +char* http_arg_get_remove(struct http_arg_list* list, const char* name) { static __thread char buf[128]; - int empty; - http_arg_t *ra; - TAILQ_FOREACH(ra, list, link) - if(!strcasecmp(ra->key, name)) { + int empty; + http_arg_t* ra; + TAILQ_FOREACH (ra, list, link) + if (!strcasecmp(ra->key, name)) { TAILQ_REMOVE(list, ra, link); empty = ra->val == NULL; if (!empty) @@ -1611,14 +1534,11 @@ http_arg_get_remove(struct http_arg_list *list, const char *name) return buf; } - /** * Set an argument associated with a connection */ -void -http_arg_set(struct http_arg_list *list, const char *key, const char *val) -{ - http_arg_t *ra; +void http_arg_set(struct http_arg_list* list, const char* key, const char* val) { + http_arg_t* ra; ra = malloc(sizeof(http_arg_t)); TAILQ_INSERT_TAIL(list, ra, link); @@ -1629,18 +1549,16 @@ http_arg_set(struct http_arg_list *list, const char *key, const char *val) /* * */ -char * -http_arg_get_query(http_arg_list_t *args) -{ +char* http_arg_get_query(http_arg_list_t* args) { htsbuf_queue_t q; - http_arg_t *ra; - char *r; + http_arg_t* ra; + char* r; if (http_args_empty(args)) return NULL; htsbuf_queue_init(&q, 0); htsbuf_queue_init(&q, 0); - TAILQ_FOREACH(ra, args, link) { + TAILQ_FOREACH (ra, args, link) { if (!htsbuf_empty(&q)) htsbuf_append(&q, "&", 1); htsbuf_append_and_escape_url(&q, ra->key); @@ -1657,22 +1575,20 @@ http_arg_get_query(http_arg_list_t *args) /* * Split a string in components delimited by 'delimiter' */ -int -http_tokenize(char *buf, char **vec, int vecsize, int delimiter) -{ +int http_tokenize(char* buf, char** vec, int vecsize, int delimiter) { int n = 0; - while(1) { - while((*buf > 0 && *buf < 33) || *buf == delimiter) + while (1) { + while ((*buf > 0 && *buf < 33) || *buf == delimiter) buf++; - if(*buf == 0) + if (*buf == 0) break; vec[n++] = buf; - if(n == vecsize) + if (n == vecsize) break; - while(*buf > 32 && *buf != delimiter) + while (*buf > 32 && *buf != delimiter) buf++; - if(*buf == 0) + if (*buf == 0) break; *buf = 0; buf++; @@ -1680,29 +1596,29 @@ http_tokenize(char *buf, char **vec, int vecsize, int delimiter) return n; } - /** * Add a callback for a given "virtual path" on our HTTP server */ -http_path_t * -http_path_add_modify(const char *path, void *opaque, http_callback_t *callback, - uint32_t accessmask, http_path_modify_t *path_modify) -{ - http_path_t *hp = malloc(sizeof(http_path_t)); - char *tmp; +http_path_t* http_path_add_modify(const char* path, + void* opaque, + http_callback_t* callback, + uint32_t accessmask, + http_path_modify_t* path_modify) { + http_path_t* hp = malloc(sizeof(http_path_t)); + char* tmp; if (tvheadend_webroot) { - size_t len = strlen(tvheadend_webroot) + strlen(path) + 1; - hp->hp_path = tmp = malloc(len); + size_t len = strlen(tvheadend_webroot) + strlen(path) + 1; + hp->hp_path = tmp = malloc(len); sprintf(tmp, "%s%s", tvheadend_webroot, path); } else - hp->hp_path = strdup(path); - hp->hp_len = strlen(hp->hp_path); - hp->hp_opaque = opaque; - hp->hp_callback = callback; - hp->hp_accessmask = accessmask; + hp->hp_path = strdup(path); + hp->hp_len = strlen(hp->hp_path); + hp->hp_opaque = opaque; + hp->hp_callback = callback; + hp->hp_accessmask = accessmask; hp->hp_path_modify = path_modify; - hp->hp_flags = 0; + hp->hp_flags = 0; tvh_mutex_lock(&http_paths_mutex); LIST_INSERT_HEAD(&http_paths, hp, hp_link); tvh_mutex_unlock(&http_paths_mutex); @@ -1712,51 +1628,55 @@ http_path_add_modify(const char *path, void *opaque, http_callback_t *callback, /** * Add a callback for a given "virtual path" on our HTTP server */ -http_path_t * -http_path_add(const char *path, void *opaque, http_callback_t *callback, - uint32_t accessmask) -{ +http_path_t* +http_path_add(const char* path, void* opaque, http_callback_t* callback, uint32_t accessmask) { return http_path_add_modify(path, opaque, callback, accessmask, NULL); } /** * */ -int -http_websocket_send(http_connection_t *hc, uint8_t *buf, uint64_t buflen, - int opcode) -{ - int op, r = 0; - uint8_t b[10]; +int http_websocket_send(http_connection_t* hc, uint8_t* buf, uint64_t buflen, int opcode) { + int op, r = 0; + uint8_t b[10]; uint64_t bsize; switch (opcode) { - case HTTP_WSOP_TEXT: op = 0x01; break; - case HTTP_WSOP_BINARY: op = 0x02; break; - case HTTP_WSOP_PING: op = 0x09; break; - case HTTP_WSOP_PONG: op = 0x0a; break; - default: return -1; + case HTTP_WSOP_TEXT: + op = 0x01; + break; + case HTTP_WSOP_BINARY: + op = 0x02; + break; + case HTTP_WSOP_PING: + op = 0x09; + break; + case HTTP_WSOP_PONG: + op = 0x0a; + break; + default: + return -1; } b[0] = 0x80 | op; /* FIN + opcode */ if (buflen <= 125) { - b[1] = buflen; + b[1] = buflen; bsize = 2; } else if (buflen <= 65535) { - b[1] = 126; - b[2] = (buflen >> 8) & 0xff; - b[3] = buflen & 0xff; + b[1] = 126; + b[2] = (buflen >> 8) & 0xff; + b[3] = buflen & 0xff; bsize = 4; } else { - b[1] = 127; - b[2] = (buflen >> 56) & 0xff; - b[3] = (buflen >> 48) & 0xff; - b[4] = (buflen >> 40) & 0xff; - b[5] = (buflen >> 32) & 0xff; - b[6] = (buflen >> 24) & 0xff; - b[7] = (buflen >> 16) & 0xff; - b[8] = (buflen >> 8) & 0xff; - b[9] = (buflen >> 0) & 0xff; + b[1] = 127; + b[2] = (buflen >> 56) & 0xff; + b[3] = (buflen >> 48) & 0xff; + b[4] = (buflen >> 40) & 0xff; + b[5] = (buflen >> 32) & 0xff; + b[6] = (buflen >> 24) & 0xff; + b[7] = (buflen >> 16) & 0xff; + b[8] = (buflen >> 8) & 0xff; + b[9] = (buflen >> 0) & 0xff; bsize = 10; } http_send_begin(hc); @@ -1771,18 +1691,16 @@ http_websocket_send(http_connection_t *hc, uint8_t *buf, uint64_t buflen, /** * */ -int -http_websocket_send_json(http_connection_t *hc, htsmsg_t *msg) -{ +int http_websocket_send_json(http_connection_t* hc, htsmsg_t* msg) { htsbuf_queue_t q; - char *s; - int r; + char* s; + int r; htsbuf_queue_init(&q, 0); htsmsg_json_serialize(msg, &q, 0); s = htsbuf_to_string(&q); htsbuf_queue_flush(&q); - r = http_websocket_send(hc, (uint8_t *)s, strlen(s), HTTP_WSOP_TEXT); + r = http_websocket_send(hc, (uint8_t*)s, strlen(s), HTTP_WSOP_TEXT); free(s); return r; } @@ -1790,42 +1708,40 @@ http_websocket_send_json(http_connection_t *hc, htsmsg_t *msg) /** * */ -int -http_websocket_read(http_connection_t *hc, htsmsg_t **_res, int timeout) -{ +int http_websocket_read(http_connection_t* hc, htsmsg_t** _res, int timeout) { htsmsg_t *msg, *msg1; - uint8_t b[2], bl[8], *p; - int op, r; - uint64_t plen, pi; + uint8_t b[2], bl[8], *p; + int op, r; + uint64_t plen, pi; *_res = NULL; again: r = tcp_read_timeout(hc->hc_fd, b, 2, timeout); if (r == ETIMEDOUT) return 0; - if (r) /* closed connection */ + if (r) /* closed connection */ return -1; if ((b[1] & 0x80) == 0) /* accept only masked messages */ return -1; - switch (b[0] & 0x0f) { /* opcode */ - case 0x0: /* continuation */ - goto again; - case 0x1: /* text */ - op = HTTP_WSOP_TEXT; - break; - case 0x2: /* binary */ - op = HTTP_WSOP_BINARY; - break; - case 0x8: /* close connection */ - return -1; - case 0x9: /* ping */ - op = HTTP_WSOP_PING; - break; - case 0xa: /* pong */ - op = HTTP_WSOP_PONG; - break; - default: - return -1; + switch (b[0] & 0x0f) { /* opcode */ + case 0x0: /* continuation */ + goto again; + case 0x1: /* text */ + op = HTTP_WSOP_TEXT; + break; + case 0x2: /* binary */ + op = HTTP_WSOP_BINARY; + break; + case 0x8: /* close connection */ + return -1; + case 0x9: /* ping */ + op = HTTP_WSOP_PING; + break; + case 0xa: /* pong */ + op = HTTP_WSOP_PONG; + break; + default: + return -1; } plen = b[1] & 0x7f; if (plen == 126) { @@ -1835,12 +1751,11 @@ again: } else if (plen == 127) { if (tcp_read(hc->hc_fd, bl, 8)) return -1; - plen = ((uint64_t)bl[0] << 56) | ((uint64_t)bl[1] << 48) | - ((uint64_t)bl[2] << 40) | ((uint64_t)bl[3] << 32) | - ((uint64_t)bl[4] << 24) | ((uint64_t)bl[5] << 16) | - ((uint64_t)bl[6] << 8 ) | ((uint64_t)bl[7] << 0); + plen = ((uint64_t)bl[0] << 56) | ((uint64_t)bl[1] << 48) | ((uint64_t)bl[2] << 40) | + ((uint64_t)bl[3] << 32) | ((uint64_t)bl[4] << 24) | ((uint64_t)bl[5] << 16) | + ((uint64_t)bl[6] << 8) | ((uint64_t)bl[7] << 0); } - if (plen > 5*1024*1024) + if (plen > 5 * 1024 * 1024) return -1; p = malloc(plen + 1); if (p == NULL) @@ -1861,13 +1776,12 @@ again: htsmsg_add_s32(msg, "op", op); if (op == HTTP_WSOP_TEXT) { p[plen] = '\0'; - msg1 = p[0] == '{' || p[0] == '[' ? - htsmsg_json_deserialize((char *)p) : NULL; + msg1 = p[0] == '{' || p[0] == '[' ? htsmsg_json_deserialize((char*)p) : NULL; if (msg1) { htsmsg_add_msg(msg, "json", msg1); free(p); } else { - htsmsg_add_str_alloc(msg, "text", (char *)p); + htsmsg_add_str_alloc(msg, "text", (char*)p); } } else { htsmsg_add_bin_alloc(msg, "bin", p, plen); @@ -1882,26 +1796,24 @@ err1: /** * Parse arguments of a HTTP GET url, not perfect, but works for us */ -void -http_parse_args(http_arg_list_t *list, char *args) -{ +void http_parse_args(http_arg_list_t* list, char* args) { char *k, *v; if (args && *args == '&') args++; - while(args) { + while (args) { k = args; - if((args = strchr(args, '=')) != NULL) { + if ((args = strchr(args, '=')) != NULL) { *args++ = 0; } else { args = k; } - v = args; + v = args; args = strchr(args, '&'); - if(args != NULL) + if (args != NULL) *args++ = 0; - else if(v == k) { + else if (v == k) { if (*k == '\0') break; v = NULL; @@ -1918,12 +1830,10 @@ http_parse_args(http_arg_list_t *list, char *args) /** * */ -void -http_serve_requests(http_connection_t *hc) -{ +void http_serve_requests(http_connection_t* hc) { htsbuf_queue_t spill; - char *argv[3], *c, *s, *cmdline = NULL, *hdrline = NULL; - int n, r, delim; + char * argv[3], *c, *s, *cmdline = NULL, *hdrline = NULL; + int n, r, delim; tvh_mutex_init(&hc->hc_extra_lock, NULL); http_arg_init(&hc->hc_args); @@ -1935,9 +1845,10 @@ http_serve_requests(http_connection_t *hc) atomic_set(&hc->hc_extra_chunks, 0); do { - hc->hc_no_output = 0; + hc->hc_no_output = 0; - if (cmdline) free(cmdline); + if (cmdline) + free(cmdline); if ((cmdline = tcp_read_line(hc->hc_fd, &spill)) == NULL) goto error; @@ -1949,11 +1860,11 @@ http_serve_requests(http_connection_t *hc) tvhtrace(hc->hc_subsys, "[PROXY] PROXY protocol detected! cmdline='%s'", cmdline); argv[0] = cmdline; - s = cmdline + 6; + s = cmdline + 6; if ((cmdline = tcp_read_line(hc->hc_fd, &spill)) == NULL) - goto error; /* No more data after the PROXY protocol */ - + goto error; /* No more data after the PROXY protocol */ + delim = '.'; if (strncmp(s, "TCP6 ", 5) == 0) { delim = ':'; @@ -1965,20 +1876,26 @@ http_serve_requests(http_connection_t *hc) /* Check the SRC-ADDRESS */ for (c = s; *c != ' '; c++) { - if (*c == '\0') goto error; /* Incomplete PROXY format */ + if (*c == '\0') + goto error; /* Incomplete PROXY format */ if (*c != delim && (*c < '0' || *c > '9')) { if (delim == ':') { - if (*c >= 'a' && *c <= 'f') continue; - if (*c >= 'A' && *c <= 'F') continue; + if (*c >= 'a' && *c <= 'f') + continue; + if (*c >= 'A' && *c <= 'F') + continue; } - goto error; /* Not valid IP address */ + goto error; /* Not valid IP address */ } } - if (*c != ' ') goto error; + if (*c != ' ') + goto error; /* Check length */ - if ((c-s) < 7) goto error; - if ((c-s) > (delim == ':' ? 45 : 15)) goto error; - + if ((c - s) < 7) + goto error; + if ((c - s) > (delim == ':' ? 45 : 15)) + goto error; + /* Add null terminator */ *c = '\0'; @@ -1989,35 +1906,36 @@ http_serve_requests(http_connection_t *hc) free(argv[0]); } - if((n = http_tokenize(cmdline, argv, 3, -1)) != 3) + if ((n = http_tokenize(cmdline, argv, 3, -1)) != 3) goto error; - - if((hc->hc_cmd = str2val(argv[0], HTTP_cmdtab)) == -1) + + if ((hc->hc_cmd = str2val(argv[0], HTTP_cmdtab)) == -1) goto error; hc->hc_url = argv[1]; - if((hc->hc_version = str2val(argv[2], HTTP_versiontab)) == -1) + if ((hc->hc_version = str2val(argv[2], HTTP_versiontab)) == -1) goto error; /* parse header */ - while(1) { - if (hdrline) free(hdrline); + while (1) { + if (hdrline) + free(hdrline); if ((hdrline = tcp_read_line(hc->hc_fd, &spill)) == NULL) goto error; - if(!*hdrline) + if (!*hdrline) break; /* header complete */ - if((n = http_tokenize(hdrline, argv, 2, -1)) < 2) { + if ((n = http_tokenize(hdrline, argv, 2, -1)) < 2) { if ((c = strchr(hdrline, ':')) != NULL) { - *c = '\0'; + *c = '\0'; argv[0] = hdrline; argv[1] = c + 1; } else { continue; } - } else if((c = strrchr(argv[0], ':')) == NULL) + } else if ((c = strrchr(argv[0], ':')) == NULL) goto error; *c = 0; @@ -2037,7 +1955,7 @@ http_serve_requests(http_connection_t *hc) if (r) break; - } while(hc->hc_keep_alive && atomic_get(&http_server_running)); + } while (hc->hc_keep_alive && atomic_get(&http_server_running)); error: free(hdrline); @@ -2052,14 +1970,11 @@ error: free(hc->hc_local_ip); } - /** * */ static void -http_serve(int fd, void **opaque, struct sockaddr_storage *peer, - struct sockaddr_storage *self) -{ +http_serve(int fd, void** opaque, struct sockaddr_storage* peer, struct sockaddr_storage* self) { http_connection_t hc; /* Note: global_lock held on entry */ @@ -2067,13 +1982,13 @@ http_serve(int fd, void **opaque, struct sockaddr_storage *peer, memset(&hc, 0, sizeof(http_connection_t)); *opaque = &hc; - hc.hc_subsys = LS_HTTP; - hc.hc_fd = fd; - hc.hc_peer = peer; - hc.hc_self = self; - hc.hc_paths = &http_paths; + hc.hc_subsys = LS_HTTP; + hc.hc_fd = fd; + hc.hc_peer = peer; + hc.hc_self = self; + hc.hc_paths = &http_paths; hc.hc_paths_mutex = &http_paths_mutex; - hc.hc_process = http_process_request; + hc.hc_process = http_process_request; http_serve_requests(&hc); @@ -2084,10 +1999,8 @@ http_serve(int fd, void **opaque, struct sockaddr_storage *peer, *opaque = NULL; } -void -http_cancel( void *opaque ) -{ - http_connection_t *hc = opaque; +void http_cancel(void* opaque) { + http_connection_t* hc = opaque; if (hc) { shutdown(hc->hc_fd, SHUT_RDWR); @@ -2098,14 +2011,8 @@ http_cancel( void *opaque ) /** * Fire up HTTP server */ -void -http_server_init(const char *bindaddr) -{ - static tcp_server_ops_t ops = { - .start = http_serve, - .stop = NULL, - .cancel = http_cancel - }; +void http_server_init(const char* bindaddr) { + static tcp_server_ops_t ops = {.start = http_serve, .stop = NULL, .cancel = http_cancel}; RB_INIT(&http_nonces); if (tvheadend_webui_port > 0) { http_server = tcp_server_create(LS_HTTP, "HTTP", bindaddr, tvheadend_webui_port, &ops, NULL); @@ -2113,17 +2020,13 @@ http_server_init(const char *bindaddr) } } -void -http_server_register(void) -{ +void http_server_register(void) { tcp_server_register(http_server); } -void -http_server_done(void) -{ - http_path_t *hp; - http_nonce_t *n; +void http_server_done(void) { + http_path_t* hp; + http_nonce_t* n; tvh_mutex_lock(&global_lock); atomic_set(&http_server_running, 0); @@ -2133,7 +2036,7 @@ http_server_done(void) tvh_mutex_lock(&http_paths_mutex); while ((hp = LIST_FIRST(&http_paths)) != NULL) { LIST_REMOVE(hp, hp_link); - free((void *)hp->hp_path); + free((void*)hp->hp_path); free(hp); } tvh_mutex_unlock(&http_paths_mutex); diff --git a/src/http.h b/src/http.h index 338c514a8..3ff67841c 100644 --- a/src/http.h +++ b/src/http.h @@ -33,13 +33,13 @@ typedef LIST_HEAD(, http_path) http_path_list_t; typedef TAILQ_HEAD(http_arg_list, http_arg) http_arg_list_t; -typedef RB_HEAD(,http_arg) http_arg_tree_t; +typedef RB_HEAD(, http_arg) http_arg_tree_t; typedef struct http_arg { RB_ENTRY(http_arg) rb_link; TAILQ_ENTRY(http_arg) link; - char *key; - char *val; + char* key; + char* val; } http_arg_t; #define HTTP_STATUS_CONTINUE 100 @@ -88,13 +88,13 @@ typedef struct http_arg { #define HTTP_STATUS_HTTP_VERSION 505 #define HTTP_STATUS_OP_NOT_SUPPRT 551 -#define HTTP_AUTH_PLAIN 0 -#define HTTP_AUTH_DIGEST 1 -#define HTTP_AUTH_PLAIN_DIGEST 2 +#define HTTP_AUTH_PLAIN 0 +#define HTTP_AUTH_DIGEST 1 +#define HTTP_AUTH_PLAIN_DIGEST 2 -#define HTTP_AUTH_ALGO_MD5 0 -#define HTTP_AUTH_ALGO_SHA256 1 -#define HTTP_AUTH_ALGO_SHA512_256 2 +#define HTTP_AUTH_ALGO_MD5 0 +#define HTTP_AUTH_ALGO_SHA256 1 +#define HTTP_AUTH_ALGO_SHA512_256 2 typedef enum http_state { HTTP_CON_WAIT_REQUEST, @@ -132,49 +132,49 @@ typedef enum http_ver { } http_ver_t; typedef enum http_wsop { - HTTP_WSOP_TEXT = 0, + HTTP_WSOP_TEXT = 0, HTTP_WSOP_BINARY = 1, - HTTP_WSOP_PING = 2, - HTTP_WSOP_PONG = 3 + HTTP_WSOP_PING = 2, + HTTP_WSOP_PONG = 3 } http_wsop_t; typedef struct http_connection { - int hc_subsys; - int hc_fd; - struct sockaddr_storage *hc_peer; - char *hc_peer_ipstr; - struct sockaddr_storage *hc_self; - char *hc_representative; - struct sockaddr_storage *hc_proxy_ip; - struct sockaddr_storage *hc_local_ip; + int hc_subsys; + int hc_fd; + struct sockaddr_storage* hc_peer; + char* hc_peer_ipstr; + struct sockaddr_storage* hc_self; + char* hc_representative; + struct sockaddr_storage* hc_proxy_ip; + struct sockaddr_storage* hc_local_ip; - tvh_mutex_t *hc_paths_mutex; - http_path_list_t *hc_paths; - int (*hc_process)(struct http_connection *hc, htsbuf_queue_t *spill); + tvh_mutex_t* hc_paths_mutex; + http_path_list_t* hc_paths; + int (*hc_process)(struct http_connection* hc, htsbuf_queue_t* spill); - char *hc_url; - char *hc_url_orig; + char* hc_url; + char* hc_url_orig; - htsbuf_queue_t hc_reply; + htsbuf_queue_t hc_reply; - int hc_extra_insend; - tvh_mutex_t hc_extra_lock; - int hc_extra_chunks; - htsbuf_queue_t hc_extra; + int hc_extra_insend; + tvh_mutex_t hc_extra_lock; + int hc_extra_chunks; + htsbuf_queue_t hc_extra; http_arg_list_t hc_args; http_arg_list_t hc_req_args; /* Argumets from GET or POST request */ - http_state_t hc_state; - http_cmd_t hc_cmd; - http_ver_t hc_version; + http_state_t hc_state; + http_cmd_t hc_cmd; + http_ver_t hc_version; - char *hc_username; - char *hc_password; - char *hc_authhdr; - char *hc_nonce; - access_t *hc_access; + char* hc_username; + char* hc_password; + char* hc_authhdr; + char* hc_nonce; + access_t* hc_access; enum { HC_AUTH_NONE, HC_AUTH_ADDR, @@ -186,151 +186,157 @@ typedef struct http_connection { /* RTSP */ uint64_t hc_cseq; - char *hc_session; + char* hc_session; /* Flags */ uint8_t hc_keep_alive; uint8_t hc_no_output; uint8_t hc_shutdown; - uint8_t hc_is_local_ip; /*< a connection from the local network */ + uint8_t hc_is_local_ip; /*< a connection from the local network */ /* Support for HTTP POST */ - - char *hc_post_data; + + char* hc_post_data; unsigned int hc_post_len; } http_connection_t; -extern void *http_server; +extern void* http_server; -const char *http_cmd2str(int val); -int http_str2cmd(const char *str); -const char *http_ver2str(int val); -int http_str2ver(const char *str); +const char* http_cmd2str(int val); +int http_str2cmd(const char* str); +const char* http_ver2str(int val); +int http_str2ver(const char* str); -static inline void http_arg_init(http_arg_list_t *list) -{ +static inline void http_arg_init(http_arg_list_t* list) { TAILQ_INIT(list); } -void http_arg_remove(http_arg_list_t *list, struct http_arg *arg); -void http_arg_flush(http_arg_list_t *list); +void http_arg_remove(http_arg_list_t* list, struct http_arg* arg); +void http_arg_flush(http_arg_list_t* list); -char *http_arg_get(http_arg_list_t *list, const char *name); -char *http_arg_get_remove(http_arg_list_t *list, const char *name); +char* http_arg_get(http_arg_list_t* list, const char* name); +char* http_arg_get_remove(http_arg_list_t* list, const char* name); -void http_arg_set(http_arg_list_t *list, const char *key, const char *val); +void http_arg_set(http_arg_list_t* list, const char* key, const char* val); -char *http_arg_get_query(http_arg_list_t *list); +char* http_arg_get_query(http_arg_list_t* list); -static inline int http_args_empty(const http_arg_list_t *list) { return TAILQ_EMPTY(list); } +static inline int http_args_empty(const http_arg_list_t* list) { + return TAILQ_EMPTY(list); +} -int http_tokenize(char *buf, char **vec, int vecsize, int delimiter); +int http_tokenize(char* buf, char** vec, int vecsize, int delimiter); -const char * http_username(http_connection_t *hc); +const char* http_username(http_connection_t* hc); -int http_noaccess_code(http_connection_t *hc); +int http_noaccess_code(http_connection_t* hc); -void http_alive(http_connection_t *hc); +void http_alive(http_connection_t* hc); -void http_error(http_connection_t *hc, int error); +void http_error(http_connection_t* hc, int error); -int http_encoding_valid(http_connection_t *hc, const char *encoding); +int http_encoding_valid(http_connection_t* hc, const char* encoding); -int http_header_match(http_connection_t *hc, const char *name, const char *value); +int http_header_match(http_connection_t* hc, const char* name, const char* value); -void http_output_html(http_connection_t *hc); +void http_output_html(http_connection_t* hc); -void http_output_content(http_connection_t *hc, const char *content); +void http_output_content(http_connection_t* hc, const char* content); -void http_redirect(http_connection_t *hc, const char *location, - struct http_arg_list *req_args, int external); +void http_redirect(http_connection_t* hc, + const char* location, + struct http_arg_list* req_args, + int external); -void http_css_import(http_connection_t *hc, const char *location); +void http_css_import(http_connection_t* hc, const char* location); -void http_extra_destroy(http_connection_t *hc); +void http_extra_destroy(http_connection_t* hc); -int http_extra_flush(http_connection_t *hc); +int http_extra_flush(http_connection_t* hc); -int http_extra_flush_partial(http_connection_t *hc); +int http_extra_flush_partial(http_connection_t* hc); -int http_extra_send(http_connection_t *hc, const void *data, - size_t data_len, int may_discard); +int http_extra_send(http_connection_t* hc, const void* data, size_t data_len, int may_discard); -int http_extra_send_prealloc(http_connection_t *hc, const void *data, - size_t data_len, int may_discard); +int http_extra_send_prealloc(http_connection_t* hc, + const void* data, + size_t data_len, + int may_discard); -static inline void http_send_begin(http_connection_t *hc) -{ +static inline void http_send_begin(http_connection_t* hc) { atomic_add(&hc->hc_extra_insend, 1); if (atomic_get(&hc->hc_extra_chunks) > 0) http_extra_flush_partial(hc); } -static inline void http_send_end(http_connection_t *hc) -{ +static inline void http_send_end(http_connection_t* hc) { atomic_dec(&hc->hc_extra_insend, 1); if (atomic_get(&hc->hc_extra_chunks) > 0) http_extra_flush(hc); } -void http_send_header(http_connection_t *hc, int rc, const char *content, - int64_t contentlen, const char *encoding, - const char *location, int maxage, const char *range, - const char *disposition, http_arg_list_t *args); +void http_send_header(http_connection_t* hc, + int rc, + const char* content, + int64_t contentlen, + const char* encoding, + const char* location, + int maxage, + const char* range, + const char* disposition, + http_arg_list_t* args); + +int http_send_header_websocket(http_connection_t* hc, const char* protocol); -int http_send_header_websocket(http_connection_t *hc, const char *protocol); +int http_websocket_send(http_connection_t* hc, uint8_t* buf, uint64_t buflen, int opcode); -int http_websocket_send(http_connection_t *hc, uint8_t *buf, uint64_t buflen, int opcode); +int http_websocket_send_json(http_connection_t* hc, htsmsg_t* msg); -int http_websocket_send_json(http_connection_t *hc, htsmsg_t *msg); +int http_websocket_read(http_connection_t* hc, htsmsg_t** _res, int timeout); -int http_websocket_read(http_connection_t *hc, htsmsg_t **_res, int timeout); +void http_serve_requests(http_connection_t* hc); -void http_serve_requests(http_connection_t *hc); +void http_cancel(void* opaque); -void http_cancel(void *opaque); +int http_check_local_ip(http_connection_t* hc); -int http_check_local_ip(http_connection_t *hc); +typedef int(http_callback_t)(http_connection_t* hc, const char* remain, void* opaque); -typedef int (http_callback_t)(http_connection_t *hc, - const char *remain, void *opaque); +typedef char*(http_path_modify_t)(http_connection_t* hc, const char* path, int* cut); -typedef char * (http_path_modify_t)(http_connection_t *hc, - const char * path, int *cut); - -#define HTTP_PATH_NO_VERIFICATION (1 << 0) -#define HTTP_PATH_WEBSOCKET (1 << 1) +#define HTTP_PATH_NO_VERIFICATION (1 << 0) +#define HTTP_PATH_WEBSOCKET (1 << 1) typedef struct http_path { LIST_ENTRY(http_path) hp_link; - const char *hp_path; - void *hp_opaque; - http_callback_t *hp_callback; - int hp_len; - uint32_t hp_flags; - uint32_t hp_accessmask; - http_path_modify_t *hp_path_modify; + const char* hp_path; + void* hp_opaque; + http_callback_t* hp_callback; + int hp_len; + uint32_t hp_flags; + uint32_t hp_accessmask; + http_path_modify_t* hp_path_modify; } http_path_t; -http_path_t *http_path_add_modify(const char *path, void *opaque, - http_callback_t *callback, - uint32_t accessmask, - http_path_modify_t path_modify); -http_path_t *http_path_add(const char *path, void *opaque, - http_callback_t *callback, uint32_t accessmask); +http_path_t* http_path_add_modify(const char* path, + void* opaque, + http_callback_t* callback, + uint32_t accessmask, + http_path_modify_t path_modify); +http_path_t* +http_path_add(const char* path, void* opaque, http_callback_t* callback, uint32_t accessmask); -void http_server_init(const char *bindaddr); +void http_server_init(const char* bindaddr); void http_server_register(void); void http_server_done(void); -int http_access_verify(http_connection_t *hc, int mask); -int http_access_verify_channel(http_connection_t *hc, int mask, - struct channel *ch); +int http_access_verify(http_connection_t* hc, int mask); +int http_access_verify_channel(http_connection_t* hc, int mask, struct channel* ch); -void http_parse_args(http_arg_list_t *list, char *args); +void http_parse_args(http_arg_list_t* list, char* args); -char *http_get_hostpath(http_connection_t *hc, char *buf, size_t buflen); +char* http_get_hostpath(http_connection_t* hc, char* buf, size_t buflen); /* * HTTP/RTSP Client @@ -345,193 +351,206 @@ typedef struct http_client_wcmd { enum http_cmd wcmd; int wcseq; - void *wbuf; - size_t wpos; - size_t wsize; + void* wbuf; + size_t wpos; + size_t wsize; } http_client_wcmd_t; struct http_client { TAILQ_ENTRY(http_client) hc_link; - tvh_mutex_t hc_mutex; + tvh_mutex_t hc_mutex; - int hc_id; - int hc_fd; - char *hc_scheme; - char *hc_host; - int hc_port; - char *hc_bindaddr; - tvhpoll_t *hc_efd; - int hc_pevents; - int hc_pevents_pause; + int hc_id; + int hc_fd; + char* hc_scheme; + char* hc_host; + int hc_port; + char* hc_bindaddr; + tvhpoll_t* hc_efd; + int hc_pevents; + int hc_pevents_pause; - int hc_code; - http_ver_t hc_version; - http_ver_t hc_redirv; - http_cmd_t hc_cmd; + int hc_code; + http_ver_t hc_version; + http_ver_t hc_redirv; + http_cmd_t hc_cmd; struct http_arg_list hc_args; /* header */ - char *hc_url; + char* hc_url; - void *hc_aux; - size_t hc_data_limit; - size_t hc_io_size; - char *hc_data; /* data body */ - size_t hc_data_size; /* data body size - result for caller */ + void* hc_aux; + size_t hc_data_limit; + size_t hc_io_size; + char* hc_data; /* data body */ + size_t hc_data_size; /* data body size - result for caller */ - int64_t hc_ping_time; /* last issued command */ + int64_t hc_ping_time; /* last issued command */ - char *hc_rbuf; /* read buffer */ - size_t hc_rsize; /* read buffer size */ - size_t hc_rpos; /* read buffer position */ - size_t hc_hsize; /* header size in bytes */ - size_t hc_csize; /* contents size in bytes */ - char *hc_chunk; + char* hc_rbuf; /* read buffer */ + size_t hc_rsize; /* read buffer size */ + size_t hc_rpos; /* read buffer position */ + size_t hc_hsize; /* header size in bytes */ + size_t hc_csize; /* contents size in bytes */ + char* hc_chunk; size_t hc_chunk_size; size_t hc_chunk_csize; size_t hc_chunk_alloc; size_t hc_chunk_pos; - char *hc_location; - uint8_t hc_running; /* outside hc_mutex */ - uint8_t hc_shutdown_wait;/* outside hc_mutex */ - int hc_refcnt; /* callback protection - outside hc_mutex */ + char* hc_location; + uint8_t hc_running; /* outside hc_mutex */ + uint8_t hc_shutdown_wait; /* outside hc_mutex */ + int hc_refcnt; /* callback protection - outside hc_mutex */ int hc_redirects; int hc_result; - unsigned int hc_shutdown:1; - unsigned int hc_sending:1; - unsigned int hc_einprogress:1; - unsigned int hc_reconnected:1; - unsigned int hc_keepalive:1; - unsigned int hc_in_data:1; - unsigned int hc_in_rtp_data:1; - unsigned int hc_chunked:1; - unsigned int hc_chunk_trails:1; - unsigned int hc_handle_location:1; /* handle the redirection (location) requests */ - unsigned int hc_pause:1; - - http_client_wcmd_t *hc_wcmd; - TAILQ_HEAD(,http_client_wcmd) hc_wqueue; - - int hc_verify_peer; /* SSL - verify peer */ - - int hc_cseq; /* RTSP */ - int hc_rcseq; /* RTSP - expected cseq */ - char *hc_rtsp_session; - char *hc_rtp_dest; + unsigned int hc_shutdown : 1; + unsigned int hc_sending : 1; + unsigned int hc_einprogress : 1; + unsigned int hc_reconnected : 1; + unsigned int hc_keepalive : 1; + unsigned int hc_in_data : 1; + unsigned int hc_in_rtp_data : 1; + unsigned int hc_chunked : 1; + unsigned int hc_chunk_trails : 1; + unsigned int hc_handle_location : 1; /* handle the redirection (location) requests */ + unsigned int hc_pause : 1; + + http_client_wcmd_t* hc_wcmd; + TAILQ_HEAD(, http_client_wcmd) hc_wqueue; + + int hc_verify_peer; /* SSL - verify peer */ + + int hc_cseq; /* RTSP */ + int hc_rcseq; /* RTSP - expected cseq */ + char* hc_rtsp_session; + char* hc_rtp_dest; int hc_rtp_port; int hc_rtcp_port; int hc_rtp_tcp; int hc_rtcp_tcp; int hc_rtcp_server_port; - unsigned int hc_rtp_multicast:1; - unsigned int hc_rtp_avpf:1; + unsigned int hc_rtp_multicast : 1; + unsigned int hc_rtp_avpf : 1; long hc_rtsp_stream_id; int hc_rtp_timeout; - char *hc_rtsp_user; - char *hc_rtsp_pass; + char* hc_rtsp_user; + char* hc_rtsp_pass; char hc_rtsp_keep_alive_cmd; time_t hc_rtsp_stream_start; time_t hc_rtsp_range_start; time_t hc_rtsp_range_end; float hc_rtsp_scale; - struct http_client_ssl *hc_ssl; /* ssl internals */ + struct http_client_ssl* hc_ssl; /* ssl internals */ - mtimer_t hc_close_timer; + mtimer_t hc_close_timer; /* callbacks */ - void (*hc_hdr_create) (http_client_t *hc, http_arg_list_t *h, - const url_t *url, int keepalive); - int (*hc_hdr_received) (http_client_t *hc); - int (*hc_data_received)(http_client_t *hc, void *buf, size_t len); - int (*hc_data_complete)(http_client_t *hc); - int (*hc_rtp_data_received)(http_client_t *hc, void *buf, size_t len); - int (*hc_rtp_data_complete)(http_client_t *hc); - void (*hc_conn_closed) (http_client_t *hc, int err); + void (*hc_hdr_create)(http_client_t* hc, http_arg_list_t* h, const url_t* url, int keepalive); + int (*hc_hdr_received)(http_client_t* hc); + int (*hc_data_received)(http_client_t* hc, void* buf, size_t len); + int (*hc_data_complete)(http_client_t* hc); + int (*hc_rtp_data_received)(http_client_t* hc, void* buf, size_t len); + int (*hc_rtp_data_complete)(http_client_t* hc); + void (*hc_conn_closed)(http_client_t* hc, int err); }; -void http_client_init ( void ); -void http_client_done ( void ); - -const char * http_client_con2str(http_state_t state); - -http_client_t* -http_client_connect ( void *aux, http_ver_t ver, const char *scheme, - const char *host, int port, const char *bindaddr ); -void http_client_register ( http_client_t *hc ); -void http_client_close ( http_client_t *hc ); - -int http_client_send( http_client_t *hc, http_cmd_t cmd, - const char *path, const char *query, - http_arg_list_t *header, void *body, size_t body_size ); -void http_client_basic_auth( http_client_t *hc, http_arg_list_t *h, - const char *user, const char *pass ); -void http_client_basic_args ( http_client_t *hc, http_arg_list_t *h, - const url_t *url, int keepalive ); -void http_client_add_args ( http_client_t *hc, http_arg_list_t *h, - const char *args ); -int http_client_simple_reconnect ( http_client_t *hc, const url_t *u, http_ver_t ver ); -int http_client_simple( http_client_t *hc, const url_t *url); -int http_client_clear_state( http_client_t *hc ); -int http_client_run( http_client_t *hc ); -void http_client_ssl_peer_verify( http_client_t *hc, int verify ); -void http_client_unpause( http_client_t *hc ); +void http_client_init(void); +void http_client_done(void); + +const char* http_client_con2str(http_state_t state); + +http_client_t* http_client_connect(void* aux, + http_ver_t ver, + const char* scheme, + const char* host, + int port, + const char* bindaddr); +void http_client_register(http_client_t* hc); +void http_client_close(http_client_t* hc); + +int http_client_send(http_client_t* hc, + http_cmd_t cmd, + const char* path, + const char* query, + http_arg_list_t* header, + void* body, + size_t body_size); +void http_client_basic_auth(http_client_t* hc, + http_arg_list_t* h, + const char* user, + const char* pass); +void http_client_basic_args(http_client_t* hc, http_arg_list_t* h, const url_t* url, int keepalive); +void http_client_add_args(http_client_t* hc, http_arg_list_t* h, const char* args); +int http_client_simple_reconnect(http_client_t* hc, const url_t* u, http_ver_t ver); +int http_client_simple(http_client_t* hc, const url_t* url); +int http_client_clear_state(http_client_t* hc); +int http_client_run(http_client_t* hc); +void http_client_ssl_peer_verify(http_client_t* hc, int verify); +void http_client_unpause(http_client_t* hc); /* * RTSP helpers */ -int rtsp_send_ext( http_client_t *hc, http_cmd_t cmd, const char *path, - const char *query, http_arg_list_t *hdr, const char *body, size_t size ); - -static inline int -rtsp_send( http_client_t *hc, http_cmd_t cmd, const char *path, - const char *query, http_arg_list_t *hdr ) { - return rtsp_send_ext( hc, cmd, path, query, hdr, NULL, 0 ); +int rtsp_send_ext(http_client_t* hc, + http_cmd_t cmd, + const char* path, + const char* query, + http_arg_list_t* hdr, + const char* body, + size_t size); + +static inline int rtsp_send(http_client_t* hc, + http_cmd_t cmd, + const char* path, + const char* query, + http_arg_list_t* hdr) { + return rtsp_send_ext(hc, cmd, path, query, hdr, NULL, 0); } - -void rtsp_clear_session( http_client_t *hc ); -static inline int rtsp_options( http_client_t *hc ) { +void rtsp_clear_session(http_client_t* hc); + +static inline int rtsp_options(http_client_t* hc) { return rtsp_send(hc, RTSP_CMD_OPTIONS, NULL, NULL, NULL); } -static inline int -rtsp_describe( http_client_t *hc, const char *path, const char *query ) { +static inline int rtsp_describe(http_client_t* hc, const char* path, const char* query) { return rtsp_send(hc, RTSP_CMD_DESCRIBE, path, query, NULL); } -int rtsp_setup( http_client_t *hc, const char *path, const char *query, - const char *multicast_addr, int rtp_port, int rtcp_port ); +int rtsp_setup(http_client_t* hc, + const char* path, + const char* query, + const char* multicast_addr, + int rtp_port, + int rtcp_port); -static inline int -rtsp_play( http_client_t *hc, const char *path, const char *query ) { +static inline int rtsp_play(http_client_t* hc, const char* path, const char* query) { return rtsp_send(hc, RTSP_CMD_PLAY, path, query, NULL); } -static inline int -rtsp_pause( http_client_t *hc, const char *path, const char *query ) { +static inline int rtsp_pause(http_client_t* hc, const char* path, const char* query) { return rtsp_send(hc, RTSP_CMD_PAUSE, path, query, NULL); } -static inline int -rtsp_teardown( http_client_t *hc, const char *path, const char *query ) { +static inline int rtsp_teardown(http_client_t* hc, const char* path, const char* query) { return rtsp_send(hc, RTSP_CMD_TEARDOWN, path, query, NULL); } -int rtsp_get_parameter( http_client_t *hc, const char *parameter ); +int rtsp_get_parameter(http_client_t* hc, const char* parameter); -int rtsp_set_speed( http_client_t *hc, float speed ); +int rtsp_set_speed(http_client_t* hc, float speed); -int rtsp_set_position( http_client_t *hc, time_t position ); +int rtsp_set_position(http_client_t* hc, time_t position); -int rtsp_describe_decode( http_client_t *hc, const char *buf, size_t len ); +int rtsp_describe_decode(http_client_t* hc, const char* buf, size_t len); -int rtsp_setup_decode( http_client_t *hc, int satip ); +int rtsp_setup_decode(http_client_t* hc, int satip); -int rtsp_options_decode( http_client_t *hc ); +int rtsp_options_decode(http_client_t* hc); -int rtsp_play_decode( http_client_t *hc ); +int rtsp_play_decode(http_client_t* hc); #endif /* HTTP_H_ */ diff --git a/src/httpc.c b/src/httpc.c index 26353a0be..f0f8b20e8 100644 --- a/src/httpc.c +++ b/src/httpc.c @@ -49,102 +49,86 @@ #endif struct http_client_ssl { - int connected; - int shutdown; - int notified; - - SSL_CTX *ctx; - SSL *ssl; - - BIO *rbio; - char *rbio_buf; - size_t rbio_size; - size_t rbio_pos; - - BIO *wbio; - char *wbio_buf; - size_t wbio_size; - size_t wbio_pos; + int connected; + int shutdown; + int notified; + + SSL_CTX* ctx; + SSL* ssl; + + BIO* rbio; + char* rbio_buf; + size_t rbio_size; + size_t rbio_pos; + + BIO* wbio; + char* wbio_buf; + size_t wbio_size; + size_t wbio_pos; }; -static int -http_client_redirected ( http_client_t *hc ); -static int -http_client_ssl_write_update( http_client_t *hc ); -static int -http_client_reconnect - ( http_client_t *hc, http_ver_t ver, const char *scheme, - const char *host, int port ); +static int http_client_redirected(http_client_t* hc); +static int http_client_ssl_write_update(http_client_t* hc); +static int http_client_reconnect(http_client_t* hc, + http_ver_t ver, + const char* scheme, + const char* host, + int port); #if HTTPCLIENT_TESTSUITE -static void -http_client_testsuite_run( void ); +static void http_client_testsuite_run(void); #endif /* * Global state */ -static int http_running; -static tvhpoll_t *http_poll; -static TAILQ_HEAD(,http_client) http_clients; -static tvh_mutex_t http_lock; -static tvh_cond_t http_cond; -static th_pipe_t http_pipe; +static int http_running; +static tvhpoll_t* http_poll; +static TAILQ_HEAD(, http_client) http_clients; +static tvh_mutex_t http_lock; +static tvh_cond_t http_cond; +static th_pipe_t http_pipe; /* * */ -static inline int -shortid( http_client_t *hc ) -{ +static inline int shortid(http_client_t* hc) { return hc->hc_id; } /* * */ -static void -http_client_get( http_client_t *hc ) -{ +static void http_client_get(http_client_t* hc) { hc->hc_refcnt++; } -static void -http_client_put( http_client_t *hc ) -{ +static void http_client_put(http_client_t* hc) { hc->hc_refcnt--; } -static int -http_client_busy( http_client_t *hc ) -{ +static int http_client_busy(http_client_t* hc) { return !!hc->hc_refcnt; } -static struct strtab HTTP_statetab[] = { - { "WAIT_REQUEST", HTTP_CON_WAIT_REQUEST }, - { "READ_HEADER", HTTP_CON_READ_HEADER }, - { "END", HTTP_CON_END }, - { "POST_DATA", HTTP_CON_POST_DATA }, - { "SENDING", HTTP_CON_SENDING }, - { "SENT", HTTP_CON_SENT }, - { "RECEIVING", HTTP_CON_RECEIVING }, - { "DONE", HTTP_CON_DONE }, - { "IDLE", HTTP_CON_IDLE }, - { "OK", HTTP_CON_OK } -}; - -const char * -http_client_con2str(http_state_t val) -{ +static struct strtab HTTP_statetab[] = {{"WAIT_REQUEST", HTTP_CON_WAIT_REQUEST}, + {"READ_HEADER", HTTP_CON_READ_HEADER}, + {"END", HTTP_CON_END}, + {"POST_DATA", HTTP_CON_POST_DATA}, + {"SENDING", HTTP_CON_SENDING}, + {"SENT", HTTP_CON_SENT}, + {"RECEIVING", HTTP_CON_RECEIVING}, + {"DONE", HTTP_CON_DONE}, + {"IDLE", HTTP_CON_IDLE}, + {"OK", HTTP_CON_OK}}; + +const char* http_client_con2str(http_state_t val) { return val2str(val, HTTP_statetab); } /* * */ -static int -http_port( http_client_t *hc, const char *scheme, int port ) -{ +static int http_port(http_client_t* hc, const char* scheme, int port) { if (port <= 0 || port > 65535) { if (scheme && strcmp(scheme, "http") == 0) port = 80; @@ -163,10 +147,8 @@ http_port( http_client_t *hc, const char *scheme, int port ) /* * Disable */ -static void -http_client_shutdown ( http_client_t *hc, int force, int reconnect ) -{ - struct http_client_ssl *ssl = hc->hc_ssl; +static void http_client_shutdown(http_client_t* hc, int force, int reconnect) { + struct http_client_ssl* ssl = hc->hc_ssl; tvhtrace(LS_HTTPC, "%04X: shutdown", shortid(hc)); hc->hc_shutdown = 1; @@ -187,7 +169,7 @@ http_client_shutdown ( http_client_t *hc, int force, int reconnect ) hc->hc_efd = NULL; tvh_mutex_unlock(&http_lock); } else { - hc->hc_efd = NULL; + hc->hc_efd = NULL; } } if (hc->hc_fd >= 0) { @@ -207,9 +189,7 @@ http_client_shutdown ( http_client_t *hc, int force, int reconnect ) /* * Poll I/O */ -static void -http_client_poll_dir ( http_client_t *hc, int in, int out ) -{ +static void http_client_poll_dir(http_client_t* hc, int in, int out) { int events = (in ? TVHPOLL_IN : 0) | (out ? TVHPOLL_OUT : 0); if (hc->hc_efd) { if (events == 0 && hc->hc_pause) { @@ -218,7 +198,11 @@ http_client_poll_dir ( http_client_t *hc, int in, int out ) hc->hc_pevents_pause = hc->hc_pevents; tvhpoll_rem1(hc->hc_efd, hc->hc_fd); } else if (hc->hc_pevents != events) { - tvhtrace(LS_HTTPC, "%04X: add poll for input%s (%x)", shortid(hc), out ? " and output" : "", events); + tvhtrace(LS_HTTPC, + "%04X: add poll for input%s (%x)", + shortid(hc), + out ? " and output" : "", + events); tvhpoll_add1(hc->hc_efd, hc->hc_fd, events | TVHPOLL_IN, hc); } } @@ -227,22 +211,17 @@ http_client_poll_dir ( http_client_t *hc, int in, int out ) errno = EAGAIN; } -void -http_client_unpause( http_client_t *hc ) -{ +void http_client_unpause(http_client_t* hc) { if (hc->hc_pause) { int pevents_pause = hc->hc_pevents_pause; tvhtrace(LS_HTTPC, "%04X: resuming input", shortid(hc)); - hc->hc_pause = 0; + hc->hc_pause = 0; hc->hc_pevents_pause = 0; - http_client_poll_dir(hc, pevents_pause & TVHPOLL_IN, - pevents_pause & TVHPOLL_OUT); + http_client_poll_dir(hc, pevents_pause & TVHPOLL_IN, pevents_pause & TVHPOLL_OUT); } } -static void -http_client_direction ( http_client_t *hc, int sending ) -{ +static void http_client_direction(http_client_t* hc, int sending) { hc->hc_sending = sending; if (hc->hc_ssl == NULL) http_client_poll_dir(hc, 1, sending); @@ -252,35 +231,29 @@ http_client_direction ( http_client_t *hc, int sending ) * Main I/O routines */ -static inline void -http_client_rbuf_cut( http_client_t *hc, size_t cut ) -{ +static inline void http_client_rbuf_cut(http_client_t* hc, size_t cut) { size_t len = hc->hc_rpos - cut; memmove(hc->hc_rbuf, hc->hc_rbuf + cut, len); hc->hc_rpos = len; } -static void -http_client_cmd_destroy( http_client_t *hc, http_client_wcmd_t *cmd ) -{ +static void http_client_cmd_destroy(http_client_t* hc, http_client_wcmd_t* cmd) { TAILQ_REMOVE(&hc->hc_wqueue, cmd, link); free(cmd->wbuf); free(cmd); } -static int -http_client_flush( http_client_t *hc, int result ) -{ - hc->hc_result = result; +static int http_client_flush(http_client_t* hc, int result) { + hc->hc_result = result; tvhtrace(LS_HTTPC, "%04X: client flush %i", shortid(hc), result); if (result < 0) http_client_shutdown(hc, 0, 0); - hc->hc_in_data = 0; - hc->hc_in_rtp_data = 0; - hc->hc_hsize = 0; - hc->hc_csize = 0; - hc->hc_rpos = 0; - hc->hc_chunked = 0; + hc->hc_in_data = 0; + hc->hc_in_rtp_data = 0; + hc->hc_hsize = 0; + hc->hc_csize = 0; + hc->hc_rpos = 0; + hc->hc_chunked = 0; free(hc->hc_chunk); hc->hc_chunk = 0; hc->hc_chunk_pos = 0; @@ -292,23 +265,19 @@ http_client_flush( http_client_t *hc, int result ) return result; } -int -http_client_clear_state( http_client_t *hc ) -{ +int http_client_clear_state(http_client_t* hc) { if (hc->hc_shutdown) return -EBADF; free(hc->hc_data); - hc->hc_data = NULL; + hc->hc_data = NULL; hc->hc_data_size = 0; return http_client_flush(hc, 0); } -static int -http_client_einprogress( http_client_t *hc ) -{ +static int http_client_einprogress(http_client_t* hc) { struct pollfd fds; fds.fd = hc->hc_fd; - fds.events = POLLOUT|POLLNVAL|POLLERR; + fds.events = POLLOUT | POLLNVAL | POLLERR; fds.revents = 0; if (poll(&fds, 1, 0) == 0) { http_client_poll_dir(hc, 0, 1); @@ -318,13 +287,11 @@ http_client_einprogress( http_client_t *hc ) return 0; } -static int -http_client_ssl_read_update( http_client_t *hc ) -{ - struct http_client_ssl *ssl = hc->hc_ssl; - char *rbuf = alloca(hc->hc_io_size); - ssize_t r, r2; - size_t len; +static int http_client_ssl_read_update(http_client_t* hc) { + struct http_client_ssl* ssl = hc->hc_ssl; + char* rbuf = alloca(hc->hc_io_size); + ssize_t r, r2; + size_t len; if (ssl->rbio_pos > 0) { r = BIO_write(ssl->rbio, ssl->rbio_buf, ssl->rbio_pos); @@ -349,7 +316,7 @@ http_client_ssl_read_update( http_client_t *hc ) } return r; } - r2 = BIO_write(ssl->rbio, rbuf, r); + r2 = BIO_write(ssl->rbio, rbuf, r); len = r - (r2 < 0 ? 0 : r2); if (len) { if (ssl->rbio_pos + len > ssl->rbio_size) { @@ -362,13 +329,11 @@ http_client_ssl_read_update( http_client_t *hc ) return 0; } -static int -http_client_ssl_write_update( http_client_t *hc ) -{ - struct http_client_ssl *ssl = hc->hc_ssl; - char *rbuf = alloca(hc->hc_io_size); - ssize_t r, r2; - size_t len; +static int http_client_ssl_write_update(http_client_t* hc) { + struct http_client_ssl* ssl = hc->hc_ssl; + char* rbuf = alloca(hc->hc_io_size); + ssize_t r, r2; + size_t len; if (ssl->wbio_pos) { r = send(hc->hc_fd, ssl->wbio_buf, ssl->wbio_pos, MSG_DONTWAIT); @@ -388,7 +353,7 @@ http_client_ssl_write_update( http_client_t *hc ) } r = BIO_read(ssl->wbio, rbuf, hc->hc_io_size); if (r > 0) { - r2 = send(hc->hc_fd, rbuf, r, MSG_DONTWAIT); + r2 = send(hc->hc_fd, rbuf, r, MSG_DONTWAIT); len = r - (r2 < 0 ? 0 : r2); if (len) { if (ssl->wbio_pos + len > ssl->wbio_size) { @@ -411,11 +376,9 @@ http_client_ssl_write_update( http_client_t *hc ) return 0; } -static ssize_t -http_client_ssl_recv( http_client_t *hc, void *buf, size_t len ) -{ +static ssize_t http_client_ssl_recv(http_client_t* hc, void* buf, size_t len) { ssize_t r; - int e; + int e; while (1) { r = SSL_read(hc->hc_ssl->ssl, buf, len); @@ -450,12 +413,10 @@ http_client_ssl_recv( http_client_t *hc, void *buf, size_t len ) return 0; } -static ssize_t -http_client_ssl_send( http_client_t *hc, const void *buf, size_t len ) -{ - struct http_client_ssl *ssl = hc->hc_ssl; - ssize_t r, r2; - int e; +static ssize_t http_client_ssl_send(http_client_t* hc, const void* buf, size_t len) { + struct http_client_ssl* ssl = hc->hc_ssl; + ssize_t r, r2; + int e; if (hc->hc_verify_peer < 0) http_client_ssl_peer_verify(hc, 1); /* default method - verify */ @@ -467,10 +428,13 @@ http_client_ssl_send( http_client_t *hc, const void *buf, size_t len ) if (hc->hc_verify_peer > 0) { if (SSL_get_peer_certificate(ssl->ssl) == NULL || SSL_get_verify_result(ssl->ssl) != X509_V_OK) { - tvherror(LS_HTTPC, "%04X: SSL peer verification failed (%s:%i)%s %li", - shortid(hc), hc->hc_host, hc->hc_port, - SSL_get_peer_certificate(ssl->ssl) ? " X509" : "", - SSL_get_verify_result(ssl->ssl)); + tvherror(LS_HTTPC, + "%04X: SSL peer verification failed (%s:%i)%s %li", + shortid(hc), + hc->hc_host, + hc->hc_port, + SSL_get_peer_certificate(ssl->ssl) ? " X509" : "", + SSL_get_verify_result(ssl->ssl)); errno = EPERM; return -1; } @@ -478,7 +442,7 @@ http_client_ssl_send( http_client_t *hc, const void *buf, size_t len ) goto write; } } else { -write: + write: r = SSL_write(ssl->ssl, buf, len); } if (r > 0) { @@ -521,11 +485,9 @@ write: return 0; } -static ssize_t -http_client_ssl_shutdown( http_client_t *hc ) -{ +static ssize_t http_client_ssl_shutdown(http_client_t* hc) { ssize_t r; - int e; + int e; while (1) { r = SSL_shutdown(hc->hc_ssl->ssl); @@ -560,12 +522,10 @@ http_client_ssl_shutdown( http_client_t *hc ) return 0; } -static int -http_client_send_partial( http_client_t *hc ) -{ - http_client_wcmd_t *wcmd; - ssize_t r; - int res = HTTP_CON_IDLE; +static int http_client_send_partial(http_client_t* hc) { + http_client_wcmd_t* wcmd; + ssize_t r; + int res = HTTP_CON_IDLE; wcmd = TAILQ_FIRST(&hc->hc_wqueue); while (wcmd != NULL) { @@ -573,16 +533,14 @@ http_client_send_partial( http_client_t *hc ) hc->hc_rcseq = wcmd->wcseq; if (hc->hc_einprogress && http_client_einprogress(hc)) { errno = EINPROGRESS; - r = -1; + r = -1; goto skip; } if (hc->hc_ssl) - r = http_client_ssl_send(hc, wcmd->wbuf + wcmd->wpos, - wcmd->wsize - wcmd->wpos); + r = http_client_ssl_send(hc, wcmd->wbuf + wcmd->wpos, wcmd->wsize - wcmd->wpos); else - r = send(hc->hc_fd, wcmd->wbuf + wcmd->wpos, - wcmd->wsize - wcmd->wpos, MSG_DONTWAIT); -skip: + r = send(hc->hc_fd, wcmd->wbuf + wcmd->wpos, wcmd->wsize - wcmd->wpos, MSG_DONTWAIT); + skip: if (r < 0) { if (ERRNO_AGAIN(errno) || errno == EINPROGRESS) { http_client_direction(hc, 1); @@ -592,7 +550,7 @@ skip: } wcmd->wpos += r; if (wcmd->wpos >= wcmd->wsize) { - res = HTTP_CON_SENT; + res = HTTP_CON_SENT; wcmd = NULL; } break; @@ -606,16 +564,18 @@ skip: } } -int -http_client_send( http_client_t *hc, enum http_cmd cmd, - const char *path, const char *query, - http_arg_list_t *header, void *body, size_t body_size ) -{ - http_client_wcmd_t *wcmd = calloc(1, sizeof(*wcmd)); - http_arg_t *h; - htsbuf_queue_t q; - const char *s; - int empty; +int http_client_send(http_client_t* hc, + enum http_cmd cmd, + const char* path, + const char* query, + http_arg_list_t* header, + void* body, + size_t body_size) { + http_client_wcmd_t* wcmd = calloc(1, sizeof(*wcmd)); + http_arg_t* h; + htsbuf_queue_t q; + const char* s; + int empty; if (hc->hc_shutdown) { if (header) @@ -624,13 +584,13 @@ http_client_send( http_client_t *hc, enum http_cmd cmd, return -EIO; } - wcmd->wcmd = cmd; + wcmd->wcmd = cmd; hc->hc_keepalive = 1; htsbuf_queue_init(&q, 0); s = http_cmd2str(cmd); if (s == NULL) { -error: + error: if (header) http_arg_flush(header); free(wcmd); @@ -655,14 +615,13 @@ error: htsbuf_append(&q, "\r\n", 2); if (header) { - TAILQ_FOREACH(h, header, link) { + TAILQ_FOREACH (h, header, link) { htsbuf_append_str(&q, h->key); htsbuf_append(&q, ": ", 2); if (h->val) htsbuf_append_str(&q, h->val); htsbuf_append(&q, "\r\n", 2); - if (strcasecmp(h->key, "Connection") == 0 && - strcasecmp(h->val ?: "", "close") == 0) + if (strcasecmp(h->key, "Connection") == 0 && strcasecmp(h->val ?: "", "close") == 0) hc->hc_keepalive = 0; } http_arg_flush(header); @@ -680,7 +639,7 @@ error: htsbuf_append(&q, body, body_size); body_size = q.hq_size; - body = malloc(body_size); + body = malloc(body_size); htsbuf_read(&q, body, body_size); if (tvhtrace_enabled()) { @@ -701,11 +660,9 @@ error: return HTTP_CON_SENDING; } -static int -http_client_finish( http_client_t *hc ) -{ - http_client_wcmd_t *wcmd; - int res; +static int http_client_finish(http_client_t* hc) { + http_client_wcmd_t* wcmd; + int res; tvhtrace(LS_HTTPC, "%04X: finishing", shortid(hc)); @@ -721,18 +678,16 @@ http_client_finish( http_client_t *hc ) return http_client_flush(hc, res); } hc->hc_hsize = hc->hc_csize = 0; - wcmd = TAILQ_FIRST(&hc->hc_wqueue); + wcmd = TAILQ_FIRST(&hc->hc_wqueue); if (wcmd) http_client_cmd_destroy(hc, wcmd); if (hc->hc_handle_location && - (hc->hc_code == HTTP_STATUS_MOVED || - hc->hc_code == HTTP_STATUS_FOUND || - hc->hc_code == HTTP_STATUS_SEE_OTHER || - hc->hc_code == HTTP_STATUS_NOT_MODIFIED)) { - const char *p = http_arg_get(&hc->hc_args, "Location"); + (hc->hc_code == HTTP_STATUS_MOVED || hc->hc_code == HTTP_STATUS_FOUND || + hc->hc_code == HTTP_STATUS_SEE_OTHER || hc->hc_code == HTTP_STATUS_NOT_MODIFIED)) { + const char* p = http_arg_get(&hc->hc_args, "Location"); if (p) { hc->hc_location = strdup(p); - res = http_client_redirected(hc); + res = http_client_redirected(hc); if (res < 0) return http_client_flush(hc, res); return HTTP_CON_RECEIVING; @@ -753,9 +708,7 @@ http_client_finish( http_client_t *hc ) return hc->hc_reconnected ? HTTP_CON_RECEIVING : HTTP_CON_DONE; } -static int -http_client_parse_arg( http_arg_list_t *list, const char *p ) -{ +static int http_client_parse_arg(http_arg_list_t* list, const char* p) { char *d, *t; d = strchr(p, ':'); @@ -772,9 +725,7 @@ http_client_parse_arg( http_arg_list_t *list, const char *p ) return -EINVAL; } -static int -http_client_data_copy( http_client_t *hc, char *buf, size_t len ) -{ +static int http_client_data_copy(http_client_t* hc, char* buf, size_t len) { int res; if (hc->hc_data_received) { @@ -794,12 +745,10 @@ http_client_data_copy( http_client_t *hc, char *buf, size_t len ) return 0; } -static ssize_t -http_client_data_chunked( http_client_t *hc, char *buf, size_t len, int *end ) -{ +static ssize_t http_client_data_chunked(http_client_t* hc, char* buf, size_t len, int* end) { size_t old = len, l, l2; - char *d, *s; - int res; + char * d, *s; + int res; while (len > 0) { if (hc->hc_chunk_size) { @@ -812,8 +761,7 @@ http_client_data_chunked( http_client_t *hc, char *buf, size_t len, int *end ) buf += l; len -= l; if (hc->hc_chunk_pos >= hc->hc_chunk_size) { - if (s[hc->hc_chunk_size - 2] != '\r' && - s[hc->hc_chunk_size - 1] != '\n') + if (s[hc->hc_chunk_size - 2] != '\r' && s[hc->hc_chunk_size - 1] != '\n') return -EIO; res = http_client_data_copy(hc, hc->hc_chunk, hc->hc_chunk_size - 2); if (res < 0) @@ -825,7 +773,7 @@ http_client_data_chunked( http_client_t *hc, char *buf, size_t len, int *end ) l = 0; if (hc->hc_chunk_csize) { s = hc->hc_chunk; - if (buf[0] == '\n' && s[hc->hc_chunk_csize-1] == '\r') + if (buf[0] == '\n' && s[hc->hc_chunk_csize - 1] == '\r') l = 1; else if (len > 1 && buf[0] == '\r' && buf[1] == '\n') l = 2; @@ -833,7 +781,7 @@ http_client_data_chunked( http_client_t *hc, char *buf, size_t len, int *end ) d = strstr(s = buf, "\r\n"); if (d) { *d = '\0'; - l = (d + 2) - s; + l = (d + 2) - s; } } if (l) { @@ -859,13 +807,13 @@ http_client_data_chunked( http_client_t *hc, char *buf, size_t len, int *end ) hc->hc_chunk_size = strtoll(s, NULL, 16); if (hc->hc_chunk_size == 0) return -EIO; - if (hc->hc_chunk_size > 256*1024) + if (hc->hc_chunk_size > 256 * 1024) return -EMSGSIZE; hc->hc_chunk_size += 2; /* CR-LF */ if (hc->hc_chunk_alloc < hc->hc_chunk_size) { - hc->hc_chunk = realloc(hc->hc_chunk, hc->hc_chunk_size + 1); + hc->hc_chunk = realloc(hc->hc_chunk, hc->hc_chunk_size + 1); hc->hc_chunk[hc->hc_chunk_size] = '\0'; - hc->hc_chunk_alloc = hc->hc_chunk_size; + hc->hc_chunk_alloc = hc->hc_chunk_size; } } buf += l; @@ -873,8 +821,8 @@ http_client_data_chunked( http_client_t *hc, char *buf, size_t len, int *end ) } else { l2 = hc->hc_chunk_csize + len; if (l2 > hc->hc_chunk_alloc) { - hc->hc_chunk = realloc(hc->hc_chunk, l2 + 1); - hc->hc_chunk[l2] = '\0'; + hc->hc_chunk = realloc(hc->hc_chunk, l2 + 1); + hc->hc_chunk[l2] = '\0'; hc->hc_chunk_alloc = l2; } memcpy(hc->hc_chunk + hc->hc_chunk_csize, buf, len); @@ -886,11 +834,9 @@ http_client_data_chunked( http_client_t *hc, char *buf, size_t len, int *end ) return old; } -static int -http_client_data_received( http_client_t *hc, char *buf, ssize_t len, int hdr ) -{ +static int http_client_data_received(http_client_t* hc, char* buf, ssize_t len, int hdr) { ssize_t l, l2, csize; - int res, end = 0; + int res, end = 0; buf[len] = '\0'; @@ -900,10 +846,10 @@ http_client_data_received( http_client_t *hc, char *buf, ssize_t len, int hdr ) if (!hdr && hc->hc_rpos >= hc->hc_csize) return 1; return 0; - } + } csize = hc->hc_csize == (size_t)-1 ? 0 : hc->hc_csize; - l = len; + l = len; if (hc->hc_csize && hc->hc_csize != (size_t)-1 && hc->hc_rpos > csize) { l2 = hc->hc_rpos - csize; if (l2 < l) @@ -922,8 +868,8 @@ http_client_data_received( http_client_t *hc, char *buf, ssize_t len, int hdr ) } hc->hc_rpos += l; if (hc->hc_csize && hc->hc_rpos >= hc->hc_csize) { - end = 1; - hc->hc_rpos = 0; + end = 1; + hc->hc_rpos = 0; hc->hc_in_data = 0; } else if (end) { hc->hc_in_data = 0; @@ -934,14 +880,12 @@ http_client_data_received( http_client_t *hc, char *buf, ssize_t len, int hdr ) hc->hc_rbuf = realloc(hc->hc_rbuf, hc->hc_rsize = l2 + 1); memcpy(hc->hc_rbuf, buf + l, l2); hc->hc_rbuf[l2] = '\0'; - hc->hc_rpos = l2; + hc->hc_rpos = l2; } return end ? 1 : 0; } -static int -http_arg_contains(const char *arg, const char *val) -{ +static int http_arg_contains(const char* arg, const char* val) { char *a, *next, *p; /* copy will be modified by strsep() */ a = strdup(arg); @@ -957,13 +901,11 @@ http_arg_contains(const char *arg, const char *val) return 0; } -static int -http_client_run0( http_client_t *hc ) -{ - char *buf, *saveptr, *argv[3], *d, *p; - int ver, res, delimsize; +static int http_client_run0(http_client_t* hc) { + char * buf, *saveptr, *argv[3], *d, *p; + int ver, res, delimsize; ssize_t r; - size_t len; + size_t len; if (hc->hc_shutdown) { if (hc->hc_ssl && hc->hc_ssl->shutdown) { @@ -1047,12 +989,17 @@ retry: } if (hc->hc_rsize < r + hc->hc_rpos) { - if (hc->hc_rpos + r > hc->hc_io_size + 20*1024) { - tvhtrace(LS_HTTPC, "%04X: overflow, buf %zd pos %zd read %zd io %zd", - shortid(hc), hc->hc_rsize, hc->hc_rpos, r, hc->hc_io_size); + if (hc->hc_rpos + r > hc->hc_io_size + 20 * 1024) { + tvhtrace(LS_HTTPC, + "%04X: overflow, buf %zd pos %zd read %zd io %zd", + shortid(hc), + hc->hc_rsize, + hc->hc_rpos, + r, + hc->hc_io_size); return http_client_flush(hc, -EMSGSIZE); } - hc->hc_rsize += hc->hc_rpos + r + 4*1024; + hc->hc_rsize += hc->hc_rpos + r + 4 * 1024; hc->hc_rbuf = realloc(hc->hc_rbuf, hc->hc_rsize + 1); } memcpy(hc->hc_rbuf + hc->hc_rpos, buf, r); @@ -1064,7 +1011,7 @@ next_header: if (hc->hc_version == RTSP_VERSION_1_0 && hc->hc_rbuf[0] == '$') goto rtsp_data; hc->hc_rbuf[hc->hc_rpos] = '\0'; - delimsize = 4; + delimsize = 4; if ((d = strstr(hc->hc_rbuf, "\r\n\r\n")) == NULL) { delimsize = 2; if ((d = strstr(hc->hc_rbuf, "\n\n")) == NULL) @@ -1072,17 +1019,21 @@ next_header: } header: - *d = '\0'; - len = hc->hc_rpos; + *d = '\0'; + len = hc->hc_rpos; hc->hc_reconnected = 0; http_client_clear_state(hc); hc->hc_rpos = len; hc->hc_hsize = d - hc->hc_rbuf + delimsize; - p = strtok_r(hc->hc_rbuf, "\r\n", &saveptr); + p = strtok_r(hc->hc_rbuf, "\r\n", &saveptr); if (p == NULL) return http_client_flush(hc, -EINVAL); - tvhtrace(LS_HTTPC, "%04X: %s answer '%s' (rcseq: %d)", - shortid(hc), http_ver2str(hc->hc_version), p, hc->hc_rcseq); + tvhtrace(LS_HTTPC, + "%04X: %s answer '%s' (rcseq: %d)", + shortid(hc), + http_ver2str(hc->hc_version), + p, + hc->hc_rcseq); tvhlog_hexdump(LS_HTTPC, hc->hc_rbuf, hc->hc_hsize); if (http_tokenize(p, argv, 3, -1) != 3) return http_client_flush(hc, -EINVAL); @@ -1138,18 +1089,17 @@ header: http_client_rbuf_cut(hc, hc->hc_hsize); goto next_header; } - if (hc->hc_version == RTSP_VERSION_1_0 && - (hc->hc_csize == -1 || !hc->hc_csize)) { - hc->hc_csize = -1; + if (hc->hc_version == RTSP_VERSION_1_0 && (hc->hc_csize == -1 || !hc->hc_csize)) { + hc->hc_csize = -1; hc->hc_in_data = 0; http_client_rbuf_cut(hc, hc->hc_hsize); return http_client_finish(hc); } else { hc->hc_in_data = 1; } - len = hc->hc_rpos - hc->hc_hsize; + len = hc->hc_rpos - hc->hc_hsize; hc->hc_rpos = 0; - res = http_client_data_received(hc, hc->hc_rbuf + hc->hc_hsize, len, 1); + res = http_client_data_received(hc, hc->hc_rbuf + hc->hc_hsize, len, 1); if (res < 0) return http_client_flush(hc, res); if (res > 0) @@ -1158,13 +1108,13 @@ header: rtsp_data: /* RTSP embedded data */ - r = 0; - hc->hc_in_data = 0; + r = 0; + hc->hc_in_data = 0; hc->hc_in_rtp_data = 0; while (hc->hc_rpos > r + 3) { if (hc->hc_rbuf[r] != '$') break; - hc->hc_csize = 4 + ((hc->hc_rbuf[r+2] << 8) | hc->hc_rbuf[r+3]); + hc->hc_csize = 4 + ((hc->hc_rbuf[r + 2] << 8) | hc->hc_rbuf[r + 3]); hc->hc_chunked = 0; if (r + hc->hc_csize > hc->hc_rpos) { http_client_rbuf_cut(hc, r); @@ -1184,7 +1134,7 @@ rtsp_data: } r += hc->hc_csize; hc->hc_code = 0; - res = 0; + res = 0; if (hc->hc_rtp_data_complete) { http_client_get(hc); tvh_mutex_unlock(&hc->hc_mutex); @@ -1203,9 +1153,7 @@ rtsp_data: return HTTP_CON_RECEIVING; } -int -http_client_run( http_client_t *hc ) -{ +int http_client_run(http_client_t* hc) { int r; if (hc == NULL) @@ -1219,23 +1167,22 @@ http_client_run( http_client_t *hc ) /* * */ -void -http_client_basic_auth( http_client_t *hc, http_arg_list_t *h, - const char *user, const char *pass ) -{ +void http_client_basic_auth(http_client_t* hc, + http_arg_list_t* h, + const char* user, + const char* pass) { if (user && user[0] && pass && pass[0]) { #define BASIC "Basic " size_t plen = strlen(pass); size_t ulen = strlen(user); - size_t len = BASE64_SIZE(plen + ulen + 1) + 1; - char *buf = alloca(ulen + 1 + plen + 1); - char *cbuf = alloca(len + sizeof(BASIC) + 1); + size_t len = BASE64_SIZE(plen + ulen + 1) + 1; + char* buf = alloca(ulen + 1 + plen + 1); + char* cbuf = alloca(len + sizeof(BASIC) + 1); strcpy(buf, user); strcat(buf, ":"); strcat(buf, pass); strcpy(cbuf, BASIC); - base64_encode(cbuf + sizeof(BASIC) - 1, len, - (uint8_t *)buf, ulen + 1 + plen); + base64_encode(cbuf + sizeof(BASIC) - 1, len, (uint8_t*)buf, ulen + 1 + plen); http_arg_set(h, "Authorization", cbuf); #undef BASIC } @@ -1244,17 +1191,17 @@ http_client_basic_auth( http_client_t *hc, http_arg_list_t *h, /* * Redirected */ -void -http_client_basic_args ( http_client_t *hc, http_arg_list_t *h, const url_t *url, int keepalive ) -{ +void http_client_basic_args(http_client_t* hc, + http_arg_list_t* h, + const url_t* url, + int keepalive) { char buf[256]; http_arg_flush(h); if (url->port == 0) { /* default port */ http_arg_set(h, "Host", url->host); } else { - snprintf(buf, sizeof(buf), "%s:%u", url->host, - http_port(hc, url->scheme, url->port)); + snprintf(buf, sizeof(buf), "%s:%u", url->host, http_port(hc, url->scheme, url->port)); http_arg_set(h, "Host", buf); } assert(config.http_user_agent); @@ -1264,74 +1211,74 @@ http_client_basic_args ( http_client_t *hc, http_arg_list_t *h, const url_t *url http_client_basic_auth(hc, h, url->user, url->pass); } -static char * -strstrip(char *s) -{ +static char* strstrip(char* s) { size_t l; if (s != NULL) { - while (*s && *s <= ' ') s++; + while (*s && *s <= ' ') + s++; l = *s ? 0 : strlen(s) - 1; - while (*s && s[l] <= ' ') s[l--] = '\0'; + while (*s && s[l] <= ' ') + s[l--] = '\0'; } return s; } -void -http_client_add_args ( http_client_t *hc, http_arg_list_t *h, const char *args ) -{ +void http_client_add_args(http_client_t* hc, http_arg_list_t* h, const char* args) { char *p, *k, *v; if (args == NULL) return; p = tvh_strdupa(args); while (*p) { - while (*p && *p <= ' ') p++; - if (*p == '\0') break; + while (*p && *p <= ' ') + p++; + if (*p == '\0') + break; k = p; - while (*p && *p != '\r' && *p != '\n' && *p != ':' && *p != '=') p++; + while (*p && *p != '\r' && *p != '\n' && *p != ':' && *p != '=') + p++; v = NULL; - if (*p == '=' || *p == ':') { *p = '\0'; p++; v = p; } - while (*p && *p != '\r' && *p != '\n') p++; - if (*p) { *p = '\0'; p++; } + if (*p == '=' || *p == ':') { + *p = '\0'; + p++; + v = p; + } + while (*p && *p != '\r' && *p != '\n') + p++; + if (*p) { + *p = '\0'; + p++; + } k = strstrip(k); v = strstrip(v); - if (v && *v && *k && - strcasecmp(k, "Connection") != 0 && - strcasecmp(k, "Host") != 0) { + if (v && *v && *k && strcasecmp(k, "Connection") != 0 && strcasecmp(k, "Host") != 0) { http_arg_get_remove(h, k); http_arg_set(h, k, v); } } } -int -http_client_simple_reconnect ( http_client_t *hc, const url_t *u, - http_ver_t ver ) -{ +int http_client_simple_reconnect(http_client_t* hc, const url_t* u, http_ver_t ver) { http_arg_list_t h; - tvhpoll_t *efd; - int r; + tvhpoll_t* efd; + int r; lock_assert(&hc->hc_mutex); - if (tvh_str_default(u->scheme, NULL) == NULL || - tvh_str_default(u->host, NULL) == NULL || + if (tvh_str_default(u->scheme, NULL) == NULL || tvh_str_default(u->host, NULL) == NULL || u->port < 0) { tvherror(LS_HTTPC, "Invalid url '%s'", u->raw); return -EINVAL; } - if (strcmp(u->scheme, hc->hc_scheme) || - strcmp(u->host, hc->hc_host) || - http_port(hc, u->scheme, u->port) != hc->hc_port || - !hc->hc_keepalive) { + if (strcmp(u->scheme, hc->hc_scheme) || strcmp(u->host, hc->hc_host) || + http_port(hc, u->scheme, u->port) != hc->hc_port || !hc->hc_keepalive) { efd = hc->hc_efd; http_client_shutdown(hc, 1, 1); - r = http_client_reconnect(hc, hc->hc_version, - u->scheme, u->host, u->port); + r = http_client_reconnect(hc, hc->hc_version, u->scheme, u->host, u->port); hc->hc_efd = efd; if (r < 0) return r; - r = hc->hc_verify_peer; + r = hc->hc_verify_peer; hc->hc_verify_peer = -1; http_client_ssl_peer_verify(hc, r); } @@ -1358,12 +1305,10 @@ http_client_simple_reconnect ( http_client_t *hc, const url_t *u, return HTTP_CON_RECEIVING; } -static int -http_client_redirected ( http_client_t *hc ) -{ +static int http_client_redirected(http_client_t* hc) { char *location, *location2; url_t u; - int r; + int r; if (++hc->hc_redirects > 10) return -ELOOP; @@ -1372,17 +1317,17 @@ http_client_redirected ( http_client_t *hc ) location2 = hc->hc_location = NULL; if (location[0] == '\0' || location[0] == '/') { - size_t size2 = strlen(hc->hc_scheme) + 3 + strlen(hc->hc_host) + - 12 + strlen(location) + 1; - location2 = alloca(size2); - snprintf(location2, size2, "%s://%s:%i%s", - hc->hc_scheme, hc->hc_host, hc->hc_port, location); + size_t size2 = strlen(hc->hc_scheme) + 3 + strlen(hc->hc_host) + 12 + strlen(location) + 1; + location2 = alloca(size2); + snprintf(location2, size2, "%s://%s:%i%s", hc->hc_scheme, hc->hc_host, hc->hc_port, location); } urlinit(&u); if (urlparse(location2 ? location2 : location, &u)) { - tvherror(LS_HTTPC, "%04X: redirection - cannot parse url '%s'", - shortid(hc), location2 ? location2 : location); + tvherror(LS_HTTPC, + "%04X: redirection - cannot parse url '%s'", + shortid(hc), + location2 ? location2 : location); free(location); return -EIO; } @@ -1394,37 +1339,32 @@ http_client_redirected ( http_client_t *hc ) return r; } -int -http_client_simple( http_client_t *hc, const url_t *url ) -{ +int http_client_simple(http_client_t* hc, const url_t* url) { http_arg_list_t h; - int r; + int r; tvh_mutex_lock(&hc->hc_mutex); http_arg_init(&h); hc->hc_hdr_create(hc, &h, url, 0); free(hc->hc_url); hc->hc_url = url->raw ? strdup(url->raw) : NULL; - r = http_client_send(hc, HTTP_CMD_GET, url->path, url->query, - &h, NULL, 0); + r = http_client_send(hc, HTTP_CMD_GET, url->path, url->query, &h, NULL, 0); tvh_mutex_unlock(&hc->hc_mutex); return r; } -void -http_client_ssl_peer_verify( http_client_t *hc, int verify ) -{ - struct http_client_ssl *ssl; +void http_client_ssl_peer_verify(http_client_t* hc, int verify) { + struct http_client_ssl* ssl; if (hc->hc_verify_peer < 0) { hc->hc_verify_peer = verify ? 1 : 0; if ((ssl = hc->hc_ssl) != NULL) { if (!SSL_CTX_set_default_verify_paths(ssl->ctx)) - tvherror(LS_HTTPC, "%04X: SSL - unable to load CA certificates for verification", shortid(hc)); + tvherror(LS_HTTPC, + "%04X: SSL - unable to load CA certificates for verification", + shortid(hc)); SSL_CTX_set_verify_depth(ssl->ctx, 1); - SSL_CTX_set_verify(ssl->ctx, - hc->hc_verify_peer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, - NULL); + SSL_CTX_set_verify(ssl->ctx, hc->hc_verify_peer ? SSL_VERIFY_PEER : SSL_VERIFY_NONE, NULL); } } else { tvherror(LS_HTTPC, "%04X: SSL peer verification method must be set only once", shortid(hc)); @@ -1434,13 +1374,11 @@ http_client_ssl_peer_verify( http_client_t *hc, int verify ) /* * Data thread */ -static void * -http_client_thread ( void *p ) -{ - int n; +static void* http_client_thread(void* p) { + int n; tvhpoll_event_t ev; - http_client_t *hc; - char c; + http_client_t* hc; + char c; while (atomic_get(&http_running)) { n = tvhpoll_wait(http_poll, &ev, 1, -1); @@ -1456,7 +1394,7 @@ http_client_thread ( void *p ) continue; } tvh_mutex_lock(&http_lock); - TAILQ_FOREACH(hc, &http_clients, hc_link) + TAILQ_FOREACH (hc, &http_clients, hc_link) if (hc == ev.ptr) break; if (hc == NULL) { @@ -1484,10 +1422,8 @@ http_client_thread ( void *p ) return NULL; } -static void -http_client_ssl_free( http_client_t *hc ) -{ - struct http_client_ssl *ssl; +static void http_client_ssl_free(http_client_t* hc) { + struct http_client_ssl* ssl; if ((ssl = hc->hc_ssl) != NULL) { free(ssl->rbio_buf); @@ -1502,44 +1438,44 @@ http_client_ssl_free( http_client_t *hc ) /* * Setup a connection (async) */ -static int -http_client_reconnect - ( http_client_t *hc, http_ver_t ver, const char *scheme, - const char *host, int port ) -{ - struct http_client_ssl *ssl; - char errbuf[256]; +static int http_client_reconnect(http_client_t* hc, + http_ver_t ver, + const char* scheme, + const char* host, + int port) { + struct http_client_ssl* ssl; + char errbuf[256]; free(hc->hc_scheme); free(hc->hc_host); hc->hc_scheme = NULL; - hc->hc_host = NULL; + hc->hc_host = NULL; if (scheme == NULL || host == NULL) goto errnval; - port = http_port(hc, scheme, port); - hc->hc_fd = tcp_connect(host, port, hc->hc_bindaddr, errbuf, sizeof(errbuf), -1); + port = http_port(hc, scheme, port); + hc->hc_fd = tcp_connect(host, port, hc->hc_bindaddr, errbuf, sizeof(errbuf), -1); if (hc->hc_fd < 0) { tvherror(LS_HTTPC, "%04X: Unable to connect to %s:%i - %s", shortid(hc), host, port, errbuf); goto errnval; } - hc->hc_pevents = 0; - hc->hc_version = ver; - hc->hc_redirv = ver; - hc->hc_port = port; - hc->hc_scheme = strdup(scheme); - hc->hc_host = strdup(host); + hc->hc_pevents = 0; + hc->hc_version = ver; + hc->hc_redirv = ver; + hc->hc_port = port; + hc->hc_scheme = strdup(scheme); + hc->hc_host = strdup(host); hc->hc_einprogress = 1; tvhtrace(LS_HTTPC, "%04X: Connected to %s:%i", shortid(hc), host, port); http_client_ssl_free(hc); if (strcasecmp(scheme, "https") == 0 || strcasecmp(scheme, "rtsps") == 0) { - ssl = calloc(1, sizeof(*ssl)); + ssl = calloc(1, sizeof(*ssl)); hc->hc_ssl = ssl; #if OPENSSL_VERSION_NUMBER < 0x10100000L - ssl->ctx = SSL_CTX_new(SSLv23_client_method()); + ssl->ctx = SSL_CTX_new(SSLv23_client_method()); #else - ssl->ctx = SSL_CTX_new(TLS_client_method()); + ssl->ctx = SSL_CTX_new(TLS_client_method()); #endif if (ssl->ctx == NULL) { tvherror(LS_HTTPC, "%04X: Unable to get SSL_CTX", shortid(hc)); @@ -1552,9 +1488,9 @@ http_client_reconnect tvherror(LS_HTTPC, "%04X: Unable to adjust SSL cipher list", shortid(hc)); goto err2; } - ssl->rbio = BIO_new(BIO_s_mem()); - ssl->wbio = BIO_new(BIO_s_mem()); - ssl->ssl = SSL_new(ssl->ctx); + ssl->rbio = BIO_new(BIO_s_mem()); + ssl->wbio = BIO_new(BIO_s_mem()); + ssl->ssl = SSL_new(ssl->ctx); if (ssl->ssl == NULL || ssl->rbio == NULL || ssl->wbio == NULL) { tvherror(LS_HTTPC, "%04X: Unable to get SSL handle", shortid(hc)); goto err3; @@ -1586,23 +1522,24 @@ errnval: return -EINVAL; } -http_client_t * -http_client_connect - ( void *aux, http_ver_t ver, const char *scheme, - const char *host, int port, const char *bindaddr ) -{ - http_client_t *hc; - static int tally; - int r; - - hc = calloc(1, sizeof(http_client_t)); +http_client_t* http_client_connect(void* aux, + http_ver_t ver, + const char* scheme, + const char* host, + int port, + const char* bindaddr) { + http_client_t* hc; + static int tally; + int r; + + hc = calloc(1, sizeof(http_client_t)); tvh_mutex_init(&hc->hc_mutex, NULL); - hc->hc_id = atomic_add(&tally, 1); - hc->hc_aux = aux; - hc->hc_io_size = 1024; + hc->hc_id = atomic_add(&tally, 1); + hc->hc_aux = aux; + hc->hc_io_size = 1024; hc->hc_rtsp_stream_id = -1; - hc->hc_verify_peer = -1; - hc->hc_bindaddr = bindaddr ? strdup(bindaddr) : NULL; + hc->hc_verify_peer = -1; + hc->hc_bindaddr = bindaddr ? strdup(bindaddr) : NULL; TAILQ_INIT(&hc->hc_args); TAILQ_INIT(&hc->hc_wqueue); @@ -1623,17 +1560,15 @@ http_client_connect /* * Register to the another thread */ -void -http_client_register( http_client_t *hc ) -{ +void http_client_register(http_client_t* hc) { assert(hc->hc_data_received || hc->hc_conn_closed || hc->hc_data_complete); assert(hc->hc_efd == NULL); - + tvh_mutex_lock(&http_lock); TAILQ_INSERT_TAIL(&http_clients, hc, hc_link); - hc->hc_efd = http_poll; + hc->hc_efd = http_poll; tvh_mutex_unlock(&http_lock); } @@ -1644,10 +1579,8 @@ http_client_register( http_client_t *hc ) * This function is not allowed to be called inside the callbacks for * registered clients to the http_client_thread . */ -void -http_client_close ( http_client_t *hc ) -{ - http_client_wcmd_t *wcmd; +void http_client_close(http_client_t* hc) { + http_client_wcmd_t* wcmd; if (hc == NULL) return; @@ -1702,9 +1635,7 @@ http_client_close ( http_client_t *hc ) */ pthread_t http_client_tid; -void -http_client_init ( void ) -{ +void http_client_init(void) { /* Setup list */ tvh_mutex_init(&http_lock, NULL); tvh_cond_init(&http_cond, 1); @@ -1714,7 +1645,7 @@ http_client_init ( void ) tvh_pipe(O_NONBLOCK, &http_pipe); /* Setup poll */ - http_poll = tvhpoll_create(10); + http_poll = tvhpoll_create(10); tvhpoll_add1(http_poll, http_pipe.rd, TVHPOLL_IN, &http_pipe); /* Setup thread */ @@ -1725,17 +1656,15 @@ http_client_init ( void ) #endif } -void -http_client_done ( void ) -{ - http_client_t *hc; +void http_client_done(void) { + http_client_t* hc; atomic_set(&http_running, 0); tvh_write(http_pipe.wr, "", 1); pthread_join(http_client_tid, NULL); tvh_pipe_close(&http_pipe); tvh_mutex_lock(&http_lock); - TAILQ_FOREACH(hc, &http_clients, hc_link) + TAILQ_FOREACH (hc, &http_clients, hc_link) if (hc->hc_efd == http_poll) hc->hc_efd = NULL; tvhpoll_destroy(http_poll); @@ -1751,34 +1680,29 @@ http_client_done ( void ) #if HTTPCLIENT_TESTSUITE -static int -http_client_testsuite_hdr_received( http_client_t *hc ) -{ - http_arg_t *ra; +static int http_client_testsuite_hdr_received(http_client_t* hc) { + http_arg_t* ra; fprintf(stderr, "HTTPCTS: Received header from %s:%i\n", hc->hc_host, hc->hc_port); - TAILQ_FOREACH(ra, &hc->hc_args, link) + TAILQ_FOREACH (ra, &hc->hc_args, link) fprintf(stderr, " %s: %s\n", ra->key, ra->val); return 0; } -static void -http_client_testsuite_conn_closed( http_client_t *hc, int result ) -{ +static void http_client_testsuite_conn_closed(http_client_t* hc, int result) { fprintf(stderr, "HTTPCTS: Closed (result=%i - %s)\n", result, strerror(result)); } -static int -http_client_testsuite_data_complete( http_client_t *hc ) -{ - fprintf(stderr, "HTTPCTS: Data Complete (code=%i, data=%p, data_size=%zi)\n", - hc->hc_code, hc->hc_data, hc->hc_data_size); +static int http_client_testsuite_data_complete(http_client_t* hc) { + fprintf(stderr, + "HTTPCTS: Data Complete (code=%i, data=%p, data_size=%zi)\n", + hc->hc_code, + hc->hc_data, + hc->hc_data_size); return 0; } -static int -http_client_testsuite_data_received( http_client_t *hc, void *data, size_t len ) -{ +static int http_client_testsuite_data_received(http_client_t* hc, void* data, size_t len) { fprintf(stderr, "HTTPCTS: Data received (len=%zi)\n", len); /* check, if the data memory area is OK */ memset(data, 0xa5, len); @@ -1786,166 +1710,164 @@ http_client_testsuite_data_received( http_client_t *hc, void *data, size_t len ) } static struct strtab ERRNO_tab[] = { - { "EPERM", EPERM }, - { "ENOENT", ENOENT }, - { "ESRCH", ESRCH }, - { "EINTR", EINTR }, - { "EIO", EIO }, - { "ENXIO", ENXIO }, - { "E2BIG", E2BIG }, - { "ENOEXEC", ENOEXEC }, - { "EBADF", EBADF }, - { "ECHILD", ECHILD }, - { "EAGAIN", EAGAIN }, - { "ENOMEM", ENOMEM }, - { "EACCES", EACCES }, - { "EFAULT", EFAULT }, - { "ENOTBLK", ENOTBLK }, - { "EBUSY", EBUSY }, - { "EEXIST", EEXIST }, - { "EXDEV", EXDEV }, - { "ENODEV", ENODEV }, - { "ENOTDIR", ENOTDIR }, - { "EISDIR", EISDIR }, - { "EINVAL", EINVAL }, - { "ENFILE", ENFILE }, - { "EMFILE", EMFILE }, - { "ENOTTY", ENOTTY }, - { "ETXTBSY", ETXTBSY }, - { "EFBIG", EFBIG }, - { "ENOSPC", ENOSPC }, - { "ESPIPE", ESPIPE }, - { "EROFS", EROFS }, - { "EMLINK", EMLINK }, - { "EPIPE", EPIPE }, - { "EDOM", EDOM }, - { "ERANGE", ERANGE }, + {"EPERM", EPERM}, + {"ENOENT", ENOENT}, + {"ESRCH", ESRCH}, + {"EINTR", EINTR}, + {"EIO", EIO}, + {"ENXIO", ENXIO}, + {"E2BIG", E2BIG}, + {"ENOEXEC", ENOEXEC}, + {"EBADF", EBADF}, + {"ECHILD", ECHILD}, + {"EAGAIN", EAGAIN}, + {"ENOMEM", ENOMEM}, + {"EACCES", EACCES}, + {"EFAULT", EFAULT}, + {"ENOTBLK", ENOTBLK}, + {"EBUSY", EBUSY}, + {"EEXIST", EEXIST}, + {"EXDEV", EXDEV}, + {"ENODEV", ENODEV}, + {"ENOTDIR", ENOTDIR}, + {"EISDIR", EISDIR}, + {"EINVAL", EINVAL}, + {"ENFILE", ENFILE}, + {"EMFILE", EMFILE}, + {"ENOTTY", ENOTTY}, + {"ETXTBSY", ETXTBSY}, + {"EFBIG", EFBIG}, + {"ENOSPC", ENOSPC}, + {"ESPIPE", ESPIPE}, + {"EROFS", EROFS}, + {"EMLINK", EMLINK}, + {"EPIPE", EPIPE}, + {"EDOM", EDOM}, + {"ERANGE", ERANGE}, #ifdef __linux__ - { "EDEADLK", EDEADLK }, - { "ENAMETOOLONG", ENAMETOOLONG }, - { "ENOLCK", ENOLCK }, - { "ENOSYS", ENOSYS }, - { "ENOTEMPTY", ENOTEMPTY }, - { "ELOOP", ELOOP }, - { "EWOULDBLOCK", EWOULDBLOCK }, - { "ENOMSG", ENOMSG }, - { "EIDRM", EIDRM }, - { "ECHRNG", ECHRNG }, - { "EL2NSYNC", EL2NSYNC }, - { "EL3HLT", EL3HLT }, - { "EL3RST", EL3RST }, - { "ELNRNG", ELNRNG }, - { "EUNATCH", EUNATCH }, - { "ENOCSI", ENOCSI }, - { "EL2HLT", EL2HLT }, - { "EBADE", EBADE }, - { "EBADR", EBADR }, - { "EXFULL", EXFULL }, - { "ENOANO", ENOANO }, - { "EBADRQC", EBADRQC }, - { "EBADSLT", EBADSLT }, - { "EDEADLOCK", EDEADLOCK }, - { "EBFONT", EBFONT }, - { "ENOSTR", ENOSTR }, - { "ENODATA", ENODATA }, - { "ETIME", ETIME }, - { "ENOSR", ENOSR }, - { "ENONET", ENONET }, - { "ENOPKG", ENOPKG }, - { "EREMOTE", EREMOTE }, - { "ENOLINK", ENOLINK }, - { "EADV", EADV }, - { "ESRMNT", ESRMNT }, - { "ECOMM", ECOMM }, - { "EPROTO", EPROTO }, - { "EMULTIHOP", EMULTIHOP }, - { "EDOTDOT", EDOTDOT }, - { "EBADMSG", EBADMSG }, - { "EOVERFLOW", EOVERFLOW }, - { "ENOTUNIQ", ENOTUNIQ }, - { "EBADFD", EBADFD }, - { "EREMCHG", EREMCHG }, - { "ELIBACC", ELIBACC }, - { "ELIBBAD", ELIBBAD }, - { "ELIBSCN", ELIBSCN }, - { "ELIBMAX", ELIBMAX }, - { "ELIBEXEC", ELIBEXEC }, - { "EILSEQ", EILSEQ }, - { "ERESTART", ERESTART }, - { "ESTRPIPE", ESTRPIPE }, - { "EUSERS", EUSERS }, - { "ENOTSOCK", ENOTSOCK }, - { "EDESTADDRREQ", EDESTADDRREQ }, - { "EMSGSIZE", EMSGSIZE }, - { "EPROTOTYPE", EPROTOTYPE }, - { "ENOPROTOOPT", ENOPROTOOPT }, - { "EPROTONOSUPPORT", EPROTONOSUPPORT }, - { "ESOCKTNOSUPPORT", ESOCKTNOSUPPORT }, - { "EOPNOTSUPP", EOPNOTSUPP }, - { "EPFNOSUPPORT", EPFNOSUPPORT }, - { "EAFNOSUPPORT", EAFNOSUPPORT }, - { "EADDRINUSE", EADDRINUSE }, - { "EADDRNOTAVAIL", EADDRNOTAVAIL }, - { "ENETDOWN", ENETDOWN }, - { "ENETUNREACH", ENETUNREACH }, - { "ENETRESET", ENETRESET }, - { "ECONNABORTED", ECONNABORTED }, - { "ECONNRESET", ECONNRESET }, - { "ENOBUFS", ENOBUFS }, - { "EISCONN", EISCONN }, - { "ENOTCONN", ENOTCONN }, - { "ESHUTDOWN", ESHUTDOWN }, - { "ETOOMANYREFS", ETOOMANYREFS }, - { "ETIMEDOUT", ETIMEDOUT }, - { "ECONNREFUSED", ECONNREFUSED }, - { "EHOSTDOWN", EHOSTDOWN }, - { "EHOSTUNREACH", EHOSTUNREACH }, - { "EALREADY", EALREADY }, - { "EINPROGRESS", EINPROGRESS }, - { "ESTALE", ESTALE }, - { "EUCLEAN", EUCLEAN }, - { "ENOTNAM", ENOTNAM }, - { "ENAVAIL", ENAVAIL }, - { "EISNAM", EISNAM }, - { "EREMOTEIO", EREMOTEIO }, - { "EDQUOT", EDQUOT }, - { "ENOMEDIUM", ENOMEDIUM }, - { "EMEDIUMTYPE", EMEDIUMTYPE }, - { "ECANCELED", ECANCELED }, - { "ENOKEY", ENOKEY }, - { "EKEYEXPIRED", EKEYEXPIRED }, - { "EKEYREVOKED", EKEYREVOKED }, - { "EKEYREJECTED", EKEYREJECTED }, - { "EOWNERDEAD", EOWNERDEAD }, - { "ENOTRECOVERABLE", ENOTRECOVERABLE }, + {"EDEADLK", EDEADLK}, + {"ENAMETOOLONG", ENAMETOOLONG}, + {"ENOLCK", ENOLCK}, + {"ENOSYS", ENOSYS}, + {"ENOTEMPTY", ENOTEMPTY}, + {"ELOOP", ELOOP}, + {"EWOULDBLOCK", EWOULDBLOCK}, + {"ENOMSG", ENOMSG}, + {"EIDRM", EIDRM}, + {"ECHRNG", ECHRNG}, + {"EL2NSYNC", EL2NSYNC}, + {"EL3HLT", EL3HLT}, + {"EL3RST", EL3RST}, + {"ELNRNG", ELNRNG}, + {"EUNATCH", EUNATCH}, + {"ENOCSI", ENOCSI}, + {"EL2HLT", EL2HLT}, + {"EBADE", EBADE}, + {"EBADR", EBADR}, + {"EXFULL", EXFULL}, + {"ENOANO", ENOANO}, + {"EBADRQC", EBADRQC}, + {"EBADSLT", EBADSLT}, + {"EDEADLOCK", EDEADLOCK}, + {"EBFONT", EBFONT}, + {"ENOSTR", ENOSTR}, + {"ENODATA", ENODATA}, + {"ETIME", ETIME}, + {"ENOSR", ENOSR}, + {"ENONET", ENONET}, + {"ENOPKG", ENOPKG}, + {"EREMOTE", EREMOTE}, + {"ENOLINK", ENOLINK}, + {"EADV", EADV}, + {"ESRMNT", ESRMNT}, + {"ECOMM", ECOMM}, + {"EPROTO", EPROTO}, + {"EMULTIHOP", EMULTIHOP}, + {"EDOTDOT", EDOTDOT}, + {"EBADMSG", EBADMSG}, + {"EOVERFLOW", EOVERFLOW}, + {"ENOTUNIQ", ENOTUNIQ}, + {"EBADFD", EBADFD}, + {"EREMCHG", EREMCHG}, + {"ELIBACC", ELIBACC}, + {"ELIBBAD", ELIBBAD}, + {"ELIBSCN", ELIBSCN}, + {"ELIBMAX", ELIBMAX}, + {"ELIBEXEC", ELIBEXEC}, + {"EILSEQ", EILSEQ}, + {"ERESTART", ERESTART}, + {"ESTRPIPE", ESTRPIPE}, + {"EUSERS", EUSERS}, + {"ENOTSOCK", ENOTSOCK}, + {"EDESTADDRREQ", EDESTADDRREQ}, + {"EMSGSIZE", EMSGSIZE}, + {"EPROTOTYPE", EPROTOTYPE}, + {"ENOPROTOOPT", ENOPROTOOPT}, + {"EPROTONOSUPPORT", EPROTONOSUPPORT}, + {"ESOCKTNOSUPPORT", ESOCKTNOSUPPORT}, + {"EOPNOTSUPP", EOPNOTSUPP}, + {"EPFNOSUPPORT", EPFNOSUPPORT}, + {"EAFNOSUPPORT", EAFNOSUPPORT}, + {"EADDRINUSE", EADDRINUSE}, + {"EADDRNOTAVAIL", EADDRNOTAVAIL}, + {"ENETDOWN", ENETDOWN}, + {"ENETUNREACH", ENETUNREACH}, + {"ENETRESET", ENETRESET}, + {"ECONNABORTED", ECONNABORTED}, + {"ECONNRESET", ECONNRESET}, + {"ENOBUFS", ENOBUFS}, + {"EISCONN", EISCONN}, + {"ENOTCONN", ENOTCONN}, + {"ESHUTDOWN", ESHUTDOWN}, + {"ETOOMANYREFS", ETOOMANYREFS}, + {"ETIMEDOUT", ETIMEDOUT}, + {"ECONNREFUSED", ECONNREFUSED}, + {"EHOSTDOWN", EHOSTDOWN}, + {"EHOSTUNREACH", EHOSTUNREACH}, + {"EALREADY", EALREADY}, + {"EINPROGRESS", EINPROGRESS}, + {"ESTALE", ESTALE}, + {"EUCLEAN", EUCLEAN}, + {"ENOTNAM", ENOTNAM}, + {"ENAVAIL", ENAVAIL}, + {"EISNAM", EISNAM}, + {"EREMOTEIO", EREMOTEIO}, + {"EDQUOT", EDQUOT}, + {"ENOMEDIUM", ENOMEDIUM}, + {"EMEDIUMTYPE", EMEDIUMTYPE}, + {"ECANCELED", ECANCELED}, + {"ENOKEY", ENOKEY}, + {"EKEYEXPIRED", EKEYEXPIRED}, + {"EKEYREVOKED", EKEYREVOKED}, + {"EKEYREJECTED", EKEYREJECTED}, + {"EOWNERDEAD", EOWNERDEAD}, + {"ENOTRECOVERABLE", ENOTRECOVERABLE}, #ifdef ERFKILL - { "ERFKILL", ERFKILL }, + {"ERFKILL", ERFKILL}, #endif #ifdef EHWPOISON - { "EHWPOISON", EHWPOISON }, + {"EHWPOISON", EHWPOISON}, #endif #endif /* __linux__ */ }; -void -http_client_testsuite_run( void ) -{ - const char *path, *cs, *cs2; - char line[1024], *s; +void http_client_testsuite_run(void) { + const char * path, *cs, *cs2; + char line[1024], *s; http_arg_list_t args; - http_client_t *hc = NULL; - http_cmd_t cmd; - http_ver_t ver = HTTP_VERSION_1_1; - int data_transfer = 0, port = 0; - size_t data_limit = 0; + http_client_t* hc = NULL; + http_cmd_t cmd; + http_ver_t ver = HTTP_VERSION_1_1; + int data_transfer = 0, port = 0; + size_t data_limit = 0; tvhpoll_event_t ev; - tvhpoll_t *efd; - url_t u1, u2; - FILE *fp; - int r, expected = HTTP_CON_DONE, expected_code = 200; - int handle_location = 0; - int peer_verify = 1; - int repeat = 0, repeat2; + tvhpoll_t* efd; + url_t u1, u2; + FILE* fp; + int r, expected = HTTP_CON_DONE, expected_code = 200; + int handle_location = 0; + int peer_verify = 1; + int repeat = 0, repeat2; path = getenv("TVHEADEND_HTTPC_TEST"); if (path == NULL) @@ -1979,15 +1901,15 @@ http_client_testsuite_run( void ) urlreset(&u1); urlreset(&u2); http_client_close(hc); - hc = NULL; - data_transfer = 0; - data_limit = 0; - port = 0; - expected = HTTP_CON_DONE; - expected_code = 200; + hc = NULL; + data_transfer = 0; + data_limit = 0; + port = 0; + expected = HTTP_CON_DONE; + expected_code = 200; handle_location = 0; - peer_verify = 1; - repeat = 0; + peer_verify = 1; + repeat = 0; } else if (strcmp(s, "DataTransfer=all") == 0) { data_transfer = 0; } else if (strcmp(s, "DataTransfer=cont") == 0) { @@ -2039,18 +1961,22 @@ http_client_testsuite_run( void ) fprintf(stderr, "HTTPCTS: Define URL\n"); goto fatal; } - cmd = http_str2cmd(s + 8); + cmd = http_str2cmd(s + 8); repeat2 = 0; -rep: + rep: http_client_basic_args(hc, &args, &u1, 1); - if (u2.host == NULL || u1.host == NULL || strcmp(u1.host, u2.host) || - u2.port != u1.port || (hc && !hc->hc_keepalive)) { + if (u2.host == NULL || u1.host == NULL || strcmp(u1.host, u2.host) || u2.port != u1.port || + (hc && !hc->hc_keepalive)) { http_client_close(hc); if (port) u1.port = port; hc = http_client_connect(NULL, ver, u1.scheme, u1.host, u1.port, NULL); if (hc == NULL) { - fprintf(stderr, "HTTPCTS: Unable to connect to %s:%i (%s)\n", u1.host, u1.port, u1.scheme); + fprintf(stderr, + "HTTPCTS: Unable to connect to %s:%i (%s)\n", + u1.host, + u1.port, + u1.scheme); goto fatal; } else { fprintf(stderr, "HTTPCTS: Connected to %s:%i\n", hc->hc_host, hc->hc_port); @@ -2059,14 +1985,18 @@ rep: urlreset(&u2); urlcopy(&u2, &u1); } - fprintf(stderr, "HTTPCTS Send: Cmd=%s Ver=%s Host=%s Path=%s\n", - http_cmd2str(cmd), http_ver2str(ver), http_arg_get(&args, "Host"), u1.path); - hc->hc_efd = efd; + fprintf(stderr, + "HTTPCTS Send: Cmd=%s Ver=%s Host=%s Path=%s\n", + http_cmd2str(cmd), + http_ver2str(ver), + http_arg_get(&args, "Host"), + u1.path); + hc->hc_efd = efd; hc->hc_handle_location = handle_location; - hc->hc_data_limit = data_limit; - hc->hc_hdr_received = http_client_testsuite_hdr_received; - hc->hc_data_complete = http_client_testsuite_data_complete; - hc->hc_conn_closed = http_client_testsuite_conn_closed; + hc->hc_data_limit = data_limit; + hc->hc_hdr_received = http_client_testsuite_hdr_received; + hc->hc_data_complete = http_client_testsuite_data_complete; + hc->hc_conn_closed = http_client_testsuite_conn_closed; if (data_transfer) { hc->hc_data_received = http_client_testsuite_data_received; } else { @@ -2093,17 +2023,25 @@ rep: fprintf(stderr, "HTTPCTS: Poll returned a wrong value\n"); goto fatal; } - r = http_client_run(hc); + r = http_client_run(hc); cs = val2str(r, HTTP_contab); if (cs == NULL) cs = val2str(-r, ERRNO_tab); cs2 = val2str(expected, HTTP_contab); if (cs2 == NULL) cs2 = val2str(-expected, ERRNO_tab); - fprintf(stderr, "HTTPCTS: Run Done, Result = %i (%s), Expected = %i (%s)\n", r, cs, expected, cs2); + fprintf(stderr, + "HTTPCTS: Run Done, Result = %i (%s), Expected = %i (%s)\n", + r, + cs, + expected, + cs2); if (r == expected) { if (hc->hc_code != expected_code) { - fprintf(stderr, "HTTPCTS: HTTP Code Fail: Expected = %i Got = %i\n", expected_code, hc->hc_code); + fprintf(stderr, + "HTTPCTS: HTTP Code Fail: Expected = %i Got = %i\n", + expected_code, + hc->hc_code); goto fatal; } break; diff --git a/src/huffman.c b/src/huffman.c index ac3a322f6..69169963f 100644 --- a/src/huffman.c +++ b/src/huffman.c @@ -23,43 +23,45 @@ #include "htsmsg.h" #include "settings.h" -void huffman_tree_destroy ( huffman_node_t *n ) -{ - if (!n) return; +void huffman_tree_destroy(huffman_node_t* n) { + if (!n) + return; huffman_tree_destroy(n->b0); huffman_tree_destroy(n->b1); - if (n->data) free(n->data); + if (n->data) + free(n->data); free(n); } -huffman_node_t *huffman_tree_load ( const char *path ) -{ - htsmsg_t *m; - huffman_node_t *ret; - if (!(m = hts_settings_load(path))) return NULL; +huffman_node_t* huffman_tree_load(const char* path) { + htsmsg_t* m; + huffman_node_t* ret; + if (!(m = hts_settings_load(path))) + return NULL; ret = huffman_tree_build(m); htsmsg_destroy(m); return ret; } -huffman_node_t *huffman_tree_build ( htsmsg_t *m ) -{ - const char *code, *data, *c; - htsmsg_t *e; - htsmsg_field_t *f; - huffman_node_t *root = calloc(1, sizeof(huffman_node_t)); +huffman_node_t* huffman_tree_build(htsmsg_t* m) { + const char * code, *data, *c; + htsmsg_t* e; + htsmsg_field_t* f; + huffman_node_t* root = calloc(1, sizeof(huffman_node_t)); HTSMSG_FOREACH(f, m) { e = htsmsg_get_map_by_field(f); c = code = htsmsg_get_str(e, "code"); - data = htsmsg_get_str(e, "data"); + data = htsmsg_get_str(e, "data"); if (code && data) { - huffman_node_t *node = root; + huffman_node_t* node = root; while (*c) { - if ( *c == '0' ) { - if (!node->b0) node->b0 = calloc(1, sizeof(huffman_node_t)); + if (*c == '0') { + if (!node->b0) + node->b0 = calloc(1, sizeof(huffman_node_t)); node = node->b0; - } else if ( *c == '1' ) { - if (!node->b1) node->b1 = calloc(1, sizeof(huffman_node_t)); + } else if (*c == '1') { + if (!node->b1) + node->b1 = calloc(1, sizeof(huffman_node_t)); node = node->b1; } else { huffman_tree_destroy(root); @@ -70,16 +72,19 @@ huffman_node_t *huffman_tree_build ( htsmsg_t *m ) node->data = strdup(data); } } - return root; + return root; } -char *huffman_decode - ( huffman_node_t *tree, const uint8_t *data, size_t len, uint8_t mask, - char *outb, int outl ) -{ - char *ret = outb; - huffman_node_t *node = tree; - if (!len) return NULL; +char* huffman_decode(huffman_node_t* tree, + const uint8_t* data, + size_t len, + uint8_t mask, + char* outb, + int outl) { + char* ret = outb; + huffman_node_t* node = tree; + if (!len) + return NULL; outl--; // leave space for NULL while (len) { @@ -91,14 +96,18 @@ char *huffman_decode node = node->b0; } mask >>= 1; - if (!node) goto end; + if (!node) + goto end; if (node->data) { - char *t = node->data; + char* t = node->data; while (*t && outl) { *outb = *t; - outb++; t++; outl--; + outb++; + t++; + outl--; } - if (!outl) goto end; + if (!outl) + goto end; node = tree; } } diff --git a/src/huffman.h b/src/huffman.h index 184a5a8f4..c7a85563f 100644 --- a/src/huffman.h +++ b/src/huffman.h @@ -22,18 +22,20 @@ #include #include "htsmsg.h" -typedef struct huffman_node -{ - struct huffman_node *b0; - struct huffman_node *b1; - char *data; +typedef struct huffman_node { + struct huffman_node* b0; + struct huffman_node* b1; + char* data; } huffman_node_t; -void huffman_tree_destroy ( huffman_node_t *tree ); -huffman_node_t *huffman_tree_load ( const char *path ); -huffman_node_t *huffman_tree_build ( htsmsg_t *codes ); -char *huffman_decode - ( huffman_node_t *tree, const uint8_t *data, size_t len, uint8_t mask, - char *outb, int outl ); +void huffman_tree_destroy(huffman_node_t* tree); +huffman_node_t* huffman_tree_load(const char* path); +huffman_node_t* huffman_tree_build(htsmsg_t* codes); +char* huffman_decode(huffman_node_t* tree, + const uint8_t* data, + size_t len, + uint8_t mask, + char* outb, + int outl); #endif diff --git a/src/idnode.c b/src/idnode.c index 457b19171..6dd183c85 100644 --- a/src/idnode.c +++ b/src/idnode.c @@ -31,30 +31,29 @@ #include "uuid.h" #include "access.h" -static const idnodes_rb_t * idnode_domain ( const idclass_t *idc ); -static idnodes_rb_t * idclass_find_domain ( const idclass_t *idc ); +static const idnodes_rb_t* idnode_domain(const idclass_t* idc); +static idnodes_rb_t* idclass_find_domain(const idclass_t* idc); -typedef struct idclass_link -{ - const idclass_t *idc; - idnodes_rb_t nodes; +typedef struct idclass_link { + const idclass_t* idc; + idnodes_rb_t nodes; RB_ENTRY(idclass_link) link; } idclass_link_t; -tvh_mutex_t idnode_mutex; -static idnodes_rb_t idnodes; -static RB_HEAD(,idclass_link) idclasses; -static RB_HEAD(,idclass_link) idrootclasses; -static TAILQ_HEAD(,idnode_save) idnodes_save; +tvh_mutex_t idnode_mutex; +static idnodes_rb_t idnodes; +static RB_HEAD(, idclass_link) idclasses; +static RB_HEAD(, idclass_link) idrootclasses; +static TAILQ_HEAD(, idnode_save) idnodes_save; static tvh_cond_t save_cond; static pthread_t save_tid; static int save_running; static mtimer_t save_timer; -static tvh_mutex_t idnode_lnotify_mutex = TVH_THREAD_MUTEX_INITIALIZER; -static tvh_uuid_set_t idnode_lnotify_set; -static tvh_uuid_set_t idnode_lnotify_title_set; +static tvh_mutex_t idnode_lnotify_mutex = TVH_THREAD_MUTEX_INITIALIZER; +static tvh_uuid_set_t idnode_lnotify_set; +static tvh_uuid_set_t idnode_lnotify_title_set; SKEL_DECLARE(idclasses_skel, idclass_link_t); @@ -65,15 +64,11 @@ SKEL_DECLARE(idclasses_skel, idclass_link_t); /** * */ -static int -in_cmp(const idnode_t *a, const idnode_t *b) -{ +static int in_cmp(const idnode_t* a, const idnode_t* b) { return uuid_cmp(&a->in_uuid, &b->in_uuid); } -static int -ic_cmp ( const idclass_link_t *a, const idclass_link_t *b ) -{ +static int ic_cmp(const idclass_link_t* a, const idclass_link_t* b) { assert(a->idc->ic_class); assert(b->idc->ic_class); return strcmp(a->idc->ic_class, b->idc->ic_class); @@ -83,9 +78,7 @@ ic_cmp ( const idclass_link_t *a, const idclass_link_t *b ) * Registration * *************************************************************************/ -static const idclass_t * -idnode_root_class(const idclass_t *idc) -{ +static const idclass_t* idnode_root_class(const idclass_t* idc) { while (idc && idc->ic_super) idc = idc->ic_super; return idc; @@ -94,15 +87,13 @@ idnode_root_class(const idclass_t *idc) /** * */ -int -idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class, int flags) -{ - idnode_t *c; - tvh_uuid_t u; - int retries = 5; - uint32_t u32; - const idclass_t *idc; - char ubuf[UUID_HEX_SIZE]; +int idnode_insert(idnode_t* in, const char* uuid, const idclass_t* class, int flags) { + idnode_t* c; + tvh_uuid_t u; + int retries = 5; + uint32_t u32; + const idclass_t* idc; + char ubuf[UUID_HEX_SIZE]; lock_assert(&global_lock); @@ -121,7 +112,7 @@ idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class, int flags) if (flags & IDNODE_SHORT_UUID) { u32 = idnode_get_short_uuid(in); idc = idnode_root_class(in->in_class); - RB_FOREACH(c, &idnodes, in_link) { + RB_FOREACH (c, &idnodes, in_link) { if (idc != idnode_root_class(c->in_class)) continue; if (idnode_get_short_uuid(c) == u32) @@ -134,11 +125,15 @@ idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class, int flags) } while (c != NULL && --retries > 0); - if(c != NULL) { - tvherror(LS_IDNODE, "Id node collission (%s) %s", - uuid, (flags & IDNODE_SHORT_UUID) ? " (short)" : ""); - fprintf(stderr, "Id node collision (%s) %s\n", - uuid, (flags & IDNODE_SHORT_UUID) ? " (short)" : ""); + if (c != NULL) { + tvherror(LS_IDNODE, + "Id node collission (%s) %s", + uuid, + (flags & IDNODE_SHORT_UUID) ? " (short)" : ""); + fprintf(stderr, + "Id node collision (%s) %s\n", + uuid, + (flags & IDNODE_SHORT_UUID) ? " (short)" : ""); abort(); } tvhtrace(LS_IDNODE, "insert node %s", idnode_uuid_as_str(in, ubuf)); @@ -163,9 +158,7 @@ idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class, int flags) /** * */ -void -idnode_unlink(idnode_t *in) -{ +void idnode_unlink(idnode_t* in) { char ubuf[UUID_HEX_SIZE]; lock_assert(&global_lock); @@ -181,14 +174,12 @@ idnode_unlink(idnode_t *in) /** * */ -static void -idnode_handler(size_t off, idnode_t *in, const char *action) -{ - void (**fcn)(idnode_t *); +static void idnode_handler(size_t off, idnode_t* in, const char* action) { + void (**fcn)(idnode_t*); lock_assert(&global_lock); - const idclass_t *idc = in->in_class; + const idclass_t* idc = in->in_class; while (idc) { - fcn = (void *)idc + off; + fcn = (void*)idc + off; if (*fcn) { if (action) idnode_notify(in, action); @@ -199,21 +190,15 @@ idnode_handler(size_t off, idnode_t *in, const char *action) } } -void -idnode_delete(idnode_t *in) -{ +void idnode_delete(idnode_t* in) { idnode_handler(offsetof(idclass_t, ic_delete), in, NULL); } -void -idnode_moveup(idnode_t *in) -{ +void idnode_moveup(idnode_t* in) { return idnode_handler(offsetof(idclass_t, ic_moveup), in, "moveup"); } -void -idnode_movedown(idnode_t *in) -{ +void idnode_movedown(idnode_t* in) { return idnode_handler(offsetof(idclass_t, ic_movedown), in, "movedown"); } @@ -221,9 +206,7 @@ idnode_movedown(idnode_t *in) * Info * *************************************************************************/ -uint32_t -idnode_get_short_uuid (const idnode_t *in) -{ +uint32_t idnode_get_short_uuid(const idnode_t* in) { uint32_t u32; memcpy(&u32, in->in_uuid.bin, sizeof(u32)); return u32 & 0x7FFFFFFF; // compat needs to be +ve signed @@ -232,22 +215,18 @@ idnode_get_short_uuid (const idnode_t *in) /** * */ -const char * -idnode_uuid_as_str(const idnode_t *in, char *uuid) -{ +const char* idnode_uuid_as_str(const idnode_t* in, char* uuid) { return bin2hex(uuid, UUID_HEX_SIZE, in->in_uuid.bin, sizeof(in->in_uuid.bin)); } /** * */ -const char * -idnode_get_title(idnode_t *in, const char *lang, char *dst, size_t dstsize) -{ - static char ubuf[UUID_HEX_SIZE]; - const idclass_t *ic = in->in_class; - for(; ic != NULL; ic = ic->ic_super) { - if(ic->ic_get_title != NULL) { +const char* idnode_get_title(idnode_t* in, const char* lang, char* dst, size_t dstsize) { + static char ubuf[UUID_HEX_SIZE]; + const idclass_t* ic = in->in_class; + for (; ic != NULL; ic = ic->ic_super) { + if (ic->ic_get_title != NULL) { ic->ic_get_title(in, lang, dst, dstsize); return dst; } @@ -256,19 +235,16 @@ idnode_get_title(idnode_t *in, const char *lang, char *dst, size_t dstsize) return dst; } - /** * */ -idnode_set_t * -idnode_get_childs(idnode_t *in) -{ - if(in == NULL) +idnode_set_t* idnode_get_childs(idnode_t* in) { + if (in == NULL) return NULL; - const idclass_t *ic = in->in_class; - for(; ic != NULL; ic = ic->ic_super) { - if(ic->ic_get_childs != NULL) + const idclass_t* ic = in->in_class; + for (; ic != NULL; ic = ic->ic_super) { + if (ic->ic_get_childs != NULL) return ic->ic_get_childs(in); } return NULL; @@ -277,23 +253,20 @@ idnode_get_childs(idnode_t *in) /** * */ -int -idnode_is_leaf(idnode_t *in) -{ - const idclass_t *ic = in->in_class; - for(; ic != NULL; ic = ic->ic_super) { - if(ic->ic_get_childs != NULL) +int idnode_is_leaf(idnode_t* in) { + const idclass_t* ic = in->in_class; + for (; ic != NULL; ic = ic->ic_super) { + if (ic->ic_get_childs != NULL) return 0; } return 1; } -int -idnode_is_instance(idnode_t *in, const idclass_t *idc) -{ - const idclass_t *ic = in->in_class; - for(; ic != NULL; ic = ic->ic_super) { - if (ic == idc) return 1; +int idnode_is_instance(idnode_t* in, const idclass_t* idc) { + const idclass_t* ic = in->in_class; + for (; ic != NULL; ic = ic->ic_super) { + if (ic == idc) + return 1; } return 0; } @@ -302,14 +275,12 @@ idnode_is_instance(idnode_t *in, const idclass_t *idc) * Properties * *************************************************************************/ -static const property_t * -idnode_find_prop - ( idnode_t *self, const char *key ) -{ - const idclass_t *idc = self->in_class; - const property_t *p; +static const property_t* idnode_find_prop(idnode_t* self, const char* key) { + const idclass_t* idc = self->in_class; + const property_t* p; while (idc) { - if ((p = prop_find(idc->ic_properties, key))) return p; + if ((p = prop_find(idc->ic_properties, key))) + return p; idc = idc->ic_super; } return NULL; @@ -318,31 +289,26 @@ idnode_find_prop /* * Get display value */ -static char * -idnode_get_display - ( idnode_t *self, const property_t *p, const char *lang ) -{ - char *r = NULL; +static char* idnode_get_display(idnode_t* self, const property_t* p, const char* lang) { + char* r = NULL; if (p) { if (p->rend) r = p->rend(self, lang); else if (p->islist) { - htsmsg_t *l = (htsmsg_t*)p->get(self); + htsmsg_t* l = (htsmsg_t*)p->get(self); if (l) { r = htsmsg_list_2_csv(l, ',', 1); htsmsg_destroy(l); } } else if (p->list) { - htsmsg_t *l = p->list(self, lang), *m; - htsmsg_field_t *f; - int32_t k, v; - const char *s; - if (l && !idnode_get_u32(self, p->id, (uint32_t *)&v)) + htsmsg_t * l = p->list(self, lang), *m; + htsmsg_field_t* f; + int32_t k, v; + const char* s; + if (l && !idnode_get_u32(self, p->id, (uint32_t*)&v)) HTSMSG_FOREACH(f, l) { m = htsmsg_field_get_map(f); - if (!htsmsg_get_s32(m, "key", &k) && - (s = htsmsg_get_str(m, "val")) != NULL && - v == k) { + if (!htsmsg_get_s32(m, "key", &k) && (s = htsmsg_get_str(m, "val")) != NULL && v == k) { r = strdup(s); break; } @@ -356,13 +322,10 @@ idnode_get_display /* * Get field as string */ -const char * -idnode_get_str - ( idnode_t *self, const char *key ) -{ - const property_t *p = idnode_find_prop(self, key); +const char* idnode_get_str(idnode_t* self, const char* key) { + const property_t* p = idnode_find_prop(self, key); if (p && p->type == PT_STR) { - const void *ptr; + const void* ptr; if (p->get) ptr = p->get(self); else @@ -376,13 +339,10 @@ idnode_get_str /* * Get field as unsigned int */ -int -idnode_get_u32 - ( idnode_t *self, const char *key, uint32_t *u32 ) -{ - const property_t *p = idnode_find_prop(self, key); +int idnode_get_u32(idnode_t* self, const char* key, uint32_t* u32) { + const property_t* p = idnode_find_prop(self, key); if (p) { - const void *ptr; + const void* ptr; if (p->islist) return 1; else if (p->get) @@ -410,13 +370,10 @@ idnode_get_u32 /* * Get field as signed 64-bit int */ -int -idnode_get_s64 - ( idnode_t *self, const char *key, int64_t *s64 ) -{ - const property_t *p = idnode_find_prop(self, key); +int idnode_get_s64(idnode_t* self, const char* key, int64_t* s64) { + const property_t* p = idnode_find_prop(self, key); if (p) { - const void *ptr; + const void* ptr; if (p->islist) return 1; else if (p->get) @@ -453,13 +410,10 @@ idnode_get_s64 /* * Get field as signed 64-bit int */ -int -idnode_get_s64_atomic - ( idnode_t *self, const char *key, int64_t *s64 ) -{ - const property_t *p = idnode_find_prop(self, key); +int idnode_get_s64_atomic(idnode_t* self, const char* key, int64_t* s64) { + const property_t* p = idnode_find_prop(self, key); if (p) { - const void *ptr; + const void* ptr; if (p->islist) return 1; else if (p->get) @@ -480,13 +434,10 @@ idnode_get_s64_atomic /* * Get field as double */ -int -idnode_get_dbl - ( idnode_t *self, const char *key, double *dbl ) -{ - const property_t *p = idnode_find_prop(self, key); +int idnode_get_dbl(idnode_t* self, const char* key, double* dbl) { + const property_t* p = idnode_find_prop(self, key); if (p) { - const void *ptr; + const void* ptr; if (p->islist) return 1; else if (p->get) @@ -508,7 +459,7 @@ idnode_get_dbl *dbl = *(int64_t*)ptr; return 0; case PT_DBL: - *dbl = *(double *)ptr; + *dbl = *(double*)ptr; return 0; case PT_TIME: *dbl = *(time_t*)ptr; @@ -523,13 +474,10 @@ idnode_get_dbl /* * Get field as BOOL */ -int -idnode_get_bool - ( idnode_t *self, const char *key, int *b ) -{ - const property_t *p = idnode_find_prop(self, key); - if (p) { - const void *ptr; +int idnode_get_bool(idnode_t* self, const char* key, int* b) { + const property_t* p = idnode_find_prop(self, key); + if (p) { + const void* ptr; if (p->islist) return 1; else if (p->get) @@ -544,19 +492,16 @@ idnode_get_bool break; } } - return 1; + return 1; } /* * Get field as time */ -int -idnode_get_time - ( idnode_t *self, const char *key, time_t *tm ) -{ - const property_t *p = idnode_find_prop(self, key); +int idnode_get_time(idnode_t* self, const char* key, time_t* tm) { + const property_t* p = idnode_find_prop(self, key); if (p) { - const void *ptr; + const void* ptr; if (p->islist) return 1; if (p->get) @@ -578,11 +523,9 @@ idnode_get_time * Lookup * *************************************************************************/ -int -idnode_perm(idnode_t *self, struct access *a, htsmsg_t *msg_to_write) -{ - const idclass_t *ic = self->in_class; - int r; +int idnode_perm(idnode_t* self, struct access* a, htsmsg_t* msg_to_write) { + const idclass_t* ic = self->in_class; + int r; while (ic) { if (ic->ic_perm) @@ -605,14 +548,12 @@ idnode_perm(idnode_t *self, struct access *a, htsmsg_t *msg_to_write) /** * */ -static const idnodes_rb_t * -idnode_domain(const idclass_t *idc) -{ +static const idnodes_rb_t* idnode_domain(const idclass_t* idc) { if (idc) { - idclass_link_t lskel, *l; - const idclass_t *root = idnode_root_class(idc); - lskel.idc = root; - l = RB_FIND(&idrootclasses, &lskel, link, ic_cmp); + idclass_link_t lskel, *l; + const idclass_t* root = idnode_root_class(idc); + lskel.idc = root; + l = RB_FIND(&idrootclasses, &lskel, link, ic_cmp); if (l == NULL) return NULL; return &l->nodes; @@ -621,10 +562,8 @@ idnode_domain(const idclass_t *idc) } } -static idnode_t * -idnode_find_ ( idnode_t *skel, const idclass_t *idc, const idnodes_rb_t *domain ) -{ - idnode_t *r; +static idnode_t* idnode_find_(idnode_t* skel, const idclass_t* idc, const idnodes_rb_t* domain) { + idnode_t* r; if (domain == NULL) domain = idnode_domain(idc); @@ -632,10 +571,10 @@ idnode_find_ ( idnode_t *skel, const idclass_t *idc, const idnodes_rb_t *domain r = RB_FIND(&idnodes, skel, in_link, in_cmp); else r = RB_FIND(domain, skel, in_domain_link, in_cmp); - if(r != NULL && idc != NULL) { - const idclass_t *c = r->in_class; - for(;c != NULL; c = c->ic_super) { - if(idc == c) + if (r != NULL && idc != NULL) { + const idclass_t* c = r->in_class; + for (; c != NULL; c = c->ic_super) { + if (idc == c) return r; } return NULL; @@ -643,41 +582,34 @@ idnode_find_ ( idnode_t *skel, const idclass_t *idc, const idnodes_rb_t *domain return r; } -void * -idnode_find0 ( tvh_uuid_t *uuid, const idclass_t *idc, const idnodes_rb_t *domain ) -{ - char buf[UUID_HEX_SIZE]; +void* idnode_find0(tvh_uuid_t* uuid, const idclass_t* idc, const idnodes_rb_t* domain) { + char buf[UUID_HEX_SIZE]; idnode_t skel; skel.in_uuid = *uuid; - tvhtrace(LS_IDNODE, "find node %s class %s", - uuid_get_hex(uuid, buf), idc ? idc->ic_class : NULL); + tvhtrace(LS_IDNODE, "find node %s class %s", uuid_get_hex(uuid, buf), idc ? idc->ic_class : NULL); return idnode_find_(&skel, idc, domain); } -void * -idnode_find ( const char *uuid, const idclass_t *idc, const idnodes_rb_t *domain ) -{ +void* idnode_find(const char* uuid, const idclass_t* idc, const idnodes_rb_t* domain) { idnode_t skel; tvhtrace(LS_IDNODE, "find node %s class %s", uuid, idc ? idc->ic_class : NULL); - if(uuid == NULL || strlen(uuid) != UUID_HEX_SIZE - 1) + if (uuid == NULL || strlen(uuid) != UUID_HEX_SIZE - 1) return NULL; - if(hex2bin(skel.in_uuid.bin, sizeof(skel.in_uuid.bin), uuid)) + if (hex2bin(skel.in_uuid.bin, sizeof(skel.in_uuid.bin), uuid)) return NULL; return idnode_find_(&skel, idc, domain); } -idnode_set_t * -idnode_find_all ( const idclass_t *idc, const idnodes_rb_t *domain ) -{ - idnode_t *in; - const idclass_t *ic; - char ubuf[UUID_HEX_SIZE]; +idnode_set_t* idnode_find_all(const idclass_t* idc, const idnodes_rb_t* domain) { + idnode_t* in; + const idclass_t* ic; + char ubuf[UUID_HEX_SIZE]; tvhtrace(LS_IDNODE, "find class %s", idc->ic_class); - idnode_set_t *is = calloc(1, sizeof(idnode_set_t)); + idnode_set_t* is = calloc(1, sizeof(idnode_set_t)); if (domain == NULL) domain = idnode_domain(idc); if (domain == NULL) { - RB_FOREACH(in, &idnodes, in_link) { + RB_FOREACH (in, &idnodes, in_link) { ic = in->in_class; while (ic) { if (ic == idc) { @@ -689,7 +621,7 @@ idnode_find_all ( const idclass_t *idc, const idnodes_rb_t *domain ) } } } else { - RB_FOREACH(in, domain, in_domain_link) { + RB_FOREACH (in, domain, in_domain_link) { ic = in->in_class; while (ic) { if (ic == idc) { @@ -708,36 +640,31 @@ idnode_find_all ( const idclass_t *idc, const idnodes_rb_t *domain ) * Set processing * *************************************************************************/ -static int -idnode_cmp_title - ( const void *a, const void *b, void *lang ) -{ - idnode_t *ina = *(idnode_t**)a; - idnode_t *inb = *(idnode_t**)b; - char bufa[384]; - char bufb[384]; - idnode_get_title(ina, (const char *)lang, bufa, sizeof(bufa)); - idnode_get_title(inb, (const char *)lang, bufb, sizeof(bufb)); +static int idnode_cmp_title(const void* a, const void* b, void* lang) { + idnode_t* ina = *(idnode_t**)a; + idnode_t* inb = *(idnode_t**)b; + char bufa[384]; + char bufb[384]; + idnode_get_title(ina, (const char*)lang, bufa, sizeof(bufa)); + idnode_get_title(inb, (const char*)lang, bufb, sizeof(bufb)); return strcmp(bufa, bufb); } #define safecmp(a, b) ((a) > (b) ? 1 : ((a) < (b) ? -1 : 0)) -static int -idnode_cmp_sort - ( const void *a, const void *b, void *s ) -{ - idnode_t *ina = *(idnode_t**)a; - idnode_t *inb = *(idnode_t**)b; - idnode_sort_t *sort = s; - const property_t *p = idnode_find_prop(ina, sort->key); - if (!p) return 0; +static int idnode_cmp_sort(const void* a, const void* b, void* s) { + idnode_t* ina = *(idnode_t**)a; + idnode_t* inb = *(idnode_t**)b; + idnode_sort_t* sort = s; + const property_t* p = idnode_find_prop(ina, sort->key); + if (!p) + return 0; /* Get display string */ if (p->islist || (p->list && !(p->opts & PO_SORTKEY))) { - int r; - char *stra = idnode_get_display(ina, p, sort->lang); - char *strb = idnode_get_display(inb, p, sort->lang); + int r; + char* stra = idnode_get_display(ina, p, sort->lang); + char* strb = idnode_get_display(inb, p, sort->lang); if (sort->dir == IS_ASC) r = strcmp(stra ?: "", strb ?: ""); else @@ -748,87 +675,73 @@ idnode_cmp_sort } switch (p->type) { - case PT_STR: - { - int r; - const char *stra = tvh_strdupa(idnode_get_str(ina, sort->key) ?: ""); - const char *strb = idnode_get_str(inb, sort->key) ?: ""; - if (sort->dir == IS_ASC) - r = strcmp(stra, strb); - else - r = strcmp(strb, stra); - return r; - } - break; + case PT_STR: { + int r; + const char* stra = tvh_strdupa(idnode_get_str(ina, sort->key) ?: ""); + const char* strb = idnode_get_str(inb, sort->key) ?: ""; + if (sort->dir == IS_ASC) + r = strcmp(stra, strb); + else + r = strcmp(strb, stra); + return r; + } break; case PT_INT: case PT_U16: case PT_BOOL: - case PT_PERM: - { - int32_t i32a = 0, i32b = 0; - idnode_get_u32(ina, sort->key, (uint32_t *)&i32a); - idnode_get_u32(inb, sort->key, (uint32_t *)&i32b); - if (sort->dir == IS_ASC) - return safecmp(i32a, i32b); - else - return safecmp(i32b, i32a); - } - break; - case PT_U32: - { - uint32_t u32a = 0, u32b = 0; - idnode_get_u32(ina, sort->key, &u32a); - idnode_get_u32(inb, sort->key, &u32b); - if (sort->dir == IS_ASC) - return safecmp(u32a, u32b); - else - return safecmp(u32b, u32a); - } - break; - case PT_S64: - { - int64_t s64a = 0, s64b = 0; - idnode_get_s64(ina, sort->key, &s64a); - idnode_get_s64(inb, sort->key, &s64b); - if (sort->dir == IS_ASC) - return safecmp(s64a, s64b); - else - return safecmp(s64b, s64a); - } - break; - case PT_S64_ATOMIC: - { - int64_t s64a = 0, s64b = 0; - idnode_get_s64_atomic(ina, sort->key, &s64a); - idnode_get_s64_atomic(inb, sort->key, &s64b); - if (sort->dir == IS_ASC) - return safecmp(s64a, s64b); - else - return safecmp(s64b, s64a); - } - break; - case PT_DBL: - { - double dbla = 0, dblb = 0; - idnode_get_dbl(ina, sort->key, &dbla); - idnode_get_dbl(inb, sort->key, &dblb); - if (sort->dir == IS_ASC) - return safecmp(dbla, dblb); - else - return safecmp(dblb, dbla); - } - break; - case PT_TIME: - { - time_t ta = 0, tb = 0; - idnode_get_time(ina, sort->key, &ta); - idnode_get_time(inb, sort->key, &tb); - if (sort->dir == IS_ASC) - return safecmp(ta, tb); - else - return safecmp(tb, ta); - } - break; + case PT_PERM: { + int32_t i32a = 0, i32b = 0; + idnode_get_u32(ina, sort->key, (uint32_t*)&i32a); + idnode_get_u32(inb, sort->key, (uint32_t*)&i32b); + if (sort->dir == IS_ASC) + return safecmp(i32a, i32b); + else + return safecmp(i32b, i32a); + } break; + case PT_U32: { + uint32_t u32a = 0, u32b = 0; + idnode_get_u32(ina, sort->key, &u32a); + idnode_get_u32(inb, sort->key, &u32b); + if (sort->dir == IS_ASC) + return safecmp(u32a, u32b); + else + return safecmp(u32b, u32a); + } break; + case PT_S64: { + int64_t s64a = 0, s64b = 0; + idnode_get_s64(ina, sort->key, &s64a); + idnode_get_s64(inb, sort->key, &s64b); + if (sort->dir == IS_ASC) + return safecmp(s64a, s64b); + else + return safecmp(s64b, s64a); + } break; + case PT_S64_ATOMIC: { + int64_t s64a = 0, s64b = 0; + idnode_get_s64_atomic(ina, sort->key, &s64a); + idnode_get_s64_atomic(inb, sort->key, &s64b); + if (sort->dir == IS_ASC) + return safecmp(s64a, s64b); + else + return safecmp(s64b, s64a); + } break; + case PT_DBL: { + double dbla = 0, dblb = 0; + idnode_get_dbl(ina, sort->key, &dbla); + idnode_get_dbl(inb, sort->key, &dblb); + if (sort->dir == IS_ASC) + return safecmp(dbla, dblb); + else + return safecmp(dblb, dbla); + } break; + case PT_TIME: { + time_t ta = 0, tb = 0; + idnode_get_time(ina, sort->key, &ta); + idnode_get_time(inb, sort->key, &tb); + if (sort->dir == IS_ASC) + return safecmp(ta, tb); + else + return safecmp(tb, ta); + } break; case PT_LANGSTR: // TODO? case PT_NONE: @@ -837,22 +750,18 @@ idnode_cmp_sort return 0; } -static void -idnode_filter_init - ( idnode_t *in, idnode_filter_t *filter ) -{ - idnode_filter_ele_t *f; - const property_t *p; +static void idnode_filter_init(idnode_t* in, idnode_filter_t* filter) { + idnode_filter_ele_t* f; + const property_t* p; - LIST_FOREACH(f, filter, link) { + LIST_FOREACH (f, filter, link) { if (f->type == IF_NUM) { p = idnode_find_prop(in, f->key); if (p) { - if (p->type == PT_U32 || p->type == PT_S64 || - p->type == PT_TIME) { + if (p->type == PT_U32 || p->type == PT_S64 || p->type == PT_TIME) { int64_t v = f->u.n.n; if (INTEXTRA_IS_SPLIT(p->intextra) && p->intextra != f->u.n.intsplit) { - v = (v / MAX(1, f->u.n.intsplit)) * p->intextra; + v = (v / MAX(1, f->u.n.intsplit)) * p->intextra; f->u.n.n = v; } } @@ -862,29 +771,36 @@ idnode_filter_init } } -int -idnode_filter - ( idnode_t *in, idnode_filter_t *filter, const char *lang ) -{ - idnode_filter_ele_t *f; - - LIST_FOREACH(f, filter, link) { +int idnode_filter(idnode_t* in, idnode_filter_t* filter, const char* lang) { + idnode_filter_ele_t* f; + + LIST_FOREACH (f, filter, link) { if (!f->checked) idnode_filter_init(in, filter); if (f->type == IF_STR) { - const char *str; - char *strdisp; - int r = 1; + const char* str; + char* strdisp; + int r = 1; str = strdisp = idnode_get_display(in, idnode_find_prop(in, f->key), lang); if (!str) if (!(str = idnode_get_str(in, f->key))) return 1; - switch(f->comp) { - case IC_IN: r = strstr(str, f->u.s) == NULL; break; - case IC_EQ: r = strcmp(str, f->u.s) != 0; break; - case IC_LT: r = strcmp(str, f->u.s) > 0; break; - case IC_GT: r = strcmp(str, f->u.s) < 0; break; - case IC_RE: r = !!regexec(&f->u.re, str, 0, NULL, 0); break; + switch (f->comp) { + case IC_IN: + r = strstr(str, f->u.s) == NULL; + break; + case IC_EQ: + r = strcmp(str, f->u.s) != 0; + break; + case IC_LT: + r = strcmp(str, f->u.s) > 0; + break; + case IC_GT: + r = strcmp(str, f->u.s) < 0; + break; + case IC_RE: + r = !!regexec(&f->u.re, str, 0, NULL, 0); + break; } if (strdisp) free(strdisp); @@ -940,66 +856,55 @@ idnode_filter return 0; } -void -idnode_filter_add_str - ( idnode_filter_t *filt, const char *key, const char *val, int comp ) -{ - idnode_filter_ele_t *ele = calloc(1, sizeof(idnode_filter_ele_t)); - ele->key = strdup(key); - ele->type = IF_STR; - ele->comp = comp; +void idnode_filter_add_str(idnode_filter_t* filt, const char* key, const char* val, int comp) { + idnode_filter_ele_t* ele = calloc(1, sizeof(idnode_filter_ele_t)); + ele->key = strdup(key); + ele->type = IF_STR; + ele->comp = comp; if (comp == IC_RE) { if (regcomp(&ele->u.re, val, REG_ICASE | REG_EXTENDED | REG_NOSUB)) { free(ele); return; } } else - ele->u.s = strdup(val); + ele->u.s = strdup(val); LIST_INSERT_HEAD(filt, ele, link); } -void -idnode_filter_add_num - ( idnode_filter_t *filt, const char *key, int64_t val, int comp, int64_t intsplit ) -{ - idnode_filter_ele_t *ele = calloc(1, sizeof(idnode_filter_ele_t)); - ele->key = strdup(key); - ele->type = IF_NUM; - ele->comp = comp; - ele->u.n.n = val; - ele->u.n.intsplit = intsplit; +void idnode_filter_add_num(idnode_filter_t* filt, + const char* key, + int64_t val, + int comp, + int64_t intsplit) { + idnode_filter_ele_t* ele = calloc(1, sizeof(idnode_filter_ele_t)); + ele->key = strdup(key); + ele->type = IF_NUM; + ele->comp = comp; + ele->u.n.n = val; + ele->u.n.intsplit = intsplit; LIST_INSERT_HEAD(filt, ele, link); } -void -idnode_filter_add_dbl - ( idnode_filter_t *filt, const char *key, double dbl, int comp ) -{ - idnode_filter_ele_t *ele = calloc(1, sizeof(idnode_filter_ele_t)); - ele->key = strdup(key); - ele->type = IF_DBL; - ele->comp = comp; - ele->u.dbl = dbl; +void idnode_filter_add_dbl(idnode_filter_t* filt, const char* key, double dbl, int comp) { + idnode_filter_ele_t* ele = calloc(1, sizeof(idnode_filter_ele_t)); + ele->key = strdup(key); + ele->type = IF_DBL; + ele->comp = comp; + ele->u.dbl = dbl; LIST_INSERT_HEAD(filt, ele, link); } -void -idnode_filter_add_bool - ( idnode_filter_t *filt, const char *key, int val, int comp ) -{ - idnode_filter_ele_t *ele = calloc(1, sizeof(idnode_filter_ele_t)); - ele->key = strdup(key); - ele->type = IF_BOOL; - ele->comp = comp; - ele->u.b = val; +void idnode_filter_add_bool(idnode_filter_t* filt, const char* key, int val, int comp) { + idnode_filter_ele_t* ele = calloc(1, sizeof(idnode_filter_ele_t)); + ele->key = strdup(key); + ele->type = IF_BOOL; + ele->comp = comp; + ele->u.b = val; LIST_INSERT_HEAD(filt, ele, link); } -void -idnode_filter_clear - ( idnode_filter_t *filt ) -{ - idnode_filter_ele_t *ele; +void idnode_filter_clear(idnode_filter_t* filt) { + idnode_filter_ele_t* ele; while ((ele = LIST_FIRST(filt))) { LIST_REMOVE(ele, link); if (ele->type == IF_STR) { @@ -1013,29 +918,23 @@ idnode_filter_clear } } -void -idnode_set_alloc - ( idnode_set_t *is, size_t alloc ) -{ +void idnode_set_alloc(idnode_set_t* is, size_t alloc) { if (is->is_alloc < alloc) { is->is_alloc = alloc; is->is_array = realloc(is->is_array, alloc * sizeof(idnode_t*)); } } -void -idnode_set_add - ( idnode_set_t *is, idnode_t *in, idnode_filter_t *filt, const char *lang ) -{ +void idnode_set_add(idnode_set_t* is, idnode_t* in, idnode_filter_t* filt, const char* lang) { if (filt && idnode_filter(in, filt, lang)) return; - + /* Allocate more space */ if (is->is_alloc == is->is_count) idnode_set_alloc(is, MAX(100, is->is_alloc * 2)); if (is->is_sorted) { - size_t i; - idnode_t **a = is->is_array; + size_t i; + idnode_t** a = is->is_array; for (i = is->is_count++; i > 0 && a[i - 1] > in; i--) a[i] = a[i - 1]; a[i] = in; @@ -1044,15 +943,12 @@ idnode_set_add } } -ssize_t -idnode_set_find_index - ( idnode_set_t *is, idnode_t *in ) -{ +ssize_t idnode_set_find_index(idnode_set_t* is, idnode_t* in) { ssize_t i; if (is->is_sorted) { - idnode_t **a = is->is_array; - ssize_t first = 0, last = is->is_count - 1; + idnode_t** a = is->is_array; + ssize_t first = 0, last = is->is_count - 1; i = last / 2; while (first <= last) { if (a[i] < in) @@ -1071,57 +967,40 @@ idnode_set_find_index return -1; } -int -idnode_set_remove - ( idnode_set_t *is, idnode_t *in ) -{ +int idnode_set_remove(idnode_set_t* is, idnode_t* in) { ssize_t i = idnode_set_find_index(is, in); if (i >= 0) { if (is->is_count > 1) - memmove(&is->is_array[i], &is->is_array[i+1], - (is->is_count - i - 1) * sizeof(idnode_t *)); + memmove(&is->is_array[i], &is->is_array[i + 1], (is->is_count - i - 1) * sizeof(idnode_t*)); is->is_count--; return 1; } return 0; } -void -idnode_set_sort - ( idnode_set_t *is, idnode_sort_t *sort ) -{ +void idnode_set_sort(idnode_set_t* is, idnode_sort_t* sort) { tvh_qsort_r(is->is_array, is->is_count, sizeof(idnode_t*), idnode_cmp_sort, (void*)sort); } -void -idnode_set_sort_by_title - ( idnode_set_t *is, const char *lang ) -{ +void idnode_set_sort_by_title(idnode_set_t* is, const char* lang) { tvh_qsort_r(is->is_array, is->is_count, sizeof(idnode_t*), idnode_cmp_title, (void*)lang); } -htsmsg_t * -idnode_set_as_htsmsg - ( idnode_set_t *is ) -{ - htsmsg_t *l = htsmsg_create_list(); - int i; +htsmsg_t* idnode_set_as_htsmsg(idnode_set_t* is) { + htsmsg_t* l = htsmsg_create_list(); + int i; for (i = 0; i < is->is_count; i++) htsmsg_add_uuid(l, NULL, &is->is_array[i]->in_uuid); return l; } -void -idnode_set_clear ( idnode_set_t *is ) -{ +void idnode_set_clear(idnode_set_t* is) { free(is->is_array); is->is_array = NULL; is->is_count = is->is_alloc = 0; } -void -idnode_set_free ( idnode_set_t *is ) -{ +void idnode_set_free(idnode_set_t* is) { free(is->is_array); free(is); } @@ -1131,9 +1010,7 @@ idnode_set_free ( idnode_set_t *is ) * *************************************************************************/ static int -idnode_class_write_values - ( idnode_t *self, const idclass_t *idc, htsmsg_t *c, int optmask ) -{ +idnode_class_write_values(idnode_t* self, const idclass_t* idc, htsmsg_t* c, int optmask) { int save = 0; if (idc->ic_super) save |= idnode_class_write_values(self, idc->ic_super, c, optmask); @@ -1141,10 +1018,8 @@ idnode_class_write_values return save; } -static void -idnode_changedfn ( idnode_t *self ) -{ - const idclass_t *idc = self->in_class; +static void idnode_changedfn(idnode_t* self) { + const idclass_t* idc = self->in_class; while (idc) { if (idc->ic_changed) { idc->ic_changed(self); @@ -1154,10 +1029,8 @@ idnode_changedfn ( idnode_t *self ) } } -htsmsg_t * -idnode_savefn ( idnode_t *self, char *filename, size_t fsize ) -{ - const idclass_t *idc = self->in_class; +htsmsg_t* idnode_savefn(idnode_t* self, char* filename, size_t fsize) { + const idclass_t* idc = self->in_class; while (idc) { if (idc->ic_save) return idc->ic_save(self, filename, fsize); @@ -1166,10 +1039,8 @@ idnode_savefn ( idnode_t *self, char *filename, size_t fsize ) return NULL; } -void -idnode_loadfn ( idnode_t *self, htsmsg_t *conf ) -{ - const idclass_t *idc = self->in_class; +void idnode_loadfn(idnode_t* self, htsmsg_t* conf) { + const idclass_t* idc = self->in_class; while (idc) { if (idc->ic_load) { idc->ic_load(self, conf); @@ -1180,21 +1051,17 @@ idnode_loadfn ( idnode_t *self, htsmsg_t *conf ) idnode_load(self, conf); } -static void -idnode_save_trigger_thread_cb( void *aux ) -{ +static void idnode_save_trigger_thread_cb(void* aux) { tvh_cond_signal(&save_cond, 0); } -static void -idnode_save_queue ( idnode_t *self ) -{ - idnode_save_t *ise; +static void idnode_save_queue(idnode_t* self) { + idnode_save_t* ise; if (self->in_save) return; - ise = malloc(sizeof(*ise)); - ise->ise_node = self; + ise = malloc(sizeof(*ise)); + ise->ise_node = self; ise->ise_reqtime = mclk(); if (TAILQ_EMPTY(&idnodes_save) && atomic_get(&save_running)) mtimer_arm_rel(&save_timer, idnode_save_trigger_thread_cb, NULL, IDNODE_SAVE_DELAY); @@ -1202,11 +1069,9 @@ idnode_save_queue ( idnode_t *self ) self->in_save = ise; } -void -idnode_save_check ( idnode_t *self, int weak ) -{ - char filename[PATH_MAX]; - htsmsg_t *m; +void idnode_save_check(idnode_t* self, int weak) { + char filename[PATH_MAX]; + htsmsg_t* m; if (self->in_save == NULL || self->in_save == SAVEPTR_OUTOFSERVICE) return; @@ -1225,12 +1090,10 @@ idnode_save_check ( idnode_t *self, int weak ) } } -int -idnode_write0 ( idnode_t *self, htsmsg_t *c, int optmask, int dosave ) -{ - int save = 0; - const idclass_t *idc = self->in_class; - save = idnode_class_write_values(self, idc, c, optmask); +int idnode_write0(idnode_t* self, htsmsg_t* c, int optmask, int dosave) { + int save = 0; + const idclass_t* idc = self->in_class; + save = idnode_class_write_values(self, idc, c, optmask); if ((idc->ic_flags & IDCLASS_ALWAYS_SAVE) != 0 || (save && dosave)) { idnode_changedfn(self); idnode_save_queue(self); @@ -1245,9 +1108,7 @@ idnode_write0 ( idnode_t *self, htsmsg_t *c, int optmask, int dosave ) return save; } -void -idnode_changed( idnode_t *self ) -{ +void idnode_changed(idnode_t* self) { idnode_notify_changed(self); idnode_changedfn(self); idnode_save_queue(self); @@ -1257,11 +1118,8 @@ idnode_changed( idnode_t *self ) * Read * *************************************************************************/ -void -idnode_read0 ( idnode_t *self, htsmsg_t *c, htsmsg_t *list, - int optmask, const char *lang ) -{ - const idclass_t *idc = self->in_class; +void idnode_read0(idnode_t* self, htsmsg_t* c, htsmsg_t* list, int optmask, const char* lang) { + const idclass_t* idc = self->in_class; for (; idc; idc = idc->ic_super) prop_read_values(self, idc->ic_properties, c, list, optmask, lang); } @@ -1269,16 +1127,17 @@ idnode_read0 ( idnode_t *self, htsmsg_t *c, htsmsg_t *list, /** * Recursive to get superclass nodes first */ -static void -add_params - (struct idnode *self, const idclass_t *ic, htsmsg_t *p, htsmsg_t *list, - int optmask, const char *lang) -{ +static void add_params(struct idnode* self, + const idclass_t* ic, + htsmsg_t* p, + htsmsg_t* list, + int optmask, + const char* lang) { /* Parent first */ - if(ic->ic_super != NULL) + if (ic->ic_super != NULL) add_params(self, ic->ic_super, p, list, optmask, lang); - /* Seperator (if not empty) */ + /* Seperator (if not empty) */ #if 0 if(TAILQ_FIRST(&p->hm_fields) != NULL) { htsmsg_t *m = htsmsg_create_map(); @@ -1292,19 +1151,14 @@ add_params prop_serialize(self, ic->ic_properties, p, list, optmask, lang); } -static htsmsg_t * -idnode_params - (const idclass_t *idc, idnode_t *self, htsmsg_t *list, - int optmask, const char *lang) -{ - htsmsg_t *p = htsmsg_create_list(); +static htsmsg_t* +idnode_params(const idclass_t* idc, idnode_t* self, htsmsg_t* list, int optmask, const char* lang) { + htsmsg_t* p = htsmsg_create_list(); add_params(self, idc, p, list, optmask, lang); return p; } -const char * -idclass_get_caption (const idclass_t *idc, const char *lang) -{ +const char* idclass_get_caption(const idclass_t* idc, const char* lang) { while (idc) { if (idc->ic_caption) return tvh_gettext_lang(lang, idc->ic_caption); @@ -1313,9 +1167,7 @@ idclass_get_caption (const idclass_t *idc, const char *lang) return NULL; } -static const char * -idclass_get_class (const idclass_t *idc) -{ +static const char* idclass_get_class(const idclass_t* idc) { while (idc) { if (idc->ic_class) return idc->ic_class; @@ -1324,9 +1176,7 @@ idclass_get_class (const idclass_t *idc) return NULL; } -static const char * -idclass_get_event (const idclass_t *idc) -{ +static const char* idclass_get_event(const idclass_t* idc) { while (idc) { if (idc->ic_event) return idc->ic_event; @@ -1335,9 +1185,7 @@ idclass_get_event (const idclass_t *idc) return NULL; } -static const char * -idclass_get_order (const idclass_t *idc) -{ +static const char* idclass_get_order(const idclass_t* idc) { while (idc) { if (idc->ic_order) return idc->ic_order; @@ -1346,9 +1194,7 @@ idclass_get_order (const idclass_t *idc) return NULL; } -const char ** -idclass_get_doc (const idclass_t *idc) -{ +const char** idclass_get_doc(const idclass_t* idc) { while (idc) { if (idc->ic_doc) return idc->ic_doc; @@ -1357,20 +1203,18 @@ idclass_get_doc (const idclass_t *idc) return NULL; } -static htsmsg_t * -idclass_get_property_groups (const idclass_t *idc, const char *lang) -{ - const property_group_t *g; - htsmsg_t *e, *m; - int count; +static htsmsg_t* idclass_get_property_groups(const idclass_t* idc, const char* lang) { + const property_group_t* g; + htsmsg_t * e, *m; + int count; while (idc) { if (idc->ic_groups) { - m = htsmsg_create_list(); + m = htsmsg_create_list(); count = 0; for (g = idc->ic_groups; g->number && g->name; g++) { e = htsmsg_create_map(); htsmsg_add_u32(e, "number", g->number); - htsmsg_add_str(e, "name", tvh_gettext_lang(lang, g->name)); + htsmsg_add_str(e, "name", tvh_gettext_lang(lang, g->name)); if (g->parent) htsmsg_add_u32(e, "parent", g->parent); if (g->column) @@ -1388,36 +1232,31 @@ idclass_get_property_groups (const idclass_t *idc, const char *lang) return NULL; } -static idnodes_rb_t * -idclass_find_domain(const idclass_t *idc) -{ - idclass_link_t *r; +static idnodes_rb_t* idclass_find_domain(const idclass_t* idc) { + idclass_link_t* r; idc = idnode_root_class(idc); SKEL_ALLOC(idclasses_skel); idclasses_skel->idc = idc; - r = RB_FIND(&idrootclasses, idclasses_skel, link, ic_cmp); + r = RB_FIND(&idrootclasses, idclasses_skel, link, ic_cmp); if (r) return &r->nodes; return NULL; } -static void -idclass_root_register(const idclass_t *idc) -{ - idclass_link_t *r; +static void idclass_root_register(const idclass_t* idc) { + idclass_link_t* r; SKEL_ALLOC(idclasses_skel); idclasses_skel->idc = idc; - r = RB_INSERT_SORTED(&idrootclasses, idclasses_skel, link, ic_cmp); - if (r) return; + r = RB_INSERT_SORTED(&idrootclasses, idclasses_skel, link, ic_cmp); + if (r) + return; RB_INIT(&idclasses_skel->nodes); SKEL_USED(idclasses_skel); tvhtrace(LS_IDNODE, "register root class %s", idc->ic_class); } -void -idclass_register(const idclass_t *idc) -{ - const idclass_t *prev = NULL; +void idclass_register(const idclass_t* idc) { + const idclass_t* prev = NULL; while (idc) { SKEL_ALLOC(idclasses_skel); idclasses_skel->idc = idc; @@ -1429,67 +1268,61 @@ idclass_register(const idclass_t *idc) SKEL_USED(idclasses_skel); tvhtrace(LS_IDNODE, "register class %s", idc->ic_class); prev = idc; - idc = idc->ic_super; + idc = idc->ic_super; } if (prev) idclass_root_register(prev); } -const idclass_t * -idclass_find ( const char *class ) -{ +const idclass_t* idclass_find(const char* class) { idclass_link_t *t, skel; - idclass_t idc; - skel.idc = &idc; + idclass_t idc; + skel.idc = &idc; idc.ic_class = class; tvhtrace(LS_IDNODE, "find class %s", class); t = RB_FIND(&idclasses, &skel, link, ic_cmp); return t ? t->idc : NULL; } -idclass_t const ** -idclass_find_all(void) -{ - idclass_link_t *l; - idclass_t const **ret; - int i = 0, count = 0; - RB_FOREACH(l, &idclasses, link) +idclass_t const** idclass_find_all(void) { + idclass_link_t* l; + idclass_t const** ret; + int i = 0, count = 0; + RB_FOREACH (l, &idclasses, link) count++; if (count == 0) return NULL; - ret = calloc(count + 1, sizeof(idclass_t *)); - RB_FOREACH(l, &idclasses, link) + ret = calloc(count + 1, sizeof(idclass_t*)); + RB_FOREACH (l, &idclasses, link) ret[i++] = l->idc; ret[i] = NULL; return ret; } -idclass_t const ** -idclass_find_children(const char *clazz) -{ - const idclass_t *ic = idclass_find(clazz), *root; - idclass_link_t *l; - idclass_t const **ret; - int i, count; +idclass_t const** idclass_find_children(const char* clazz) { + const idclass_t * ic = idclass_find(clazz), *root; + idclass_link_t* l; + idclass_t const** ret; + int i, count; if (ic == NULL) return NULL; root = idnode_root_class(ic); if (root == NULL) return NULL; - ret = NULL; + ret = NULL; count = i = 0; - RB_FOREACH(l, &idclasses, link) { + RB_FOREACH (l, &idclasses, link) { if (root == idnode_root_class(l->idc)) { if (i <= count) { count += 50; - ret = realloc(ret, count * sizeof(const idclass_t *)); + ret = realloc(ret, count * sizeof(const idclass_t*)); } ret[i++] = ic; } } if (i <= count) - ret = realloc(ret, (count + 1) * sizeof(const idclass_t *)); + ret = realloc(ret, (count + 1) * sizeof(const idclass_t*)); ret[i] = NULL; return ret; } @@ -1497,11 +1330,9 @@ idclass_find_children(const char *clazz) /* * Just get the class definition */ -htsmsg_t * -idclass_serialize0(const idclass_t *idc, htsmsg_t *list, int optmask, const char *lang) -{ - const char *s; - htsmsg_t *p, *m = htsmsg_create_map(); +htsmsg_t* idclass_serialize0(const idclass_t* idc, htsmsg_t* list, int optmask, const char* lang) { + const char* s; + htsmsg_t * p, *m = htsmsg_create_map(); /* Caption and name */ if ((s = idclass_get_caption(idc, lang))) @@ -1518,24 +1349,22 @@ idclass_serialize0(const idclass_t *idc, htsmsg_t *list, int optmask, const char /* Props */ if ((p = idnode_params(idc, NULL, list, optmask, lang))) htsmsg_add_msg(m, "props", p); - + return m; } /** * */ -htsmsg_t * -idnode_serialize0(idnode_t *self, htsmsg_t *list, int optmask, const char *lang) -{ - const idclass_t *idc = self->in_class; - const char *s; - char buf[384]; - - htsmsg_t *m = htsmsg_create_map(); +htsmsg_t* idnode_serialize0(idnode_t* self, htsmsg_t* list, int optmask, const char* lang) { + const idclass_t* idc = self->in_class; + const char* s; + char buf[384]; + + htsmsg_t* m = htsmsg_create_map(); if (!idc->ic_snode) { htsmsg_add_uuid(m, "uuid", &self->in_uuid); - htsmsg_add_uuid(m, "id", &self->in_uuid); + htsmsg_add_uuid(m, "id", &self->in_uuid); } htsmsg_add_str(m, "text", idnode_get_title(self, lang, buf, sizeof(buf)) ?: ""); if ((s = idclass_get_caption(idc, lang))) @@ -1554,9 +1383,7 @@ idnode_serialize0(idnode_t *self, htsmsg_t *list, int optmask, const char *lang) * Simple list helpers * *************************************************************************/ -htsmsg_t * -idnode_slist_enum ( idnode_t *in, idnode_slist_t *options, const char *lang ) -{ +htsmsg_t* idnode_slist_enum(idnode_t* in, idnode_slist_t* options, const char* lang) { htsmsg_t *l = htsmsg_create_list(), *m; for (; options->id; options++) { @@ -1566,17 +1393,15 @@ idnode_slist_enum ( idnode_t *in, idnode_slist_t *options, const char *lang ) return l; } -htsmsg_t * -idnode_slist_get ( idnode_t *in, idnode_slist_t *options ) -{ - htsmsg_t *l = htsmsg_create_list(); - int val; +htsmsg_t* idnode_slist_get(idnode_t* in, idnode_slist_t* options) { + htsmsg_t* l = htsmsg_create_list(); + int val; for (; options->id; options++) { if (options->get) val = options->get(in, options); else if (options->off) - val = *(int *)((void *)in + options->off); + val = *(int*)((void*)in + options->off); else val = 0; if (val) @@ -1585,17 +1410,15 @@ idnode_slist_get ( idnode_t *in, idnode_slist_t *options ) return l; } -int -idnode_slist_set ( idnode_t *in, idnode_slist_t *options, const htsmsg_t *vals ) -{ - idnode_slist_t *o; - htsmsg_field_t *f; - int *ip, changed = 0; - const char *s; +int idnode_slist_set(idnode_t* in, idnode_slist_t* options, const htsmsg_t* vals) { + idnode_slist_t* o; + htsmsg_field_t* f; + int * ip, changed = 0; + const char* s; for (o = options; o->id; o++) { if (o->off) { - ip = (void *)in + o->off; + ip = (void*)in + o->off; } else { ip = NULL; } @@ -1615,7 +1438,7 @@ idnode_slist_set ( idnode_t *in, idnode_slist_t *options, const htsmsg_t *vals ) if (o->set) { changed |= o->set(in, o, 0); } else if (*ip) { - *ip = 0; + *ip = 0; changed = 1; } } @@ -1623,18 +1446,20 @@ idnode_slist_set ( idnode_t *in, idnode_slist_t *options, const htsmsg_t *vals ) return changed; } -char * -idnode_slist_rend ( idnode_t *in, idnode_slist_t *options, const char *lang ) -{ - int *ip; +char* idnode_slist_rend(idnode_t* in, idnode_slist_t* options, const char* lang) { + int* ip; size_t l = 0; prop_sbuf[0] = '\0'; for (; options->id; options++) { - ip = (void *)in + options->off; + ip = (void*)in + options->off; if (*ip) - tvh_strlcatf(prop_sbuf, PROP_SBUF_LEN, l, "%s%s", prop_sbuf[0] ? "," : "", - tvh_gettext_lang(lang, options->name)); + tvh_strlcatf(prop_sbuf, + PROP_SBUF_LEN, + l, + "%s%s", + prop_sbuf[0] ? "," : "", + tvh_gettext_lang(lang, options->name)); } return strdup(prop_sbuf); } @@ -1643,9 +1468,7 @@ idnode_slist_rend ( idnode_t *in, idnode_slist_t *options, const char *lang ) * List helpers * *************************************************************************/ -static void -idnode_list_notify ( idnode_list_mapping_t *ilm, void *origin ) -{ +static void idnode_list_notify(idnode_list_mapping_t* ilm, void* origin) { if (origin == NULL) return; if (origin == ilm->ilm_in1) { @@ -1663,27 +1486,28 @@ idnode_list_notify ( idnode_list_mapping_t *ilm, void *origin ) /* * Link class1 and class2 */ -idnode_list_mapping_t * -idnode_list_link ( idnode_t *in1, idnode_list_head_t *in1_list, - idnode_t *in2, idnode_list_head_t *in2_list, - void *origin, uint32_t savemask ) -{ - idnode_list_mapping_t *ilm; +idnode_list_mapping_t* idnode_list_link(idnode_t* in1, + idnode_list_head_t* in1_list, + idnode_t* in2, + idnode_list_head_t* in2_list, + void* origin, + uint32_t savemask) { + idnode_list_mapping_t* ilm; /* Already linked */ - LIST_FOREACH(ilm, in1_list, ilm_in1_link) + LIST_FOREACH (ilm, in1_list, ilm_in1_link) if (ilm->ilm_in2 == in2) { ilm->ilm_mark = 0; return NULL; } - LIST_FOREACH(ilm, in2_list, ilm_in2_link) + LIST_FOREACH (ilm, in2_list, ilm_in2_link) if (ilm->ilm_in1 == in1) { ilm->ilm_mark = 0; return NULL; } /* Link */ - ilm = calloc(1, sizeof(idnode_list_mapping_t)); + ilm = calloc(1, sizeof(idnode_list_mapping_t)); ilm->ilm_in1 = in1; ilm->ilm_in2 = in2; LIST_INSERT_HEAD(in1_list, ilm, ilm_in1_link); @@ -1694,29 +1518,22 @@ idnode_list_link ( idnode_t *in1, idnode_list_head_t *in1_list, return ilm; } -void -idnode_list_unlink ( idnode_list_mapping_t *ilm, void *origin ) -{ +void idnode_list_unlink(idnode_list_mapping_t* ilm, void* origin) { LIST_REMOVE(ilm, ilm_in1_link); LIST_REMOVE(ilm, ilm_in2_link); idnode_list_notify(ilm, origin); free(ilm); } -void -idnode_list_destroy(idnode_list_head_t *ilh, void *origin) -{ - idnode_list_mapping_t *ilm; +void idnode_list_destroy(idnode_list_head_t* ilh, void* origin) { + idnode_list_mapping_t* ilm; while ((ilm = LIST_FIRST(ilh)) != NULL) idnode_list_unlink(ilm, origin); } -static int -idnode_list_clean1 - ( idnode_t *in1, idnode_list_head_t *in1_list ) -{ - int save = 0; +static int idnode_list_clean1(idnode_t* in1, idnode_list_head_t* in1_list) { + int save = 0; idnode_list_mapping_t *ilm, *n; for (ilm = LIST_FIRST(in1_list); ilm != NULL; ilm = n) { @@ -1729,11 +1546,8 @@ idnode_list_clean1 return save; } -static int -idnode_list_clean2 - ( idnode_t *in2, idnode_list_head_t *in2_list ) -{ - int save = 0; +static int idnode_list_clean2(idnode_t* in2, idnode_list_head_t* in2_list) { + int save = 0; idnode_list_mapping_t *ilm, *n; for (ilm = LIST_FIRST(in2_list); ilm != NULL; ilm = n) { @@ -1746,40 +1560,31 @@ idnode_list_clean2 return save; } -htsmsg_t * -idnode_list_get1 - ( idnode_list_head_t *in1_list ) -{ - idnode_list_mapping_t *ilm; - htsmsg_t *l = htsmsg_create_list(); +htsmsg_t* idnode_list_get1(idnode_list_head_t* in1_list) { + idnode_list_mapping_t* ilm; + htsmsg_t* l = htsmsg_create_list(); - LIST_FOREACH(ilm, in1_list, ilm_in1_link) + LIST_FOREACH (ilm, in1_list, ilm_in1_link) htsmsg_add_uuid(l, NULL, &ilm->ilm_in2->in_uuid); return l; } -htsmsg_t * -idnode_list_get2 - ( idnode_list_head_t *in2_list ) -{ - idnode_list_mapping_t *ilm; - htsmsg_t *l = htsmsg_create_list(); +htsmsg_t* idnode_list_get2(idnode_list_head_t* in2_list) { + idnode_list_mapping_t* ilm; + htsmsg_t* l = htsmsg_create_list(); - LIST_FOREACH(ilm, in2_list, ilm_in2_link) + LIST_FOREACH (ilm, in2_list, ilm_in2_link) htsmsg_add_uuid(l, NULL, &ilm->ilm_in1->in_uuid); return l; } -char * -idnode_list_get_csv1 - ( idnode_list_head_t *in1_list, const char *lang ) -{ - char *str; - idnode_list_mapping_t *ilm; - htsmsg_t *l = htsmsg_create_list(); - char buf[384]; +char* idnode_list_get_csv1(idnode_list_head_t* in1_list, const char* lang) { + char* str; + idnode_list_mapping_t* ilm; + htsmsg_t* l = htsmsg_create_list(); + char buf[384]; - LIST_FOREACH(ilm, in1_list, ilm_in1_link) + LIST_FOREACH (ilm, in1_list, ilm_in1_link) htsmsg_add_str(l, NULL, idnode_get_title(ilm->ilm_in2, lang, buf, sizeof(buf))); str = htsmsg_list_2_csv(l, ',', 1); @@ -1787,16 +1592,13 @@ idnode_list_get_csv1 return str; } -char * -idnode_list_get_csv2 - ( idnode_list_head_t *in2_list, const char *lang ) -{ - char *str; - idnode_list_mapping_t *ilm; - htsmsg_t *l = htsmsg_create_list(); - char buf[384]; +char* idnode_list_get_csv2(idnode_list_head_t* in2_list, const char* lang) { + char* str; + idnode_list_mapping_t* ilm; + htsmsg_t* l = htsmsg_create_list(); + char buf[384]; - LIST_FOREACH(ilm, in2_list, ilm_in2_link) + LIST_FOREACH (ilm, in2_list, ilm_in2_link) htsmsg_add_str(l, NULL, idnode_get_title(ilm->ilm_in1, lang, buf, sizeof(buf))); str = htsmsg_list_2_csv(l, ',', 1); @@ -1804,28 +1606,27 @@ idnode_list_get_csv2 return str; } -int -idnode_list_set1 - ( idnode_t *in1, idnode_list_head_t *in1_list, - const idclass_t *in2_class, htsmsg_t *in2_list, - int (*in2_create)(idnode_t *in1, idnode_t *in2, void *origin) ) -{ - const char *str; - htsmsg_field_t *f; - idnode_t *in2; - idnode_list_mapping_t *ilm; - int save = 0; +int idnode_list_set1(idnode_t* in1, + idnode_list_head_t* in1_list, + const idclass_t* in2_class, + htsmsg_t* in2_list, + int (*in2_create)(idnode_t* in1, idnode_t* in2, void* origin)) { + const char* str; + htsmsg_field_t* f; + idnode_t* in2; + idnode_list_mapping_t* ilm; + int save = 0; /* Mark all for deletion */ - LIST_FOREACH(ilm, in1_list, ilm_in1_link) + LIST_FOREACH (ilm, in1_list, ilm_in1_link) ilm->ilm_mark = 1; /* Make new links */ HTSMSG_FOREACH(f, in2_list) - if ((str = htsmsg_field_get_str(f))) - if ((in2 = idnode_find(str, in2_class, NULL)) != NULL) - if (in2_create(in1, in2, in1)) - save = 1; + if ((str = htsmsg_field_get_str(f))) + if ((in2 = idnode_find(str, in2_class, NULL)) != NULL) + if (in2_create(in1, in2, in1)) + save = 1; /* Delete unlinked */ if (idnode_list_clean1(in1, in1_list)) @@ -1843,28 +1644,27 @@ idnode_list_set1 return save; } -int -idnode_list_set2 - ( idnode_t *in2, idnode_list_head_t *in2_list, - const idclass_t *in1_class, htsmsg_t *in1_list, - int (*in1_create)(idnode_t *in1, idnode_t *in2, void *origin) ) -{ - const char *str; - htsmsg_field_t *f; - idnode_t *in1; - idnode_list_mapping_t *ilm; - int save = 0; +int idnode_list_set2(idnode_t* in2, + idnode_list_head_t* in2_list, + const idclass_t* in1_class, + htsmsg_t* in1_list, + int (*in1_create)(idnode_t* in1, idnode_t* in2, void* origin)) { + const char* str; + htsmsg_field_t* f; + idnode_t* in1; + idnode_list_mapping_t* ilm; + int save = 0; /* Mark all for deletion */ - LIST_FOREACH(ilm, in2_list, ilm_in2_link) + LIST_FOREACH (ilm, in2_list, ilm_in2_link) ilm->ilm_mark = 1; /* Make new links */ HTSMSG_FOREACH(f, in1_list) - if ((str = htsmsg_field_get_str(f))) - if ((in1 = idnode_find(str, in1_class, NULL)) != NULL) - if (in1_create(in1, in2, in2)) - save = 1; + if ((str = htsmsg_field_get_str(f))) + if ((in1 = idnode_find(str, in1_class, NULL)) != NULL) + if (in1_create(in1, in2, in2)) + save = 1; /* Delete unlinked */ if (idnode_list_clean2(in2, in2_list)) @@ -1882,7 +1682,6 @@ idnode_list_set2 return save; } - /* ************************************************************************** * Notification * *************************************************************************/ @@ -1890,12 +1689,10 @@ idnode_list_set2 /** * Notify about a change */ -void -idnode_notify ( idnode_t *in, const char *action ) -{ - const idclass_t *ic = in->in_class; - char ubuf[UUID_HEX_SIZE]; - const char *uuid = idnode_uuid_as_str(in, ubuf); +void idnode_notify(idnode_t* in, const char* action) { + const idclass_t* ic = in->in_class; + char ubuf[UUID_HEX_SIZE]; + const char* uuid = idnode_uuid_as_str(in, ubuf); if (!tvheadend_is_running()) return; @@ -1911,24 +1708,18 @@ idnode_notify ( idnode_t *in, const char *action ) } } -void -idnode_notify_changed (void *in) -{ +void idnode_notify_changed(void* in) { idnode_notify(in, "change"); } -void -idnode_notify_title_changed (void *in) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_uuid(m, "uuid", &((idnode_t *)in)->in_uuid); +void idnode_notify_title_changed(void* in) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_uuid(m, "uuid", &((idnode_t*)in)->in_uuid); notify_by_msg("title", m, 0, NOTIFY_REWRITE_TITLE); idnode_notify_changed(in); } -void -idnode_notify_title_changed_lang (void *in, const char *lang) -{ +void idnode_notify_title_changed_lang(void* in, const char* lang) { return idnode_notify_title_changed(in); } @@ -1936,17 +1727,15 @@ idnode_notify_title_changed_lang (void *in, const char *lang) * Save thread * *************************************************************************/ -static void * -save_thread ( void *aux ) -{ - idnode_save_t *ise; - idnode_t *in; - htsmsg_t *m; - uint32_t u32; - tvh_uuid_t *uuid; - char filename[PATH_MAX]; +static void* save_thread(void* aux) { + idnode_save_t* ise; + idnode_t* in; + htsmsg_t* m; + uint32_t u32; + tvh_uuid_t* uuid; + char filename[PATH_MAX]; tvh_uuid_set_t set, tset; - int lnotify; + int lnotify; uuid_set_init(&set, 10); uuid_set_init(&tset, 10); @@ -1959,19 +1748,20 @@ save_thread ( void *aux ) if ((ise = TAILQ_FIRST(&idnodes_save)) == NULL || ise->ise_reqtime + IDNODE_SAVE_DELAY > mclk()) { tvh_mutex_lock(&idnode_lnotify_mutex); - lnotify = !uuid_set_empty(&idnode_lnotify_set) || - !uuid_set_empty(&idnode_lnotify_title_set); + lnotify = !uuid_set_empty(&idnode_lnotify_set) || !uuid_set_empty(&idnode_lnotify_title_set); tvh_mutex_unlock(&idnode_lnotify_mutex); if (lnotify) goto lnotifygo; if (ise) - mtimer_arm_abs(&save_timer, idnode_save_trigger_thread_cb, NULL, - ise->ise_reqtime + IDNODE_SAVE_DELAY); + mtimer_arm_abs(&save_timer, + idnode_save_trigger_thread_cb, + NULL, + ise->ise_reqtime + IDNODE_SAVE_DELAY); tvh_cond_wait(&save_cond, &global_lock); continue; } if (ise) { - m = idnode_savefn(ise->ise_node, filename, sizeof(filename)); + m = idnode_savefn(ise->ise_node, filename, sizeof(filename)); ise->ise_node->in_save = NULL; TAILQ_REMOVE(&idnodes_save, ise, ise_link); tvh_mutex_unlock(&global_lock); @@ -1982,7 +1772,7 @@ save_thread ( void *aux ) } tvh_mutex_lock(&global_lock); } -lnotifygo: + lnotifygo: tvh_mutex_lock(&idnode_lnotify_mutex); if (!uuid_set_empty(&idnode_lnotify_set)) { set = idnode_lnotify_set; @@ -1997,7 +1787,7 @@ lnotifygo: UUID_SET_FOREACH(uuid, &set, u32) { in = idnode_find0(uuid, NULL, NULL); if (in) - idnode_notify_changed(in); + idnode_notify_changed(in); } uuid_set_free(&set); } @@ -2014,7 +1804,7 @@ lnotifygo: mtimer_disarm(&save_timer); while ((ise = TAILQ_FIRST(&idnodes_save)) != NULL) { - m = idnode_savefn(ise->ise_node, filename, sizeof(filename)); + m = idnode_savefn(ise->ise_node, filename, sizeof(filename)); ise->ise_node->in_save = NULL; TAILQ_REMOVE(&idnodes_save, ise, ise_link); tvh_mutex_unlock(&global_lock); @@ -2034,18 +1824,16 @@ lnotifygo: * Light update - outside global lock * *************************************************************************/ -void idnode_lnotify_changed( void *in ) -{ +void idnode_lnotify_changed(void* in) { tvh_mutex_lock(&idnode_lnotify_mutex); - uuid_set_add(&idnode_lnotify_set, &((idnode_t *)in)->in_uuid); + uuid_set_add(&idnode_lnotify_set, &((idnode_t*)in)->in_uuid); tvh_mutex_unlock(&idnode_lnotify_mutex); tvh_cond_signal(&save_cond, 0); } -void idnode_lnotify_title_changed( void *in ) -{ +void idnode_lnotify_title_changed(void* in) { tvh_mutex_lock(&idnode_lnotify_mutex); - uuid_set_add(&idnode_lnotify_title_set, &((idnode_t *)in)->in_uuid); + uuid_set_add(&idnode_lnotify_title_set, &((idnode_t*)in)->in_uuid); tvh_mutex_unlock(&idnode_lnotify_mutex); tvh_cond_signal(&save_cond, 0); } @@ -2054,9 +1842,7 @@ void idnode_lnotify_title_changed( void *in ) * Initialization * *************************************************************************/ -void -idnode_boot(void) -{ +void idnode_boot(void) { tvh_mutex_init(&idnode_mutex, NULL); RB_INIT(&idnodes); RB_INIT(&idclasses); @@ -2067,17 +1853,13 @@ idnode_boot(void) uuid_set_init(&idnode_lnotify_title_set, 10); } -void -idnode_init(void) -{ +void idnode_init(void) { atomic_set(&save_running, 1); tvh_thread_create(&save_tid, NULL, save_thread, NULL, "save"); } -void -idnode_done(void) -{ - idclass_link_t *il; +void idnode_done(void) { + idclass_link_t* il; tvh_mutex_lock(&global_lock); atomic_set(&save_running, 0); diff --git a/src/idnode.h b/src/idnode.h index 1224db7e7..4b094f5a7 100644 --- a/src/idnode.h +++ b/src/idnode.h @@ -27,19 +27,18 @@ #include struct access; -typedef struct idnode idnode_t; +typedef struct idnode idnode_t; typedef struct idnode_save idnode_save_t; #define IDNODE_SAVE_DELAY (3 * MONOCLOCK_RESOLUTION) -#define SAVEPTR_OUTOFSERVICE ((void *)((intptr_t)-1LL)) +#define SAVEPTR_OUTOFSERVICE ((void*)((intptr_t) - 1LL)) /* * Node set */ -typedef struct idnode_set -{ - idnode_t **is_array; ///< Array of nodes +typedef struct idnode_set { + idnode_t** is_array; ///< Array of nodes size_t is_alloc; ///< Size of is_array size_t is_count; ///< Current usage of is_array uint8_t is_sorted; ///< Sorted array of nodes @@ -48,9 +47,8 @@ typedef struct idnode_set /* * Property groups */ -typedef struct property_group -{ - const char *name; +typedef struct property_group { + const char* name; uint32_t number; uint32_t parent; uint32_t column; @@ -59,59 +57,58 @@ typedef struct property_group /* * Class definition */ -#define IDCLASS_ALWAYS_SAVE (1<<0) ///< Always call the save callback +#define IDCLASS_ALWAYS_SAVE (1 << 0) ///< Always call the save callback -#define CLASS_DOC(name) extern const char *tvh_doc_##name##_class[]; +#define CLASS_DOC(name) extern const char* tvh_doc_##name##_class[]; typedef struct idclass idclass_t; struct idclass { - const struct idclass *ic_super; ///< Parent class - const char *ic_class; ///< Class name - const char *ic_caption; ///< Class description - const char *ic_order; ///< Property order (comma-separated) - const char **ic_doc; ///< NULL terminated array of strings - const property_group_t *ic_groups; ///< Groups for visual representation - const property_t *ic_properties; ///< Property list - const char *ic_event; ///< Events to fire on add/delete/title - uint32_t ic_perm_def; ///< Default permissions - uint32_t ic_flags; ///< Extra flags - idnode_t *ic_snode; ///< Simple node + const struct idclass* ic_super; ///< Parent class + const char* ic_class; ///< Class name + const char* ic_caption; ///< Class description + const char* ic_order; ///< Property order (comma-separated) + const char** ic_doc; ///< NULL terminated array of strings + const property_group_t* ic_groups; ///< Groups for visual representation + const property_t* ic_properties; ///< Property list + const char* ic_event; ///< Events to fire on add/delete/title + uint32_t ic_perm_def; ///< Default permissions + uint32_t ic_flags; ///< Extra flags + idnode_t* ic_snode; ///< Simple node /* Callbacks */ - idnode_set_t *(*ic_get_childs) (idnode_t *self); - void (*ic_get_title) (idnode_t *self, const char *lang, char *dst, size_t dstsize); - void (*ic_changed) (idnode_t *self); - htsmsg_t *(*ic_save) (idnode_t *self, char *filename, size_t fsize); - void (*ic_load) (idnode_t *self, htsmsg_t *conf); - void (*ic_delete) (idnode_t *self); - void (*ic_moveup) (idnode_t *self); - void (*ic_movedown) (idnode_t *self); - int (*ic_perm) (idnode_t *self, struct access *a, htsmsg_t *msg_to_write); + idnode_set_t* (*ic_get_childs)(idnode_t* self); + void (*ic_get_title)(idnode_t* self, const char* lang, char* dst, size_t dstsize); + void (*ic_changed)(idnode_t* self); + htsmsg_t* (*ic_save)(idnode_t* self, char* filename, size_t fsize); + void (*ic_load)(idnode_t* self, htsmsg_t* conf); + void (*ic_delete)(idnode_t* self); + void (*ic_moveup)(idnode_t* self); + void (*ic_movedown)(idnode_t* self); + int (*ic_perm)(idnode_t* self, struct access* a, htsmsg_t* msg_to_write); }; - typedef RB_HEAD(, idnode) idnodes_rb_t; /* * Node definition */ struct idnode { - tvh_uuid_t in_uuid; ///< Unique ID - RB_ENTRY(idnode) in_link; ///< Global hash - RB_ENTRY(idnode) in_domain_link; ///< Root class link (domain) - idnodes_rb_t *in_domain; ///< Domain nodes - const idclass_t *in_class; ///< Class definition - struct access *in_access; ///< Actual permissions - idnode_save_t *in_save; ///< Pointer to the save link + tvh_uuid_t in_uuid; ///< Unique ID + RB_ENTRY(idnode) in_link; ///< Global hash + RB_ENTRY(idnode) in_domain_link; ///< Root class link (domain) + idnodes_rb_t* in_domain; ///< Domain nodes + const idclass_t* in_class; ///< Class definition + struct access* in_access; ///< Actual permissions + idnode_save_t* in_save; ///< Pointer to the save link }; /* * Node save list */ struct idnode_save { - TAILQ_ENTRY(idnode_save) ise_link; ///< List chain - idnode_t *ise_node; ///< Node owning this - int64_t ise_reqtime; ///< First request + TAILQ_ENTRY(idnode_save) ise_link; ///< List chain + idnode_t* ise_node; ///< Node owning this + int64_t ise_reqtime; ///< First request }; /* @@ -119,12 +116,12 @@ struct idnode_save { */ typedef struct idnode_slist idnode_slist_t; struct idnode_slist { - const char *id; - const char *name; - size_t off; - - int (*set)(void *self, idnode_slist_t *entry, int val); - int (*get)(void *self, idnode_slist_t *entry); + const char* id; + const char* name; + size_t off; + + int (*set)(void* self, idnode_slist_t* entry, int val); + int (*get)(void* self, idnode_slist_t* entry); }; /* @@ -133,15 +130,15 @@ struct idnode_slist { struct idnode_list_mapping; typedef struct idnode_list_head { - struct idnode_list_mapping *lh_first; + struct idnode_list_mapping* lh_first; } idnode_list_head_t; typedef struct idnode_list_mapping { LIST_ENTRY(idnode_list_mapping) ilm_in1_link; LIST_ENTRY(idnode_list_mapping) ilm_in2_link; - idnode_t *ilm_in1; - idnode_t *ilm_in2; + idnode_t* ilm_in1; + idnode_t* ilm_in2; uint8_t ilm_in1_save; uint8_t ilm_in2_save; @@ -152,183 +149,178 @@ typedef struct idnode_list_mapping { * Sorting definition */ typedef struct idnode_sort { - const char *lang; ///< Language (UI) - const char *key; ///< Sort key - enum { - IS_ASC, - IS_DSC - } dir; ///< Sort direction + const char* lang; ///< Language (UI) + const char* key; ///< Sort key + enum { IS_ASC, IS_DSC } dir; ///< Sort direction } idnode_sort_t; /* * Filter definition */ -typedef struct idnode_filter_ele -{ +typedef struct idnode_filter_ele { LIST_ENTRY(idnode_filter_ele) link; ///< List link - int checked; - char *key; ///< Filter key - enum { - IF_STR, - IF_NUM, - IF_DBL, - IF_BOOL - } type; ///< Filter type + int checked; + char* key; ///< Filter key + enum { IF_STR, IF_NUM, IF_DBL, IF_BOOL } type; ///< Filter type union { - int b; - char *s; + int b; + char* s; struct { int64_t n; int64_t intsplit; } n; - double dbl; - regex_t re; - } u; ///< Filter data + double dbl; + regex_t re; + } u; ///< Filter data enum { IC_EQ, ///< Equals IC_LT, ///< LT IC_GT, ///< GT IC_IN, ///< contains (STR only) IC_RE, ///< regexp (STR only) - } comp; ///< Filter comparison + } comp; ///< Filter comparison } idnode_filter_ele_t; -typedef LIST_HEAD(,idnode_filter_ele) idnode_filter_t; +typedef LIST_HEAD(, idnode_filter_ele) idnode_filter_t; -extern idnode_t tvhlog_conf; +extern idnode_t tvhlog_conf; extern const idclass_t tvhlog_conf_class; -extern tvh_mutex_t idnode_mutex; +extern tvh_mutex_t idnode_mutex; void idnode_boot(void); void idnode_init(void); void idnode_done(void); -static inline void idnode_lock(void) - { tvh_mutex_lock(&idnode_mutex); } -static inline void idnode_unlock(void) - { tvh_mutex_unlock(&idnode_mutex); } - -#define IDNODE_SHORT_UUID (1<<0) - -int idnode_insert(idnode_t *in, const char *uuid, const idclass_t *idc, int flags); -void idnode_unlink(idnode_t *in); - -uint32_t idnode_get_short_uuid (const idnode_t *in); -const char *idnode_uuid_as_str (const idnode_t *in, char *buf); -idnode_set_t *idnode_get_childs (idnode_t *in); -const char *idnode_get_title (idnode_t *in, const char *lang, char *dst, size_t dstsize); -int idnode_is_leaf (idnode_t *in); -int idnode_is_instance (idnode_t *in, const idclass_t *idc); -void idnode_delete (idnode_t *in); -void idnode_moveup (idnode_t *in); -void idnode_movedown (idnode_t *in); - -void idnode_changed (idnode_t *in); - -void *idnode_find (const char *uuid, const idclass_t *idc, const idnodes_rb_t *nodes); -void *idnode_find0 (tvh_uuid_t *uuid, const idclass_t *idc, const idnodes_rb_t *nodes); -idnode_set_t *idnode_find_all(const idclass_t *idc, const idnodes_rb_t *nodes); - - -void idnode_notify (idnode_t *in, const char *action); -void idnode_notify_changed (void *in); -void idnode_notify_title_changed (void *in); -void idnode_notify_title_changed_lang (void *in, const char *lang); - -void idnode_lnotify_changed (void *in); -void idnode_lnotify_title_changed (void *in); - -void idclass_register ( const idclass_t *idc ); -const idclass_t *idclass_find ( const char *name ); -idclass_t const **idclass_find_all(void); -idclass_t const **idclass_find_children(const char *name); -const char **idclass_get_doc(const idclass_t *idc); -const char *idclass_get_caption ( const idclass_t *idc, const char *lang ); -htsmsg_t *idclass_serialize0 (const idclass_t *idc, htsmsg_t *list, int optmask, const char *lang); -htsmsg_t *idnode_serialize0 (idnode_t *self, htsmsg_t *list, int optmask, const char *lang); -void idnode_read0 (idnode_t *self, htsmsg_t *m, htsmsg_t *list, int optmask, const char *lang); -int idnode_write0 (idnode_t *self, htsmsg_t *m, int optmask, int dosave); -void idnode_save_check (idnode_t *self, int weak); -htsmsg_t *idnode_savefn (idnode_t *self, char *filename, size_t fsize); -void idnode_loadfn (idnode_t *self, htsmsg_t *conf); +static inline void idnode_lock(void) { + tvh_mutex_lock(&idnode_mutex); +} +static inline void idnode_unlock(void) { + tvh_mutex_unlock(&idnode_mutex); +} + +#define IDNODE_SHORT_UUID (1 << 0) + +int idnode_insert(idnode_t* in, const char* uuid, const idclass_t* idc, int flags); +void idnode_unlink(idnode_t* in); + +uint32_t idnode_get_short_uuid(const idnode_t* in); +const char* idnode_uuid_as_str(const idnode_t* in, char* buf); +idnode_set_t* idnode_get_childs(idnode_t* in); +const char* idnode_get_title(idnode_t* in, const char* lang, char* dst, size_t dstsize); +int idnode_is_leaf(idnode_t* in); +int idnode_is_instance(idnode_t* in, const idclass_t* idc); +void idnode_delete(idnode_t* in); +void idnode_moveup(idnode_t* in); +void idnode_movedown(idnode_t* in); + +void idnode_changed(idnode_t* in); + +void* idnode_find(const char* uuid, const idclass_t* idc, const idnodes_rb_t* nodes); +void* idnode_find0(tvh_uuid_t* uuid, const idclass_t* idc, const idnodes_rb_t* nodes); +idnode_set_t* idnode_find_all(const idclass_t* idc, const idnodes_rb_t* nodes); + +void idnode_notify(idnode_t* in, const char* action); +void idnode_notify_changed(void* in); +void idnode_notify_title_changed(void* in); +void idnode_notify_title_changed_lang(void* in, const char* lang); + +void idnode_lnotify_changed(void* in); +void idnode_lnotify_title_changed(void* in); + +void idclass_register(const idclass_t* idc); +const idclass_t* idclass_find(const char* name); +idclass_t const** idclass_find_all(void); +idclass_t const** idclass_find_children(const char* name); +const char** idclass_get_doc(const idclass_t* idc); +const char* idclass_get_caption(const idclass_t* idc, const char* lang); +htsmsg_t* idclass_serialize0(const idclass_t* idc, htsmsg_t* list, int optmask, const char* lang); +htsmsg_t* idnode_serialize0(idnode_t* self, htsmsg_t* list, int optmask, const char* lang); +void idnode_read0(idnode_t* self, htsmsg_t* m, htsmsg_t* list, int optmask, const char* lang); +int idnode_write0(idnode_t* self, htsmsg_t* m, int optmask, int dosave); +void idnode_save_check(idnode_t* self, int weak); +htsmsg_t* idnode_savefn(idnode_t* self, char* filename, size_t fsize); +void idnode_loadfn(idnode_t* self, htsmsg_t* conf); #define idclass_serialize(idc, lang) idclass_serialize0(idc, NULL, 0, lang) #define idclass_serializedoc(idc, lang) idclass_serialize0(idc, NULL, PO_DOC, lang) #define idnode_serialize(in, lang) idnode_serialize0(in, NULL, 0, lang) -#define idnode_load(in, m) idnode_write0(in, m, PO_NOSAVE, 0) -#define idnode_save(in, m) idnode_read0(in, m, NULL, PO_NOSAVE | PO_USERAW, NULL) -#define idnode_update(in, m) idnode_write0(in, m, PO_RDONLY | PO_WRONCE, 1) +#define idnode_load(in, m) idnode_write0(in, m, PO_NOSAVE, 0) +#define idnode_save(in, m) idnode_read0(in, m, NULL, PO_NOSAVE | PO_USERAW, NULL) +#define idnode_update(in, m) idnode_write0(in, m, PO_RDONLY | PO_WRONCE, 1) -int idnode_perm(idnode_t *self, struct access *a, htsmsg_t *msg_to_write); -static inline void idnode_perm_unset(idnode_t *self) { self->in_access = NULL; } +int idnode_perm(idnode_t* self, struct access* a, htsmsg_t* msg_to_write); +static inline void idnode_perm_unset(idnode_t* self) { + self->in_access = NULL; +} #define idnode_lang(self) \ - (((idnode_t *)self)->in_access ? \ - ((idnode_t *)self)->in_access->aa_lang : NULL) + (((idnode_t*)self)->in_access ? ((idnode_t*)self)->in_access->aa_lang : NULL) #define idnode_lang_ui(self) \ - (((idnode_t *)self)->in_access ? \ - ((idnode_t *)self)->in_access->aa_lang_ui : NULL) - -htsmsg_t * idnode_slist_enum ( idnode_t *in, idnode_slist_t *options, const char *lang ); -htsmsg_t * idnode_slist_get ( idnode_t *in, idnode_slist_t *options ); -int idnode_slist_set ( idnode_t *in, idnode_slist_t *options, const htsmsg_t *vals ); -char * idnode_slist_rend ( idnode_t *in, idnode_slist_t *options, const char *lang ); - -idnode_list_mapping_t * idnode_list_link - ( idnode_t *in1, idnode_list_head_t *in1_list, - idnode_t *in2, idnode_list_head_t *in2_list, - void *origin, uint32_t savemask ); -void idnode_list_unlink ( idnode_list_mapping_t *ilm, void *origin ); -void idnode_list_destroy ( idnode_list_head_t *ilh, void *origin ); -htsmsg_t * idnode_list_get1 ( idnode_list_head_t *in1_list ); -htsmsg_t * idnode_list_get2 ( idnode_list_head_t *in2_list ); -char * idnode_list_get_csv1 ( idnode_list_head_t *in1_list, const char *lang ); -char * idnode_list_get_csv2 ( idnode_list_head_t *in2_list, const char *lang ); -int idnode_list_set1 ( idnode_t *in1, idnode_list_head_t *in1_list, - const idclass_t *in2_class, htsmsg_t *in2_list, - int (*in2_create)(idnode_t *in1, idnode_t *in2, void *origin) ); -int idnode_list_set2 ( idnode_t *in2, idnode_list_head_t *in2_list, - const idclass_t *in1_class, htsmsg_t *in1_list, - int (*in2_create)(idnode_t *in1, idnode_t *in2, void *origin) ); - -const char *idnode_get_str (idnode_t *self, const char *key ); -int idnode_get_u32 (idnode_t *self, const char *key, uint32_t *u32); -int idnode_get_s64 (idnode_t *self, const char *key, int64_t *s64); -int idnode_get_s64_atomic (idnode_t *self, const char *key, int64_t *s64); -int idnode_get_dbl (idnode_t *self, const char *key, double *dbl); -int idnode_get_bool(idnode_t *self, const char *key, int *b); -int idnode_get_time(idnode_t *self, const char *key, time_t *tm); - -void idnode_filter_add_str - (idnode_filter_t *f, const char *k, const char *v, int t); -void idnode_filter_add_num - (idnode_filter_t *f, const char *k, int64_t s64, int t, int64_t intsplit); -void idnode_filter_add_dbl - (idnode_filter_t *f, const char *k, double dbl, int t); -void idnode_filter_add_bool - (idnode_filter_t *f, const char *k, int b, int t); -void idnode_filter_clear - (idnode_filter_t *f); -int idnode_filter - ( idnode_t *in, idnode_filter_t *filt, const char *lang ); -static inline idnode_set_t * idnode_set_create(int sorted) - { idnode_set_t *is = calloc(1, sizeof(idnode_set_t)); - is->is_sorted = sorted; return is; } -void idnode_set_alloc ( idnode_set_t *is, size_t alloc ); -void idnode_set_add - ( idnode_set_t *is, idnode_t *in, idnode_filter_t *filt, const char *lang ); -int idnode_set_remove ( idnode_set_t *is, idnode_t *in ); -ssize_t idnode_set_find_index( idnode_set_t *is, idnode_t *in ); -static inline int idnode_set_exists ( idnode_set_t *is, idnode_t *in ) - { return idnode_set_find_index(is, in) >= 0; } -static inline int idnode_set_empty ( idnode_set_t *is ) - { return is->is_count == 0; } -void idnode_set_sort ( idnode_set_t *is, idnode_sort_t *s ); -void idnode_set_sort_by_title ( idnode_set_t *is, const char *lang ); -htsmsg_t *idnode_set_as_htsmsg ( idnode_set_t *is ); -void idnode_set_clear ( idnode_set_t *is ); -void idnode_set_free ( idnode_set_t *is ); + (((idnode_t*)self)->in_access ? ((idnode_t*)self)->in_access->aa_lang_ui : NULL) + +htsmsg_t* idnode_slist_enum(idnode_t* in, idnode_slist_t* options, const char* lang); +htsmsg_t* idnode_slist_get(idnode_t* in, idnode_slist_t* options); +int idnode_slist_set(idnode_t* in, idnode_slist_t* options, const htsmsg_t* vals); +char* idnode_slist_rend(idnode_t* in, idnode_slist_t* options, const char* lang); + +idnode_list_mapping_t* idnode_list_link(idnode_t* in1, + idnode_list_head_t* in1_list, + idnode_t* in2, + idnode_list_head_t* in2_list, + void* origin, + uint32_t savemask); +void idnode_list_unlink(idnode_list_mapping_t* ilm, void* origin); +void idnode_list_destroy(idnode_list_head_t* ilh, void* origin); +htsmsg_t* idnode_list_get1(idnode_list_head_t* in1_list); +htsmsg_t* idnode_list_get2(idnode_list_head_t* in2_list); +char* idnode_list_get_csv1(idnode_list_head_t* in1_list, const char* lang); +char* idnode_list_get_csv2(idnode_list_head_t* in2_list, const char* lang); +int idnode_list_set1(idnode_t* in1, + idnode_list_head_t* in1_list, + const idclass_t* in2_class, + htsmsg_t* in2_list, + int (*in2_create)(idnode_t* in1, idnode_t* in2, void* origin)); +int idnode_list_set2(idnode_t* in2, + idnode_list_head_t* in2_list, + const idclass_t* in1_class, + htsmsg_t* in1_list, + int (*in2_create)(idnode_t* in1, idnode_t* in2, void* origin)); + +const char* idnode_get_str(idnode_t* self, const char* key); +int idnode_get_u32(idnode_t* self, const char* key, uint32_t* u32); +int idnode_get_s64(idnode_t* self, const char* key, int64_t* s64); +int idnode_get_s64_atomic(idnode_t* self, const char* key, int64_t* s64); +int idnode_get_dbl(idnode_t* self, const char* key, double* dbl); +int idnode_get_bool(idnode_t* self, const char* key, int* b); +int idnode_get_time(idnode_t* self, const char* key, time_t* tm); + +void idnode_filter_add_str(idnode_filter_t* f, const char* k, const char* v, int t); +void idnode_filter_add_num(idnode_filter_t* f, const char* k, int64_t s64, int t, int64_t intsplit); +void idnode_filter_add_dbl(idnode_filter_t* f, const char* k, double dbl, int t); +void idnode_filter_add_bool(idnode_filter_t* f, const char* k, int b, int t); +void idnode_filter_clear(idnode_filter_t* f); +int idnode_filter(idnode_t* in, idnode_filter_t* filt, const char* lang); +static inline idnode_set_t* idnode_set_create(int sorted) { + idnode_set_t* is = calloc(1, sizeof(idnode_set_t)); + is->is_sorted = sorted; + return is; +} +void idnode_set_alloc(idnode_set_t* is, size_t alloc); +void idnode_set_add(idnode_set_t* is, idnode_t* in, idnode_filter_t* filt, const char* lang); +int idnode_set_remove(idnode_set_t* is, idnode_t* in); +ssize_t idnode_set_find_index(idnode_set_t* is, idnode_t* in); +static inline int idnode_set_exists(idnode_set_t* is, idnode_t* in) { + return idnode_set_find_index(is, in) >= 0; +} +static inline int idnode_set_empty(idnode_set_t* is) { + return is->is_count == 0; +} +void idnode_set_sort(idnode_set_t* is, idnode_sort_t* s); +void idnode_set_sort_by_title(idnode_set_t* is, const char* lang); +htsmsg_t* idnode_set_as_htsmsg(idnode_set_t* is); +void idnode_set_clear(idnode_set_t* is); +void idnode_set_free(idnode_set_t* is); #endif /* __TVH_IDNODE_H__ */ diff --git a/src/imagecache.c b/src/imagecache.c index a88ef6253..ee32ca87c 100644 --- a/src/imagecache.c +++ b/src/imagecache.c @@ -33,129 +33,113 @@ /* * Image metadata */ -typedef struct imagecache_image -{ - int id; ///< Internal ID - int ref; ///< Number of references - const char *url; ///< Upstream URL - uint8_t failed; ///< Last update failed - uint8_t savepend; ///< Pending save - time_t accessed; ///< Last time the file was accessed - time_t updated; ///< Last time the file was checked - uint8_t sha1[20]; ///< Contents hash - enum { - IDLE, - SAVE, - QUEUED, - FETCHING - } state; ///< save/fetch status - - TAILQ_ENTRY(imagecache_image) q_link; ///< Fetch Q link - RB_ENTRY(imagecache_image) id_link; ///< Index by ID - RB_ENTRY(imagecache_image) url_link; ///< Index by URL +typedef struct imagecache_image { + int id; ///< Internal ID + int ref; ///< Number of references + const char* url; ///< Upstream URL + uint8_t failed; ///< Last update failed + uint8_t savepend; ///< Pending save + time_t accessed; ///< Last time the file was accessed + time_t updated; ///< Last time the file was checked + uint8_t sha1[20]; ///< Contents hash + enum { IDLE, SAVE, QUEUED, FETCHING } state; ///< save/fetch status + + TAILQ_ENTRY(imagecache_image) q_link; ///< Fetch Q link + RB_ENTRY(imagecache_image) id_link; ///< Index by ID + RB_ENTRY(imagecache_image) url_link; ///< Index by URL } imagecache_image_t; tvh_mutex_t imagecache_lock = TVH_THREAD_MUTEX_INITIALIZER; -static int imagecache_id; -static RB_HEAD(,imagecache_image) imagecache_by_id; -static RB_HEAD(,imagecache_image) imagecache_by_url; +static int imagecache_id; +static RB_HEAD(, imagecache_image) imagecache_by_id; +static RB_HEAD(, imagecache_image) imagecache_by_url; SKEL_DECLARE(imagecache_skel, imagecache_image_t); struct imagecache_config imagecache_conf = { - .idnode.in_class = &imagecache_class, + .idnode.in_class = &imagecache_class, }; -static htsmsg_t *imagecache_class_save(idnode_t *self, char *filename, size_t fsize); -static void imagecache_destroy(imagecache_image_t *img, int delconf); +static htsmsg_t* imagecache_class_save(idnode_t* self, char* filename, size_t fsize); +static void imagecache_destroy(imagecache_image_t* img, int delconf); -static inline time_t clkwrap(time_t clk) -{ +static inline time_t clkwrap(time_t clk) { return clk / 8192; /* more than two hours */ } CLASS_DOC(imagecache) -const idclass_t imagecache_class = { - .ic_snode = (idnode_t *)&imagecache_conf, - .ic_class = "imagecache", - .ic_caption = N_("Configuration - Image Cache"), - .ic_event = "imagecache", - .ic_perm_def = ACCESS_ADMIN, - .ic_doc = tvh_doc_imagecache_class, - .ic_save = imagecache_class_save, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Select whether or not to enable caching. Note, " - "even with this disabled you can still specify " - "local (file://) icons and these will be served by " - "the built-in webserver."), - .off = offsetof(struct imagecache_config, enabled), - }, - { - .type = PT_BOOL, - .id = "ignore_sslcert", - .name = N_("Ignore invalid SSL certificate"), - .desc = N_("Ignore invalid/unverifiable (expired, " - "self-certified, etc.) certificates"), - .off = offsetof(struct imagecache_config, ignore_sslcert), - }, - { - .type = PT_U32, - .id = "expire", - .name = N_("Expire time"), - .desc = N_("The time in days after the cached URL will " - "be removed. The time starts when the URL was " - "lastly requested. Zero means unlimited cache " - "(not recommended)."), - .off = offsetof(struct imagecache_config, expire), - }, - { - .type = PT_U32, - .id = "ok_period", - .name = N_("Re-fetch period (hours)"), - .desc = N_("How frequently the upstream provider is checked " - "for changes."), - .off = offsetof(struct imagecache_config, ok_period), - }, - { - .type = PT_U32, - .id = "fail_period", - .name = N_("Re-try period (hours)"), - .desc = N_("How frequently it will re-try fetching an image " - "that has failed to be fetched."), - .off = offsetof(struct imagecache_config, fail_period), - }, - {} - } -}; - -static tvh_cond_t imagecache_cond; +const idclass_t imagecache_class = {.ic_snode = (idnode_t*)&imagecache_conf, + .ic_class = "imagecache", + .ic_caption = N_("Configuration - Image Cache"), + .ic_event = "imagecache", + .ic_perm_def = ACCESS_ADMIN, + .ic_doc = tvh_doc_imagecache_class, + .ic_save = imagecache_class_save, + .ic_properties = + (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Select whether or not to enable caching. Note, " + "even with this disabled you can still specify " + "local (file://) icons and these will be served by " + "the built-in webserver."), + .off = offsetof(struct imagecache_config, enabled), + }, + { + .type = PT_BOOL, + .id = "ignore_sslcert", + .name = N_("Ignore invalid SSL certificate"), + .desc = N_("Ignore invalid/unverifiable (expired, " + "self-certified, etc.) certificates"), + .off = offsetof(struct imagecache_config, ignore_sslcert), + }, + { + .type = PT_U32, + .id = "expire", + .name = N_("Expire time"), + .desc = N_("The time in days after the cached URL will " + "be removed. The time starts when the URL was " + "lastly requested. Zero means unlimited cache " + "(not recommended)."), + .off = offsetof(struct imagecache_config, expire), + }, + { + .type = PT_U32, + .id = "ok_period", + .name = N_("Re-fetch period (hours)"), + .desc = N_("How frequently the upstream provider is checked " + "for changes."), + .off = offsetof(struct imagecache_config, ok_period), + }, + { + .type = PT_U32, + .id = "fail_period", + .name = N_("Re-try period (hours)"), + .desc = N_("How frequently it will re-try fetching an image " + "that has failed to be fetched."), + .off = offsetof(struct imagecache_config, fail_period), + }, + {}}}; + +static tvh_cond_t imagecache_cond; static TAILQ_HEAD(, imagecache_image) imagecache_queue; -static void -imagecache_incref(imagecache_image_t *img) -{ +static void imagecache_incref(imagecache_image_t* img) { lock_assert(&imagecache_lock); assert(img->ref > 0); img->ref++; } -static void -imagecache_decref(imagecache_image_t *img) -{ +static void imagecache_decref(imagecache_image_t* img) { lock_assert(&imagecache_lock); if (--img->ref == 0) { - free((void *)img->url); + free((void*)img->url); free(img); } } -static inline int -sha1_empty( const uint8_t *sha1 ) -{ +static inline int sha1_empty(const uint8_t* sha1) { int i; for (i = 0; i < 20; i++) if (sha1[i]) @@ -163,23 +147,17 @@ sha1_empty( const uint8_t *sha1 ) return 1; } -static int -url_cmp ( imagecache_image_t *a, imagecache_image_t *b ) -{ +static int url_cmp(imagecache_image_t* a, imagecache_image_t* b) { return strcmp(a->url, b->url); } -static int -id_cmp ( imagecache_image_t *a, imagecache_image_t *b ) -{ +static int id_cmp(imagecache_image_t* a, imagecache_image_t* b) { return (a->id - b->id); } -static htsmsg_t * -imagecache_image_htsmsg ( imagecache_image_t *img ) -{ - char hex[41]; - htsmsg_t *m = htsmsg_create_map(); +static htsmsg_t* imagecache_image_htsmsg(imagecache_image_t* img) { + char hex[41]; + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "url", img->url); if (img->accessed) htsmsg_add_s64(m, "accessed", img->accessed); @@ -192,9 +170,7 @@ imagecache_image_htsmsg ( imagecache_image_t *img ) return m; } -static void -imagecache_image_save ( imagecache_image_t *img ) -{ +static void imagecache_image_save(imagecache_image_t* img) { img->savepend = 1; if (img->state != SAVE && img->state != QUEUED && img->state != FETCHING) { img->state = SAVE; @@ -203,23 +179,21 @@ imagecache_image_save ( imagecache_image_t *img ) } } -static void -imagecache_new_id ( imagecache_image_t *i ) -{ - imagecache_image_t *j; +static void imagecache_new_id(imagecache_image_t* i) { + imagecache_image_t* j; do { i->id = ++imagecache_id % INT_MAX; - if (!i->id) i->id = ++imagecache_id % INT_MAX; + if (!i->id) + i->id = ++imagecache_id % INT_MAX; j = RB_INSERT_SORTED(&imagecache_by_id, i, id_link, id_cmp); } while (j); } -static void -imagecache_image_add ( imagecache_image_t *img ) -{ +static void imagecache_image_add(imagecache_image_t* img) { int oldstate = img->state; - if (!imagecache_conf.enabled) return; + if (!imagecache_conf.enabled) + return; if (strncasecmp("file://", img->url, 7)) { img->state = QUEUED; if (oldstate != SAVE && oldstate != QUEUED) @@ -230,18 +204,16 @@ imagecache_image_add ( imagecache_image_t *img ) } } -static int -imagecache_update_sha1 ( imagecache_image_t *img, - const char *path ) -{ - int fd; +static int imagecache_update_sha1(imagecache_image_t* img, const char* path) { + int fd; uint8_t sha1[20]; - sbuf_t sb; + sbuf_t sb; sbuf_init(&sb); if ((fd = tvh_open(path, O_RDONLY, 0)) < 0) return 0; - while (sbuf_read(&sb, fd) < 0 && ERRNO_AGAIN(errno)); + while (sbuf_read(&sb, fd) < 0 && ERRNO_AGAIN(errno)) + ; close(fd); sha1_calc(sha1, sb.sb_data, sb.sb_ptr, NULL, 0); memcpy(img->sha1, sha1, 20); @@ -249,14 +221,14 @@ imagecache_update_sha1 ( imagecache_image_t *img, return 1; } -static int -imagecache_new_contents ( imagecache_image_t *img, - const char *tpath, char *path, - const uint8_t *data, size_t dsize ) -{ - int empty, r = 0; +static int imagecache_new_contents(imagecache_image_t* img, + const char* tpath, + char* path, + const uint8_t* data, + size_t dsize) { + int empty, r = 0; uint8_t sha1[20]; - FILE *fp; + FILE* fp; sha1_calc(sha1, data, dsize, NULL, 0); empty = sha1_empty(img->sha1); @@ -289,15 +261,13 @@ imagecache_new_contents ( imagecache_image_t *img, return r; } -static int -imagecache_image_fetch ( imagecache_image_t *img ) -{ - int res = 1, r; - url_t url; - char tpath[PATH_MAX + 4] = "", path[PATH_MAX]; +static int imagecache_image_fetch(imagecache_image_t* img) { + int res = 1, r; + url_t url; + char tpath[PATH_MAX + 4] = "", path[PATH_MAX]; tvhpoll_event_t ev; - tvhpoll_t *efd = NULL; - http_client_t *hc = NULL; + tvhpoll_t* efd = NULL; + http_client_t* hc = NULL; urlinit(&url); @@ -307,8 +277,7 @@ imagecache_image_fetch ( imagecache_image_t *img ) return res; /* Open file */ - if (hts_settings_buildpath(path, sizeof(path), "imagecache/data/%d", - img->id)) + if (hts_settings_buildpath(path, sizeof(path), "imagecache/data/%d", img->id)) goto error; if (hts_settings_makedirs(path)) goto error; @@ -325,16 +294,15 @@ imagecache_image_fetch ( imagecache_image_t *img ) goto error_lock; } - hc = http_client_connect(NULL, HTTP_VERSION_1_1, url.scheme, - url.host, url.port, NULL); + hc = http_client_connect(NULL, HTTP_VERSION_1_1, url.scheme, url.host, url.port, NULL); if (hc == NULL) goto error_lock; http_client_ssl_peer_verify(hc, imagecache_conf.ignore_sslcert ? 0 : 1); hc->hc_handle_location = 1; - hc->hc_data_limit = 256*1024; - efd = tvhpoll_create(1); - hc->hc_efd = efd; + hc->hc_data_limit = 256 * 1024; + efd = tvhpoll_create(1); + hc->hc_efd = efd; r = http_client_simple(hc, &url); if (r < 0) @@ -351,15 +319,15 @@ imagecache_image_fetch ( imagecache_image_t *img ) break; if (r == HTTP_CON_DONE) { if (hc->hc_code == HTTP_STATUS_OK && hc->hc_data_size > 0) - res = imagecache_new_contents(img, tpath, path, - (uint8_t *)hc->hc_data, hc->hc_data_size); + res = imagecache_new_contents(img, tpath, path, (uint8_t*)hc->hc_data, hc->hc_data_size); break; } } /* Process */ error_lock: - if (NULL != hc) http_client_close(hc); + if (NULL != hc) + http_client_close(hc); tvh_mutex_lock(&imagecache_lock); error: urlreset(&url); @@ -379,10 +347,8 @@ error: return res; }; -static void -imagecache_timer ( void ) -{ - time_t now, when; +static void imagecache_timer(void) { + time_t now, when; imagecache_image_t *img, *img_next; now = gclk(); @@ -396,20 +362,18 @@ imagecache_timer ( void ) continue; } } - if (img->state != IDLE) continue; - when = img->failed ? imagecache_conf.fail_period - : imagecache_conf.ok_period; + if (img->state != IDLE) + continue; + when = img->failed ? imagecache_conf.fail_period : imagecache_conf.ok_period; when = img->updated + (when * 3600); if (when < now) imagecache_image_add(img); } } -static void * -imagecache_thread ( void *p ) -{ - imagecache_image_t *img; - int64_t timer_expire = mclk() + sec2mono(600); +static void* imagecache_thread(void* p) { + imagecache_image_t* img; + int64_t timer_expire = mclk() + sec2mono(600); tvh_mutex_lock(&imagecache_lock); while (tvheadend_is_running()) { @@ -428,11 +392,11 @@ imagecache_thread ( void *p ) TAILQ_REMOVE(&imagecache_queue, img, q_link); -retry: + retry: if (img->state == SAVE) { /* Do save outside global mutex */ - htsmsg_t *m = imagecache_image_htsmsg(img); - img->state = IDLE; + htsmsg_t* m = imagecache_image_htsmsg(img); + img->state = IDLE; img->savepend = 0; tvh_mutex_unlock(&imagecache_lock); hts_settings_save(m, "imagecache/meta/%d", img->id); @@ -468,14 +432,12 @@ retry: */ pthread_t imagecache_tid; -void -imagecache_init ( void ) -{ - htsmsg_t *m, *e; - htsmsg_field_t *f; +void imagecache_init(void) { + htsmsg_t * m, *e; + htsmsg_field_t* f; imagecache_image_t *img, *i; - const char *url, *sha1; - int id; + const char * url, *sha1; + int id; /* Init vars */ imagecache_id = 0; @@ -498,16 +460,19 @@ imagecache_init ( void ) } if ((m = hts_settings_load("imagecache/meta"))) { HTSMSG_FOREACH(f, m) { - if (!(e = htsmsg_get_map_by_field(f))) continue; - if (!(id = atoi(htsmsg_field_name(f)))) continue; - if (!(url = htsmsg_get_str(e, "url"))) continue; + if (!(e = htsmsg_get_map_by_field(f))) + continue; + if (!(id = atoi(htsmsg_field_name(f)))) + continue; + if (!(url = htsmsg_get_str(e, "url"))) + continue; img = calloc(1, sizeof(imagecache_image_t)); img->id = id; img->ref = 1; img->url = strdup(url); img->accessed = htsmsg_get_s64_or_default(e, "accessed", 0); img->updated = htsmsg_get_s64_or_default(e, "updated", 0); - sha1 = htsmsg_get_str(e, "sha1"); + sha1 = htsmsg_get_str(e, "sha1"); if (sha1 && strlen(sha1) == 40) hex2bin(img->sha1, 20, sha1); i = RB_INSERT_SORTED(&imagecache_by_url, img, url_link, url_cmp); @@ -536,13 +501,10 @@ imagecache_init ( void ) tvh_thread_create(&imagecache_tid, NULL, imagecache_thread, NULL, "imagecache"); } - /* * Destroy */ -static void -imagecache_destroy ( imagecache_image_t *img, int delconf ) -{ +static void imagecache_destroy(imagecache_image_t* img, int delconf) { if (delconf) { hts_settings_remove("imagecache/meta/%d", img->id); hts_settings_remove("imagecache/data/%d", img->id); @@ -555,10 +517,8 @@ imagecache_destroy ( imagecache_image_t *img, int delconf ) /* * Shutdown */ -void -imagecache_done ( void ) -{ - imagecache_image_t *img; +void imagecache_done(void) { + imagecache_image_t* img; tvh_mutex_lock(&imagecache_lock); tvh_cond_signal(&imagecache_cond, 1); @@ -567,7 +527,7 @@ imagecache_done ( void ) tvh_mutex_lock(&imagecache_lock); while ((img = RB_FIRST(&imagecache_by_id)) != NULL) { if (img->state == SAVE) { - htsmsg_t *m = imagecache_image_htsmsg(img); + htsmsg_t* m = imagecache_image_htsmsg(img); hts_settings_save(m, "imagecache/meta/%d", img->id); htsmsg_destroy(m); } @@ -577,14 +537,11 @@ imagecache_done ( void ) tvh_mutex_unlock(&imagecache_lock); } - /* * Class save */ -static htsmsg_t * -imagecache_class_save ( idnode_t *self, char *filename, size_t fsize ) -{ - htsmsg_t *c = htsmsg_create_map(); +static htsmsg_t* imagecache_class_save(idnode_t* self, char* filename, size_t fsize) { + htsmsg_t* c = htsmsg_create_map(); idnode_save(&imagecache_conf.idnode, c); if (filename) snprintf(filename, fsize, "imagecache/config"); @@ -595,13 +552,11 @@ imagecache_class_save ( idnode_t *self, char *filename, size_t fsize ) /* * Clean */ -void -imagecache_clean( void ) -{ +void imagecache_clean(void) { imagecache_image_t *img, *next, skel; - fb_dirent **namelist; - char path[PATH_MAX], *name; - int i, n; + fb_dirent** namelist; + char path[PATH_MAX], *name; + int i, n; tvh_mutex_lock(&imagecache_lock); @@ -619,14 +574,14 @@ imagecache_clean( void ) tvherror(LS_IMAGECACHE, "clean - buildpath"); goto done; } - if((n = fb_scandir(path, &namelist)) < 0) + if ((n = fb_scandir(path, &namelist)) < 0) goto done; for (i = 0; i < n; i++) { name = namelist[i]->name; if (name[0] == '.') continue; skel.id = atoi(name); - img = RB_FIND(&imagecache_by_id, &skel, id_link, id_cmp); + img = RB_FIND(&imagecache_by_id, &skel, id_link, id_cmp); if (img) continue; tvhinfo(LS_IMAGECACHE, "clean: removing unassociated file '%s/%s'", path, name); @@ -644,15 +599,14 @@ done: /* * Trigger */ -void -imagecache_trigger( void ) -{ - imagecache_image_t *img; +void imagecache_trigger(void) { + imagecache_image_t* img; tvh_mutex_lock(&imagecache_lock); tvhinfo(LS_IMAGECACHE, "load triggered"); - RB_FOREACH(img, &imagecache_by_url, url_link) { - if (img->state != IDLE) continue; + RB_FOREACH (img, &imagecache_by_url, url_link) { + if (img->state != IDLE) + continue; imagecache_image_add(img); } tvh_mutex_unlock(&imagecache_lock); @@ -664,13 +618,11 @@ imagecache_trigger( void ) * If imagecache is not enabled, just manage the id<->local filename * mapping database. */ -int -imagecache_get_id ( const char *url ) -{ - int id = 0; - imagecache_image_t *i; - int save = 0; - time_t clk; +int imagecache_get_id(const char* url) { + int id = 0; + imagecache_image_t* i; + int save = 0; + time_t clk; /* Invalid */ if (!url || url[0] == '\0' || !strstr(url, "://")) @@ -689,7 +641,7 @@ imagecache_get_id ( const char *url ) /* Create/Find */ i = RB_INSERT_SORTED(&imagecache_by_url, imagecache_skel, url_link, url_cmp); if (!i) { - i = imagecache_skel; + i = imagecache_skel; i->ref = 1; i->url = strdup(url); SKEL_USED(imagecache_skel); @@ -705,7 +657,7 @@ imagecache_get_id ( const char *url ) clk = gclk(); if (clkwrap(clk) != clkwrap(i->accessed)) { i->accessed = clk; - save = 1; + save = 1; } if (save) imagecache_image_save(i); @@ -718,11 +670,10 @@ imagecache_get_id ( const char *url ) /* * */ -const char * -imagecache_get_propstr ( const char *image, char *buf, size_t buflen ) -{ +const char* imagecache_get_propstr(const char* image, char* buf, size_t buflen) { int id = imagecache_get_id(image); - if (id == 0) return image; + if (id == 0) + return image; snprintf(buf, buflen, "imagecache/%d", id); return buf; } @@ -730,11 +681,9 @@ imagecache_get_propstr ( const char *image, char *buf, size_t buflen ) /* * Get data */ -int -imagecache_filename ( int id, char *name, size_t len ) -{ +int imagecache_filename(int id, char* name, size_t len) { imagecache_image_t skel, *i = NULL; - char *fn; + char* fn; tvh_mutex_lock(&imagecache_lock); @@ -754,13 +703,13 @@ imagecache_filename ( int id, char *name, size_t len ) /* Remote file */ else if (imagecache_conf.enabled) { - int e; + int e; int64_t mono; /* Use existing */ if (i->updated) { - /* Wait */ + /* Wait */ } else if (i->state == FETCHING) { mono = mclk() + sec2mono(5); do { @@ -769,7 +718,7 @@ imagecache_filename ( int id, char *name, size_t len ) goto out_error; } while (ERRNO_AGAIN(e)); - /* Attempt to fetch */ + /* Attempt to fetch */ } else if (i->state == QUEUED) { i->state = FETCHING; TAILQ_REMOVE(&imagecache_queue, i, q_link); @@ -786,7 +735,8 @@ imagecache_filename ( int id, char *name, size_t len ) return 0; out_error: - if (i) imagecache_decref(i); + if (i) + imagecache_decref(i); tvh_mutex_unlock(&imagecache_lock); return -1; } diff --git a/src/imagecache.h b/src/imagecache.h index 5a2d0e19b..84da67297 100644 --- a/src/imagecache.h +++ b/src/imagecache.h @@ -23,30 +23,30 @@ #include "idnode.h" struct imagecache_config { - idnode_t idnode; - int enabled; - int ignore_sslcert; - uint32_t expire; - uint32_t ok_period; - uint32_t fail_period; + idnode_t idnode; + int enabled; + int ignore_sslcert; + uint32_t expire; + uint32_t ok_period; + uint32_t fail_period; }; extern struct imagecache_config imagecache_conf; -extern const idclass_t imagecache_class; +extern const idclass_t imagecache_class; extern tvh_mutex_t imagecache_mutex; -void imagecache_init ( void ); -void imagecache_done ( void ); +void imagecache_init(void); +void imagecache_done(void); -void imagecache_clean ( void ); -void imagecache_trigger ( void ); +void imagecache_clean(void); +void imagecache_trigger(void); // Note: will return 0 if invalid (must serve original URL) -int imagecache_get_id ( const char *url ); +int imagecache_get_id(const char* url); -const char *imagecache_get_propstr ( const char *image, char *buf, size_t buflen ); +const char* imagecache_get_propstr(const char* image, char* buf, size_t buflen); -int imagecache_filename ( int id, char *name, size_t len ); +int imagecache_filename(int id, char* name, size_t len); #endif /* __IMAGE_CACHE_H__ */ diff --git a/src/input.c b/src/input.c index d8c825a96..a776ba503 100644 --- a/src/input.c +++ b/src/input.c @@ -23,26 +23,18 @@ tvh_input_list_t tvh_inputs; tvh_hardware_list_t tvh_hardware; -const idclass_t tvh_input_class = -{ - .ic_class = "tvh_input", - .ic_caption = N_("Input base"), - .ic_perm_def = ACCESS_ADMIN -}; - -const idclass_t tvh_input_instance_class = -{ - .ic_class = "tvh_input_instance", - .ic_caption = N_("Input instance"), - .ic_perm_def = ACCESS_ADMIN -}; +const idclass_t tvh_input_class = {.ic_class = "tvh_input", + .ic_caption = N_("Input base"), + .ic_perm_def = ACCESS_ADMIN}; + +const idclass_t tvh_input_instance_class = {.ic_class = "tvh_input_instance", + .ic_caption = N_("Input instance"), + .ic_perm_def = ACCESS_ADMIN}; /* * */ -void -tvh_hardware_init ( void ) -{ +void tvh_hardware_init(void) { idclass_register(&tvh_input_class); idclass_register(&tvh_input_instance_class); } @@ -50,27 +42,24 @@ tvh_hardware_init ( void ) /* * Create entry */ -void * -tvh_hardware_create0 - ( void *o, const idclass_t *idc, const char *uuid, htsmsg_t *conf ) -{ - tvh_hardware_t *th = o; +void* tvh_hardware_create0(void* o, const idclass_t* idc, const char* uuid, htsmsg_t* conf) { + tvh_hardware_t* th = o; /* Create node */ if (idnode_insert(&th->th_id, uuid, idc, 0)) { free(o); return NULL; } - + /* Update list */ LIST_INSERT_HEAD(&tvh_hardware, th, th_link); - + /* Load config */ if (conf) idnode_load(&th->th_id, conf); notify_reload("hardware"); - + return o; } @@ -78,9 +67,7 @@ tvh_hardware_create0 * Delete hardware entry */ -void -tvh_hardware_delete ( tvh_hardware_t *th ) -{ +void tvh_hardware_delete(tvh_hardware_t* th) { // TODO LIST_REMOVE(th, th_link); idnode_unlink(&th->th_id); @@ -91,10 +78,8 @@ tvh_hardware_delete ( tvh_hardware_t *th ) * */ -void -tvh_input_instance_clear_stats ( tvh_input_instance_t *tii ) -{ - tvh_input_stream_stats_t *s = &tii->tii_stats; +void tvh_input_instance_clear_stats(tvh_input_instance_t* tii) { + tvh_input_stream_stats_t* s = &tii->tii_stats; atomic_set(&s->ber, 0); atomic_set(&s->unc, 0); @@ -108,18 +93,15 @@ tvh_input_instance_clear_stats ( tvh_input_instance_t *tii ) * Input status handling */ -htsmsg_t * -tvh_input_stream_create_msg - ( tvh_input_stream_t *st ) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_t *l = NULL; - mpegts_apids_t *pids; - int i; +htsmsg_t* tvh_input_stream_create_msg(tvh_input_stream_t* st) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_t* l = NULL; + mpegts_apids_t* pids; + int i; htsmsg_add_str(m, "uuid", st->uuid); if (st->input_name) - htsmsg_add_str(m, "input", st->input_name); + htsmsg_add_str(m, "input", st->input_name); if (st->stream_name) htsmsg_add_str(m, "stream", st->stream_name); htsmsg_add_u32(m, "subs", st->subs_count); @@ -150,10 +132,7 @@ tvh_input_stream_create_msg return m; } -void -tvh_input_stream_destroy - ( tvh_input_stream_t *st ) -{ +void tvh_input_stream_destroy(tvh_input_stream_t* st) { free(st->uuid); free(st->input_name); free(st->stream_name); diff --git a/src/input.h b/src/input.h index 3dce355c6..2708db040 100644 --- a/src/input.h +++ b/src/input.h @@ -35,15 +35,14 @@ typedef struct tvh_input_instance tvh_input_instance_t; typedef struct tvh_input_stream tvh_input_stream_t; typedef struct tvh_input_stream_stats tvh_input_stream_stats_t; -typedef LIST_HEAD(,tvh_hardware) tvh_hardware_list_t; -typedef LIST_HEAD(,tvh_input) tvh_input_list_t; -typedef LIST_HEAD(,tvh_input_stream) tvh_input_stream_list_t; +typedef LIST_HEAD(, tvh_hardware) tvh_hardware_list_t; +typedef LIST_HEAD(, tvh_input) tvh_input_list_t; +typedef LIST_HEAD(, tvh_input_stream) tvh_input_stream_list_t; /* * Input stream structure - used for getting statistics about active streams */ -struct tvh_input_stream_stats -{ +struct tvh_input_stream_stats { int signal; ///< signal strength, value depending on signal_scale value: ///< - SCALE_RELATIVE : 0...65535 (which means 0%...100%) ///< - SCALE DECIBEL : 0.0001 dBm units. This value is generally negative. @@ -60,25 +59,25 @@ struct tvh_input_stream_stats signal_status_scale_t snr_scale; /* Note: if tc_bit > 0, BER = ec_bit / tc_bit (0...1) else BER = ber (driver specific value) */ - int ec_bit; ///< ERROR_BIT_COUNT (same as unc?) - int tc_bit; ///< TOTAL_BIT_COUNT + int ec_bit; ///< ERROR_BIT_COUNT (same as unc?) + int tc_bit; ///< TOTAL_BIT_COUNT /* Note: PER = ec_block / tc_block (0...1) */ - int ec_block; ///< ERROR_BLOCK_COUNT - int tc_block; ///< TOTAL_BLOCK_COUNT + int ec_block; ///< ERROR_BLOCK_COUNT + int tc_block; ///< TOTAL_BLOCK_COUNT }; struct tvh_input_stream { LIST_ENTRY(tvh_input_stream) link; - char *uuid; ///< Unique ID of the entry (used for updates) - char *input_name; ///< Name of the parent input - char *stream_name; ///< Name for this stream - int subs_count; ///< Number of subcscriptions - int max_weight; ///< Current max weight + char* uuid; ///< Unique ID of the entry (used for updates) + char* input_name; ///< Name of the parent input + char* stream_name; ///< Name for this stream + int subs_count; ///< Number of subcscriptions + int max_weight; ///< Current max weight - struct mpegts_apids *pids; ///< active PID list + struct mpegts_apids* pids; ///< active PID list tvh_input_stream_stats_t stats; }; @@ -91,11 +90,11 @@ struct tvh_input { LIST_ENTRY(tvh_input) ti_link; - void (*ti_get_streams) (tvh_input_t *, tvh_input_stream_list_t*); - void (*ti_clear_stats) (tvh_input_t *); + void (*ti_get_streams)(tvh_input_t*, tvh_input_stream_list_t*); + void (*ti_clear_stats)(tvh_input_t*); - struct htsmsg *(*ti_wizard_get) (tvh_input_t *, const char *); - void (*ti_wizard_set) (tvh_input_t *, struct htsmsg *, const char *); + struct htsmsg* (*ti_wizard_get)(tvh_input_t*, const char*); + void (*ti_wizard_set)(tvh_input_t*, struct htsmsg*, const char*); }; /* @@ -109,23 +108,22 @@ struct tvh_input_instance { tvh_mutex_t tii_stats_mutex; tvh_input_stream_stats_t tii_stats; - void (*tii_delete) (tvh_input_instance_t *tii); - void (*tii_clear_stats) (tvh_input_instance_t *tii); + void (*tii_delete)(tvh_input_instance_t* tii); + void (*tii_clear_stats)(tvh_input_instance_t* tii); }; /* * Generic hardware super-class */ struct tvh_hardware { - idnode_t th_id; - LIST_ENTRY(tvh_hardware) th_link; + idnode_t th_id; + LIST_ENTRY(tvh_hardware) th_link; }; void tvh_hardware_init(void); -void *tvh_hardware_create0 - ( void *o, const idclass_t *idc, const char *uuid, htsmsg_t *conf ); -void tvh_hardware_delete ( tvh_hardware_t *th ); +void* tvh_hardware_create0(void* o, const idclass_t* idc, const char* uuid, htsmsg_t* conf); +void tvh_hardware_delete(tvh_hardware_t* th); /* * Class and Global list defs @@ -136,26 +134,26 @@ extern const idclass_t tvh_input_instance_class; extern tvh_input_list_t tvh_inputs; extern tvh_hardware_list_t tvh_hardware; -#define TVH_INPUT_FOREACH(x) LIST_FOREACH(x, &tvh_inputs, ti_link) -#define TVH_HARDWARE_FOREACH(x) LIST_FOREACH(x, &tvh_hardware, th_link) +#define TVH_INPUT_FOREACH(x) LIST_FOREACH (x, &tvh_inputs, ti_link) +#define TVH_HARDWARE_FOREACH(x) LIST_FOREACH (x, &tvh_hardware, th_link) /* * Methods */ -htsmsg_t * tvh_input_stream_create_msg ( tvh_input_stream_t *st ); +htsmsg_t* tvh_input_stream_create_msg(tvh_input_stream_t* st); -void tvh_input_stream_destroy ( tvh_input_stream_t *st ); +void tvh_input_stream_destroy(tvh_input_stream_t* st); -static inline tvh_input_t * -tvh_input_find_by_uuid(const char *uuid) - { return (tvh_input_t*)idnode_find(uuid, &tvh_input_class, NULL); } +static inline tvh_input_t* tvh_input_find_by_uuid(const char* uuid) { + return (tvh_input_t*)idnode_find(uuid, &tvh_input_class, NULL); +} -static inline tvh_input_instance_t * -tvh_input_instance_find_by_uuid(const char *uuid) - { return (tvh_input_instance_t*)idnode_find(uuid, &tvh_input_instance_class, NULL); } +static inline tvh_input_instance_t* tvh_input_instance_find_by_uuid(const char* uuid) { + return (tvh_input_instance_t*)idnode_find(uuid, &tvh_input_instance_class, NULL); +} -void tvh_input_instance_clear_stats ( tvh_input_instance_t *tii ); +void tvh_input_instance_clear_stats(tvh_input_instance_t* tii); /* * Input subsystem includes diff --git a/src/input/mpegts.c b/src/input/mpegts.c index fca4f3429..d4d094911 100644 --- a/src/input/mpegts.c +++ b/src/input/mpegts.c @@ -25,10 +25,11 @@ struct mpegts_listeners mpegts_listeners; extern memoryinfo_t mpegts_input_queue_memoryinfo; extern memoryinfo_t mpegts_input_table_memoryinfo; -void -mpegts_init ( int linuxdvb_mask, int nosatip, str_list_t *satip_client, - str_list_t *tsfiles, int tstuners ) -{ +void mpegts_init(int linuxdvb_mask, + int nosatip, + str_list_t* satip_client, + str_list_t* tsfiles, + int tstuners) { /* Register classes (avoid API 400 errors due to not yet defined) */ idclass_register(&mpegts_network_class); idclass_register(&mpegts_mux_class); @@ -55,7 +56,7 @@ mpegts_init ( int linuxdvb_mask, int nosatip, str_list_t *satip_client, /* TS files */ #if ENABLE_TSFILE - if(tsfiles->num) { + if (tsfiles->num) { int i; tsfile_init(tstuners ?: tsfiles->num); for (i = 0; i < tsfiles->num; i++) @@ -78,7 +79,7 @@ mpegts_init ( int linuxdvb_mask, int nosatip, str_list_t *satip_client, satip_init(nosatip, satip_client); #endif - /* HDHomerun client */ + /* HDHomerun client */ #if ENABLE_HDHOMERUN_CLIENT tvhdhomerun_init(); #endif @@ -87,12 +88,9 @@ mpegts_init ( int linuxdvb_mask, int nosatip, str_list_t *satip_client, #if ENABLE_MPEGTS mpegts_mux_sched_init(); #endif - } -void -mpegts_done ( void ) -{ +void mpegts_done(void) { tvhftrace(LS_MAIN, mpegts_network_scan_done); tvhftrace(LS_MAIN, mpegts_mux_sched_done); #if ENABLE_MPEGTS_DVB diff --git a/src/input/mpegts.h b/src/input/mpegts.h index 9c4c57b73..fd700c99f 100644 --- a/src/input/mpegts.h +++ b/src/input/mpegts.h @@ -32,36 +32,35 @@ #include "mpegts/dvb.h" #include "subscriptions.h" -#define MPEGTS_ONID_NONE 0x10000 -#define MPEGTS_TSID_NONE 0x10000 -#define MPEGTS_FULLMUX_PID 0x2000 -#define MPEGTS_TABLES_PID 0x2001 -#define MPEGTS_PID_NONE 0xFFFF +#define MPEGTS_ONID_NONE 0x10000 +#define MPEGTS_TSID_NONE 0x10000 +#define MPEGTS_FULLMUX_PID 0x2000 +#define MPEGTS_TABLES_PID 0x2001 +#define MPEGTS_PID_NONE 0xFFFF /* Types */ -typedef struct mpegts_apid mpegts_apid_t; -typedef struct mpegts_apids mpegts_apids_t; -typedef struct mpegts_table mpegts_table_t; -typedef struct mpegts_network mpegts_network_t; -typedef struct mpegts_mux mpegts_mux_t; -typedef struct mpegts_service mpegts_service_t; -typedef struct mpegts_mux_instance mpegts_mux_instance_t; -typedef struct mpegts_mux_sub mpegts_mux_sub_t; -typedef struct mpegts_input mpegts_input_t; -typedef struct mpegts_table_feed mpegts_table_feed_t; -typedef struct mpegts_network_link mpegts_network_link_t; -typedef struct mpegts_packet mpegts_packet_t; -typedef struct mpegts_pcr mpegts_pcr_t; -typedef struct mpegts_buffer mpegts_buffer_t; +typedef struct mpegts_apid mpegts_apid_t; +typedef struct mpegts_apids mpegts_apids_t; +typedef struct mpegts_table mpegts_table_t; +typedef struct mpegts_network mpegts_network_t; +typedef struct mpegts_mux mpegts_mux_t; +typedef struct mpegts_service mpegts_service_t; +typedef struct mpegts_mux_instance mpegts_mux_instance_t; +typedef struct mpegts_mux_sub mpegts_mux_sub_t; +typedef struct mpegts_input mpegts_input_t; +typedef struct mpegts_table_feed mpegts_table_feed_t; +typedef struct mpegts_network_link mpegts_network_link_t; +typedef struct mpegts_packet mpegts_packet_t; +typedef struct mpegts_pcr mpegts_pcr_t; +typedef struct mpegts_buffer mpegts_buffer_t; /* Lists */ -typedef LIST_HEAD (,mpegts_network) mpegts_network_list_t; -typedef LIST_HEAD (,mpegts_input) mpegts_input_list_t; -typedef TAILQ_HEAD(mpegts_mux_queue,mpegts_mux) mpegts_mux_queue_t; -typedef LIST_HEAD (,mpegts_mux) mpegts_mux_list_t; -typedef LIST_HEAD (,mpegts_network_link) mpegts_network_link_list_t; -typedef TAILQ_HEAD(mpegts_table_feed_queue, mpegts_table_feed) - mpegts_table_feed_queue_t; +typedef LIST_HEAD(, mpegts_network) mpegts_network_list_t; +typedef LIST_HEAD(, mpegts_input) mpegts_input_list_t; +typedef TAILQ_HEAD(mpegts_mux_queue, mpegts_mux) mpegts_mux_queue_t; +typedef LIST_HEAD(, mpegts_mux) mpegts_mux_list_t; +typedef LIST_HEAD(, mpegts_network_link) mpegts_network_link_list_t; +typedef TAILQ_HEAD(mpegts_table_feed_queue, mpegts_table_feed) mpegts_table_feed_queue_t; /* Classes */ extern const idclass_t mpegts_network_class; @@ -75,9 +74,12 @@ extern const idclass_t mpegts_input_class; * Setup / Tear down * *************************************************************************/ -void mpegts_init ( int linuxdvb_mask, int nosatip, str_list_t *satip_client, - str_list_t *tsfiles, int tstuners ); -void mpegts_done ( void ); +void mpegts_init(int linuxdvb_mask, + int nosatip, + str_list_t* satip_client, + str_list_t* tsfiles, + int tstuners); +void mpegts_done(void); /* ************************************************************************** * PIDs @@ -89,48 +91,53 @@ struct mpegts_apid { }; struct mpegts_apids { - mpegts_apid_t *pids; - int alloc; - int count; - int all; - int sorted; + mpegts_apid_t* pids; + int alloc; + int count; + int all; + int sorted; }; -int mpegts_pid_init ( mpegts_apids_t *pids ); -void mpegts_pid_done ( mpegts_apids_t *pids ); -mpegts_apids_t *mpegts_pid_alloc ( void ); -void mpegts_pid_destroy ( mpegts_apids_t **pids ); -void mpegts_pid_reset ( mpegts_apids_t *pids ); -int mpegts_pid_add ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight ); -int mpegts_pid_add_group ( mpegts_apids_t *pids, mpegts_apids_t *vals ); -int mpegts_pid_del ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight ); -int mpegts_pid_del_group ( mpegts_apids_t *pids, mpegts_apids_t *vals ); -int mpegts_pid_find_windex ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight ); -int mpegts_pid_find_rindex ( mpegts_apids_t *pids, uint16_t pid ); -static inline int mpegts_pid_wexists ( mpegts_apids_t *pids, uint16_t pid, uint16_t weight ) - { return pids && (pids->all || mpegts_pid_find_windex(pids, pid, weight) >= 0); } -static inline int mpegts_pid_rexists ( mpegts_apids_t *pids, uint16_t pid ) - { return pids && (pids->all || mpegts_pid_find_rindex(pids, pid) >= 0); } -int mpegts_pid_copy ( mpegts_apids_t *dst, mpegts_apids_t *src ); -int mpegts_pid_cmp ( mpegts_apids_t *a, mpegts_apids_t *b ); -int mpegts_pid_compare ( mpegts_apids_t *dst, mpegts_apids_t *src, - mpegts_apids_t *add, mpegts_apids_t *del ); -int mpegts_pid_compare_weight ( mpegts_apids_t *dst, mpegts_apids_t *src, - mpegts_apids_t *add, mpegts_apids_t *del ); -int mpegts_pid_weighted ( mpegts_apids_t *dst, mpegts_apids_t *src, int limit, int mweight ); -int mpegts_pid_dump ( mpegts_apids_t *pids, char *buf, int len, int wflag, int raw ); +int mpegts_pid_init(mpegts_apids_t* pids); +void mpegts_pid_done(mpegts_apids_t* pids); +mpegts_apids_t* mpegts_pid_alloc(void); +void mpegts_pid_destroy(mpegts_apids_t** pids); +void mpegts_pid_reset(mpegts_apids_t* pids); +int mpegts_pid_add(mpegts_apids_t* pids, uint16_t pid, uint16_t weight); +int mpegts_pid_add_group(mpegts_apids_t* pids, mpegts_apids_t* vals); +int mpegts_pid_del(mpegts_apids_t* pids, uint16_t pid, uint16_t weight); +int mpegts_pid_del_group(mpegts_apids_t* pids, mpegts_apids_t* vals); +int mpegts_pid_find_windex(mpegts_apids_t* pids, uint16_t pid, uint16_t weight); +int mpegts_pid_find_rindex(mpegts_apids_t* pids, uint16_t pid); +static inline int mpegts_pid_wexists(mpegts_apids_t* pids, uint16_t pid, uint16_t weight) { + return pids && (pids->all || mpegts_pid_find_windex(pids, pid, weight) >= 0); +} +static inline int mpegts_pid_rexists(mpegts_apids_t* pids, uint16_t pid) { + return pids && (pids->all || mpegts_pid_find_rindex(pids, pid) >= 0); +} +int mpegts_pid_copy(mpegts_apids_t* dst, mpegts_apids_t* src); +int mpegts_pid_cmp(mpegts_apids_t* a, mpegts_apids_t* b); +int mpegts_pid_compare(mpegts_apids_t* dst, + mpegts_apids_t* src, + mpegts_apids_t* add, + mpegts_apids_t* del); +int mpegts_pid_compare_weight(mpegts_apids_t* dst, + mpegts_apids_t* src, + mpegts_apids_t* add, + mpegts_apids_t* del); +int mpegts_pid_weighted(mpegts_apids_t* dst, mpegts_apids_t* src, int limit, int mweight); +int mpegts_pid_dump(mpegts_apids_t* pids, char* buf, int len, int wflag, int raw); /* ************************************************************************** * Data / SI processing * *************************************************************************/ -struct mpegts_packet -{ - TAILQ_ENTRY(mpegts_packet) mp_link; - size_t mp_len; - mpegts_mux_t *mp_mux; - uint8_t mp_cc_restart; - uint8_t mp_data[0]; +struct mpegts_packet { + TAILQ_ENTRY(mpegts_packet) mp_link; + size_t mp_len; + mpegts_mux_t* mp_mux; + uint8_t mp_cc_restart; + uint8_t mp_data[0]; }; struct mpegts_pcr { @@ -139,76 +146,75 @@ struct mpegts_pcr { uint16_t pcr_pid; }; -#define MPEGTS_DATA_CC_RESTART (1<<0) -#define MPEGTS_DATA_REMOVE_SCRAMBLED (1<<1) +#define MPEGTS_DATA_CC_RESTART (1 << 0) +#define MPEGTS_DATA_REMOVE_SCRAMBLED (1 << 1) -typedef int (*mpegts_table_callback_t) - ( mpegts_table_t*, const uint8_t *buf, int len, int tableid ); +typedef int (*mpegts_table_callback_t)(mpegts_table_t*, const uint8_t* buf, int len, int tableid); -struct mpegts_table_mux_cb -{ +struct mpegts_table_mux_cb { int tag; - int (*cb) ( mpegts_table_t*, mpegts_mux_t *mm, uint16_t nbid, - const uint8_t dtag, const uint8_t *dptr, int dlen ); + int (*cb)(mpegts_table_t*, + mpegts_mux_t* mm, + uint16_t nbid, + const uint8_t dtag, + const uint8_t* dptr, + int dlen); }; -typedef struct mpegts_pid_sub -{ +typedef struct mpegts_pid_sub { RB_ENTRY(mpegts_pid_sub) mps_link; LIST_ENTRY(mpegts_pid_sub) mps_raw_link; LIST_ENTRY(mpegts_pid_sub) mps_svcraw_link; -#define MPS_NONE 0x00 -#define MPS_ALL 0x01 -#define MPS_RAW 0x02 -#define MPS_STREAM 0x04 -#define MPS_SERVICE 0x08 -#define MPS_TABLE 0x10 -#define MPS_FTABLE 0x20 -#define MPS_TABLES 0x40 -#define MPS_NOPOSTDEMUX 0x80 - int mps_type; -#define MPS_WEIGHT_PAT 1000 -#define MPS_WEIGHT_CAT 999 -#define MPS_WEIGHT_SDT 999 -#define MPS_WEIGHT_NIT 999 -#define MPS_WEIGHT_BAT 999 -#define MPS_WEIGHT_VCT 999 -#define MPS_WEIGHT_EIT 999 -#define MPS_WEIGHT_ETT 999 -#define MPS_WEIGHT_MGT 999 -#define MPS_WEIGHT_PMT 998 -#define MPS_WEIGHT_PCR 997 -#define MPS_WEIGHT_CA 996 -#define MPS_WEIGHT_VIDEO 900 -#define MPS_WEIGHT_AUDIO 800 -#define MPS_WEIGHT_SUBTITLE 700 -#define MPS_WEIGHT_ESOTHER 500 -#define MPS_WEIGHT_RAW 400 -#define MPS_WEIGHT_NIT2 300 -#define MPS_WEIGHT_SDT2 300 -#define MPS_WEIGHT_ALLLIMIT 200 /* values under this limit does not switch */ - /* input to the unfiltered PIDs (all) mode */ +#define MPS_NONE 0x00 +#define MPS_ALL 0x01 +#define MPS_RAW 0x02 +#define MPS_STREAM 0x04 +#define MPS_SERVICE 0x08 +#define MPS_TABLE 0x10 +#define MPS_FTABLE 0x20 +#define MPS_TABLES 0x40 +#define MPS_NOPOSTDEMUX 0x80 + int mps_type; +#define MPS_WEIGHT_PAT 1000 +#define MPS_WEIGHT_CAT 999 +#define MPS_WEIGHT_SDT 999 +#define MPS_WEIGHT_NIT 999 +#define MPS_WEIGHT_BAT 999 +#define MPS_WEIGHT_VCT 999 +#define MPS_WEIGHT_EIT 999 +#define MPS_WEIGHT_ETT 999 +#define MPS_WEIGHT_MGT 999 +#define MPS_WEIGHT_PMT 998 +#define MPS_WEIGHT_PCR 997 +#define MPS_WEIGHT_CA 996 +#define MPS_WEIGHT_VIDEO 900 +#define MPS_WEIGHT_AUDIO 800 +#define MPS_WEIGHT_SUBTITLE 700 +#define MPS_WEIGHT_ESOTHER 500 +#define MPS_WEIGHT_RAW 400 +#define MPS_WEIGHT_NIT2 300 +#define MPS_WEIGHT_SDT2 300 +#define MPS_WEIGHT_ALLLIMIT 200 /* values under this limit does not switch */ + /* input to the unfiltered PIDs (all) mode */ #define MPS_WEIGHT_TDT 102 #define MPS_WEIGHT_STT 102 #define MPS_WEIGHT_PMT_SCAN 101 #define MPS_WEIGHT_HBBTV_SCAN 100 int mps_weight; - void *mps_owner; + void* mps_owner; } mpegts_pid_sub_t; -typedef struct mpegts_pid -{ - int mp_pid; - int mp_type; // mask for all subscribers - int8_t mp_cc; - RB_HEAD(,mpegts_pid_sub) mp_subs; // subscribers to pid - LIST_HEAD(,mpegts_pid_sub) mp_raw_subs; - LIST_HEAD(,mpegts_pid_sub) mp_svc_subs; - RB_ENTRY(mpegts_pid) mp_link; +typedef struct mpegts_pid { + int mp_pid; + int mp_type; // mask for all subscribers + int8_t mp_cc; + RB_HEAD(, mpegts_pid_sub) mp_subs; // subscribers to pid + LIST_HEAD(, mpegts_pid_sub) mp_raw_subs; + LIST_HEAD(, mpegts_pid_sub) mp_svc_subs; + RB_ENTRY(mpegts_pid) mp_link; } mpegts_pid_t; -struct mpegts_table -{ +struct mpegts_table { mpegts_psi_table_t; /** @@ -247,9 +253,9 @@ struct mpegts_table */ TAILQ_ENTRY(mpegts_table) mt_defer_link; - mpegts_mux_t *mt_mux; + mpegts_mux_t* mt_mux; - void *mt_bat; + void* mt_bat; mpegts_table_callback_t mt_callback; uint8_t mt_subscribed; @@ -263,20 +269,20 @@ struct mpegts_table int mt_count; int mt_id; - - int mt_destroyed; // Refcounting - int mt_arefcount; + + int mt_destroyed; // Refcounting + int mt_arefcount; uint32_t mt_priv; - struct mpegts_table_mux_cb *mt_mux_cb; + struct mpegts_table_mux_cb* mt_mux_cb; - mpegts_service_t *mt_service; + mpegts_service_t* mt_service; tprofile_t mt_profile; - - void (*mt_destroy) (mpegts_table_t *mt); // Allow customisable destroy hook - // useful for dynamic allocation of - // the opaque field + + void (*mt_destroy)(mpegts_table_t* mt); // Allow customisable destroy hook + // useful for dynamic allocation of + // the opaque field }; /** @@ -287,13 +293,13 @@ struct mpegts_table struct mpegts_table_feed { TAILQ_ENTRY(mpegts_table_feed) mtf_link; - uint8_t mtf_cc_restart; - int mtf_len; - mpegts_mux_t *mtf_mux; - uint8_t mtf_tsb[0]; + uint8_t mtf_cc_restart; + int mtf_len; + mpegts_mux_t* mtf_mux; + uint8_t mtf_tsb[0]; }; -#define MPEGTS_MTF_ALLOC_CHUNK (21*188) +#define MPEGTS_MTF_ALLOC_CHUNK (21 * 188) /* ************************************************************************** * Logical network @@ -306,64 +312,64 @@ typedef enum { } mpegts_discovery_t; /* Network/Input linkage */ -struct mpegts_network_link -{ - int mnl_mark; - mpegts_input_t *mnl_input; - mpegts_network_t *mnl_network; +struct mpegts_network_link { + int mnl_mark; + mpegts_input_t* mnl_input; + mpegts_network_t* mnl_network; LIST_ENTRY(mpegts_network_link) mnl_mn_link; LIST_ENTRY(mpegts_network_link) mnl_mi_link; }; /* Network */ -struct mpegts_network -{ - idnode_t mn_id; +struct mpegts_network { + idnode_t mn_id; LIST_ENTRY(mpegts_network) mn_global_link; /* * Identification */ - char *mn_network_name; - char *mn_provider_network_name; - int mn_wizard; - uint8_t mn_wizard_free; + char* mn_network_name; + char* mn_provider_network_name; + int mn_wizard; + uint8_t mn_wizard_free; /* * Inputs */ - mpegts_network_link_list_t mn_inputs; + mpegts_network_link_list_t mn_inputs; /* * Multiplexes */ - mpegts_mux_list_t mn_muxes; + mpegts_mux_list_t mn_muxes; /* * Scanning */ - mpegts_mux_queue_t mn_scan_pend; // Pending muxes - mpegts_mux_queue_t mn_scan_ipend; // Pending muxes (idle) - mpegts_mux_queue_t mn_scan_active; // Active muxes - mtimer_t mn_scan_timer; // Timer for activity + mpegts_mux_queue_t mn_scan_pend; // Pending muxes + mpegts_mux_queue_t mn_scan_ipend; // Pending muxes (idle) + mpegts_mux_queue_t mn_scan_active; // Active muxes + mtimer_t mn_scan_timer; // Timer for activity mtimer_t mn_bouquet_timer; /* * Functions */ - void (*mn_delete) (mpegts_network_t*, int delconf); - void (*mn_display_name) (mpegts_network_t*, char *buf, size_t len); - int (*mn_bouquet_source) (mpegts_network_t*, char *buf, size_t len); - int (*mn_bouquet_comment) (mpegts_network_t*, char *buf, size_t len); - htsmsg_t * (*mn_config_save) (mpegts_network_t*, char *filename, size_t fsize); - mpegts_mux_t* (*mn_create_mux) - (mpegts_network_t*, void *origin, uint32_t onid, uint32_t tsid, - void *conf, int force); - mpegts_service_t* (*mn_create_service) - (mpegts_mux_t*, uint16_t sid, uint16_t pmt_pid); - const idclass_t* (*mn_mux_class) (mpegts_network_t*); - mpegts_mux_t * (*mn_mux_create2) (mpegts_network_t *mn, htsmsg_t *conf); - void (*mn_scan) (mpegts_network_t*); + void (*mn_delete)(mpegts_network_t*, int delconf); + void (*mn_display_name)(mpegts_network_t*, char* buf, size_t len); + int (*mn_bouquet_source)(mpegts_network_t*, char* buf, size_t len); + int (*mn_bouquet_comment)(mpegts_network_t*, char* buf, size_t len); + htsmsg_t* (*mn_config_save)(mpegts_network_t*, char* filename, size_t fsize); + mpegts_mux_t* (*mn_create_mux)(mpegts_network_t*, + void* origin, + uint32_t onid, + uint32_t tsid, + void* conf, + int force); + mpegts_service_t* (*mn_create_service)(mpegts_mux_t*, uint16_t sid, uint16_t pmt_pid); + const idclass_t* (*mn_mux_class)(mpegts_network_t*); + mpegts_mux_t* (*mn_mux_create2)(mpegts_network_t* mn, htsmsg_t* conf); + void (*mn_scan)(mpegts_network_t*); /* * Configuration @@ -374,7 +380,7 @@ struct mpegts_network int mn_autodiscovery; int mn_skipinitscan; int mn_bouquet; - char *mn_charset; + char* mn_charset; int mn_idlescan; int mn_ignore_chnum; int mn_sid_chnum; @@ -382,16 +388,14 @@ struct mpegts_network int mn_satpos; }; -typedef enum mpegts_mux_scan_state -{ - MM_SCAN_STATE_IDLE, // Nothing - MM_SCAN_STATE_PEND, // Queue'd pending scan - MM_SCAN_STATE_IPEND, // Queue'd pending scan - idle queue - MM_SCAN_STATE_ACTIVE, // Scan is active +typedef enum mpegts_mux_scan_state { + MM_SCAN_STATE_IDLE, // Nothing + MM_SCAN_STATE_PEND, // Queue'd pending scan + MM_SCAN_STATE_IPEND, // Queue'd pending scan - idle queue + MM_SCAN_STATE_ACTIVE, // Scan is active } mpegts_mux_scan_state_t; -typedef enum mpegts_mux_scan_result -{ +typedef enum mpegts_mux_scan_result { MM_SCAN_NONE, MM_SCAN_OK, MM_SCAN_FAIL, @@ -402,15 +406,13 @@ typedef enum mpegts_mux_scan_result #define MM_SCAN_CHECK_OK(mm) \ ((mm)->mm_scan_result == MM_SCAN_OK || (mm)->mm_scan_result == MM_SCAN_PARTIAL) -enum mpegts_mux_enable -{ +enum mpegts_mux_enable { MM_IGNORE = -1, - MM_DISABLE = 0, - MM_ENABLE = 1, + MM_DISABLE = 0, + MM_ENABLE = 1, }; -enum mpegts_mux_epg_flag -{ +enum mpegts_mux_epg_flag { MM_EPG_DISABLE, MM_EPG_ENABLE, MM_EPG_FORCE, @@ -418,71 +420,69 @@ enum mpegts_mux_epg_flag MM_EPG_DETECTED }; -enum mpegts_mux_ac3_flag -{ +enum mpegts_mux_ac3_flag { MM_AC3_STANDARD, MM_AC3_PMT_06, MM_AC3_PMT_N05, }; /* Multiplex */ -struct mpegts_mux -{ +struct mpegts_mux { idnode_t mm_id; int mm_refcount; /* * Identification */ - - LIST_ENTRY(mpegts_mux) mm_network_link; - mpegts_network_t *mm_network; - char *mm_nicename; - char *mm_provider_network_name; - uint32_t mm_onid; - uint32_t mm_tsid; - int mm_tsid_checks; - int mm_tsid_accept_zero_value; - tvhlog_limit_t mm_tsid_loglimit; - int64_t mm_start_monoclock; - time_t mm_created; - - int mm_update_pids_flag; - mtimer_t mm_update_pids_timer; + + LIST_ENTRY(mpegts_mux) mm_network_link; + mpegts_network_t* mm_network; + char* mm_nicename; + char* mm_provider_network_name; + uint32_t mm_onid; + uint32_t mm_tsid; + int mm_tsid_checks; + int mm_tsid_accept_zero_value; + tvhlog_limit_t mm_tsid_loglimit; + int64_t mm_start_monoclock; + time_t mm_created; + + int mm_update_pids_flag; + mtimer_t mm_update_pids_timer; /* * Services */ - - LIST_HEAD(,mpegts_service) mm_services; + + LIST_HEAD(, mpegts_service) mm_services; /* * Scanning */ - time_t mm_scan_first; ///< Time for the first successful scan - time_t mm_scan_last_seen; ///< Time for the last successful scan + time_t mm_scan_first; ///< Time for the first successful scan + time_t mm_scan_last_seen; ///< Time for the last successful scan mpegts_mux_scan_result_t mm_scan_result; ///< Result of last scan int mm_scan_weight; ///< Scan priority int mm_scan_flags; ///< Subscription flags int mm_scan_init; ///< Flag to timeout handler mtimer_t mm_scan_timeout; ///< Timer to handle timeout - TAILQ_ENTRY(mpegts_mux) mm_scan_link; ///< Link to Queue - mpegts_mux_scan_state_t mm_scan_state; ///< Scanning state + TAILQ_ENTRY(mpegts_mux) mm_scan_link; ///< Link to Queue + mpegts_mux_scan_state_t mm_scan_state; ///< Scanning state - void *mm_dmc_origin; - int64_t mm_dmc_origin_expire; + void* mm_dmc_origin; + int64_t mm_dmc_origin_expire; - char *mm_fastscan_muxes; + char* mm_fastscan_muxes; /* * Physical instances */ LIST_HEAD(, mpegts_mux_instance) mm_instances; - mpegts_mux_instance_t *mm_active; - LIST_HEAD(,service) mm_transports; + mpegts_mux_instance_t* mm_active; + LIST_HEAD(, service) mm_transports; /* * Raw subscriptions @@ -494,73 +494,72 @@ struct mpegts_mux * Data processing */ - uint64_t mm_input_pos; - RB_HEAD(, mpegts_pid) mm_pids; + uint64_t mm_input_pos; + RB_HEAD(, mpegts_pid) mm_pids; LIST_HEAD(, mpegts_pid_sub) mm_all_subs; - int mm_last_pid; - mpegts_pid_t *mm_last_mp; + int mm_last_pid; + mpegts_pid_t* mm_last_mp; - int mm_num_tables; - LIST_HEAD(, mpegts_table) mm_tables; - TAILQ_HEAD(, mpegts_table) mm_defer_tables; - tvh_mutex_t mm_tables_lock; - TAILQ_HEAD(, mpegts_table) mm_table_queue; + int mm_num_tables; + LIST_HEAD(, mpegts_table) mm_tables; + TAILQ_HEAD(, mpegts_table) mm_defer_tables; + tvh_mutex_t mm_tables_lock; + TAILQ_HEAD(, mpegts_table) mm_table_queue; - LIST_HEAD(, caid) mm_descrambler_caids; + LIST_HEAD(, caid) mm_descrambler_caids; TAILQ_HEAD(, descrambler_table) mm_descrambler_tables; TAILQ_HEAD(, descrambler_emm) mm_descrambler_emms; - tvh_mutex_t mm_descrambler_lock; - int mm_descrambler_flush; + tvh_mutex_t mm_descrambler_lock; + int mm_descrambler_flush; /* * Functions */ - void (*mm_delete) (mpegts_mux_t *mm, int delconf); - void (*mm_free) (mpegts_mux_t *mm); - htsmsg_t *(*mm_config_save) (mpegts_mux_t *mm, char *filename, size_t fsize); - void (*mm_display_name) (mpegts_mux_t*, char *buf, size_t len); - int (*mm_is_enabled) (mpegts_mux_t *mm); - void (*mm_stop) (mpegts_mux_t *mm, int force, int reason); - void (*mm_open_table) (mpegts_mux_t*,mpegts_table_t*,int subscribe); - void (*mm_unsubscribe_table)(mpegts_mux_t*,mpegts_table_t*); - void (*mm_close_table) (mpegts_mux_t*,mpegts_table_t*); - void (*mm_create_instances) (mpegts_mux_t*); - int (*mm_is_epg) (mpegts_mux_t*); + void (*mm_delete)(mpegts_mux_t* mm, int delconf); + void (*mm_free)(mpegts_mux_t* mm); + htsmsg_t* (*mm_config_save)(mpegts_mux_t* mm, char* filename, size_t fsize); + void (*mm_display_name)(mpegts_mux_t*, char* buf, size_t len); + int (*mm_is_enabled)(mpegts_mux_t* mm); + void (*mm_stop)(mpegts_mux_t* mm, int force, int reason); + void (*mm_open_table)(mpegts_mux_t*, mpegts_table_t*, int subscribe); + void (*mm_unsubscribe_table)(mpegts_mux_t*, mpegts_table_t*); + void (*mm_close_table)(mpegts_mux_t*, mpegts_table_t*); + void (*mm_create_instances)(mpegts_mux_t*); + int (*mm_is_epg)(mpegts_mux_t*); /* * Configuration */ - char *mm_crid_authority; + char* mm_crid_authority; int mm_enabled; int mm_epg; - char *mm_epg_module_id; - char *mm_charset; + char* mm_epg_module_id; + char* mm_charset; int mm_pmt_ac3; int mm_eit_tsid_nocheck; uint16_t mm_sid_filter; }; -#define PREFCAPID_OFF 0 -#define PREFCAPID_ON 1 -#define PREFCAPID_FORCE 2 +#define PREFCAPID_OFF 0 +#define PREFCAPID_ON 1 +#define PREFCAPID_FORCE 2 /* Service */ -struct mpegts_service -{ +struct mpegts_service { service_t; // Parent - int (*s_update_pids)(mpegts_service_t *t, struct mpegts_apids *pids); - int (*s_link)(mpegts_service_t *master, mpegts_service_t *slave); - int (*s_unlink)(mpegts_service_t *master, mpegts_service_t *slave); + int (*s_update_pids)(mpegts_service_t* t, struct mpegts_apids* pids); + int (*s_link)(mpegts_service_t* master, mpegts_service_t* slave); + int (*s_unlink)(mpegts_service_t* master, mpegts_service_t* slave); - int s_dvb_subscription_flags; - int s_dvb_subscription_weight; + int s_dvb_subscription_flags; + int s_dvb_subscription_weight; - mpegts_apids_t *s_pids; - idnode_set_t s_masters; - idnode_set_t s_slaves; - mpegts_apids_t *s_slaves_pids; + mpegts_apids_t* s_pids; + idnode_set_t s_masters; + idnode_set_t s_slaves; + mpegts_apids_t* s_slaves_pids; /* * Fields defined by DVB standard EN 300 468 @@ -569,12 +568,12 @@ struct mpegts_service uint32_t s_dvb_channel_num; uint16_t s_dvb_channel_minor; uint8_t s_dvb_channel_dtag; - char *s_dvb_svcname; - char *s_dvb_provider; - char *s_dvb_cridauth; + char* s_dvb_svcname; + char* s_dvb_provider; + char* s_dvb_cridauth; uint16_t s_dvb_servicetype; int s_dvb_ignore_eit; - char *s_dvb_charset; + char* s_dvb_charset; uint16_t s_dvb_prefcapid; int s_dvb_prefcapid_lock; time_t s_dvb_created; @@ -595,8 +594,8 @@ struct mpegts_service */ LIST_ENTRY(mpegts_service) s_dvb_mux_link; - mpegts_mux_t *s_dvb_mux; - mpegts_input_t *s_dvb_active_input; + mpegts_mux_t* s_dvb_mux; + mpegts_input_t* s_dvb_active_input; /* * Streaming elements @@ -608,22 +607,21 @@ struct mpegts_service * When a subscription request SMT_MPEGTS, chunk them together * in order to reduce load. */ - sbuf_t s_tsbuf; + sbuf_t s_tsbuf; int64_t s_tsbuf_last; /** * PCR drift compensation. This should really be per-packet. */ - int64_t s_pcr_drift; + int64_t s_pcr_drift; /** * PMT/CAT monitoring */ - uint8_t s_cat_opened; - mpegts_table_t *s_pmt_mon; ///< Table entry for monitoring PMT - mpegts_table_t *s_cat_mon; ///< Table entry for monitoring CAT - + uint8_t s_cat_opened; + mpegts_table_t* s_pmt_mon; ///< Table entry for monitoring PMT + mpegts_table_t* s_cat_mon; ///< Table entry for monitoring CAT }; /* ************************************************************************** @@ -631,63 +629,59 @@ struct mpegts_service * *************************************************************************/ /* Physical mux instance */ -struct mpegts_mux_instance -{ +struct mpegts_mux_instance { tvh_input_instance_t; LIST_ENTRY(mpegts_mux_instance) mmi_mux_link; LIST_ENTRY(mpegts_mux_instance) mmi_active_link; streaming_pad_t mmi_streaming_pad; - - mpegts_mux_t *mmi_mux; - mpegts_input_t *mmi_input; - int mmi_start_weight; - int mmi_tune_failed; + mpegts_mux_t* mmi_mux; + mpegts_input_t* mmi_input; + + int mmi_start_weight; + int mmi_tune_failed; }; -struct mpegts_mux_sub -{ - RB_ENTRY(mpegts_mux_sub) mms_link; - void *mms_src; - int mms_weight; +struct mpegts_mux_sub { + RB_ENTRY(mpegts_mux_sub) mms_link; + void* mms_src; + int mms_weight; }; enum mpegts_input_is_enabled { MI_IS_ENABLED_RETRY = -1, MI_IS_ENABLED_NEVER = 0, - MI_IS_ENABLED_OK = 1, + MI_IS_ENABLED_OK = 1, }; /* Input source */ -struct mpegts_input -{ +struct mpegts_input { tvh_input_t; int mi_enabled; int mi_instance; - char *mi_name; + char* mi_name; int mi_priority; int mi_streaming_priority; int mi_ota_epg; - int mi_initscan; - int mi_idlescan; + int mi_initscan; + int mi_idlescan; uint32_t mi_free_weight; - char *mi_linked; + char* mi_linked; LIST_ENTRY(mpegts_input) mi_global_link; mpegts_network_link_list_t mi_networks; - LIST_HEAD(,tvh_input_instance) mi_mux_instances; - + LIST_HEAD(, tvh_input_instance) mi_mux_instances; /* * Status @@ -698,64 +692,64 @@ struct mpegts_input * Input processing */ - int mi_running; /* threads running */ + int mi_running; /* threads running */ int64_t mi_last_dispatch; /* Data input */ // Note: this section is protected by mi_input_lock - pthread_t mi_input_tid; - mtimer_t mi_input_thread_start; - tvh_mutex_t mi_input_lock; - tvh_cond_t mi_input_cond; - TAILQ_HEAD(,mpegts_packet) mi_input_queue; - uint64_t mi_input_queue_size; - tvhlog_limit_t mi_input_queue_loglimit; - qprofile_t mi_qprofile; - int mi_remove_scrambled_bits; + pthread_t mi_input_tid; + mtimer_t mi_input_thread_start; + tvh_mutex_t mi_input_lock; + tvh_cond_t mi_input_cond; + TAILQ_HEAD(, mpegts_packet) mi_input_queue; + uint64_t mi_input_queue_size; + tvhlog_limit_t mi_input_queue_loglimit; + qprofile_t mi_qprofile; + int mi_remove_scrambled_bits; /* Data processing/output */ // Note: this lock (mi_output_lock) protects all the remaining // data fields (excluding the callback functions) - tvh_mutex_t mi_output_lock; + tvh_mutex_t mi_output_lock; /* Active sources */ - LIST_HEAD(,mpegts_mux_instance) mi_mux_active; + LIST_HEAD(, mpegts_mux_instance) mi_mux_active; /* Table processing */ - pthread_t mi_table_tid; - tvh_cond_t mi_table_cond; - mpegts_table_feed_queue_t mi_table_queue; - uint64_t mi_table_queue_size; - tvhlog_limit_t mi_table_queue_loglimit; + pthread_t mi_table_tid; + tvh_cond_t mi_table_cond; + mpegts_table_feed_queue_t mi_table_queue; + uint64_t mi_table_queue_size; + tvhlog_limit_t mi_table_queue_loglimit; /* DBus */ #if ENABLE_DBUS_1 - int64_t mi_dbus_subs; + int64_t mi_dbus_subs; #endif /* * Functions */ - int (*mi_is_enabled) (mpegts_input_t*, mpegts_mux_t *mm, int flags, int weight); + int (*mi_is_enabled)(mpegts_input_t*, mpegts_mux_t* mm, int flags, int weight); void (*mi_enabled_updated)(mpegts_input_t*); - void (*mi_display_name) (mpegts_input_t*, char *buf, size_t len); - int (*mi_get_weight) (mpegts_input_t*, mpegts_mux_t *mm, int flags, int weight); - int (*mi_get_priority) (mpegts_input_t*, mpegts_mux_t *mm, int flags); - int (*mi_get_grace) (mpegts_input_t*, mpegts_mux_t *mm); - int (*mi_warm_mux) (mpegts_input_t*,mpegts_mux_instance_t*); - int (*mi_start_mux) (mpegts_input_t*,mpegts_mux_instance_t*, int weight); - void (*mi_stop_mux) (mpegts_input_t*,mpegts_mux_instance_t*); - void (*mi_open_service) (mpegts_input_t*,mpegts_service_t*, int flags, int first, int weight); - void (*mi_close_service) (mpegts_input_t*,mpegts_service_t*); - void (*mi_update_pids) (mpegts_input_t*,mpegts_mux_t*); - void (*mi_create_mux_instance) (mpegts_input_t*,mpegts_mux_t*); - void (*mi_started_mux) (mpegts_input_t*,mpegts_mux_instance_t*); - void (*mi_stopping_mux) (mpegts_input_t*,mpegts_mux_instance_t*); - void (*mi_stopped_mux) (mpegts_input_t*,mpegts_mux_instance_t*); - int (*mi_has_subscription) (mpegts_input_t*, mpegts_mux_t *mm); - void (*mi_error) (mpegts_input_t*, mpegts_mux_t *, int tss_flags); - void (*mi_empty_status) (mpegts_input_t*, tvh_input_stream_t *); - idnode_set_t *(*mi_network_list) (mpegts_input_t*); + void (*mi_display_name)(mpegts_input_t*, char* buf, size_t len); + int (*mi_get_weight)(mpegts_input_t*, mpegts_mux_t* mm, int flags, int weight); + int (*mi_get_priority)(mpegts_input_t*, mpegts_mux_t* mm, int flags); + int (*mi_get_grace)(mpegts_input_t*, mpegts_mux_t* mm); + int (*mi_warm_mux)(mpegts_input_t*, mpegts_mux_instance_t*); + int (*mi_start_mux)(mpegts_input_t*, mpegts_mux_instance_t*, int weight); + void (*mi_stop_mux)(mpegts_input_t*, mpegts_mux_instance_t*); + void (*mi_open_service)(mpegts_input_t*, mpegts_service_t*, int flags, int first, int weight); + void (*mi_close_service)(mpegts_input_t*, mpegts_service_t*); + void (*mi_update_pids)(mpegts_input_t*, mpegts_mux_t*); + void (*mi_create_mux_instance)(mpegts_input_t*, mpegts_mux_t*); + void (*mi_started_mux)(mpegts_input_t*, mpegts_mux_instance_t*); + void (*mi_stopping_mux)(mpegts_input_t*, mpegts_mux_instance_t*); + void (*mi_stopped_mux)(mpegts_input_t*, mpegts_mux_instance_t*); + int (*mi_has_subscription)(mpegts_input_t*, mpegts_mux_t* mm); + void (*mi_error)(mpegts_input_t*, mpegts_mux_t*, int tss_flags); + void (*mi_empty_status)(mpegts_input_t*, tvh_input_stream_t*); + idnode_set_t* (*mi_network_list)(mpegts_input_t*); }; /* **************************************************************************** @@ -766,12 +760,11 @@ extern mpegts_network_list_t mpegts_network_all; typedef struct mpegts_network_builder { LIST_ENTRY(mpegts_network_builder) link; - const idclass_t *idc; - mpegts_network_t * (*build) ( const idclass_t *idc, htsmsg_t *conf ); + const idclass_t* idc; + mpegts_network_t* (*build)(const idclass_t* idc, htsmsg_t* conf); } mpegts_network_builder_t; - -typedef LIST_HEAD(,mpegts_network_builder) mpegts_network_builder_list_t; +typedef LIST_HEAD(, mpegts_network_builder) mpegts_network_builder_list_t; extern mpegts_network_builder_list_t mpegts_network_builders; @@ -781,135 +774,152 @@ extern mpegts_input_list_t mpegts_input_all; * Functions * ***************************************************************************/ -mpegts_input_t *mpegts_input_create0 - ( mpegts_input_t *mi, const idclass_t *idc, const char *uuid, htsmsg_t *c ); +mpegts_input_t* +mpegts_input_create0(mpegts_input_t* mi, const idclass_t* idc, const char* uuid, htsmsg_t* c); -#define mpegts_input_create(t, u, c)\ +#define mpegts_input_create(t, u, c) \ (struct t*)mpegts_input_create0(calloc(1, sizeof(struct t)), &t##_class, u, c) -#define mpegts_input_create1(u, c)\ - mpegts_input_create0(calloc(1, sizeof(mpegts_input_t)),\ - &mpegts_input_class, u, c) - -void mpegts_input_stop_all ( mpegts_input_t *mi ); +#define mpegts_input_create1(u, c) \ + mpegts_input_create0(calloc(1, sizeof(mpegts_input_t)), &mpegts_input_class, u, c) -void mpegts_input_delete ( mpegts_input_t *mi, int delconf ); +void mpegts_input_stop_all(mpegts_input_t* mi); -static inline mpegts_input_t *mpegts_input_find(const char *uuid) - { return idnode_find(uuid, &mpegts_input_class, NULL); } +void mpegts_input_delete(mpegts_input_t* mi, int delconf); -int mpegts_input_set_networks ( mpegts_input_t *mi, htsmsg_t *msg ); +static inline mpegts_input_t* mpegts_input_find(const char* uuid) { + return idnode_find(uuid, &mpegts_input_class, NULL); +} -int mpegts_input_add_network ( mpegts_input_t *mi, mpegts_network_t *mn ); +int mpegts_input_set_networks(mpegts_input_t* mi, htsmsg_t* msg); -void mpegts_input_open_service ( mpegts_input_t *mi, mpegts_service_t *s, int flags, int init, int weight ); -void mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s ); +int mpegts_input_add_network(mpegts_input_t* mi, mpegts_network_t* mn); -void mpegts_input_status_timer ( void *p ); +void mpegts_input_open_service(mpegts_input_t* mi, + mpegts_service_t* s, + int flags, + int init, + int weight); +void mpegts_input_close_service(mpegts_input_t* mi, mpegts_service_t* s); -int mpegts_input_grace ( mpegts_input_t * mi, mpegts_mux_t * mm ); +void mpegts_input_status_timer(void* p); -int mpegts_input_is_enabled ( mpegts_input_t * mi, mpegts_mux_t *mm, int flags, int weight ); +int mpegts_input_grace(mpegts_input_t* mi, mpegts_mux_t* mm); -void mpegts_input_set_enabled ( mpegts_input_t *mi, int enabled ); +int mpegts_input_is_enabled(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight); -void mpegts_input_empty_status ( mpegts_input_t *mi, tvh_input_stream_t *st ); +void mpegts_input_set_enabled(mpegts_input_t* mi, int enabled); +void mpegts_input_empty_status(mpegts_input_t* mi, tvh_input_stream_t* st); /* TODO: exposing these class methods here is a bit of a hack */ -const void *mpegts_input_class_network_get ( void *o ); -int mpegts_input_class_network_set ( void *o, const void *p ); -htsmsg_t *mpegts_input_class_network_enum ( void *o, const char *lang ); -char *mpegts_input_class_network_rend ( void *o, const char *lang ); -const void *mpegts_input_class_active_get ( void *o ); +const void* mpegts_input_class_network_get(void* o); +int mpegts_input_class_network_set(void* o, const void* p); +htsmsg_t* mpegts_input_class_network_enum(void* o, const char* lang); +char* mpegts_input_class_network_rend(void* o, const char* lang); +const void* mpegts_input_class_active_get(void* o); + +int mpegts_mps_weight(elementary_stream_t* st); -int mpegts_mps_weight(elementary_stream_t *st); +int mpegts_mps_cmp(mpegts_pid_sub_t* a, mpegts_pid_sub_t* b); -int mpegts_mps_cmp( mpegts_pid_sub_t *a, mpegts_pid_sub_t *b ); +void mpegts_network_register_builder(const idclass_t* idc, + mpegts_network_t* (*build)(const idclass_t* idc, htsmsg_t* conf)); -void mpegts_network_register_builder - ( const idclass_t *idc, - mpegts_network_t *(*build)(const idclass_t *idc, htsmsg_t *conf) ); +void mpegts_network_unregister_builder(const idclass_t* idc); -void mpegts_network_unregister_builder - ( const idclass_t *idc ); +mpegts_network_builder_t* mpegts_network_builder_find(const char* clazz); -mpegts_network_builder_t *mpegts_network_builder_find ( const char *clazz ); +mpegts_network_t* mpegts_network_build(const char* clazz, htsmsg_t* conf); -mpegts_network_t *mpegts_network_build - ( const char *clazz, htsmsg_t *conf ); - -mpegts_network_t *mpegts_network_create0 - ( mpegts_network_t *mn, const idclass_t *idc, const char *uuid, - const char *name, htsmsg_t *conf ); +mpegts_network_t* mpegts_network_create0(mpegts_network_t* mn, + const idclass_t* idc, + const char* uuid, + const char* name, + htsmsg_t* conf); -#define mpegts_network_create(t, u, n, c)\ +#define mpegts_network_create(t, u, n, c) \ (struct t*)mpegts_network_create0(calloc(1, sizeof(struct t)), &t##_class, u, n, c) extern const idclass_t mpegts_network_class; -static inline mpegts_network_t *mpegts_network_find(const char *uuid) - { return idnode_find(uuid, &mpegts_network_class, NULL); } - -mpegts_mux_t *mpegts_network_find_mux - (mpegts_network_t *mn, uint32_t onid, uint32_t tsid, int check); - -mpegts_service_t *mpegts_network_find_active_service - (mpegts_network_t *mn, uint16_t sid, mpegts_mux_t **rmm); - -void mpegts_network_class_delete ( const idclass_t *idc, int delconf ); - -void mpegts_network_delete ( mpegts_network_t *mn, int delconf ); +static inline mpegts_network_t* mpegts_network_find(const char* uuid) { + return idnode_find(uuid, &mpegts_network_class, NULL); +} -int mpegts_network_set_nid ( mpegts_network_t *mn, uint16_t nid ); -int mpegts_network_set_network_name ( mpegts_network_t *mn, const char *name ); -void mpegts_network_scan ( mpegts_network_t *mn ); -void mpegts_network_get_type_str( mpegts_network_t *mn, char *buf, size_t buflen ); +mpegts_mux_t* +mpegts_network_find_mux(mpegts_network_t* mn, uint32_t onid, uint32_t tsid, int check); -void mpegts_network_bouquet_trigger0(mpegts_network_t *mn, int timeout); -static inline void mpegts_network_bouquet_trigger(mpegts_network_t *mn, int timeout) -{ if (mn->mn_bouquet) mpegts_network_bouquet_trigger0(mn, timeout); } +mpegts_service_t* +mpegts_network_find_active_service(mpegts_network_t* mn, uint16_t sid, mpegts_mux_t** rmm); -htsmsg_t * mpegts_network_wizard_get ( mpegts_input_t *mi, const idclass_t *idc, - mpegts_network_t *mn, const char *lang ); -void mpegts_network_wizard_create ( const char *clazz, htsmsg_t **nlist, const char *lang ); +void mpegts_network_class_delete(const idclass_t* idc, int delconf); -mpegts_mux_t *mpegts_mux_create0 - ( mpegts_mux_t *mm, const idclass_t *class, const char *uuid, - mpegts_network_t *mn, uint32_t onid, uint32_t tsid, - htsmsg_t *conf ); +void mpegts_network_delete(mpegts_network_t* mn, int delconf); -#define mpegts_mux_create(type, uuid, mn, onid, tsid, conf)\ - (struct type*)mpegts_mux_create0(calloc(1, sizeof(struct type)),\ - &type##_class, uuid,\ - mn, onid, tsid, conf) -#define mpegts_mux_create1(uuid, mn, onid, tsid, conf)\ - mpegts_mux_create0(calloc(1, sizeof(mpegts_mux_t)), &mpegts_mux_class, uuid,\ - mn, onid, tsid, conf) +int mpegts_network_set_nid(mpegts_network_t* mn, uint16_t nid); +int mpegts_network_set_network_name(mpegts_network_t* mn, const char* name); +void mpegts_network_scan(mpegts_network_t* mn); +void mpegts_network_get_type_str(mpegts_network_t* mn, char* buf, size_t buflen); -mpegts_mux_t *mpegts_mux_post_create(mpegts_mux_t *mm); +void mpegts_network_bouquet_trigger0(mpegts_network_t* mn, int timeout); +static inline void mpegts_network_bouquet_trigger(mpegts_network_t* mn, int timeout) { + if (mn->mn_bouquet) + mpegts_network_bouquet_trigger0(mn, timeout); +} -static inline mpegts_mux_t *mpegts_mux_find0(tvh_uuid_t *uuid) - { return idnode_find0(uuid, &mpegts_mux_class, NULL); } +htsmsg_t* mpegts_network_wizard_get(mpegts_input_t* mi, + const idclass_t* idc, + mpegts_network_t* mn, + const char* lang); +void mpegts_network_wizard_create(const char* clazz, htsmsg_t** nlist, const char* lang); + +mpegts_mux_t* mpegts_mux_create0(mpegts_mux_t* mm, + const idclass_t* class, + const char* uuid, + mpegts_network_t* mn, + uint32_t onid, + uint32_t tsid, + htsmsg_t* conf); + +#define mpegts_mux_create(type, uuid, mn, onid, tsid, conf) \ + (struct type*)mpegts_mux_create0(calloc(1, sizeof(struct type)), \ + &type##_class, \ + uuid, \ + mn, \ + onid, \ + tsid, \ + conf) +#define mpegts_mux_create1(uuid, mn, onid, tsid, conf) \ + mpegts_mux_create0(calloc(1, sizeof(mpegts_mux_t)), &mpegts_mux_class, uuid, mn, onid, tsid, conf) + +mpegts_mux_t* mpegts_mux_post_create(mpegts_mux_t* mm); + +static inline mpegts_mux_t* mpegts_mux_find0(tvh_uuid_t* uuid) { + return idnode_find0(uuid, &mpegts_mux_class, NULL); +} -static inline mpegts_mux_t *mpegts_mux_find(const char *uuid) - { return idnode_find(uuid, &mpegts_mux_class, NULL); } +static inline mpegts_mux_t* mpegts_mux_find(const char* uuid) { + return idnode_find(uuid, &mpegts_mux_class, NULL); +} -#define mpegts_mux_delete_by_uuid(u, delconf)\ - { mpegts_mux_t *mm = mpegts_mux_find(u); if (mm) mm->mm_delete(mm, delconf); } +#define mpegts_mux_delete_by_uuid(u, delconf) \ + { \ + mpegts_mux_t* mm = mpegts_mux_find(u); \ + if (mm) \ + mm->mm_delete(mm, delconf); \ + } -void mpegts_mux_delete ( mpegts_mux_t *mm, int delconf ); +void mpegts_mux_delete(mpegts_mux_t* mm, int delconf); -void mpegts_mux_free ( mpegts_mux_t *mm ); +void mpegts_mux_free(mpegts_mux_t* mm); -static inline void mpegts_mux_grab ( mpegts_mux_t *mm ) -{ +static inline void mpegts_mux_grab(mpegts_mux_t* mm) { int v = atomic_add(&mm->mm_refcount, 1); assert(v > 0); } -static inline int mpegts_mux_release ( mpegts_mux_t *mm ) -{ +static inline int mpegts_mux_release(mpegts_mux_t* mm) { int v = atomic_dec(&mm->mm_refcount, 1); assert(v > 0); if (v == 1) { @@ -919,127 +929,140 @@ static inline int mpegts_mux_release ( mpegts_mux_t *mm ) return 0; } -void mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c, int refs ); +void mpegts_mux_save(mpegts_mux_t* mm, htsmsg_t* c, int refs); -void mpegts_mux_tuning_error( const char *mux_uuid, mpegts_mux_instance_t *mmi_match ); +void mpegts_mux_tuning_error(const char* mux_uuid, mpegts_mux_instance_t* mmi_match); -mpegts_mux_instance_t *mpegts_mux_instance_create0 - ( mpegts_mux_instance_t *mmi, const idclass_t *class, const char *uuid, - mpegts_input_t *mi, mpegts_mux_t *mm ); +mpegts_mux_instance_t* mpegts_mux_instance_create0(mpegts_mux_instance_t* mmi, + const idclass_t* class, + const char* uuid, + mpegts_input_t* mi, + mpegts_mux_t* mm); -mpegts_service_t *mpegts_mux_find_service(mpegts_mux_t *ms, uint16_t sid); +mpegts_service_t* mpegts_mux_find_service(mpegts_mux_t* ms, uint16_t sid); -#define mpegts_mux_instance_create(type, uuid, mi, mm)\ - (struct type*)mpegts_mux_instance_create0(calloc(1, sizeof(struct type)),\ - &type##_class, uuid,\ - mi, mm); +#define mpegts_mux_instance_create(type, uuid, mi, mm) \ + (struct type*) \ + mpegts_mux_instance_create0(calloc(1, sizeof(struct type)), &type##_class, uuid, mi, mm); -void mpegts_mux_instance_delete ( tvh_input_instance_t *tii ); +void mpegts_mux_instance_delete(tvh_input_instance_t* tii); -int mpegts_mux_instance_start - ( mpegts_mux_instance_t **mmiptr, service_t *t, int weight ); +int mpegts_mux_instance_start(mpegts_mux_instance_t** mmiptr, service_t* t, int weight); -int mpegts_mux_instance_weight ( mpegts_mux_instance_t *mmi ); +int mpegts_mux_instance_weight(mpegts_mux_instance_t* mmi); -int mpegts_mux_set_network_name ( mpegts_mux_t *mm, const char *name ); -int mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint32_t tsid, int force ); -int mpegts_mux_set_onid ( mpegts_mux_t *mm, uint32_t onid ); -int mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth ); -int mpegts_mux_set_epg_module ( mpegts_mux_t *mm, const char *modid ); +int mpegts_mux_set_network_name(mpegts_mux_t* mm, const char* name); +int mpegts_mux_set_tsid(mpegts_mux_t* mm, uint32_t tsid, int force); +int mpegts_mux_set_onid(mpegts_mux_t* mm, uint32_t onid); +int mpegts_mux_set_crid_authority(mpegts_mux_t* mm, const char* defauth); +int mpegts_mux_set_epg_module(mpegts_mux_t* mm, const char* modid); -void mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe ); -void mpegts_mux_unsubscribe_table ( mpegts_mux_t *mm, mpegts_table_t *mt ); -void mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ); +void mpegts_mux_open_table(mpegts_mux_t* mm, mpegts_table_t* mt, int subscribe); +void mpegts_mux_unsubscribe_table(mpegts_mux_t* mm, mpegts_table_t* mt); +void mpegts_mux_close_table(mpegts_mux_t* mm, mpegts_table_t* mt); -void mpegts_mux_remove_subscriber(mpegts_mux_t *mm, th_subscription_t *s, int reason); -int mpegts_mux_subscribe(mpegts_mux_t *mm, mpegts_input_t *mi, - const char *name, int weight, int flags); -void mpegts_mux_unsubscribe_by_name(mpegts_mux_t *mm, const char *name); -th_subscription_t *mpegts_mux_find_subscription_by_name(mpegts_mux_t *mm, const char *name); +void mpegts_mux_remove_subscriber(mpegts_mux_t* mm, th_subscription_t* s, int reason); +int mpegts_mux_subscribe(mpegts_mux_t* mm, + mpegts_input_t* mi, + const char* name, + int weight, + int flags); +void mpegts_mux_unsubscribe_by_name(mpegts_mux_t* mm, const char* name); +th_subscription_t* mpegts_mux_find_subscription_by_name(mpegts_mux_t* mm, const char* name); -void mpegts_mux_unsubscribe_linked(mpegts_input_t *mi, service_t *t); +void mpegts_mux_unsubscribe_linked(mpegts_input_t* mi, service_t* t); -void mpegts_mux_scan_done ( mpegts_mux_t *mm, const char *buf, int res ); +void mpegts_mux_scan_done(mpegts_mux_t* mm, const char* buf, int res); -void mpegts_mux_bouquet_rescan ( const char *src, const char *extra ); +void mpegts_mux_bouquet_rescan(const char* src, const char* extra); -void mpegts_mux_nice_name( mpegts_mux_t *mm, char *buf, size_t len ); -void mpegts_mux_update_nice_name( mpegts_mux_t *mm ); +void mpegts_mux_nice_name(mpegts_mux_t* mm, char* buf, size_t len); +void mpegts_mux_update_nice_name(mpegts_mux_t* mm); -int mpegts_mux_class_scan_state_set ( void *, const void * ); +int mpegts_mux_class_scan_state_set(void*, const void*); -static inline int mpegts_mux_scan_state_set ( mpegts_mux_t *m, int state ) - { return mpegts_mux_class_scan_state_set ( m, &state ); } +static inline int mpegts_mux_scan_state_set(mpegts_mux_t* m, int state) { + return mpegts_mux_class_scan_state_set(m, &state); +} -mpegts_pid_t *mpegts_mux_find_pid_(mpegts_mux_t *mm, int pid, int create); +mpegts_pid_t* mpegts_mux_find_pid_(mpegts_mux_t* mm, int pid, int create); -static inline mpegts_pid_t * -mpegts_mux_find_pid(mpegts_mux_t *mm, int pid, int create) -{ +static inline mpegts_pid_t* mpegts_mux_find_pid(mpegts_mux_t* mm, int pid, int create) { if (mm->mm_last_pid != pid) return mpegts_mux_find_pid_(mm, pid, create); else return mm->mm_last_mp; } -void mpegts_mux_update_pids ( mpegts_mux_t *mm ); +void mpegts_mux_update_pids(mpegts_mux_t* mm); -void mpegts_input_create_mux_instance ( mpegts_input_t *mi, mpegts_mux_t *mm ); +void mpegts_input_create_mux_instance(mpegts_input_t* mi, mpegts_mux_t* mm); -int mpegts_mux_compare ( mpegts_mux_t *a, mpegts_mux_t *b ); +int mpegts_mux_compare(mpegts_mux_t* a, mpegts_mux_t* b); -void mpegts_input_recv_packets - (mpegts_mux_instance_t *mmi, sbuf_t *sb, - int flags, mpegts_pcr_t *pcr); +void mpegts_input_recv_packets(mpegts_mux_instance_t* mmi, + sbuf_t* sb, + int flags, + mpegts_pcr_t* pcr); -void mpegts_input_postdemux - ( mpegts_input_t *mi, mpegts_mux_t *mm, uint8_t *data, int len ); +void mpegts_input_postdemux(mpegts_input_t* mi, mpegts_mux_t* mm, uint8_t* data, int len); -int mpegts_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ); -int mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ); -int mpegts_input_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm ); -int mpegts_input_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ); +int mpegts_input_get_weight(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight); +int mpegts_input_get_priority(mpegts_input_t* mi, mpegts_mux_t* mm, int flags); +int mpegts_input_get_grace(mpegts_input_t* mi, mpegts_mux_t* mm); +int mpegts_input_warm_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi); -void mpegts_input_save ( mpegts_input_t *mi, htsmsg_t *c ); +void mpegts_input_save(mpegts_input_t* mi, htsmsg_t* c); -void mpegts_input_flush_mux ( mpegts_input_t *mi, mpegts_mux_t *mm ); +void mpegts_input_flush_mux(mpegts_input_t* mi, mpegts_mux_t* mm); -mpegts_pid_t * mpegts_input_open_pid - ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, - void *owner, int reopen ); +mpegts_pid_t* mpegts_input_open_pid(mpegts_input_t* mi, + mpegts_mux_t* mm, + int pid, + int type, + int weight, + void* owner, + int reopen); -int mpegts_input_close_pid - ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, void *owner ); +int mpegts_input_close_pid(mpegts_input_t* mi, mpegts_mux_t* mm, int pid, int type, void* owner); -mpegts_pid_t * mpegts_input_update_pid_weight - ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, - void *owner ); +mpegts_pid_t* mpegts_input_update_pid_weight(mpegts_input_t* mi, + mpegts_mux_t* mm, + int pid, + int type, + int weight, + void* owner); -void mpegts_input_close_pids - ( mpegts_input_t *mi, mpegts_mux_t *mm, void *owner, int all ); +void mpegts_input_close_pids(mpegts_input_t* mi, mpegts_mux_t* mm, void* owner, int all); -elementary_stream_t *mpegts_input_open_service_pid - ( mpegts_input_t *mi, mpegts_mux_t *mm, service_t *s, - streaming_component_type_t stype, int pid, int weight, int create ); +elementary_stream_t* mpegts_input_open_service_pid(mpegts_input_t* mi, + mpegts_mux_t* mm, + service_t* s, + streaming_component_type_t stype, + int pid, + int weight, + int create); -void mpegts_input_open_pmt_monitor ( mpegts_mux_t *mm, mpegts_service_t *s ); -void mpegts_input_open_cat_monitor ( mpegts_mux_t *mm, mpegts_service_t *s ); +void mpegts_input_open_pmt_monitor(mpegts_mux_t* mm, mpegts_service_t* s); +void mpegts_input_open_cat_monitor(mpegts_mux_t* mm, mpegts_service_t* s); -void tsdebug_encode_keys - ( uint8_t *dst, uint16_t sid, uint16_t pid, - uint8_t keytype, uint8_t keylen, uint8_t *even, uint8_t *odd ); +void tsdebug_encode_keys(uint8_t* dst, + uint16_t sid, + uint16_t pid, + uint8_t keytype, + uint8_t keylen, + uint8_t* even, + uint8_t* odd); -void tsdebug_check_tspkt( mpegts_mux_t *mm, uint8_t *pkt, int len ); +void tsdebug_check_tspkt(mpegts_mux_t* mm, uint8_t* pkt, int len); -void mpegts_table_dispatch(const uint8_t *sec, size_t r, void *mt); -static inline void mpegts_table_grab(mpegts_table_t *mt) -{ +void mpegts_table_dispatch(const uint8_t* sec, size_t r, void* mt); +static inline void mpegts_table_grab(mpegts_table_t* mt) { int v = atomic_add(&mt->mt_arefcount, 1); assert(v > 0); } -void mpegts_table_release_(mpegts_table_t *mt); -static inline int mpegts_table_release(mpegts_table_t *mt) -{ +void mpegts_table_release_(mpegts_table_t* mt); +static inline int mpegts_table_release(mpegts_table_t* mt) { int v = atomic_dec(&mt->mt_arefcount, 1); assert(v > 0); if (v == 1) { @@ -1049,133 +1072,132 @@ static inline int mpegts_table_release(mpegts_table_t *mt) } return 0; } -int mpegts_table_type(mpegts_table_t *mt); -mpegts_table_t *mpegts_table_add - (mpegts_mux_t *mm, int tableid, int mask, - mpegts_table_callback_t callback, void *opaque, - const char *name, int subsys, int flags, int pid, int weight); -mpegts_table_t *mpegts_table_find - (mpegts_mux_t *mm, const char *name, void *opaque); -void mpegts_table_flush_all(mpegts_mux_t *mm); -void mpegts_table_destroy(mpegts_table_t *mt); -static inline void mpegts_table_reset(mpegts_table_t *mt) - { dvb_table_reset((mpegts_psi_table_t *)mt); } -void mpegts_table_consistency_check(mpegts_mux_t *mm); - -void dvb_bat_destroy(struct mpegts_table *mt); - -void dvb_cat_decode( const uint8_t *data, int len, - void (*add_emm)(void *aux, uint16_t caid, uint32_t prov, uint16_t pid), - void *aux ); - -int dvb_pat_callback - (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); -int dvb_cat_callback - (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); -int dvb_pmt_callback - (struct mpegts_table *mt, const uint8_t *ptr, int len, int tabelid); -int dvb_nit_callback - (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); -int dvb_bat_callback - (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); -int dvb_fs_sdt_callback - (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); -int dvb_sdt_callback - (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); -int dvb_tdt_callback - (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); -int dvb_tot_callback - (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); -int atsc_vct_callback - (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); -int atsc_stt_callback - (struct mpegts_table *mt, const uint8_t *ptr, int len, int tableid); - -void psi_tables_install - (mpegts_input_t *mi, mpegts_mux_t *mm, dvb_fe_delivery_system_t delsys); - -mpegts_service_t *mpegts_service_create0 - ( mpegts_service_t *ms, const idclass_t *class, const char *uuid, - mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, htsmsg_t *conf ); - -#define mpegts_service_create(t, u, m, s, p, c)\ - (struct t*)mpegts_service_create0(calloc(1, sizeof(struct t)),\ - &t##_class, u, m, s, p, c) - -#define mpegts_service_create1(u, m, s, p, c)\ - mpegts_service_create0(calloc(1, sizeof(mpegts_service_t)),\ - &mpegts_service_class, u, m, s, p, c) - -mpegts_service_t *mpegts_service_create_raw(mpegts_mux_t *mm); - -mpegts_service_t *mpegts_service_find - ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, int create, int *save ); - -service_t * -mpegts_service_find_e2 - ( uint32_t stype, uint32_t sid, uint32_t tsid, uint32_t onid, uint32_t hash); - -mpegts_service_t * -mpegts_service_find_by_pid ( mpegts_mux_t *mm, int pid ); - -void mpegts_service_autoenable( mpegts_service_t *s, const char *where ); - -void mpegts_service_update_slave_pids - ( mpegts_service_t *t, mpegts_service_t *master_filter, int del ); - -static inline mpegts_service_t *mpegts_service_find_by_uuid0(tvh_uuid_t *uuid) - { return idnode_find0(uuid, &mpegts_service_class, NULL); } - -static inline mpegts_service_t *mpegts_service_find_by_uuid(const char *uuid) - { return idnode_find(uuid, &mpegts_service_class, NULL); } - -void mpegts_service_unref ( service_t *s ); - -void mpegts_service_delete ( service_t *s, int delconf ); - -int64_t mpegts_service_channel_number ( service_t *s ); +int mpegts_table_type(mpegts_table_t* mt); +mpegts_table_t* mpegts_table_add(mpegts_mux_t* mm, + int tableid, + int mask, + mpegts_table_callback_t callback, + void* opaque, + const char* name, + int subsys, + int flags, + int pid, + int weight); +mpegts_table_t* mpegts_table_find(mpegts_mux_t* mm, const char* name, void* opaque); +void mpegts_table_flush_all(mpegts_mux_t* mm); +void mpegts_table_destroy(mpegts_table_t* mt); +static inline void mpegts_table_reset(mpegts_table_t* mt) { + dvb_table_reset((mpegts_psi_table_t*)mt); +} +void mpegts_table_consistency_check(mpegts_mux_t* mm); + +void dvb_bat_destroy(struct mpegts_table* mt); + +void dvb_cat_decode(const uint8_t* data, + int len, + void (*add_emm)(void* aux, uint16_t caid, uint32_t prov, uint16_t pid), + void* aux); + +int dvb_pat_callback(struct mpegts_table* mt, const uint8_t* ptr, int len, int tableid); +int dvb_cat_callback(struct mpegts_table* mt, const uint8_t* ptr, int len, int tableid); +int dvb_pmt_callback(struct mpegts_table* mt, const uint8_t* ptr, int len, int tabelid); +int dvb_nit_callback(struct mpegts_table* mt, const uint8_t* ptr, int len, int tableid); +int dvb_bat_callback(struct mpegts_table* mt, const uint8_t* ptr, int len, int tableid); +int dvb_fs_sdt_callback(struct mpegts_table* mt, const uint8_t* ptr, int len, int tableid); +int dvb_sdt_callback(struct mpegts_table* mt, const uint8_t* ptr, int len, int tableid); +int dvb_tdt_callback(struct mpegts_table* mt, const uint8_t* ptr, int len, int tableid); +int dvb_tot_callback(struct mpegts_table* mt, const uint8_t* ptr, int len, int tableid); +int atsc_vct_callback(struct mpegts_table* mt, const uint8_t* ptr, int len, int tableid); +int atsc_stt_callback(struct mpegts_table* mt, const uint8_t* ptr, int len, int tableid); + +void psi_tables_install(mpegts_input_t* mi, mpegts_mux_t* mm, dvb_fe_delivery_system_t delsys); + +mpegts_service_t* mpegts_service_create0(mpegts_service_t* ms, + const idclass_t* class, + const char* uuid, + mpegts_mux_t* mm, + uint16_t sid, + uint16_t pmt_pid, + htsmsg_t* conf); + +#define mpegts_service_create(t, u, m, s, p, c) \ + (struct t*)mpegts_service_create0(calloc(1, sizeof(struct t)), &t##_class, u, m, s, p, c) + +#define mpegts_service_create1(u, m, s, p, c) \ + mpegts_service_create0(calloc(1, sizeof(mpegts_service_t)), &mpegts_service_class, u, m, s, p, c) + +mpegts_service_t* mpegts_service_create_raw(mpegts_mux_t* mm); + +mpegts_service_t* +mpegts_service_find(mpegts_mux_t* mm, uint16_t sid, uint16_t pmt_pid, int create, int* save); + +service_t* +mpegts_service_find_e2(uint32_t stype, uint32_t sid, uint32_t tsid, uint32_t onid, uint32_t hash); + +mpegts_service_t* mpegts_service_find_by_pid(mpegts_mux_t* mm, int pid); + +void mpegts_service_autoenable(mpegts_service_t* s, const char* where); + +void mpegts_service_update_slave_pids(mpegts_service_t* t, + mpegts_service_t* master_filter, + int del); + +static inline mpegts_service_t* mpegts_service_find_by_uuid0(tvh_uuid_t* uuid) { + return idnode_find0(uuid, &mpegts_service_class, NULL); +} + +static inline mpegts_service_t* mpegts_service_find_by_uuid(const char* uuid) { + return idnode_find(uuid, &mpegts_service_class, NULL); +} + +void mpegts_service_unref(service_t* s); + +void mpegts_service_delete(service_t* s, int delconf); + +int64_t mpegts_service_channel_number(service_t* s); /* * MPEG-TS event handler */ -typedef struct mpegts_listener -{ +typedef struct mpegts_listener { LIST_ENTRY(mpegts_listener) ml_link; - void *ml_opaque; - void (*ml_mux_start) (mpegts_mux_t *mm, void *p); - void (*ml_mux_stop) (mpegts_mux_t *mm, void *p, int reason); - void (*ml_mux_create) (mpegts_mux_t *mm, void *p); - void (*ml_mux_delete) (mpegts_mux_t *mm, void *p); + void* ml_opaque; + void (*ml_mux_start)(mpegts_mux_t* mm, void* p); + void (*ml_mux_stop)(mpegts_mux_t* mm, void* p, int reason); + void (*ml_mux_create)(mpegts_mux_t* mm, void* p); + void (*ml_mux_delete)(mpegts_mux_t* mm, void* p); } mpegts_listener_t; extern LIST_HEAD(mpegts_listeners, mpegts_listener) mpegts_listeners; -#define mpegts_add_listener(ml)\ - LIST_INSERT_HEAD(&mpegts_listeners, ml, ml_link) +#define mpegts_add_listener(ml) LIST_INSERT_HEAD(&mpegts_listeners, ml, ml_link) -#define mpegts_rem_listener(ml)\ - LIST_REMOVE(ml, ml_link) +#define mpegts_rem_listener(ml) LIST_REMOVE(ml, ml_link) -#define mpegts_fire_event(t, op)\ -{\ - mpegts_listener_t *ml;\ - LIST_FOREACH(ml, &mpegts_listeners, ml_link)\ - if (ml->op) ml->op(t, ml->ml_opaque);\ -} (void)0 +#define mpegts_fire_event(t, op) \ + { \ + mpegts_listener_t* ml; \ + LIST_FOREACH (ml, &mpegts_listeners, ml_link) \ + if (ml->op) \ + ml->op(t, ml->ml_opaque); \ + } \ + (void)0 -#define mpegts_fire_event1(t, op, arg1)\ -{\ - mpegts_listener_t *ml;\ - LIST_FOREACH(ml, &mpegts_listeners, ml_link)\ - if (ml->op) ml->op(t, ml->ml_opaque, arg1);\ -} (void)0 +#define mpegts_fire_event1(t, op, arg1) \ + { \ + mpegts_listener_t* ml; \ + LIST_FOREACH (ml, &mpegts_listeners, ml_link) \ + if (ml->op) \ + ml->op(t, ml->ml_opaque, arg1); \ + } \ + (void)0 /* * misc */ -void eit_nit_callback(mpegts_table_t *mt, uint16_t nbid, const char *name, uint32_t priv); -void eit_sdt_callback(mpegts_table_t *mt, uint32_t priv); +void eit_nit_callback(mpegts_table_t* mt, uint16_t nbid, const char* name, uint32_t priv); +void eit_sdt_callback(mpegts_table_t* mt, uint32_t priv); #endif /* __TVH_MPEGTS_H__ */ diff --git a/src/input/mpegts/dvb.h b/src/input/mpegts/dvb.h index 311e27cd5..addcdeee9 100644 --- a/src/input/mpegts/dvb.h +++ b/src/input/mpegts/dvb.h @@ -16,7 +16,7 @@ * along with this program. If not, see . */ -/* +/* * Based on: * * ITU-T Recommendation H.222.0 / ISO standard 13818-1 @@ -37,251 +37,255 @@ struct lang_str; /* PIDs */ -#define DVB_PAT_PID 0x00 -#define DVB_CAT_PID 0x01 -#define DVB_TSDT_PID 0x02 -#define DVB_NIT_PID 0x10 -#define DVB_SDT_PID 0x11 -#define DVB_BAT_PID 0x11 -#define DVB_EIT_PID 0x12 -#define DVB_RST_PID 0x13 -#define DVB_TDT_PID 0x14 -#define DVB_SNC_PID 0x15 -#define DVB_RNT_PID 0x16 -#define DVB_INB_PID 0x1C -#define DVB_MSR_PID 0x1D -#define DVB_DIT_PID 0x1E -#define DVB_SIT_PID 0x1F -#define DVB_VCT_PID 0x1FFB -#define DVB_ATSC_STT_PID 0x1FFB -#define DVB_ATSC_MGT_PID 0x1FFB +#define DVB_PAT_PID 0x00 +#define DVB_CAT_PID 0x01 +#define DVB_TSDT_PID 0x02 +#define DVB_NIT_PID 0x10 +#define DVB_SDT_PID 0x11 +#define DVB_BAT_PID 0x11 +#define DVB_EIT_PID 0x12 +#define DVB_RST_PID 0x13 +#define DVB_TDT_PID 0x14 +#define DVB_SNC_PID 0x15 +#define DVB_RNT_PID 0x16 +#define DVB_INB_PID 0x1C +#define DVB_MSR_PID 0x1D +#define DVB_DIT_PID 0x1E +#define DVB_SIT_PID 0x1F +#define DVB_VCT_PID 0x1FFB +#define DVB_ATSC_STT_PID 0x1FFB +#define DVB_ATSC_MGT_PID 0x1FFB /* Tables */ -#define DVB_PAT_BASE 0x00 -#define DVB_PAT_MASK 0x00 +#define DVB_PAT_BASE 0x00 +#define DVB_PAT_MASK 0x00 -#define DVB_CAT_BASE 0x01 -#define DVB_CAT_MASK 0xFF +#define DVB_CAT_BASE 0x01 +#define DVB_CAT_MASK 0xFF -#define DVB_PMT_BASE 0x02 -#define DVB_PMT_MASK 0xFF +#define DVB_PMT_BASE 0x02 +#define DVB_PMT_MASK 0xFF -#define DVB_NIT_BASE 0x00 -#define DVB_NIT_MASK 0x00 +#define DVB_NIT_BASE 0x00 +#define DVB_NIT_MASK 0x00 -#define DVB_SDT_BASE 0x40 -#define DVB_SDT_MASK 0xF8 +#define DVB_SDT_BASE 0x40 +#define DVB_SDT_MASK 0xF8 -#define DVB_BAT_BASE 0x48 -#define DVB_BAT_MASK 0xF8 +#define DVB_BAT_BASE 0x48 +#define DVB_BAT_MASK 0xF8 -#define DVB_TDT_BASE 0x70 -#define DVB_TDT_MASK 0xFF +#define DVB_TDT_BASE 0x70 +#define DVB_TDT_MASK 0xFF -#define DVB_TOT_BASE 0x73 -#define DVB_TOT_MASK 0xFF +#define DVB_TOT_BASE 0x73 +#define DVB_TOT_MASK 0xFF -#define DVB_HBBTV_BASE 0x74 -#define DVB_HBBTV_MASK 0xFF +#define DVB_HBBTV_BASE 0x74 +#define DVB_HBBTV_MASK 0xFF -#define DVB_FASTSCAN_NIT_BASE 0xBC -#define DVB_FASTSCAN_SDT_BASE 0xBD -#define DVB_FASTSCAN_MASK 0xFF +#define DVB_FASTSCAN_NIT_BASE 0xBC +#define DVB_FASTSCAN_SDT_BASE 0xBD +#define DVB_FASTSCAN_MASK 0xFF -#define DVB_VCT_T_BASE 0xC8 -#define DVB_VCT_C_BASE 0xC9 -#define DVB_VCT_MASK 0xFF +#define DVB_VCT_T_BASE 0xC8 +#define DVB_VCT_C_BASE 0xC9 +#define DVB_VCT_MASK 0xFF -#define DVB_ATSC_MGT_BASE 0xC7 -#define DVB_ATSC_MGT_MASK 0xFF +#define DVB_ATSC_MGT_BASE 0xC7 +#define DVB_ATSC_MGT_MASK 0xFF -#define DVB_ATSC_EIT_BASE 0xCB -#define DVB_ATSC_EIT_MASK 0xFF +#define DVB_ATSC_EIT_BASE 0xCB +#define DVB_ATSC_EIT_MASK 0xFF -#define DVB_ATSC_ETT_BASE 0xCC -#define DVB_ATSC_ETT_MASK 0xFF +#define DVB_ATSC_ETT_BASE 0xCC +#define DVB_ATSC_ETT_MASK 0xFF -#define DVB_ATSC_STT_BASE 0xCD -#define DVB_ATSC_STT_MASK 0xFF +#define DVB_ATSC_STT_BASE 0xCD +#define DVB_ATSC_STT_MASK 0xFF -#define DVB_TELETEXT_BASE 0x2000 +#define DVB_TELETEXT_BASE 0x2000 /* Descriptors */ -#define DVB_DESC_VIDEO_STREAM 0x02 -#define DVB_DESC_REGISTRATION 0x05 -#define DVB_DESC_CA 0x09 -#define DVB_DESC_LANGUAGE 0x0A +#define DVB_DESC_VIDEO_STREAM 0x02 +#define DVB_DESC_REGISTRATION 0x05 +#define DVB_DESC_CA 0x09 +#define DVB_DESC_LANGUAGE 0x0A /* Descriptors defined in EN 300 468 */ -#define DVB_DESC_NETWORK_NAME 0x40 -#define DVB_DESC_SERVICE_LIST 0x41 -#define DVB_DESC_STUFFING 0x42 -#define DVB_DESC_SAT_DEL 0x43 -#define DVB_DESC_CABLE_DEL 0x44 -#define DVB_DESC_VBI_DATA 0x45 -#define DVB_DESC_VBI_TELETEXT 0x46 -#define DVB_DESC_BOUQUET_NAME 0x47 -#define DVB_DESC_SERVICE 0x48 -#define DVB_DESC_COUNTRY_AVAILABILITY 0x49 -#define DVB_DESC_LINKAGE 0x4A -#define DVB_DESC_NVOD_REFERENCE 0x4B -#define DVB_DESC_TIME_SHIFTED_SERVICE 0x4C -#define DVB_DESC_SHORT_EVENT 0x4D -#define DVB_DESC_EXT_EVENT 0x4E -#define DVB_DESC_TIME_SHIFTED_EVENT 0x4F -#define DVB_DESC_COMPONENT 0x50 -#define DVB_DESC_MOSAIC 0x51 -#define DVB_DESC_STREAM_ID 0x52 -#define DVB_DESC_CA_ID 0x53 -#define DVB_DESC_CONTENT 0x54 -#define DVB_DESC_PARENTAL_RAT 0x55 -#define DVB_DESC_TELETEXT 0x56 -#define DVB_DESC_TELEPHONE 0x57 -#define DVB_DESC_LOCAL_TIME_OFFSET 0x58 -#define DVB_DESC_SUBTITLE 0x59 -#define DVB_DESC_TERR_DEL 0x5A -#define DVB_DESC_MULTI_NETWORK_NAME 0x5B -#define DVB_DESC_MULTI_BOUQUET_NAME 0x5C -#define DVB_DESC_MULTI_SERVICE_NAME 0x5D -#define DVB_DESC_MULTI_COMPONENT_NAME 0x5E -#define DVB_DESC_PRIVATE_DATA 0x5F -#define DVB_DESC_SERVICE_MOVE 0x60 -#define DVB_DESC_SHORT_SMOOTHING_BUF 0x61 -#define DVB_DESC_FREQ_LIST 0x62 +#define DVB_DESC_NETWORK_NAME 0x40 +#define DVB_DESC_SERVICE_LIST 0x41 +#define DVB_DESC_STUFFING 0x42 +#define DVB_DESC_SAT_DEL 0x43 +#define DVB_DESC_CABLE_DEL 0x44 +#define DVB_DESC_VBI_DATA 0x45 +#define DVB_DESC_VBI_TELETEXT 0x46 +#define DVB_DESC_BOUQUET_NAME 0x47 +#define DVB_DESC_SERVICE 0x48 +#define DVB_DESC_COUNTRY_AVAILABILITY 0x49 +#define DVB_DESC_LINKAGE 0x4A +#define DVB_DESC_NVOD_REFERENCE 0x4B +#define DVB_DESC_TIME_SHIFTED_SERVICE 0x4C +#define DVB_DESC_SHORT_EVENT 0x4D +#define DVB_DESC_EXT_EVENT 0x4E +#define DVB_DESC_TIME_SHIFTED_EVENT 0x4F +#define DVB_DESC_COMPONENT 0x50 +#define DVB_DESC_MOSAIC 0x51 +#define DVB_DESC_STREAM_ID 0x52 +#define DVB_DESC_CA_ID 0x53 +#define DVB_DESC_CONTENT 0x54 +#define DVB_DESC_PARENTAL_RAT 0x55 +#define DVB_DESC_TELETEXT 0x56 +#define DVB_DESC_TELEPHONE 0x57 +#define DVB_DESC_LOCAL_TIME_OFFSET 0x58 +#define DVB_DESC_SUBTITLE 0x59 +#define DVB_DESC_TERR_DEL 0x5A +#define DVB_DESC_MULTI_NETWORK_NAME 0x5B +#define DVB_DESC_MULTI_BOUQUET_NAME 0x5C +#define DVB_DESC_MULTI_SERVICE_NAME 0x5D +#define DVB_DESC_MULTI_COMPONENT_NAME 0x5E +#define DVB_DESC_PRIVATE_DATA 0x5F +#define DVB_DESC_SERVICE_MOVE 0x60 +#define DVB_DESC_SHORT_SMOOTHING_BUF 0x61 +#define DVB_DESC_FREQ_LIST 0x62 #define DVB_DESC_PARTIAL_TRANSPORT_STREAM 0x63 -#define DVB_DESC_DATA_BROADCAST 0x64 -#define DVB_DESC_SCRAMBLING 0x65 -#define DVB_DESC_DATA_BROADCAST_ID 0x66 -#define DVB_DESC_TRANSPORT_STREAM 0x67 -#define DVB_DESC_DSNG 0x68 -#define DVB_DESC_PDC 0x69 -#define DVB_DESC_AC3 0x6A -#define DVB_DESC_ANCILLARY_DATA 0x6B -#define DVB_DESC_CALL_LIST 0x6C -#define DVB_DESC_CALL_FREQ_LINK 0x6D -#define DVB_DESC_ANNOUNCEMENT_SUPPORT 0x6E -#define DVB_DESC_DEF_AUTHORITY 0x73 -#define DVB_DESC_CRID 0x76 -#define DVB_DESC_EAC3 0x7A -#define DVB_DESC_AAC 0x7C -#define DVB_DESC_AC4 0x7F - -#define DVB_DESC_BSKYB_LCN 0xB1 - -#define DVB_DESC_BSKYB_NVOD 0xC0 - -#define DVB_DESC_FREESAT_NIT 0xD2 -#define DVB_DESC_FREESAT_LCN 0xD3 -#define DVB_DESC_FREESAT_REGIONS 0xD4 +#define DVB_DESC_DATA_BROADCAST 0x64 +#define DVB_DESC_SCRAMBLING 0x65 +#define DVB_DESC_DATA_BROADCAST_ID 0x66 +#define DVB_DESC_TRANSPORT_STREAM 0x67 +#define DVB_DESC_DSNG 0x68 +#define DVB_DESC_PDC 0x69 +#define DVB_DESC_AC3 0x6A +#define DVB_DESC_ANCILLARY_DATA 0x6B +#define DVB_DESC_CALL_LIST 0x6C +#define DVB_DESC_CALL_FREQ_LINK 0x6D +#define DVB_DESC_ANNOUNCEMENT_SUPPORT 0x6E +#define DVB_DESC_DEF_AUTHORITY 0x73 +#define DVB_DESC_CRID 0x76 +#define DVB_DESC_EAC3 0x7A +#define DVB_DESC_AAC 0x7C +#define DVB_DESC_AC4 0x7F + +#define DVB_DESC_BSKYB_LCN 0xB1 + +#define DVB_DESC_BSKYB_NVOD 0xC0 + +#define DVB_DESC_FREESAT_NIT 0xD2 +#define DVB_DESC_FREESAT_LCN 0xD3 +#define DVB_DESC_FREESAT_REGIONS 0xD4 /* HBBTV */ -#define DVB_DESC_APP 0x00 -#define DVB_DESC_APP_NAME 0x01 -#define DVB_DESC_APP_TRANSPORT 0x02 -#define DVB_DESC_APP_EXT_AUTH 0x05 -#define DVB_DESC_APP_REC 0x06 -#define DVB_DESC_APP_ICONS 0x0B -#define DVB_DESC_APP_STORAGE 0x10 -#define DVB_DESC_APP_GRAPHICS_CONSTR 0x14 -#define DVB_DESC_APP_SIMPLE_LOCATION 0x15 -#define DVB_DESC_APP_USAGE 0x16 -#define DVB_DESC_APP_SIMPLE_BOUNDARY 0x17 +#define DVB_DESC_APP 0x00 +#define DVB_DESC_APP_NAME 0x01 +#define DVB_DESC_APP_TRANSPORT 0x02 +#define DVB_DESC_APP_EXT_AUTH 0x05 +#define DVB_DESC_APP_REC 0x06 +#define DVB_DESC_APP_ICONS 0x0B +#define DVB_DESC_APP_STORAGE 0x10 +#define DVB_DESC_APP_GRAPHICS_CONSTR 0x14 +#define DVB_DESC_APP_SIMPLE_LOCATION 0x15 +#define DVB_DESC_APP_USAGE 0x16 +#define DVB_DESC_APP_SIMPLE_BOUNDARY 0x17 /* Descriptors defined in A/65:2009 */ -#define ATSC_DESC_STUFFING 0x80 -#define ATSC_DESC_AC3 0x81 -#define ATSC_DESC_CAPTION 0x86 -#define ATSC_DESC_CONTENT_ADVISORY 0x87 -#define ATSC_DESC_EXT_CHANNEL_NAME 0xA0 -#define ATSC_DESC_SERVICE_LOCATION 0xA1 -#define ATSC_DESC_TIMESHIFTED_SVC 0xA2 -#define ATSC_DESC_COMPONENT_NAME 0xA3 -#define ATSC_DESC_DCC_DEPARTING 0xA8 -#define ATSC_DESC_DCC_ARRIVING 0xA9 -#define ATSC_DESC_REDISTRIB_CTRL 0xAA -#define ATSC_DESC_GENRE 0xAB -#define ATSC_DESC_PRIVATE_INFO 0xAD +#define ATSC_DESC_STUFFING 0x80 +#define ATSC_DESC_AC3 0x81 +#define ATSC_DESC_CAPTION 0x86 +#define ATSC_DESC_CONTENT_ADVISORY 0x87 +#define ATSC_DESC_EXT_CHANNEL_NAME 0xA0 +#define ATSC_DESC_SERVICE_LOCATION 0xA1 +#define ATSC_DESC_TIMESHIFTED_SVC 0xA2 +#define ATSC_DESC_COMPONENT_NAME 0xA3 +#define ATSC_DESC_DCC_DEPARTING 0xA8 +#define ATSC_DESC_DCC_ARRIVING 0xA9 +#define ATSC_DESC_REDISTRIB_CTRL 0xAA +#define ATSC_DESC_GENRE 0xAB +#define ATSC_DESC_PRIVATE_INFO 0xAD /* Service type lookup */ -int dvb_servicetype_lookup ( int t ); +int dvb_servicetype_lookup(int t); /* String Extraction */ -typedef struct dvb_string_conv -{ +typedef struct dvb_string_conv { uint8_t type; - size_t (*func) ( char *dst, size_t *dstlen, - const uint8_t* src, size_t srclen ); + size_t (*func)(char* dst, size_t* dstlen, const uint8_t* src, size_t srclen); } dvb_string_conv_t; -int dvb_get_string - (char *dst, size_t dstlen, const uint8_t *src, const size_t srclen, - const char *dvb_charset, dvb_string_conv_t *conv); +int dvb_get_string(char* dst, + size_t dstlen, + const uint8_t* src, + const size_t srclen, + const char* dvb_charset, + dvb_string_conv_t* conv); -int dvb_get_string_with_len - (char *dst, size_t dstlen, const uint8_t *buf, size_t buflen, - const char *dvb_charset, dvb_string_conv_t *conv); +int dvb_get_string_with_len(char* dst, + size_t dstlen, + const uint8_t* buf, + size_t buflen, + const char* dvb_charset, + dvb_string_conv_t* conv); -struct lang_str *atsc_get_string - (const uint8_t *src, size_t srclen); +struct lang_str* atsc_get_string(const uint8_t* src, size_t srclen); /* Conversion */ static inline uint32_t bcdtoint(const uint32_t i) { return ((((i & 0xf0) >> 4) * 10) + (i & 0x0f)); } -static inline uint32_t bcdtoint4(const uint8_t *ptr) { - return (bcdtoint(ptr[0]) * 1000000) + - (bcdtoint(ptr[1]) * 10000) + - (bcdtoint(ptr[2]) * 100) + - bcdtoint(ptr[3]); +static inline uint32_t bcdtoint4(const uint8_t* ptr) { + return (bcdtoint(ptr[0]) * 1000000) + (bcdtoint(ptr[1]) * 10000) + (bcdtoint(ptr[2]) * 100) + + bcdtoint(ptr[3]); } -static inline uint32_t bcdtoint41(const uint8_t *ptr) { - return (bcdtoint(ptr[0]) * 100000) + - (bcdtoint(ptr[1]) * 1000) + - (bcdtoint(ptr[2]) * 10) + - ((ptr[3]) >> 4); +static inline uint32_t bcdtoint41(const uint8_t* ptr) { + return (bcdtoint(ptr[0]) * 100000) + (bcdtoint(ptr[1]) * 1000) + (bcdtoint(ptr[2]) * 10) + + ((ptr[3]) >> 4); } -htsmsg_t *dvb_timezone_enum(void *p, const char *lang); +htsmsg_t* dvb_timezone_enum(void* p, const char* lang); -time_t dvb_convert_date(const uint8_t *dvb_buf, int tmzone); +time_t dvb_convert_date(const uint8_t* dvb_buf, int tmzone); time_t atsc_convert_gpstime(uint32_t gpstime); -void atsc_utf16_to_utf8(const uint8_t *src, int len, char *buf, int buflen); +void atsc_utf16_to_utf8(const uint8_t* src, int len, char* buf, int buflen); /* * PSI processing */ -#define DVB_LOOP_INIT(mt, ptr, len, off, lptr, llen)\ -do {\ - llen = ((ptr[off] & 0xF) << 8) | ptr[off+1];\ - lptr = 2 + off + ptr;\ - ptr += 2 + off + llen;\ - len -= 2 + off + llen;\ - if (len < 0) {tvhtrace(mt->mt_subsys, "%s: len < 0", mt->mt_name);goto dvberr;}\ -} while(0) - -#define DVB_LOOP_EACH(ptr, len, min)\ - for ( ; len > min ; )\ - -#define DVB_LOOP_FOREACH(mt, ptr, len, off, lptr, llen, min)\ - DVB_LOOP_INIT(mt, ptr, len, off, lptr, llen);\ +#define DVB_LOOP_INIT(mt, ptr, len, off, lptr, llen) \ + do { \ + llen = ((ptr[off] & 0xF) << 8) | ptr[off + 1]; \ + lptr = 2 + off + ptr; \ + ptr += 2 + off + llen; \ + len -= 2 + off + llen; \ + if (len < 0) { \ + tvhtrace(mt->mt_subsys, "%s: len < 0", mt->mt_name); \ + goto dvberr; \ + } \ + } while (0) + +#define DVB_LOOP_EACH(ptr, len, min) for (; len > min;) + +#define DVB_LOOP_FOREACH(mt, ptr, len, off, lptr, llen, min) \ + DVB_LOOP_INIT(mt, ptr, len, off, lptr, llen); \ DVB_LOOP_EACH(lptr, llen, min) -#define DVB_DESC_EACH(mt, ptr, len, dtag, dlen, dptr)\ - DVB_LOOP_EACH(ptr, len, 2) { \ - dtag = ptr[0], dlen = ptr[1], dptr = ptr+2, ptr += 2+dlen; \ - if ((len -= 2+dlen) < 0) {tvhtrace(mt->mt_subsys, "%s: dlen < 0", mt->mt_name);goto dvberr;}\ +#define DVB_DESC_EACH(mt, ptr, len, dtag, dlen, dptr) \ + DVB_LOOP_EACH(ptr, len, 2) { \ + dtag = ptr[0], dlen = ptr[1], dptr = ptr + 2, ptr += 2 + dlen; \ + if ((len -= 2 + dlen) < 0) { \ + tvhtrace(mt->mt_subsys, "%s: dlen < 0", mt->mt_name); \ + goto dvberr; \ + } -#define DVB_DESC_FOREACH(mt, ptr, len, off, lptr, llen, dtag, dlen, dptr)\ - DVB_LOOP_INIT(mt, ptr, len, off, lptr, llen);\ - DVB_DESC_EACH(mt, lptr, llen, dtag, dlen, dptr)\ +#define DVB_DESC_FOREACH(mt, ptr, len, off, lptr, llen, dtag, dlen, dptr) \ + DVB_LOOP_INIT(mt, ptr, len, off, lptr, llen); \ + DVB_DESC_EACH(mt, lptr, llen, dtag, dlen, dptr) /* * SI typedefs @@ -290,10 +294,9 @@ do {\ #define MPEGTS_PSI_SECTION_SIZE 5000 #define MPEGTS_PSI_VERSION_NONE 255 -typedef struct mpegts_psi_section -{ - uint8_t ps_table; // SI table ID - uint8_t ps_mask; // mask +typedef struct mpegts_psi_section { + uint8_t ps_table; // SI table ID + uint8_t ps_mask; // mask int8_t ps_cc; int8_t ps_cco; int ps_offset; @@ -301,11 +304,9 @@ typedef struct mpegts_psi_section uint8_t ps_data[MPEGTS_PSI_SECTION_SIZE]; } mpegts_psi_section_t; -typedef void (*mpegts_psi_section_callback_t) - ( const uint8_t *tsb, size_t len, void *opaque ); +typedef void (*mpegts_psi_section_callback_t)(const uint8_t* tsb, size_t len, void* opaque); -typedef struct mpegts_psi_table_state -{ +typedef struct mpegts_psi_table_state { int tableid; uint64_t extraid; int version; @@ -316,19 +317,18 @@ typedef struct mpegts_psi_table_state RB_ENTRY(mpegts_psi_table_state) link; } mpegts_psi_table_state_t; -typedef struct mpegts_psi_table -{ +typedef struct mpegts_psi_table { LIST_ENTRY(mpegts_table) mt_link; - RB_HEAD(,mpegts_psi_table_state) mt_state; + RB_HEAD(, mpegts_psi_table_state) mt_state; - int mt_subsys; - char *mt_name; - void *mt_opaque; + int mt_subsys; + char* mt_name; + void* mt_opaque; uint8_t mt_table; // SI table id (base) uint8_t mt_mask; // mask - int mt_pid; + int mt_pid; time_t mt_last_complete; int mt_complete; @@ -344,73 +344,86 @@ typedef struct mpegts_psi_table /* * Assemble SI section */ -void mpegts_psi_section_reassemble - ( mpegts_psi_table_t *mt, const char *logpref, const uint8_t *tsb, int crc, - mpegts_psi_section_callback_t cb, void *opaque ); +void mpegts_psi_section_reassemble(mpegts_psi_table_t* mt, + const char* logpref, + const uint8_t* tsb, + int crc, + mpegts_psi_section_callback_t cb, + void* opaque); /* PSI table parser helpers */ -int dvb_table_end - (mpegts_psi_table_t *mt, mpegts_psi_table_state_t *st, int sect ); -int dvb_table_begin - (mpegts_psi_table_t *mt, const uint8_t *ptr, int len, - int tableid, uint64_t extraid, int minlen, - mpegts_psi_table_state_t **st, int *sect, int *last, int *ver, - time_t interval); -void dvb_table_reset (mpegts_psi_table_t *mt); -void dvb_table_release (mpegts_psi_table_t *mt); +int dvb_table_end(mpegts_psi_table_t* mt, mpegts_psi_table_state_t* st, int sect); +int dvb_table_begin(mpegts_psi_table_t* mt, + const uint8_t* ptr, + int len, + int tableid, + uint64_t extraid, + int minlen, + mpegts_psi_table_state_t** st, + int* sect, + int* last, + int* ver, + time_t interval); +void dvb_table_reset(mpegts_psi_table_t* mt); +void dvb_table_release(mpegts_psi_table_t* mt); /* all-in-one parser */ -typedef void (*mpegts_psi_parse_callback_t) - ( mpegts_psi_table_t *, const uint8_t *buf, int len ); +typedef void (*mpegts_psi_parse_callback_t)(mpegts_psi_table_t*, const uint8_t* buf, int len); -void dvb_table_parse_init - ( mpegts_psi_table_t *mt, const char *name, int subsys, int pid, - uint8_t table, uint8_t mask, void *opaque ); +void dvb_table_parse_init(mpegts_psi_table_t* mt, + const char* name, + int subsys, + int pid, + uint8_t table, + uint8_t mask, + void* opaque); -void dvb_table_parse_reinit_input ( mpegts_psi_table_t *mt ); -void dvb_table_parse_reinit_output ( mpegts_psi_table_t *mt ); +void dvb_table_parse_reinit_input(mpegts_psi_table_t* mt); +void dvb_table_parse_reinit_output(mpegts_psi_table_t* mt); -void dvb_table_parse_done ( mpegts_psi_table_t *mt); +void dvb_table_parse_done(mpegts_psi_table_t* mt); -void dvb_table_parse - (mpegts_psi_table_t *mt, const char *logprefix, - const uint8_t *tsb, int len, int crc, int full, - mpegts_psi_parse_callback_t cb); +void dvb_table_parse(mpegts_psi_table_t* mt, + const char* logprefix, + const uint8_t* tsb, + int len, + int crc, + int full, + mpegts_psi_parse_callback_t cb); -int dvb_table_append_crc32(uint8_t *dst, int off, int maxlen); +int dvb_table_append_crc32(uint8_t* dst, int off, int maxlen); -int dvb_table_remux - (mpegts_psi_table_t *mt, const uint8_t *buf, int len, uint8_t **out); +int dvb_table_remux(mpegts_psi_table_t* mt, const uint8_t* buf, int len, uint8_t** out); -extern htsmsg_t *satellites; +extern htsmsg_t* satellites; /* Delivery systems */ typedef enum dvb_fe_delivery_system { - DVB_SYS_NONE = 0, - DVB_SYS_DVBC_ANNEX_A = 100, + DVB_SYS_NONE = 0, + DVB_SYS_DVBC_ANNEX_A = 100, DVB_SYS_DVBC_ANNEX_B, DVB_SYS_DVBC_ANNEX_C, - DVB_SYS_DVBT = 200, + DVB_SYS_DVBT = 200, DVB_SYS_DVBT2, - DVB_SYS_DVBS = 300, + DVB_SYS_DVBS = 300, DVB_SYS_DVBS2, - DVB_SYS_DVBH = 400, - DVB_SYS_DSS = 500, - DVB_SYS_ISDBT = 600, + DVB_SYS_DVBH = 400, + DVB_SYS_DSS = 500, + DVB_SYS_ISDBT = 600, DVB_SYS_ISDBS, DVB_SYS_ISDBC, - DVB_SYS_ATSC = 700, + DVB_SYS_ATSC = 700, DVB_SYS_ATSCMH, - DVB_SYS_DTMB = 800, - DVB_SYS_CMMB = 900, - DVB_SYS_DAB = 1000, - DVB_SYS_TURBO = 1100, + DVB_SYS_DTMB = 800, + DVB_SYS_CMMB = 900, + DVB_SYS_DAB = 1000, + DVB_SYS_TURBO = 1100, /* TVH internal */ - DVB_SYS_ATSC_ALL = 9998, - DVB_SYS_UNKNOWN = 9999 + DVB_SYS_ATSC_ALL = 9998, + DVB_SYS_UNKNOWN = 9999 } dvb_fe_delivery_system_t; /* @@ -420,17 +433,17 @@ typedef enum dvb_fe_delivery_system { typedef enum dvb_fe_type { DVB_TYPE_NONE = 0, - DVB_TYPE_T = 1, /* terrestrial */ - DVB_TYPE_C, /* cable */ - DVB_TYPE_S, /* satellite */ - DVB_TYPE_ATSC_T, /* terrestrial - north america */ - DVB_TYPE_ATSC_C, /* cable - north america */ + DVB_TYPE_T = 1, /* terrestrial */ + DVB_TYPE_C, /* cable */ + DVB_TYPE_S, /* satellite */ + DVB_TYPE_ATSC_T, /* terrestrial - north america */ + DVB_TYPE_ATSC_C, /* cable - north america */ DVB_TYPE_CABLECARD, /* CableCARD - North America */ - DVB_TYPE_ISDB_T, /* terrestrial - japan, brazil */ - DVB_TYPE_ISDB_C, /* cable - japan, brazil */ - DVB_TYPE_ISDB_S, /* satellite - japan, brazil */ - DVB_TYPE_DTMB, /* DTMB - china, cuba, hong kong, macau */ - DVB_TYPE_DAB, /* digital radio (europe) */ + DVB_TYPE_ISDB_T, /* terrestrial - japan, brazil */ + DVB_TYPE_ISDB_C, /* cable - japan, brazil */ + DVB_TYPE_ISDB_S, /* satellite - japan, brazil */ + DVB_TYPE_DTMB, /* DTMB - china, cuba, hong kong, macau */ + DVB_TYPE_DAB, /* digital radio (europe) */ DVB_TYPE_LAST = DVB_TYPE_DAB } dvb_fe_type_t; @@ -442,29 +455,29 @@ typedef enum dvb_fe_spectral_inversion { } dvb_fe_spectral_inversion_t; typedef enum dvb_fe_code_rate { - DVB_FEC_NONE = 0, + DVB_FEC_NONE = 0, DVB_FEC_AUTO, - DVB_FEC_1_2 = 102, - DVB_FEC_1_3 = 103, - DVB_FEC_1_4 = 104, - DVB_FEC_1_5 = 105, - DVB_FEC_2_3 = 203, - DVB_FEC_2_5 = 205, - DVB_FEC_2_9 = 209, - DVB_FEC_3_4 = 304, - DVB_FEC_3_5 = 305, - DVB_FEC_4_5 = 405, - DVB_FEC_4_15 = 415, - DVB_FEC_5_6 = 506, - DVB_FEC_5_9 = 509, - DVB_FEC_6_7 = 607, - DVB_FEC_7_8 = 708, - DVB_FEC_7_9 = 709, - DVB_FEC_7_15 = 715, - DVB_FEC_8_9 = 809, - DVB_FEC_8_15 = 815, - DVB_FEC_9_10 = 910, - DVB_FEC_9_20 = 920, + DVB_FEC_1_2 = 102, + DVB_FEC_1_3 = 103, + DVB_FEC_1_4 = 104, + DVB_FEC_1_5 = 105, + DVB_FEC_2_3 = 203, + DVB_FEC_2_5 = 205, + DVB_FEC_2_9 = 209, + DVB_FEC_3_4 = 304, + DVB_FEC_3_5 = 305, + DVB_FEC_4_5 = 405, + DVB_FEC_4_15 = 415, + DVB_FEC_5_6 = 506, + DVB_FEC_5_9 = 509, + DVB_FEC_6_7 = 607, + DVB_FEC_7_8 = 708, + DVB_FEC_7_9 = 709, + DVB_FEC_7_15 = 715, + DVB_FEC_8_9 = 809, + DVB_FEC_8_15 = 815, + DVB_FEC_9_10 = 910, + DVB_FEC_9_20 = 920, DVB_FEC_11_15 = 1115, DVB_FEC_11_20 = 1120, DVB_FEC_11_45 = 1145, @@ -482,29 +495,29 @@ typedef enum dvb_fe_code_rate { } dvb_fe_code_rate_t; typedef enum dvb_fe_modulation { - DVB_MOD_NONE = 0, + DVB_MOD_NONE = 0, DVB_MOD_AUTO, - DVB_MOD_QPSK = 1001, - DVB_MOD_QAM_4_NR = 2004, - DVB_MOD_QAM_AUTO = 3000, - DVB_MOD_QAM_16 = 3016, - DVB_MOD_QAM_32 = 3032, - DVB_MOD_QAM_64 = 3064, - DVB_MOD_QAM_128 = 3128, - DVB_MOD_QAM_256 = 3256, - DVB_MOD_QAM_1024 = 31024, - DVB_MOD_QAM_4096 = 34096, - DVB_MOD_VSB_8 = 4008, - DVB_MOD_VSB_16 = 4016, - DVB_MOD_PSK_8 = 5008, - DVB_MOD_DQPSK = 6001, - DVB_MOD_BPSK = 7001, - DVB_MOD_BPSK_S = 8001, - DVB_MOD_APSK_16 = 9016, - DVB_MOD_APSK_32 = 9032, - DVB_MOD_APSK_64 = 9064, - DVB_MOD_APSK_128 = 9128, - DVB_MOD_APSK_256 = 9256, + DVB_MOD_QPSK = 1001, + DVB_MOD_QAM_4_NR = 2004, + DVB_MOD_QAM_AUTO = 3000, + DVB_MOD_QAM_16 = 3016, + DVB_MOD_QAM_32 = 3032, + DVB_MOD_QAM_64 = 3064, + DVB_MOD_QAM_128 = 3128, + DVB_MOD_QAM_256 = 3256, + DVB_MOD_QAM_1024 = 31024, + DVB_MOD_QAM_4096 = 34096, + DVB_MOD_VSB_8 = 4008, + DVB_MOD_VSB_16 = 4016, + DVB_MOD_PSK_8 = 5008, + DVB_MOD_DQPSK = 6001, + DVB_MOD_BPSK = 7001, + DVB_MOD_BPSK_S = 8001, + DVB_MOD_APSK_16 = 9016, + DVB_MOD_APSK_32 = 9032, + DVB_MOD_APSK_64 = 9064, + DVB_MOD_APSK_128 = 9128, + DVB_MOD_APSK_256 = 9256, DVB_MOD_APSK_8_L = 10008, DVB_MOD_APSK_16_L = 10016, DVB_MOD_APSK_32_L = 10032, @@ -514,9 +527,9 @@ typedef enum dvb_fe_modulation { } dvb_fe_modulation_t; typedef enum dvb_fe_transmit_mode { - DVB_TRANSMISSION_MODE_NONE = 0, + DVB_TRANSMISSION_MODE_NONE = 0, DVB_TRANSMISSION_MODE_AUTO, - DVB_TRANSMISSION_MODE_1K = 100, + DVB_TRANSMISSION_MODE_1K = 100, DVB_TRANSMISSION_MODE_2K, DVB_TRANSMISSION_MODE_4K, DVB_TRANSMISSION_MODE_8K, @@ -527,37 +540,37 @@ typedef enum dvb_fe_transmit_mode { } dvb_fe_transmit_mode_t; typedef enum dvb_fe_bandwidth { - DVB_BANDWIDTH_NONE = 0, + DVB_BANDWIDTH_NONE = 0, DVB_BANDWIDTH_AUTO, - DVB_BANDWIDTH_1_712_MHZ = 1712, - DVB_BANDWIDTH_5_MHZ = 5000, - DVB_BANDWIDTH_6_MHZ = 6000, - DVB_BANDWIDTH_7_MHZ = 7000, - DVB_BANDWIDTH_8_MHZ = 8000, - DVB_BANDWIDTH_10_MHZ = 10000, + DVB_BANDWIDTH_1_712_MHZ = 1712, + DVB_BANDWIDTH_5_MHZ = 5000, + DVB_BANDWIDTH_6_MHZ = 6000, + DVB_BANDWIDTH_7_MHZ = 7000, + DVB_BANDWIDTH_8_MHZ = 8000, + DVB_BANDWIDTH_10_MHZ = 10000, } dvb_fe_bandwidth_t; typedef enum dvb_fe_guard_interval { - DVB_GUARD_INTERVAL_NONE = 0, + DVB_GUARD_INTERVAL_NONE = 0, DVB_GUARD_INTERVAL_AUTO, - DVB_GUARD_INTERVAL_1_4 = 1004, - DVB_GUARD_INTERVAL_1_8 = 1008, - DVB_GUARD_INTERVAL_1_16 = 1016, - DVB_GUARD_INTERVAL_1_32 = 1032, - DVB_GUARD_INTERVAL_1_128 = 1128, - DVB_GUARD_INTERVAL_19_128 = 19128, - DVB_GUARD_INTERVAL_19_256 = 19256, - DVB_GUARD_INTERVAL_PN420 = 90420, - DVB_GUARD_INTERVAL_PN595 = 90595, - DVB_GUARD_INTERVAL_PN945 = 90945, + DVB_GUARD_INTERVAL_1_4 = 1004, + DVB_GUARD_INTERVAL_1_8 = 1008, + DVB_GUARD_INTERVAL_1_16 = 1016, + DVB_GUARD_INTERVAL_1_32 = 1032, + DVB_GUARD_INTERVAL_1_128 = 1128, + DVB_GUARD_INTERVAL_19_128 = 19128, + DVB_GUARD_INTERVAL_19_256 = 19256, + DVB_GUARD_INTERVAL_PN420 = 90420, + DVB_GUARD_INTERVAL_PN595 = 90595, + DVB_GUARD_INTERVAL_PN945 = 90945, } dvb_fe_guard_interval_t; typedef enum dvb_fe_hierarchy { - DVB_HIERARCHY_NONE = 0, + DVB_HIERARCHY_NONE = 0, DVB_HIERARCHY_AUTO, - DVB_HIERARCHY_1 = 1001, - DVB_HIERARCHY_2 = 1002, - DVB_HIERARCHY_4 = 1004, + DVB_HIERARCHY_1 = 1001, + DVB_HIERARCHY_2 = 1002, + DVB_HIERARCHY_4 = 1004, } dvb_fe_hierarchy_t; typedef enum dvb_fe_pilot { @@ -568,14 +581,14 @@ typedef enum dvb_fe_pilot { } dvb_fe_pilot_t; typedef enum dvb_fe_rolloff { - DVB_ROLLOFF_NONE = 0, + DVB_ROLLOFF_NONE = 0, DVB_ROLLOFF_AUTO, - DVB_ROLLOFF_5 = 50, - DVB_ROLLOFF_10 = 100, - DVB_ROLLOFF_15 = 150, - DVB_ROLLOFF_20 = 200, - DVB_ROLLOFF_25 = 250, - DVB_ROLLOFF_35 = 350, + DVB_ROLLOFF_5 = 50, + DVB_ROLLOFF_10 = 100, + DVB_ROLLOFF_15 = 150, + DVB_ROLLOFF_20 = 200, + DVB_ROLLOFF_25 = 250, + DVB_ROLLOFF_35 = 350, } dvb_fe_rolloff_t; typedef enum dvb_fe_pls_mode { @@ -595,15 +608,15 @@ typedef enum dvb_polarisation { #define DVB_NO_STREAM_ID_FILTER (-1) typedef struct dvb_qpsk_config { - dvb_polarisation_t polarisation; - int orbital_pos; - uint32_t symbol_rate; - dvb_fe_code_rate_t fec_inner; + dvb_polarisation_t polarisation; + int orbital_pos; + uint32_t symbol_rate; + dvb_fe_code_rate_t fec_inner; } dvb_qpsk_config_t; typedef struct dvb_qam_config { - uint32_t symbol_rate; - dvb_fe_code_rate_t fec_inner; + uint32_t symbol_rate; + dvb_fe_code_rate_t fec_inner; } dvb_qam_config_t; typedef struct dvb_ofdm_config { @@ -619,20 +632,19 @@ typedef struct dvb_isdbt_config { dvb_fe_bandwidth_t bandwidth; dvb_fe_guard_interval_t guard_interval; struct { - dvb_fe_code_rate_t fec; - dvb_fe_modulation_t modulation; - uint32_t segment_count; - uint32_t time_interleaving; + dvb_fe_code_rate_t fec; + dvb_fe_modulation_t modulation; + uint32_t segment_count; + uint32_t time_interleaving; } layers[3]; } dvb_isdbt_config_t; typedef struct dvb_cablecard_config { - uint32_t vchannel; - char *name; + uint32_t vchannel; + char* name; } dvb_cablecard_config_t; -typedef struct dvb_mux_conf -{ +typedef struct dvb_mux_conf { dvb_fe_type_t dmc_fe_type; dvb_fe_delivery_system_t dmc_fe_delsys; dvb_fe_modulation_t dmc_fe_modulation; @@ -645,79 +657,76 @@ typedef struct dvb_mux_conf uint32_t dmc_fe_pls_code; uint32_t dmc_fe_data_slice; union { - dvb_qpsk_config_t dmc_fe_qpsk; - dvb_qam_config_t dmc_fe_qam; - dvb_ofdm_config_t dmc_fe_ofdm; - dvb_isdbt_config_t dmc_fe_isdbt; - dvb_cablecard_config_t dmc_fe_cablecard; + dvb_qpsk_config_t dmc_fe_qpsk; + dvb_qam_config_t dmc_fe_qam; + dvb_ofdm_config_t dmc_fe_ofdm; + dvb_isdbt_config_t dmc_fe_isdbt; + dvb_cablecard_config_t dmc_fe_cablecard; } u; // For scan file configurations - LIST_ENTRY(dvb_mux_conf) dmc_link; - + LIST_ENTRY(dvb_mux_conf) dmc_link; + } dvb_mux_conf_t; /* conversion routines */ -const char *dvb_rolloff2str ( int rolloff ); -const char *dvb_delsys2str ( int delsys ); -const char *dvb_fec2str ( int fec ); -const char *dvb_qam2str ( int qam ); -const char *dvb_bw2str ( int bw ); -const char *dvb_mode2str ( int mode ); -const char *dvb_inver2str ( int inver ); -const char *dvb_guard2str ( int guard ); -const char *dvb_hier2str ( int hier ); -const char *dvb_pol2str ( int pol ); -const char *dvb_type2str ( int type ); -const char *dvb_pilot2str ( int pilot ); -const char *dvb_plsmode2str ( int pls_mode ); +const char* dvb_rolloff2str(int rolloff); +const char* dvb_delsys2str(int delsys); +const char* dvb_fec2str(int fec); +const char* dvb_qam2str(int qam); +const char* dvb_bw2str(int bw); +const char* dvb_mode2str(int mode); +const char* dvb_inver2str(int inver); +const char* dvb_guard2str(int guard); +const char* dvb_hier2str(int hier); +const char* dvb_pol2str(int pol); +const char* dvb_type2str(int type); +const char* dvb_pilot2str(int pilot); +const char* dvb_plsmode2str(int pls_mode); #define dvb_feclo2str dvb_fec2str #define dvb_fechi2str dvb_fec2str -int dvb_str2rolloff ( const char *str ); -int dvb_str2delsys ( const char *str ); -int dvb_str2fec ( const char *str ); -int dvb_str2qam ( const char *str ); -int dvb_str2bw ( const char *str ); -int dvb_str2inver ( const char *str ); -int dvb_str2mode ( const char *str ); -int dvb_str2guard ( const char *str ); -int dvb_str2hier ( const char *str ); -int dvb_str2pol ( const char *str ); -int dvb_str2type ( const char *str ); -int dvb_str2pilot ( const char *str ); -int dvb_str2plsmode ( const char *str ); +int dvb_str2rolloff(const char* str); +int dvb_str2delsys(const char* str); +int dvb_str2fec(const char* str); +int dvb_str2qam(const char* str); +int dvb_str2bw(const char* str); +int dvb_str2inver(const char* str); +int dvb_str2mode(const char* str); +int dvb_str2guard(const char* str); +int dvb_str2hier(const char* str); +int dvb_str2pol(const char* str); +int dvb_str2type(const char* str); +int dvb_str2pilot(const char* str); +int dvb_str2plsmode(const char* str); #define dvb_str2feclo dvb_str2fec #define dvb_str2fechi dvb_str2fec -static inline int dvb_bandwidth( dvb_fe_bandwidth_t bw ) -{ +static inline int dvb_bandwidth(dvb_fe_bandwidth_t bw) { return bw < 1000 ? 0 : bw * 1000; } -int dvb_delsys2type ( struct mpegts_network *ln, enum dvb_fe_delivery_system ds ); +int dvb_delsys2type(struct mpegts_network* ln, enum dvb_fe_delivery_system ds); -void dvb_mux_conf_init ( struct mpegts_network *ln, dvb_mux_conf_t *dmc, - dvb_fe_delivery_system_t delsys ); +void dvb_mux_conf_init(struct mpegts_network* ln, + dvb_mux_conf_t* dmc, + dvb_fe_delivery_system_t delsys); -int dvb_mux_conf_str ( dvb_mux_conf_t *conf, char *buf, size_t bufsize ); +int dvb_mux_conf_str(dvb_mux_conf_t* conf, char* buf, size_t bufsize); -const char *dvb_sat_position_to_str( int position, char *buf, size_t buflen ); +const char* dvb_sat_position_to_str(int position, char* buf, size_t buflen); -int dvb_sat_position_from_str( const char *buf ); +int dvb_sat_position_from_str(const char* buf); -static inline int dvb_modulation_is_none_or_auto ( int modulation ) -{ - return modulation == DVB_MOD_NONE || - modulation == DVB_MOD_AUTO || - modulation == DVB_MOD_QAM_AUTO; +static inline int dvb_modulation_is_none_or_auto(int modulation) { + return modulation == DVB_MOD_NONE || modulation == DVB_MOD_AUTO || modulation == DVB_MOD_QAM_AUTO; } -uint32_t dvb_sat_pls( dvb_mux_conf_t *dmc ); +uint32_t dvb_sat_pls(dvb_mux_conf_t* dmc); #endif /* ENABLE_MPEGTS_DVB */ -void dvb_init ( void ); -void dvb_done ( void ); +void dvb_init(void); +void dvb_done(void); #endif /* DVB_SUPPORT_H */ diff --git a/src/input/mpegts/dvb_charset.c b/src/input/mpegts/dvb_charset.c index 237f19b73..da99b8600 100644 --- a/src/input/mpegts/dvb_charset.c +++ b/src/input/mpegts/dvb_charset.c @@ -22,38 +22,35 @@ #include "dvb_charset.h" #include "input.h" -static LIST_HEAD(,dvb_charset) dvb_charset_list; +static LIST_HEAD(, dvb_charset) dvb_charset_list; /* * Process a file */ -static void _charset_load_file() -{ - htsmsg_t *l, *e; - htsmsg_field_t *f; +static void _charset_load_file() { + htsmsg_t * l, *e; + htsmsg_field_t* f; - dvb_charset_t *enc; - const char *charset; - uint32_t tsid, onid, sid; - int i = 0; + dvb_charset_t* enc; + const char* charset; + uint32_t tsid, onid, sid; + int i = 0; l = hts_settings_load("charset"); - if (l) - { + if (l) { HTSMSG_FOREACH(f, l) { if ((e = htsmsg_get_map_by_field(f))) { tsid = onid = sid = 0; htsmsg_get_u32(e, "onid", &onid); htsmsg_get_u32(e, "tsid", &tsid); - htsmsg_get_u32(e, "sid", &sid); + htsmsg_get_u32(e, "sid", &sid); charset = htsmsg_get_str(e, "charset"); if (tsid == 0 || onid == 0 || !charset) continue; enc = calloc(1, sizeof(dvb_charset_t)); - if (enc) - { + if (enc) { enc->onid = onid; enc->tsid = tsid; enc->sid = sid; @@ -73,21 +70,19 @@ static void _charset_load_file() /* * Initialise the charset list */ -void dvb_charset_init ( void ) -{ +void dvb_charset_init(void) { _charset_load_file(); } /* * */ -void dvb_charset_done ( void ) -{ - dvb_charset_t *enc; - +void dvb_charset_done(void) { + dvb_charset_t* enc; + while ((enc = LIST_FIRST(&dvb_charset_list)) != NULL) { LIST_REMOVE(enc, link); - free((void *)enc->charset); + free((void*)enc->charset); free(enc); } } @@ -95,13 +90,13 @@ void dvb_charset_done ( void ) /* * Find default charset */ -const char *dvb_charset_find - ( mpegts_network_t *mn, mpegts_mux_t *mm, mpegts_service_t *s ) -{ +const char* dvb_charset_find(mpegts_network_t* mn, mpegts_mux_t* mm, mpegts_service_t* s) { dvb_charset_t *ret = NULL, *enc; - if (!mm && s) mm = s->s_dvb_mux; - if (!mn && mm) mn = mm->mm_network; + if (!mm && s) + mm = s->s_dvb_mux; + if (!mn && mm) + mn = mm->mm_network; /* User Overrides */ if (s && s->s_dvb_charset && *s->s_dvb_charset) @@ -113,7 +108,7 @@ const char *dvb_charset_find /* Global overrides */ if (mm) { - LIST_FOREACH(enc, &dvb_charset_list, link) { + LIST_FOREACH (enc, &dvb_charset_list, link) { if (mm->mm_onid == enc->onid && mm->mm_tsid == enc->tsid) { if (s && service_id16(s) == enc->sid) { ret = enc; @@ -130,35 +125,33 @@ const char *dvb_charset_find /* * List of available charsets */ -htsmsg_t * -dvb_charset_enum ( void *p, const char *lang ) -{ - int i; - static const char *charsets[] = { - "AUTO", - "ISO-6937", - "ISO-8859-1", - "ISO-8859-2", - "ISO-8859-3", - "ISO-8859-4", - "ISO-8859-5", - "ISO-8859-6", - "ISO-8859-7", - "ISO-8859-8", - "ISO-8859-9", - "ISO-8859-10", - "ISO-8859-11", - "ISO-8859-12", - "ISO-8859-13", - "ISO-8859-14", - "ISO-8859-15", - "UTF-8", - "GB2312", - "UCS2", - "AUTO_POLISH", +htsmsg_t* dvb_charset_enum(void* p, const char* lang) { + int i; + static const char* charsets[] = { + "AUTO", + "ISO-6937", + "ISO-8859-1", + "ISO-8859-2", + "ISO-8859-3", + "ISO-8859-4", + "ISO-8859-5", + "ISO-8859-6", + "ISO-8859-7", + "ISO-8859-8", + "ISO-8859-9", + "ISO-8859-10", + "ISO-8859-11", + "ISO-8859-12", + "ISO-8859-13", + "ISO-8859-14", + "ISO-8859-15", + "UTF-8", + "GB2312", + "UCS2", + "AUTO_POLISH", }; - htsmsg_t *m = htsmsg_create_list(); - for ( i = 0; i < ARRAY_SIZE(charsets); i++) + htsmsg_t* m = htsmsg_create_list(); + for (i = 0; i < ARRAY_SIZE(charsets); i++) htsmsg_add_str(m, NULL, charsets[i]); return m; } diff --git a/src/input/mpegts/dvb_charset.h b/src/input/mpegts/dvb_charset.h index eb3c40ad6..0c58248e6 100644 --- a/src/input/mpegts/dvb_charset.h +++ b/src/input/mpegts/dvb_charset.h @@ -21,22 +21,22 @@ typedef struct dvb_charset { LIST_ENTRY(dvb_charset) link; - uint16_t onid; - uint16_t tsid; - uint16_t sid; - const char *charset; + uint16_t onid; + uint16_t tsid; + uint16_t sid; + const char* charset; } dvb_charset_t; -void dvb_charset_init ( void ); -void dvb_charset_done ( void ); +void dvb_charset_init(void); +void dvb_charset_done(void); struct mpegts_network; struct mpegts_mux; struct mpegts_service; -const char *dvb_charset_find - (struct mpegts_network *mn, struct mpegts_mux *mm, struct mpegts_service *s); +const char* +dvb_charset_find(struct mpegts_network* mn, struct mpegts_mux* mm, struct mpegts_service* s); -htsmsg_t *dvb_charset_enum ( void*, const char *lang ); +htsmsg_t* dvb_charset_enum(void*, const char* lang); #endif /* __TVH_DVB_CHARSET_H__ */ diff --git a/src/input/mpegts/dvb_charset_tables.h b/src/input/mpegts/dvb_charset_tables.h index b106ebe8a..6a4aa9966 100644 --- a/src/input/mpegts/dvb_charset_tables.h +++ b/src/input/mpegts/dvb_charset_tables.h @@ -3,359 +3,2226 @@ // Code tables for the variable part of the iso 8859 family (codes 0xa0 to 0xff) static uint16_t conv_8859_table[14][96] = { - /* ISO-8859-1 */ { - /* 0xA0 */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, - /* 0xA8 */ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, - /* 0xB0 */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, - /* 0xB8 */ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, - /* 0xC0 */ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, - /* 0xC8 */ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - /* 0xD0 */ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, - /* 0xD8 */ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, - /* 0xE0 */ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, - /* 0xE8 */ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - /* 0xF0 */ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, - /* 0xF8 */ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, - }, - /* ISO-8859-2 */ { - /* 0xA0 */ 0x00A0, 0x0104, 0x02D8, 0x0141, 0x00A4, 0x013D, 0x015A, 0x00A7, - /* 0xA8 */ 0x00A8, 0x0160, 0x015E, 0x0164, 0x0179, 0x00AD, 0x017D, 0x017B, - /* 0xB0 */ 0x00B0, 0x0105, 0x02DB, 0x0142, 0x00B4, 0x013E, 0x015B, 0x02C7, - /* 0xB8 */ 0x00B8, 0x0161, 0x015F, 0x0165, 0x017A, 0x02DD, 0x017E, 0x017C, - /* 0xC0 */ 0x0154, 0x00C1, 0x00C2, 0x0102, 0x00C4, 0x0139, 0x0106, 0x00C7, - /* 0xC8 */ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x011A, 0x00CD, 0x00CE, 0x010E, - /* 0xD0 */ 0x0110, 0x0143, 0x0147, 0x00D3, 0x00D4, 0x0150, 0x00D6, 0x00D7, - /* 0xD8 */ 0x0158, 0x016E, 0x00DA, 0x0170, 0x00DC, 0x00DD, 0x0162, 0x00DF, - /* 0xE0 */ 0x0155, 0x00E1, 0x00E2, 0x0103, 0x00E4, 0x013A, 0x0107, 0x00E7, - /* 0xE8 */ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x011B, 0x00ED, 0x00EE, 0x010F, - /* 0xF0 */ 0x0111, 0x0144, 0x0148, 0x00F3, 0x00F4, 0x0151, 0x00F6, 0x00F7, - /* 0xF8 */ 0x0159, 0x016F, 0x00FA, 0x0171, 0x00FC, 0x00FD, 0x0163, 0x02D9, - }, - /* ISO-8859-3 */ { - /* 0xA0 */ 0x00A0, 0x0126, 0x02D8, 0x00A3, 0x00A4, 0x0000, 0x0124, 0x00A7, - /* 0xA8 */ 0x00A8, 0x0130, 0x015E, 0x011E, 0x0134, 0x00AD, 0x0000, 0x017B, - /* 0xB0 */ 0x00B0, 0x0127, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x0125, 0x00B7, - /* 0xB8 */ 0x00B8, 0x0131, 0x015F, 0x011F, 0x0135, 0x00BD, 0x0000, 0x017C, - /* 0xC0 */ 0x00C0, 0x00C1, 0x00C2, 0x0000, 0x00C4, 0x010A, 0x0108, 0x00C7, - /* 0xC8 */ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - /* 0xD0 */ 0x0000, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x0120, 0x00D6, 0x00D7, - /* 0xD8 */ 0x011C, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x016C, 0x015C, 0x00DF, - /* 0xE0 */ 0x00E0, 0x00E1, 0x00E2, 0x0000, 0x00E4, 0x010B, 0x0109, 0x00E7, - /* 0xE8 */ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - /* 0xF0 */ 0x0000, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x0121, 0x00F6, 0x00F7, - /* 0xF8 */ 0x011D, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x016D, 0x015D, 0x02D9, - }, - /* ISO-8859-4 */ { - /* 0xA0 */ 0x00A0, 0x0104, 0x0138, 0x0156, 0x00A4, 0x0128, 0x013B, 0x00A7, - /* 0xA8 */ 0x00A8, 0x0160, 0x0112, 0x0122, 0x0166, 0x00AD, 0x017D, 0x00AF, - /* 0xB0 */ 0x00B0, 0x0105, 0x02DB, 0x0157, 0x00B4, 0x0129, 0x013C, 0x02C7, - /* 0xB8 */ 0x00B8, 0x0161, 0x0113, 0x0123, 0x0167, 0x014A, 0x017E, 0x014B, - /* 0xC0 */ 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, - /* 0xC8 */ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x012A, - /* 0xD0 */ 0x0110, 0x0145, 0x014C, 0x0136, 0x00D4, 0x00D5, 0x00D6, 0x00D7, - /* 0xD8 */ 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x0168, 0x016A, 0x00DF, - /* 0xE0 */ 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, - /* 0xE8 */ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x012B, - /* 0xF0 */ 0x0111, 0x0146, 0x014D, 0x0137, 0x00F4, 0x00F5, 0x00F6, 0x00F7, - /* 0xF8 */ 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x0169, 0x016B, 0x02D9, - }, - /* ISO-8859-5 */ { - /* 0xA0 */ 0x00A0, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, - /* 0xA8 */ 0x0408, 0x0409, 0x040A, 0x040B, 0x040C, 0x00AD, 0x040E, 0x040F, - /* 0xB0 */ 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415, 0x0416, 0x0417, - /* 0xB8 */ 0x0418, 0x0419, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, 0x041F, - /* 0xC0 */ 0x0420, 0x0421, 0x0422, 0x0423, 0x0424, 0x0425, 0x0426, 0x0427, - /* 0xC8 */ 0x0428, 0x0429, 0x042A, 0x042B, 0x042C, 0x042D, 0x042E, 0x042F, - /* 0xD0 */ 0x0430, 0x0431, 0x0432, 0x0433, 0x0434, 0x0435, 0x0436, 0x0437, - /* 0xD8 */ 0x0438, 0x0439, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, 0x043F, - /* 0xE0 */ 0x0440, 0x0441, 0x0442, 0x0443, 0x0444, 0x0445, 0x0446, 0x0447, - /* 0xE8 */ 0x0448, 0x0449, 0x044A, 0x044B, 0x044C, 0x044D, 0x044E, 0x044F, - /* 0xF0 */ 0x2116, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, - /* 0xF8 */ 0x0458, 0x0459, 0x045A, 0x045B, 0x045C, 0x00A7, 0x045E, 0x045F, - }, - /* ISO-8859-6 */ { - /* 0xA0 */ 0x00A0, 0x0000, 0x0000, 0x0000, 0x00A4, 0x0000, 0x0000, 0x0000, - /* 0xA8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x060C, 0x00AD, 0x0000, 0x0000, - /* 0xB0 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0xB8 */ 0x0000, 0x0000, 0x0000, 0x061B, 0x0000, 0x0000, 0x0000, 0x061F, - /* 0xC0 */ 0x0000, 0x0621, 0x0622, 0x0623, 0x0624, 0x0625, 0x0626, 0x0627, - /* 0xC8 */ 0x0628, 0x0629, 0x062A, 0x062B, 0x062C, 0x062D, 0x062E, 0x062F, - /* 0xD0 */ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, - /* 0xD8 */ 0x0638, 0x0639, 0x063A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0xE0 */ 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, - /* 0xE8 */ 0x0648, 0x0649, 0x064A, 0x064B, 0x064C, 0x064D, 0x064E, 0x064F, - /* 0xF0 */ 0x0650, 0x0651, 0x0652, - }, - /* ISO-8859-7 */ { - /* 0xA0 */ 0x00A0, 0x2018, 0x2019, 0x00A3, 0x20AC, 0x20AF, 0x00A6, 0x00A7, - /* 0xA8 */ 0x00A8, 0x00A9, 0x037A, 0x00AB, 0x00AC, 0x00AD, 0x0000, 0x2015, - /* 0xB0 */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0384, 0x0385, 0x0386, 0x00B7, - /* 0xB8 */ 0x0388, 0x0389, 0x038A, 0x00BB, 0x038C, 0x00BD, 0x038E, 0x038F, - /* 0xC0 */ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - /* 0xC8 */ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, - /* 0xD0 */ 0x03A0, 0x03A1, 0x0000, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, - /* 0xD8 */ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, - /* 0xE0 */ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, - /* 0xE8 */ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, - /* 0xF0 */ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, - /* 0xF8 */ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, - }, - /* ISO-8859-8 */ { - /* 0xA0 */ 0x00A0, 0x0000, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, - /* 0xA8 */ 0x00A8, 0x00A9, 0x00D7, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, - /* 0xB0 */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, - /* 0xB8 */ 0x00B8, 0x00B9, 0x00F7, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x0000, - /* 0xC0 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0xC8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0xD0 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0xD8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2017, - /* 0xE0 */ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, - /* 0xE8 */ 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, - /* 0xF0 */ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, - /* 0xF8 */ 0x05E8, 0x05E9, 0x05EA, 0x0000, 0x0000, 0x200E, 0x200F, - }, - /* ISO-8859-9 */ { - /* 0xA0 */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, - /* 0xA8 */ 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, - /* 0xB0 */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, - /* 0xB8 */ 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, - /* 0xC0 */ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, - /* 0xC8 */ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - /* 0xD0 */ 0x011E, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, - /* 0xD8 */ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x0130, 0x015E, 0x00DF, - /* 0xE0 */ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, - /* 0xE8 */ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - /* 0xF0 */ 0x011F, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, - /* 0xF8 */ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x0131, 0x015F, 0x00FF, - }, - /* ISO-8859-10 */ { - /* 0xA0 */ 0x00A0, 0x0104, 0x0112, 0x0122, 0x012A, 0x0128, 0x0136, 0x00A7, - /* 0xA8 */ 0x013B, 0x0110, 0x0160, 0x0166, 0x017D, 0x00AD, 0x016A, 0x014A, - /* 0xB0 */ 0x00B0, 0x0105, 0x0113, 0x0123, 0x012B, 0x0129, 0x0137, 0x00B7, - /* 0xB8 */ 0x013C, 0x0111, 0x0161, 0x0167, 0x017E, 0x2015, 0x016B, 0x014B, - /* 0xC0 */ 0x0100, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x012E, - /* 0xC8 */ 0x010C, 0x00C9, 0x0118, 0x00CB, 0x0116, 0x00CD, 0x00CE, 0x00CF, - /* 0xD0 */ 0x00D0, 0x0145, 0x014C, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x0168, - /* 0xD8 */ 0x00D8, 0x0172, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, - /* 0xE0 */ 0x0101, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x012F, - /* 0xE8 */ 0x010D, 0x00E9, 0x0119, 0x00EB, 0x0117, 0x00ED, 0x00EE, 0x00EF, - /* 0xF0 */ 0x00F0, 0x0146, 0x014D, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x0169, - /* 0xF8 */ 0x00F8, 0x0173, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x0138, - }, - /* ISO-8859-11 */ { - /* 0xA0 */ 0x00A0, 0x0E01, 0x0E02, 0x0E03, 0x0E04, 0x0E05, 0x0E06, 0x0E07, - /* 0xA8 */ 0x0E08, 0x0E09, 0x0E0A, 0x0E0B, 0x0E0C, 0x0E0D, 0x0E0E, 0x0E0F, - /* 0xB0 */ 0x0E10, 0x0E11, 0x0E12, 0x0E13, 0x0E14, 0x0E15, 0x0E16, 0x0E17, - /* 0xB8 */ 0x0E18, 0x0E19, 0x0E1A, 0x0E1B, 0x0E1C, 0x0E1D, 0x0E1E, 0x0E1F, - /* 0xC0 */ 0x0E20, 0x0E21, 0x0E22, 0x0E23, 0x0E24, 0x0E25, 0x0E26, 0x0E27, - /* 0xC8 */ 0x0E28, 0x0E29, 0x0E2A, 0x0E2B, 0x0E2C, 0x0E2D, 0x0E2E, 0x0E2F, - /* 0xD0 */ 0x0E30, 0x0E31, 0x0E32, 0x0E33, 0x0E34, 0x0E35, 0x0E36, 0x0E37, - /* 0xD8 */ 0x0E38, 0x0E39, 0x0E3A, 0x0000, 0x0000, 0x0000, 0x0000, 0x0E3F, - /* 0xE0 */ 0x0E40, 0x0E41, 0x0E42, 0x0E43, 0x0E44, 0x0E45, 0x0E46, 0x0E47, - /* 0xE8 */ 0x0E48, 0x0E49, 0x0E4A, 0x0E4B, 0x0E4C, 0x0E4D, 0x0E4E, 0x0E4F, - /* 0xF0 */ 0x0E50, 0x0E51, 0x0E52, 0x0E53, 0x0E54, 0x0E55, 0x0E56, 0x0E57, - /* 0xF8 */ 0x0E58, 0x0E59, 0x0E5A, 0x0E5B, - }, - /* ISO-8859-13 */ { - /* 0xA0 */ 0x00A0, 0x201D, 0x00A2, 0x00A3, 0x00A4, 0x201E, 0x00A6, 0x00A7, - /* 0xA8 */ 0x00D8, 0x00A9, 0x0156, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00C6, - /* 0xB0 */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x201C, 0x00B5, 0x00B6, 0x00B7, - /* 0xB8 */ 0x00F8, 0x00B9, 0x0157, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00E6, - /* 0xC0 */ 0x0104, 0x012E, 0x0100, 0x0106, 0x00C4, 0x00C5, 0x0118, 0x0112, - /* 0xC8 */ 0x010C, 0x00C9, 0x0179, 0x0116, 0x0122, 0x0136, 0x012A, 0x013B, - /* 0xD0 */ 0x0160, 0x0143, 0x0145, 0x00D3, 0x014C, 0x00D5, 0x00D6, 0x00D7, - /* 0xD8 */ 0x0172, 0x0141, 0x015A, 0x016A, 0x00DC, 0x017B, 0x017D, 0x00DF, - /* 0xE0 */ 0x0105, 0x012F, 0x0101, 0x0107, 0x00E4, 0x00E5, 0x0119, 0x0113, - /* 0xE8 */ 0x010D, 0x00E9, 0x017A, 0x0117, 0x0123, 0x0137, 0x012B, 0x013C, - /* 0xF0 */ 0x0161, 0x0144, 0x0146, 0x00F3, 0x014D, 0x00F5, 0x00F6, 0x00F7, - /* 0xF8 */ 0x0173, 0x0142, 0x015B, 0x016B, 0x00FC, 0x017C, 0x017E, 0x2019, - }, - /* ISO-8859-14 */ { - /* 0xA0 */ 0x00A0, 0x1E02, 0x1E03, 0x00A3, 0x010A, 0x010B, 0x1E0A, 0x00A7, - /* 0xA8 */ 0x1E80, 0x00A9, 0x1E82, 0x1E0B, 0x1EF2, 0x00AD, 0x00AE, 0x0178, - /* 0xB0 */ 0x1E1E, 0x1E1F, 0x0120, 0x0121, 0x1E40, 0x1E41, 0x00B6, 0x1E56, - /* 0xB8 */ 0x1E81, 0x1E57, 0x1E83, 0x1E60, 0x1EF3, 0x1E84, 0x1E85, 0x1E61, - /* 0xC0 */ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, - /* 0xC8 */ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - /* 0xD0 */ 0x0174, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x1E6A, - /* 0xD8 */ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x0176, 0x00DF, - /* 0xE0 */ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, - /* 0xE8 */ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - /* 0xF0 */ 0x0175, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x1E6B, - /* 0xF8 */ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x0177, 0x00FF, - }, - /* ISO-8859-15 */ { - /* 0xA0 */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x20AC, 0x00A5, 0x0160, 0x00A7, - /* 0xA8 */ 0x0161, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, - /* 0xB0 */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x017D, 0x00B5, 0x00B6, 0x00B7, - /* 0xB8 */ 0x017E, 0x00B9, 0x00BA, 0x00BB, 0x0152, 0x0153, 0x0178, 0x00BF, - /* 0xC0 */ 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, - /* 0xC8 */ 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, - /* 0xD0 */ 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, - /* 0xD8 */ 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, - /* 0xE0 */ 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, - /* 0xE8 */ 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, - /* 0xF0 */ 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, - /* 0xF8 */ 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF, - } -}; + /* ISO-8859-1 */ { + /* 0xA0 */ 0x00A0, + 0x00A1, + 0x00A2, + 0x00A3, + 0x00A4, + 0x00A5, + 0x00A6, + 0x00A7, + /* 0xA8 */ 0x00A8, + 0x00A9, + 0x00AA, + 0x00AB, + 0x00AC, + 0x00AD, + 0x00AE, + 0x00AF, + /* 0xB0 */ 0x00B0, + 0x00B1, + 0x00B2, + 0x00B3, + 0x00B4, + 0x00B5, + 0x00B6, + 0x00B7, + /* 0xB8 */ 0x00B8, + 0x00B9, + 0x00BA, + 0x00BB, + 0x00BC, + 0x00BD, + 0x00BE, + 0x00BF, + /* 0xC0 */ 0x00C0, + 0x00C1, + 0x00C2, + 0x00C3, + 0x00C4, + 0x00C5, + 0x00C6, + 0x00C7, + /* 0xC8 */ 0x00C8, + 0x00C9, + 0x00CA, + 0x00CB, + 0x00CC, + 0x00CD, + 0x00CE, + 0x00CF, + /* 0xD0 */ 0x00D0, + 0x00D1, + 0x00D2, + 0x00D3, + 0x00D4, + 0x00D5, + 0x00D6, + 0x00D7, + /* 0xD8 */ 0x00D8, + 0x00D9, + 0x00DA, + 0x00DB, + 0x00DC, + 0x00DD, + 0x00DE, + 0x00DF, + /* 0xE0 */ 0x00E0, + 0x00E1, + 0x00E2, + 0x00E3, + 0x00E4, + 0x00E5, + 0x00E6, + 0x00E7, + /* 0xE8 */ 0x00E8, + 0x00E9, + 0x00EA, + 0x00EB, + 0x00EC, + 0x00ED, + 0x00EE, + 0x00EF, + /* 0xF0 */ 0x00F0, + 0x00F1, + 0x00F2, + 0x00F3, + 0x00F4, + 0x00F5, + 0x00F6, + 0x00F7, + /* 0xF8 */ 0x00F8, + 0x00F9, + 0x00FA, + 0x00FB, + 0x00FC, + 0x00FD, + 0x00FE, + 0x00FF, + }, + /* ISO-8859-2 */ + { + /* 0xA0 */ 0x00A0, + 0x0104, + 0x02D8, + 0x0141, + 0x00A4, + 0x013D, + 0x015A, + 0x00A7, + /* 0xA8 */ 0x00A8, + 0x0160, + 0x015E, + 0x0164, + 0x0179, + 0x00AD, + 0x017D, + 0x017B, + /* 0xB0 */ 0x00B0, + 0x0105, + 0x02DB, + 0x0142, + 0x00B4, + 0x013E, + 0x015B, + 0x02C7, + /* 0xB8 */ 0x00B8, + 0x0161, + 0x015F, + 0x0165, + 0x017A, + 0x02DD, + 0x017E, + 0x017C, + /* 0xC0 */ 0x0154, + 0x00C1, + 0x00C2, + 0x0102, + 0x00C4, + 0x0139, + 0x0106, + 0x00C7, + /* 0xC8 */ 0x010C, + 0x00C9, + 0x0118, + 0x00CB, + 0x011A, + 0x00CD, + 0x00CE, + 0x010E, + /* 0xD0 */ 0x0110, + 0x0143, + 0x0147, + 0x00D3, + 0x00D4, + 0x0150, + 0x00D6, + 0x00D7, + /* 0xD8 */ 0x0158, + 0x016E, + 0x00DA, + 0x0170, + 0x00DC, + 0x00DD, + 0x0162, + 0x00DF, + /* 0xE0 */ 0x0155, + 0x00E1, + 0x00E2, + 0x0103, + 0x00E4, + 0x013A, + 0x0107, + 0x00E7, + /* 0xE8 */ 0x010D, + 0x00E9, + 0x0119, + 0x00EB, + 0x011B, + 0x00ED, + 0x00EE, + 0x010F, + /* 0xF0 */ 0x0111, + 0x0144, + 0x0148, + 0x00F3, + 0x00F4, + 0x0151, + 0x00F6, + 0x00F7, + /* 0xF8 */ 0x0159, + 0x016F, + 0x00FA, + 0x0171, + 0x00FC, + 0x00FD, + 0x0163, + 0x02D9, + }, + /* ISO-8859-3 */ + { + /* 0xA0 */ 0x00A0, + 0x0126, + 0x02D8, + 0x00A3, + 0x00A4, + 0x0000, + 0x0124, + 0x00A7, + /* 0xA8 */ 0x00A8, + 0x0130, + 0x015E, + 0x011E, + 0x0134, + 0x00AD, + 0x0000, + 0x017B, + /* 0xB0 */ 0x00B0, + 0x0127, + 0x00B2, + 0x00B3, + 0x00B4, + 0x00B5, + 0x0125, + 0x00B7, + /* 0xB8 */ 0x00B8, + 0x0131, + 0x015F, + 0x011F, + 0x0135, + 0x00BD, + 0x0000, + 0x017C, + /* 0xC0 */ 0x00C0, + 0x00C1, + 0x00C2, + 0x0000, + 0x00C4, + 0x010A, + 0x0108, + 0x00C7, + /* 0xC8 */ 0x00C8, + 0x00C9, + 0x00CA, + 0x00CB, + 0x00CC, + 0x00CD, + 0x00CE, + 0x00CF, + /* 0xD0 */ 0x0000, + 0x00D1, + 0x00D2, + 0x00D3, + 0x00D4, + 0x0120, + 0x00D6, + 0x00D7, + /* 0xD8 */ 0x011C, + 0x00D9, + 0x00DA, + 0x00DB, + 0x00DC, + 0x016C, + 0x015C, + 0x00DF, + /* 0xE0 */ 0x00E0, + 0x00E1, + 0x00E2, + 0x0000, + 0x00E4, + 0x010B, + 0x0109, + 0x00E7, + /* 0xE8 */ 0x00E8, + 0x00E9, + 0x00EA, + 0x00EB, + 0x00EC, + 0x00ED, + 0x00EE, + 0x00EF, + /* 0xF0 */ 0x0000, + 0x00F1, + 0x00F2, + 0x00F3, + 0x00F4, + 0x0121, + 0x00F6, + 0x00F7, + /* 0xF8 */ 0x011D, + 0x00F9, + 0x00FA, + 0x00FB, + 0x00FC, + 0x016D, + 0x015D, + 0x02D9, + }, + /* ISO-8859-4 */ + { + /* 0xA0 */ 0x00A0, + 0x0104, + 0x0138, + 0x0156, + 0x00A4, + 0x0128, + 0x013B, + 0x00A7, + /* 0xA8 */ 0x00A8, + 0x0160, + 0x0112, + 0x0122, + 0x0166, + 0x00AD, + 0x017D, + 0x00AF, + /* 0xB0 */ 0x00B0, + 0x0105, + 0x02DB, + 0x0157, + 0x00B4, + 0x0129, + 0x013C, + 0x02C7, + /* 0xB8 */ 0x00B8, + 0x0161, + 0x0113, + 0x0123, + 0x0167, + 0x014A, + 0x017E, + 0x014B, + /* 0xC0 */ 0x0100, + 0x00C1, + 0x00C2, + 0x00C3, + 0x00C4, + 0x00C5, + 0x00C6, + 0x012E, + /* 0xC8 */ 0x010C, + 0x00C9, + 0x0118, + 0x00CB, + 0x0116, + 0x00CD, + 0x00CE, + 0x012A, + /* 0xD0 */ 0x0110, + 0x0145, + 0x014C, + 0x0136, + 0x00D4, + 0x00D5, + 0x00D6, + 0x00D7, + /* 0xD8 */ 0x00D8, + 0x0172, + 0x00DA, + 0x00DB, + 0x00DC, + 0x0168, + 0x016A, + 0x00DF, + /* 0xE0 */ 0x0101, + 0x00E1, + 0x00E2, + 0x00E3, + 0x00E4, + 0x00E5, + 0x00E6, + 0x012F, + /* 0xE8 */ 0x010D, + 0x00E9, + 0x0119, + 0x00EB, + 0x0117, + 0x00ED, + 0x00EE, + 0x012B, + /* 0xF0 */ 0x0111, + 0x0146, + 0x014D, + 0x0137, + 0x00F4, + 0x00F5, + 0x00F6, + 0x00F7, + /* 0xF8 */ 0x00F8, + 0x0173, + 0x00FA, + 0x00FB, + 0x00FC, + 0x0169, + 0x016B, + 0x02D9, + }, + /* ISO-8859-5 */ + { + /* 0xA0 */ 0x00A0, + 0x0401, + 0x0402, + 0x0403, + 0x0404, + 0x0405, + 0x0406, + 0x0407, + /* 0xA8 */ 0x0408, + 0x0409, + 0x040A, + 0x040B, + 0x040C, + 0x00AD, + 0x040E, + 0x040F, + /* 0xB0 */ 0x0410, + 0x0411, + 0x0412, + 0x0413, + 0x0414, + 0x0415, + 0x0416, + 0x0417, + /* 0xB8 */ 0x0418, + 0x0419, + 0x041A, + 0x041B, + 0x041C, + 0x041D, + 0x041E, + 0x041F, + /* 0xC0 */ 0x0420, + 0x0421, + 0x0422, + 0x0423, + 0x0424, + 0x0425, + 0x0426, + 0x0427, + /* 0xC8 */ 0x0428, + 0x0429, + 0x042A, + 0x042B, + 0x042C, + 0x042D, + 0x042E, + 0x042F, + /* 0xD0 */ 0x0430, + 0x0431, + 0x0432, + 0x0433, + 0x0434, + 0x0435, + 0x0436, + 0x0437, + /* 0xD8 */ 0x0438, + 0x0439, + 0x043A, + 0x043B, + 0x043C, + 0x043D, + 0x043E, + 0x043F, + /* 0xE0 */ 0x0440, + 0x0441, + 0x0442, + 0x0443, + 0x0444, + 0x0445, + 0x0446, + 0x0447, + /* 0xE8 */ 0x0448, + 0x0449, + 0x044A, + 0x044B, + 0x044C, + 0x044D, + 0x044E, + 0x044F, + /* 0xF0 */ 0x2116, + 0x0451, + 0x0452, + 0x0453, + 0x0454, + 0x0455, + 0x0456, + 0x0457, + /* 0xF8 */ 0x0458, + 0x0459, + 0x045A, + 0x045B, + 0x045C, + 0x00A7, + 0x045E, + 0x045F, + }, + /* ISO-8859-6 */ + { + /* 0xA0 */ 0x00A0, + 0x0000, + 0x0000, + 0x0000, + 0x00A4, + 0x0000, + 0x0000, + 0x0000, + /* 0xA8 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x060C, + 0x00AD, + 0x0000, + 0x0000, + /* 0xB0 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0xB8 */ 0x0000, + 0x0000, + 0x0000, + 0x061B, + 0x0000, + 0x0000, + 0x0000, + 0x061F, + /* 0xC0 */ 0x0000, + 0x0621, + 0x0622, + 0x0623, + 0x0624, + 0x0625, + 0x0626, + 0x0627, + /* 0xC8 */ 0x0628, + 0x0629, + 0x062A, + 0x062B, + 0x062C, + 0x062D, + 0x062E, + 0x062F, + /* 0xD0 */ 0x0630, + 0x0631, + 0x0632, + 0x0633, + 0x0634, + 0x0635, + 0x0636, + 0x0637, + /* 0xD8 */ 0x0638, + 0x0639, + 0x063A, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0xE0 */ 0x0640, + 0x0641, + 0x0642, + 0x0643, + 0x0644, + 0x0645, + 0x0646, + 0x0647, + /* 0xE8 */ 0x0648, + 0x0649, + 0x064A, + 0x064B, + 0x064C, + 0x064D, + 0x064E, + 0x064F, + /* 0xF0 */ 0x0650, + 0x0651, + 0x0652, + }, + /* ISO-8859-7 */ + { + /* 0xA0 */ 0x00A0, + 0x2018, + 0x2019, + 0x00A3, + 0x20AC, + 0x20AF, + 0x00A6, + 0x00A7, + /* 0xA8 */ 0x00A8, + 0x00A9, + 0x037A, + 0x00AB, + 0x00AC, + 0x00AD, + 0x0000, + 0x2015, + /* 0xB0 */ 0x00B0, + 0x00B1, + 0x00B2, + 0x00B3, + 0x0384, + 0x0385, + 0x0386, + 0x00B7, + /* 0xB8 */ 0x0388, + 0x0389, + 0x038A, + 0x00BB, + 0x038C, + 0x00BD, + 0x038E, + 0x038F, + /* 0xC0 */ 0x0390, + 0x0391, + 0x0392, + 0x0393, + 0x0394, + 0x0395, + 0x0396, + 0x0397, + /* 0xC8 */ 0x0398, + 0x0399, + 0x039A, + 0x039B, + 0x039C, + 0x039D, + 0x039E, + 0x039F, + /* 0xD0 */ 0x03A0, + 0x03A1, + 0x0000, + 0x03A3, + 0x03A4, + 0x03A5, + 0x03A6, + 0x03A7, + /* 0xD8 */ 0x03A8, + 0x03A9, + 0x03AA, + 0x03AB, + 0x03AC, + 0x03AD, + 0x03AE, + 0x03AF, + /* 0xE0 */ 0x03B0, + 0x03B1, + 0x03B2, + 0x03B3, + 0x03B4, + 0x03B5, + 0x03B6, + 0x03B7, + /* 0xE8 */ 0x03B8, + 0x03B9, + 0x03BA, + 0x03BB, + 0x03BC, + 0x03BD, + 0x03BE, + 0x03BF, + /* 0xF0 */ 0x03C0, + 0x03C1, + 0x03C2, + 0x03C3, + 0x03C4, + 0x03C5, + 0x03C6, + 0x03C7, + /* 0xF8 */ 0x03C8, + 0x03C9, + 0x03CA, + 0x03CB, + 0x03CC, + 0x03CD, + 0x03CE, + }, + /* ISO-8859-8 */ + { + /* 0xA0 */ 0x00A0, + 0x0000, + 0x00A2, + 0x00A3, + 0x00A4, + 0x00A5, + 0x00A6, + 0x00A7, + /* 0xA8 */ 0x00A8, + 0x00A9, + 0x00D7, + 0x00AB, + 0x00AC, + 0x00AD, + 0x00AE, + 0x00AF, + /* 0xB0 */ 0x00B0, + 0x00B1, + 0x00B2, + 0x00B3, + 0x00B4, + 0x00B5, + 0x00B6, + 0x00B7, + /* 0xB8 */ 0x00B8, + 0x00B9, + 0x00F7, + 0x00BB, + 0x00BC, + 0x00BD, + 0x00BE, + 0x0000, + /* 0xC0 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0xC8 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0xD0 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0xD8 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x2017, + /* 0xE0 */ 0x05D0, + 0x05D1, + 0x05D2, + 0x05D3, + 0x05D4, + 0x05D5, + 0x05D6, + 0x05D7, + /* 0xE8 */ 0x05D8, + 0x05D9, + 0x05DA, + 0x05DB, + 0x05DC, + 0x05DD, + 0x05DE, + 0x05DF, + /* 0xF0 */ 0x05E0, + 0x05E1, + 0x05E2, + 0x05E3, + 0x05E4, + 0x05E5, + 0x05E6, + 0x05E7, + /* 0xF8 */ 0x05E8, + 0x05E9, + 0x05EA, + 0x0000, + 0x0000, + 0x200E, + 0x200F, + }, + /* ISO-8859-9 */ + { + /* 0xA0 */ 0x00A0, + 0x00A1, + 0x00A2, + 0x00A3, + 0x00A4, + 0x00A5, + 0x00A6, + 0x00A7, + /* 0xA8 */ 0x00A8, + 0x00A9, + 0x00AA, + 0x00AB, + 0x00AC, + 0x00AD, + 0x00AE, + 0x00AF, + /* 0xB0 */ 0x00B0, + 0x00B1, + 0x00B2, + 0x00B3, + 0x00B4, + 0x00B5, + 0x00B6, + 0x00B7, + /* 0xB8 */ 0x00B8, + 0x00B9, + 0x00BA, + 0x00BB, + 0x00BC, + 0x00BD, + 0x00BE, + 0x00BF, + /* 0xC0 */ 0x00C0, + 0x00C1, + 0x00C2, + 0x00C3, + 0x00C4, + 0x00C5, + 0x00C6, + 0x00C7, + /* 0xC8 */ 0x00C8, + 0x00C9, + 0x00CA, + 0x00CB, + 0x00CC, + 0x00CD, + 0x00CE, + 0x00CF, + /* 0xD0 */ 0x011E, + 0x00D1, + 0x00D2, + 0x00D3, + 0x00D4, + 0x00D5, + 0x00D6, + 0x00D7, + /* 0xD8 */ 0x00D8, + 0x00D9, + 0x00DA, + 0x00DB, + 0x00DC, + 0x0130, + 0x015E, + 0x00DF, + /* 0xE0 */ 0x00E0, + 0x00E1, + 0x00E2, + 0x00E3, + 0x00E4, + 0x00E5, + 0x00E6, + 0x00E7, + /* 0xE8 */ 0x00E8, + 0x00E9, + 0x00EA, + 0x00EB, + 0x00EC, + 0x00ED, + 0x00EE, + 0x00EF, + /* 0xF0 */ 0x011F, + 0x00F1, + 0x00F2, + 0x00F3, + 0x00F4, + 0x00F5, + 0x00F6, + 0x00F7, + /* 0xF8 */ 0x00F8, + 0x00F9, + 0x00FA, + 0x00FB, + 0x00FC, + 0x0131, + 0x015F, + 0x00FF, + }, + /* ISO-8859-10 */ + { + /* 0xA0 */ 0x00A0, + 0x0104, + 0x0112, + 0x0122, + 0x012A, + 0x0128, + 0x0136, + 0x00A7, + /* 0xA8 */ 0x013B, + 0x0110, + 0x0160, + 0x0166, + 0x017D, + 0x00AD, + 0x016A, + 0x014A, + /* 0xB0 */ 0x00B0, + 0x0105, + 0x0113, + 0x0123, + 0x012B, + 0x0129, + 0x0137, + 0x00B7, + /* 0xB8 */ 0x013C, + 0x0111, + 0x0161, + 0x0167, + 0x017E, + 0x2015, + 0x016B, + 0x014B, + /* 0xC0 */ 0x0100, + 0x00C1, + 0x00C2, + 0x00C3, + 0x00C4, + 0x00C5, + 0x00C6, + 0x012E, + /* 0xC8 */ 0x010C, + 0x00C9, + 0x0118, + 0x00CB, + 0x0116, + 0x00CD, + 0x00CE, + 0x00CF, + /* 0xD0 */ 0x00D0, + 0x0145, + 0x014C, + 0x00D3, + 0x00D4, + 0x00D5, + 0x00D6, + 0x0168, + /* 0xD8 */ 0x00D8, + 0x0172, + 0x00DA, + 0x00DB, + 0x00DC, + 0x00DD, + 0x00DE, + 0x00DF, + /* 0xE0 */ 0x0101, + 0x00E1, + 0x00E2, + 0x00E3, + 0x00E4, + 0x00E5, + 0x00E6, + 0x012F, + /* 0xE8 */ 0x010D, + 0x00E9, + 0x0119, + 0x00EB, + 0x0117, + 0x00ED, + 0x00EE, + 0x00EF, + /* 0xF0 */ 0x00F0, + 0x0146, + 0x014D, + 0x00F3, + 0x00F4, + 0x00F5, + 0x00F6, + 0x0169, + /* 0xF8 */ 0x00F8, + 0x0173, + 0x00FA, + 0x00FB, + 0x00FC, + 0x00FD, + 0x00FE, + 0x0138, + }, + /* ISO-8859-11 */ + { + /* 0xA0 */ 0x00A0, + 0x0E01, + 0x0E02, + 0x0E03, + 0x0E04, + 0x0E05, + 0x0E06, + 0x0E07, + /* 0xA8 */ 0x0E08, + 0x0E09, + 0x0E0A, + 0x0E0B, + 0x0E0C, + 0x0E0D, + 0x0E0E, + 0x0E0F, + /* 0xB0 */ 0x0E10, + 0x0E11, + 0x0E12, + 0x0E13, + 0x0E14, + 0x0E15, + 0x0E16, + 0x0E17, + /* 0xB8 */ 0x0E18, + 0x0E19, + 0x0E1A, + 0x0E1B, + 0x0E1C, + 0x0E1D, + 0x0E1E, + 0x0E1F, + /* 0xC0 */ 0x0E20, + 0x0E21, + 0x0E22, + 0x0E23, + 0x0E24, + 0x0E25, + 0x0E26, + 0x0E27, + /* 0xC8 */ 0x0E28, + 0x0E29, + 0x0E2A, + 0x0E2B, + 0x0E2C, + 0x0E2D, + 0x0E2E, + 0x0E2F, + /* 0xD0 */ 0x0E30, + 0x0E31, + 0x0E32, + 0x0E33, + 0x0E34, + 0x0E35, + 0x0E36, + 0x0E37, + /* 0xD8 */ 0x0E38, + 0x0E39, + 0x0E3A, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0E3F, + /* 0xE0 */ 0x0E40, + 0x0E41, + 0x0E42, + 0x0E43, + 0x0E44, + 0x0E45, + 0x0E46, + 0x0E47, + /* 0xE8 */ 0x0E48, + 0x0E49, + 0x0E4A, + 0x0E4B, + 0x0E4C, + 0x0E4D, + 0x0E4E, + 0x0E4F, + /* 0xF0 */ 0x0E50, + 0x0E51, + 0x0E52, + 0x0E53, + 0x0E54, + 0x0E55, + 0x0E56, + 0x0E57, + /* 0xF8 */ 0x0E58, + 0x0E59, + 0x0E5A, + 0x0E5B, + }, + /* ISO-8859-13 */ + { + /* 0xA0 */ 0x00A0, + 0x201D, + 0x00A2, + 0x00A3, + 0x00A4, + 0x201E, + 0x00A6, + 0x00A7, + /* 0xA8 */ 0x00D8, + 0x00A9, + 0x0156, + 0x00AB, + 0x00AC, + 0x00AD, + 0x00AE, + 0x00C6, + /* 0xB0 */ 0x00B0, + 0x00B1, + 0x00B2, + 0x00B3, + 0x201C, + 0x00B5, + 0x00B6, + 0x00B7, + /* 0xB8 */ 0x00F8, + 0x00B9, + 0x0157, + 0x00BB, + 0x00BC, + 0x00BD, + 0x00BE, + 0x00E6, + /* 0xC0 */ 0x0104, + 0x012E, + 0x0100, + 0x0106, + 0x00C4, + 0x00C5, + 0x0118, + 0x0112, + /* 0xC8 */ 0x010C, + 0x00C9, + 0x0179, + 0x0116, + 0x0122, + 0x0136, + 0x012A, + 0x013B, + /* 0xD0 */ 0x0160, + 0x0143, + 0x0145, + 0x00D3, + 0x014C, + 0x00D5, + 0x00D6, + 0x00D7, + /* 0xD8 */ 0x0172, + 0x0141, + 0x015A, + 0x016A, + 0x00DC, + 0x017B, + 0x017D, + 0x00DF, + /* 0xE0 */ 0x0105, + 0x012F, + 0x0101, + 0x0107, + 0x00E4, + 0x00E5, + 0x0119, + 0x0113, + /* 0xE8 */ 0x010D, + 0x00E9, + 0x017A, + 0x0117, + 0x0123, + 0x0137, + 0x012B, + 0x013C, + /* 0xF0 */ 0x0161, + 0x0144, + 0x0146, + 0x00F3, + 0x014D, + 0x00F5, + 0x00F6, + 0x00F7, + /* 0xF8 */ 0x0173, + 0x0142, + 0x015B, + 0x016B, + 0x00FC, + 0x017C, + 0x017E, + 0x2019, + }, + /* ISO-8859-14 */ + { + /* 0xA0 */ 0x00A0, + 0x1E02, + 0x1E03, + 0x00A3, + 0x010A, + 0x010B, + 0x1E0A, + 0x00A7, + /* 0xA8 */ 0x1E80, + 0x00A9, + 0x1E82, + 0x1E0B, + 0x1EF2, + 0x00AD, + 0x00AE, + 0x0178, + /* 0xB0 */ 0x1E1E, + 0x1E1F, + 0x0120, + 0x0121, + 0x1E40, + 0x1E41, + 0x00B6, + 0x1E56, + /* 0xB8 */ 0x1E81, + 0x1E57, + 0x1E83, + 0x1E60, + 0x1EF3, + 0x1E84, + 0x1E85, + 0x1E61, + /* 0xC0 */ 0x00C0, + 0x00C1, + 0x00C2, + 0x00C3, + 0x00C4, + 0x00C5, + 0x00C6, + 0x00C7, + /* 0xC8 */ 0x00C8, + 0x00C9, + 0x00CA, + 0x00CB, + 0x00CC, + 0x00CD, + 0x00CE, + 0x00CF, + /* 0xD0 */ 0x0174, + 0x00D1, + 0x00D2, + 0x00D3, + 0x00D4, + 0x00D5, + 0x00D6, + 0x1E6A, + /* 0xD8 */ 0x00D8, + 0x00D9, + 0x00DA, + 0x00DB, + 0x00DC, + 0x00DD, + 0x0176, + 0x00DF, + /* 0xE0 */ 0x00E0, + 0x00E1, + 0x00E2, + 0x00E3, + 0x00E4, + 0x00E5, + 0x00E6, + 0x00E7, + /* 0xE8 */ 0x00E8, + 0x00E9, + 0x00EA, + 0x00EB, + 0x00EC, + 0x00ED, + 0x00EE, + 0x00EF, + /* 0xF0 */ 0x0175, + 0x00F1, + 0x00F2, + 0x00F3, + 0x00F4, + 0x00F5, + 0x00F6, + 0x1E6B, + /* 0xF8 */ 0x00F8, + 0x00F9, + 0x00FA, + 0x00FB, + 0x00FC, + 0x00FD, + 0x0177, + 0x00FF, + }, + /* ISO-8859-15 */ + { + /* 0xA0 */ 0x00A0, + 0x00A1, + 0x00A2, + 0x00A3, + 0x20AC, + 0x00A5, + 0x0160, + 0x00A7, + /* 0xA8 */ 0x0161, + 0x00A9, + 0x00AA, + 0x00AB, + 0x00AC, + 0x00AD, + 0x00AE, + 0x00AF, + /* 0xB0 */ 0x00B0, + 0x00B1, + 0x00B2, + 0x00B3, + 0x017D, + 0x00B5, + 0x00B6, + 0x00B7, + /* 0xB8 */ 0x017E, + 0x00B9, + 0x00BA, + 0x00BB, + 0x0152, + 0x0153, + 0x0178, + 0x00BF, + /* 0xC0 */ 0x00C0, + 0x00C1, + 0x00C2, + 0x00C3, + 0x00C4, + 0x00C5, + 0x00C6, + 0x00C7, + /* 0xC8 */ 0x00C8, + 0x00C9, + 0x00CA, + 0x00CB, + 0x00CC, + 0x00CD, + 0x00CE, + 0x00CF, + /* 0xD0 */ 0x00D0, + 0x00D1, + 0x00D2, + 0x00D3, + 0x00D4, + 0x00D5, + 0x00D6, + 0x00D7, + /* 0xD8 */ 0x00D8, + 0x00D9, + 0x00DA, + 0x00DB, + 0x00DC, + 0x00DD, + 0x00DE, + 0x00DF, + /* 0xE0 */ 0x00E0, + 0x00E1, + 0x00E2, + 0x00E3, + 0x00E4, + 0x00E5, + 0x00E6, + 0x00E7, + /* 0xE8 */ 0x00E8, + 0x00E9, + 0x00EA, + 0x00EB, + 0x00EC, + 0x00ED, + 0x00EE, + 0x00EF, + /* 0xF0 */ 0x00F0, + 0x00F1, + 0x00F2, + 0x00F3, + 0x00F4, + 0x00F5, + 0x00F6, + 0x00F7, + /* 0xF8 */ 0x00F8, + 0x00F9, + 0x00FA, + 0x00FB, + 0x00FC, + 0x00FD, + 0x00FE, + 0x00FF, + }}; // Code table for ISO6937 codes from 0xa0 to 0xbf and 0xd0 to 0xff static const uint16_t iso6937_single_byte[96] = { - /* 0xA0 */ 0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x0000, 0x00a5, 0x0000, 0x00a7, - /* 0xA8 */ 0x00a4, 0x2018, 0x201c, 0x00ab, 0x2190, 0x2191, 0x2192, 0x2193, - /* 0xB0 */ 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00d7, 0x00b5, 0x00b6, 0x00b7, - /* 0xB8 */ 0x00f7, 0x2019, 0x201d, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, - /* 0xC0 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0xC8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0xD0 */ 0x2014, 0x00b9, 0x00ae, 0x00a9, 0x2122, 0x266a, 0x00ac, 0x00a6, - /* 0xD8 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x215b, 0x215c, 0x215d, 0x215e, - /* 0xE0 */ 0x2126, 0x00c6, 0x00d0, 0x00aa, 0x0126, 0x0000, 0x0132, 0x013f, - /* 0xE8 */ 0x0141, 0x00d8, 0x0152, 0x00ba, 0x00de, 0x0166, 0x014a, 0x0149, - /* 0xF0 */ 0x0138, 0x00e6, 0x0111, 0x00f0, 0x0127, 0x0131, 0x0133, 0x0140, - /* 0xF8 */ 0x0142, 0x00f8, 0x0153, 0x00df, 0x00fe, 0x0167, 0x014b, 0x00ad, + /* 0xA0 */ 0x00a0, + 0x00a1, + 0x00a2, + 0x00a3, + 0x0000, + 0x00a5, + 0x0000, + 0x00a7, + /* 0xA8 */ 0x00a4, + 0x2018, + 0x201c, + 0x00ab, + 0x2190, + 0x2191, + 0x2192, + 0x2193, + /* 0xB0 */ 0x00b0, + 0x00b1, + 0x00b2, + 0x00b3, + 0x00d7, + 0x00b5, + 0x00b6, + 0x00b7, + /* 0xB8 */ 0x00f7, + 0x2019, + 0x201d, + 0x00bb, + 0x00bc, + 0x00bd, + 0x00be, + 0x00bf, + /* 0xC0 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0xC8 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0xD0 */ 0x2014, + 0x00b9, + 0x00ae, + 0x00a9, + 0x2122, + 0x266a, + 0x00ac, + 0x00a6, + /* 0xD8 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x215b, + 0x215c, + 0x215d, + 0x215e, + /* 0xE0 */ 0x2126, + 0x00c6, + 0x00d0, + 0x00aa, + 0x0126, + 0x0000, + 0x0132, + 0x013f, + /* 0xE8 */ 0x0141, + 0x00d8, + 0x0152, + 0x00ba, + 0x00de, + 0x0166, + 0x014a, + 0x0149, + /* 0xF0 */ 0x0138, + 0x00e6, + 0x0111, + 0x00f0, + 0x0127, + 0x0131, + 0x0133, + 0x0140, + /* 0xF8 */ 0x0142, + 0x00f8, + 0x0153, + 0x00df, + 0x00fe, + 0x0167, + 0x014b, + 0x00ad, }; // Code table for ISO6937 two-byte sequences combining an accent byte. // in the range 0xc0 to 0xcf with a space character (0x20) static const uint16_t iso6937_lone_accents[16] = { - /* 0xC0 */ 0x0000, 0x00B4, 0x0000, 0x0000, 0x0000, 0x00Af, 0x02D8, 0x02D9, - /* 0xC8 */ 0x00A8, 0x0000, 0x02DA, 0x00B8, 0x0000, 0x02DD, 0x02DB, 0x02C7, + /* 0xC0 */ 0x0000, + 0x00B4, + 0x0000, + 0x0000, + 0x0000, + 0x00Af, + 0x02D8, + 0x02D9, + /* 0xC8 */ 0x00A8, + 0x0000, + 0x02DA, + 0x00B8, + 0x0000, + 0x02DD, + 0x02DB, + 0x02C7, }; // Code tables for ISO6937 two-byte sequences combining an accent byte. // in the range 0xc1 to 0xcf with a letter in one of the ranges // 0x41 to 0x5a (A-Z) or 0x61 to 0x7a (a-z) static const uint16_t iso6937_multi_byte[16][52] = { - /* 0xC0 */ - { - 0x0000, - }, - /* 0xC1 */ - { - /* A-Z */ - 0x00c0, 0x0000, 0x0000, 0x0000, 0x00c8, 0x0000, 0x0000, 0x0000, 0x00cc, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x00d2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00d9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* a-z */ - 0x00e0, 0x0000, 0x0000, 0x0000, 0x00e8, 0x0000, 0x0000, 0x0000, 0x00ec, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x00f2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00f9, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - }, - /* 0xC2 */ - { - /* A-Z */ - 0x00c1, 0x0000, 0x0106, 0x0000, 0x00c9, 0x0000, 0x0000, 0x0000, 0x00cd, 0x0000, 0x0000, 0x0139, 0x0000, - 0x0143, 0x00d3, 0x0000, 0x0000, 0x0154, 0x015a, 0x0000, 0x00da, 0x0000, 0x0000, 0x0000, 0x00dd, 0x0179, - /* a-z */ - 0x00e1, 0x0000, 0x0107, 0x0000, 0x00e9, 0x0000, 0x0000, 0x0000, 0x00ed, 0x0000, 0x0000, 0x013a, 0x0000, - 0x0144, 0x00f3, 0x0000, 0x0000, 0x0155, 0x015b, 0x0000, 0x00fa, 0x0000, 0x0000, 0x0000, 0x00fd, 0x017a - }, - /* 0xC3 */ - { - /* A-Z */ - 0x00c2, 0x0000, 0x0108, 0x0000, 0x00ca, 0x0000, 0x011c, 0x0124, 0x00ce, 0x0134, 0x0000, 0x0000, 0x0000, - 0x0000, 0x00d4, 0x0000, 0x0000, 0x0000, 0x015c, 0x0000, 0x00db, 0x0000, 0x0174, 0x0000, 0x0176, 0x0000, - /* a-z */ - 0x00e2, 0x0000, 0x0109, 0x0000, 0x00ea, 0x0000, 0x011d, 0x0125, 0x00ee, 0x0135, 0x0000, 0x0000, 0x0000, - 0x0000, 0x00f4, 0x0000, 0x0000, 0x0000, 0x015d, 0x0000, 0x00fb, 0x0000, 0x0175, 0x0000, 0x0177, 0x0000 - }, - /* 0xC4 */ - { - /* A-Z */ - 0x00c3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0128, 0x0000, 0x0000, 0x0000, 0x0000, - 0x00d1, 0x00d5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0168, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* a-z */ - 0x00e3, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0129, 0x0000, 0x0000, 0x0000, 0x0000, - 0x00f1, 0x00f5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0169, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }, - /* 0xC5 */ - { - /* A-Z */ - 0x0100, 0x0000, 0x0000, 0x0000, 0x0112, 0x0000, 0x0000, 0x0000, 0x012a, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x014c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* a-z */ - 0x0101, 0x0000, 0x0000, 0x0000, 0x0113, 0x0000, 0x0000, 0x0000, 0x012b, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x014d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }, - /* 0xC6 */ - { - /* A-Z */ - 0x0102, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x011e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* a-z */ - 0x0103, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x011f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }, - /* 0xC7 */ - { - /* A-Z */ - 0x0000, 0x0000, 0x010a, 0x0000, 0x0116, 0x0000, 0x0120, 0x0000, 0x0130, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x017b, - /* a-z */ - 0x0000, 0x0000, 0x010b, 0x0000, 0x0117, 0x0000, 0x0121, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x017c - }, - /* 0xC8 */ - { - /* A-Z */ - 0x00c4, 0x0000, 0x0000, 0x0000, 0x00cb, 0x0000, 0x0000, 0x0000, 0x00cf, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x00d6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00dc, 0x0000, 0x0000, 0x0000, 0x0178, 0x0000, - /* a-z */ - 0x00e4, 0x0000, 0x0000, 0x0000, 0x00eb, 0x0000, 0x0000, 0x0000, 0x00ef, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x00f6, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x00fc, 0x0000, 0x0000, 0x0000, 0x00ff, 0x0000 - }, - /* 0xC9 */ - { - 0x0000, - }, - /* 0xCA */ - { - /* A-Z */ - 0x00c5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* a-z */ - 0x00e5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x016f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }, - /* 0xCB */ - { - /* A-Z */ - 0x0000, 0x0000, 0x00c7, 0x0000, 0x0000, 0x0000, 0x0122, 0x0000, 0x0000, 0x0000, 0x0136, 0x013b, 0x0000, - 0x0145, 0x0000, 0x0000, 0x0000, 0x0156, 0x015e, 0x0162, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* a-z */ - 0x0000, 0x0000, 0x00e7, 0x0000, 0x0000, 0x0000, 0x0123, 0x0000, 0x0000, 0x0000, 0x0137, 0x013c, 0x0000, - 0x0146, 0x0000, 0x0000, 0x0000, 0x0157, 0x015f, 0x0163, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }, - /* 0xCC */ - { - 0x0000, - }, - /* 0xCD */ - { - /* A-Z */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0150, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0170, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* a-z */ - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0151, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0171, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }, - /* 0xCE */ - { - /* A-Z */ - 0x0104, 0x0000, 0x0000, 0x0000, 0x0118, 0x0000, 0x0000, 0x0000, 0x012e, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0172, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* a-z */ - 0x0105, 0x0000, 0x0000, 0x0000, 0x0119, 0x0000, 0x0000, 0x0000, 0x012f, 0x0000, 0x0000, 0x0000, 0x0000, - 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0173, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 - }, - /* 0xCF */ - { - /* A-Z */ - 0x0000, 0x0000, 0x010c, 0x010e, 0x011a, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x013d, 0x0000, - 0x0147, 0x0000, 0x0000, 0x0000, 0x0158, 0x0160, 0x0164, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x017d, - /* a-z */ - 0x0000, 0x0000, 0x010d, 0x010f, 0x011b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x013e, 0x0000, - 0x0148, 0x0000, 0x0000, 0x0000, 0x0159, 0x0161, 0x0165, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x017e - } -}; + /* 0xC0 */ + { + 0x0000, + }, + /* 0xC1 */ + { + /* A-Z */ + 0x00c0, + 0x0000, + 0x0000, + 0x0000, + 0x00c8, + 0x0000, + 0x0000, + 0x0000, + 0x00cc, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00d2, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00d9, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* a-z */ + 0x00e0, + 0x0000, + 0x0000, + 0x0000, + 0x00e8, + 0x0000, + 0x0000, + 0x0000, + 0x00ec, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00f2, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00f9, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + }, + /* 0xC2 */ + {/* A-Z */ + 0x00c1, + 0x0000, + 0x0106, + 0x0000, + 0x00c9, + 0x0000, + 0x0000, + 0x0000, + 0x00cd, + 0x0000, + 0x0000, + 0x0139, + 0x0000, + 0x0143, + 0x00d3, + 0x0000, + 0x0000, + 0x0154, + 0x015a, + 0x0000, + 0x00da, + 0x0000, + 0x0000, + 0x0000, + 0x00dd, + 0x0179, + /* a-z */ + 0x00e1, + 0x0000, + 0x0107, + 0x0000, + 0x00e9, + 0x0000, + 0x0000, + 0x0000, + 0x00ed, + 0x0000, + 0x0000, + 0x013a, + 0x0000, + 0x0144, + 0x00f3, + 0x0000, + 0x0000, + 0x0155, + 0x015b, + 0x0000, + 0x00fa, + 0x0000, + 0x0000, + 0x0000, + 0x00fd, + 0x017a}, + /* 0xC3 */ + {/* A-Z */ + 0x00c2, + 0x0000, + 0x0108, + 0x0000, + 0x00ca, + 0x0000, + 0x011c, + 0x0124, + 0x00ce, + 0x0134, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00d4, + 0x0000, + 0x0000, + 0x0000, + 0x015c, + 0x0000, + 0x00db, + 0x0000, + 0x0174, + 0x0000, + 0x0176, + 0x0000, + /* a-z */ + 0x00e2, + 0x0000, + 0x0109, + 0x0000, + 0x00ea, + 0x0000, + 0x011d, + 0x0125, + 0x00ee, + 0x0135, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00f4, + 0x0000, + 0x0000, + 0x0000, + 0x015d, + 0x0000, + 0x00fb, + 0x0000, + 0x0175, + 0x0000, + 0x0177, + 0x0000}, + /* 0xC4 */ + {/* A-Z */ + 0x00c3, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0128, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00d1, + 0x00d5, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0168, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* a-z */ + 0x00e3, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0129, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00f1, + 0x00f5, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0169, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000}, + /* 0xC5 */ + {/* A-Z */ + 0x0100, + 0x0000, + 0x0000, + 0x0000, + 0x0112, + 0x0000, + 0x0000, + 0x0000, + 0x012a, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x014c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x016a, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* a-z */ + 0x0101, + 0x0000, + 0x0000, + 0x0000, + 0x0113, + 0x0000, + 0x0000, + 0x0000, + 0x012b, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x014d, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x016b, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000}, + /* 0xC6 */ + {/* A-Z */ + 0x0102, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x011e, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x016c, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* a-z */ + 0x0103, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x011f, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x016d, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000}, + /* 0xC7 */ + {/* A-Z */ + 0x0000, + 0x0000, + 0x010a, + 0x0000, + 0x0116, + 0x0000, + 0x0120, + 0x0000, + 0x0130, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x017b, + /* a-z */ + 0x0000, + 0x0000, + 0x010b, + 0x0000, + 0x0117, + 0x0000, + 0x0121, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x017c}, + /* 0xC8 */ + {/* A-Z */ + 0x00c4, + 0x0000, + 0x0000, + 0x0000, + 0x00cb, + 0x0000, + 0x0000, + 0x0000, + 0x00cf, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00d6, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00dc, + 0x0000, + 0x0000, + 0x0000, + 0x0178, + 0x0000, + /* a-z */ + 0x00e4, + 0x0000, + 0x0000, + 0x0000, + 0x00eb, + 0x0000, + 0x0000, + 0x0000, + 0x00ef, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00f6, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x00fc, + 0x0000, + 0x0000, + 0x0000, + 0x00ff, + 0x0000}, + /* 0xC9 */ + { + 0x0000, + }, + /* 0xCA */ + {/* A-Z */ + 0x00c5, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x016e, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* a-z */ + 0x00e5, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x016f, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000}, + /* 0xCB */ + {/* A-Z */ + 0x0000, + 0x0000, + 0x00c7, + 0x0000, + 0x0000, + 0x0000, + 0x0122, + 0x0000, + 0x0000, + 0x0000, + 0x0136, + 0x013b, + 0x0000, + 0x0145, + 0x0000, + 0x0000, + 0x0000, + 0x0156, + 0x015e, + 0x0162, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* a-z */ + 0x0000, + 0x0000, + 0x00e7, + 0x0000, + 0x0000, + 0x0000, + 0x0123, + 0x0000, + 0x0000, + 0x0000, + 0x0137, + 0x013c, + 0x0000, + 0x0146, + 0x0000, + 0x0000, + 0x0000, + 0x0157, + 0x015f, + 0x0163, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000}, + /* 0xCC */ + { + 0x0000, + }, + /* 0xCD */ + {/* A-Z */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0150, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0170, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* a-z */ + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0151, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0171, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000}, + /* 0xCE */ + {/* A-Z */ + 0x0104, + 0x0000, + 0x0000, + 0x0000, + 0x0118, + 0x0000, + 0x0000, + 0x0000, + 0x012e, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0172, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* a-z */ + 0x0105, + 0x0000, + 0x0000, + 0x0000, + 0x0119, + 0x0000, + 0x0000, + 0x0000, + 0x012f, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0173, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000}, + /* 0xCF */ + {/* A-Z */ + 0x0000, + 0x0000, + 0x010c, + 0x010e, + 0x011a, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x013d, + 0x0000, + 0x0147, + 0x0000, + 0x0000, + 0x0000, + 0x0158, + 0x0160, + 0x0164, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x017d, + /* a-z */ + 0x0000, + 0x0000, + 0x010d, + 0x010f, + 0x011b, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x013e, + 0x0000, + 0x0148, + 0x0000, + 0x0000, + 0x0000, + 0x0159, + 0x0161, + 0x0165, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x017e}}; #endif diff --git a/src/input/mpegts/dvb_psi.c b/src/input/mpegts/dvb_psi.c index 4e7f369cc..8ec6a5927 100644 --- a/src/input/mpegts/dvb_psi.c +++ b/src/input/mpegts/dvb_psi.c @@ -39,114 +39,92 @@ #define PRIV_FSAT (('F' << 24) | ('S' << 16) | ('A' << 8) | 'T') -#define DVB_FASTSCAN_MUXES (8192/UUID_HEX_SIZE) +#define DVB_FASTSCAN_MUXES (8192 / UUID_HEX_SIZE) typedef struct dvb_freesat_svc { TAILQ_ENTRY(dvb_freesat_svc) link; TAILQ_ENTRY(dvb_freesat_svc) region_link; - uint16_t sid; - uint16_t regionid; - uint16_t lcn; - mpegts_service_t *svc; + uint16_t sid; + uint16_t regionid; + uint16_t lcn; + mpegts_service_t* svc; } dvb_freesat_svc_t; typedef struct dvb_freesat_region { LIST_ENTRY(dvb_freesat_region) link; - TAILQ_HEAD(,dvb_freesat_svc) services; - uint16_t regionid; - char name[52]; - bouquet_t *bouquet; + TAILQ_HEAD(, dvb_freesat_svc) services; + uint16_t regionid; + char name[52]; + bouquet_t* bouquet; } dvb_freesat_region_t; typedef struct dvb_bat_svc { TAILQ_ENTRY(dvb_bat_svc) link; - mpegts_service_t *svc; - uint8_t lcn_dtag; - uint32_t lcn; - dvb_freesat_svc_t *fallback; - int used; + mpegts_service_t* svc; + uint8_t lcn_dtag; + uint32_t lcn; + dvb_freesat_svc_t* fallback; + int used; } dvb_bat_svc_t; typedef struct dvb_bat_id { LIST_ENTRY(dvb_bat_id) link; - uint32_t complete:1; - uint32_t freesat:1; - uint32_t bskyb:1; - uint16_t nbid; - char name[32]; - mpegts_mux_t *mm; - TAILQ_HEAD(,dvb_bat_svc) services; - TAILQ_HEAD(,dvb_freesat_svc) fservices; - LIST_HEAD(,dvb_freesat_region) fregions; + uint32_t complete : 1; + uint32_t freesat : 1; + uint32_t bskyb : 1; + uint16_t nbid; + char name[32]; + mpegts_mux_t* mm; + TAILQ_HEAD(, dvb_bat_svc) services; + TAILQ_HEAD(, dvb_freesat_svc) fservices; + LIST_HEAD(, dvb_freesat_region) fregions; } dvb_bat_id_t; typedef struct dvb_bat { int complete; - LIST_HEAD(,dvb_bat_id) bats; + LIST_HEAD(, dvb_bat_id) bats; } dvb_bat_t; int dvb_bouquets_parse = 1; - -static inline uint16_t -extract_2byte(const uint8_t *ptr) -{ +static inline uint16_t extract_2byte(const uint8_t* ptr) { return (((uint16_t)ptr[0]) << 8) | ptr[1]; } - -static inline uint32_t -extract_4byte(const uint8_t *ptr) -{ - return (((uint32_t)ptr[0]) << 24) | (((uint32_t)ptr[1]) << 16) | - (((uint32_t)ptr[2]) << 8) | ptr[3]; +static inline uint32_t extract_4byte(const uint8_t* ptr) { + return (((uint32_t)ptr[0]) << 24) | (((uint32_t)ptr[1]) << 16) | (((uint32_t)ptr[2]) << 8) | + ptr[3]; } - -static inline uint16_t -extract_tsid(const uint8_t *ptr) -{ +static inline uint16_t extract_tsid(const uint8_t* ptr) { return (ptr[0] << 8) | ptr[1]; } - -static inline uint16_t -extract_onid(const uint8_t *ptr) -{ +static inline uint16_t extract_onid(const uint8_t* ptr) { return (ptr[0] << 8) | ptr[1]; } - -static inline uint16_t -extract_pid(const uint8_t *ptr) -{ +static inline uint16_t extract_pid(const uint8_t* ptr) { return ((ptr[0] & 0x1f) << 8) | ptr[1]; } - -static inline uint16_t -extract_svcid(const uint8_t *ptr) -{ +static inline uint16_t extract_svcid(const uint8_t* ptr) { return (ptr[0] << 8) | ptr[1]; } - -static inline int -mpegts_mux_alive(mpegts_mux_t *mm) -{ +static inline int mpegts_mux_alive(mpegts_mux_t* mm) { /* * Return, if mux seems to be alive for updating. */ - if (mm->mm_enabled != MM_ENABLE) return 0; + if (mm->mm_enabled != MM_ENABLE) + return 0; return !LIST_EMPTY(&mm->mm_services) && mm->mm_scan_result != MM_SCAN_FAIL; } -static uint32_t -dvb_priv_lookup(mpegts_table_t *mt, const uint8_t *lptr, int llen) -{ - uint32_t priv = 0; - uint8_t dtag; - int dllen, dlen; +static uint32_t dvb_priv_lookup(mpegts_table_t* mt, const uint8_t* lptr, int llen) { + uint32_t priv = 0; + uint8_t dtag; + int dllen, dlen; const uint8_t *dlptr, *dptr; DVB_DESC_FOREACH(mt, lptr, llen, 4, dlptr, dllen, dtag, dlen, dptr) { @@ -157,17 +135,18 @@ dvb_priv_lookup(mpegts_table_t *mt, const uint8_t *lptr, int llen) break; } } - }} -dvberr: - return priv; + } +} +dvberr: return priv; } -static int -mpegts_mux_tsid_check(mpegts_mux_t *mm, mpegts_table_t *mt, uint16_t tsid) -{ +static int mpegts_mux_tsid_check(mpegts_mux_t* mm, mpegts_table_t* mt, uint16_t tsid) { if (tsid == 0 && !mm->mm_tsid_accept_zero_value) { if (tvhlog_limit(&mm->mm_tsid_loglimit, 2)) { - tvhwarn(mt->mt_subsys, "%s: %s: TSID zero value detected, ignoring", mt->mt_name, mm->mm_nicename); + tvhwarn(mt->mt_subsys, + "%s: %s: TSID zero value detected, ignoring", + mt->mt_name, + mm->mm_nicename); } return 1; } @@ -175,12 +154,25 @@ mpegts_mux_tsid_check(mpegts_mux_t *mm, mpegts_table_t *mt, uint16_t tsid) if (mm->mm_tsid != MPEGTS_TSID_NONE) { if (mm->mm_tsid && mm->mm_tsid != tsid) { if (++mm->mm_tsid_checks > 12) { - tvhwarn(mt->mt_subsys, "%s: %s: TSID change detected - old %04x (%d), new %04x (%d)", - mt->mt_name, mm->mm_nicename, mm->mm_tsid, mm->mm_tsid, tsid, tsid); + tvhwarn(mt->mt_subsys, + "%s: %s: TSID change detected - old %04x (%d), new %04x (%d)", + mt->mt_name, + mm->mm_nicename, + mm->mm_tsid, + mm->mm_tsid, + tsid, + tsid); } else { if (tvhtrace_enabled()) { - tvhtrace(mt->mt_subsys, "%s: %s: ignore TSID - old %04x (%d), new %04x (%d) (checks %d)", - mt->mt_name, mm->mm_nicename, mm->mm_tsid, mm->mm_tsid, tsid, tsid, mm->mm_tsid_checks); + tvhtrace(mt->mt_subsys, + "%s: %s: ignore TSID - old %04x (%d), new %04x (%d) (checks %d)", + mt->mt_name, + mm->mm_nicename, + mm->mm_tsid, + mm->mm_tsid, + tsid, + tsid, + mm->mm_tsid_checks); } return -1; /* keep rolling */ } @@ -191,21 +183,17 @@ mpegts_mux_tsid_check(mpegts_mux_t *mm, mpegts_table_t *mt, uint16_t tsid) return 0; } -static void -dvb_bouquet_comment ( bouquet_t *bq, mpegts_mux_t *mm ) -{ +static void dvb_bouquet_comment(bouquet_t* bq, mpegts_mux_t* mm) { if (bq->bq_comment && bq->bq_comment[0]) return; bouquet_change_comment(bq, mm->mm_nicename, 0); } #if ENABLE_MPEGTS_DVB -static mpegts_mux_t * -dvb_fs_mux_find ( mpegts_mux_t *mm, uint16_t onid, uint16_t tsid ) -{ - mpegts_mux_t *mux; - char *s; - int i; +static mpegts_mux_t* dvb_fs_mux_find(mpegts_mux_t* mm, uint16_t onid, uint16_t tsid) { + mpegts_mux_t* mux; + char* s; + int i; if (mm->mm_fastscan_muxes == NULL) return NULL; @@ -220,13 +208,11 @@ dvb_fs_mux_find ( mpegts_mux_t *mm, uint16_t onid, uint16_t tsid ) return NULL; } -static void -dvb_fs_mux_add ( mpegts_table_t *mt, mpegts_mux_t *mm, mpegts_mux_t *mux ) -{ - const char *uuid; - char ubuf[UUID_HEX_SIZE]; - char *s; - int i; +static void dvb_fs_mux_add(mpegts_table_t* mt, mpegts_mux_t* mm, mpegts_mux_t* mux) { + const char* uuid; + char ubuf[UUID_HEX_SIZE]; + char* s; + int i; uuid = idnode_uuid_as_str(&mux->mm_id, ubuf); if (mm->mm_fastscan_muxes == NULL) @@ -258,30 +244,43 @@ dvb_fs_mux_add ( mpegts_table_t *mt, mpegts_mux_t *mm, mpegts_mux_t *mux ) /** * Tables for delivery descriptor parsing */ -static const dvb_fe_code_rate_t fec_tab [16] = { - DVB_FEC_AUTO, DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, - DVB_FEC_5_6, DVB_FEC_7_8, DVB_FEC_8_9, DVB_FEC_3_5, - DVB_FEC_4_5, DVB_FEC_9_10, DVB_FEC_NONE, DVB_FEC_NONE, - DVB_FEC_NONE, DVB_FEC_NONE, DVB_FEC_NONE, DVB_FEC_NONE -}; +static const dvb_fe_code_rate_t fec_tab[16] = {DVB_FEC_AUTO, + DVB_FEC_1_2, + DVB_FEC_2_3, + DVB_FEC_3_4, + DVB_FEC_5_6, + DVB_FEC_7_8, + DVB_FEC_8_9, + DVB_FEC_3_5, + DVB_FEC_4_5, + DVB_FEC_9_10, + DVB_FEC_NONE, + DVB_FEC_NONE, + DVB_FEC_NONE, + DVB_FEC_NONE, + DVB_FEC_NONE, + DVB_FEC_NONE}; /* * Satellite delivery descriptor */ -static mpegts_mux_t * -dvb_desc_sat_del - (mpegts_table_t *mt, mpegts_mux_t *mm, - uint16_t onid, uint16_t tsid, - const uint8_t *ptr, int len, int force) -{ - int frequency, symrate, polarisation, orbitalpos; +static mpegts_mux_t* dvb_desc_sat_del(mpegts_table_t* mt, + mpegts_mux_t* mm, + uint16_t onid, + uint16_t tsid, + const uint8_t* ptr, + int len, + int force) { + int frequency, symrate, polarisation, orbitalpos; dvb_mux_conf_t dmc; - char buf[128]; + char buf[128]; /* Not enough data */ - if(len < 11) return NULL; + if (len < 11) + return NULL; - if(!idnode_is_instance(&mm->mm_id, &dvb_mux_dvbs_class)) return NULL; + if (!idnode_is_instance(&mm->mm_id, &dvb_mux_dvbs_class)) + return NULL; /* Extract data */ frequency = bcdtoint4(ptr); @@ -299,28 +298,26 @@ dvb_desc_sat_del symrate *= 1000; orbitalpos = bcdtoint(ptr[4]) * 100 + bcdtoint(ptr[5]); - if ((ptr[6] & 0x80) == 0) orbitalpos *= -1; + if ((ptr[6] & 0x80) == 0) + orbitalpos *= -1; if (orbitalpos == 0) - orbitalpos = ((dvb_mux_t *)mm)->lm_tuning.u.dmc_fe_qpsk.orbital_pos; + orbitalpos = ((dvb_mux_t*)mm)->lm_tuning.u.dmc_fe_qpsk.orbital_pos; polarisation = (ptr[6] >> 5) & 0x03; - dvb_mux_conf_init((mpegts_network_t *)mm->mm_network, &dmc, - (ptr[6] & 0x4) ? DVB_SYS_DVBS2 : DVB_SYS_DVBS); + dvb_mux_conf_init((mpegts_network_t*)mm->mm_network, + &dmc, + (ptr[6] & 0x4) ? DVB_SYS_DVBS2 : DVB_SYS_DVBS); dmc.dmc_fe_freq = frequency * 10; dmc.u.dmc_fe_qpsk.orbital_pos = orbitalpos; dmc.u.dmc_fe_qpsk.polarisation = polarisation; - dmc.u.dmc_fe_qpsk.symbol_rate = symrate * 100; - dmc.u.dmc_fe_qpsk.fec_inner = fec_tab[ptr[10] & 0x0f]; + dmc.u.dmc_fe_qpsk.symbol_rate = symrate * 100; + dmc.u.dmc_fe_qpsk.fec_inner = fec_tab[ptr[10] & 0x0f]; - static int mtab[4] = { - DVB_MOD_NONE, DVB_MOD_QPSK, DVB_MOD_PSK_8, DVB_MOD_QAM_16 - }; - static int rtab[4] = { - DVB_ROLLOFF_35, DVB_ROLLOFF_25, DVB_ROLLOFF_20, DVB_ROLLOFF_AUTO - }; + static int mtab[4] = {DVB_MOD_NONE, DVB_MOD_QPSK, DVB_MOD_PSK_8, DVB_MOD_QAM_16}; + static int rtab[4] = {DVB_ROLLOFF_35, DVB_ROLLOFF_25, DVB_ROLLOFF_20, DVB_ROLLOFF_AUTO}; dmc.dmc_fe_modulation = mtab[ptr[6] & 0x3]; #if 0 if (dmc.dmc_fe_modulation != DVB_MOD_NONE && @@ -329,9 +326,8 @@ dvb_desc_sat_del /* on 13.0E, there are (ptr[6] & 4) == 0 muxes with 8PSK and DVB-S2 */ dmc.dmc_fe_delsys = DVB_SYS_DVBS2; #endif - dmc.dmc_fe_rolloff = rtab[(ptr[6] >> 3) & 0x3]; - if (dmc.dmc_fe_delsys == DVB_SYS_DVBS && - dmc.dmc_fe_rolloff != DVB_ROLLOFF_35) { + dmc.dmc_fe_rolloff = rtab[(ptr[6] >> 3) & 0x3]; + if (dmc.dmc_fe_delsys == DVB_SYS_DVBS && dmc.dmc_fe_rolloff != DVB_ROLLOFF_35) { tvhtrace(mt->mt_subsys, "%s: dvb-s rolloff error", mt->mt_name); return NULL; } @@ -347,31 +343,43 @@ dvb_desc_sat_del /* * Cable delivery descriptor */ -static mpegts_mux_t * -dvb_desc_cable_del - (mpegts_table_t *mt, mpegts_mux_t *mm, - uint16_t onid, uint16_t tsid, - const uint8_t *ptr, int len) -{ - int frequency, symrate; +static mpegts_mux_t* dvb_desc_cable_del(mpegts_table_t* mt, + mpegts_mux_t* mm, + uint16_t onid, + uint16_t tsid, + const uint8_t* ptr, + int len) { + int frequency, symrate; dvb_mux_conf_t dmc; - char buf[128]; - - static const dvb_fe_modulation_t qtab [16] = { - DVB_MOD_QAM_AUTO, DVB_MOD_QAM_16, DVB_MOD_QAM_32, DVB_MOD_QAM_64, - DVB_MOD_QAM_128, DVB_MOD_QAM_256, DVB_MOD_QAM_AUTO, DVB_MOD_QAM_AUTO, - DVB_MOD_QAM_AUTO, DVB_MOD_QAM_AUTO, DVB_MOD_QAM_AUTO, DVB_MOD_QAM_AUTO, - DVB_MOD_QAM_AUTO, DVB_MOD_QAM_AUTO, DVB_MOD_QAM_AUTO, DVB_MOD_QAM_AUTO - }; + char buf[128]; + + static const dvb_fe_modulation_t qtab[16] = {DVB_MOD_QAM_AUTO, + DVB_MOD_QAM_16, + DVB_MOD_QAM_32, + DVB_MOD_QAM_64, + DVB_MOD_QAM_128, + DVB_MOD_QAM_256, + DVB_MOD_QAM_AUTO, + DVB_MOD_QAM_AUTO, + DVB_MOD_QAM_AUTO, + DVB_MOD_QAM_AUTO, + DVB_MOD_QAM_AUTO, + DVB_MOD_QAM_AUTO, + DVB_MOD_QAM_AUTO, + DVB_MOD_QAM_AUTO, + DVB_MOD_QAM_AUTO, + DVB_MOD_QAM_AUTO}; /* Not enough data */ - if(len < 11) return NULL; + if (len < 11) + return NULL; - if(!idnode_is_instance(&mm->mm_id, &dvb_mux_dvbc_class)) return NULL; + if (!idnode_is_instance(&mm->mm_id, &dvb_mux_dvbc_class)) + return NULL; /* Extract data */ - frequency = bcdtoint4(ptr); - symrate = bcdtoint41(ptr + 7); + frequency = bcdtoint4(ptr); + symrate = bcdtoint41(ptr + 7); if (!frequency) { tvhtrace(mt->mt_subsys, "%s: dvb-c frequency error", mt->mt_name); return NULL; @@ -381,13 +389,14 @@ dvb_desc_cable_del return NULL; } - dvb_mux_conf_init((mpegts_network_t *)mm->mm_network, &dmc, - ((dvb_mux_t *)mm)->lm_tuning.dmc_fe_delsys); + dvb_mux_conf_init((mpegts_network_t*)mm->mm_network, + &dmc, + ((dvb_mux_t*)mm)->lm_tuning.dmc_fe_delsys); - dmc.dmc_fe_freq = frequency * 100; - dmc.u.dmc_fe_qam.symbol_rate = symrate * 100; - dmc.dmc_fe_modulation = qtab[ptr[6] & 0x0f]; - dmc.u.dmc_fe_qam.fec_inner = fec_tab[ptr[10] & 0x07]; + dmc.dmc_fe_freq = frequency * 100; + dmc.u.dmc_fe_qam.symbol_rate = symrate * 100; + dmc.dmc_fe_modulation = qtab[ptr[6] & 0x0f]; + dmc.u.dmc_fe_qam.fec_inner = fec_tab[ptr[10] & 0x07]; /* Debug */ dvb_mux_conf_str(&dmc, buf, sizeof(buf)); @@ -400,53 +409,60 @@ dvb_desc_cable_del /* * Terrestrial delivery descriptor */ -static mpegts_mux_t * -dvb_desc_terr_del - (mpegts_table_t *mt, mpegts_mux_t *mm, - uint16_t onid, uint16_t tsid, - const uint8_t *ptr, int len) -{ - static const dvb_fe_bandwidth_t btab [8] = { - DVB_BANDWIDTH_8_MHZ, DVB_BANDWIDTH_7_MHZ, - DVB_BANDWIDTH_6_MHZ, DVB_BANDWIDTH_AUTO, - DVB_BANDWIDTH_AUTO, DVB_BANDWIDTH_AUTO, - DVB_BANDWIDTH_AUTO, DVB_BANDWIDTH_AUTO - }; - static const dvb_fe_modulation_t ctab [4] = { - DVB_MOD_QPSK, DVB_MOD_QAM_16, DVB_MOD_QAM_64, DVB_MOD_QAM_AUTO - }; - static const dvb_fe_guard_interval_t gtab [4] = { - DVB_GUARD_INTERVAL_1_32, DVB_GUARD_INTERVAL_1_16, - DVB_GUARD_INTERVAL_1_8, DVB_GUARD_INTERVAL_1_4 - }; - static const dvb_fe_transmit_mode_t ttab [4] = { - DVB_TRANSMISSION_MODE_2K, - DVB_TRANSMISSION_MODE_8K, - DVB_TRANSMISSION_MODE_4K, - DVB_TRANSMISSION_MODE_AUTO - }; - static const dvb_fe_hierarchy_t htab [8] = { - DVB_HIERARCHY_NONE, DVB_HIERARCHY_1, DVB_HIERARCHY_2, DVB_HIERARCHY_4, - DVB_HIERARCHY_NONE, DVB_HIERARCHY_1, DVB_HIERARCHY_2, DVB_HIERARCHY_4 - }; - - int frequency; +static mpegts_mux_t* dvb_desc_terr_del(mpegts_table_t* mt, + mpegts_mux_t* mm, + uint16_t onid, + uint16_t tsid, + const uint8_t* ptr, + int len) { + static const dvb_fe_bandwidth_t btab[8] = {DVB_BANDWIDTH_8_MHZ, + DVB_BANDWIDTH_7_MHZ, + DVB_BANDWIDTH_6_MHZ, + DVB_BANDWIDTH_AUTO, + DVB_BANDWIDTH_AUTO, + DVB_BANDWIDTH_AUTO, + DVB_BANDWIDTH_AUTO, + DVB_BANDWIDTH_AUTO}; + static const dvb_fe_modulation_t ctab[4] = {DVB_MOD_QPSK, + DVB_MOD_QAM_16, + DVB_MOD_QAM_64, + DVB_MOD_QAM_AUTO}; + static const dvb_fe_guard_interval_t gtab[4] = {DVB_GUARD_INTERVAL_1_32, + DVB_GUARD_INTERVAL_1_16, + DVB_GUARD_INTERVAL_1_8, + DVB_GUARD_INTERVAL_1_4}; + static const dvb_fe_transmit_mode_t ttab[4] = {DVB_TRANSMISSION_MODE_2K, + DVB_TRANSMISSION_MODE_8K, + DVB_TRANSMISSION_MODE_4K, + DVB_TRANSMISSION_MODE_AUTO}; + static const dvb_fe_hierarchy_t htab[8] = {DVB_HIERARCHY_NONE, + DVB_HIERARCHY_1, + DVB_HIERARCHY_2, + DVB_HIERARCHY_4, + DVB_HIERARCHY_NONE, + DVB_HIERARCHY_1, + DVB_HIERARCHY_2, + DVB_HIERARCHY_4}; + + int frequency; dvb_mux_conf_t dmc; - char buf[128]; + char buf[128]; /* Not enough data */ - if (len < 11) return NULL; + if (len < 11) + return NULL; - if(!idnode_is_instance(&mm->mm_id, &dvb_mux_dvbt_class)) return NULL; + if (!idnode_is_instance(&mm->mm_id, &dvb_mux_dvbt_class)) + return NULL; /* Extract data */ - frequency = extract_4byte(ptr); + frequency = extract_4byte(ptr); if (frequency < 50000000 || frequency > 1000000000) { tvhtrace(mt->mt_subsys, "%s: dvb-t frequency error (%d)", mt->mt_name, frequency); return NULL; } - dvb_mux_conf_init((mpegts_network_t *)mm->mm_network, &dmc, DVB_SYS_DVBT); + dvb_mux_conf_init((mpegts_network_t*)mm->mm_network, &dmc, DVB_SYS_DVBT); dmc.dmc_fe_freq = frequency * 10; dmc.u.dmc_fe_ofdm.bandwidth = btab[(ptr[4] >> 5) & 0x7]; @@ -454,14 +470,14 @@ dvb_desc_terr_del dmc.u.dmc_fe_ofdm.hierarchy_information = htab[(ptr[5] >> 3) & 0x3]; dmc.u.dmc_fe_ofdm.code_rate_HP = fec_tab[(ptr[5] + 1) & 0x7]; if (dmc.u.dmc_fe_ofdm.hierarchy_information != DVB_HIERARCHY_NONE) - dmc.u.dmc_fe_ofdm.code_rate_LP = fec_tab[((ptr[6] + 1) >> 5) & 0x7]; - dmc.u.dmc_fe_ofdm.guard_interval = gtab[(ptr[6] >> 3) & 0x3]; - dmc.u.dmc_fe_ofdm.transmission_mode = ttab[(ptr[6] >> 1) & 0x3]; + dmc.u.dmc_fe_ofdm.code_rate_LP = fec_tab[((ptr[6] + 1) >> 5) & 0x7]; + dmc.u.dmc_fe_ofdm.guard_interval = gtab[(ptr[6] >> 3) & 0x3]; + dmc.u.dmc_fe_ofdm.transmission_mode = ttab[(ptr[6] >> 1) & 0x3]; /* Debug */ dvb_mux_conf_str(&dmc, buf, sizeof(buf)); tvhdebug(mt->mt_subsys, "%s: %s", mt->mt_name, buf); - + /* Create */ return mm->mm_network->mn_create_mux(mm->mm_network, mm, onid, tsid, &dmc, 0); } @@ -469,13 +485,10 @@ dvb_desc_terr_del /* * Frequency list delivery descriptor */ -static void -dvb_desc_freq_list - (mpegts_table_t *mt, mpegts_mux_t *mm, const uint8_t *ptr, int len) -{ - static const char *clat[4] = { "unknown", "sat", "cable", "terr" }; - int i, j, ctype; - uint32_t frequency; +static void dvb_desc_freq_list(mpegts_table_t* mt, mpegts_mux_t* mm, const uint8_t* ptr, int len) { + static const char* clat[4] = {"unknown", "sat", "cable", "terr"}; + int i, j, ctype; + uint32_t frequency; if (len < 8) return; ctype = ptr[0] & 0x03; @@ -483,36 +496,43 @@ dvb_desc_freq_list len--; for (i = j = 0; len > 3; i++, ptr += 4, len -= 4) { switch (ctype) { - case 1: /* satellite */ - frequency = 10 * bcdtoint4(ptr); - break; - case 2: /* cable */ - frequency = 100 * bcdtoint4(ptr); - break; - case 3: /* terresterial */ - frequency = 10 * extract_4byte(ptr); - break; - default: - frequency = 0; - break; + case 1: /* satellite */ + frequency = 10 * bcdtoint4(ptr); + break; + case 2: /* cable */ + frequency = 100 * bcdtoint4(ptr); + break; + case 3: /* terresterial */ + frequency = 10 * extract_4byte(ptr); + break; + default: + frequency = 0; + break; } if (frequency == 0) continue; - tvhtrace(mt->mt_subsys, "%s: %s center freq %d: %u", mt->mt_name, clat[ctype], i, frequency); + tvhtrace(mt->mt_subsys, + "%s: %s center freq %d: %u", + mt->mt_name, + clat[ctype], + i, + frequency); } } - + #endif /* ENABLE_MPEGTS_DVB */ -static int -dvb_desc_service - ( const uint8_t *ptr, int len, int *stype, - char *sprov, size_t sprov_len, - char *sname, size_t sname_len, const char *charset ) -{ - int r; +static int dvb_desc_service(const uint8_t* ptr, + int len, + int* stype, + char* sprov, + size_t sprov_len, + char* sname, + size_t sname_len, + const char* charset) { + int r; size_t l; - char *str; + char* str; if (len < 2) return -1; @@ -525,7 +545,7 @@ dvb_desc_service return -1; /* Name */ - if (dvb_get_string_with_len(sname, sname_len, ptr+r, len-r, charset, NULL) < 0) + if (dvb_get_string_with_len(sname, sname_len, ptr + r, len - r, charset, NULL) < 0) return -1; /* Cleanup name */ @@ -535,51 +555,55 @@ dvb_desc_service if (str != sname) memmove(sname, str, sname_len - (str - sname)); l = strlen(str); - while (l > 1 && str[l-1] <= ' ') + while (l > 1 && str[l - 1] <= ' ') str[--l] = '\0'; return 0; } -static dvb_bat_svc_t * -dvb_bat_find_service( dvb_bat_id_t *bi, mpegts_service_t *s, - uint8_t lcn_dtag, uint32_t lcn ) -{ - dvb_bat_svc_t *bs; +static dvb_bat_svc_t* +dvb_bat_find_service(dvb_bat_id_t* bi, mpegts_service_t* s, uint8_t lcn_dtag, uint32_t lcn) { + dvb_bat_svc_t* bs; assert(bi); - TAILQ_FOREACH(bs, &bi->services, link) + TAILQ_FOREACH (bs, &bi->services, link) if (bs->svc == s) break; if (!bs) { - bs = calloc(1, sizeof(*bs)); + bs = calloc(1, sizeof(*bs)); bs->svc = s; - service_ref((service_t *)s); + service_ref((service_t*)s); TAILQ_INSERT_TAIL(&bi->services, bs, link); } if (lcn != UINT_MAX && !bs->lcn_dtag) { bs->lcn_dtag = lcn_dtag; - bs->lcn = lcn; + bs->lcn = lcn; } return bs; } -static int -dvb_desc_service_list - ( mpegts_table_t *mt, const uint8_t *ptr, int len, mpegts_mux_t *mm, - dvb_bat_id_t *bi ) -{ - uint16_t stype, sid; - mpegts_service_t *s; - int i; +static int dvb_desc_service_list(mpegts_table_t* mt, + const uint8_t* ptr, + int len, + mpegts_mux_t* mm, + dvb_bat_id_t* bi) { + uint16_t stype, sid; + mpegts_service_t* s; + int i; for (i = 0; i < len; i += 3) { sid = extract_svcid(ptr + i); - stype = ptr[i+2]; - tvhdebug(mt->mt_subsys, "%s: service %04X (%d) type %02X (%d)", mt->mt_name, sid, sid, stype, stype); + stype = ptr[i + 2]; + tvhdebug(mt->mt_subsys, + "%s: service %04X (%d) type %02X (%d)", + mt->mt_name, + sid, + sid, + stype, + stype); if (mm) { int save = 0; - s = mpegts_service_find(mm, sid, 0, 1, &save); + s = mpegts_service_find(mm, sid, 0, 1, &save); if (bi) dvb_bat_find_service(bi, s, 0, UINT_MAX); if (save) @@ -589,19 +613,22 @@ dvb_desc_service_list return 0; } -static int -dvb_desc_local_channel - ( mpegts_table_t *mt, mpegts_network_t *mn, const uint8_t *ptr, int len, - uint8_t dtag, mpegts_mux_t *mm, dvb_bat_id_t *bi, int prefer ) -{ - int save = 0; - uint16_t sid, lcn; - mpegts_service_t *s; +static int dvb_desc_local_channel(mpegts_table_t* mt, + mpegts_network_t* mn, + const uint8_t* ptr, + int len, + uint8_t dtag, + mpegts_mux_t* mm, + dvb_bat_id_t* bi, + int prefer) { + int save = 0; + uint16_t sid, lcn; + mpegts_service_t* s; if ((len % 4) != 0) return 0; - while(len >= 4) { + while (len >= 4) { sid = extract_svcid(ptr); lcn = extract_2byte(ptr + 2) & 0x3ff; tvhdebug(mt->mt_subsys, "%s: sid %d lcn %d", mt->mt_name, sid, lcn); @@ -610,11 +637,10 @@ dvb_desc_local_channel if (s) { if (bi) { dvb_bat_find_service(bi, s, dtag, lcn); - } else if ((!s->s_dvb_channel_dtag || - s->s_dvb_channel_dtag == dtag || prefer) && - s->s_dvb_channel_num != lcn) { + } else if ((!s->s_dvb_channel_dtag || s->s_dvb_channel_dtag == dtag || prefer) && + s->s_dvb_channel_num != lcn) { s->s_dvb_channel_dtag = dtag; - s->s_dvb_channel_num = lcn; + s->s_dvb_channel_num = lcn; mpegts_network_bouquet_trigger(mn, 0); idnode_changed(&s->s_id); service_refresh_channel((service_t*)s); @@ -634,36 +660,40 @@ dvb_desc_local_channel */ static void -dvb_freesat_local_channels - ( dvb_bat_id_t *bi, mpegts_table_t *mt, const uint8_t *ptr, int len ) -{ - uint16_t sid, lcn, regionid; - uint16_t unk; - dvb_freesat_svc_t *fs; - int len2; +dvb_freesat_local_channels(dvb_bat_id_t* bi, mpegts_table_t* mt, const uint8_t* ptr, int len) { + uint16_t sid, lcn, regionid; + uint16_t unk; + dvb_freesat_svc_t* fs; + int len2; while (len > 4) { - sid = extract_svcid(ptr); - unk = extract_2byte(ptr + 2); + sid = extract_svcid(ptr); + unk = extract_2byte(ptr + 2); len2 = ptr[4]; ptr += 5; len -= 5; if (len2 > len) break; - tvhtrace(mt->mt_subsys, "%s: sid %04X (%d) uknown %04X (%d)", mt->mt_name, sid, sid, unk, unk); + tvhtrace(mt->mt_subsys, + "%s: sid %04X (%d) uknown %04X (%d)", + mt->mt_name, + sid, + sid, + unk, + unk); while (len2 > 3) { - lcn = extract_2byte(ptr) & 0xfff; + lcn = extract_2byte(ptr) & 0xfff; regionid = extract_2byte(ptr + 2); tvhtrace(mt->mt_subsys, "%s: lcn %d region %d", mt->mt_name, lcn, regionid); - - TAILQ_FOREACH(fs, &bi->fservices, link) + + TAILQ_FOREACH (fs, &bi->fservices, link) if (fs->sid == sid && fs->regionid == regionid) break; if (!fs) { - fs = calloc(1, sizeof(*fs)); - fs->sid = sid; + fs = calloc(1, sizeof(*fs)); + fs->sid = sid; fs->regionid = regionid; - fs->lcn = lcn; + fs->lcn = lcn; TAILQ_INSERT_TAIL(&bi->fservices, fs, link); } @@ -674,14 +704,11 @@ dvb_freesat_local_channels } } -static void -dvb_freesat_regions - ( dvb_bat_id_t *bi, mpegts_table_t *mt, const uint8_t *ptr, int len ) -{ - uint16_t id; - char name[32]; - dvb_freesat_region_t *fr; - int r; +static void dvb_freesat_regions(dvb_bat_id_t* bi, mpegts_table_t* mt, const uint8_t* ptr, int len) { + uint16_t id; + char name[32]; + dvb_freesat_region_t* fr; + int r; if (!bi) return; @@ -693,11 +720,11 @@ dvb_freesat_regions break; tvhtrace(mt->mt_subsys, "%s: region %u - '%s'", mt->mt_name, id, name); - LIST_FOREACH(fr, &bi->fregions, link) + LIST_FOREACH (fr, &bi->fregions, link) if (fr->regionid == id) break; if (!fr) { - fr = calloc(1, sizeof(*fr)); + fr = calloc(1, sizeof(*fr)); fr->regionid = id; strlcpy(fr->name, name, sizeof(fr->name)); TAILQ_INIT(&fr->services); @@ -709,43 +736,50 @@ dvb_freesat_regions } } -static int -dvb_freesat_add_service - ( dvb_bat_id_t *bi, dvb_freesat_region_t *fr, mpegts_service_t *s, uint32_t lcn ) -{ +static int dvb_freesat_add_service(dvb_bat_id_t* bi, + dvb_freesat_region_t* fr, + mpegts_service_t* s, + uint32_t lcn) { char name[96], src[126]; if (!fr->bouquet) { strcpy(name, "???"); if (idnode_is_instance(&bi->mm->mm_id, &dvb_mux_dvbs_class)) - dvb_sat_position_to_str(((dvb_mux_t *)bi->mm)->lm_tuning.u.dmc_fe_qpsk.orbital_pos, - name, sizeof(name)); - snprintf(src, sizeof(src), "dvb-%s://dvbs,%s,%04X,%u", - bi->freesat ? "freesat" : "bskyb", name, bi->nbid, fr->regionid); + dvb_sat_position_to_str(((dvb_mux_t*)bi->mm)->lm_tuning.u.dmc_fe_qpsk.orbital_pos, + name, + sizeof(name)); + snprintf(src, + sizeof(src), + "dvb-%s://dvbs,%s,%04X,%u", + bi->freesat ? "freesat" : "bskyb", + name, + bi->nbid, + fr->regionid); snprintf(name, sizeof(name), "%s: %s", bi->name, fr->name); fr->bouquet = bouquet_find_by_source(name, src, 1); } - bouquet_add_service(fr->bouquet, (service_t *)s, (int64_t)lcn * CHANNEL_SPLIT, NULL); + bouquet_add_service(fr->bouquet, (service_t*)s, (int64_t)lcn * CHANNEL_SPLIT, NULL); return fr->bouquet->bq_enabled; } -static void -dvb_freesat_completed - ( dvb_bat_t *b, dvb_bat_id_t *bi, mpegts_table_t *mt ) -{ - dvb_bat_svc_t *bs; - dvb_freesat_svc_t *fs; - dvb_freesat_region_t *fr; - uint16_t sid; - uint32_t total = 0, regions = 0, uregions = 0; - - tvhtrace(mt->mt_subsys, "%s: completed %s [%04X] bouquets '%s'", - mt->mt_name, bi->freesat ? "freesat" : "bskyb", bi->nbid, bi->name); +static void dvb_freesat_completed(dvb_bat_t* b, dvb_bat_id_t* bi, mpegts_table_t* mt) { + dvb_bat_svc_t* bs; + dvb_freesat_svc_t* fs; + dvb_freesat_region_t* fr; + uint16_t sid; + uint32_t total = 0, regions = 0, uregions = 0; + + tvhtrace(mt->mt_subsys, + "%s: completed %s [%04X] bouquets '%s'", + mt->mt_name, + bi->freesat ? "freesat" : "bskyb", + bi->nbid, + bi->name); /* Find all "fallback" services and region specific */ - TAILQ_FOREACH(bs, &bi->services, link) { + TAILQ_FOREACH (bs, &bi->services, link) { total++; sid = service_id16(bs->svc); - TAILQ_FOREACH(fs, &bi->fservices, link) + TAILQ_FOREACH (fs, &bi->fservices, link) if (fs->sid == sid) { fs->svc = bs->svc; if (fs->regionid == 0 || fs->regionid == 0xffff) { @@ -756,11 +790,14 @@ dvb_freesat_completed /* already assigned? skip it */ if (!TAILQ_SAFE_ENTRY(fs, region_link)) continue; - LIST_FOREACH(fr, &bi->fregions, link) + LIST_FOREACH (fr, &bi->fregions, link) if (fr->regionid == fs->regionid) break; if (!fr) { - tvhtrace(mt->mt_subsys, "%s: cannot find freesat region id %u", mt->mt_name, fs->regionid); + tvhtrace(mt->mt_subsys, + "%s: cannot find freesat region id %u", + mt->mt_name, + fs->regionid); continue; } TAILQ_INSERT_TAIL(&fr->services, fs, region_link); @@ -768,40 +805,52 @@ dvb_freesat_completed } /* create bouquets, one per region */ - LIST_FOREACH(fr, &bi->fregions, link) { + LIST_FOREACH (fr, &bi->fregions, link) { regions++; - if (TAILQ_EMPTY(&fr->services)) continue; + if (TAILQ_EMPTY(&fr->services)) + continue; uregions++; - TAILQ_FOREACH(fs, &fr->services, region_link) { - if (!dvb_freesat_add_service(bi, fr, fs->svc, fs->lcn)) break; - TAILQ_FOREACH(bs, &bi->services, link) + TAILQ_FOREACH (fs, &fr->services, region_link) { + if (!dvb_freesat_add_service(bi, fr, fs->svc, fs->lcn)) + break; + TAILQ_FOREACH (bs, &bi->services, link) if (bs->fallback && fs->lcn == bs->fallback->lcn) bs->used = 1; } - if (fs) continue; - TAILQ_FOREACH(bs, &bi->services, link) { + if (fs) + continue; + TAILQ_FOREACH (bs, &bi->services, link) { if (bs->used) { bs->used = 0; continue; } - TAILQ_FOREACH(fs, &fr->services, region_link) + TAILQ_FOREACH (fs, &fr->services, region_link) if (fs->svc == bs->svc) break; - if (fs) continue; + if (fs) + continue; if ((fs = bs->fallback) != NULL) { - if (!dvb_freesat_add_service(bi, fr, bs->svc, fs->lcn)) break; + if (!dvb_freesat_add_service(bi, fr, bs->svc, fs->lcn)) + break; } else { - if (!dvb_freesat_add_service(bi, fr, bs->svc, 0)) break; + if (!dvb_freesat_add_service(bi, fr, bs->svc, 0)) + break; } } } - tvhtrace(mt->mt_subsys, "%s: completed %s [%04X] bouquets '%s' total %u regions %u (%u)", - mt->mt_name, bi->freesat ? "freesat" : "bskyb", bi->nbid, bi->name, - total, regions, uregions); + tvhtrace(mt->mt_subsys, + "%s: completed %s [%04X] bouquets '%s' total %u regions %u (%u)", + mt->mt_name, + bi->freesat ? "freesat" : "bskyb", + bi->nbid, + bi->name, + total, + regions, + uregions); /* Remove all services associated to region, notify the completed status */ - LIST_FOREACH(fr, &bi->fregions, link) { + LIST_FOREACH (fr, &bi->fregions, link) { TAILQ_INIT(&fr->services); if (fr->bouquet) { dvb_bouquet_comment(fr->bouquet, bi->mm); @@ -811,12 +860,15 @@ dvb_freesat_completed } /* Clear all "fallback/default" services */ - TAILQ_FOREACH(bs, &bi->services, link) + TAILQ_FOREACH (bs, &bi->services, link) bs->fallback = NULL; - tvhtrace(mt->mt_subsys, "%s: completed %s [%04X] bouquets '%s' update finished", - mt->mt_name, bi->freesat ? "freesat" : "bskyb", bi->nbid, bi->name); - + tvhtrace(mt->mt_subsys, + "%s: completed %s [%04X] bouquets '%s' update finished", + mt->mt_name, + bi->freesat ? "freesat" : "bskyb", + bi->nbid, + bi->name); } /* @@ -824,68 +876,68 @@ dvb_freesat_completed */ static struct strtab bskyb_regions[] = { - { "Atherstone", 19 }, - { "Border England", 12 }, - { "Border Scotland", 36 }, - { "Brighton", 65 }, - { "Central Midlands", 3 }, - { "Channel Isles", 34 }, - { "Dundee", 39 }, - { "East Midlands", 20 }, - { "Essex", 2 }, - { "Gloucester", 24 }, - { "Grampian", 35 }, - { "Granada", 7 }, - { "Henley On Thames", 70 }, - { "HTV Wales", 43 }, - { "HTV West", 4 }, - { "HTV West / Thames Valley", 63 }, - { "Humber", 29 }, - { "London", 1 }, - { "London / Essex", 18 }, - { "London / Thames Valley", 66 }, - { "London Kent", 64 }, - { "Meridian East", 11 }, - { "Meridian North", 68 }, - { "Meridian South", 5 }, - { "Meridian South East", 10 }, - { "Merseyside", 45 }, - { "Norfolk", 21 }, - { "North East Midlands", 62 }, - { "North West Yorkshire", 8 }, - { "North Yorkshire", 26 }, - { "Northern Ireland", 33 }, - { "Oxford", 71 }, - { "Republic of Ireland", 50 }, - { "Ridge Hill", 41 }, - { "Scarborough", 61 }, - { "Scottish East", 37 }, - { "Scottish West", 38 }, - { "Sheffield", 60 }, - { "South Lakeland", 28 }, - { "South Yorkshire", 72 }, - { "Tees", 69 }, - { "Thames Valley", 9 }, - { "Tring", 27 }, - { "Tyne", 13 }, - { "West Anglia", 25 }, - { "West Dorset", 67 }, - { "Westcountry", 6 }, + {"Atherstone", 19}, + {"Border England", 12}, + {"Border Scotland", 36}, + {"Brighton", 65}, + {"Central Midlands", 3}, + {"Channel Isles", 34}, + {"Dundee", 39}, + {"East Midlands", 20}, + {"Essex", 2}, + {"Gloucester", 24}, + {"Grampian", 35}, + {"Granada", 7}, + {"Henley On Thames", 70}, + {"HTV Wales", 43}, + {"HTV West", 4}, + {"HTV West / Thames Valley", 63}, + {"Humber", 29}, + {"London", 1}, + {"London / Essex", 18}, + {"London / Thames Valley", 66}, + {"London Kent", 64}, + {"Meridian East", 11}, + {"Meridian North", 68}, + {"Meridian South", 5}, + {"Meridian South East", 10}, + {"Merseyside", 45}, + {"Norfolk", 21}, + {"North East Midlands", 62}, + {"North West Yorkshire", 8}, + {"North Yorkshire", 26}, + {"Northern Ireland", 33}, + {"Oxford", 71}, + {"Republic of Ireland", 50}, + {"Ridge Hill", 41}, + {"Scarborough", 61}, + {"Scottish East", 37}, + {"Scottish West", 38}, + {"Sheffield", 60}, + {"South Lakeland", 28}, + {"South Yorkshire", 72}, + {"Tees", 69}, + {"Thames Valley", 9}, + {"Tring", 27}, + {"Tyne", 13}, + {"West Anglia", 25}, + {"West Dorset", 67}, + {"Westcountry", 6}, }; -static void -dvb_bskyb_local_channels - ( dvb_bat_id_t *bi, mpegts_table_t *mt, - const uint8_t *ptr, int len, mpegts_mux_t *mm ) -{ - uint16_t sid, lcn, regionid; - uint16_t unk, stype; - dvb_freesat_region_t *fr; - dvb_freesat_svc_t *fs; - dvb_bat_svc_t *bs; - mpegts_service_t *s; - const char *str; - char buf[16]; +static void dvb_bskyb_local_channels(dvb_bat_id_t* bi, + mpegts_table_t* mt, + const uint8_t* ptr, + int len, + mpegts_mux_t* mm) { + uint16_t sid, lcn, regionid; + uint16_t unk, stype; + dvb_freesat_region_t* fr; + dvb_freesat_svc_t* fs; + dvb_bat_svc_t* bs; + mpegts_service_t* s; + const char* str; + char buf[16]; if (len < 2) return; @@ -906,54 +958,67 @@ dvb_bskyb_local_channels len -= 2; ptr += 2; - tvhtrace(mt->mt_subsys, "%s: region id %04X (%d) unknown %02X (%d)", - mt->mt_name, regionid, regionid, ptr[0], ptr[0]); + tvhtrace(mt->mt_subsys, + "%s: region id %04X (%d) unknown %02X (%d)", + mt->mt_name, + regionid, + regionid, + ptr[0], + ptr[0]); while (len > 8) { - sid = extract_svcid(ptr); - lcn = extract_2byte(ptr + 5); + sid = extract_svcid(ptr); + lcn = extract_2byte(ptr + 5); stype = ptr[2]; - unk = extract_2byte(ptr + 3); + unk = extract_2byte(ptr + 3); ptr += 9; len -= 9; - tvhtrace(mt->mt_subsys, "%s: sid %04X (%d) type %02X (%d) lcn %d unknown %04X (%d)", - mt->mt_name, sid, sid, stype, stype, lcn, unk, unk); - - TAILQ_FOREACH(fs, &bi->fservices, link) + tvhtrace(mt->mt_subsys, + "%s: sid %04X (%d) type %02X (%d) lcn %d unknown %04X (%d)", + mt->mt_name, + sid, + sid, + stype, + stype, + lcn, + unk, + unk); + + TAILQ_FOREACH (fs, &bi->fservices, link) if (fs->sid == sid && fs->regionid == regionid) break; if (!fs) { - fs = calloc(1, sizeof(*fs)); - fs->sid = sid; + fs = calloc(1, sizeof(*fs)); + fs->sid = sid; fs->regionid = regionid; - fs->lcn = lcn != 0xffff ? lcn : 0; + fs->lcn = lcn != 0xffff ? lcn : 0; TAILQ_INSERT_TAIL(&bi->fservices, fs, link); } - TAILQ_FOREACH(bs, &bi->services, link) + TAILQ_FOREACH (bs, &bi->services, link) if (service_id16(bs->svc) == sid) break; if (mm && !bs) { s = mpegts_service_find(mm, sid, 0, 0, NULL); if (s) { - bs = calloc(1, sizeof(*bs)); + bs = calloc(1, sizeof(*bs)); bs->svc = s; - service_ref((service_t *)s); + service_ref((service_t*)s); TAILQ_INSERT_TAIL(&bi->services, bs, link); } } if (regionid && regionid != 0xffff) { - LIST_FOREACH(fr, &bi->fregions, link) + LIST_FOREACH (fr, &bi->fregions, link) if (fr->regionid == regionid) break; if (!fr) { - fr = calloc(1, sizeof(*fr)); + fr = calloc(1, sizeof(*fr)); fr->regionid = regionid; /* Note: Poland provider on 13E uses also this bouquet format */ if (bi->nbid < 0x1000 || bi->nbid > 0x1010 || - (str = val2str(regionid, bskyb_regions)) == NULL) { + (str = val2str(regionid, bskyb_regions)) == NULL) { snprintf(buf, sizeof(buf), "Region %d", regionid); str = buf; } @@ -970,34 +1035,43 @@ dvb_bskyb_local_channels /* * PAT processing */ -int -dvb_pat_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int r, sect, last, ver; - uint16_t sid, pid, tsid; - uint16_t nit_pid = 0; - mpegts_mux_t *mm = mt->mt_mux; - mpegts_psi_table_state_t *st = NULL; - mpegts_service_t *s; +int dvb_pat_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int r, sect, last, ver; + uint16_t sid, pid, tsid; + uint16_t nit_pid = 0; + mpegts_mux_t* mm = mt->mt_mux; + mpegts_psi_table_state_t* st = NULL; + mpegts_service_t* s; /* Begin */ - if (tableid != 0) return -1; + if (tableid != 0) + return -1; tsid = extract_tsid(ptr); - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, - tableid, tsid, 5, &st, §, &last, &ver, - 3600); - if (r != 1) return r; + r = dvb_table_begin((mpegts_psi_table_t*)mt, + ptr, + len, + tableid, + tsid, + 5, + &st, + §, + &last, + &ver, + 3600); + if (r != 1) + return r; /* Multiplex */ r = mpegts_mux_tsid_check(mm, mt, tsid); - if (r < 0) return -1; - if (r > 0) goto end; - + if (r < 0) + return -1; + if (r > 0) + goto end; + /* Process each programme */ ptr += 5; len -= 5; - while(len >= 4) { + while (len >= 4) { sid = extract_svcid(ptr); pid = extract_pid(ptr + 2); @@ -1008,15 +1082,27 @@ dvb_pat_callback tvhdebug(mt->mt_subsys, "%s: nit on pid %04X (%d)", mt->mt_name, pid, pid); } - /* Service */ + /* Service */ } else if (pid) { - tvhdebug(mt->mt_subsys, "%s: sid %04X (%d) on pid %04X (%d)", mt->mt_name, sid, sid, pid, pid); + tvhdebug(mt->mt_subsys, + "%s: sid %04X (%d) on pid %04X (%d)", + mt->mt_name, + sid, + sid, + pid, + pid); int save = 0; if ((s = mpegts_service_find(mm, sid, pid, 1, &save))) { - mpegts_table_add(mm, DVB_PMT_BASE, DVB_PMT_MASK, dvb_pmt_callback, - NULL, "pmt", LS_TBL_BASE, - MT_CRC | MT_QUICKREQ | MT_ONESHOT | MT_SCANSUBS, - pid, MPS_WEIGHT_PMT_SCAN); + mpegts_table_add(mm, + DVB_PMT_BASE, + DVB_PMT_MASK, + dvb_pmt_callback, + NULL, + "pmt", + LS_TBL_BASE, + MT_CRC | MT_QUICKREQ | MT_ONESHOT | MT_SCANSUBS, + pid, + MPS_WEIGHT_PMT_SCAN); if (save) service_request_save((service_t*)s); } @@ -1026,32 +1112,38 @@ dvb_pat_callback ptr += 4; len -= 4; } - + /* Install NIT handler */ if (nit_pid) - mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback, - NULL, "nit", LS_TBL_BASE, MT_QUICKREQ | MT_CRC, nit_pid, - MPS_WEIGHT_NIT); + mpegts_table_add(mm, + DVB_NIT_BASE, + DVB_NIT_MASK, + dvb_nit_callback, + NULL, + "nit", + LS_TBL_BASE, + MT_QUICKREQ | MT_CRC, + nit_pid, + MPS_WEIGHT_NIT); /* End */ end: - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); } /* * CAT processing */ -void -dvb_cat_decode( const uint8_t *data, int len, - void (*add_emm)(void *aux, uint16_t caid, uint32_t prov, uint16_t pid), - void *aux ) -{ - uint8_t dtag, dlen, dlen2; - uint16_t caid = 0, pid = 0; - uint32_t prov; - const uint8_t *data2; - int len2; - card_type_t ctype; +void dvb_cat_decode(const uint8_t* data, + int len, + void (*add_emm)(void* aux, uint16_t caid, uint32_t prov, uint16_t pid), + void* aux) { + uint8_t dtag, dlen, dlen2; + uint16_t caid = 0, pid = 0; + uint32_t prov; + const uint8_t* data2; + int len2; + card_type_t ctype; while (len > 2) { dtag = *data++; @@ -1059,7 +1151,7 @@ dvb_cat_decode( const uint8_t *data, int len, len -= 2; if (dtag != DVB_DESC_CA || len < 4 || dlen < 4) goto next; - caid = (data[0] << 8) | data[1]; + caid = (data[0] << 8) | data[1]; pid = ((data[2] << 8) | data[3]) & 0x1fff; if (pid > 0) { ctype = detect_card_type(caid); @@ -1069,7 +1161,7 @@ dvb_cat_decode( const uint8_t *data, int len, data2 = data + 5; len2 = len - 5; while (dlen2 >= 4 && len2 >= 4) { - pid = ((data2[0] << 8) | data2[1]) & 0xfff; + pid = ((data2[0] << 8) | data2[1]) & 0xfff; prov = (data2[2] << 8) | data2[3]; add_emm(aux, caid, prov, pid); data2 += 4; @@ -1078,32 +1170,32 @@ dvb_cat_decode( const uint8_t *data, int len, } } } -next: + next: data += dlen; - len -= dlen; + len -= dlen; } } -static void -dvb_cat_entry(void *_mt, uint16_t caid, uint32_t prov, uint16_t pid) -{ - mpegts_table_t *mt = _mt; - tvhdebug(mt->mt_subsys, "%s: caid %04X (%d) pid %04X (%d)", - mt->mt_name, (uint16_t)caid, (uint16_t)caid, pid, pid); +static void dvb_cat_entry(void* _mt, uint16_t caid, uint32_t prov, uint16_t pid) { + mpegts_table_t* mt = _mt; + tvhdebug(mt->mt_subsys, + "%s: caid %04X (%d) pid %04X (%d)", + mt->mt_name, + (uint16_t)caid, + (uint16_t)caid, + pid, + pid); } -int -dvb_cat_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int r, sect, last, ver; - mpegts_mux_t *mm = mt->mt_mux; - mpegts_psi_table_state_t *st = NULL; +int dvb_cat_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int r, sect, last, ver; + mpegts_mux_t* mm = mt->mt_mux; + mpegts_psi_table_state_t* st = NULL; /* Start */ - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, - tableid, 0, 5, &st, §, &last, &ver, 0); - if (r != 1) return r; + r = dvb_table_begin((mpegts_psi_table_t*)mt, ptr, len, tableid, 0, 5, &st, §, &last, &ver, 0); + if (r != 1) + return r; ptr += 5; len -= 5; @@ -1114,32 +1206,30 @@ dvb_cat_callback dvb_cat_decode(ptr, len, dvb_cat_entry, mt); /* Finish */ - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); } /* * NIT/BAT processing (because its near identical) */ -static void -dvb_bat_destroy_lists( mpegts_table_t *mt ) -{ - dvb_bat_t *b = mt->mt_bat; - dvb_bat_id_t *bi; - dvb_bat_svc_t *bs; - dvb_freesat_region_t *fr; - dvb_freesat_svc_t *fs; - bouquet_t *bq; +static void dvb_bat_destroy_lists(mpegts_table_t* mt) { + dvb_bat_t* b = mt->mt_bat; + dvb_bat_id_t* bi; + dvb_bat_svc_t* bs; + dvb_freesat_region_t* fr; + dvb_freesat_svc_t* fs; + bouquet_t* bq; if (mt->mt_table == DVB_FASTSCAN_NIT_BASE) { - bq = mt->mt_opaque; + bq = mt->mt_opaque; bq->bq_fastscan_bi = NULL; } while ((bi = LIST_FIRST(&b->bats)) != NULL) { while ((bs = TAILQ_FIRST(&bi->services)) != NULL) { TAILQ_REMOVE(&bi->services, bs, link); if (bs->svc) - service_unref((service_t *)bs->svc); + service_unref((service_t*)bs->svc); free(bs); } while ((fs = TAILQ_FIRST(&bi->fservices)) != NULL) { @@ -1155,27 +1245,27 @@ dvb_bat_destroy_lists( mpegts_table_t *mt ) } } -void -dvb_bat_destroy( mpegts_table_t *mt ) -{ +void dvb_bat_destroy(mpegts_table_t* mt) { dvb_bat_destroy_lists(mt); free(mt->mt_bat); mt->mt_bat = NULL; } -static void -dvb_bat_completed - ( dvb_bat_t *b, mpegts_table_t *mt, int tableid, int tsid, int nbid, - mpegts_mux_t *mux, bouquet_t *bq_alt ) -{ - dvb_bat_id_t *bi; - dvb_bat_svc_t *bs; - uint32_t services_count; - bouquet_t *bq; +static void dvb_bat_completed(dvb_bat_t* b, + mpegts_table_t* mt, + int tableid, + int tsid, + int nbid, + mpegts_mux_t* mux, + bouquet_t* bq_alt) { + dvb_bat_id_t* bi; + dvb_bat_svc_t* bs; + uint32_t services_count; + bouquet_t* bq; b->complete = 1; - LIST_FOREACH(bi, &b->bats, link) { + LIST_FOREACH (bi, &b->bats, link) { if (bi->nbid != nbid) { if (!bi->complete) @@ -1196,7 +1286,7 @@ dvb_bat_completed if (tableid == 0x4A /* BAT */) { char src[64] = ""; if (idnode_is_instance(&mux->mm_id, &dvb_mux_dvbs_class)) { - dvb_mux_conf_t *mc = &((dvb_mux_t *)mux)->lm_tuning; + dvb_mux_conf_t* mc = &((dvb_mux_t*)mux)->lm_tuning; if (mc->u.dmc_fe_qpsk.orbital_pos != INT_MAX) { char buf[16]; dvb_sat_position_to_str(mc->u.dmc_fe_qpsk.orbital_pos, buf, sizeof(buf)); @@ -1214,52 +1304,60 @@ dvb_bat_completed } #endif - if (!bq) continue; + if (!bq) + continue; dvb_bouquet_comment(bq, bi->mm); services_count = 0; - TAILQ_FOREACH(bs, &bi->services, link) { + TAILQ_FOREACH (bs, &bi->services, link) { services_count++; if (bq->bq_enabled) - bouquet_add_service(bq, (service_t *)bs->svc, - (int64_t)bs->lcn * CHANNEL_SPLIT, NULL); + bouquet_add_service(bq, (service_t*)bs->svc, (int64_t)bs->lcn * CHANNEL_SPLIT, NULL); } bouquet_completed(bq, services_count); -complete: + complete: bi->complete = 1; } } -static int -dvb_nit_mux - (mpegts_table_t *mt, mpegts_mux_t *mux, mpegts_mux_t *mm, - uint16_t onid, uint16_t tsid, - const uint8_t *lptr, int llen, uint8_t tableid, - dvb_bat_id_t *bi, int discovery) -{ - uint32_t priv = 0; - uint8_t dtag; - int dllen, dlen; - const uint8_t *dlptr, *dptr, *lptr_orig = lptr; - const char *charset; - mpegts_network_t *mn; - char dauth[256]; +static int dvb_nit_mux(mpegts_table_t* mt, + mpegts_mux_t* mux, + mpegts_mux_t* mm, + uint16_t onid, + uint16_t tsid, + const uint8_t* lptr, + int llen, + uint8_t tableid, + dvb_bat_id_t* bi, + int discovery) { + uint32_t priv = 0; + uint8_t dtag; + int dllen, dlen; + const uint8_t * dlptr, *dptr, *lptr_orig = lptr; + const char* charset; + mpegts_network_t* mn; + char dauth[256]; if (mux && mux->mm_enabled != MM_ENABLE) bi = NULL; - mn = mux ? mux->mm_network : mm->mm_network; + mn = mux ? mux->mm_network : mm->mm_network; charset = discovery ? NULL : dvb_charset_find(mn, mux, NULL); if (!discovery || tvhtrace_enabled()) { tvhlog(discovery ? LOG_TRACE : LOG_DEBUG, - mt->mt_subsys, "%s: onid %04X (%d) tsid %04X (%d) mux %s%s", - mt->mt_name, onid, onid, tsid, tsid, - mm->mm_nicename ?: "", - discovery ? " (discovery)" : ""); + mt->mt_subsys, + "%s: onid %04X (%d) tsid %04X (%d) mux %s%s", + mt->mt_name, + onid, + onid, + tsid, + tsid, + mm->mm_nicename ?: "", + discovery ? " (discovery)" : ""); } DVB_DESC_FOREACH(mt, lptr, llen, 4, dlptr, dllen, dtag, dlen, dptr) { @@ -1267,11 +1365,8 @@ dvb_nit_mux #if ENABLE_MPEGTS_DVB /* Limit delivery descriptiors only in the discovery phase */ - if (discovery > 0 && - dtag != DVB_DESC_SAT_DEL && - dtag != DVB_DESC_CABLE_DEL && - dtag != DVB_DESC_TERR_DEL && - dtag != DVB_DESC_FREQ_LIST) + if (discovery > 0 && dtag != DVB_DESC_SAT_DEL && dtag != DVB_DESC_CABLE_DEL && + dtag != DVB_DESC_TERR_DEL && dtag != DVB_DESC_FREQ_LIST) continue; #endif @@ -1282,7 +1377,7 @@ dvb_nit_mux if (mt->mt_mux_cb[i].tag == dtag) break; i++; - } + } if (mt->mt_mux_cb[i].cb) { if (mt->mt_mux_cb[i].cb(mt, mux, bi ? bi->nbid : 0, dtag, dptr, dlen)) return -1; @@ -1292,133 +1387,134 @@ dvb_nit_mux /* Pre-defined */ switch (dtag) { - default: - case 0: - break; + default: + case 0: + break; - /* nit only */ + /* nit only */ #if ENABLE_MPEGTS_DVB - case DVB_DESC_SAT_DEL: - case DVB_DESC_CABLE_DEL: - case DVB_DESC_TERR_DEL: - if (discovery > 0) { - if (dtag == DVB_DESC_SAT_DEL) - mux = dvb_desc_sat_del(mt, mm, onid, tsid, dptr, dlen, - tableid == DVB_FASTSCAN_NIT_BASE); - else if (dtag == DVB_DESC_CABLE_DEL) - mux = dvb_desc_cable_del(mt, mm, onid, tsid, dptr, dlen); - else - mux = dvb_desc_terr_del(mt, mm, onid, tsid, dptr, dlen); - if (mux) { - mpegts_mux_set_onid(mux, onid); - mpegts_mux_set_tsid(mux, tsid, 0); - if (tableid == DVB_FASTSCAN_NIT_BASE) - dvb_fs_mux_add(mt, mm, mux); + case DVB_DESC_SAT_DEL: + case DVB_DESC_CABLE_DEL: + case DVB_DESC_TERR_DEL: + if (discovery > 0) { + if (dtag == DVB_DESC_SAT_DEL) + mux = + dvb_desc_sat_del(mt, mm, onid, tsid, dptr, dlen, tableid == DVB_FASTSCAN_NIT_BASE); + else if (dtag == DVB_DESC_CABLE_DEL) + mux = dvb_desc_cable_del(mt, mm, onid, tsid, dptr, dlen); + else + mux = dvb_desc_terr_del(mt, mm, onid, tsid, dptr, dlen); + if (mux) { + mpegts_mux_set_onid(mux, onid); + mpegts_mux_set_tsid(mux, tsid, 0); + if (tableid == DVB_FASTSCAN_NIT_BASE) + dvb_fs_mux_add(mt, mm, mux); + } } - } - break; - case DVB_DESC_FREQ_LIST: - if (discovery) - dvb_desc_freq_list(mt, mm, dptr, dlen); - break; + break; + case DVB_DESC_FREQ_LIST: + if (discovery) + dvb_desc_freq_list(mt, mm, dptr, dlen); + break; #endif - /* Both */ - case DVB_DESC_DEF_AUTHORITY: - if (!dvb_get_string(dauth, sizeof(dauth), dptr, dlen, charset, NULL)) { - tvhdebug(mt->mt_subsys, "%s: default auth [%s]", mt->mt_name, dauth); - if (mux && *dauth) - mpegts_mux_set_crid_authority(mux, dauth); - } else { - tvhtrace(mt->mt_subsys, "%s: auth error", mt->mt_name); - } - break; - case DVB_DESC_SERVICE_LIST: - if (dvb_desc_service_list(mt, dptr, dlen, mux, bi)) - tvhtrace(mt->mt_subsys, "%s: service list error", mt->mt_name); - break; - case DVB_DESC_PRIVATE_DATA: - if (dlen == 4) { - priv = extract_4byte(dptr); - tvhtrace(mt->mt_subsys, "%s: private %08X", mt->mt_name, priv); - } - break; - case 0x81: - if (priv == 0) goto lcn; - break; - case 0x82: - if (priv == 0) goto lcn; - break; - case 0x83: - if (priv == 0 || priv == 0x28 || priv == 0x29 || priv == 0xa5 || - priv == 0x212c || priv == 0x233A || - priv == 0x3200 || priv == 0x3201) goto lcn; - break; - case 0x86: - if (priv == 0 || priv == 0x1a0) goto lcn; - break; - case 0x88: - if (priv == 0x28) { - /* HD simulcast */ - if (dvb_desc_local_channel(mt, mn, dptr, dlen, dtag, mux, bi, 1)) - tvhtrace(mt->mt_subsys, "%s: lcn 88 error", mt->mt_name); - } - break; - case 0x93: - if (priv == 0 || priv == 0x362275) - /* fall thru */ -lcn: - if (dvb_desc_local_channel(mt, mn, dptr, dlen, dtag, mux, bi, 0)) - tvhtrace(mt->mt_subsys, "%s: lcn %02X error", mt->mt_name, dtag); - break; - case DVB_DESC_FREESAT_LCN: + /* Both */ + case DVB_DESC_DEF_AUTHORITY: + if (!dvb_get_string(dauth, sizeof(dauth), dptr, dlen, charset, NULL)) { + tvhdebug(mt->mt_subsys, "%s: default auth [%s]", mt->mt_name, dauth); + if (mux && *dauth) + mpegts_mux_set_crid_authority(mux, dauth); + } else { + tvhtrace(mt->mt_subsys, "%s: auth error", mt->mt_name); + } + break; + case DVB_DESC_SERVICE_LIST: + if (dvb_desc_service_list(mt, dptr, dlen, mux, bi)) + tvhtrace(mt->mt_subsys, "%s: service list error", mt->mt_name); + break; + case DVB_DESC_PRIVATE_DATA: + if (dlen == 4) { + priv = extract_4byte(dptr); + tvhtrace(mt->mt_subsys, "%s: private %08X", mt->mt_name, priv); + } + break; + case 0x81: + if (priv == 0) + goto lcn; + break; + case 0x82: + if (priv == 0) + goto lcn; + break; + case 0x83: + if (priv == 0 || priv == 0x28 || priv == 0x29 || priv == 0xa5 || priv == 0x212c || + priv == 0x233A || priv == 0x3200 || priv == 0x3201) + goto lcn; + break; + case 0x86: + if (priv == 0 || priv == 0x1a0) + goto lcn; + break; + case 0x88: + if (priv == 0x28) { + /* HD simulcast */ + if (dvb_desc_local_channel(mt, mn, dptr, dlen, dtag, mux, bi, 1)) + tvhtrace(mt->mt_subsys, "%s: lcn 88 error", mt->mt_name); + } + break; + case 0x93: + if (priv == 0 || priv == 0x362275) + /* fall thru */ + lcn: + if (dvb_desc_local_channel(mt, mn, dptr, dlen, dtag, mux, bi, 0)) + tvhtrace(mt->mt_subsys, "%s: lcn %02X error", mt->mt_name, dtag); + break; + case DVB_DESC_FREESAT_LCN: #if ENABLE_MPEGTS_DVB - if (bi && tableid == 0x4A && priv == PRIV_FSAT) { - dvb_freesat_local_channels(bi, mt, dptr, dlen); - bi->freesat = 1; - } + if (bi && tableid == 0x4A && priv == PRIV_FSAT) { + dvb_freesat_local_channels(bi, mt, dptr, dlen); + bi->freesat = 1; + } #endif - break; - case DVB_DESC_BSKYB_LCN: + break; + case DVB_DESC_BSKYB_LCN: #if ENABLE_MPEGTS_DVB - if (bi && tableid == 0x4A && priv == 2) { - dvb_bskyb_local_channels(bi, mt, dptr, dlen, mux); - bi->bskyb = 1; - } + if (bi && tableid == 0x4A && priv == 2) { + dvb_bskyb_local_channels(bi, mt, dptr, dlen, mux); + bi->bskyb = 1; + } #endif - break; + break; } - }} + } +} - return lptr - lptr_orig; +return lptr - lptr_orig; -dvberr: - tvhtrace(mt->mt_subsys, "%s: error", mt->mt_name); - return -1; +dvberr: tvhtrace(mt->mt_subsys, "%s: error", mt->mt_name); +return -1; } -int -dvb_nit_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int save = 0, retry = 0; - int r, sect, last, ver; - uint32_t priv = 0, priv2 = 0; - uint8_t dtag; - int llen, dlen; - const uint8_t *lptr, *dptr; - uint16_t nbid = 0, onid, tsid; - mpegts_mux_t *mm = mt->mt_mux, *mux; - mpegts_network_t *mn = mm->mm_network; - char name[256]; - mpegts_psi_table_state_t *st = NULL; - const char *charset; - bouquet_t *bq = NULL; - dvb_bat_t *b = NULL; - dvb_bat_id_t *bi = NULL; +int dvb_nit_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int save = 0, retry = 0; + int r, sect, last, ver; + uint32_t priv = 0, priv2 = 0; + uint8_t dtag; + int llen, dlen; + const uint8_t * lptr, *dptr; + uint16_t nbid = 0, onid, tsid; + mpegts_mux_t * mm = mt->mt_mux, *mux; + mpegts_network_t* mn = mm->mm_network; + char name[256]; + mpegts_psi_table_state_t* st = NULL; + const char* charset; + bouquet_t* bq = NULL; + dvb_bat_t* b = NULL; + dvb_bat_id_t* bi = NULL; /* Net/Bat ID */ - if (len < 2) return -1; + if (len < 2) + return -1; nbid = extract_2byte(ptr); /* Begin */ @@ -1428,8 +1524,17 @@ dvb_nit_callback return -1; } - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, - tableid, nbid, 7, &st, §, &last, &ver, 0); + r = dvb_table_begin((mpegts_psi_table_t*)mt, + ptr, + len, + tableid, + nbid, + 7, + &st, + §, + &last, + &ver, + 0); if (r == 0) { if (tableid == 0x4A || tableid == DVB_FASTSCAN_NIT_BASE) { if (tableid == DVB_FASTSCAN_NIT_BASE && bq) { @@ -1440,8 +1545,7 @@ dvb_nit_callback } if ((b = mt->mt_bat) != NULL) { if (!b->complete) { - dvb_bat_completed(b, mt, tableid, mm->mm_tsid, nbid, - mm, mt->mt_opaque); + dvb_bat_completed(b, mt, tableid, mm->mm_tsid, nbid, mm, mt->mt_opaque); mt->mt_working -= st->working; st->working = 0; } @@ -1450,7 +1554,8 @@ dvb_nit_callback } } } - if (r != 1) return r; + if (r != 1) + return r; /* NIT */ if (tableid != 0x4A && tableid != DVB_FASTSCAN_NIT_BASE) { @@ -1458,27 +1563,26 @@ dvb_nit_callback /* Specific NID */ if (mn->mn_nid) { if (mn->mn_nid != nbid) { - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); } - - /* Only use "this" network */ + + /* Only use "this" network */ } else if (tableid != 0x40) { - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); } } /* BAT ID lookup */ - if (dvb_bouquets_parse && - (tableid == 0x4A || tableid == DVB_FASTSCAN_NIT_BASE)) { + if (dvb_bouquets_parse && (tableid == 0x4A || tableid == DVB_FASTSCAN_NIT_BASE)) { if ((b = mt->mt_bat) == NULL) { - b = calloc(1, sizeof(*b)); + b = calloc(1, sizeof(*b)); mt->mt_bat = b; } - LIST_FOREACH(bi, &b->bats, link) + LIST_FOREACH (bi, &b->bats, link) if (bi->nbid == nbid) break; if (!bi) { - bi = calloc(1, sizeof(*bi)); + bi = calloc(1, sizeof(*bi)); bi->nbid = nbid; TAILQ_INIT(&bi->services); TAILQ_INIT(&bi->fservices); @@ -1505,7 +1609,10 @@ dvb_nit_callback case DVB_DESC_BOUQUET_NAME: case DVB_DESC_NETWORK_NAME: if (dvb_get_string(name, sizeof(name), dptr, dlen, charset, NULL)) - tvhtrace(mt->mt_subsys, "%s: %s name error", mt->mt_name, dtag == DVB_DESC_BOUQUET_NAME ? "bouquet" : "network"); + tvhtrace(mt->mt_subsys, + "%s: %s name error", + mt->mt_name, + dtag == DVB_DESC_BOUQUET_NAME ? "bouquet" : "network"); break; case DVB_DESC_MULTI_NETWORK_NAME: // TODO: implement this? @@ -1516,65 +1623,65 @@ dvb_nit_callback tvhtrace(mt->mt_subsys, "%s: private %08X", mt->mt_name, priv); } break; - case DVB_DESC_FREESAT_REGIONS: + case DVB_DESC_FREESAT_REGIONS: #if ENABLE_MPEGTS_DVB if (tableid == 0x4A && priv == PRIV_FSAT) dvb_freesat_regions(bi, mt, dptr, dlen); #endif break; } - }} + } +} - /* Fastscan */ - if (tableid == DVB_FASTSCAN_NIT_BASE) { - tvhdebug(mt->mt_subsys, "%s: fastscan %04X (%d) [%s]", mt->mt_name, nbid, nbid, name); - if (bq && bi) { - dvb_bouquet_comment(bq, mm); - bq->bq_fastscan_bi = bi; - } +/* Fastscan */ +if (tableid == DVB_FASTSCAN_NIT_BASE) { + tvhdebug(mt->mt_subsys, "%s: fastscan %04X (%d) [%s]", mt->mt_name, nbid, nbid, name); + if (bq && bi) { + dvb_bouquet_comment(bq, mm); + bq->bq_fastscan_bi = bi; + } /* BAT */ - } else if (tableid == 0x4A) { - tvhdebug(mt->mt_subsys, "%s: bouquet %04X (%d) [%s]", mt->mt_name, nbid, nbid, name); - if (bi && *name) - strlcpy(bi->name, name, sizeof(bi->name)); +} else if (tableid == 0x4A) { + tvhdebug(mt->mt_subsys, "%s: bouquet %04X (%d) [%s]", mt->mt_name, nbid, nbid, name); + if (bi && *name) + strlcpy(bi->name, name, sizeof(bi->name)); /* NIT */ - } else { - tvhdebug(mt->mt_subsys, "%s: network %04X (%d) [%s]", mt->mt_name, nbid, nbid, name); - save |= mpegts_network_set_network_name(mn, name); - if (save) - idnode_changed(&mn->mn_id); - if (mpegts_mux_set_network_name(mm, name)) - idnode_changed(&mm->mm_id); - } +} else { + tvhdebug(mt->mt_subsys, "%s: network %04X (%d) [%s]", mt->mt_name, nbid, nbid, name); + save |= mpegts_network_set_network_name(mn, name); + if (save) + idnode_changed(&mn->mn_id); + if (mpegts_mux_set_network_name(mm, name)) + idnode_changed(&mm->mm_id); +} - /* Transport length */ - DVB_LOOP_FOREACH(mt, ptr, len, 0, lptr, llen, 6) { - tsid = extract_tsid(lptr); - onid = extract_onid(lptr + 2); +/* Transport length */ +DVB_LOOP_FOREACH(mt, ptr, len, 0, lptr, llen, 6) { + tsid = extract_tsid(lptr); + onid = extract_onid(lptr + 2); #if ENABLE_MPEGTS_DVB - /* Create new muxes (auto-discovery) */ - r = dvb_nit_mux(mt, NULL, mm, onid, tsid, lptr, llen, tableid, bi, 1); - if (r < 0) - return r; + /* Create new muxes (auto-discovery) */ + r = dvb_nit_mux(mt, NULL, mm, onid, tsid, lptr, llen, tableid, bi, 1); + if (r < 0) + return r; #endif /* Find existing mux */ #if ENABLE_MPEGTS_DVB - if (tableid == DVB_FASTSCAN_NIT_BASE) { - mux = dvb_fs_mux_find(mm, onid, tsid); - if (mux && (mm == mux || mpegts_mux_alive(mux))) { - r = dvb_nit_mux(mt, mux, mm, onid, tsid, lptr, llen, tableid, bi, 0); - if (r < 0) - return r; - } - } else + if (tableid == DVB_FASTSCAN_NIT_BASE) { + mux = dvb_fs_mux_find(mm, onid, tsid); + if (mux && (mm == mux || mpegts_mux_alive(mux))) { + r = dvb_nit_mux(mt, mux, mm, onid, tsid, lptr, llen, tableid, bi, 0); + if (r < 0) + return r; + } + } else #endif - LIST_FOREACH(mux, &mn->mn_muxes, mm_network_link) { - if (mux->mm_onid == onid && mux->mm_tsid == tsid && - (mm == mux || mpegts_mux_alive(mux))) { + LIST_FOREACH (mux, &mn->mn_muxes, mm_network_link) { + if (mux->mm_onid == onid && mux->mm_tsid == tsid && (mm == mux || mpegts_mux_alive(mux))) { r = dvb_nit_mux(mt, mux, mm, onid, tsid, lptr, llen, tableid, bi, 0); if (r < 0) return r; @@ -1585,65 +1692,70 @@ dvb_nit_callback retry = 1; /* keep rolling - perhaps SDT was not parsed yet */ } - if ((tableid == 0x40 || (mn->mn_nid && mn->mn_nid == nbid)) && priv == 0) { - priv2 = dvb_priv_lookup(mt, lptr, llen); - if (priv2) { - tvhtrace(mt->mt_subsys, "%s: using private2 data 0x%08x", mt->mt_name, priv2); - priv = priv2; - } + if ((tableid == 0x40 || (mn->mn_nid && mn->mn_nid == nbid)) && priv == 0) { + priv2 = dvb_priv_lookup(mt, lptr, llen); + if (priv2) { + tvhtrace(mt->mt_subsys, "%s: using private2 data 0x%08x", mt->mt_name, priv2); + priv = priv2; } - - lptr += r; - llen -= r; } - /* End */ - if (retry) - return 0; + lptr += r; + llen -= r; +} - if (tableid == 0x40 || (mn->mn_nid && mn->mn_nid == nbid)) - eit_nit_callback(mt, nbid, name, priv); +/* End */ +if (retry) + return 0; + +if (tableid == 0x40 || (mn->mn_nid && mn->mn_nid == nbid)) + eit_nit_callback(mt, nbid, name, priv); - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); +return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); -dvberr: - tvhtrace(mt->mt_subsys, "%s: error", mt->mt_name); - return -1; +dvberr: tvhtrace(mt->mt_subsys, "%s: error", mt->mt_name); +return -1; } /** * DVB SDT (Service Description Table) */ -static int -dvb_sdt_mux - (mpegts_table_t *mt, mpegts_mux_t *mm, mpegts_mux_t *mm_orig, - const uint8_t *ptr, int len, uint8_t tableid) -{ - uint32_t priv = 0; - uint8_t dtag; - const uint8_t *lptr, *dptr; - int llen, dlen; - mpegts_network_t *mn = mm->mm_network; +static int dvb_sdt_mux(mpegts_table_t* mt, + mpegts_mux_t* mm, + mpegts_mux_t* mm_orig, + const uint8_t* ptr, + int len, + uint8_t tableid) { + uint32_t priv = 0; + uint8_t dtag; + const uint8_t * lptr, *dptr; + int llen, dlen; + mpegts_network_t* mn = mm->mm_network; tvhdebug(mt->mt_subsys, "%s: mux %s", mt->mt_name, mm->mm_nicename); /* Service loop */ - while(len >= 5) { - mpegts_service_t *s; - int master = 0, save = 0, save2 = 0; - uint16_t service_id = extract_svcid(ptr); - int free_ca_mode = (ptr[3] >> 4) & 0x1; - int stype = 0; - char sprov[256], sname[256], sauth[256]; - int running_status = (ptr[3] >> 5) & 0x7; - const char *charset; + while (len >= 5) { + mpegts_service_t* s; + int master = 0, save = 0, save2 = 0; + uint16_t service_id = extract_svcid(ptr); + int free_ca_mode = (ptr[3] >> 4) & 0x1; + int stype = 0; + char sprov[256], sname[256], sauth[256]; + int running_status = (ptr[3] >> 5) & 0x7; + const char* charset; *sprov = *sname = *sauth = 0; - tvhdebug(mt->mt_subsys, "%s: sid %04X (%d) running %d free_ca %d", - mt->mt_name, service_id, service_id, running_status, free_ca_mode); + tvhdebug(mt->mt_subsys, + "%s: sid %04X (%d) running %d free_ca %d", + mt->mt_name, + service_id, + service_id, + running_status, + free_ca_mode); /* Initialise the loop */ DVB_LOOP_INIT(mt, ptr, len, 3, lptr, llen); - + /* Find service */ s = mpegts_service_find(mm, service_id, 0, 1, &save); charset = dvb_charset_find(mn, mm, s); @@ -1656,8 +1768,14 @@ dvb_sdt_mux tvhtrace(mt->mt_subsys, "%s: dtag %02X dlen %d", mt->mt_name, dtag, dlen); switch (dtag) { case DVB_DESC_SERVICE: - if (dvb_desc_service(dptr, dlen, &stype, sprov, - sizeof(sprov), sname, sizeof(sname), charset)) + if (dvb_desc_service(dptr, + dlen, + &stype, + sprov, + sizeof(sprov), + sname, + sizeof(sname), + charset)) tvhtrace(mt->mt_subsys, "%s: service name error", mt->mt_name); break; case DVB_DESC_DEF_AUTHORITY: @@ -1667,7 +1785,8 @@ dvb_sdt_mux case DVB_DESC_PRIVATE_DATA: if (dlen == 4) { priv = extract_4byte(dptr); - if (priv && mt->mt_priv == 0) mt->mt_priv = priv; + if (priv && mt->mt_priv == 0) + mt->mt_priv = priv; tvhtrace(mt->mt_subsys, "%s: private %08X", mt->mt_name, priv); } break; @@ -1677,103 +1796,120 @@ dvb_sdt_mux tvhtrace(mt->mt_subsys, "%s: bskyb nvod error", mt->mt_name); break; } - }} - - tvhtrace(mt->mt_subsys, "%s: type %02X (%d) name [%s] provider [%s] def_auth [%s]", - mt->mt_name, stype, stype, sname, sprov, sauth); - if (!s) continue; - - /* Update service type */ - if (stype && s->s_dvb_servicetype != stype) { - int r; - s->s_dvb_servicetype = stype; - save = 1; - tvhtrace(mt->mt_subsys, "%s: type changed / old %02X (%i)", - mt->mt_name, s->s_dvb_servicetype, s->s_dvb_servicetype); - - /* Set tvh service type */ - if ((r = dvb_servicetype_lookup(stype)) != -1) - s->s_servicetype = r; - } - - /* Check if this is master - * Some networks appear to provide diff service names on diff transponders - */ - if (tableid == 0x42 || mm == mm_orig) - master = 1; - - /* Update CRID authority */ - if (*sauth && strcmp(s->s_dvb_cridauth ?: "", sauth)) { - tvh_str_update(&s->s_dvb_cridauth, sauth); - save = 1; - tvhtrace(mt->mt_subsys, "%s: cridauth changed", mt->mt_name); } + } - /* Update name */ - if (*sname && strcmp(s->s_dvb_svcname ?: "", sname)) { - if (!s->s_dvb_svcname || master) { - tvh_str_update(&s->s_dvb_svcname, sname); - save2 = 1; - tvhtrace(mt->mt_subsys, "%s: name changed", mt->mt_name); - } - } - - /* Update provider */ - if (*sprov && strcmp(s->s_dvb_provider ?: "", sprov)) { - if (!s->s_dvb_provider || master) { - tvh_str_update(&s->s_dvb_provider, sprov); - save2 = 1; - tvhtrace(mt->mt_subsys, "%s: provider changed", mt->mt_name); - } - } + tvhtrace(mt->mt_subsys, + "%s: type %02X (%d) name [%s] provider [%s] def_auth [%s]", + mt->mt_name, + stype, + stype, + sname, + sprov, + sauth); + if (!s) + continue; + + /* Update service type */ + if (stype && s->s_dvb_servicetype != stype) { + int r; + s->s_dvb_servicetype = stype; + save = 1; + tvhtrace(mt->mt_subsys, + "%s: type changed / old %02X (%i)", + mt->mt_name, + s->s_dvb_servicetype, + s->s_dvb_servicetype); + + /* Set tvh service type */ + if ((r = dvb_servicetype_lookup(stype)) != -1) + s->s_servicetype = r; + } - /* Update nice name */ - if (save2) { - tvh_mutex_lock(&s->s_stream_mutex); - service_make_nicename((service_t*)s); - tvh_mutex_unlock(&s->s_stream_mutex); - tvhdebug(mt->mt_subsys, "%s: nicename %s", mt->mt_name, s->s_nicename); - save = 1; + /* Check if this is master + * Some networks appear to provide diff service names on diff transponders + */ + if (tableid == 0x42 || mm == mm_orig) + master = 1; + + /* Update CRID authority */ + if (*sauth && strcmp(s->s_dvb_cridauth ?: "", sauth)) { + tvh_str_update(&s->s_dvb_cridauth, sauth); + save = 1; + tvhtrace(mt->mt_subsys, "%s: cridauth changed", mt->mt_name); + } + + /* Update name */ + if (*sname && strcmp(s->s_dvb_svcname ?: "", sname)) { + if (!s->s_dvb_svcname || master) { + tvh_str_update(&s->s_dvb_svcname, sname); + save2 = 1; + tvhtrace(mt->mt_subsys, "%s: name changed", mt->mt_name); } + } - /* Save details */ - if (save) { - idnode_changed(&s->s_id); - service_refresh_channel((service_t*)s); + /* Update provider */ + if (*sprov && strcmp(s->s_dvb_provider ?: "", sprov)) { + if (!s->s_dvb_provider || master) { + tvh_str_update(&s->s_dvb_provider, sprov); + save2 = 1; + tvhtrace(mt->mt_subsys, "%s: provider changed", mt->mt_name); } } - return 0; + /* Update nice name */ + if (save2) { + tvh_mutex_lock(&s->s_stream_mutex); + service_make_nicename((service_t*)s); + tvh_mutex_unlock(&s->s_stream_mutex); + tvhdebug(mt->mt_subsys, "%s: nicename %s", mt->mt_name, s->s_nicename); + save = 1; + } + + /* Save details */ + if (save) { + idnode_changed(&s->s_id); + service_refresh_channel((service_t*)s); + } +} -dvberr: - tvhtrace(mt->mt_subsys, "%s: error", mt->mt_name); - return -1; +return 0; + +dvberr: tvhtrace(mt->mt_subsys, "%s: error", mt->mt_name); +return -1; } -int -dvb_sdt_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int r, sect, last, ver, extraid; - uint16_t onid, tsid; - mpegts_mux_t *mm = mt->mt_mux, *mm_orig = mm; - mpegts_network_t *mn = mm->mm_network; - mpegts_psi_table_state_t *st = NULL; +int dvb_sdt_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int r, sect, last, ver, extraid; + uint16_t onid, tsid; + mpegts_mux_t * mm = mt->mt_mux, *mm_orig = mm; + mpegts_network_t* mn = mm->mm_network; + mpegts_psi_table_state_t* st = NULL; /* Begin */ - if (len < 8) return -1; + if (len < 8) + return -1; tsid = extract_onid(ptr); onid = extract_tsid(ptr + 5); extraid = ((int)onid) << 16 | tsid; - if (tableid != 0x42 && tableid != 0x46) return -1; - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, - tableid, extraid, 8, &st, §, &last, &ver, 0); + if (tableid != 0x42 && tableid != 0x46) + return -1; + r = dvb_table_begin((mpegts_psi_table_t*)mt, + ptr, + len, + tableid, + extraid, + 8, + &st, + §, + &last, + &ver, + 0); if (r != 1) return r; /* ID */ - tvhdebug(mt->mt_subsys, "%s: onid %04X (%d) tsid %04X (%d)", - mt->mt_name, onid, onid, tsid, tsid); + tvhdebug(mt->mt_subsys, "%s: onid %04X (%d) tsid %04X (%d)", mt->mt_name, onid, onid, tsid, tsid); /* Service descriptors */ len -= 8; @@ -1781,7 +1917,8 @@ dvb_sdt_callback /* Find Transport Stream */ if (tableid == 0x42) { - if (mm->mm_tsid != tsid) return 0; /* keep rolling - perhaps PAT was not parsed yet */ + if (mm->mm_tsid != tsid) + return 0; /* keep rolling - perhaps PAT was not parsed yet */ mpegts_mux_set_onid(mm, onid); r = dvb_sdt_mux(mt, mm, mm, ptr, len, tableid); if (r) @@ -1790,9 +1927,8 @@ dvb_sdt_callback if (mm->mm_start_monoclock + sec2mono(10) < mclk()) eit_sdt_callback(mt, mt->mt_priv); } else { - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) - if (mm->mm_onid == onid && mm->mm_tsid == tsid && - (mm == mm_orig || mpegts_mux_alive(mm))) { + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) + if (mm->mm_onid == onid && mm->mm_tsid == tsid && (mm == mm_orig || mpegts_mux_alive(mm))) { r = dvb_sdt_mux(mt, mm, mm_orig, ptr, len, tableid); if (r) return r; @@ -1802,74 +1938,87 @@ dvb_sdt_callback eit_sdt_callback(mt, mt->mt_priv); /* Done */ - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); } /* * ATSC VCT processing */ - /* Done */ -int -atsc_vct_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int i, j, r, sect, last, ver, extraid, save, dlen; - int maj, min, count; - uint16_t tsid, sid, type; - uint16_t srcid; - char chname[256]; - const char *x; - mpegts_mux_t *mm = mt->mt_mux, *mm_orig = mm; - mpegts_network_t *mn = mm->mm_network; - mpegts_service_t *s; - mpegts_psi_table_state_t *st = NULL; - lang_str_t *ls; +/* Done */ +int atsc_vct_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int i, j, r, sect, last, ver, extraid, save, dlen; + int maj, min, count; + uint16_t tsid, sid, type; + uint16_t srcid; + char chname[256]; + const char* x; + mpegts_mux_t * mm = mt->mt_mux, *mm_orig = mm; + mpegts_network_t* mn = mm->mm_network; + mpegts_service_t* s; + mpegts_psi_table_state_t* st = NULL; + lang_str_t* ls; /* Validate */ - if (tableid != 0xc8 && tableid != 0xc9) return -1; + if (tableid != 0xc8 && tableid != 0xc9) + return -1; /* Extra ID */ - if (len < 2) return -1; + if (len < 2) + return -1; tsid = extract_tsid(ptr); extraid = tsid; /* Begin */ - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, - tableid, extraid, 7, &st, §, &last, &ver, 0); - if (r != 1) return r; + r = dvb_table_begin((mpegts_psi_table_t*)mt, + ptr, + len, + tableid, + extraid, + 7, + &st, + §, + &last, + &ver, + 0); + if (r != 1) + return r; if (mm->mm_tsid == 0 && tsid) { if (!LIST_EMPTY(&mm->mm_services)) { mm->mm_tsid = tsid; } else { - mpegts_table_t *mt2 = mpegts_table_find(mm, "pat", NULL); - if (mt2) mpegts_table_reset(mt2); + mpegts_table_t* mt2 = mpegts_table_find(mm, "pat", NULL); + if (mt2) + mpegts_table_reset(mt2); return -1; } } mm->mm_tsid_accept_zero_value = 1; /* ohh, we saw that */ - r = mpegts_mux_tsid_check(mm, mt, tsid); - if (r < 0) return -1; - if (r > 0) goto end; + r = mpegts_mux_tsid_check(mm, mt, tsid); + if (r < 0) + return -1; + if (r > 0) + goto end; /* # channels */ count = ptr[6]; tvhdebug(mt->mt_subsys, "%s: channel count %d", mt->mt_name, count); - ptr += 7; - len -= 7; + ptr += 7; + len -= 7; for (i = 0; i < count && len >= 32; i++) { dlen = ((ptr[30] & 0x3) << 8) | ptr[31]; - if (dlen + 32 > len) return -1; + if (dlen + 32 > len) + return -1; /* Extract fields */ atsc_utf16_to_utf8(ptr, 7, chname, sizeof(chname)); - maj = (ptr[14] & 0xF) << 6 | ptr[15] >> 2; - min = (ptr[15] & 0x3) << 2 | ptr[16]; - tsid = extract_tsid(ptr + 22); - sid = extract_svcid(ptr + 24); - type = ptr[27] & 0x3f; - srcid = (ptr[28]) << 8 | ptr[29]; + maj = (ptr[14] & 0xF) << 6 | ptr[15] >> 2; + min = (ptr[15] & 0x3) << 2 | ptr[16]; + tsid = extract_tsid(ptr + 22); + sid = extract_svcid(ptr + 24); + type = ptr[27] & 0x3f; + srcid = (ptr[28]) << 8 | ptr[29]; tvhdebug(mt->mt_subsys, "%s: tsid %04X (%d)", mt->mt_name, tsid, tsid); tvhdebug(mt->mt_subsys, "%s: sid %04X (%d)", mt->mt_name, sid, sid); tvhdebug(mt->mt_subsys, "%s: chname %s", mt->mt_name, chname); @@ -1883,17 +2032,17 @@ atsc_vct_callback goto next; /* Find mux */ - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) if (mm->mm_tsid == tsid && (mm == mm_orig || mpegts_mux_alive(mm))) { /* Find the service */ save = 0; if (!(s = mpegts_service_find(mm, sid, 0, 1, &save))) continue; - for (j=0; j < dlen; ) { + for (j = 0; j < dlen;) { unsigned int len, tag; - tag = ptr[32+j]; - len = ptr[33+j]; + tag = ptr[32 + j]; + len = ptr[33 + j]; if (tag == ATSC_DESC_EXT_CHANNEL_NAME) { ls = atsc_get_string(ptr + 34 + j, len); if (ls) { @@ -1902,7 +2051,11 @@ atsc_vct_callback x = lang_str_get(ls, "eng"); if (x) snprintf(chname, sizeof(chname), "%s", x); - tvhdebug(mt->mt_subsys, "%s: extended channel name: '%s' (%d bytes)", mt->mt_name, x, len); + tvhdebug(mt->mt_subsys, + "%s: extended channel name: '%s' (%d bytes)", + mt->mt_name, + x, + len); lang_str_destroy(ls); } } else { @@ -1918,96 +2071,108 @@ atsc_vct_callback } if (s->s_dvb_channel_num != maj || s->s_dvb_channel_minor != min) { mpegts_network_bouquet_trigger(mn, 0); - s->s_dvb_channel_num = maj; + s->s_dvb_channel_num = maj; s->s_dvb_channel_minor = min; - save = 1; + save = 1; } if (s->s_atsc_source_id != srcid) { s->s_atsc_source_id = srcid; - save = 1; + save = 1; } /* Save */ if (save) idnode_changed(&s->s_id); - } + } /* Move on */ -next: + next: ptr += dlen + 32; len -= dlen + 32; } end: - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); } /* * ATSC STT processing */ -int -atsc_stt_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int r, sect, last, ver, extraid; - uint32_t systemtime, gps_utc_offset; - int is_dst; - mpegts_psi_table_state_t *st = NULL; +int atsc_stt_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int r, sect, last, ver, extraid; + uint32_t systemtime, gps_utc_offset; + int is_dst; + mpegts_psi_table_state_t* st = NULL; /* Validate */ - if (tableid != DVB_ATSC_STT_BASE) return -1; + if (tableid != DVB_ATSC_STT_BASE) + return -1; /* Extra ID */ - if (len < 2) return -1; + if (len < 2) + return -1; extraid = extract_2byte(ptr); /* Begin */ - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, tableid, extraid, 7, - &st, §, &last, &ver, 0); - if (r != 1) return r; + r = dvb_table_begin((mpegts_psi_table_t*)mt, + ptr, + len, + tableid, + extraid, + 7, + &st, + §, + &last, + &ver, + 0); + if (r != 1) + return r; /* Parse fields */ - systemtime = extract_4byte(ptr + 6); + systemtime = extract_4byte(ptr + 6); gps_utc_offset = ptr[10]; - is_dst = ptr[11] >> 7; + is_dst = ptr[11] >> 7; - tvhdebug(mt->mt_subsys, "%s: system_time %d, gps_utc_offset %d, is DST %d", - mt->mt_name, systemtime, gps_utc_offset, is_dst); + tvhdebug(mt->mt_subsys, + "%s: system_time %d, gps_utc_offset %d, is DST %d", + mt->mt_name, + systemtime, + gps_utc_offset, + is_dst); - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); } /* * DVB BAT processing */ -int -dvb_bat_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ +int dvb_bat_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { return dvb_nit_callback(mt, ptr, len, tableid); } #if ENABLE_MPEGTS_DVB -static int -dvb_fs_sdt_mux - ( mpegts_table_t *mt, mpegts_mux_t *mm, mpegts_psi_table_state_t *st, - const uint8_t *ptr, int len, int discovery, dvb_bat_id_t *bi ) -{ - uint16_t onid, tsid, service_id; - uint8_t dtag; - int llen, dlen; - const uint8_t *lptr, *dptr; - mpegts_network_t *mn; - mpegts_mux_t *mux; +static int dvb_fs_sdt_mux(mpegts_table_t* mt, + mpegts_mux_t* mm, + mpegts_psi_table_state_t* st, + const uint8_t* ptr, + int len, + int discovery, + dvb_bat_id_t* bi) { + uint16_t onid, tsid, service_id; + uint8_t dtag; + int llen, dlen; + const uint8_t * lptr, *dptr; + mpegts_network_t* mn; + mpegts_mux_t* mux; while (len > 0) { - const char *charset; - char sprov[256] = "", sname[256] = ""; - mpegts_service_t *s; - int stype = 0, save = 0; + const char* charset; + char sprov[256] = "", sname[256] = ""; + mpegts_service_t* s; + int stype = 0, save = 0; - onid = extract_onid(ptr); - tsid = extract_tsid(ptr + 2); + onid = extract_onid(ptr); + tsid = extract_tsid(ptr + 2); service_id = extract_svcid(ptr + 4); /* (ptr[6] << 8) | ptr[7] - video pid */ /* (ptr[7] << 8) | ptr[8] - audio pid */ @@ -2023,8 +2188,15 @@ dvb_fs_sdt_mux DVB_DESC_EACH(mt, lptr, llen, dtag, dlen, dptr) { switch (dtag) { case DVB_DESC_SAT_DEL: - tvhtrace(mt->mt_subsys, "%s: dtag %02X dlen %d (discovery) onid %04X (%d) tsid %04X (%d)", - mt->mt_name, dtag, dlen, onid, onid, tsid, tsid); + tvhtrace(mt->mt_subsys, + "%s: dtag %02X dlen %d (discovery) onid %04X (%d) tsid %04X (%d)", + mt->mt_name, + dtag, + dlen, + onid, + onid, + tsid, + tsid); mux = dvb_desc_sat_del(mt, mm, onid, tsid, dptr, dlen, 1); if (mux) { mpegts_mux_set_onid(mux, onid); @@ -2033,114 +2205,124 @@ dvb_fs_sdt_mux } break; } - }} - continue; - } - - tvhdebug(mt->mt_subsys, "%s: service %04X (%d) onid %04X (%d) tsid %04X (%d)", - mt->mt_name, service_id, service_id, onid, onid, tsid, tsid); - - /* Find existing mux */ - mux = dvb_fs_mux_find(mm, onid, tsid); - if (mux == NULL) { - tvhtrace(mt->mt_subsys, "%s: mux not found", mt->mt_name); - continue; + } } - mn = mux->mm_network; - - /* Find service */ - s = mpegts_service_find(mux, service_id, 0, 1, &save); - charset = dvb_charset_find(mn, mux, s); + continue; + } - /* Descriptor loop */ - DVB_DESC_EACH(mt, lptr, llen, dtag, dlen, dptr) { - tvhtrace(mt->mt_subsys, "%s: dtag %02X dlen %d", mt->mt_name, dtag, dlen); - switch (dtag) { - case DVB_DESC_SERVICE: - if (dvb_desc_service(dptr, dlen, &stype, sprov, - sizeof(sprov), sname, sizeof(sname), charset)) - tvhtrace(mt->mt_subsys, "%s: service name error", mt->mt_name); - break; - } - }} + tvhdebug(mt->mt_subsys, + "%s: service %04X (%d) onid %04X (%d) tsid %04X (%d)", + mt->mt_name, + service_id, + service_id, + onid, + onid, + tsid, + tsid); + + /* Find existing mux */ + mux = dvb_fs_mux_find(mm, onid, tsid); + if (mux == NULL) { + tvhtrace(mt->mt_subsys, "%s: mux not found", mt->mt_name); + continue; + } + mn = mux->mm_network; - tvhtrace(mt->mt_subsys, "%s: type %d name [%s] provider [%s]", - mt->mt_name, stype, sname, sprov); + /* Find service */ + s = mpegts_service_find(mux, service_id, 0, 1, &save); + charset = dvb_charset_find(mn, mux, s); - if (bi) - dvb_bat_find_service(bi, s, 0, UINT_MAX); + /* Descriptor loop */ + DVB_DESC_EACH(mt, lptr, llen, dtag, dlen, dptr) { + tvhtrace(mt->mt_subsys, "%s: dtag %02X dlen %d", mt->mt_name, dtag, dlen); + switch (dtag) { + case DVB_DESC_SERVICE: + if (dvb_desc_service(dptr, + dlen, + &stype, + sprov, + sizeof(sprov), + sname, + sizeof(sname), + charset)) + tvhtrace(mt->mt_subsys, "%s: service name error", mt->mt_name); + break; + } + } +} - /* Update service type */ - if (stype && !s->s_dvb_servicetype) { - int r; - s->s_dvb_servicetype = stype; - save = 1; - tvhtrace(mt->mt_subsys, "%s: type changed", mt->mt_name); +tvhtrace(mt->mt_subsys, "%s: type %d name [%s] provider [%s]", mt->mt_name, stype, sname, sprov); - /* Set tvh service type */ - if ((r = dvb_servicetype_lookup(stype)) != -1) - s->s_servicetype = r; - } +if (bi) + dvb_bat_find_service(bi, s, 0, UINT_MAX); - /* Update name */ - if (*sname && strcmp(s->s_dvb_svcname ?: "", sname)) { - if (!s->s_dvb_svcname) { - tvh_str_update(&s->s_dvb_svcname, sname); - save = 1; - tvhtrace(mt->mt_subsys, "%s: name changed", mt->mt_name); - } - } +/* Update service type */ +if (stype && !s->s_dvb_servicetype) { + int r; + s->s_dvb_servicetype = stype; + save = 1; + tvhtrace(mt->mt_subsys, "%s: type changed", mt->mt_name); - /* Update provider */ - if (*sprov && strcmp(s->s_dvb_provider ?: "", sprov)) { - if (!s->s_dvb_provider) { - tvh_str_update(&s->s_dvb_provider, sprov); - save = 1; - tvhtrace(mt->mt_subsys, "%s: provider changed", mt->mt_name); - } - } + /* Set tvh service type */ + if ((r = dvb_servicetype_lookup(stype)) != -1) + s->s_servicetype = r; +} - if (save) { - /* Update nice name */ - tvh_mutex_lock(&s->s_stream_mutex); - service_make_nicename((service_t*)s); - tvh_mutex_unlock(&s->s_stream_mutex); - tvhdebug(mt->mt_subsys, "%s: nicename %s", mt->mt_name, s->s_nicename); - /* Save changes */ - idnode_changed(&s->s_id); - service_refresh_channel((service_t*)s); - } +/* Update name */ +if (*sname && strcmp(s->s_dvb_svcname ?: "", sname)) { + if (!s->s_dvb_svcname) { + tvh_str_update(&s->s_dvb_svcname, sname); + save = 1; + tvhtrace(mt->mt_subsys, "%s: name changed", mt->mt_name); + } +} - if (!st->working) { - st->working = 1; - mt->mt_working++; - mt->mt_flags |= MT_FASTSWITCH; - } +/* Update provider */ +if (*sprov && strcmp(s->s_dvb_provider ?: "", sprov)) { + if (!s->s_dvb_provider) { + tvh_str_update(&s->s_dvb_provider, sprov); + save = 1; + tvhtrace(mt->mt_subsys, "%s: provider changed", mt->mt_name); } +} - return 0; +if (save) { + /* Update nice name */ + tvh_mutex_lock(&s->s_stream_mutex); + service_make_nicename((service_t*)s); + tvh_mutex_unlock(&s->s_stream_mutex); + tvhdebug(mt->mt_subsys, "%s: nicename %s", mt->mt_name, s->s_nicename); + /* Save changes */ + idnode_changed(&s->s_id); + service_refresh_channel((service_t*)s); +} -dvberr: - tvhtrace(mt->mt_subsys, "%s: error", mt->mt_name); - return -1; +if (!st->working) { + st->working = 1; + mt->mt_working++; + mt->mt_flags |= MT_FASTSWITCH; +} } +return 0; + +dvberr: tvhtrace(mt->mt_subsys, "%s: error", mt->mt_name); +return -1; +} /* * DVB fastscan table processing */ -int -dvb_fs_sdt_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int r, sect, last, ver; - uint16_t nbid; - mpegts_mux_t *mm = mt->mt_mux; - bouquet_t *bq = mt->mt_opaque; - mpegts_psi_table_state_t *st = NULL; +int dvb_fs_sdt_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int r, sect, last, ver; + uint16_t nbid; + mpegts_mux_t* mm = mt->mt_mux; + bouquet_t* bq = mt->mt_opaque; + mpegts_psi_table_state_t* st = NULL; /* Fastscan ID */ - if (len < 2) return -1; + if (len < 2) + return -1; nbid = extract_2byte(ptr); /* Begin */ @@ -2152,8 +2334,17 @@ dvb_fs_sdt_callback if (!bq->bq_fastscan_sdt) return 0; } - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, - tableid, nbid, 7, &st, §, &last, &ver, 0); + r = dvb_table_begin((mpegts_psi_table_t*)mt, + ptr, + len, + tableid, + nbid, + 7, + &st, + §, + &last, + &ver, + 0); if (r == 0) { mt->mt_working -= st->working; st->working = 0; @@ -2161,17 +2352,18 @@ dvb_fs_sdt_callback bq->bq_fastscan_sdt = 0; mpegts_table_destroy(mt); } - if (r != 1) return r; - if (len < 5) return -1; + if (r != 1) + return r; + if (len < 5) + return -1; ptr += 5; len -= 5; dvb_fs_sdt_mux(mt, mm, st, ptr, len, 1, NULL); - dvb_fs_sdt_mux(mt, mm, st, ptr, len, 0, - bq && bq->bq_fastscan_nit ? bq->bq_fastscan_bi : NULL); + dvb_fs_sdt_mux(mt, mm, st, ptr, len, 0, bq && bq->bq_fastscan_nit ? bq->bq_fastscan_bi : NULL); /* End */ - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); } #endif @@ -2179,10 +2371,9 @@ dvb_fs_sdt_callback * TDT parser, from ISO 13818-1 and ETSI EN 300 468 */ -static void dvb_time_update(const uint8_t *ptr, const char *srcname) -{ +static void dvb_time_update(const uint8_t* ptr, const char* srcname) { static int64_t dvb_last_update = 0; - time_t t; + time_t t; if (dvb_last_update == 0 || dvb_last_update + sec2mono(1800) < mclk()) { t = dvb_convert_date(ptr, 0); if (t > 0) { @@ -2192,15 +2383,12 @@ static void dvb_time_update(const uint8_t *ptr, const char *srcname) } } -int -dvb_tdt_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ +int dvb_tdt_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { if (len == 5) { dvb_time_update(ptr, "TDT"); mt->mt_incomplete = 0; - mt->mt_complete = 1; - mt->mt_finished = 1; + mt->mt_complete = 1; + mt->mt_finished = 1; } return 0; } @@ -2208,15 +2396,12 @@ dvb_tdt_callback /** * TOT parser, from ISO 13818-1 and ETSI EN 300 468 */ -int -dvb_tot_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ +int dvb_tot_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { if (len >= 5) { dvb_time_update(ptr, "TOT"); mt->mt_incomplete = 0; - mt->mt_complete = 1; - mt->mt_finished = 1; + mt->mt_complete = 1; + mt->mt_finished = 1; } return 0; } @@ -2225,135 +2410,217 @@ dvb_tot_callback * Install default table sets */ -static void -psi_tables_default ( mpegts_mux_t *mm ) -{ - mpegts_table_add(mm, DVB_PAT_BASE, DVB_PAT_MASK, dvb_pat_callback, - NULL, "pat", LS_TBL_BASE, MT_QUICKREQ | MT_CRC | MT_RECORD, - DVB_PAT_PID, MPS_WEIGHT_PAT); - mpegts_table_add(mm, DVB_CAT_BASE, DVB_CAT_MASK, dvb_cat_callback, - NULL, "cat", LS_TBL_BASE, MT_QUICKREQ | MT_CRC, DVB_CAT_PID, - MPS_WEIGHT_CAT); +static void psi_tables_default(mpegts_mux_t* mm) { + mpegts_table_add(mm, + DVB_PAT_BASE, + DVB_PAT_MASK, + dvb_pat_callback, + NULL, + "pat", + LS_TBL_BASE, + MT_QUICKREQ | MT_CRC | MT_RECORD, + DVB_PAT_PID, + MPS_WEIGHT_PAT); + mpegts_table_add(mm, + DVB_CAT_BASE, + DVB_CAT_MASK, + dvb_cat_callback, + NULL, + "cat", + LS_TBL_BASE, + MT_QUICKREQ | MT_CRC, + DVB_CAT_PID, + MPS_WEIGHT_CAT); } #if ENABLE_MPEGTS_DVB -static void -psi_tables_dvb_fastscan( void *aux, bouquet_t *bq, const char *name, int pid ) -{ +static void psi_tables_dvb_fastscan(void* aux, bouquet_t* bq, const char* name, int pid) { tvhtrace(LS_FASTSCAN, "adding table %04X (%i) for '%s'", pid, pid, name); bq->bq_fastscan_nit = 1; bq->bq_fastscan_sdt = 1; - mpegts_table_add(aux, DVB_FASTSCAN_NIT_BASE, DVB_FASTSCAN_MASK, - dvb_nit_callback, bq, "fs_nit", LS_FASTSCAN, MT_CRC, pid, - MPS_WEIGHT_NIT2); - mpegts_table_add(aux, DVB_FASTSCAN_SDT_BASE, DVB_FASTSCAN_MASK, - dvb_fs_sdt_callback, bq, "fs_sdt", LS_FASTSCAN, MT_CRC, pid, - MPS_WEIGHT_SDT2); + mpegts_table_add(aux, + DVB_FASTSCAN_NIT_BASE, + DVB_FASTSCAN_MASK, + dvb_nit_callback, + bq, + "fs_nit", + LS_FASTSCAN, + MT_CRC, + pid, + MPS_WEIGHT_NIT2); + mpegts_table_add(aux, + DVB_FASTSCAN_SDT_BASE, + DVB_FASTSCAN_MASK, + dvb_fs_sdt_callback, + bq, + "fs_sdt", + LS_FASTSCAN, + MT_CRC, + pid, + MPS_WEIGHT_SDT2); } #endif -static void -psi_tables_dvb ( mpegts_mux_t *mm ) -{ - mpegts_table_add(mm, DVB_NIT_BASE, DVB_NIT_MASK, dvb_nit_callback, - NULL, "nit", LS_TBL_BASE, MT_QUICKREQ | MT_CRC | MT_RECORD, - DVB_NIT_PID, MPS_WEIGHT_NIT); - mpegts_table_add(mm, DVB_SDT_BASE, DVB_SDT_MASK, dvb_sdt_callback, - NULL, "sdt", LS_TBL_BASE, MT_QUICKREQ | MT_CRC | MT_RECORD, - DVB_SDT_PID, MPS_WEIGHT_SDT); - mpegts_table_add(mm, DVB_BAT_BASE, DVB_BAT_MASK, dvb_bat_callback, - NULL, "bat", LS_TBL_BASE, MT_CRC, DVB_BAT_PID, MPS_WEIGHT_BAT); +static void psi_tables_dvb(mpegts_mux_t* mm) { + mpegts_table_add(mm, + DVB_NIT_BASE, + DVB_NIT_MASK, + dvb_nit_callback, + NULL, + "nit", + LS_TBL_BASE, + MT_QUICKREQ | MT_CRC | MT_RECORD, + DVB_NIT_PID, + MPS_WEIGHT_NIT); + mpegts_table_add(mm, + DVB_SDT_BASE, + DVB_SDT_MASK, + dvb_sdt_callback, + NULL, + "sdt", + LS_TBL_BASE, + MT_QUICKREQ | MT_CRC | MT_RECORD, + DVB_SDT_PID, + MPS_WEIGHT_SDT); + mpegts_table_add(mm, + DVB_BAT_BASE, + DVB_BAT_MASK, + dvb_bat_callback, + NULL, + "bat", + LS_TBL_BASE, + MT_CRC, + DVB_BAT_PID, + MPS_WEIGHT_BAT); if (config.tvhtime_update_enabled) { - mpegts_table_add(mm, DVB_TDT_BASE, DVB_TDT_MASK, dvb_tdt_callback, - NULL, "tdt", LS_TBL_TIME, MT_ONESHOT | MT_QUICKREQ | MT_RECORD, - DVB_TDT_PID, MPS_WEIGHT_TDT); - mpegts_table_add(mm, DVB_TOT_BASE, DVB_TOT_MASK, dvb_tot_callback, - NULL, "tot", LS_TBL_TIME, MT_ONESHOT | MT_QUICKREQ | MT_CRC | MT_RECORD, - DVB_TDT_PID, MPS_WEIGHT_TDT); + mpegts_table_add(mm, + DVB_TDT_BASE, + DVB_TDT_MASK, + dvb_tdt_callback, + NULL, + "tdt", + LS_TBL_TIME, + MT_ONESHOT | MT_QUICKREQ | MT_RECORD, + DVB_TDT_PID, + MPS_WEIGHT_TDT); + mpegts_table_add(mm, + DVB_TOT_BASE, + DVB_TOT_MASK, + dvb_tot_callback, + NULL, + "tot", + LS_TBL_TIME, + MT_ONESHOT | MT_QUICKREQ | MT_CRC | MT_RECORD, + DVB_TDT_PID, + MPS_WEIGHT_TDT); } #if ENABLE_MPEGTS_DVB if (idnode_is_instance(&mm->mm_id, &dvb_mux_dvbs_class)) { - dvb_mux_conf_t *mc = &((dvb_mux_t *)mm)->lm_tuning; + dvb_mux_conf_t* mc = &((dvb_mux_t*)mm)->lm_tuning; if (mc->dmc_fe_type == DVB_TYPE_S) - dvb_fastscan_each(mm, mc->u.dmc_fe_qpsk.orbital_pos, - mc->dmc_fe_freq, mc->u.dmc_fe_qpsk.polarisation, psi_tables_dvb_fastscan); + dvb_fastscan_each(mm, + mc->u.dmc_fe_qpsk.orbital_pos, + mc->dmc_fe_freq, + mc->u.dmc_fe_qpsk.polarisation, + psi_tables_dvb_fastscan); } #endif } -static void -psi_tables_atsc_c ( mpegts_mux_t *mm ) -{ - mpegts_table_add(mm, DVB_VCT_C_BASE, DVB_VCT_MASK, atsc_vct_callback, - NULL, "vct", LS_TBL_ATSC, MT_QUICKREQ | MT_CRC | MT_RECORD, - DVB_VCT_PID, MPS_WEIGHT_VCT); - mpegts_table_add(mm, DVB_ATSC_STT_BASE, DVB_ATSC_STT_MASK, atsc_stt_callback, - NULL, "stt", LS_TBL_ATSC, MT_QUICKREQ | MT_CRC | MT_RECORD, - DVB_ATSC_STT_PID, MPS_WEIGHT_STT); +static void psi_tables_atsc_c(mpegts_mux_t* mm) { + mpegts_table_add(mm, + DVB_VCT_C_BASE, + DVB_VCT_MASK, + atsc_vct_callback, + NULL, + "vct", + LS_TBL_ATSC, + MT_QUICKREQ | MT_CRC | MT_RECORD, + DVB_VCT_PID, + MPS_WEIGHT_VCT); + mpegts_table_add(mm, + DVB_ATSC_STT_BASE, + DVB_ATSC_STT_MASK, + atsc_stt_callback, + NULL, + "stt", + LS_TBL_ATSC, + MT_QUICKREQ | MT_CRC | MT_RECORD, + DVB_ATSC_STT_PID, + MPS_WEIGHT_STT); } -static void -psi_tables_atsc_t ( mpegts_mux_t *mm ) -{ - mpegts_table_add(mm, DVB_VCT_T_BASE, DVB_VCT_MASK, atsc_vct_callback, - NULL, "vct", LS_TBL_ATSC, MT_QUICKREQ | MT_CRC | MT_RECORD, - DVB_VCT_PID, MPS_WEIGHT_VCT); - mpegts_table_add(mm, DVB_ATSC_STT_BASE, DVB_ATSC_STT_MASK, atsc_stt_callback, - NULL, "stt", LS_TBL_ATSC, MT_QUICKREQ | MT_CRC | MT_RECORD, - DVB_ATSC_STT_PID, MPS_WEIGHT_STT); +static void psi_tables_atsc_t(mpegts_mux_t* mm) { + mpegts_table_add(mm, + DVB_VCT_T_BASE, + DVB_VCT_MASK, + atsc_vct_callback, + NULL, + "vct", + LS_TBL_ATSC, + MT_QUICKREQ | MT_CRC | MT_RECORD, + DVB_VCT_PID, + MPS_WEIGHT_VCT); + mpegts_table_add(mm, + DVB_ATSC_STT_BASE, + DVB_ATSC_STT_MASK, + atsc_stt_callback, + NULL, + "stt", + LS_TBL_ATSC, + MT_QUICKREQ | MT_CRC | MT_RECORD, + DVB_ATSC_STT_PID, + MPS_WEIGHT_STT); } -void -psi_tables_install ( mpegts_input_t *mi, mpegts_mux_t *mm, - dvb_fe_delivery_system_t delsys) -{ +void psi_tables_install(mpegts_input_t* mi, mpegts_mux_t* mm, dvb_fe_delivery_system_t delsys) { if (mi == NULL || mm == NULL) return; psi_tables_default(mm); switch (delsys) { - case DVB_SYS_DVBC_ANNEX_A: - case DVB_SYS_DVBC_ANNEX_C: - case DVB_SYS_DVBT: - case DVB_SYS_DVBT2: - case DVB_SYS_DVBS: - case DVB_SYS_DVBS2: - case DVB_SYS_ISDBT: - case DVB_SYS_ISDBC: - case DVB_SYS_ISDBS: - case DVB_SYS_DAB: - psi_tables_dvb(mm); - break; - case DVB_SYS_TURBO: - case DVB_SYS_ATSC: - case DVB_SYS_ATSCMH: - psi_tables_atsc_t(mm); - break; - case DVB_SYS_DVBC_ANNEX_B: -#if ENABLE_MPEGTS_DVB - if (idnode_is_instance(&mm->mm_id, &dvb_mux_dvbc_class)) + case DVB_SYS_DVBC_ANNEX_A: + case DVB_SYS_DVBC_ANNEX_C: + case DVB_SYS_DVBT: + case DVB_SYS_DVBT2: + case DVB_SYS_DVBS: + case DVB_SYS_DVBS2: + case DVB_SYS_ISDBT: + case DVB_SYS_ISDBC: + case DVB_SYS_ISDBS: + case DVB_SYS_DAB: psi_tables_dvb(mm); - else + break; + case DVB_SYS_TURBO: + case DVB_SYS_ATSC: + case DVB_SYS_ATSCMH: + psi_tables_atsc_t(mm); + break; + case DVB_SYS_DVBC_ANNEX_B: +#if ENABLE_MPEGTS_DVB + if (idnode_is_instance(&mm->mm_id, &dvb_mux_dvbc_class)) + psi_tables_dvb(mm); + else #endif + psi_tables_atsc_c(mm); + break; + case DVB_SYS_NONE: + case DVB_SYS_DVBH: + case DVB_SYS_DTMB: + case DVB_SYS_CMMB: + case DVB_SYS_DSS: + break; + case DVB_SYS_ATSC_ALL: psi_tables_atsc_c(mm); - break; - case DVB_SYS_NONE: - case DVB_SYS_DVBH: - case DVB_SYS_DTMB: - case DVB_SYS_CMMB: - case DVB_SYS_DSS: - break; - case DVB_SYS_ATSC_ALL: - psi_tables_atsc_c(mm); - psi_tables_atsc_t(mm); - break; - case DVB_SYS_UNKNOWN: - psi_tables_dvb(mm); - psi_tables_atsc_c(mm); - psi_tables_atsc_t(mm); - break; - break; + psi_tables_atsc_t(mm); + break; + case DVB_SYS_UNKNOWN: + psi_tables_dvb(mm); + psi_tables_atsc_c(mm); + psi_tables_atsc_t(mm); + break; + break; } mpegts_mux_update_pids(mm); diff --git a/src/input/mpegts/dvb_psi_hbbtv.c b/src/input/mpegts/dvb_psi_hbbtv.c index fd64a69c7..cab5dd04f 100644 --- a/src/input/mpegts/dvb_psi_hbbtv.c +++ b/src/input/mpegts/dvb_psi_hbbtv.c @@ -24,24 +24,21 @@ /** * Extract Hbbtv */ -htsmsg_t * -dvb_psi_parse_hbbtv - (mpegts_psi_table_t *mt, const uint8_t *buf, int len, int *_sect) -{ - static const char *visibility_table[4] = { - "none", - "apps", - "reserved", - "all", +htsmsg_t* dvb_psi_parse_hbbtv(mpegts_psi_table_t* mt, const uint8_t* buf, int len, int* _sect) { + static const char* visibility_table[4] = { + "none", + "apps", + "reserved", + "all", }; - mpegts_psi_table_state_t *tst = NULL; - int r, sect, last, ver, l, l2, l3, dllen, dlen, flags; - uint8_t tableid = buf[0], dtag; - const uint8_t *p, *dlptr, *dptr; - uint16_t app_type, app_id, protocol_id; - uint32_t org_id; - char title[256], name[256], location[256], *str; - htsmsg_t *map, *apps = NULL, *titles = NULL; + mpegts_psi_table_state_t* tst = NULL; + int r, sect, last, ver, l, l2, l3, dllen, dlen, flags; + uint8_t tableid = buf[0], dtag; + const uint8_t * p, *dlptr, *dptr; + uint16_t app_type, app_id, protocol_id; + uint32_t org_id; + char title[256], name[256], location[256], *str; + htsmsg_t * map, *apps = NULL, *titles = NULL; if (tableid != 0x74 || len < 16) return NULL; @@ -49,42 +46,57 @@ dvb_psi_parse_hbbtv if (app_type & 1) /* testing */ return NULL; - r = dvb_table_begin(mt, buf + 3, len - 3, - tableid, app_type, 5, &tst, §, &last, &ver, 0); - if (r != 1) return NULL; + r = dvb_table_begin(mt, buf + 3, len - 3, tableid, app_type, 5, &tst, §, &last, &ver, 0); + if (r != 1) + return NULL; p = buf; l = len; DVB_DESC_FOREACH(mt, p, l, 8, dlptr, dllen, dtag, dlen, dptr) { tvhtrace(mt->mt_subsys, "%s: common dtag %02X dlen %d", mt->mt_name, dtag, dlen); - }} + } +} - l2 = ((p[0] << 8) | p[1]) & 0xfff; - p += 2; - l += 2; - while (l2 >= 9) { - org_id = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; - app_id = (p[4] << 8) | p[5]; - tvhtrace(mt->mt_subsys, "%s: app org %08X id %04X control %02X", mt->mt_name, org_id, app_id, p[6]); - l2 -= 9; - title[0] = name[0] = location[0] = '\0'; - titles = NULL; - flags = 0; - DVB_DESC_FOREACH(mt, p, l, 7, dlptr, dllen, dtag, dlen, dptr) { - l2 -= dlen + 2; - tvhtrace(mt->mt_subsys, "%s: dtag %02X dlen %d", mt->mt_name, dtag, dlen); - switch (dtag) { +l2 = ((p[0] << 8) | p[1]) & 0xfff; +p += 2; +l += 2; +while (l2 >= 9) { + org_id = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; + app_id = (p[4] << 8) | p[5]; + tvhtrace(mt->mt_subsys, + "%s: app org %08X id %04X control %02X", + mt->mt_name, + org_id, + app_id, + p[6]); + l2 -= 9; + title[0] = name[0] = location[0] = '\0'; + titles = NULL; + flags = 0; + DVB_DESC_FOREACH(mt, p, l, 7, dlptr, dllen, dtag, dlen, dptr) { + l2 -= dlen + 2; + tvhtrace(mt->mt_subsys, "%s: dtag %02X dlen %d", mt->mt_name, dtag, dlen); + switch (dtag) { case DVB_DESC_APP: - l3 = *dptr++; dlen--; - if (l3 > dlen || (l3 % 5)) goto dvberr; + l3 = *dptr++; + dlen--; + if (l3 > dlen || (l3 % 5)) + goto dvberr; while (dlen >= 5 && l3 >= 5) { - tvhtrace(mt->mt_subsys, "%s: profile %04X %d.%d.%d", mt->mt_name, (dptr[0] << 8) | dptr[1], dptr[2], dptr[3], dptr[4]); + tvhtrace(mt->mt_subsys, + "%s: profile %04X %d.%d.%d", + mt->mt_name, + (dptr[0] << 8) | dptr[1], + dptr[2], + dptr[3], + dptr[4]); dptr += 5; dlen -= 5; l3 -= 5; } - if (dlen < 3) goto dvberr; + if (dlen < 3) + goto dvberr; flags = dptr[0]; tvhtrace(mt->mt_subsys, "%s: flags %02X prio %02X", mt->mt_name, dptr[0], dptr[1]); dptr += 2; @@ -95,12 +107,20 @@ dvb_psi_parse_hbbtv } break; case DVB_DESC_APP_NAME: - if(titles != NULL) htsmsg_destroy(titles); + if (titles != NULL) + htsmsg_destroy(titles); titles = htsmsg_create_list(); while (dlen > 4) { r = dvb_get_string_with_len(title, sizeof(title), dptr + 3, dlen - 3, "UTF-8", NULL); - if (r < 0) goto dvberr; - tvhtrace(mt->mt_subsys, "%s: lang '%c%c%c' name '%s'", mt->mt_name, dptr[0], dptr[1], dptr[2], title); + if (r < 0) + goto dvberr; + tvhtrace(mt->mt_subsys, + "%s: lang '%c%c%c' name '%s'", + mt->mt_name, + dptr[0], + dptr[1], + dptr[2], + title); map = htsmsg_create_map(); htsmsg_add_str(map, "name", title); memcpy(title, dptr, 3); @@ -112,13 +132,20 @@ dvb_psi_parse_hbbtv } break; case DVB_DESC_APP_TRANSPORT: - if (dlen < 4) goto dvberr; + if (dlen < 4) + goto dvberr; protocol_id = (dptr[0] << 8) | dptr[1]; - tvhtrace(mt->mt_subsys, "%s: protocol_id %04X transport protocol label %02X", mt->mt_name, protocol_id, dptr[2]); - dptr += 3; dlen -= 3; + tvhtrace(mt->mt_subsys, + "%s: protocol_id %04X transport protocol label %02X", + mt->mt_name, + protocol_id, + dptr[2]); + dptr += 3; + dlen -= 3; if (protocol_id == 0x0003) { r = dvb_get_string_with_len(name, sizeof(name), dptr, dlen, "UTF-8", NULL); - if (r < 0) goto dvberr; + if (r < 0) + goto dvberr; tvhtrace(mt->mt_subsys, "%s: http '%s'", mt->mt_name, name); } else { while (dlen-- > 0) { @@ -129,50 +156,49 @@ dvb_psi_parse_hbbtv break; case DVB_DESC_APP_SIMPLE_LOCATION: r = dvb_get_string(location, sizeof(location), dptr, dlen, "UTF-8", NULL); - if (r < 0) goto dvberr; + if (r < 0) + goto dvberr; tvhtrace(mt->mt_subsys, "%s: simple location '%s'", mt->mt_name, location); break; - } - }} - if (titles && name[0] && location[0]) { - map = htsmsg_create_map(); - htsmsg_add_msg(map, "title", titles); - titles = NULL; - str = malloc(strlen(name) + strlen(location) + 1); - strcpy(str, name); - strcat(str, location); - htsmsg_add_str(map, "url", str); - free(str); - if (apps == NULL) - apps = htsmsg_create_list(); - htsmsg_add_str(map, "visibility", visibility_table[(flags >> 5) & 3]); - htsmsg_add_msg(apps, NULL, map); - } else { - htsmsg_destroy(titles); - titles = NULL; } } - if (l2 != 0) - goto dvberr; +} +if (titles && name[0] && location[0]) { + map = htsmsg_create_map(); + htsmsg_add_msg(map, "title", titles); + titles = NULL; + str = malloc(strlen(name) + strlen(location) + 1); + strcpy(str, name); + strcat(str, location); + htsmsg_add_str(map, "url", str); + free(str); + if (apps == NULL) + apps = htsmsg_create_list(); + htsmsg_add_str(map, "visibility", visibility_table[(flags >> 5) & 3]); + htsmsg_add_msg(apps, NULL, map); +} else { + htsmsg_destroy(titles); + titles = NULL; +} +} +if (l2 != 0) + goto dvberr; - dvb_table_end(mt, tst, sect); - if (_sect) - *_sect = sect; - return apps; +dvb_table_end(mt, tst, sect); +if (_sect) + *_sect = sect; +return apps; -dvberr: - htsmsg_destroy(apps); - htsmsg_destroy(titles); - return NULL; +dvberr: htsmsg_destroy(apps); +htsmsg_destroy(titles); +return NULL; } -void -dvb_psi_hbbtv_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) -{ - elementary_stream_t *st = (elementary_stream_t *)mt->mt_opaque; - service_t *t = st->es_service; - int sect; - htsmsg_t *apps = dvb_psi_parse_hbbtv(mt, buf, len, §); +void dvb_psi_hbbtv_cb(mpegts_psi_table_t* mt, const uint8_t* buf, int len) { + elementary_stream_t* st = (elementary_stream_t*)mt->mt_opaque; + service_t* t = st->es_service; + int sect; + htsmsg_t* apps = dvb_psi_parse_hbbtv(mt, buf, len, §); if (apps == NULL) return; if (t->s_hbbtv == NULL) @@ -185,9 +211,7 @@ dvb_psi_hbbtv_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) } } -int -dvb_hbbtv_callback(mpegts_table_t *mt, const uint8_t *buf, int len, int tableid) -{ - dvb_psi_hbbtv_cb((mpegts_psi_table_t *)mt, buf, len); +int dvb_hbbtv_callback(mpegts_table_t* mt, const uint8_t* buf, int len, int tableid) { + dvb_psi_hbbtv_cb((mpegts_psi_table_t*)mt, buf, len); return 0; } diff --git a/src/input/mpegts/dvb_psi_hbbtv.h b/src/input/mpegts/dvb_psi_hbbtv.h index 3946d96ec..2d1507c7a 100644 --- a/src/input/mpegts/dvb_psi_hbbtv.h +++ b/src/input/mpegts/dvb_psi_hbbtv.h @@ -28,12 +28,10 @@ struct mpegts_table; * HBBTV processing */ -htsmsg_t *dvb_psi_parse_hbbtv - (struct mpegts_psi_table *mt, const uint8_t *buf, int len, int *_sect); +htsmsg_t* dvb_psi_parse_hbbtv(struct mpegts_psi_table* mt, const uint8_t* buf, int len, int* _sect); -void dvb_psi_hbbtv_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len); +void dvb_psi_hbbtv_cb(mpegts_psi_table_t* mt, const uint8_t* buf, int len); -int dvb_hbbtv_callback - (struct mpegts_table *mt, const uint8_t *buf, int len, int tableid); +int dvb_hbbtv_callback(struct mpegts_table* mt, const uint8_t* buf, int len, int tableid); #endif diff --git a/src/input/mpegts/dvb_psi_lib.c b/src/input/mpegts/dvb_psi_lib.c index c6d24b45e..0d65f8b1c 100644 --- a/src/input/mpegts/dvb_psi_lib.c +++ b/src/input/mpegts/dvb_psi_lib.c @@ -26,32 +26,30 @@ * *************************************************************************/ static const int dvb_servicetype_map[][2] = { - { 0x01, ST_SDTV }, /* SDTV (MPEG2) */ - { 0x02, ST_RADIO }, - { 0x11, ST_HDTV }, /* HDTV (MPEG2) */ - { 0x16, ST_SDTV }, /* Advanced codec SDTV */ - { 0x17, ST_SDTV }, /* Advanced codec SDTV - NVOD time-shifted */ - { 0x18, ST_SDTV }, /* Advanced codec SDTV - NVOD reference */ - { 0x19, ST_HDTV }, /* Advanced codec HDTV */ - { 0x1A, ST_HDTV }, /* Advanced codec HDTV - NVOD time-shifted */ - { 0x1B, ST_HDTV }, /* Advanced codec HDTV - NVOD reference */ - { 0x1C, ST_HDTV }, /* Advanced codec HDTV - plano-stereoscopic */ - { 0x1D, ST_HDTV }, /* Advanced codec HDTV - plano-stereoscopic - NVOD time-shifted */ - { 0x1E, ST_HDTV }, /* Advanced codec HDTV - plano-stereoscopic - NVOID reference */ - { 0x1F, ST_UHDTV }, /* HEVC (assume all HEVC content is UHD?) */ - { 0x80, ST_SDTV }, /* NET POA - Cabo SDTV */ - { 0x91, ST_HDTV }, /* Bell TV HDTV */ - { 0x96, ST_SDTV }, /* Bell TV SDTV */ - { 0xA0, ST_HDTV }, /* Bell TV tiered HDTV */ - { 0xA4, ST_HDTV }, /* DN HDTV */ - { 0xA6, ST_HDTV }, /* Bell TV tiered HDTV */ - { 0xA8, ST_SDTV }, /* DN advanced SDTV */ - { 0xD3, ST_SDTV }, /* SKY TV SDTV */ + {0x01, ST_SDTV}, /* SDTV (MPEG2) */ + {0x02, ST_RADIO}, + {0x11, ST_HDTV}, /* HDTV (MPEG2) */ + {0x16, ST_SDTV}, /* Advanced codec SDTV */ + {0x17, ST_SDTV}, /* Advanced codec SDTV - NVOD time-shifted */ + {0x18, ST_SDTV}, /* Advanced codec SDTV - NVOD reference */ + {0x19, ST_HDTV}, /* Advanced codec HDTV */ + {0x1A, ST_HDTV}, /* Advanced codec HDTV - NVOD time-shifted */ + {0x1B, ST_HDTV}, /* Advanced codec HDTV - NVOD reference */ + {0x1C, ST_HDTV}, /* Advanced codec HDTV - plano-stereoscopic */ + {0x1D, ST_HDTV}, /* Advanced codec HDTV - plano-stereoscopic - NVOD time-shifted */ + {0x1E, ST_HDTV}, /* Advanced codec HDTV - plano-stereoscopic - NVOID reference */ + {0x1F, ST_UHDTV}, /* HEVC (assume all HEVC content is UHD?) */ + {0x80, ST_SDTV}, /* NET POA - Cabo SDTV */ + {0x91, ST_HDTV}, /* Bell TV HDTV */ + {0x96, ST_SDTV}, /* Bell TV SDTV */ + {0xA0, ST_HDTV}, /* Bell TV tiered HDTV */ + {0xA4, ST_HDTV}, /* DN HDTV */ + {0xA6, ST_HDTV}, /* Bell TV tiered HDTV */ + {0xA8, ST_SDTV}, /* DN advanced SDTV */ + {0xD3, ST_SDTV}, /* SKY TV SDTV */ }; -int -dvb_servicetype_lookup ( int t ) -{ +int dvb_servicetype_lookup(int t) { int i; for (i = 0; i < ARRAY_SIZE(dvb_servicetype_map); i++) { if (dvb_servicetype_map[i][0] == t) @@ -67,36 +65,37 @@ dvb_servicetype_lookup ( int t ) /* * Section assembly */ -static int -mpegts_psi_section_reassemble0 - ( mpegts_psi_table_t *mt, const char *logpref, - const uint8_t *data, - int len, int start, int crc, - mpegts_psi_section_callback_t cb, void *opaque) -{ - uint8_t *p = mt->mt_sect.ps_data; - int excess, tsize; - - if(len <= 0) +static int mpegts_psi_section_reassemble0(mpegts_psi_table_t* mt, + const char* logpref, + const uint8_t* data, + int len, + int start, + int crc, + mpegts_psi_section_callback_t cb, + void* opaque) { + uint8_t* p = mt->mt_sect.ps_data; + int excess, tsize; + + if (len <= 0) return -1; - if(start) { + if (start) { /* Payload unit start indicator */ mt->mt_sect.ps_offset = 0; - mt->mt_sect.ps_lock = 1; - if((data[0] & mt->mt_sect.ps_mask) != mt->mt_sect.ps_table) { - if(len >= 3) { + mt->mt_sect.ps_lock = 1; + if ((data[0] & mt->mt_sect.ps_mask) != mt->mt_sect.ps_table) { + if (len >= 3) { tsize = 3 + (((data[1] & 0xf) << 8) | data[2]); - if(len >= tsize) + if (len >= tsize) return tsize; } } } - if(!mt->mt_sect.ps_lock) + if (!mt->mt_sect.ps_lock) return -1; - if(mt->mt_sect.ps_offset + len > MPEGTS_PSI_SECTION_SIZE) { + if (mt->mt_sect.ps_offset + len > MPEGTS_PSI_SECTION_SIZE) { tvherror(mt->mt_subsys, "PSI section overflow"); return -1; } @@ -104,27 +103,31 @@ mpegts_psi_section_reassemble0 memcpy(p + mt->mt_sect.ps_offset, data, len); mt->mt_sect.ps_offset += len; - if(mt->mt_sect.ps_offset < 3) { + if (mt->mt_sect.ps_offset < 3) { /* We don't know the total length yet */ return len; } tsize = 3 + (((p[1] & 0xf) << 8) | p[2]); - if(mt->mt_sect.ps_offset < tsize) + if (mt->mt_sect.ps_offset < tsize) return len; // Not there yet - if(p[0] == 0x72) { /* stuffing section */ - cb = NULL; + if (p[0] == 0x72) { /* stuffing section */ + cb = NULL; crc = 0; - } else if((p[0] & mt->mt_sect.ps_mask) != mt->mt_sect.ps_table) { + } else if ((p[0] & mt->mt_sect.ps_mask) != mt->mt_sect.ps_table) { cb = NULL; } - if(crc && tvh_crc32(p, tsize, 0xffffffff)) { + if (crc && tvh_crc32(p, tsize, 0xffffffff)) { if (cb && tvhlog_limit(&mt->mt_err_log, 10)) { - tvhwarn(mt->mt_subsys, "%s: %s: invalid checksum (len %i, errors %zi)", - mt->mt_name, logpref, tsize, mt->mt_err_log.count); + tvhwarn(mt->mt_subsys, + "%s: %s: invalid checksum (len %i, errors %zi)", + mt->mt_name, + logpref, + tsize, + mt->mt_err_log.count); } return -1; } @@ -140,33 +143,38 @@ mpegts_psi_section_reassemble0 /** * */ -void -mpegts_psi_section_reassemble - (mpegts_psi_table_t *mt, const char *logprefix, - const uint8_t *tsb, int crc, - mpegts_psi_section_callback_t cb, void *opaque) -{ - int pusi = tsb[1] & 0x40; - uint8_t cc = tsb[3]; - int off = cc & 0x20 ? tsb[4] + 5 : 4; - int r; +void mpegts_psi_section_reassemble(mpegts_psi_table_t* mt, + const char* logprefix, + const uint8_t* tsb, + int crc, + mpegts_psi_section_callback_t cb, + void* opaque) { + int pusi = tsb[1] & 0x40; + uint8_t cc = tsb[3]; + int off = cc & 0x20 ? tsb[4] + 5 : 4; + int r; if (cc & 0x10) { if (mt->mt_sect.ps_cc != -1 && mt->mt_sect.ps_cc != (cc & 0x0f)) { uint16_t pid = ((tsb[1] & 0x1f) << 8) | tsb[2]; - tvhdebug(mt->mt_subsys, "%s: %s: PID %04X CC error %d != %d", - mt->mt_name, logprefix, pid, cc & 0x0f, mt->mt_sect.ps_cc); + tvhdebug(mt->mt_subsys, + "%s: %s: PID %04X CC error %d != %d", + mt->mt_name, + logprefix, + pid, + cc & 0x0f, + mt->mt_sect.ps_cc); mt->mt_sect.ps_lock = 0; } mt->mt_sect.ps_cc = (cc + 1) & 0x0f; } - if(off >= 188) { + if (off >= 188) { mt->mt_sect.ps_lock = 0; return; } - if(pusi) { + if (pusi) { uint8_t len2 = tsb[off++]; uint8_t off2 = off; off += len2; @@ -181,9 +189,8 @@ mpegts_psi_section_reassemble } } - while(off < 188) { - r = mpegts_psi_section_reassemble0(mt, logprefix, tsb + off, 188 - off, pusi, crc, - cb, opaque); + while (off < 188) { + r = mpegts_psi_section_reassemble0(mt, logprefix, tsb + off, 188 - off, pusi, crc, cb, opaque); if (r < 0) goto wrong_state; off += r; @@ -198,9 +205,7 @@ wrong_state: * */ -static int sect_cmp - ( mpegts_psi_table_state_t *a, mpegts_psi_table_state_t *b ) -{ +static int sect_cmp(mpegts_psi_table_state_t* a, mpegts_psi_table_state_t* b) { if (a->tableid != b->tableid) return a->tableid - b->tableid; if (a->extraid < b->extraid) @@ -211,24 +216,22 @@ static int sect_cmp } static void -mpegts_table_state_reset - ( mpegts_psi_table_t *mt, mpegts_psi_table_state_t *st, int last ) -{ +mpegts_table_state_reset(mpegts_psi_table_t* mt, mpegts_psi_table_state_t* st, int last) { int i; mt->mt_finished = 0; - st->complete = 0; - st->version = MPEGTS_PSI_VERSION_NONE; - st->last = last; + st->complete = 0; + st->version = MPEGTS_PSI_VERSION_NONE; + st->last = last; memset(st->sections, 0, sizeof(st->sections)); for (i = 0; i < last / 32; i++) st->sections[i] = 0xFFFFFFFF; st->sections[last / 32] = 0xFFFFFFFF << (31 - (last % 32)); } -static void -mpegts_table_state_restart - ( mpegts_psi_table_t *mt, mpegts_psi_table_state_t *st, int last, int ver ) -{ +static void mpegts_table_state_restart(mpegts_psi_table_t* mt, + mpegts_psi_table_state_t* st, + int last, + int ver) { if (st->complete == 2) mt->mt_complete--; if (st->complete) @@ -237,22 +240,20 @@ mpegts_table_state_restart st->version = ver; } -static mpegts_psi_table_state_t * -mpegts_table_state_find - ( mpegts_psi_table_t *mt, int tableid, uint64_t extraid, int last ) -{ +static mpegts_psi_table_state_t* +mpegts_table_state_find(mpegts_psi_table_t* mt, int tableid, uint64_t extraid, int last) { mpegts_psi_table_state_t *st, *st2, st_cmp; /* Find state */ st_cmp.tableid = tableid; st_cmp.extraid = extraid; - st = RB_FIND(&mt->mt_state, &st_cmp, link, sect_cmp); + st = RB_FIND(&mt->mt_state, &st_cmp, link, sect_cmp); if (st) return st; - st = calloc(1, sizeof(*st)); + st = calloc(1, sizeof(*st)); st->tableid = tableid; st->extraid = extraid; - st2 = RB_INSERT_SORTED(&mt->mt_state, st, link, sect_cmp); + st2 = RB_INSERT_SORTED(&mt->mt_state, st, link, sect_cmp); assert(st2 == NULL); mt->mt_incomplete++; mpegts_table_state_reset(mt, st, last); @@ -262,31 +263,33 @@ mpegts_table_state_find /* * End table */ -static int -dvb_table_complete - (mpegts_psi_table_t *mt) -{ +static int dvb_table_complete(mpegts_psi_table_t* mt) { if (mt->mt_incomplete || !mt->mt_complete) { - int total = 0; - mpegts_psi_table_state_t *st; - RB_FOREACH(st, &mt->mt_state, link) + int total = 0; + mpegts_psi_table_state_t* st; + RB_FOREACH (st, &mt->mt_state, link) total++; - tvhtrace(mt->mt_subsys, "%s: incomplete %d complete %d total %d", - mt->mt_name, mt->mt_incomplete, mt->mt_complete, total); + tvhtrace(mt->mt_subsys, + "%s: incomplete %d complete %d total %d", + mt->mt_name, + mt->mt_incomplete, + mt->mt_complete, + total); return 2; } if (!mt->mt_finished) - tvhdebug(mt->mt_subsys, "%s: completed pid %d table %08X / %08x", - mt->mt_name, mt->mt_pid, mt->mt_table, mt->mt_mask); + tvhdebug(mt->mt_subsys, + "%s: completed pid %d table %08X / %08x", + mt->mt_name, + mt->mt_pid, + mt->mt_table, + mt->mt_mask); mt->mt_finished = 1; return 0; } -int -dvb_table_end - (mpegts_psi_table_t *mt, mpegts_psi_table_state_t *st, int sect) -{ - int sa, sb; +int dvb_table_end(mpegts_psi_table_t* mt, mpegts_psi_table_state_t* st, int sect) { + int sa, sb; uint32_t rem; if (st && !st->complete) { assert(sect >= 0 && sect <= 255); @@ -297,9 +300,13 @@ dvb_table_end rem = 0; for (sa = 0; sa < 8; sa++) rem |= st->sections[sa]; - if (rem) return 1; - tvhtrace(mt->mt_subsys, "%s: tableid %02X extraid %016" PRIx64 " completed", - mt->mt_name, st->tableid, st->extraid); + if (rem) + return 1; + tvhtrace(mt->mt_subsys, + "%s: tableid %02X extraid %016" PRIx64 " completed", + mt->mt_name, + st->tableid, + st->extraid); st->complete = 1; mt->mt_incomplete--; return dvb_table_complete(mt); @@ -312,15 +319,19 @@ dvb_table_end /* * Begin table */ -int -dvb_table_begin - (mpegts_psi_table_t *mt, const uint8_t *ptr, int len, - int tableid, uint64_t extraid, int minlen, - mpegts_psi_table_state_t **ret, int *sect, int *last, int *ver, - time_t interval) -{ +int dvb_table_begin(mpegts_psi_table_t* mt, + const uint8_t* ptr, + int len, + int tableid, + uint64_t extraid, + int minlen, + mpegts_psi_table_state_t** ret, + int* sect, + int* last, + int* ver, + time_t interval) { mpegts_psi_table_state_t *st, *st2; - uint32_t sa, sb; + uint32_t sa, sb; /* Not long enough */ if (len < minlen) { @@ -329,11 +340,16 @@ dvb_table_begin } /* Ignore next */ - if((ptr[2] & 1) == 0) + if ((ptr[2] & 1) == 0) return -1; - tvhtrace(mt->mt_subsys, "%s: pid %02X tableid %02X extraid %016" PRIx64 " len %d", - mt->mt_name, mt->mt_pid, tableid, extraid, len); + tvhtrace(mt->mt_subsys, + "%s: pid %02X tableid %02X extraid %016" PRIx64 " len %d", + mt->mt_name, + mt->mt_pid, + tableid, + extraid, + len); /* Section info */ if (sect && ret) { @@ -341,8 +357,16 @@ dvb_table_begin *last = ptr[4]; *ver = (ptr[2] >> 1) & 0x1F; *ret = st = mpegts_table_state_find(mt, tableid, extraid, *last); - tvhtrace(mt->mt_subsys, "%s: section %d last %d ver %d (ver %d st %d incomp %d comp %d)", - mt->mt_name, *sect, *last, *ver, st->version, st->complete, mt->mt_incomplete, mt->mt_complete); + tvhtrace(mt->mt_subsys, + "%s: section %d last %d ver %d (ver %d st %d incomp %d comp %d)", + mt->mt_name, + *sect, + *last, + *ver, + st->version, + st->complete, + mt->mt_incomplete, + mt->mt_complete); #if 0 // FIXME, cannot be enabled in this form /* Ignore previous version */ @@ -355,11 +379,10 @@ dvb_table_begin #endif /* Interval check */ - if (interval && mt->mt_last_complete && - mt->mt_last_complete + interval < gclk()) { + if (interval && mt->mt_last_complete && mt->mt_last_complete + interval < gclk()) { mt->mt_last_complete = 0; tvhtrace(mt->mt_subsys, "%s: time interval exceeded, complete restart", mt->mt_name); - RB_FOREACH(st2, &mt->mt_state, link) + RB_FOREACH (st2, &mt->mt_state, link) if (st != st2) mpegts_table_state_restart(mt, st2, st2->last, MPEGTS_PSI_VERSION_NONE); mpegts_table_state_restart(mt, st, *last, *ver); @@ -403,14 +426,12 @@ dvb_table_begin return 1; } -void -dvb_table_reset(mpegts_psi_table_t *mt) -{ - mpegts_psi_table_state_t *st; +void dvb_table_reset(mpegts_psi_table_t* mt) { + mpegts_psi_table_state_t* st; tvhtrace(mt->mt_subsys, "%s: pid %02X complete reset", mt->mt_name, mt->mt_pid); - mt->mt_incomplete = 0; - mt->mt_complete = 0; + mt->mt_incomplete = 0; + mt->mt_complete = 0; mt->mt_last_complete = 0; while ((st = RB_FIRST(&mt->mt_state)) != NULL) { RB_REMOVE(&mt->mt_state, st, link); @@ -418,10 +439,8 @@ dvb_table_reset(mpegts_psi_table_t *mt) } } -void -dvb_table_release(mpegts_psi_table_t *mt) -{ - mpegts_psi_table_state_t *st; +void dvb_table_release(mpegts_psi_table_t* mt) { + mpegts_psi_table_state_t* st; while ((st = RB_FIRST(&mt->mt_state))) { RB_REMOVE(&mt->mt_state, st, link); @@ -433,65 +452,63 @@ dvb_table_release(mpegts_psi_table_t *mt) * */ -void dvb_table_parse_init - ( mpegts_psi_table_t *mt, const char *name, int subsys, int pid, - uint8_t table, uint8_t mask, void *opaque ) -{ +void dvb_table_parse_init(mpegts_psi_table_t* mt, + const char* name, + int subsys, + int pid, + uint8_t table, + uint8_t mask, + void* opaque) { memset(mt, 0, sizeof(*mt)); - mt->mt_name = strdup(name); - mt->mt_subsys = subsys; - mt->mt_opaque = opaque; - mt->mt_pid = pid; - mt->mt_sect.ps_cc = -1; + mt->mt_name = strdup(name); + mt->mt_subsys = subsys; + mt->mt_opaque = opaque; + mt->mt_pid = pid; + mt->mt_sect.ps_cc = -1; mt->mt_sect.ps_table = table; - mt->mt_sect.ps_mask = mask; + mt->mt_sect.ps_mask = mask; } -void dvb_table_parse_reinit_input - ( mpegts_psi_table_t *mt ) -{ +void dvb_table_parse_reinit_input(mpegts_psi_table_t* mt) { dvb_table_release(mt); mt->mt_last_complete = 0; mt->mt_complete = mt->mt_incomplete = 0; - mt->mt_finished = 0; - mt->mt_sect.ps_cc = -1; - mt->mt_sect.ps_offset = 0; - mt->mt_sect.ps_lock = 0; + mt->mt_finished = 0; + mt->mt_sect.ps_cc = -1; + mt->mt_sect.ps_offset = 0; + mt->mt_sect.ps_lock = 0; } -void dvb_table_parse_reinit_output - ( mpegts_psi_table_t *mt ) -{ +void dvb_table_parse_reinit_output(mpegts_psi_table_t* mt) { mt->mt_sect.ps_cco = 0; } -void dvb_table_parse_done( mpegts_psi_table_t *mt ) -{ +void dvb_table_parse_done(mpegts_psi_table_t* mt) { dvb_table_release(mt); free(mt->mt_name); mt->mt_name = NULL; } struct psi_parse { - mpegts_psi_table_t *mt; + mpegts_psi_table_t* mt; mpegts_psi_parse_callback_t cb; - int full; + int full; }; -static void -dvb_table_parse_cb( const uint8_t *sec, size_t len, void *opaque ) -{ - struct psi_parse *parse = opaque; +static void dvb_table_parse_cb(const uint8_t* sec, size_t len, void* opaque) { + struct psi_parse* parse = opaque; parse->cb(parse->mt, sec + parse->full, len - parse->full); } -void dvb_table_parse - (mpegts_psi_table_t *mt, const char *logprefix, - const uint8_t *tsb, int len, - int crc, int full, mpegts_psi_parse_callback_t cb) -{ - const uint8_t *end; +void dvb_table_parse(mpegts_psi_table_t* mt, + const char* logprefix, + const uint8_t* tsb, + int len, + int crc, + int full, + mpegts_psi_parse_callback_t cb) { + const uint8_t* end; struct psi_parse parse; parse.mt = mt; @@ -499,28 +516,24 @@ void dvb_table_parse parse.full = full ? 3 : 0; for (end = tsb + len; tsb < end; tsb += 188) - mpegts_psi_section_reassemble(mt, logprefix, tsb, crc, - dvb_table_parse_cb, &parse); + mpegts_psi_section_reassemble(mt, logprefix, tsb, crc, dvb_table_parse_cb, &parse); } -int dvb_table_append_crc32(uint8_t *dst, int off, int maxlen) -{ +int dvb_table_append_crc32(uint8_t* dst, int off, int maxlen) { if (off + 4 > maxlen) return -1; uint32_t crc = tvh_crc32(dst, off, 0xffffffff); - dst[off++] = crc >> 24; - dst[off++] = crc >> 16; - dst[off++] = crc >> 8; - dst[off++] = crc; + dst[off++] = crc >> 24; + dst[off++] = crc >> 16; + dst[off++] = crc >> 8; + dst[off++] = crc; return off; } -int dvb_table_remux - (mpegts_psi_table_t *mt, const uint8_t *buf, int len, uint8_t **out) -{ +int dvb_table_remux(mpegts_psi_table_t* mt, const uint8_t* buf, int len, uint8_t** out) { uint8_t *obuf, pusi; - int ol = 0, l, m; + int ol = 0, l, m; /* try to guess the output size here */ obuf = malloc(((len + 183 + 1 /* pusi */) / 184) * 188); @@ -533,8 +546,8 @@ int dvb_table_remux obuf[ol++] = 0x10 | ((mt->mt_sect.ps_cco++) & 0x0f); if (pusi) { obuf[ol++] = 0; - m = 183; - pusi = 0; + m = 183; + pusi = 0; } else { m = 184; } @@ -542,7 +555,7 @@ int dvb_table_remux memcpy(obuf + ol, buf, l); if (l < m) memset(obuf + ol + l, 0xff, m - l); - ol += m; + ol += m; len -= l; buf += l; } diff --git a/src/input/mpegts/dvb_psi_pmt.c b/src/input/mpegts/dvb_psi_pmt.c index df14f47ec..adeec52db 100644 --- a/src/input/mpegts/dvb_psi_pmt.c +++ b/src/input/mpegts/dvb_psi_pmt.c @@ -29,38 +29,37 @@ * PMT processing */ -static inline uint16_t -extract_2byte(const uint8_t *ptr) -{ +static inline uint16_t extract_2byte(const uint8_t* ptr) { return (((uint16_t)ptr[0]) << 8) | ptr[1]; } -static inline uint16_t -extract_pid(const uint8_t *ptr) -{ +static inline uint16_t extract_pid(const uint8_t* ptr) { return ((ptr[0] & 0x1f) << 8) | ptr[1]; } -static inline uint16_t -extract_svcid(const uint8_t *ptr) -{ +static inline uint16_t extract_svcid(const uint8_t* ptr) { return (ptr[0] << 8) | ptr[1]; } /** * Add a CA descriptor */ -static int -psi_desc_add_ca - (mpegts_table_t *mt, elementary_set_t *set, - uint16_t caid, uint32_t provid, uint16_t pid) -{ - elementary_stream_t *st; - caid_t *c; - int r = 0; - - tvhdebug(mt->mt_subsys, "%s: caid %04X (%s) provider %08X pid %04X", - mt->mt_name, caid, caid2name(caid), provid, pid); +static int psi_desc_add_ca(mpegts_table_t* mt, + elementary_set_t* set, + uint16_t caid, + uint32_t provid, + uint16_t pid) { + elementary_stream_t* st; + caid_t* c; + int r = 0; + + tvhdebug(mt->mt_subsys, + "%s: caid %04X (%s) provider %08X pid %04X", + mt->mt_name, + caid, + caid2name(caid), + provid, + pid); st = elementary_stream_find(set, pid); if (st == NULL || st->es_type != SCT_CA) { @@ -72,14 +71,14 @@ psi_desc_add_ca st->es_position = 0x40000; - LIST_FOREACH(c, &st->es_caids, link) { - if(c->caid == caid) { + LIST_FOREACH (c, &st->es_caids, link) { + if (c->caid == caid) { if (c->pid > 0 && c->pid != pid) r |= PMT_UPDATE_CAID_PID; - c->pid = pid; + c->pid = pid; c->delete_me = 0; - if(c->providerid != provid) { + if (c->providerid != provid) { c->providerid = provid; r |= PMT_UPDATE_CA_PROVIDER_CHANGE; } @@ -89,12 +88,12 @@ psi_desc_add_ca c = malloc(sizeof(caid_t)); - c->caid = caid; + c->caid = caid; c->providerid = provid; - c->use = 1; - c->pid = pid; - c->delete_me = 0; - c->filter = 0; + c->use = 1; + c->pid = pid; + c->delete_me = 0; + c->filter = 0; LIST_INSERT_HEAD(&st->es_caids, c, link); r |= PMT_UPDATE_NEW_CAID; return r; @@ -103,12 +102,9 @@ psi_desc_add_ca /** * Parser for CA descriptors */ -static int -psi_desc_ca - (mpegts_table_t *mt, elementary_set_t *set, const uint8_t *buffer, int size) -{ - int r = 0; - int i; +static int psi_desc_ca(mpegts_table_t* mt, elementary_set_t* set, const uint8_t* buffer, int size) { + int r = 0; + int i; uint32_t provid = 0; uint16_t caid, pid; @@ -116,51 +112,51 @@ psi_desc_ca return 0; caid = extract_2byte(buffer); - pid = extract_pid(buffer + 2); + pid = extract_pid(buffer + 2); switch (caid & 0xFF00) { - case 0x0100: // SECA/Mediaguard - if (size < 6) - return 0; - provid = extract_2byte(buffer + 4); + case 0x0100: // SECA/Mediaguard + if (size < 6) + return 0; + provid = extract_2byte(buffer + 4); - //Add extra providers, if any - for (i = 17; i < size; i += 15){ - uint16_t xpid = extract_pid(buffer + i); - uint16_t xprovid = extract_2byte(buffer + i + 2); + // Add extra providers, if any + for (i = 17; i < size; i += 15) { + uint16_t xpid = extract_pid(buffer + i); + uint16_t xprovid = extract_2byte(buffer + i + 2); - r |= psi_desc_add_ca(mt, set, caid, xprovid, xpid); - } - break; - case 0x0500:// Viaccess - for (i = 4; i + 5 <= size;) { - uint8_t nano = buffer[i++]; - uint8_t nanolen = buffer[i++]; - - if (nano == 0x14) { - provid = (buffer[i] << 16) | (buffer[i + 1] << 8) | (buffer[i + 2] & 0xf0); - break; + r |= psi_desc_add_ca(mt, set, caid, xprovid, xpid); } + break; + case 0x0500: // Viaccess + for (i = 4; i + 5 <= size;) { + uint8_t nano = buffer[i++]; + uint8_t nanolen = buffer[i++]; - i += nanolen; - } - break; - case 0x4a00: - if (caid == 0x4ad2)//streamguard - provid=0; - if (caid != 0x4aee && caid != 0x4ad2) { // Bulcrypt - provid = size < 5 ? 0 : buffer[4]; - } - break; - case 0x1800: // Nagra - if (size == 0x7) - provid = extract_2byte(buffer + 5); - else + if (nano == 0x14) { + provid = (buffer[i] << 16) | (buffer[i + 1] << 8) | (buffer[i + 2] & 0xf0); + break; + } + + i += nanolen; + } + break; + case 0x4a00: + if (caid == 0x4ad2) // streamguard + provid = 0; + if (caid != 0x4aee && caid != 0x4ad2) { // Bulcrypt + provid = size < 5 ? 0 : buffer[4]; + } + break; + case 0x1800: // Nagra + if (size == 0x7) + provid = extract_2byte(buffer + 5); + else + provid = 0; + break; + default: provid = 0; - break; - default: - provid = 0; - break; + break; } r |= psi_desc_add_ca(mt, set, caid, provid, pid); @@ -171,25 +167,26 @@ psi_desc_ca /** * Parser for teletext descriptor */ -static int -psi_desc_teletext(elementary_set_t *set, const uint8_t *ptr, int size, - int parent_pid, int *position) -{ - int r = 0; - const char *lang; - elementary_stream_t *st; - - while(size >= 5) { +static int psi_desc_teletext(elementary_set_t* set, + const uint8_t* ptr, + int size, + int parent_pid, + int* position) { + int r = 0; + const char* lang; + elementary_stream_t* st; + + while (size >= 5) { int page = (ptr[3] & 0x7 ?: 8) * 100 + (ptr[4] >> 4) * 10 + (ptr[4] & 0xf); int type = ptr[3] >> 3; - if(page > 0 && (type == 2 || type == 5)) { + if (page > 0 && (type == 2 || type == 5)) { // 2 = subtitle page, 5 = subtitle page [hearing impaired] // We put the teletext subtitle driven streams on a list of pids // higher than normal MPEG TS (0x2000 ++) int pid = DVB_TELETEXT_BASE + page; - + st = elementary_stream_find_parent(set, pid, parent_pid); if (st == NULL || st->es_type != SCT_TEXTSUB) { r |= PMT_UPDATE_NEW_STREAM; @@ -197,13 +194,13 @@ psi_desc_teletext(elementary_set_t *set, const uint8_t *ptr, int size, } lang = lang_code_get2((const char*)ptr, 3); - if(memcmp(st->es_lang,lang,3)) { + if (memcmp(st->es_lang, lang, 3)) { r |= PMT_UPDATE_LANGUAGE; memcpy(st->es_lang, lang, 4); } // Check es_delete_me so we only compute position once per PMT update - if(st->es_position != *position && st->es_delete_me) { + if (st->es_position != *position && st->es_delete_me) { st->es_position = *position; r |= PMT_REORDERED; } @@ -219,47 +216,45 @@ psi_desc_teletext(elementary_set_t *set, const uint8_t *ptr, int size, /** * */ -static void -dvb_pmt_hbbtv_table_remove(mpegts_mux_t *mm, elementary_stream_t *st) -{ - mpegts_table_t *mt = mpegts_table_find(mm, "hbbtv", st); +static void dvb_pmt_hbbtv_table_remove(mpegts_mux_t* mm, elementary_stream_t* st) { + mpegts_table_t* mt = mpegts_table_find(mm, "hbbtv", st); if (mt) mpegts_table_destroy(mt); } -/** +/** * PMT parser, from ISO 13818-1 and ETSI EN 300 468 */ -uint32_t -dvb_psi_parse_pmt - (mpegts_table_t *mt, const char *nicename, elementary_set_t *set, - const uint8_t *ptr, int len) -{ - uint16_t pcr_pid, pid; - uint8_t estype; - int dllen; - uint8_t dtag, dlen; +uint32_t dvb_psi_parse_pmt(mpegts_table_t* mt, + const char* nicename, + elementary_set_t* set, + const uint8_t* ptr, + int len) { + uint16_t pcr_pid, pid; + uint8_t estype; + int dllen; + uint8_t dtag, dlen; streaming_component_type_t hts_stream_type; - elementary_stream_t *st, *next; - uint32_t update = 0; - int composition_id; - int ancillary_id; - int version; - int position; - int tt_position; - int video_stream; - int rds_uecp; - int pcr_shared = 0; - const char *lang; - uint8_t audio_type, audio_version; - mpegts_mux_t *mux = mt->mt_mux; - caid_t *c, *cn; + elementary_stream_t * st, *next; + uint32_t update = 0; + int composition_id; + int ancillary_id; + int version; + int position; + int tt_position; + int video_stream; + int rds_uecp; + int pcr_shared = 0; + const char* lang; + uint8_t audio_type, audio_version; + mpegts_mux_t* mux = mt->mt_mux; + caid_t * c, *cn; version = (ptr[2] >> 1) & 0x1f; pcr_pid = extract_pid(ptr + 5); dllen = (ptr[7] & 0xf) << 8 | ptr[8]; - - if(set->set_pcr_pid != pcr_pid) { + + if (set->set_pcr_pid != pcr_pid) { set->set_pcr_pid = pcr_pid; update |= PMT_UPDATE_PCR; } @@ -269,38 +264,42 @@ dvb_psi_parse_pmt len -= 9; /* Mark all streams for deletion */ - TAILQ_FOREACH(st, &set->set_all, es_link) { + TAILQ_FOREACH (st, &set->set_all, es_link) { st->es_delete_me = 1; - LIST_FOREACH(c, &st->es_caids, link) + LIST_FOREACH (c, &st->es_caids, link) c->delete_me = 1; } // Common descriptors - while(dllen > 1) { + while (dllen > 1) { dtag = ptr[0]; dlen = ptr[1]; tvhlog_hexdump(mt->mt_subsys, ptr, dlen + 2); - len -= 2; ptr += 2; dllen -= 2; - if(dlen > len) + len -= 2; + ptr += 2; + dllen -= 2; + if (dlen > len) break; - switch(dtag) { - case DVB_DESC_CA: - update |= psi_desc_ca(mt, set, ptr, dlen); - break; + switch (dtag) { + case DVB_DESC_CA: + update |= psi_desc_ca(mt, set, ptr, dlen); + break; - default: - break; + default: + break; } - len -= dlen; ptr += dlen; dllen -= dlen; + len -= dlen; + ptr += dlen; + dllen -= dlen; } - while(len >= 5) { - estype = ptr[0]; - pid = extract_pid(ptr + 1); - dllen = (ptr[3] & 0xf) << 8 | ptr[4]; + while (len >= 5) { + estype = ptr[0]; + pid = extract_pid(ptr + 1); + dllen = (ptr[3] & 0xf) << 8 | ptr[4]; tvhdebug(mt->mt_subsys, "%s: pid %04X estype %d", mt->mt_name, pid, estype); tvhlog_hexdump(mt->mt_subsys, ptr, 5); @@ -308,159 +307,163 @@ dvb_psi_parse_pmt len -= 5; hts_stream_type = SCT_UNKNOWN; - composition_id = -1; - ancillary_id = -1; - rds_uecp = 0; - position = 0; - tt_position = 1000; - lang = NULL; - audio_type = 0; - audio_version = 0; - video_stream = 0; - - switch(estype) { - case 0x01: - case 0x02: - hts_stream_type = SCT_MPEG2VIDEO; - break; + composition_id = -1; + ancillary_id = -1; + rds_uecp = 0; + position = 0; + tt_position = 1000; + lang = NULL; + audio_type = 0; + audio_version = 0; + video_stream = 0; + + switch (estype) { + case 0x01: + case 0x02: + hts_stream_type = SCT_MPEG2VIDEO; + break; - case 0x03: - case 0x04: - hts_stream_type = SCT_MPEG2AUDIO; - audio_version = 2; /* Assume Layer 2 */ - break; + case 0x03: + case 0x04: + hts_stream_type = SCT_MPEG2AUDIO; + audio_version = 2; /* Assume Layer 2 */ + break; - case 0x05: - if (config.hbbtv) - hts_stream_type = SCT_HBBTV; - break; + case 0x05: + if (config.hbbtv) + hts_stream_type = SCT_HBBTV; + break; - case 0x06: - /* 0x06 is Chinese Cable TV AC-3 audio track */ - /* but mark it so only when no more descriptors exist */ - if (dllen <= 1 && mux->mm_pmt_ac3 == MM_AC3_PMT_06) - hts_stream_type = SCT_AC3; - break; + case 0x06: + /* 0x06 is Chinese Cable TV AC-3 audio track */ + /* but mark it so only when no more descriptors exist */ + if (dllen <= 1 && mux->mm_pmt_ac3 == MM_AC3_PMT_06) + hts_stream_type = SCT_AC3; + break; - case 0x0f: - hts_stream_type = SCT_MP4A; - break; + case 0x0f: + hts_stream_type = SCT_MP4A; + break; - case 0x11: - hts_stream_type = SCT_AAC; - break; + case 0x11: + hts_stream_type = SCT_AAC; + break; - case 0x1b: - hts_stream_type = SCT_H264; - break; + case 0x1b: + hts_stream_type = SCT_H264; + break; - case 0x24: - hts_stream_type = SCT_HEVC; - break; + case 0x24: + hts_stream_type = SCT_HEVC; + break; - case 0x80: /* DigiCipher II (North American cable) encrypted MPEG-2 */ - hts_stream_type = SCT_MPEG2VIDEO; - break; + case 0x80: /* DigiCipher II (North American cable) encrypted MPEG-2 */ + hts_stream_type = SCT_MPEG2VIDEO; + break; - case 0x81: - hts_stream_type = SCT_AC3; - break; + case 0x81: + hts_stream_type = SCT_AC3; + break; - case 0x87: /* ATSC */ - hts_stream_type = SCT_EAC3; - break; + case 0x87: /* ATSC */ + hts_stream_type = SCT_EAC3; + break; - default: - break; + default: + break; } - while(dllen > 1) { + while (dllen > 1) { dtag = ptr[0]; dlen = ptr[1]; tvhlog_hexdump(mt->mt_subsys, ptr, dlen + 2); - len -= 2; ptr += 2; dllen -= 2; - if(dlen > len) + len -= 2; + ptr += 2; + dllen -= 2; + if (dlen > len) break; - switch(dtag) { - case DVB_DESC_CA: - update |= psi_desc_ca(mt, set, ptr, dlen); - break; - - case DVB_DESC_VIDEO_STREAM: - video_stream = dlen > 0 && SCT_ISVIDEO(hts_stream_type); - break; + switch (dtag) { + case DVB_DESC_CA: + update |= psi_desc_ca(mt, set, ptr, dlen); + break; - case DVB_DESC_REGISTRATION: - if(mux->mm_pmt_ac3 != MM_AC3_PMT_N05 && dlen == 4 && - ptr[0] == 'A' && ptr[1] == 'C' && ptr[2] == '-' && ptr[3] == '3') - hts_stream_type = SCT_AC3; - /* seen also these formats: */ - /* LU-A, ADV1 */ - break; + case DVB_DESC_VIDEO_STREAM: + video_stream = dlen > 0 && SCT_ISVIDEO(hts_stream_type); + break; - case DVB_DESC_LANGUAGE: - lang = lang_code_get2((const char*)ptr, 3); - audio_type = ptr[3]; - break; + case DVB_DESC_REGISTRATION: + if (mux->mm_pmt_ac3 != MM_AC3_PMT_N05 && dlen == 4 && ptr[0] == 'A' && ptr[1] == 'C' && + ptr[2] == '-' && ptr[3] == '3') + hts_stream_type = SCT_AC3; + /* seen also these formats: */ + /* LU-A, ADV1 */ + break; - case DVB_DESC_TELETEXT: - if(estype == 0x06) { - hts_stream_type = SCT_TELETEXT; - update |= psi_desc_teletext(set, ptr, dlen, pid, &tt_position); - } - break; + case DVB_DESC_LANGUAGE: + lang = lang_code_get2((const char*)ptr, 3); + audio_type = ptr[3]; + break; - case DVB_DESC_AC3: - if(estype == 0x06 || estype == 0x81) - hts_stream_type = SCT_AC3; - break; + case DVB_DESC_TELETEXT: + if (estype == 0x06) { + hts_stream_type = SCT_TELETEXT; + update |= psi_desc_teletext(set, ptr, dlen, pid, &tt_position); + } + break; - case DVB_DESC_AAC: - if(estype == 0x0f) - hts_stream_type = SCT_MP4A; - else if(estype == 0x11) - hts_stream_type = SCT_AAC; - break; + case DVB_DESC_AC3: + if (estype == 0x06 || estype == 0x81) + hts_stream_type = SCT_AC3; + break; - case DVB_DESC_SUBTITLE: - if(dlen < 8 || video_stream) + case DVB_DESC_AAC: + if (estype == 0x0f) + hts_stream_type = SCT_MP4A; + else if (estype == 0x11) + hts_stream_type = SCT_AAC; break; - lang = lang_code_get2((const char*)ptr, 3); - composition_id = extract_2byte(ptr + 4); - ancillary_id = extract_2byte(ptr + 6); - hts_stream_type = SCT_DVBSUB; - break; + case DVB_DESC_SUBTITLE: + if (dlen < 8 || video_stream) + break; - case DVB_DESC_EAC3: - if(estype == 0x06 || estype == 0x81) - hts_stream_type = SCT_EAC3; - break; + lang = lang_code_get2((const char*)ptr, 3); + composition_id = extract_2byte(ptr + 4); + ancillary_id = extract_2byte(ptr + 6); + hts_stream_type = SCT_DVBSUB; + break; - case DVB_DESC_AC4: - if(estype == 0x06 || estype == 0x81) - hts_stream_type = SCT_AC4; - break; + case DVB_DESC_EAC3: + if (estype == 0x06 || estype == 0x81) + hts_stream_type = SCT_EAC3; + break; - case DVB_DESC_ANCILLARY_DATA: - if(dlen < 1) + case DVB_DESC_AC4: + if (estype == 0x06 || estype == 0x81) + hts_stream_type = SCT_AC4; break; - if((ptr[0] & 0x40) == 0x40) /* ancillary_data_id : RDS via UECP */ - rds_uecp = 1; + case DVB_DESC_ANCILLARY_DATA: + if (dlen < 1) + break; - if(rds_uecp && hts_stream_type == SCT_UNKNOWN && estype == 0x89) - hts_stream_type = SCT_RDS; - break; + if ((ptr[0] & 0x40) == 0x40) /* ancillary_data_id : RDS via UECP */ + rds_uecp = 1; - default: - break; + if (rds_uecp && hts_stream_type == SCT_UNKNOWN && estype == 0x89) + hts_stream_type = SCT_RDS; + break; + + default: + break; } - len -= dlen; ptr += dlen; dllen -= dlen; + len -= dlen; + ptr += dlen; + dllen -= dlen; } - + if (hts_stream_type != SCT_UNKNOWN) { st = elementary_stream_find(set, pid); @@ -471,14 +474,17 @@ dvb_psi_parse_pmt if (st->es_type != hts_stream_type) { update |= PMT_UPDATE_STREAM_CHANGE; - st->es_type = hts_stream_type; + st->es_type = hts_stream_type; st->es_audio_version = audio_version; } st->es_delete_me = 0; - tvhdebug(mt->mt_subsys, "%s: type %s position %d", - mt->mt_name, streaming_component_type2txt(st->es_type), position); + tvhdebug(mt->mt_subsys, + "%s: type %s position %d", + mt->mt_name, + streaming_component_type2txt(st->es_type), + position); if (lang) tvhdebug(mt->mt_subsys, "%s: language %s", mt->mt_name, lang); if (composition_id != -1) @@ -486,41 +492,41 @@ dvb_psi_parse_pmt if (ancillary_id != -1) tvhdebug(mt->mt_subsys, "%s: ancillary_id %d", mt->mt_name, ancillary_id); - if(st->es_position != position) { + if (st->es_position != position) { update |= PMT_REORDERED; st->es_position = position; } - if(lang && memcmp(st->es_lang, lang, 3)) { + if (lang && memcmp(st->es_lang, lang, 3)) { update |= PMT_UPDATE_LANGUAGE; memcpy(st->es_lang, lang, 4); } - if(st->es_audio_type != audio_type) { + if (st->es_audio_type != audio_type) { update |= PMT_UPDATE_AUDIO_TYPE; - st->es_audio_type = audio_type; + st->es_audio_type = audio_type; st->es_audio_version = audio_version; } /* FIXME: it might make sense that PMT info has greater priority */ /* but we use this field only for MPEG1/2/3 audio which */ /* is detected in the parser code */ - if(audio_version && !st->es_audio_version) { + if (audio_version && !st->es_audio_version) { update |= PMT_UPDATE_AUDIO_VERSION; st->es_audio_version = audio_version; } - if(composition_id != -1 && st->es_composition_id != composition_id) { + if (composition_id != -1 && st->es_composition_id != composition_id) { st->es_composition_id = composition_id; update |= PMT_UPDATE_COMPOSITION_ID; } - if(ancillary_id != -1 && st->es_ancillary_id != ancillary_id) { + if (ancillary_id != -1 && st->es_ancillary_id != ancillary_id) { st->es_ancillary_id = ancillary_id; update |= PMT_UPDATE_ANCILLARY_ID; } - if(st->es_rds_uecp != rds_uecp) { + if (st->es_rds_uecp != rds_uecp) { st->es_rds_uecp = rds_uecp; update |= PMT_UPDATE_RDS_UECP; } @@ -533,15 +539,15 @@ dvb_psi_parse_pmt /* Handle PCR 'elementary stream' */ if (!pcr_shared) { - st = elementary_stream_type_modify(set, set->set_pcr_pid, SCT_PCR); + st = elementary_stream_type_modify(set, set->set_pcr_pid, SCT_PCR); st->es_delete_me = 0; } /* Scan again to see if any streams should be deleted */ - for(st = TAILQ_FIRST(&set->set_all); st != NULL; st = next) { + for (st = TAILQ_FIRST(&set->set_all); st != NULL; st = next) { next = TAILQ_NEXT(st, es_link); - for(c = LIST_FIRST(&st->es_caids); c != NULL; c = cn) { + for (c = LIST_FIRST(&st->es_caids); c != NULL; c = cn) { cn = LIST_NEXT(c, link); if (c->delete_me) { LIST_REMOVE(c, link); @@ -550,7 +556,7 @@ dvb_psi_parse_pmt } } - if(st->es_delete_me) { + if (st->es_delete_me) { if (st->es_type == SCT_HBBTV) dvb_pmt_hbbtv_table_remove(mt->mt_mux, st); elementary_set_stream_destroy(set, st); @@ -558,68 +564,79 @@ dvb_psi_parse_pmt } } - if(update & PMT_REORDERED) + if (update & PMT_REORDERED) elementary_set_sort_streams(set); if (update) { - tvhdebug(mt->mt_subsys, "%s: Service \"%s\" PMT (version %d) updated" - "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", - mt->mt_name, - nicename, version, - update&PMT_UPDATE_PCR ? ", PCR PID changed":"", - update&PMT_UPDATE_NEW_STREAM ? ", New elementary stream":"", - update&PMT_UPDATE_STREAM_CHANGE ? ", Changed elementary stream":"", - update&PMT_UPDATE_STREAM_DELETED ? ", Stream deleted":"", - update&PMT_UPDATE_LANGUAGE ? ", Language changed":"", - update&PMT_UPDATE_AUDIO_TYPE ? ", Audio type changed":"", - update&PMT_UPDATE_AUDIO_VERSION ? ", Audio version changed":"", - update&PMT_UPDATE_FRAME_DURATION ? ", Frame duration changed":"", - update&PMT_UPDATE_COMPOSITION_ID ? ", Composition ID changed":"", - update&PMT_UPDATE_ANCILLARY_ID ? ", Ancillary ID changed":"", - update&PMT_UPDATE_NEW_CA_STREAM ? ", New CA stream":"", - update&PMT_UPDATE_NEW_CAID ? ", New CAID":"", - update&PMT_UPDATE_CA_PROVIDER_CHANGE? ", CA provider changed":"", - update&PMT_UPDATE_CAID_DELETED ? ", CAID deleted":"", - update&PMT_UPDATE_CAID_PID ? ", CAID PID changed":"", - update&PMT_UPDATE_RDS_UECP ? ", RDS UECP flag changed":"", - update&PMT_REORDERED ? ", PIDs reordered":""); + tvhdebug(mt->mt_subsys, + "%s: Service \"%s\" PMT (version %d) updated" + "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", + mt->mt_name, + nicename, + version, + update & PMT_UPDATE_PCR ? ", PCR PID changed" : "", + update & PMT_UPDATE_NEW_STREAM ? ", New elementary stream" : "", + update & PMT_UPDATE_STREAM_CHANGE ? ", Changed elementary stream" : "", + update & PMT_UPDATE_STREAM_DELETED ? ", Stream deleted" : "", + update & PMT_UPDATE_LANGUAGE ? ", Language changed" : "", + update & PMT_UPDATE_AUDIO_TYPE ? ", Audio type changed" : "", + update & PMT_UPDATE_AUDIO_VERSION ? ", Audio version changed" : "", + update & PMT_UPDATE_FRAME_DURATION ? ", Frame duration changed" : "", + update & PMT_UPDATE_COMPOSITION_ID ? ", Composition ID changed" : "", + update & PMT_UPDATE_ANCILLARY_ID ? ", Ancillary ID changed" : "", + update & PMT_UPDATE_NEW_CA_STREAM ? ", New CA stream" : "", + update & PMT_UPDATE_NEW_CAID ? ", New CAID" : "", + update & PMT_UPDATE_CA_PROVIDER_CHANGE ? ", CA provider changed" : "", + update & PMT_UPDATE_CAID_DELETED ? ", CAID deleted" : "", + update & PMT_UPDATE_CAID_PID ? ", CAID PID changed" : "", + update & PMT_UPDATE_RDS_UECP ? ", RDS UECP flag changed" : "", + update & PMT_REORDERED ? ", PIDs reordered" : ""); } return update; } -int -dvb_pmt_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int r, sect, last, ver, restart; - uint32_t update; - uint16_t sid; - mpegts_mux_t *mm = mt->mt_mux; - mpegts_service_t *s; - elementary_stream_t *es; - mpegts_psi_table_state_t *st = NULL; +int dvb_pmt_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int r, sect, last, ver, restart; + uint32_t update; + uint16_t sid; + mpegts_mux_t* mm = mt->mt_mux; + mpegts_service_t* s; + elementary_stream_t* es; + mpegts_psi_table_state_t* st = NULL; /* Start */ - if (len < 2) return -1; + if (len < 2) + return -1; sid = extract_svcid(ptr); - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, - tableid, sid, 9, &st, §, &last, &ver, 0); - if (r != 1) return r; + r = dvb_table_begin((mpegts_psi_table_t*)mt, + ptr, + len, + tableid, + sid, + 9, + &st, + §, + &last, + &ver, + 0); + if (r != 1) + return r; if (mm->mm_sid_filter > 0 && sid != mm->mm_sid_filter) goto end; /* Find service */ - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) - if (service_id16(s) == sid) break; - if (!s) return -1; + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) + if (service_id16(s) == sid) + break; + if (!s) + return -1; /* Process */ tvhdebug(mt->mt_subsys, "%s: sid %04X (%d)", mt->mt_name, sid, sid); update = 0; tvh_mutex_lock(&s->s_stream_mutex); - update = dvb_psi_parse_pmt(mt, service_nicename((service_t *)s), - &s->s_components, ptr, len); + update = dvb_psi_parse_pmt(mt, service_nicename((service_t*)s), &s->s_components, ptr, len); if (update) { if (s->s_status == SERVICE_RUNNING) elementary_set_filter_build(&s->s_components); @@ -628,11 +645,9 @@ dvb_pmt_callback /* Only restart if something that our clients worry about did change */ restart = 0; if (update) { - if (update & ~(PMT_UPDATE_NEW_CA_STREAM | - PMT_UPDATE_NEW_CAID | - PMT_UPDATE_CA_PROVIDER_CHANGE | - PMT_UPDATE_CAID_DELETED | - PMT_UPDATE_CAID_PID)) { + if (update & + ~(PMT_UPDATE_NEW_CA_STREAM | PMT_UPDATE_NEW_CAID | PMT_UPDATE_CA_PROVIDER_CHANGE | + PMT_UPDATE_CAID_DELETED | PMT_UPDATE_CAID_PID)) { restart = s->s_status == SERVICE_RUNNING; } } @@ -644,19 +659,29 @@ dvb_pmt_callback tvh_mutex_unlock(&s->s_stream_mutex); if (restart) service_restart((service_t*)s); - if (update & (PMT_UPDATE_NEW_CA_STREAM|PMT_UPDATE_NEW_CAID| - PMT_UPDATE_CAID_DELETED|PMT_UPDATE_CAID_PID)) - descrambler_caid_changed((service_t *)s); - - TAILQ_FOREACH(es, &s->s_components.set_filter, es_filter_link) { - if (es->es_type != SCT_HBBTV) continue; - tvhdebug(mt->mt_subsys, "%s: install hbbtv pid %04X (%d)", - mt->mt_name, es->es_pid, es->es_pid); - mpegts_table_add(mm, DVB_HBBTV_BASE, DVB_HBBTV_MASK, - dvb_hbbtv_callback, es, "hbbtv", LS_TBL_BASE, - MT_CRC | MT_FULL | MT_QUICKREQ | MT_ONESHOT, - es->es_pid, MPS_WEIGHT_HBBTV_SCAN); - + if (update & + (PMT_UPDATE_NEW_CA_STREAM | PMT_UPDATE_NEW_CAID | PMT_UPDATE_CAID_DELETED | + PMT_UPDATE_CAID_PID)) + descrambler_caid_changed((service_t*)s); + + TAILQ_FOREACH (es, &s->s_components.set_filter, es_filter_link) { + if (es->es_type != SCT_HBBTV) + continue; + tvhdebug(mt->mt_subsys, + "%s: install hbbtv pid %04X (%d)", + mt->mt_name, + es->es_pid, + es->es_pid); + mpegts_table_add(mm, + DVB_HBBTV_BASE, + DVB_HBBTV_MASK, + dvb_hbbtv_callback, + es, + "hbbtv", + LS_TBL_BASE, + MT_CRC | MT_FULL | MT_QUICKREQ | MT_ONESHOT, + es->es_pid, + MPS_WEIGHT_HBBTV_SCAN); } #if ENABLE_LINUXDVB_CA @@ -665,5 +690,5 @@ dvb_pmt_callback /* Finish */ end: - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); } diff --git a/src/input/mpegts/dvb_psi_pmt.h b/src/input/mpegts/dvb_psi_pmt.h index 095981612..9058b6e07 100644 --- a/src/input/mpegts/dvb_psi_pmt.h +++ b/src/input/mpegts/dvb_psi_pmt.h @@ -24,26 +24,28 @@ */ /* PMT update reason flags */ -#define PMT_UPDATE_PCR (1<<0) -#define PMT_UPDATE_NEW_STREAM (1<<1) -#define PMT_UPDATE_STREAM_CHANGE (1<<2) -#define PMT_UPDATE_STREAM_DELETED (1<<3) -#define PMT_UPDATE_LANGUAGE (1<<4) -#define PMT_UPDATE_AUDIO_TYPE (1<<5) -#define PMT_UPDATE_AUDIO_VERSION (1<<6) -#define PMT_UPDATE_FRAME_DURATION (1<<7) -#define PMT_UPDATE_COMPOSITION_ID (1<<8) -#define PMT_UPDATE_ANCILLARY_ID (1<<9) -#define PMT_UPDATE_NEW_CA_STREAM (1<<10) -#define PMT_UPDATE_NEW_CAID (1<<11) -#define PMT_UPDATE_CA_PROVIDER_CHANGE (1<<12) -#define PMT_UPDATE_CAID_DELETED (1<<13) -#define PMT_UPDATE_CAID_PID (1<<14) -#define PMT_UPDATE_RDS_UECP (1<<15) -#define PMT_REORDERED (1<<16) +#define PMT_UPDATE_PCR (1 << 0) +#define PMT_UPDATE_NEW_STREAM (1 << 1) +#define PMT_UPDATE_STREAM_CHANGE (1 << 2) +#define PMT_UPDATE_STREAM_DELETED (1 << 3) +#define PMT_UPDATE_LANGUAGE (1 << 4) +#define PMT_UPDATE_AUDIO_TYPE (1 << 5) +#define PMT_UPDATE_AUDIO_VERSION (1 << 6) +#define PMT_UPDATE_FRAME_DURATION (1 << 7) +#define PMT_UPDATE_COMPOSITION_ID (1 << 8) +#define PMT_UPDATE_ANCILLARY_ID (1 << 9) +#define PMT_UPDATE_NEW_CA_STREAM (1 << 10) +#define PMT_UPDATE_NEW_CAID (1 << 11) +#define PMT_UPDATE_CA_PROVIDER_CHANGE (1 << 12) +#define PMT_UPDATE_CAID_DELETED (1 << 13) +#define PMT_UPDATE_CAID_PID (1 << 14) +#define PMT_UPDATE_RDS_UECP (1 << 15) +#define PMT_REORDERED (1 << 16) -uint32_t dvb_psi_parse_pmt - (mpegts_table_t *mt, const char *nicename, elementary_set_t *set, - const uint8_t *ptr, int len); +uint32_t dvb_psi_parse_pmt(mpegts_table_t* mt, + const char* nicename, + elementary_set_t* set, + const uint8_t* ptr, + int len); #endif diff --git a/src/input/mpegts/dvb_support.c b/src/input/mpegts/dvb_support.c index 762ddb341..748e2d57d 100644 --- a/src/input/mpegts/dvb_support.c +++ b/src/input/mpegts/dvb_support.c @@ -34,60 +34,57 @@ #include "lang_str.h" #include "settings.h" -static int convert_iso_8859[16] = { - -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, 12, 13 -}; -#define convert_utf8 14 +static int convert_iso_8859[16] = {-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, -1, 11, 12, 13}; +#define convert_utf8 14 #define convert_iso6937 15 -#define convert_ucs2 16 -#define convert_gb 17 +#define convert_ucs2 16 +#define convert_gb 17 #define conv_lower(dst, dstlen, c) \ - if (c >= 0x20 || c == '\n') { *(dst++) = c; (*dstlen)--; } - -static inline size_t conv_gb(const uint8_t *src, size_t srclen, - char *dst, size_t *dstlen) -{ - ssize_t len; - len = intlconv_to_utf8(dst, *dstlen, "gb2312", (char *)src, srclen); - if (len < 0 || len > *dstlen) - return -1; - *dstlen -= len; - return 0; + if (c >= 0x20 || c == '\n') { \ + *(dst++) = c; \ + (*dstlen)--; \ + } + +static inline size_t conv_gb(const uint8_t* src, size_t srclen, char* dst, size_t* dstlen) { + ssize_t len; + len = intlconv_to_utf8(dst, *dstlen, "gb2312", (char*)src, srclen); + if (len < 0 || len > *dstlen) + return -1; + *dstlen -= len; + return 0; } -static inline int encode_utf8(unsigned int c, char *outb, int outleft) -{ +static inline int encode_utf8(unsigned int c, char* outb, int outleft) { if (c <= 0x7F && outleft >= 1) { if (c >= 0x20 || c == '\n') { *outb = c; return 1; } return 0; - } else if (c <= 0x7FF && outleft >=2) { - *outb++ = ((c >> 6) & 0x1F) | 0xC0; - *outb++ = ( c & 0x3F) | 0x80; + } else if (c <= 0x7FF && outleft >= 2) { + *outb++ = ((c >> 6) & 0x1F) | 0xC0; + *outb++ = (c & 0x3F) | 0x80; return 2; } else if (c <= 0xFFFF && outleft >= 3) { *outb++ = ((c >> 12) & 0x0F) | 0xE0; - *outb++ = ((c >> 6) & 0x3F) | 0x80; - *outb++ = ( c & 0x3F) | 0x80; + *outb++ = ((c >> 6) & 0x3F) | 0x80; + *outb++ = (c & 0x3F) | 0x80; return 3; } else if (c <= 0x10FFFF && outleft >= 4) { *outb++ = ((c >> 18) & 0x07) | 0xF0; *outb++ = ((c >> 12) & 0x3F) | 0x80; - *outb++ = ((c >> 6) & 0x3F) | 0x80; - *outb++ = ( c & 0x3F) | 0x80; + *outb++ = ((c >> 6) & 0x3F) | 0x80; + *outb++ = (c & 0x3F) | 0x80; return 4; } else { return -1; } } -static inline size_t conv_UCS2(const uint8_t *src, size_t srclen,char *dst, size_t *dstlen) -{ - while (srclen>0 && (*dstlen)>0){ - uint16_t uc = *src<<8|*(src+1); +static inline size_t conv_UCS2(const uint8_t* src, size_t srclen, char* dst, size_t* dstlen) { + while (srclen > 0 && (*dstlen) > 0) { + uint16_t uc = *src << 8 | *(src + 1); if (uc >= 0xe080 && uc <= 0xe09f) { // codes 0xe080 - 0xe09f (control codes) are ignored except CR/LF if (uc == 0xe08a) { @@ -105,20 +102,18 @@ static inline size_t conv_UCS2(const uint8_t *src, size_t srclen,char *dst, size dst += len; } } - srclen-=2; - src+=2; + srclen -= 2; + src += 2; } - if (srclen>0) { + if (srclen > 0) { errno = E2BIG; return -1; } return 0; } -static inline size_t conv_utf8(const uint8_t *src, size_t srclen, - char *dst, size_t *dstlen) -{ - while (srclen>0 && (*dstlen)>0) { +static inline size_t conv_utf8(const uint8_t* src, size_t srclen, char* dst, size_t* dstlen) { + while (srclen > 0 && (*dstlen) > 0) { uint_fast8_t c = *src; if (c <= 0x7f) { conv_lower(dst, dstlen, c); @@ -129,20 +124,18 @@ static inline size_t conv_utf8(const uint8_t *src, size_t srclen, srclen--; src++; } - if (srclen>0) { + if (srclen > 0) { errno = E2BIG; return -1; } return 0; } -static inline size_t conv_8859(int conv, - const uint8_t *src, size_t srclen, - char *dst, size_t *dstlen) -{ - uint16_t *table = conv_8859_table[conv]; +static inline size_t +conv_8859(int conv, const uint8_t* src, size_t srclen, char* dst, size_t* dstlen) { + uint16_t* table = conv_8859_table[conv]; - while (srclen>0 && (*dstlen)>0) { + while (srclen > 0 && (*dstlen) > 0) { uint_fast8_t c = *src; if (c <= 0x7f) { conv_lower(dst, dstlen, c); @@ -156,7 +149,7 @@ static inline size_t conv_8859(int conv, } else { // map according to character table, skipping // unmapped chars (value 0 in the table) - uint_fast16_t uc = table[c-0xa0]; + uint_fast16_t uc = table[c - 0xa0]; if (uc != 0) { int len = encode_utf8(uc, dst, *dstlen); if (len == -1) { @@ -171,17 +164,15 @@ static inline size_t conv_8859(int conv, srclen--; src++; } - if (srclen>0) { + if (srclen > 0) { errno = E2BIG; return -1; } return 0; } -static inline size_t conv_6937(const uint8_t *src, size_t srclen, - char *dst, size_t *dstlen) -{ - while (srclen>0 && (*dstlen)>0) { +static inline size_t conv_6937(const uint8_t* src, size_t srclen, char* dst, size_t* dstlen) { + while (srclen > 0 && (*dstlen) > 0) { uint_fast8_t c = *src; if (c <= 0x7f) { conv_lower(dst, dstlen, c); @@ -196,7 +187,7 @@ static inline size_t conv_6937(const uint8_t *src, size_t srclen, uint16_t uc; if (c >= 0xc0 && c <= 0xcf) { // map two-byte sequence, skipping illegal combinations. - if (srclen<2) { + if (srclen < 2) { errno = EINVAL; return -1; } @@ -204,18 +195,18 @@ static inline size_t conv_6937(const uint8_t *src, size_t srclen, src++; uint8_t c2 = *src; if (c2 == 0x20) { - uc = iso6937_lone_accents[c-0xc0]; + uc = iso6937_lone_accents[c - 0xc0]; } else if (c2 >= 0x41 && c2 <= 0x5a) { - uc = iso6937_multi_byte[c-0xc0][c2-0x41]; + uc = iso6937_multi_byte[c - 0xc0][c2 - 0x41]; } else if (c2 >= 0x61 && c2 <= 0x7a) { - uc = iso6937_multi_byte[c-0xc0][c2-0x61+26]; + uc = iso6937_multi_byte[c - 0xc0][c2 - 0x61 + 26]; } else { uc = 0; } } else { // map according to single character table, skipping // unmapped chars (value 0 in the table) - uc = iso6937_single_byte[c-0xa0]; + uc = iso6937_single_byte[c - 0xa0]; } if (uc != 0) { int len = encode_utf8(uc, dst, *dstlen); @@ -231,23 +222,26 @@ static inline size_t conv_6937(const uint8_t *src, size_t srclen, srclen--; src++; } - if (srclen>0) { + if (srclen > 0) { errno = E2BIG; return -1; } return 0; } -static inline size_t dvb_convert(int conv, - const uint8_t *src, size_t srclen, - char *dst, size_t *dstlen) -{ +static inline size_t +dvb_convert(int conv, const uint8_t* src, size_t srclen, char* dst, size_t* dstlen) { switch (conv) { - case convert_utf8: return conv_utf8(src, srclen, dst, dstlen); - case convert_iso6937: return conv_6937(src, srclen, dst, dstlen); - case convert_gb: return conv_gb(src,srclen,dst,dstlen); - case convert_ucs2:return conv_UCS2(src,srclen,dst,dstlen); - default: return conv_8859(conv, src, srclen, dst, dstlen); + case convert_utf8: + return conv_utf8(src, srclen, dst, dstlen); + case convert_iso6937: + return conv_6937(src, srclen, dst, dstlen); + case convert_gb: + return conv_gb(src, srclen, dst, dstlen); + case convert_ucs2: + return conv_UCS2(src, srclen, dst, dstlen); + default: + return conv_8859(conv, src, srclen, dst, dstlen); } } @@ -256,16 +250,17 @@ static inline size_t dvb_convert(int conv, * Not all character sets are supported, but it should cover most of them */ -int -dvb_get_string - (char *dst, size_t dstlen, const uint8_t *src, size_t srclen, - const char *dvb_charset, dvb_string_conv_t *conv) -{ - int ic = -1; +int dvb_get_string(char* dst, + size_t dstlen, + const uint8_t* src, + size_t srclen, + const char* dvb_charset, + dvb_string_conv_t* conv) { + int ic = -1; size_t len, outlen; - int i, auto_pl_charset = 0; + int i, auto_pl_charset = 0; - if(srclen < 1) { + if (srclen < 1) { *dst = 0; return 0; } @@ -280,72 +275,81 @@ dvb_get_string // check for automatic polish charset detection if (dvb_charset && strcmp("AUTO_POLISH", dvb_charset) == 0) { auto_pl_charset = 1; - dvb_charset = NULL; + dvb_charset = NULL; } // automatic charset detection - switch(src[0]) { - case 0: - *dst = 0; // empty string (confirmed!) - return 0; + switch (src[0]) { + case 0: + *dst = 0; // empty string (confirmed!) + return 0; + + case 0x01 ... 0x0b: /* ISO 8859-X */ + if (auto_pl_charset && (src[0] + 4) == 5) + ic = convert_iso6937; + else + ic = convert_iso_8859[src[0] + 4]; + src++; + srclen--; + break; - case 0x01 ... 0x0b: /* ISO 8859-X */ - if (auto_pl_charset && (src[0] + 4) == 5) - ic = convert_iso6937; - else - ic = convert_iso_8859[src[0] + 4]; - src++; srclen--; - break; - - case 0x0c ... 0x0f: /* reserved for the future use */ - src++; srclen--; - break; - - case 0x10: /* ISO 8859 - Table A.4 */ - if(srclen < 3 || src[1] != 0 || src[2] == 0 || src[2] > 0x0f) - return -1; - - ic = convert_iso_8859[src[2]]; - src+=3; srclen-=3; - break; - - case 0x11: /* ISO 10646 */ - ic = convert_ucs2; - src++; srclen--; - break; - - case 0x12: /* KSX1001-2004 - Korean Character Set - NYI! */ - src++; srclen--; - break; - - case 0x13: /* GB-2312-1980 */ - ic = convert_gb; - src++; srclen--; - break; - - case 0x14: /* Big5 subset of ISO 10646 */ - ic = convert_ucs2; - src++; srclen--; - break; - - case 0x15: /* UTF-8 */ - ic = convert_utf8; - src++; srclen--; - break; - - case 0x16 ... 0x1e: /* reserved for the future use */ - src++; srclen--; - break; - - case 0x1f: /* Described by encoding_type_id, TS 101 162 */ - return -1; /* NYI */ - - default: - if (auto_pl_charset) - ic = convert_iso_8859[2]; - else - ic = convert_iso6937; - break; + case 0x0c ... 0x0f: /* reserved for the future use */ + src++; + srclen--; + break; + + case 0x10: /* ISO 8859 - Table A.4 */ + if (srclen < 3 || src[1] != 0 || src[2] == 0 || src[2] > 0x0f) + return -1; + + ic = convert_iso_8859[src[2]]; + src += 3; + srclen -= 3; + break; + + case 0x11: /* ISO 10646 */ + ic = convert_ucs2; + src++; + srclen--; + break; + + case 0x12: /* KSX1001-2004 - Korean Character Set - NYI! */ + src++; + srclen--; + break; + + case 0x13: /* GB-2312-1980 */ + ic = convert_gb; + src++; + srclen--; + break; + + case 0x14: /* Big5 subset of ISO 10646 */ + ic = convert_ucs2; + src++; + srclen--; + break; + + case 0x15: /* UTF-8 */ + ic = convert_utf8; + src++; + srclen--; + break; + + case 0x16 ... 0x1e: /* reserved for the future use */ + src++; + srclen--; + break; + + case 0x1f: /* Described by encoding_type_id, TS 101 162 */ + return -1; /* NYI */ + + default: + if (auto_pl_charset) + ic = convert_iso_8859[2]; + else + ic = convert_iso6937; + break; } // manual charset override @@ -365,12 +369,12 @@ dvb_get_string } } - if(srclen < 1) { + if (srclen < 1) { *dst = 0; return 0; } - if(ic == -1) + if (ic == -1) return -1; outlen = dstlen - 1; @@ -378,41 +382,38 @@ dvb_get_string if (dvb_convert(ic, src, srclen, dst, &outlen) == -1) return -1; - len = dstlen - outlen - 1; + len = dstlen - outlen - 1; dst[len] = 0; return 0; } - -int -dvb_get_string_with_len(char *dst, size_t dstlen, - const uint8_t *buf, size_t buflen, const char *dvb_charset, - dvb_string_conv_t *conv) -{ +int dvb_get_string_with_len(char* dst, + size_t dstlen, + const uint8_t* buf, + size_t buflen, + const char* dvb_charset, + dvb_string_conv_t* conv) { int l = buf[0]; - if(l + 1 > buflen) + if (l + 1 > buflen) return -1; - if(dvb_get_string(dst, dstlen, buf + 1, l, dvb_charset, conv)) + if (dvb_get_string(dst, dstlen, buf + 1, l, dvb_charset, conv)) return -1; return l + 1; } - /** * */ -void -atsc_utf16_to_utf8(const uint8_t *src, int len, char *buf, int buflen) -{ +void atsc_utf16_to_utf8(const uint8_t* src, int len, char* buf, int buflen) { int i, c, r; - for(i = 0; i < len; i++) { + for (i = 0; i < len; i++) { c = (src[i * 2 + 0] << 8) | src[i * 2 + 1]; - if(buflen >= 7) { + if (buflen >= 7) { r = put_utf8(buf, c); buf += r; buflen -= r; @@ -422,25 +423,22 @@ atsc_utf16_to_utf8(const uint8_t *src, int len, char *buf, int buflen) } /* Decode and convert ATSC Multiple String Structures to UTF-8. - * - * refer to "ATSC Standard: Program and System Information Protocol for Terrestrial Broadcast and Cable" - * (Document A65/2013), Section 6.10, pages 79-82 + * + * refer to "ATSC Standard: Program and System Information Protocol for Terrestrial Broadcast and + * Cable" (Document A65/2013), Section 6.10, pages 79-82 */ -lang_str_t * -atsc_get_string - (const uint8_t *src, size_t srclen) -{ - const int bufferSize = 255*3+1; /* Max length of a text segment (255) * - * Max size of a UTF-8 for Unicode characters 0x0 .. 0x33FF (3) + - * NULL terminator (1) */ - lang_str_t *ls = NULL; - int i, j, k, stringcount, segmentcount; - int compressiontype, mode, bytecount; - char langcode[4]; - char buf[bufferSize]; /* UTF-8 string */ - int utf8size, remainingbufleft; - char *bufpointer; +lang_str_t* atsc_get_string(const uint8_t* src, size_t srclen) { + const int bufferSize = 255 * 3 + 1; /* Max length of a text segment (255) * + * Max size of a UTF-8 for Unicode characters 0x0 .. 0x33FF + * (3) + NULL terminator (1) */ + lang_str_t* ls = NULL; + int i, j, k, stringcount, segmentcount; + int compressiontype, mode, bytecount; + char langcode[4]; + char buf[bufferSize]; /* UTF-8 string */ + int utf8size, remainingbufleft; + char* bufpointer; stringcount = src[0]; tvhtrace(LS_MPEGTS, "atsc-str: %d strings", stringcount); @@ -458,7 +456,7 @@ atsc_get_string tvhtrace(LS_MPEGTS, "atsc-str: %d: lang '%s', segments %d", i, langcode, segmentcount); - src += 4; + src += 4; srclen -= 4; /* Step through the list of text segments, decoding each and append them all together. */ @@ -468,29 +466,36 @@ atsc_get_string mode = src[1]; bytecount = src[2]; - src += 3; + src += 3; srclen -= 3; if (bytecount > srclen) return ls; - /* Only supports compression type == 0 (none) and + /* Only supports compression type == 0 (none) and * text modes == 0x0 .. 0x6, 0x9 .. 0x10, 0x20 .. 0x27, 0x30 .. 0x33 */ - if (compressiontype == 0 && ( /* No Compression and one of these: */ - (mode >= 0x0 && mode <= 0x6) || /* Unicode range 0x0000 .. 0x06FF */ - (mode >= 0x9 && mode <= 0x10) || /* Unicode range 0x0900 .. 0x10FF */ - (mode >= 0x20 && mode <= 0x27) || /* Unicode range 0x2000 .. 0x27FF */ - (mode >= 0x30 && mode <= 0x33) /* Unicode range 0x3000 .. 0x33FF */ - )) { - tvhtrace(LS_MPEGTS, "atsc-str: %d: comptype 0x%02x, mode 0x%02x, %d bytes: '%.*s'", - j, compressiontype, mode, bytecount, bytecount, src); + if (compressiontype == 0 && + ( /* No Compression and one of these: */ + (mode >= 0x0 && mode <= 0x6) || /* Unicode range 0x0000 .. 0x06FF */ + (mode >= 0x9 && mode <= 0x10) || /* Unicode range 0x0900 .. 0x10FF */ + (mode >= 0x20 && mode <= 0x27) || /* Unicode range 0x2000 .. 0x27FF */ + (mode >= 0x30 && mode <= 0x33) /* Unicode range 0x3000 .. 0x33FF */ + )) { + tvhtrace(LS_MPEGTS, + "atsc-str: %d: comptype 0x%02x, mode 0x%02x, %d bytes: '%.*s'", + j, + compressiontype, + mode, + bytecount, + bytecount, + src); /* Convert each decoded Unicode character to UTF-8. */ - for(k = 0, bufpointer = buf, remainingbufleft = bufferSize; k < bytecount; k++) { + for (k = 0, bufpointer = buf, remainingbufleft = bufferSize; k < bytecount; k++) { /* Make sure there is enough buffer left for the next (or last) UTF-8 character * [Max # bytes in a single UTF-8 character (3) + NULL terminator (1)] */ - if(remainingbufleft > (3+1)) { + if (remainingbufleft > (3 + 1)) { /* Construct the Unicode character and convert to UTF-8. */ utf8size = put_utf8(bufpointer, (mode << 8) | src[k]); bufpointer += utf8size; @@ -507,13 +512,20 @@ atsc_get_string if (ls == NULL) ls = lang_str_create(); lang_str_append(ls, buf, langcode); - } else if (compressiontype == 0 && mode == 0x3F) { - tvhtrace(LS_MPEGTS, "atsc-str: %d: comptype 0x%02x, mode 0x%02x, %d bytes: '%.*s'", - j, compressiontype, mode, bytecount, bytecount, src); + } else if (compressiontype == 0 && mode == 0x3F) { + tvhtrace(LS_MPEGTS, + "atsc-str: %d: comptype 0x%02x, mode 0x%02x, %d bytes: '%.*s'", + j, + compressiontype, + mode, + bytecount, + bytecount, + src); /* let the atsc_utf16_to_utf8 function do the conversion; - * bytecount/2: since the function is handling both utf16 bytes in one count only half the length is needed */ - atsc_utf16_to_utf8(src, bytecount/2, buf, bufferSize); + * bytecount/2: since the function is handling both utf16 bytes in one count only half the + * length is needed */ + atsc_utf16_to_utf8(src, bytecount / 2, buf, bufferSize); if (ls == NULL) ls = lang_str_create(); @@ -529,11 +541,16 @@ atsc_get_string * - text mode == 0x40, 0x41 (ATSC Standard for Taiwan) * - text mode == 0x48 (ATSC Standard for South Korea) * - * - text mode == 0x7, 0x8, 0x11 .. 0x1F, 0x28 .. 0x2F, 0x34 .. 0x3D, 0x42 .. 0x47, 0x49 .. 0xFF (reserved) + * - text mode == 0x7, 0x8, 0x11 .. 0x1F, 0x28 .. 0x2F, 0x34 .. 0x3D, 0x42 .. 0x47, 0x49 .. + * 0xFF (reserved) */ - tvhtrace(LS_MPEGTS, "atsc-str: %d: comptype 0x%02x, mode 0x%02x, %d bytes", - j, compressiontype, mode, bytecount); + tvhtrace(LS_MPEGTS, + "atsc-str: %d: comptype 0x%02x, mode 0x%02x, %d bytes", + j, + compressiontype, + mode, + bytecount); /* For text segments that are not supported, write a terse diagnostic text indicating * the unsupported type instead of the text segment. */ @@ -555,51 +572,47 @@ atsc_get_string * */ -static struct strtab dvb_timezone_strtab[] = { - { N_("UTC"), 0 }, - { N_("Local (server) time"), 1 }, - { N_("UTC- 1"), -1*60 }, - { N_("UTC- 2"), -2*60 }, - { N_("UTC- 2:30"), -2*60-30 }, - { N_("UTC- 3"), -3*60 }, - { N_("UTC- 3:30"), -3*60-30 }, - { N_("UTC- 4"), -4*60 }, - { N_("UTC- 4:30"), -4*60-30 }, - { N_("UTC- 5"), -5*60 }, - { N_("UTC- 6"), -6*60 }, - { N_("UTC- 7"), -7*60 }, - { N_("UTC- 8"), -8*60 }, - { N_("UTC- 9"), -9*60 }, - { N_("UTC- 9:30"), -9*60-30 }, - { N_("UTC-10"), -10*60 }, - { N_("UTC-11"), -11*60 }, - { N_("UTC+ 1"), 1*60 }, - { N_("UTC+ 2"), 2*60 }, - { N_("UTC+ 3"), 3*60 }, - { N_("UTC+ 4"), 4*60 }, - { N_("UTC+ 4:30"), 4*60+30 }, - { N_("UTC+ 5"), 5*60 }, - { N_("UTC+ 5:30"), 5*60+30 }, - { N_("UTC+ 5:45"), 5*60+45 }, - { N_("UTC+ 6"), 6*60 }, - { N_("UTC+ 6:30"), 6*60+30 }, - { N_("UTC+ 7"), 7*60 }, - { N_("UTC+ 8"), 8*60 }, - { N_("UTC+ 8:45"), 8*60+45 }, - { N_("UTC+ 9"), 9*60 }, - { N_("UTC+ 9:30"), 9*60+30 }, - { N_("UTC+10"), 10*60 }, - { N_("UTC+10:30"), 10*60+30 }, - { N_("UTC+11"), 11*60 }, - { N_("UTC+12"), 12*60 }, - { N_("UTC+12:45"), 12*60+45 }, - { N_("UTC+13"), 13*60 }, - { N_("UTC+14"), 14*60 } -}; - -htsmsg_t * -dvb_timezone_enum ( void *p, const char *lang ) -{ +static struct strtab dvb_timezone_strtab[] = {{N_("UTC"), 0}, + {N_("Local (server) time"), 1}, + {N_("UTC- 1"), -1 * 60}, + {N_("UTC- 2"), -2 * 60}, + {N_("UTC- 2:30"), -2 * 60 - 30}, + {N_("UTC- 3"), -3 * 60}, + {N_("UTC- 3:30"), -3 * 60 - 30}, + {N_("UTC- 4"), -4 * 60}, + {N_("UTC- 4:30"), -4 * 60 - 30}, + {N_("UTC- 5"), -5 * 60}, + {N_("UTC- 6"), -6 * 60}, + {N_("UTC- 7"), -7 * 60}, + {N_("UTC- 8"), -8 * 60}, + {N_("UTC- 9"), -9 * 60}, + {N_("UTC- 9:30"), -9 * 60 - 30}, + {N_("UTC-10"), -10 * 60}, + {N_("UTC-11"), -11 * 60}, + {N_("UTC+ 1"), 1 * 60}, + {N_("UTC+ 2"), 2 * 60}, + {N_("UTC+ 3"), 3 * 60}, + {N_("UTC+ 4"), 4 * 60}, + {N_("UTC+ 4:30"), 4 * 60 + 30}, + {N_("UTC+ 5"), 5 * 60}, + {N_("UTC+ 5:30"), 5 * 60 + 30}, + {N_("UTC+ 5:45"), 5 * 60 + 45}, + {N_("UTC+ 6"), 6 * 60}, + {N_("UTC+ 6:30"), 6 * 60 + 30}, + {N_("UTC+ 7"), 7 * 60}, + {N_("UTC+ 8"), 8 * 60}, + {N_("UTC+ 8:45"), 8 * 60 + 45}, + {N_("UTC+ 9"), 9 * 60}, + {N_("UTC+ 9:30"), 9 * 60 + 30}, + {N_("UTC+10"), 10 * 60}, + {N_("UTC+10:30"), 10 * 60 + 30}, + {N_("UTC+11"), 11 * 60}, + {N_("UTC+12"), 12 * 60}, + {N_("UTC+12:45"), 12 * 60 + 45}, + {N_("UTC+13"), 13 * 60}, + {N_("UTC+14"), 14 * 60}}; + +htsmsg_t* dvb_timezone_enum(void* p, const char* lang) { return strtab2htsmsg(dvb_timezone_strtab, 1, lang); } @@ -607,27 +620,25 @@ dvb_timezone_enum ( void *p, const char *lang ) * DVB time and date functions */ -time_t -dvb_convert_date(const uint8_t *dvb_buf, int tmzone) -{ - int i; - int year, month, day, hour, min, sec; - long int mjd; +time_t dvb_convert_date(const uint8_t* dvb_buf, int tmzone) { + int i; + int year, month, day, hour, min, sec; + long int mjd; struct tm dvb_time; mjd = (dvb_buf[0] & 0xff) << 8; mjd += (dvb_buf[1] & 0xff); hour = bcdtoint(dvb_buf[2] & 0xff); - min = bcdtoint(dvb_buf[3] & 0xff); - sec = bcdtoint(dvb_buf[4] & 0xff); + min = bcdtoint(dvb_buf[3] & 0xff); + sec = bcdtoint(dvb_buf[4] & 0xff); /* * Use the routine specified in ETSI EN 300 468 V1.4.1, * "Specification for Service Information in Digital Video Broadcasting" * to convert from Modified Julian Date to Year, Month, Day. */ - year = (int) ((mjd - 15078.2) / 365.25); - month = (int) ((mjd - 14956.1 - (int) (year * 365.25)) / 30.6001); - day = mjd - 14956 - (int) (year * 365.25) - (int) (month * 30.6001); + year = (int)((mjd - 15078.2) / 365.25); + month = (int)((mjd - 14956.1 - (int)(year * 365.25)) / 30.6001); + day = mjd - 14956 - (int)(year * 365.25) - (int)(month * 30.6001); if (month == 14 || month == 15) i = 1; else @@ -635,15 +646,15 @@ dvb_convert_date(const uint8_t *dvb_buf, int tmzone) year += i; month = month - 1 - i * 12; - dvb_time.tm_sec = sec; - dvb_time.tm_min = min; - dvb_time.tm_hour = hour; - dvb_time.tm_mday = day; - dvb_time.tm_mon = month - 1; - dvb_time.tm_year = year; + dvb_time.tm_sec = sec; + dvb_time.tm_min = min; + dvb_time.tm_hour = hour; + dvb_time.tm_mday = day; + dvb_time.tm_mon = month - 1; + dvb_time.tm_year = year; dvb_time.tm_isdst = -1; - dvb_time.tm_wday = 0; - dvb_time.tm_yday = 0; + dvb_time.tm_wday = 0; + dvb_time.tm_yday = 0; if (tmzone == 0) /* UTC */ return timegm(&dvb_time); @@ -655,34 +666,32 @@ dvb_convert_date(const uint8_t *dvb_buf, int tmzone) } static time_t _gps_leap_seconds[17] = { - 362793600, - 394329600, - 425865600, - 489024000, - 567993600, - 631152000, - 662688000, - 709948800, - 741484800, - 773020800, - 820454400, - 867715200, - 915148800, - 1136073600, - 1230768000, - 1341100800, - 1435708800, + 362793600, + 394329600, + 425865600, + 489024000, + 567993600, + 631152000, + 662688000, + 709948800, + 741484800, + 773020800, + 820454400, + 867715200, + 915148800, + 1136073600, + 1230768000, + 1341100800, + 1435708800, }; -time_t -atsc_convert_gpstime(uint32_t gpstime) -{ - int i; +time_t atsc_convert_gpstime(uint32_t gpstime) { + int i; time_t out = gpstime + 315964800; // Add Unix - GPS epoch - for (i = (sizeof(_gps_leap_seconds)/sizeof(time_t)) - 1; i >= 0; i--) { + for (i = (sizeof(_gps_leap_seconds) / sizeof(time_t)) - 1; i >= 0; i--) { if (out > _gps_leap_seconds[i]) { - out -= i+1; + out -= i + 1; break; } } @@ -695,16 +704,19 @@ atsc_convert_gpstime(uint32_t gpstime) */ #if ENABLE_MPEGTS_DVB -htsmsg_t *satellites; +htsmsg_t* satellites; -#define dvb_str2val(p)\ -const char *dvb_##p##2str (int p) { return val2str(p, p##tab); }\ -int dvb_str2##p (const char *p) { return str2val(p, p##tab); } +#define dvb_str2val(p) \ + const char* dvb_##p##2str(int p) { \ + return val2str(p, p##tab); \ + } \ + int dvb_str2##p(const char* p) { \ + return str2val(p, p##tab); \ + } -#define DVB_EOD -10 /* end-of-data */ +#define DVB_EOD -10 /* end-of-data */ -static const char *dvb_common2str(int p) -{ +static const char* dvb_common2str(int p) { if (p == 0) return "NONE"; if (p == 1) @@ -712,8 +724,7 @@ static const char *dvb_common2str(int p) return NULL; } -static int dvb_str2common(const char *p) -{ +static int dvb_str2common(const char* p) { if (strcmp(p, "NONE") == 0) return 0; if (strcmp(p, "AUTO") == 0) @@ -721,8 +732,7 @@ static int dvb_str2common(const char *p) return DVB_EOD; } -static int dvb_verify(int val, int *table) -{ +static int dvb_verify(int val, int* table) { while (*table != DVB_EOD) { if (val == *table) return val; @@ -731,26 +741,24 @@ static int dvb_verify(int val, int *table) return 0; /* NONE */ } -const char *dvb_rolloff2str(int p) -{ +const char* dvb_rolloff2str(int p) { static __thread char buf[16]; - const char *res = dvb_common2str(p); + const char* res = dvb_common2str(p); if (res) return res; sprintf(buf, "%02i", p / 10); return buf; } -int dvb_str2rolloff(const char *p) -{ +int dvb_str2rolloff(const char* p) { static int rolloff_table[] = { - DVB_ROLLOFF_5, - DVB_ROLLOFF_10, - DVB_ROLLOFF_15, - DVB_ROLLOFF_20, - DVB_ROLLOFF_25, - DVB_ROLLOFF_35, - DVB_EOD, + DVB_ROLLOFF_5, + DVB_ROLLOFF_10, + DVB_ROLLOFF_15, + DVB_ROLLOFF_20, + DVB_ROLLOFF_25, + DVB_ROLLOFF_35, + DVB_EOD, }; int res = dvb_str2common(p); if (res != DVB_EOD) @@ -758,51 +766,47 @@ int dvb_str2rolloff(const char *p) return dvb_verify(atoi(p) * 10, rolloff_table); } -static const struct strtab delsystab[] = { - { "NONE", DVB_SYS_NONE }, - { "DVB-C", DVB_SYS_DVBC_ANNEX_A }, - { "DVBC/ANNEX_A", DVB_SYS_DVBC_ANNEX_A }, - { "DVBC_ANNEX_A", DVB_SYS_DVBC_ANNEX_A }, - { "ATSC-C", DVB_SYS_DVBC_ANNEX_B }, - { "CableCARD", DVB_SYS_DVBC_ANNEX_B }, - { "DVBC/ANNEX_B", DVB_SYS_DVBC_ANNEX_B }, - { "DVBC_ANNEX_B", DVB_SYS_DVBC_ANNEX_B }, - { "DVB-C/ANNEX-C",DVB_SYS_DVBC_ANNEX_C }, - { "DVBC/ANNEX_C", DVB_SYS_DVBC_ANNEX_C }, - { "DVBC_ANNEX_C", DVB_SYS_DVBC_ANNEX_C }, - { "DVBC_ANNEX_AC",DVB_SYS_DVBC_ANNEX_A }, /* for compatibility */ - { "DVB-T", DVB_SYS_DVBT }, - { "DVBT", DVB_SYS_DVBT }, - { "DVB-T2", DVB_SYS_DVBT2 }, - { "DVBT2", DVB_SYS_DVBT2 }, - { "DVB-S", DVB_SYS_DVBS }, - { "DVBS", DVB_SYS_DVBS }, - { "DVB-S2", DVB_SYS_DVBS2 }, - { "DVBS2", DVB_SYS_DVBS2 }, - { "DVB-H", DVB_SYS_DVBH }, - { "DVBH", DVB_SYS_DVBH }, - { "ISDB-T", DVB_SYS_ISDBT }, - { "ISDBT", DVB_SYS_ISDBT }, - { "ISDB-S", DVB_SYS_ISDBS }, - { "ISDBS", DVB_SYS_ISDBS }, - { "ISDB-C", DVB_SYS_ISDBC }, - { "ISDBC", DVB_SYS_ISDBC }, - { "ATSC-T", DVB_SYS_ATSC }, - { "ATSC", DVB_SYS_ATSC }, - { "ATSCM-H", DVB_SYS_ATSCMH }, - { "ATSCMH", DVB_SYS_ATSCMH }, - { "DTMB", DVB_SYS_DTMB }, - { "DMBTH", DVB_SYS_DTMB }, /* for compatibility */ - { "CMMB", DVB_SYS_CMMB }, - { "DAB", DVB_SYS_DAB }, - { "DSS", DVB_SYS_DSS }, - { "TURBO", DVB_SYS_TURBO } -}; +static const struct strtab delsystab[] = {{"NONE", DVB_SYS_NONE}, + {"DVB-C", DVB_SYS_DVBC_ANNEX_A}, + {"DVBC/ANNEX_A", DVB_SYS_DVBC_ANNEX_A}, + {"DVBC_ANNEX_A", DVB_SYS_DVBC_ANNEX_A}, + {"ATSC-C", DVB_SYS_DVBC_ANNEX_B}, + {"CableCARD", DVB_SYS_DVBC_ANNEX_B}, + {"DVBC/ANNEX_B", DVB_SYS_DVBC_ANNEX_B}, + {"DVBC_ANNEX_B", DVB_SYS_DVBC_ANNEX_B}, + {"DVB-C/ANNEX-C", DVB_SYS_DVBC_ANNEX_C}, + {"DVBC/ANNEX_C", DVB_SYS_DVBC_ANNEX_C}, + {"DVBC_ANNEX_C", DVB_SYS_DVBC_ANNEX_C}, + {"DVBC_ANNEX_AC", DVB_SYS_DVBC_ANNEX_A}, /* for compatibility */ + {"DVB-T", DVB_SYS_DVBT}, + {"DVBT", DVB_SYS_DVBT}, + {"DVB-T2", DVB_SYS_DVBT2}, + {"DVBT2", DVB_SYS_DVBT2}, + {"DVB-S", DVB_SYS_DVBS}, + {"DVBS", DVB_SYS_DVBS}, + {"DVB-S2", DVB_SYS_DVBS2}, + {"DVBS2", DVB_SYS_DVBS2}, + {"DVB-H", DVB_SYS_DVBH}, + {"DVBH", DVB_SYS_DVBH}, + {"ISDB-T", DVB_SYS_ISDBT}, + {"ISDBT", DVB_SYS_ISDBT}, + {"ISDB-S", DVB_SYS_ISDBS}, + {"ISDBS", DVB_SYS_ISDBS}, + {"ISDB-C", DVB_SYS_ISDBC}, + {"ISDBC", DVB_SYS_ISDBC}, + {"ATSC-T", DVB_SYS_ATSC}, + {"ATSC", DVB_SYS_ATSC}, + {"ATSCM-H", DVB_SYS_ATSCMH}, + {"ATSCMH", DVB_SYS_ATSCMH}, + {"DTMB", DVB_SYS_DTMB}, + {"DMBTH", DVB_SYS_DTMB}, /* for compatibility */ + {"CMMB", DVB_SYS_CMMB}, + {"DAB", DVB_SYS_DAB}, + {"DSS", DVB_SYS_DSS}, + {"TURBO", DVB_SYS_TURBO}}; dvb_str2val(delsys); -int -dvb_delsys2type ( mpegts_network_t *ln, dvb_fe_delivery_system_t delsys ) -{ +int dvb_delsys2type(mpegts_network_t* ln, dvb_fe_delivery_system_t delsys) { switch (delsys) { case DVB_SYS_DVBC_ANNEX_A: case DVB_SYS_DVBC_ANNEX_C: @@ -839,55 +843,53 @@ dvb_delsys2type ( mpegts_network_t *ln, dvb_fe_delivery_system_t delsys ) } } -const char *dvb_fec2str(int p) -{ +const char* dvb_fec2str(int p) { static __thread char buf[16]; - const char *res = dvb_common2str(p); + const char* res = dvb_common2str(p); if (res) return res; sprintf(buf, "%i/%i", p / 100, p % 100); return buf; } -int dvb_str2fec(const char *p) -{ +int dvb_str2fec(const char* p) { static int fec_table[] = { - DVB_FEC_1_2, - DVB_FEC_1_3, - DVB_FEC_1_4, - DVB_FEC_1_5, - DVB_FEC_2_3, - DVB_FEC_2_5, - DVB_FEC_2_9, - DVB_FEC_3_4, - DVB_FEC_3_5, - DVB_FEC_4_5, - DVB_FEC_4_15, - DVB_FEC_5_6, - DVB_FEC_5_9, - DVB_FEC_6_7, - DVB_FEC_7_8, - DVB_FEC_7_9, - DVB_FEC_7_15, - DVB_FEC_8_9, - DVB_FEC_8_15, - DVB_FEC_9_10, - DVB_FEC_9_20, - DVB_FEC_11_15, - DVB_FEC_11_20, - DVB_FEC_11_45, - DVB_FEC_13_18, - DVB_FEC_13_45, - DVB_FEC_14_45, - DVB_FEC_23_36, - DVB_FEC_25_36, - DVB_FEC_26_45, - DVB_FEC_28_45, - DVB_FEC_29_45, - DVB_FEC_31_45, - DVB_FEC_32_45, - DVB_FEC_77_90, - DVB_EOD, + DVB_FEC_1_2, + DVB_FEC_1_3, + DVB_FEC_1_4, + DVB_FEC_1_5, + DVB_FEC_2_3, + DVB_FEC_2_5, + DVB_FEC_2_9, + DVB_FEC_3_4, + DVB_FEC_3_5, + DVB_FEC_4_5, + DVB_FEC_4_15, + DVB_FEC_5_6, + DVB_FEC_5_9, + DVB_FEC_6_7, + DVB_FEC_7_8, + DVB_FEC_7_9, + DVB_FEC_7_15, + DVB_FEC_8_9, + DVB_FEC_8_15, + DVB_FEC_9_10, + DVB_FEC_9_20, + DVB_FEC_11_15, + DVB_FEC_11_20, + DVB_FEC_11_45, + DVB_FEC_13_18, + DVB_FEC_13_45, + DVB_FEC_14_45, + DVB_FEC_23_36, + DVB_FEC_25_36, + DVB_FEC_26_45, + DVB_FEC_28_45, + DVB_FEC_29_45, + DVB_FEC_31_45, + DVB_FEC_32_45, + DVB_FEC_77_90, + DVB_EOD, }; int res = dvb_str2common(p); int hi, lo; @@ -899,53 +901,52 @@ int dvb_str2fec(const char *p) } static const struct strtab qamtab[] = { - { "NONE", DVB_MOD_NONE }, - { "AUTO", DVB_MOD_AUTO }, - { "QPSK", DVB_MOD_QPSK }, - { "QAM4NR", DVB_MOD_QAM_4_NR }, - { "QAM/AUTO", DVB_MOD_QAM_AUTO }, - { "QAM-AUTO", DVB_MOD_QAM_AUTO }, - { "QAM/16", DVB_MOD_QAM_16 }, - { "QAM16", DVB_MOD_QAM_16 }, - { "QAM/32", DVB_MOD_QAM_32 }, - { "QAM32", DVB_MOD_QAM_32 }, - { "QAM/64", DVB_MOD_QAM_64 }, - { "QAM64", DVB_MOD_QAM_64 }, - { "QAM/128", DVB_MOD_QAM_128 }, - { "QAM128", DVB_MOD_QAM_128 }, - { "QAM/256", DVB_MOD_QAM_256 }, - { "QAM256", DVB_MOD_QAM_256 }, - { "QAM/1024", DVB_MOD_QAM_1024 }, - { "QAM1024", DVB_MOD_QAM_1024 }, - { "QAM/4096", DVB_MOD_QAM_4096 }, - { "QAM4096", DVB_MOD_QAM_4096 }, - { "VSB/8", DVB_MOD_VSB_8 }, - { "8VSB", DVB_MOD_VSB_8 }, - { "VSB/16", DVB_MOD_VSB_16 }, - { "16VSB", DVB_MOD_VSB_16 }, - { "PSK/8", DVB_MOD_PSK_8 }, - { "8PSK", DVB_MOD_PSK_8 }, - { "DQPSK", DVB_MOD_DQPSK }, - { "BPSK", DVB_MOD_BPSK }, - { "BPSK-S", DVB_MOD_BPSK_S }, - { "16APSK", DVB_MOD_APSK_16 }, - { "32APSK", DVB_MOD_APSK_32 }, - { "64APSK", DVB_MOD_APSK_64 }, - { "128APSK", DVB_MOD_APSK_128 }, - { "256APSK", DVB_MOD_APSK_256 }, - { "8APSK-L", DVB_MOD_APSK_8_L }, - { "16APSK-L", DVB_MOD_APSK_16_L }, - { "32APSK-L", DVB_MOD_APSK_32_L }, - { "64APSK-L", DVB_MOD_APSK_64_L }, - { "128APSK-L", DVB_MOD_APSK_128_L }, - { "256APSK-L", DVB_MOD_APSK_256_L }, + {"NONE", DVB_MOD_NONE}, + {"AUTO", DVB_MOD_AUTO}, + {"QPSK", DVB_MOD_QPSK}, + {"QAM4NR", DVB_MOD_QAM_4_NR}, + {"QAM/AUTO", DVB_MOD_QAM_AUTO}, + {"QAM-AUTO", DVB_MOD_QAM_AUTO}, + {"QAM/16", DVB_MOD_QAM_16}, + {"QAM16", DVB_MOD_QAM_16}, + {"QAM/32", DVB_MOD_QAM_32}, + {"QAM32", DVB_MOD_QAM_32}, + {"QAM/64", DVB_MOD_QAM_64}, + {"QAM64", DVB_MOD_QAM_64}, + {"QAM/128", DVB_MOD_QAM_128}, + {"QAM128", DVB_MOD_QAM_128}, + {"QAM/256", DVB_MOD_QAM_256}, + {"QAM256", DVB_MOD_QAM_256}, + {"QAM/1024", DVB_MOD_QAM_1024}, + {"QAM1024", DVB_MOD_QAM_1024}, + {"QAM/4096", DVB_MOD_QAM_4096}, + {"QAM4096", DVB_MOD_QAM_4096}, + {"VSB/8", DVB_MOD_VSB_8}, + {"8VSB", DVB_MOD_VSB_8}, + {"VSB/16", DVB_MOD_VSB_16}, + {"16VSB", DVB_MOD_VSB_16}, + {"PSK/8", DVB_MOD_PSK_8}, + {"8PSK", DVB_MOD_PSK_8}, + {"DQPSK", DVB_MOD_DQPSK}, + {"BPSK", DVB_MOD_BPSK}, + {"BPSK-S", DVB_MOD_BPSK_S}, + {"16APSK", DVB_MOD_APSK_16}, + {"32APSK", DVB_MOD_APSK_32}, + {"64APSK", DVB_MOD_APSK_64}, + {"128APSK", DVB_MOD_APSK_128}, + {"256APSK", DVB_MOD_APSK_256}, + {"8APSK-L", DVB_MOD_APSK_8_L}, + {"16APSK-L", DVB_MOD_APSK_16_L}, + {"32APSK-L", DVB_MOD_APSK_32_L}, + {"64APSK-L", DVB_MOD_APSK_64_L}, + {"128APSK-L", DVB_MOD_APSK_128_L}, + {"256APSK-L", DVB_MOD_APSK_256_L}, }; dvb_str2val(qam); -const char *dvb_bw2str(int p) -{ +const char* dvb_bw2str(int p) { static __thread char buf[17]; - const char *res = dvb_common2str(p); + const char* res = dvb_common2str(p); if (res) return res; if (p % 1000) @@ -955,16 +956,15 @@ const char *dvb_bw2str(int p) return buf; } -int dvb_str2bw(const char *p) -{ +int dvb_str2bw(const char* p) { static int bw_table[] = { - DVB_BANDWIDTH_1_712_MHZ, - DVB_BANDWIDTH_5_MHZ, - DVB_BANDWIDTH_6_MHZ, - DVB_BANDWIDTH_7_MHZ, - DVB_BANDWIDTH_8_MHZ, - DVB_BANDWIDTH_10_MHZ, - DVB_EOD, + DVB_BANDWIDTH_1_712_MHZ, + DVB_BANDWIDTH_5_MHZ, + DVB_BANDWIDTH_6_MHZ, + DVB_BANDWIDTH_7_MHZ, + DVB_BANDWIDTH_8_MHZ, + DVB_BANDWIDTH_10_MHZ, + DVB_EOD, }; int len, res = dvb_str2common(p); int hi, lo; @@ -973,112 +973,103 @@ int dvb_str2bw(const char *p) len = strlen(p); hi = lo = 0; sscanf(p, "%i.%i", &hi, &lo); - if (len > 3 && strcmp(&p[len-3], "MHz") == 0) + if (len > 3 && strcmp(&p[len - 3], "MHz") == 0) hi = hi * 1000 + lo; return dvb_verify(hi, bw_table); } static const struct strtab invertab[] = { - { "NONE", DVB_INVERSION_UNDEFINED }, - { "AUTO", DVB_INVERSION_AUTO }, - { "ON", DVB_INVERSION_ON }, - { "OFF", DVB_INVERSION_OFF }, + {"NONE", DVB_INVERSION_UNDEFINED}, + {"AUTO", DVB_INVERSION_AUTO}, + {"ON", DVB_INVERSION_ON}, + {"OFF", DVB_INVERSION_OFF}, }; dvb_str2val(inver); static const struct strtab modetab[] = { - { "NONE", DVB_TRANSMISSION_MODE_NONE }, - { "AUTO", DVB_TRANSMISSION_MODE_AUTO }, - { "1k", DVB_TRANSMISSION_MODE_1K }, - { "2k", DVB_TRANSMISSION_MODE_2K }, - { "8k", DVB_TRANSMISSION_MODE_8K }, - { "4k", DVB_TRANSMISSION_MODE_4K }, - { "16k", DVB_TRANSMISSION_MODE_16K }, - { "32k", DVB_TRANSMISSION_MODE_32K }, - { "C1", DVB_TRANSMISSION_MODE_C1 }, - { "C3780", DVB_TRANSMISSION_MODE_C3780 }, + {"NONE", DVB_TRANSMISSION_MODE_NONE}, + {"AUTO", DVB_TRANSMISSION_MODE_AUTO}, + {"1k", DVB_TRANSMISSION_MODE_1K}, + {"2k", DVB_TRANSMISSION_MODE_2K}, + {"8k", DVB_TRANSMISSION_MODE_8K}, + {"4k", DVB_TRANSMISSION_MODE_4K}, + {"16k", DVB_TRANSMISSION_MODE_16K}, + {"32k", DVB_TRANSMISSION_MODE_32K}, + {"C1", DVB_TRANSMISSION_MODE_C1}, + {"C3780", DVB_TRANSMISSION_MODE_C3780}, }; dvb_str2val(mode); static const struct strtab guardtab[] = { - { "NONE", DVB_GUARD_INTERVAL_NONE }, - { "AUTO", DVB_GUARD_INTERVAL_AUTO }, - { "1/4", DVB_GUARD_INTERVAL_1_4 }, - { "1/8", DVB_GUARD_INTERVAL_1_8 }, - { "1/32", DVB_GUARD_INTERVAL_1_32 }, - { "1/16", DVB_GUARD_INTERVAL_1_16 }, - { "1/128", DVB_GUARD_INTERVAL_1_128 }, - { "19/128", DVB_GUARD_INTERVAL_19_128 }, - { "19/256", DVB_GUARD_INTERVAL_19_256 }, - { "PN420", DVB_GUARD_INTERVAL_PN420 }, - { "PN595", DVB_GUARD_INTERVAL_PN595 }, - { "PN945", DVB_GUARD_INTERVAL_PN945 }, + {"NONE", DVB_GUARD_INTERVAL_NONE}, + {"AUTO", DVB_GUARD_INTERVAL_AUTO}, + {"1/4", DVB_GUARD_INTERVAL_1_4}, + {"1/8", DVB_GUARD_INTERVAL_1_8}, + {"1/32", DVB_GUARD_INTERVAL_1_32}, + {"1/16", DVB_GUARD_INTERVAL_1_16}, + {"1/128", DVB_GUARD_INTERVAL_1_128}, + {"19/128", DVB_GUARD_INTERVAL_19_128}, + {"19/256", DVB_GUARD_INTERVAL_19_256}, + {"PN420", DVB_GUARD_INTERVAL_PN420}, + {"PN595", DVB_GUARD_INTERVAL_PN595}, + {"PN945", DVB_GUARD_INTERVAL_PN945}, }; dvb_str2val(guard); static const struct strtab hiertab[] = { - { "NONE", DVB_HIERARCHY_NONE }, - { "AUTO", DVB_HIERARCHY_AUTO }, - { "1", DVB_HIERARCHY_1 }, - { "2", DVB_HIERARCHY_2 }, - { "4", DVB_HIERARCHY_4 }, + {"NONE", DVB_HIERARCHY_NONE}, + {"AUTO", DVB_HIERARCHY_AUTO}, + {"1", DVB_HIERARCHY_1}, + {"2", DVB_HIERARCHY_2}, + {"4", DVB_HIERARCHY_4}, }; dvb_str2val(hier); static const struct strtab poltab[] = { - { "V", DVB_POLARISATION_VERTICAL }, - { "H", DVB_POLARISATION_HORIZONTAL }, - { "L", DVB_POLARISATION_CIRCULAR_LEFT }, - { "R", DVB_POLARISATION_CIRCULAR_RIGHT }, - { "O", DVB_POLARISATION_OFF }, + {"V", DVB_POLARISATION_VERTICAL}, + {"H", DVB_POLARISATION_HORIZONTAL}, + {"L", DVB_POLARISATION_CIRCULAR_LEFT}, + {"R", DVB_POLARISATION_CIRCULAR_RIGHT}, + {"O", DVB_POLARISATION_OFF}, }; dvb_str2val(pol); -static const struct strtab typetab[] = { - {"DVB-T", DVB_TYPE_T}, - {"DVB-C", DVB_TYPE_C}, - {"DVB-S", DVB_TYPE_S}, - {"ATSC-T", DVB_TYPE_ATSC_T}, - {"ATSC-C", DVB_TYPE_ATSC_C}, - {"CableCARD", DVB_TYPE_CABLECARD}, - {"ISDB-T", DVB_TYPE_ISDB_T}, - {"ISDB-C", DVB_TYPE_ISDB_C}, - {"ISDB-S", DVB_TYPE_ISDB_S}, - {"DAB", DVB_TYPE_DAB}, - {"DVBT", DVB_TYPE_T}, - {"DVBC", DVB_TYPE_C}, - {"DVBS", DVB_TYPE_S}, - {"ATSC", DVB_TYPE_ATSC_T}, - {"ATSCT", DVB_TYPE_ATSC_T}, - {"ATSCC", DVB_TYPE_ATSC_C}, - {"ISDBT", DVB_TYPE_ISDB_T}, - {"ISDBC", DVB_TYPE_ISDB_C}, - {"ISDBS", DVB_TYPE_ISDB_S} -}; +static const struct strtab typetab[] = {{"DVB-T", DVB_TYPE_T}, + {"DVB-C", DVB_TYPE_C}, + {"DVB-S", DVB_TYPE_S}, + {"ATSC-T", DVB_TYPE_ATSC_T}, + {"ATSC-C", DVB_TYPE_ATSC_C}, + {"CableCARD", DVB_TYPE_CABLECARD}, + {"ISDB-T", DVB_TYPE_ISDB_T}, + {"ISDB-C", DVB_TYPE_ISDB_C}, + {"ISDB-S", DVB_TYPE_ISDB_S}, + {"DAB", DVB_TYPE_DAB}, + {"DVBT", DVB_TYPE_T}, + {"DVBC", DVB_TYPE_C}, + {"DVBS", DVB_TYPE_S}, + {"ATSC", DVB_TYPE_ATSC_T}, + {"ATSCT", DVB_TYPE_ATSC_T}, + {"ATSCC", DVB_TYPE_ATSC_C}, + {"ISDBT", DVB_TYPE_ISDB_T}, + {"ISDBC", DVB_TYPE_ISDB_C}, + {"ISDBS", DVB_TYPE_ISDB_S}}; dvb_str2val(type); -static const struct strtab pilottab[] = { - {"NONE", DVB_PILOT_NONE}, - {"AUTO", DVB_PILOT_AUTO}, - {"ON", DVB_PILOT_ON}, - {"OFF", DVB_PILOT_OFF} -}; +static const struct strtab pilottab[] = {{"NONE", DVB_PILOT_NONE}, + {"AUTO", DVB_PILOT_AUTO}, + {"ON", DVB_PILOT_ON}, + {"OFF", DVB_PILOT_OFF}}; dvb_str2val(pilot); static const struct strtab plsmodetab[] = { - {"ROOT", DVB_PLS_ROOT}, - {"GOLD", DVB_PLS_GOLD}, - {"COMBO", DVB_PLS_COMBO}, + {"ROOT", DVB_PLS_ROOT}, + {"GOLD", DVB_PLS_GOLD}, + {"COMBO", DVB_PLS_COMBO}, }; dvb_str2val(plsmode); #undef dvb_str2val - -void -dvb_mux_conf_init ( mpegts_network_t *ln, - dvb_mux_conf_t *dmc, - dvb_fe_delivery_system_t delsys ) -{ +void dvb_mux_conf_init(mpegts_network_t* ln, dvb_mux_conf_t* dmc, dvb_fe_delivery_system_t delsys) { memset(dmc, 0, sizeof(*dmc)); dmc->dmc_fe_type = dvb_delsys2type(ln, delsys); dmc->dmc_fe_delsys = delsys; @@ -1087,157 +1078,145 @@ dvb_mux_conf_init ( mpegts_network_t *ln, dmc->dmc_fe_stream_id = DVB_NO_STREAM_ID_FILTER; dmc->dmc_fe_pls_mode = DVB_PLS_GOLD; switch (dmc->dmc_fe_type) { - case DVB_TYPE_S: - dmc->u.dmc_fe_qpsk.orbital_pos = INT_MAX; - break; - default: - break; + case DVB_TYPE_S: + dmc->u.dmc_fe_qpsk.orbital_pos = INT_MAX; + break; + default: + break; } } - -static int -dvb_mux_conf_str_dvbt ( dvb_mux_conf_t *dmc, char *buf, size_t bufsize ) -{ +static int dvb_mux_conf_str_dvbt(dvb_mux_conf_t* dmc, char* buf, size_t bufsize) { char hp[16]; snprintf(hp, sizeof(hp), "%s", dvb_fec2str(dmc->u.dmc_fe_ofdm.code_rate_HP)); - return - snprintf(buf, bufsize, - "%s freq %d bw %s cons %s hier %s code_rate %s:%s guard %s trans %s plp_id %d", - dvb_delsys2str(dmc->dmc_fe_delsys), - dmc->dmc_fe_freq, - dvb_bw2str(dmc->u.dmc_fe_ofdm.bandwidth), - dvb_qam2str(dmc->dmc_fe_modulation), - dvb_hier2str(dmc->u.dmc_fe_ofdm.hierarchy_information), - hp, dvb_fec2str(dmc->u.dmc_fe_ofdm.code_rate_LP), - dvb_guard2str(dmc->u.dmc_fe_ofdm.guard_interval), - dvb_mode2str(dmc->u.dmc_fe_ofdm.transmission_mode), - dmc->dmc_fe_stream_id); + return snprintf(buf, + bufsize, + "%s freq %d bw %s cons %s hier %s code_rate %s:%s guard %s trans %s plp_id %d", + dvb_delsys2str(dmc->dmc_fe_delsys), + dmc->dmc_fe_freq, + dvb_bw2str(dmc->u.dmc_fe_ofdm.bandwidth), + dvb_qam2str(dmc->dmc_fe_modulation), + dvb_hier2str(dmc->u.dmc_fe_ofdm.hierarchy_information), + hp, + dvb_fec2str(dmc->u.dmc_fe_ofdm.code_rate_LP), + dvb_guard2str(dmc->u.dmc_fe_ofdm.guard_interval), + dvb_mode2str(dmc->u.dmc_fe_ofdm.transmission_mode), + dmc->dmc_fe_stream_id); } -static int -dvb_mux_conf_str_dvbc ( dvb_mux_conf_t *dmc, char *buf, size_t bufsize ) -{ - const char *delsys; - if (dmc->dmc_fe_type == DVB_TYPE_C && - dmc->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_B) +static int dvb_mux_conf_str_dvbc(dvb_mux_conf_t* dmc, char* buf, size_t bufsize) { + const char* delsys; + if (dmc->dmc_fe_type == DVB_TYPE_C && dmc->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_B) delsys = "DVB-C/ANNEX_B"; else delsys = dvb_delsys2str(dmc->dmc_fe_delsys); - return - snprintf(buf, bufsize, - "%s freq %d sym %d mod %s fec %s ds %d plp %d", - delsys, - dmc->dmc_fe_freq, - dmc->u.dmc_fe_qam.symbol_rate, - dvb_qam2str(dmc->dmc_fe_modulation), - dvb_fec2str(dmc->u.dmc_fe_qam.fec_inner), - dmc->dmc_fe_data_slice, - dmc->dmc_fe_stream_id); + return snprintf(buf, + bufsize, + "%s freq %d sym %d mod %s fec %s ds %d plp %d", + delsys, + dmc->dmc_fe_freq, + dmc->u.dmc_fe_qam.symbol_rate, + dvb_qam2str(dmc->dmc_fe_modulation), + dvb_fec2str(dmc->u.dmc_fe_qam.fec_inner), + dmc->dmc_fe_data_slice, + dmc->dmc_fe_stream_id); } -static int -dvb_mux_conf_str_dvbs ( dvb_mux_conf_t *dmc, char *buf, size_t bufsize ) -{ - const char *pol = dvb_pol2str(dmc->u.dmc_fe_qpsk.polarisation); - const int satpos = dmc->u.dmc_fe_qpsk.orbital_pos; - char satbuf[16]; +static int dvb_mux_conf_str_dvbs(dvb_mux_conf_t* dmc, char* buf, size_t bufsize) { + const char* pol = dvb_pol2str(dmc->u.dmc_fe_qpsk.polarisation); + const int satpos = dmc->u.dmc_fe_qpsk.orbital_pos; + char satbuf[16]; if (satpos != INT_MAX) { - snprintf(satbuf, sizeof(satbuf), "%d.%d%c ", abs(satpos) / 10, abs(satpos) % 10, satpos < 0 ? 'W' : 'E'); + snprintf(satbuf, + sizeof(satbuf), + "%d.%d%c ", + abs(satpos) / 10, + abs(satpos) % 10, + satpos < 0 ? 'W' : 'E'); } else { satbuf[0] = '\0'; } - return - snprintf(buf, bufsize, - "%s %sfreq %d %c sym %d fec %s mod %s roff %s is_id %d pls_mode %s pls_code %d", - dvb_delsys2str(dmc->dmc_fe_delsys), - satbuf, - dmc->dmc_fe_freq, - pol ? pol[0] : 'X', - dmc->u.dmc_fe_qpsk.symbol_rate, - dvb_fec2str(dmc->u.dmc_fe_qpsk.fec_inner), - dvb_qam2str(dmc->dmc_fe_modulation), - dvb_rolloff2str(dmc->dmc_fe_rolloff), - dmc->dmc_fe_stream_id, - dvb_plsmode2str(dmc->dmc_fe_pls_mode), - dmc->dmc_fe_pls_code); + return snprintf(buf, + bufsize, + "%s %sfreq %d %c sym %d fec %s mod %s roff %s is_id %d pls_mode %s pls_code %d", + dvb_delsys2str(dmc->dmc_fe_delsys), + satbuf, + dmc->dmc_fe_freq, + pol ? pol[0] : 'X', + dmc->u.dmc_fe_qpsk.symbol_rate, + dvb_fec2str(dmc->u.dmc_fe_qpsk.fec_inner), + dvb_qam2str(dmc->dmc_fe_modulation), + dvb_rolloff2str(dmc->dmc_fe_rolloff), + dmc->dmc_fe_stream_id, + dvb_plsmode2str(dmc->dmc_fe_pls_mode), + dmc->dmc_fe_pls_code); } -static int -dvb_mux_conf_str_atsc_t ( dvb_mux_conf_t *dmc, char *buf, size_t bufsize ) -{ - return - snprintf(buf, bufsize, - "%s freq %d mod %s", - dvb_delsys2str(dmc->dmc_fe_delsys), - dmc->dmc_fe_freq, - dvb_qam2str(dmc->dmc_fe_modulation)); +static int dvb_mux_conf_str_atsc_t(dvb_mux_conf_t* dmc, char* buf, size_t bufsize) { + return snprintf(buf, + bufsize, + "%s freq %d mod %s", + dvb_delsys2str(dmc->dmc_fe_delsys), + dmc->dmc_fe_freq, + dvb_qam2str(dmc->dmc_fe_modulation)); } -static int -dvb_mux_conf_str_cablecard(dvb_mux_conf_t *dmc, char *buf, size_t bufsize) -{ - return snprintf(buf, bufsize, "%s channel %u", +static int dvb_mux_conf_str_cablecard(dvb_mux_conf_t* dmc, char* buf, size_t bufsize) { + return snprintf(buf, + bufsize, + "%s channel %u", dvb_type2str(dmc->dmc_fe_type), dmc->u.dmc_fe_cablecard.vchannel); } -static int -dvb_mux_conf_str_isdb_t ( dvb_mux_conf_t *dmc, char *buf, size_t bufsize ) -{ +static int dvb_mux_conf_str_isdb_t(dvb_mux_conf_t* dmc, char* buf, size_t bufsize) { char hp[16]; snprintf(hp, sizeof(hp), "%s", dvb_fec2str(dmc->u.dmc_fe_ofdm.code_rate_HP)); - return - snprintf(buf, bufsize, - "%s freq %d bw %s guard %s A (%s,%s,%d,%d) B (%s,%s,%d,%d) C (%s,%s,%d,%d)", - dvb_delsys2str(dmc->dmc_fe_delsys), - dmc->dmc_fe_freq, - dvb_bw2str(dmc->u.dmc_fe_isdbt.bandwidth), - dvb_guard2str(dmc->u.dmc_fe_isdbt.guard_interval), - dvb_fec2str(dmc->u.dmc_fe_isdbt.layers[0].fec), - dvb_qam2str(dmc->u.dmc_fe_isdbt.layers[0].modulation), - dmc->u.dmc_fe_isdbt.layers[0].segment_count, - dmc->u.dmc_fe_isdbt.layers[0].time_interleaving, - dvb_fec2str(dmc->u.dmc_fe_isdbt.layers[1].fec), - dvb_qam2str(dmc->u.dmc_fe_isdbt.layers[1].modulation), - dmc->u.dmc_fe_isdbt.layers[1].segment_count, - dmc->u.dmc_fe_isdbt.layers[1].time_interleaving, - dvb_fec2str(dmc->u.dmc_fe_isdbt.layers[2].fec), - dvb_qam2str(dmc->u.dmc_fe_isdbt.layers[2].modulation), - dmc->u.dmc_fe_isdbt.layers[2].segment_count, - dmc->u.dmc_fe_isdbt.layers[2].time_interleaving); + return snprintf(buf, + bufsize, + "%s freq %d bw %s guard %s A (%s,%s,%d,%d) B (%s,%s,%d,%d) C (%s,%s,%d,%d)", + dvb_delsys2str(dmc->dmc_fe_delsys), + dmc->dmc_fe_freq, + dvb_bw2str(dmc->u.dmc_fe_isdbt.bandwidth), + dvb_guard2str(dmc->u.dmc_fe_isdbt.guard_interval), + dvb_fec2str(dmc->u.dmc_fe_isdbt.layers[0].fec), + dvb_qam2str(dmc->u.dmc_fe_isdbt.layers[0].modulation), + dmc->u.dmc_fe_isdbt.layers[0].segment_count, + dmc->u.dmc_fe_isdbt.layers[0].time_interleaving, + dvb_fec2str(dmc->u.dmc_fe_isdbt.layers[1].fec), + dvb_qam2str(dmc->u.dmc_fe_isdbt.layers[1].modulation), + dmc->u.dmc_fe_isdbt.layers[1].segment_count, + dmc->u.dmc_fe_isdbt.layers[1].time_interleaving, + dvb_fec2str(dmc->u.dmc_fe_isdbt.layers[2].fec), + dvb_qam2str(dmc->u.dmc_fe_isdbt.layers[2].modulation), + dmc->u.dmc_fe_isdbt.layers[2].segment_count, + dmc->u.dmc_fe_isdbt.layers[2].time_interleaving); } -int -dvb_mux_conf_str ( dvb_mux_conf_t *dmc, char *buf, size_t bufsize ) -{ +int dvb_mux_conf_str(dvb_mux_conf_t* dmc, char* buf, size_t bufsize) { switch (dmc->dmc_fe_type) { - case DVB_TYPE_NONE: - return - snprintf(buf, bufsize, "NONE %s", dvb_delsys2str(dmc->dmc_fe_delsys)); - case DVB_TYPE_T: - return dvb_mux_conf_str_dvbt(dmc, buf, bufsize); - case DVB_TYPE_C: - case DVB_TYPE_ATSC_C: - case DVB_TYPE_ISDB_C: - return dvb_mux_conf_str_dvbc(dmc, buf, bufsize); - case DVB_TYPE_S: - return dvb_mux_conf_str_dvbs(dmc, buf, bufsize); - case DVB_TYPE_ATSC_T: - return dvb_mux_conf_str_atsc_t(dmc, buf, bufsize); - case DVB_TYPE_CABLECARD: - return dvb_mux_conf_str_cablecard(dmc, buf, bufsize); - case DVB_TYPE_ISDB_T: - return dvb_mux_conf_str_isdb_t(dmc, buf, bufsize); - default: - return - snprintf(buf, bufsize, "UNKNOWN MUX CONFIG"); + case DVB_TYPE_NONE: + return snprintf(buf, bufsize, "NONE %s", dvb_delsys2str(dmc->dmc_fe_delsys)); + case DVB_TYPE_T: + return dvb_mux_conf_str_dvbt(dmc, buf, bufsize); + case DVB_TYPE_C: + case DVB_TYPE_ATSC_C: + case DVB_TYPE_ISDB_C: + return dvb_mux_conf_str_dvbc(dmc, buf, bufsize); + case DVB_TYPE_S: + return dvb_mux_conf_str_dvbs(dmc, buf, bufsize); + case DVB_TYPE_ATSC_T: + return dvb_mux_conf_str_atsc_t(dmc, buf, bufsize); + case DVB_TYPE_CABLECARD: + return dvb_mux_conf_str_cablecard(dmc, buf, bufsize); + case DVB_TYPE_ISDB_T: + return dvb_mux_conf_str_isdb_t(dmc, buf, bufsize); + default: + return snprintf(buf, bufsize, "UNKNOWN MUX CONFIG"); } } -const char * -dvb_sat_position_to_str(int position, char *buf, size_t buflen) -{ +const char* dvb_sat_position_to_str(int position, char* buf, size_t buflen) { const int dec = position % 10; if (!buf || !buflen) @@ -1249,12 +1228,10 @@ dvb_sat_position_to_str(int position, char *buf, size_t buflen) return buf; } -int -dvb_sat_position_from_str( const char *buf ) -{ - const char *s = buf; - int min, maj; - char c; +int dvb_sat_position_from_str(const char* buf) { + const char* s = buf; + int min, maj; + char c; if (!buf) return INT_MAX; @@ -1262,7 +1239,8 @@ dvb_sat_position_from_str( const char *buf ) while (*s && *s != '.') s++; min = *s == '.' ? atoi(s + 1) : 0; - if (*s != '.') s = buf; + if (*s != '.') + s = buf; do { c = *s++; } while (c && c != 'W' && c != 'E'); @@ -1275,14 +1253,12 @@ dvb_sat_position_from_str( const char *buf ) return (maj * 10 + min) * (c == 'W' ? -1 : 1); } -uint32_t -dvb_sat_pls( dvb_mux_conf_t *dmc ) -{ +uint32_t dvb_sat_pls(dvb_mux_conf_t* dmc) { if (dmc->dmc_fe_pls_mode == DVB_PLS_ROOT) { - uint32_t x, g; + uint32_t x, g; const uint32_t root = dmc->dmc_fe_pls_code & 0x3ffff; - for (g = 0, x = 1; g < 0x3ffff; g++) { + for (g = 0, x = 1; g < 0x3ffff; g++) { if (root == x) return g; x = (((x ^ (x >> 7)) & 1) << 17) | (x >> 1); @@ -1297,15 +1273,13 @@ dvb_sat_pls( dvb_mux_conf_t *dmc ) /** * */ -void dvb_init( void ) -{ +void dvb_init(void) { #if ENABLE_MPEGTS_DVB satellites = hts_settings_load("satellites"); #endif } -void dvb_done( void ) -{ +void dvb_done(void) { #if ENABLE_MPEGTS_DVB htsmsg_destroy(satellites); #endif diff --git a/src/input/mpegts/en50221/en50221.c b/src/input/mpegts/en50221/en50221.c index 0c4bee8f3..21d06bf40 100644 --- a/src/input/mpegts/en50221/en50221.c +++ b/src/input/mpegts/en50221/en50221.c @@ -30,47 +30,39 @@ * slot structure, because there is 1:1 mapping. */ -static int en50221_slot_create - (en50221_transport_t *cit, uint8_t number, en50221_slot_t **cil); -static void en50221_slot_destroy(en50221_slot_t *cil); -static int en50221_slot_connection_initiated(en50221_slot_t *cil); -static void en50221_slot_reset(en50221_slot_t *cil); -static int en50221_slot_trigger_write_queue(en50221_slot_t *cil); +static int en50221_slot_create(en50221_transport_t* cit, uint8_t number, en50221_slot_t** cil); +static void en50221_slot_destroy(en50221_slot_t* cil); +static int en50221_slot_connection_initiated(en50221_slot_t* cil); +static void en50221_slot_reset(en50221_slot_t* cil); +static int en50221_slot_trigger_write_queue(en50221_slot_t* cil); #if 0 static int en50221_slot_session_create (en50221_slot_t *cil, uint32_t resource_id); #endif -static int en50221_slot_spdu_recv - (en50221_slot_t *cil, const uint8_t *data, size_t datalen); -static int en50221_slot_monitor(en50221_slot_t *cil, int64_t clock); -static int en50221_create_app - (en50221_slot_t *cil, uint32_t resource_id, - uint16_t session_id, en50221_app_t **cia); -static void en50221_app_destroy(en50221_app_t *cia); -static int en50221_app_handle - (en50221_app_t *cia, uint8_t status, const uint8_t *data, size_t datalen); -static int en50221_app_open(en50221_app_t *cia); -static int en50221_app_monitor(en50221_app_t *cia, int64_t clock); +static int en50221_slot_spdu_recv(en50221_slot_t* cil, const uint8_t* data, size_t datalen); +static int en50221_slot_monitor(en50221_slot_t* cil, int64_t clock); +static int en50221_create_app(en50221_slot_t* cil, + uint32_t resource_id, + uint16_t session_id, + en50221_app_t** cia); +static void en50221_app_destroy(en50221_app_t* cia); +static int +en50221_app_handle(en50221_app_t* cia, uint8_t status, const uint8_t* data, size_t datalen); +static int en50221_app_open(en50221_app_t* cia); +static int en50221_app_monitor(en50221_app_t* cia, int64_t clock); /* * Misc */ -static inline uint32_t get32(const uint8_t *p) -{ - return (((uint32_t)p[0]) << 24) | - (((uint32_t)p[1]) << 16) | - (((uint32_t)p[2]) << 8) | - p[3]; +static inline uint32_t get32(const uint8_t* p) { + return (((uint32_t)p[0]) << 24) | (((uint32_t)p[1]) << 16) | (((uint32_t)p[2]) << 8) | p[3]; } -static inline uint32_t getatag(const uint8_t *p, size_t l) -{ +static inline uint32_t getatag(const uint8_t* p, size_t l) { if (l < 3) return CICAM_AOT_NONE + l; - return (((uint32_t)p[0]) << 16) | - (((uint32_t)p[1]) << 8) | - p[2]; + return (((uint32_t)p[0]) << 16) | (((uint32_t)p[1]) << 8) | p[2]; } /* @@ -78,62 +70,61 @@ static inline uint32_t getatag(const uint8_t *p, size_t l) */ #define CICAM_TDPU_SIZE 4096 -#define CICAM_TDPU_DATA_SIZE (CICAM_TDPU_SIZE-7) +#define CICAM_TDPU_DATA_SIZE (CICAM_TDPU_SIZE - 7) /* EN50221, Annex A.4.1.13 (pg70) */ -#define CICAM_T_SB 0x80 /* SB h<--m */ -#define CICAM_T_RCV 0x81 /* receive h-->m */ -#define CICAM_T_CREATE_TC 0x82 /* create transport connection h-->m */ -#define CICAM_T_CTC_REPLY 0x83 /* ctc reply h<--m */ -#define CICAM_T_DELETE_TC 0x84 /* delete tc h<->m */ -#define CICAM_T_DTC_REPLY 0x85 /* delete tc reply h<->m */ -#define CICAM_T_REQUEST_TC 0x86 /* request transport connection h<--m */ -#define CICAM_T_NEW_TC 0x87 /* new tc (reply to request) h-->m */ -#define CICAM_T_TC_ERROR 0x88 /* error creating tc h-->m */ -#define CICAM_T_DATA_LAST 0xA0 /* data transfer h<->m */ -#define CICAM_T_DATA_MORE 0xA1 /* data transfer h<->m */ +#define CICAM_T_SB 0x80 /* SB h<--m */ +#define CICAM_T_RCV 0x81 /* receive h-->m */ +#define CICAM_T_CREATE_TC 0x82 /* create transport connection h-->m */ +#define CICAM_T_CTC_REPLY 0x83 /* ctc reply h<--m */ +#define CICAM_T_DELETE_TC 0x84 /* delete tc h<->m */ +#define CICAM_T_DTC_REPLY 0x85 /* delete tc reply h<->m */ +#define CICAM_T_REQUEST_TC 0x86 /* request transport connection h<--m */ +#define CICAM_T_NEW_TC 0x87 /* new tc (reply to request) h-->m */ +#define CICAM_T_TC_ERROR 0x88 /* error creating tc h-->m */ +#define CICAM_T_DATA_LAST 0xA0 /* data transfer h<->m */ +#define CICAM_T_DATA_MORE 0xA1 /* data transfer h<->m */ /* Session tags */ -#define CICAM_ST_SESSION_NUMBER 0x90 -#define CICAM_ST_OPEN_SESSION_REQUEST 0x91 -#define CICAM_ST_OPEN_SESSION_RESPONSE 0x92 -#define CICAM_ST_CREATE_SESSION 0x93 -#define CICAM_ST_CREATE_SESSION_RESPONSE 0x94 -#define CICAM_ST_CLOSE_SESSION_REQUEST 0x95 -#define CICAM_ST_CLOSE_SESSION_RESPONSE 0x96 +#define CICAM_ST_SESSION_NUMBER 0x90 +#define CICAM_ST_OPEN_SESSION_REQUEST 0x91 +#define CICAM_ST_OPEN_SESSION_RESPONSE 0x92 +#define CICAM_ST_CREATE_SESSION 0x93 +#define CICAM_ST_CREATE_SESSION_RESPONSE 0x94 +#define CICAM_ST_CLOSE_SESSION_REQUEST 0x95 +#define CICAM_ST_CLOSE_SESSION_RESPONSE 0x96 /* Session state codes */ -#define CICAM_SS_OK 0x00 -#define CICAM_SS_NOT_ALLOCATED 0xF0 +#define CICAM_SS_OK 0x00 +#define CICAM_SS_NOT_ALLOCATED 0xF0 -int en50221_create_transport - (en50221_ops_t *ops, void *ops_aux, int slots, - const char *name, en50221_transport_t **_cit) -{ - en50221_transport_t *cit; +int en50221_create_transport(en50221_ops_t* ops, + void* ops_aux, + int slots, + const char* name, + en50221_transport_t** _cit) { + en50221_transport_t* cit; cit = calloc(1, sizeof(*cit)); if (cit == NULL) return -ENOMEM; - cit->cit_ops = ops; - cit->cit_ops_aux = ops_aux; - cit->cit_name = strdup(name); + cit->cit_ops = ops; + cit->cit_ops_aux = ops_aux; + cit->cit_name = strdup(name); cit->cit_slot_count = slots; sbuf_init(&cit->cit_rmsg); *_cit = cit; return 0; } -static void en50221_transport_destroy_slots(en50221_transport_t *cit) -{ - en50221_slot_t *slot; +static void en50221_transport_destroy_slots(en50221_transport_t* cit) { + en50221_slot_t* slot; while ((slot = LIST_FIRST(&cit->cit_slots)) != NULL) en50221_slot_destroy(slot); } -void en50221_transport_destroy(en50221_transport_t *cit) -{ +void en50221_transport_destroy(en50221_transport_t* cit) { if (cit == NULL) return; en50221_transport_destroy_slots(cit); @@ -142,8 +133,7 @@ void en50221_transport_destroy(en50221_transport_t *cit) free(cit); } -static int en50221_transport_build_slots(en50221_transport_t *cit) -{ +static int en50221_transport_build_slots(en50221_transport_t* cit) { int i, r; for (i = 0; i < cit->cit_slot_count; i++) { r = en50221_slot_create(cit, i, NULL); @@ -153,8 +143,7 @@ static int en50221_transport_build_slots(en50221_transport_t *cit) return 0; } -int en50221_transport_reset(en50221_transport_t *cit) -{ +int en50221_transport_reset(en50221_transport_t* cit) { int r; r = cit->cit_ops->cihw_reset(cit->cit_ops_aux); @@ -168,103 +157,100 @@ int en50221_transport_reset(en50221_transport_t *cit) return r; } -static int -en50221_transport_pdu_write(en50221_transport_t *cit, - en50221_slot_t *cil, uint8_t tcnum, - uint8_t tag, const uint8_t *data, - size_t datalen) -{ - uint8_t *buf = alloca(8 + datalen); - size_t hlen; +static int en50221_transport_pdu_write(en50221_transport_t* cit, + en50221_slot_t* cil, + uint8_t tcnum, + uint8_t tag, + const uint8_t* data, + size_t datalen) { + uint8_t* buf = alloca(8 + datalen); + size_t hlen; buf[0] = tag; datalen++; -if (datalen < 0x80) { + if (datalen < 0x80) { buf[1] = datalen & 0x7f; - hlen = 2; + hlen = 2; } else if (datalen < 0x100) { buf[1] = 0x81; buf[2] = datalen & 0xff; - hlen = 3; + hlen = 3; } else if (datalen < 0x10000) { buf[1] = 0x82; buf[2] = datalen >> 8; buf[3] = datalen & 0xff; - hlen = 4; + hlen = 4; } else if (datalen < 0x1000000) { buf[1] = 0x83; buf[2] = datalen >> 16; buf[3] = (datalen >> 8) & 0xff; buf[4] = datalen & 0xff; - hlen = 5; + hlen = 5; } else { buf[1] = 0x84; buf[2] = datalen >> 24; buf[3] = (datalen >> 16) & 0xff; buf[4] = (datalen >> 8) & 0xff; buf[5] = datalen & 0xff; - hlen = 6; + hlen = 6; } buf[hlen++] = tcnum; if (datalen > 1) memcpy(buf + hlen, data, datalen - 1); - return - cit->cit_ops->cihw_pdu_write(cit->cit_ops_aux, cil, tcnum, - buf, datalen + hlen - 1); + return cit->cit_ops->cihw_pdu_write(cit->cit_ops_aux, cil, tcnum, buf, datalen + hlen - 1); } -en50221_slot_t * -en50221_transport_find_slot(en50221_transport_t *cit, uint8_t slotnum) -{ - en50221_slot_t *slot; +en50221_slot_t* en50221_transport_find_slot(en50221_transport_t* cit, uint8_t slotnum) { + en50221_slot_t* slot; - LIST_FOREACH(slot, &cit->cit_slots, cil_link) + LIST_FOREACH (slot, &cit->cit_slots, cil_link) if (slot->cil_number == slotnum) return slot; return NULL; } -static int en50221_transport_broken(en50221_transport_t *cit, - const uint8_t *data, size_t datalen) -{ +static int en50221_transport_broken(en50221_transport_t* cit, const uint8_t* data, size_t datalen) { cit->cit_broken = 1; tvhlog_hexdump(LS_EN50221, data, datalen); return -ENXIO; } -int en50221_transport_read(en50221_transport_t *cit, - uint8_t slotnum, uint8_t tcnum, - const uint8_t *data, size_t datalen) -{ - const uint8_t *p, *end; - uint8_t tag; - en50221_slot_t *slot; - size_t l; - int r; +int en50221_transport_read(en50221_transport_t* cit, + uint8_t slotnum, + uint8_t tcnum, + const uint8_t* data, + size_t datalen) { + const uint8_t * p, *end; + uint8_t tag; + en50221_slot_t* slot; + size_t l; + int r; if (cit->cit_broken) return -ENXIO; if (slotnum + 1 != tcnum) { - tvherror(LS_EN50221, "%s: invalid slot number 0x%02x and " - "transport connection id (0x%02x)", - cit->cit_name, slotnum, tcnum); + tvherror(LS_EN50221, + "%s: invalid slot number 0x%02x and " + "transport connection id (0x%02x)", + cit->cit_name, + slotnum, + tcnum); return en50221_transport_broken(cit, data, datalen); } slot = en50221_transport_find_slot(cit, slotnum); if (slot == NULL) { - tvherror(LS_EN50221, "%s: invalid slot number 0x%02x", - cit->cit_name, slotnum); + tvherror(LS_EN50221, "%s: invalid slot number 0x%02x", cit->cit_name, slotnum); return en50221_transport_broken(cit, data, datalen); } if (datalen > 0) slot->cil_monitor_read = mclk(); - p = data; + p = data; end = data + datalen; while (p + 3 <= end) { tag = *p++; - r = en50221_extract_len(p, end - p, &p, &l, cit->cit_name, "tpdu"); + r = en50221_extract_len(p, end - p, &p, &l, cit->cit_name, "tpdu"); if (r < 0) return en50221_transport_broken(cit, data, datalen); if (l == 0) { @@ -276,81 +262,80 @@ int en50221_transport_read(en50221_transport_t *cit, break; } switch (tag) { - case CICAM_T_SB: - if (slot->cil_closing) { - r = en50221_slot_trigger_write_queue(slot); - if (r < 0) - return en50221_transport_broken(cit, data, datalen); - break; - } - if (slot->cil_ready == 0) { - tvhwarn(LS_EN50221, "%s: received sb but slot is not ready", cit->cit_name); - break; - } - /* data are waiting? tell CAM that we can receive them or flush the write queue */ - if (l == 2) { - if ((p[1] & 0x80) != 0) { - r = en50221_transport_pdu_write(cit, slot, tcnum, CICAM_T_RCV, NULL, 0); - } else { + case CICAM_T_SB: + if (slot->cil_closing) { r = en50221_slot_trigger_write_queue(slot); + if (r < 0) + return en50221_transport_broken(cit, data, datalen); + break; } - if (r < 0) + if (slot->cil_ready == 0) { + tvhwarn(LS_EN50221, "%s: received sb but slot is not ready", cit->cit_name); + break; + } + /* data are waiting? tell CAM that we can receive them or flush the write queue */ + if (l == 2) { + if ((p[1] & 0x80) != 0) { + r = en50221_transport_pdu_write(cit, slot, tcnum, CICAM_T_RCV, NULL, 0); + } else { + r = en50221_slot_trigger_write_queue(slot); + } + if (r < 0) + return en50221_transport_broken(cit, data, datalen); + } + break; + case CICAM_T_CTC_REPLY: + if (l != 1) { + tvherror(LS_EN50221, "%s: invalid length %zd for tag 0x%02x", cit->cit_name, l, tag); return en50221_transport_broken(cit, data, datalen); - } - break; - case CICAM_T_CTC_REPLY: - if (l != 1) { - tvherror(LS_EN50221, "%s: invalid length %zd for tag 0x%02x", cit->cit_name, l, tag); - return en50221_transport_broken(cit, data, datalen); - } - slot->cil_ready = 1; - if (slot->cil_initiate_connection) - en50221_slot_connection_initiated(slot); - break; - case CICAM_T_DATA_MORE: - case CICAM_T_DATA_LAST: - if (slot->cil_ready == 0) { - tvhwarn(LS_EN50221, "%s: received data but slot is not ready", cit->cit_name); + } + slot->cil_ready = 1; + if (slot->cil_initiate_connection) + en50221_slot_connection_initiated(slot); break; - } - if (l > 1) { - p++; l--; /* what's this byte? tcnum? */ - if (tag == CICAM_T_DATA_LAST) { - if (cit->cit_rmsg.sb_ptr == 0) { - r = en50221_slot_spdu_recv(slot, p, l); + case CICAM_T_DATA_MORE: + case CICAM_T_DATA_LAST: + if (slot->cil_ready == 0) { + tvhwarn(LS_EN50221, "%s: received data but slot is not ready", cit->cit_name); + break; + } + if (l > 1) { + p++; + l--; /* what's this byte? tcnum? */ + if (tag == CICAM_T_DATA_LAST) { + if (cit->cit_rmsg.sb_ptr == 0) { + r = en50221_slot_spdu_recv(slot, p, l); + } else { + sbuf_append(&cit->cit_rmsg, p, l); + r = en50221_slot_spdu_recv(slot, cit->cit_rmsg.sb_data, cit->cit_rmsg.sb_ptr); + sbuf_reset(&cit->cit_rmsg, CICAM_TDPU_SIZE); + } + if (r < 0) + return en50221_transport_broken(cit, data, datalen); } else { sbuf_append(&cit->cit_rmsg, p, l); - r = en50221_slot_spdu_recv(slot, cit->cit_rmsg.sb_data, - cit->cit_rmsg.sb_ptr); - sbuf_reset(&cit->cit_rmsg, CICAM_TDPU_SIZE); } - if (r < 0) - return en50221_transport_broken(cit, data, datalen); - } else { - sbuf_append(&cit->cit_rmsg, p, l); } - } - break; - default: - tvherror(LS_EN50221, "%s: unknown transport tag 0x%02x", cit->cit_name, tag); - return en50221_transport_broken(cit, data, datalen); + break; + default: + tvherror(LS_EN50221, "%s: unknown transport tag 0x%02x", cit->cit_name, tag); + return en50221_transport_broken(cit, data, datalen); } p += l; } return 0; } -int en50221_transport_monitor(en50221_transport_t *cit, int64_t clock) -{ - en50221_slot_t *slot; - int r; +int en50221_transport_monitor(en50221_transport_t* cit, int64_t clock) { + en50221_slot_t* slot; + int r; if (LIST_EMPTY(&cit->cit_slots) && cit->cit_slot_count > 0) { r = en50221_transport_build_slots(cit); if (r < 0) return r; } - LIST_FOREACH(slot, &cit->cit_slots, cil_link) { + LIST_FOREACH (slot, &cit->cit_slots, cil_link) { if (cit->cit_ops->cihw_cam_is_ready(cit->cit_ops_aux, slot) > 0) { en50221_slot_enable(slot); r = en50221_slot_monitor(slot, clock); @@ -366,20 +351,17 @@ int en50221_transport_monitor(en50221_transport_t *cit, int64_t clock) /* * Slot/connection layer */ -static int -en50221_slot_create - (en50221_transport_t *cit, uint8_t number, en50221_slot_t **cil) -{ - en50221_slot_t *slot; - char buf[128]; +static int en50221_slot_create(en50221_transport_t* cit, uint8_t number, en50221_slot_t** cil) { + en50221_slot_t* slot; + char buf[128]; slot = calloc(1, sizeof(*slot)); if (slot == NULL) return -ENOMEM; snprintf(buf, sizeof(buf), "%s-slot%d", cit->cit_name, number); - slot->cil_name = strdup(buf); - slot->cil_transport = cit; - slot->cil_number = number; + slot->cil_name = strdup(buf); + slot->cil_transport = cit; + slot->cil_number = number; slot->cil_monitor_read = mclk(); TAILQ_INIT(&slot->cil_write_queue); LIST_INSERT_HEAD(&cit->cit_slots, slot, cil_link); @@ -388,19 +370,15 @@ en50221_slot_create return 0; } -static void -en50221_slot_applications_destroy(en50221_slot_t *cil) -{ - en50221_app_t *app; +static void en50221_slot_applications_destroy(en50221_slot_t* cil) { + en50221_app_t* app; while ((app = LIST_FIRST(&cil->cil_apps)) != NULL) en50221_app_destroy(app); } -static void -en50221_slot_clear(en50221_slot_t *cil) -{ - en50221_slot_wmsg_t *wmsg; +static void en50221_slot_clear(en50221_slot_t* cil) { + en50221_slot_wmsg_t* wmsg; if (cil == NULL) return; @@ -411,34 +389,31 @@ en50221_slot_clear(en50221_slot_t *cil) } } -static void -en50221_slot_destroy(en50221_slot_t *cil) -{ +static void en50221_slot_destroy(en50221_slot_t* cil) { en50221_slot_clear(cil); LIST_REMOVE(cil, cil_link); free(cil->cil_name); free(cil); } -static void -en50221_slot_reset(en50221_slot_t *cil) -{ +static void en50221_slot_reset(en50221_slot_t* cil) { en50221_slot_clear(cil); - cil->cil_ready = 0; + cil->cil_ready = 0; cil->cil_initiate_connection = 0; - cil->cil_closing = 0; - cil->cil_tcnum = 0; + cil->cil_closing = 0; + cil->cil_tcnum = 0; } -static inline int en50221_slot_pdu_send - (en50221_slot_t *cil, uint8_t tag, const uint8_t *data, size_t datalen, - int reply_is_expected) -{ - en50221_slot_wmsg_t *wmsg; +static inline int en50221_slot_pdu_send(en50221_slot_t* cil, + uint8_t tag, + const uint8_t* data, + size_t datalen, + int reply_is_expected) { + en50221_slot_wmsg_t* wmsg; - wmsg = malloc(sizeof(*wmsg) + datalen); - wmsg->tag = tag; - wmsg->len = datalen; + wmsg = malloc(sizeof(*wmsg) + datalen); + wmsg->tag = tag; + wmsg->len = datalen; wmsg->reply_is_expected = reply_is_expected; if (data && datalen > 0) memcpy(wmsg->data, data, datalen); @@ -446,21 +421,28 @@ static inline int en50221_slot_pdu_send return 0; } -static int en50221_slot_trigger_write_queue(en50221_slot_t *cil) -{ - en50221_slot_wmsg_t *wmsg; - int r = 0; +static int en50221_slot_trigger_write_queue(en50221_slot_t* cil) { + en50221_slot_wmsg_t* wmsg; + int r = 0; wmsg = TAILQ_FIRST(&cil->cil_write_queue); if (wmsg) { TAILQ_REMOVE(&cil->cil_write_queue, wmsg, link); - r = en50221_transport_pdu_write(cil->cil_transport, cil, cil->cil_tcnum, - wmsg->tag, wmsg->data, wmsg->len); + r = en50221_transport_pdu_write(cil->cil_transport, + cil, + cil->cil_tcnum, + wmsg->tag, + wmsg->data, + wmsg->len); free(wmsg); } else { if (cil->cil_ready) { - r = en50221_transport_pdu_write(cil->cil_transport, cil, cil->cil_tcnum, - CICAM_T_DATA_LAST, NULL, 0); + r = en50221_transport_pdu_write(cil->cil_transport, + cil, + cil->cil_tcnum, + CICAM_T_DATA_LAST, + NULL, + 0); } } if (cil->cil_closing && TAILQ_EMPTY(&cil->cil_write_queue)) @@ -468,11 +450,9 @@ static int en50221_slot_trigger_write_queue(en50221_slot_t *cil) return r; } -static int -en50221_slot_initiate_connection(en50221_slot_t *cil) -{ - en50221_app_t *app; - int r; +static int en50221_slot_initiate_connection(en50221_slot_t* cil) { + en50221_app_t* app; + int r; if (cil->cil_apdu_only) { /* create dummy conditional access application */ @@ -486,16 +466,14 @@ en50221_slot_initiate_connection(en50221_slot_t *cil) } /* static connection ID allocation */ cil->cil_tcnum = cil->cil_number + 1; - r = en50221_slot_pdu_send(cil, CICAM_T_CREATE_TC, NULL, 0, 1); + r = en50221_slot_pdu_send(cil, CICAM_T_CREATE_TC, NULL, 0, 1); if (r < 0) return r; cil->cil_initiate_connection = 1; return en50221_slot_trigger_write_queue(cil); } -int -en50221_slot_enable(en50221_slot_t *cil) -{ +int en50221_slot_enable(en50221_slot_t* cil) { if (!cil->cil_enabled) { en50221_slot_reset(cil); cil->cil_enabled = 1; @@ -504,9 +482,7 @@ en50221_slot_enable(en50221_slot_t *cil) return 0; } -int -en50221_slot_disable(en50221_slot_t *cil) -{ +int en50221_slot_disable(en50221_slot_t* cil) { if (cil->cil_enabled) { en50221_slot_reset(cil); cil->cil_enabled = 0; @@ -519,30 +495,26 @@ en50221_slot_disable(en50221_slot_t *cil) return 0; } -static int en50221_slot_connection_initiated(en50221_slot_t *cil) -{ +static int en50221_slot_connection_initiated(en50221_slot_t* cil) { cil->cil_initiate_connection = 0; return 0; } -static en50221_app_t * -en50221_slot_find_session(en50221_slot_t *cil, uint16_t session_id) -{ - en50221_app_t *cia; +static en50221_app_t* en50221_slot_find_session(en50221_slot_t* cil, uint16_t session_id) { + en50221_app_t* cia; - LIST_FOREACH(cia, &cil->cil_apps, cia_link) + LIST_FOREACH (cia, &cil->cil_apps, cia_link) if (cia->cia_session_id == session_id) return cia; return NULL; } -en50221_app_t * -en50221_slot_find_application(en50221_slot_t *cil, uint32_t resource_id, uint32_t mask) -{ - en50221_app_t *cia; +en50221_app_t* +en50221_slot_find_application(en50221_slot_t* cil, uint32_t resource_id, uint32_t mask) { + en50221_app_t* cia; resource_id &= mask; - LIST_FOREACH(cia, &cil->cil_apps, cia_link) { + LIST_FOREACH (cia, &cil->cil_apps, cia_link) { if ((cia->cia_resource_id & mask) == resource_id) return cia; } @@ -576,133 +548,150 @@ static int en50221_slot_session_create } #endif -static int en50221_slot_spdu_recv - (en50221_slot_t *cil, const uint8_t *data, size_t datalen) -{ - en50221_app_t *app; - uint16_t session; - uint32_t ri; - uint8_t buf[9]; - int r; +static int en50221_slot_spdu_recv(en50221_slot_t* cil, const uint8_t* data, size_t datalen) { + en50221_app_t* app; + uint16_t session; + uint32_t ri; + uint8_t buf[9]; + int r; switch (data[0]) { - case CICAM_ST_SESSION_NUMBER: - if (datalen <= 4) { - tvherror(LS_EN50221, "%s: unhandled session number length %zd", - cil->cil_name, datalen); - return -EINVAL; - } - session = (data[2] << 8) | data[3]; - app = en50221_slot_find_session(cil, session); - if (app == NULL) { - tvherror(LS_EN50221, "%s: unhandled session message length %zd " - "session number 0x%04x", - cil->cil_name, datalen, session); - return -EINVAL; - } - return en50221_app_handle(app, data[1], data + 4, datalen - 4); - case CICAM_ST_OPEN_SESSION_REQUEST: - if (datalen != 6 || data[1] != 4) { - tvherror(LS_EN50221, "%s: unhandled open session request length %zd " - "data1 0x%02x", cil->cil_name, datalen, data[1]); - return -EINVAL; - } - ri = get32(data + 2); - app = en50221_slot_find_application(cil, ri, ~0); - if (app == NULL) { - session = ++cil->cil_last_session_number; - if (session == 0) + case CICAM_ST_SESSION_NUMBER: + if (datalen <= 4) { + tvherror(LS_EN50221, "%s: unhandled session number length %zd", cil->cil_name, datalen); + return -EINVAL; + } + session = (data[2] << 8) | data[3]; + app = en50221_slot_find_session(cil, session); + if (app == NULL) { + tvherror(LS_EN50221, + "%s: unhandled session message length %zd " + "session number 0x%04x", + cil->cil_name, + datalen, + session); + return -EINVAL; + } + return en50221_app_handle(app, data[1], data + 4, datalen - 4); + case CICAM_ST_OPEN_SESSION_REQUEST: + if (datalen != 6 || data[1] != 4) { + tvherror(LS_EN50221, + "%s: unhandled open session request length %zd " + "data1 0x%02x", + cil->cil_name, + datalen, + data[1]); + return -EINVAL; + } + ri = get32(data + 2); + app = en50221_slot_find_application(cil, ri, ~0); + if (app == NULL) { session = ++cil->cil_last_session_number; - r = en50221_create_app(cil, ri, session, &app); - if (r < 0) - return r; - } else { - session = app->cia_session_id; - } - buf[0] = CICAM_ST_OPEN_SESSION_RESPONSE; - buf[1] = 7; - buf[2] = app->cia_prop ? CICAM_SS_OK : CICAM_SS_NOT_ALLOCATED; - memcpy(buf + 3, data + 2, 4); /* ri */ - buf[7] = session >> 8; - buf[8] = session & 0xff; - r = en50221_slot_pdu_send(cil, CICAM_T_DATA_LAST, buf, 9, 0); - if (r < 0) - return r; - return en50221_app_open(app); - case CICAM_ST_CREATE_SESSION_RESPONSE: - if (datalen != 9 || data[1] != 7) { - tvherror(LS_EN50221, "%s: unhandled create session response length %zd " - "data1 0x%02x", cil->cil_name, datalen, data[1]); - return -EINVAL; - } - ri = get32(data + 3); - session = (data[7] << 8) | data[8]; - if (data[2] != CICAM_SS_OK) { - tvherror(LS_EN50221, "%s: CAM rejected to create session 0x%04x", - cil->cil_name, session); - return -EINVAL; - } - app = en50221_slot_find_session(cil, session); - if (app == NULL) { - r = en50221_create_app(cil, ri, session, &app); + if (session == 0) + session = ++cil->cil_last_session_number; + r = en50221_create_app(cil, ri, session, &app); + if (r < 0) + return r; + } else { + session = app->cia_session_id; + } + buf[0] = CICAM_ST_OPEN_SESSION_RESPONSE; + buf[1] = 7; + buf[2] = app->cia_prop ? CICAM_SS_OK : CICAM_SS_NOT_ALLOCATED; + memcpy(buf + 3, data + 2, 4); /* ri */ + buf[7] = session >> 8; + buf[8] = session & 0xff; + r = en50221_slot_pdu_send(cil, CICAM_T_DATA_LAST, buf, 9, 0); if (r < 0) return r; - } - break; - case CICAM_ST_CLOSE_SESSION_REQUEST: - if (datalen != 4 || data[1] != 2) { - tvherror(LS_EN50221, "%s: unhandled close session request length %zd " - "data1 0x%02x", cil->cil_name, datalen, data[1]); - return -EINVAL; - } - session = (data[2] << 8) | data[3]; - app = en50221_slot_find_session(cil, session); - if (app == NULL) { - tvherror(LS_EN50221, "%s: unhandled close session request, " - "session number 0x%04x not found", cil->cil_name, session); - return -EINVAL; - } - en50221_app_destroy(app); - buf[0] = CICAM_ST_CLOSE_SESSION_RESPONSE; - buf[1] = 3; - buf[2] = CICAM_SS_OK; - buf[3] = session >> 8; - buf[4] = session & 0xff; - return en50221_slot_pdu_send(cil, CICAM_T_DATA_LAST, buf, 5, 0); - case CICAM_ST_CLOSE_SESSION_RESPONSE: - if (datalen != 5 || data[1] != 3 || data[2]) { - tvherror(LS_EN50221, "%s: unhandled close session response length %zd " - "data1 0x%02x data2 0x%02x", - cil->cil_name, datalen, data[1], data[2]); - return -EINVAL; - } - session = (data[3] << 8) | data[4]; - app = en50221_slot_find_session(cil, session); - if (app == NULL) { - tvherror(LS_EN50221, "%s: unhandled close session response, " - "session number 0x%04x not found", - cil->cil_name, session); + return en50221_app_open(app); + case CICAM_ST_CREATE_SESSION_RESPONSE: + if (datalen != 9 || data[1] != 7) { + tvherror(LS_EN50221, + "%s: unhandled create session response length %zd " + "data1 0x%02x", + cil->cil_name, + datalen, + data[1]); + return -EINVAL; + } + ri = get32(data + 3); + session = (data[7] << 8) | data[8]; + if (data[2] != CICAM_SS_OK) { + tvherror(LS_EN50221, "%s: CAM rejected to create session 0x%04x", cil->cil_name, session); + return -EINVAL; + } + app = en50221_slot_find_session(cil, session); + if (app == NULL) { + r = en50221_create_app(cil, ri, session, &app); + if (r < 0) + return r; + } + break; + case CICAM_ST_CLOSE_SESSION_REQUEST: + if (datalen != 4 || data[1] != 2) { + tvherror(LS_EN50221, + "%s: unhandled close session request length %zd " + "data1 0x%02x", + cil->cil_name, + datalen, + data[1]); + return -EINVAL; + } + session = (data[2] << 8) | data[3]; + app = en50221_slot_find_session(cil, session); + if (app == NULL) { + tvherror(LS_EN50221, + "%s: unhandled close session request, " + "session number 0x%04x not found", + cil->cil_name, + session); + return -EINVAL; + } + en50221_app_destroy(app); + buf[0] = CICAM_ST_CLOSE_SESSION_RESPONSE; + buf[1] = 3; + buf[2] = CICAM_SS_OK; + buf[3] = session >> 8; + buf[4] = session & 0xff; + return en50221_slot_pdu_send(cil, CICAM_T_DATA_LAST, buf, 5, 0); + case CICAM_ST_CLOSE_SESSION_RESPONSE: + if (datalen != 5 || data[1] != 3 || data[2]) { + tvherror(LS_EN50221, + "%s: unhandled close session response length %zd " + "data1 0x%02x data2 0x%02x", + cil->cil_name, + datalen, + data[1], + data[2]); + return -EINVAL; + } + session = (data[3] << 8) | data[4]; + app = en50221_slot_find_session(cil, session); + if (app == NULL) { + tvherror(LS_EN50221, + "%s: unhandled close session response, " + "session number 0x%04x not found", + cil->cil_name, + session); + return -EINVAL; + } + en50221_app_destroy(app); + break; + default: + tvherror(LS_EN50221, "%s: unknown session tag 0x%02x", cil->cil_name, data[0]); return -EINVAL; - } - en50221_app_destroy(app); - break; - default: - tvherror(LS_EN50221, "%s: unknown session tag 0x%02x", cil->cil_name, data[0]); - return -EINVAL; } return 0; } -static int -en50221_slot_monitor(en50221_slot_t *cil, int64_t clock) -{ - en50221_app_t *cia; - int r; +static int en50221_slot_monitor(en50221_slot_t* cil, int64_t clock) { + en50221_app_t* cia; + int r; - LIST_FOREACH(cia, &cil->cil_apps, cia_link) { + LIST_FOREACH (cia, &cil->cil_apps, cia_link) { if (cil->cil_monitor_read + ms2mono(500) < mclk()) { - tvherror(LS_EN50221, "%s: communication stalled for more than 500ms", - cil->cil_name); + tvherror(LS_EN50221, "%s: communication stalled for more than 500ms", cil->cil_name); return -ENXIO; } r = en50221_app_monitor(cia, clock); @@ -717,47 +706,41 @@ en50221_slot_monitor(en50221_slot_t *cil, int64_t clock) */ static LIST_HEAD(, en50221_app_prop) en50221_app_props; -void en50221_register_app(en50221_app_prop_t *prop) -{ +void en50221_register_app(en50221_app_prop_t* prop) { LIST_INSERT_HEAD(&en50221_app_props, prop, ciap_link); } -static int en50221_create_app - (en50221_slot_t *cil, uint32_t resource_id, - uint16_t session_id, en50221_app_t **cia) -{ - en50221_app_prop_t *prop; - en50221_app_t *app; - char buf[128]; +static int en50221_create_app(en50221_slot_t* cil, + uint32_t resource_id, + uint16_t session_id, + en50221_app_t** cia) { + en50221_app_prop_t* prop; + en50221_app_t* app; + char buf[128]; - LIST_FOREACH(prop, &en50221_app_props, ciap_link) + LIST_FOREACH (prop, &en50221_app_props, ciap_link) if (prop->ciap_resource_id == resource_id) break; if (prop == NULL) - tvherror(LS_EN50221, "%s: unknown resource id %08x", - cil->cil_name, resource_id); + tvherror(LS_EN50221, "%s: unknown resource id %08x", cil->cil_name, resource_id); app = calloc(1, prop ? prop->ciap_struct_size : 0); if (app == NULL) return -ENOMEM; - snprintf(buf, sizeof(buf), "%s-app%08x/%04X", cil->cil_name, - resource_id, session_id); - app->cia_name = strdup(buf); - app->cia_slot = cil; + snprintf(buf, sizeof(buf), "%s-app%08x/%04X", cil->cil_name, resource_id, session_id); + app->cia_name = strdup(buf); + app->cia_slot = cil; app->cia_resource_id = resource_id; - app->cia_session_id = session_id; - app->cia_prop = prop; + app->cia_session_id = session_id; + app->cia_prop = prop; LIST_INSERT_HEAD(&cil->cil_apps, app, cia_link); if (cia) *cia = app; - tvhtrace(LS_EN50221, "%s: registered (%s)", app->cia_name, - prop ? prop->ciap_name : "???"); + tvhtrace(LS_EN50221, "%s: registered (%s)", app->cia_name, prop ? prop->ciap_name : "???"); return 0; } -static void -en50221_app_destroy(en50221_app_t *cia) -{ - en50221_app_prop_t *prop; +static void en50221_app_destroy(en50221_app_t* cia) { + en50221_app_prop_t* prop; if (cia == NULL) return; @@ -765,21 +748,21 @@ en50221_app_destroy(en50221_app_t *cia) LIST_REMOVE(cia, cia_link); if (prop && prop->ciap_destroy) prop->ciap_destroy(cia); - tvhtrace(LS_EN50221, "%s: destroyed (%s)", cia->cia_name, - prop ? prop->ciap_name : "???"); + tvhtrace(LS_EN50221, "%s: destroyed (%s)", cia->cia_name, prop ? prop->ciap_name : "???"); free(cia->cia_name); free(cia); } -int en50221_app_pdu_send - (en50221_app_t *app, uint32_t atag, const uint8_t *data, size_t datalen, - int reply_is_expected) -{ - en50221_slot_t *slot = app->cia_slot; - en50221_transport_t *cit = slot->cil_transport; - uint8_t *buf = alloca(datalen + 12), *p, tag; - size_t hlen, buflen, tlen; - int r; +int en50221_app_pdu_send(en50221_app_t* app, + uint32_t atag, + const uint8_t* data, + size_t datalen, + int reply_is_expected) { + en50221_slot_t* slot = app->cia_slot; + en50221_transport_t* cit = slot->cil_transport; + uint8_t * buf = alloca(datalen + 12), *p, tag; + size_t hlen, buflen, tlen; + int r; buf[0] = CICAM_ST_SESSION_NUMBER; buf[1] = 2; @@ -790,44 +773,43 @@ int en50221_app_pdu_send buf[6] = atag & 0xff; if (datalen < 0x80) { buf[7] = datalen & 0x7f; - hlen = 8; + hlen = 8; } else if (datalen < 0x100) { buf[7] = 0x81; buf[8] = datalen & 0xff; - hlen = 9; + hlen = 9; } else if (datalen < 0x10000) { buf[7] = 0x82; buf[8] = datalen >> 8; buf[9] = datalen & 0xff; - hlen = 10; + hlen = 10; } else if (datalen < 0x1000000) { - buf[7] = 0x83; - buf[8] = datalen >> 16; - buf[9] = (datalen >> 8) & 0xff; + buf[7] = 0x83; + buf[8] = datalen >> 16; + buf[9] = (datalen >> 8) & 0xff; buf[10] = datalen & 0xff; - hlen = 11; + hlen = 11; } else { - buf[7] = 0x84; - buf[8] = datalen >> 24; - buf[9] = (datalen >> 16) & 0xff; + buf[7] = 0x84; + buf[8] = datalen >> 24; + buf[9] = (datalen >> 16) & 0xff; buf[10] = (datalen >> 8) & 0xff; buf[11] = datalen & 0xff; - hlen = 12; + hlen = 12; } if (datalen > 0) memcpy(buf + hlen, data, datalen); buflen = datalen + hlen; if (slot->cil_apdu_only) - return cit->cit_ops->cihw_apdu_write(cit->cit_ops_aux, slot, - buf + 4, buflen - 4); + return cit->cit_ops->cihw_apdu_write(cit->cit_ops_aux, slot, buf + 4, buflen - 4); p = buf; while (buflen > 0) { if (buflen > CICAM_TDPU_DATA_SIZE) { tlen = CICAM_TDPU_DATA_SIZE; - tag = CICAM_T_DATA_MORE; + tag = CICAM_T_DATA_MORE; } else { tlen = buflen; - tag = CICAM_T_DATA_LAST; + tag = CICAM_T_DATA_LAST; } r = en50221_slot_pdu_send(slot, tag, p, tlen, reply_is_expected); if (r < 0) @@ -839,14 +821,12 @@ int en50221_app_pdu_send } static int -en50221_app_handle - (en50221_app_t *cia, uint8_t status, const uint8_t *data, size_t datalen) -{ - en50221_app_prop_t *prop = cia->cia_prop; - uint32_t atag; - const uint8_t *p; - size_t l; - int r; +en50221_app_handle(en50221_app_t* cia, uint8_t status, const uint8_t* data, size_t datalen) { + en50221_app_prop_t* prop = cia->cia_prop; + uint32_t atag; + const uint8_t* p; + size_t l; + int r; if (prop && prop->ciap_handle) { if (datalen < 4) @@ -864,18 +844,14 @@ en50221_app_handle return 0; } -static int -en50221_app_open(en50221_app_t *cia) -{ - en50221_app_prop_t *prop = cia->cia_prop; +static int en50221_app_open(en50221_app_t* cia) { + en50221_app_prop_t* prop = cia->cia_prop; if (prop && prop->ciap_open) return prop->ciap_open(cia); return 0; } -static int -en50221_app_monitor(en50221_app_t *cia, int64_t clock) -{ +static int en50221_app_monitor(en50221_app_t* cia, int64_t clock) { if (cia->cia_prop && cia->cia_prop->ciap_monitor) return cia->cia_prop->ciap_monitor(cia, clock); return 0; @@ -885,20 +861,21 @@ en50221_app_monitor(en50221_app_t *cia, int64_t clock) * */ -int -en50221_extract_len - (const uint8_t *data, size_t datalen, const uint8_t **ptr, size_t *len, - const char *prefix, const char *pdu_name) -{ +int en50221_extract_len(const uint8_t* data, + size_t datalen, + const uint8_t** ptr, + size_t* len, + const char* prefix, + const char* pdu_name) { const uint8_t *p, *end; - uint32_t j; - size_t l; + uint32_t j; + size_t l; l = data[0]; p = data + 1; if (l < 0x80) { } else { - j = l & 0x7f; + j = l & 0x7f; end = data + datalen; if (j > 3) { tvherror(LS_EN50221, "%s: invalid %s length 0x%02zx", prefix, pdu_name, l); diff --git a/src/input/mpegts/en50221/en50221.h b/src/input/mpegts/en50221/en50221.h index 34c27ac2c..3c731dbe1 100644 --- a/src/input/mpegts/en50221/en50221.h +++ b/src/input/mpegts/en50221/en50221.h @@ -24,204 +24,218 @@ #include "sbuf.h" /* Session resource IDs */ -#define CICAM_RI_RESOURCE_MANAGER 0x00010041 -#define CICAM_RI_APPLICATION_INFORMATION 0x00020041 -#define CICAM_RI_CONDITIONAL_ACCESS_SUPPORT 0x00030041 -#define CICAM_RI_HOST_CONTROL 0x00200041 -#define CICAM_RI_DATE_TIME 0x00240041 -#define CICAM_RI_MMI 0x00400041 +#define CICAM_RI_RESOURCE_MANAGER 0x00010041 +#define CICAM_RI_APPLICATION_INFORMATION 0x00020041 +#define CICAM_RI_CONDITIONAL_ACCESS_SUPPORT 0x00030041 +#define CICAM_RI_HOST_CONTROL 0x00200041 +#define CICAM_RI_DATE_TIME 0x00240041 +#define CICAM_RI_MMI 0x00400041 -#define CICAM_RI_DUMMY_CAPMT 0x00ffffff +#define CICAM_RI_DUMMY_CAPMT 0x00ffffff /* Application tags */ -#define CICAM_AOT_NONE 0x000000 -#define CICAM_AOT_PROFILE_ENQ 0x9F8010 -#define CICAM_AOT_PROFILE 0x9F8011 -#define CICAM_AOT_PROFILE_CHANGE 0x9F8012 -#define CICAM_AOT_APPLICATION_INFO_ENQ 0x9F8020 -#define CICAM_AOT_APPLICATION_INFO 0x9F8021 -#define CICAM_AOT_ENTER_MENU 0x9F8022 -#define CICAM_AOT_PCMCIA_DATA_RATE 0x9F8024 -#define CICAM_AOT_CA_INFO_ENQ 0x9F8030 -#define CICAM_AOT_CA_INFO 0x9F8031 -#define CICAM_AOT_CA_PMT 0x9F8032 -#define CICAM_AOT_CA_PMT_REPLY 0x9F8033 -#define CICAM_AOT_CA_UPDATE 0x9F8034 -#define CICAM_AOT_TUNE 0x9F8400 -#define CICAM_AOT_REPLACE 0x9F8401 -#define CICAM_AOT_CLEAR_REPLACE 0x9F8402 -#define CICAM_AOT_ASK_RELEASE 0x9F8403 -#define CICAM_AOT_DATE_TIME_ENQ 0x9F8440 -#define CICAM_AOT_DATE_TIME 0x9F8441 -#define CICAM_AOT_CLOSE_MMI 0x9F8800 -#define CICAM_AOT_DISPLAY_CONTROL 0x9F8801 -#define CICAM_AOT_DISPLAY_REPLY 0x9F8802 -#define CICAM_AOT_TEXT_LAST 0x9F8803 -#define CICAM_AOT_TEXT_MORE 0x9F8804 -#define CICAM_AOT_KEYPAD_CONTROL 0x9F8805 -#define CICAM_AOT_KEYPRESS 0x9F8806 -#define CICAM_AOT_ENQ 0x9F8807 -#define CICAM_AOT_ANSW 0x9F8808 -#define CICAM_AOT_MENU_LAST 0x9F8809 -#define CICAM_AOT_MENU_MORE 0x9F880A -#define CICAM_AOT_MENU_ANSW 0x9F880B -#define CICAM_AOT_LIST_LAST 0x9F880C -#define CICAM_AOT_LIST_MORE 0x9F880D -#define CICAM_AOT_SUBTITLE_SEGMENT_LAST 0x9F880E -#define CICAM_AOT_SUBTITLE_SEGMENT_MORE 0x9F880F -#define CICAM_AOT_DISPLAY_MESSAGE 0x9F8810 -#define CICAM_AOT_SCENE_END_MARK 0x9F8811 -#define CICAM_AOT_SCENE_DONE 0x9F8812 -#define CICAM_AOT_SCENE_CONTROL 0x9F8813 -#define CICAM_AOT_SUBTITLE_DOWNLOAD_LAST 0x9F8814 -#define CICAM_AOT_SUBTITLE_DOWNLOAD_MORE 0x9F8815 -#define CICAM_AOT_FLUSH_DOWNLOAD 0x9F8816 -#define CICAM_AOT_DOWNLOAD_REPLY 0x9F8817 -#define CICAM_AOT_COMMS_CMD 0x9F8C00 -#define CICAM_AOT_CONNECTION_DESCRIPTOR 0x9F8C01 -#define CICAM_AOT_COMMS_REPLY 0x9F8C02 -#define CICAM_AOT_COMMS_SEND_LAST 0x9F8C03 -#define CICAM_AOT_COMMS_SEND_MORE 0x9F8C04 -#define CICAM_AOT_COMMS_RCV_LAST 0x9F8C05 -#define CICAM_AOT_COMMS_RCV_MORE 0x9F8C06 - -typedef struct en50221_app_prop en50221_app_prop_t; -typedef struct en50221_app en50221_app_t; -typedef struct en50221_slot en50221_slot_t; +#define CICAM_AOT_NONE 0x000000 +#define CICAM_AOT_PROFILE_ENQ 0x9F8010 +#define CICAM_AOT_PROFILE 0x9F8011 +#define CICAM_AOT_PROFILE_CHANGE 0x9F8012 +#define CICAM_AOT_APPLICATION_INFO_ENQ 0x9F8020 +#define CICAM_AOT_APPLICATION_INFO 0x9F8021 +#define CICAM_AOT_ENTER_MENU 0x9F8022 +#define CICAM_AOT_PCMCIA_DATA_RATE 0x9F8024 +#define CICAM_AOT_CA_INFO_ENQ 0x9F8030 +#define CICAM_AOT_CA_INFO 0x9F8031 +#define CICAM_AOT_CA_PMT 0x9F8032 +#define CICAM_AOT_CA_PMT_REPLY 0x9F8033 +#define CICAM_AOT_CA_UPDATE 0x9F8034 +#define CICAM_AOT_TUNE 0x9F8400 +#define CICAM_AOT_REPLACE 0x9F8401 +#define CICAM_AOT_CLEAR_REPLACE 0x9F8402 +#define CICAM_AOT_ASK_RELEASE 0x9F8403 +#define CICAM_AOT_DATE_TIME_ENQ 0x9F8440 +#define CICAM_AOT_DATE_TIME 0x9F8441 +#define CICAM_AOT_CLOSE_MMI 0x9F8800 +#define CICAM_AOT_DISPLAY_CONTROL 0x9F8801 +#define CICAM_AOT_DISPLAY_REPLY 0x9F8802 +#define CICAM_AOT_TEXT_LAST 0x9F8803 +#define CICAM_AOT_TEXT_MORE 0x9F8804 +#define CICAM_AOT_KEYPAD_CONTROL 0x9F8805 +#define CICAM_AOT_KEYPRESS 0x9F8806 +#define CICAM_AOT_ENQ 0x9F8807 +#define CICAM_AOT_ANSW 0x9F8808 +#define CICAM_AOT_MENU_LAST 0x9F8809 +#define CICAM_AOT_MENU_MORE 0x9F880A +#define CICAM_AOT_MENU_ANSW 0x9F880B +#define CICAM_AOT_LIST_LAST 0x9F880C +#define CICAM_AOT_LIST_MORE 0x9F880D +#define CICAM_AOT_SUBTITLE_SEGMENT_LAST 0x9F880E +#define CICAM_AOT_SUBTITLE_SEGMENT_MORE 0x9F880F +#define CICAM_AOT_DISPLAY_MESSAGE 0x9F8810 +#define CICAM_AOT_SCENE_END_MARK 0x9F8811 +#define CICAM_AOT_SCENE_DONE 0x9F8812 +#define CICAM_AOT_SCENE_CONTROL 0x9F8813 +#define CICAM_AOT_SUBTITLE_DOWNLOAD_LAST 0x9F8814 +#define CICAM_AOT_SUBTITLE_DOWNLOAD_MORE 0x9F8815 +#define CICAM_AOT_FLUSH_DOWNLOAD 0x9F8816 +#define CICAM_AOT_DOWNLOAD_REPLY 0x9F8817 +#define CICAM_AOT_COMMS_CMD 0x9F8C00 +#define CICAM_AOT_CONNECTION_DESCRIPTOR 0x9F8C01 +#define CICAM_AOT_COMMS_REPLY 0x9F8C02 +#define CICAM_AOT_COMMS_SEND_LAST 0x9F8C03 +#define CICAM_AOT_COMMS_SEND_MORE 0x9F8C04 +#define CICAM_AOT_COMMS_RCV_LAST 0x9F8C05 +#define CICAM_AOT_COMMS_RCV_MORE 0x9F8C06 + +typedef struct en50221_app_prop en50221_app_prop_t; +typedef struct en50221_app en50221_app_t; +typedef struct en50221_slot en50221_slot_t; typedef struct en50221_slot_wmsg en50221_slot_wmsg_t; typedef struct en50221_transport en50221_transport_t; -typedef struct en50221_ops en50221_ops_t; +typedef struct en50221_ops en50221_ops_t; struct en50221_app_prop { LIST_ENTRY(en50221_app_prop) ciap_link; - const char *ciap_name; - uint32_t ciap_resource_id; - size_t ciap_struct_size; - void (*ciap_destroy)(void *self); - int (*ciap_open)(void *self); - int (*ciap_handle)(void *self, uint8_t status, uint32_t atag, - const uint8_t *data, size_t datalen); - int (*ciap_monitor)(void *self, int64_t clock); + const char* ciap_name; + uint32_t ciap_resource_id; + size_t ciap_struct_size; + void (*ciap_destroy)(void* self); + int (*ciap_open)(void* self); + int ( + *ciap_handle)(void* self, uint8_t status, uint32_t atag, const uint8_t* data, size_t datalen); + int (*ciap_monitor)(void* self, int64_t clock); }; struct en50221_app { LIST_ENTRY(en50221_app) cia_link; - en50221_slot_t *cia_slot; - char *cia_name; - uint32_t cia_resource_id; - uint16_t cia_session_id; - en50221_app_prop_t *cia_prop; + en50221_slot_t* cia_slot; + char* cia_name; + uint32_t cia_resource_id; + uint16_t cia_session_id; + en50221_app_prop_t* cia_prop; }; struct en50221_slot_wmsg { TAILQ_ENTRY(en50221_slot_wmsg) link; uint8_t tag; uint8_t reply_is_expected; - size_t len; + size_t len; uint8_t data[0]; }; struct en50221_slot { LIST_ENTRY(en50221_slot) cil_link; - en50221_transport_t *cil_transport; - char *cil_name; - uint8_t cil_number; - uint8_t cil_tcnum; - uint8_t cil_enabled; - uint8_t cil_ready; - uint8_t cil_caid_list; - uint8_t cil_apdu_only; - uint8_t cil_initiate_connection; - uint8_t cil_closing; - uint16_t cil_last_session_number; - int64_t cil_monitor_read; - TAILQ_HEAD(,en50221_slot_wmsg) cil_write_queue; + en50221_transport_t* cil_transport; + char* cil_name; + uint8_t cil_number; + uint8_t cil_tcnum; + uint8_t cil_enabled; + uint8_t cil_ready; + uint8_t cil_caid_list; + uint8_t cil_apdu_only; + uint8_t cil_initiate_connection; + uint8_t cil_closing; + uint16_t cil_last_session_number; + int64_t cil_monitor_read; + TAILQ_HEAD(, en50221_slot_wmsg) cil_write_queue; LIST_HEAD(, en50221_app) cil_apps; }; struct en50221_transport { LIST_HEAD(, en50221_slot) cit_slots; - en50221_ops_t *cit_ops; - void *cit_ops_aux; - uint8_t cit_broken; - int cit_slot_count; - char *cit_name; - sbuf_t cit_rmsg; + en50221_ops_t* cit_ops; + void* cit_ops_aux; + uint8_t cit_broken; + int cit_slot_count; + char* cit_name; + sbuf_t cit_rmsg; }; struct en50221_ops { /* hw interface */ - int (*cihw_reset)(void *aux); - int (*cihw_cam_is_ready)(void *aux, en50221_slot_t *slot); - int (*cihw_pdu_write)(void *aux, en50221_slot_t *slot, uint8_t tcnum, - const uint8_t *data, size_t datalen); - int (*cihw_apdu_write)(void *aux, en50221_slot_t *slot, - const uint8_t *data, size_t datalen); + int (*cihw_reset)(void* aux); + int (*cihw_cam_is_ready)(void* aux, en50221_slot_t* slot); + int (*cihw_pdu_write)(void* aux, + en50221_slot_t* slot, + uint8_t tcnum, + const uint8_t* data, + size_t datalen); + int (*cihw_apdu_write)(void* aux, en50221_slot_t* slot, const uint8_t* data, size_t datalen); /* software level ops */ - int (*cisw_appinfo)(void *aux, en50221_slot_t *slot, uint8_t ver, - char *name, uint8_t type, uint16_t manufacturer, uint16_t code); - int (*cisw_pcmcia_data_rate)(void *aux, en50221_slot_t *slot, uint8_t *rate); - int (*cisw_caids)(void *aux, en50221_slot_t *slot, uint16_t *list, int listcount); - int (*cisw_ca_close)(void *aux, en50221_slot_t *slot); - int (*cisw_menu)(void *aux, en50221_slot_t *slot, htsmsg_t *menu); - int (*cisw_enquiry)(void *aux, en50221_slot_t *slot, htsmsg_t *enq); - int (*cisw_close)(void *aux, en50221_slot_t *slot, int delay); + int (*cisw_appinfo)(void* aux, + en50221_slot_t* slot, + uint8_t ver, + char* name, + uint8_t type, + uint16_t manufacturer, + uint16_t code); + int (*cisw_pcmcia_data_rate)(void* aux, en50221_slot_t* slot, uint8_t* rate); + int (*cisw_caids)(void* aux, en50221_slot_t* slot, uint16_t* list, int listcount); + int (*cisw_ca_close)(void* aux, en50221_slot_t* slot); + int (*cisw_menu)(void* aux, en50221_slot_t* slot, htsmsg_t* menu); + int (*cisw_enquiry)(void* aux, en50221_slot_t* slot, htsmsg_t* enq); + int (*cisw_close)(void* aux, en50221_slot_t* slot, int delay); }; /* * */ -int en50221_create_transport(en50221_ops_t *ops, void *ops_aux, int slots, - const char *name, en50221_transport_t **cit); -void en50221_transport_destroy(en50221_transport_t *cit); -en50221_slot_t *en50221_transport_find_slot(en50221_transport_t *cit, uint8_t slotnum); -int en50221_transport_reset(en50221_transport_t *cit); -int en50221_transport_monitor(en50221_transport_t *cit, int64_t clock); -int en50221_transport_read(en50221_transport_t *cit, - uint8_t slotnum, uint8_t tcnum, - const uint8_t *data, size_t datalen); +int en50221_create_transport(en50221_ops_t* ops, + void* ops_aux, + int slots, + const char* name, + en50221_transport_t** cit); +void en50221_transport_destroy(en50221_transport_t* cit); +en50221_slot_t* en50221_transport_find_slot(en50221_transport_t* cit, uint8_t slotnum); +int en50221_transport_reset(en50221_transport_t* cit); +int en50221_transport_monitor(en50221_transport_t* cit, int64_t clock); +int en50221_transport_read(en50221_transport_t* cit, + uint8_t slotnum, + uint8_t tcnum, + const uint8_t* data, + size_t datalen); /* * */ -en50221_app_t * -en50221_slot_find_application(en50221_slot_t *cil, - uint32_t resource_id, uint32_t mask); -int en50221_slot_enable(en50221_slot_t *cil); -int en50221_slot_disable(en50221_slot_t *cil); +en50221_app_t* + en50221_slot_find_application(en50221_slot_t* cil, uint32_t resource_id, uint32_t mask); +int en50221_slot_enable(en50221_slot_t* cil); +int en50221_slot_disable(en50221_slot_t* cil); /* * */ -void en50221_register_app(en50221_app_prop_t *prop); -int en50221_app_pdu_send(en50221_app_t *app, uint32_t atag, - const uint8_t *data, size_t datalen, - int reply_is_expected); +void en50221_register_app(en50221_app_prop_t* prop); +int en50221_app_pdu_send(en50221_app_t* app, + uint32_t atag, + const uint8_t* data, + size_t datalen, + int reply_is_expected); void en50221_register_apps(void); -#define CICAM_CALL_APP_CB(app, name, ...) ({ \ - en50221_slot_t *__s = app->cia_slot; \ - en50221_transport_t *__t = __s->cil_transport; \ - int __r = __t->cit_ops ? \ - __t->cit_ops->name(__t->cit_ops_aux, __s, ##__VA_ARGS__) : 0; \ - __r; \ -}) +#define CICAM_CALL_APP_CB(app, name, ...) \ + ({ \ + en50221_slot_t* __s = app->cia_slot; \ + en50221_transport_t* __t = __s->cil_transport; \ + int __r = __t->cit_ops ? __t->cit_ops->name(__t->cit_ops_aux, __s, ##__VA_ARGS__) : 0; \ + __r; \ + }) /* * */ -int en50221_extract_len - (const uint8_t *data, size_t datalen, const uint8_t **ptr, size_t *len, - const char *prefix, const char *pdu_name); +int en50221_extract_len(const uint8_t* data, + size_t datalen, + const uint8_t** ptr, + size_t* len, + const char* prefix, + const char* pdu_name); /* * random public functions */ -int en50221_send_capmt - (en50221_slot_t *slot, const uint8_t *capmt, size_t capmtlen); -int en50221_pcmcia_data_rate(en50221_slot_t *slot, uint8_t rate); -int en50221_mmi_answer - (en50221_slot_t *slot, const uint8_t *data, size_t datalen); -int en50221_mmi_close(en50221_slot_t *slot); +int en50221_send_capmt(en50221_slot_t* slot, const uint8_t* capmt, size_t capmtlen); +int en50221_pcmcia_data_rate(en50221_slot_t* slot, uint8_t rate); +int en50221_mmi_answer(en50221_slot_t* slot, const uint8_t* data, size_t datalen); +int en50221_mmi_close(en50221_slot_t* slot); #endif /* EN50221_H */ diff --git a/src/input/mpegts/en50221/en50221_apps.c b/src/input/mpegts/en50221/en50221_apps.c index 180e81d9e..624e824d1 100644 --- a/src/input/mpegts/en50221/en50221_apps.c +++ b/src/input/mpegts/en50221/en50221_apps.c @@ -28,25 +28,20 @@ #define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) -#define BYTE4BE(w) \ - (((w) >> 24) & 0xff), (((w) >> 16) & 0xff), (((w) >> 8) & 0xff), ((w) & 0xff) +#define BYTE4BE(w) (((w) >> 24) & 0xff), (((w) >> 16) & 0xff), (((w) >> 8) & 0xff), ((w) & 0xff) /* * */ -static inline uint8_t int2bcd(uint32_t v) -{ +static inline uint8_t int2bcd(uint32_t v) { return ((v / 10) << 4) + (v % 10); } -static inline uint32_t getatag(const uint8_t *p, size_t l) -{ +static inline uint32_t getatag(const uint8_t* p, size_t l) { if (l < 3) return CICAM_AOT_NONE + l; - return (((uint32_t)p[0]) << 16) | - (((uint32_t)p[1]) << 8) | - p[2]; + return (((uint32_t)p[0]) << 16) | (((uint32_t)p[1]) << 8) | p[2]; } /* @@ -58,38 +53,39 @@ typedef struct en50221_app_resman { uint8_t cia_profile_sent; } en50221_app_resman_t; -static int -en50221_app_resman_open(void *self) -{ - en50221_app_t *app = self; +static int en50221_app_resman_open(void* self) { + en50221_app_t* app = self; return en50221_app_pdu_send(app, CICAM_AOT_PROFILE_ENQ, NULL, 0, 1); } -static int -en50221_app_resman_handle - (void *self, uint8_t status, uint32_t atag, const uint8_t *data, size_t datalen) -{ - en50221_app_resman_t *app = self; - static const uint8_t resources[] = { - BYTE4BE(CICAM_RI_RESOURCE_MANAGER), - BYTE4BE(CICAM_RI_MMI), - BYTE4BE(CICAM_RI_CONDITIONAL_ACCESS_SUPPORT), - BYTE4BE(CICAM_RI_DATE_TIME), - BYTE4BE(CICAM_RI_APPLICATION_INFORMATION), - BYTE4BE(CICAM_RI_APPLICATION_INFORMATION+1), - BYTE4BE(CICAM_RI_APPLICATION_INFORMATION+2), - BYTE4BE(CICAM_RI_APPLICATION_INFORMATION+4), +static int en50221_app_resman_handle(void* self, + uint8_t status, + uint32_t atag, + const uint8_t* data, + size_t datalen) { + en50221_app_resman_t* app = self; + static const uint8_t resources[] = { + BYTE4BE(CICAM_RI_RESOURCE_MANAGER), + BYTE4BE(CICAM_RI_MMI), + BYTE4BE(CICAM_RI_CONDITIONAL_ACCESS_SUPPORT), + BYTE4BE(CICAM_RI_DATE_TIME), + BYTE4BE(CICAM_RI_APPLICATION_INFORMATION), + BYTE4BE(CICAM_RI_APPLICATION_INFORMATION + 1), + BYTE4BE(CICAM_RI_APPLICATION_INFORMATION + 2), + BYTE4BE(CICAM_RI_APPLICATION_INFORMATION + 4), }; if (atag == CICAM_AOT_PROFILE_ENQ) { tvhtrace(LS_EN50221, "%s: profile enq reply sent", app->cia_name); - return en50221_app_pdu_send((en50221_app_t *)app, CICAM_AOT_PROFILE, - resources, sizeof(resources), 0); + return en50221_app_pdu_send((en50221_app_t*)app, + CICAM_AOT_PROFILE, + resources, + sizeof(resources), + 0); } else if (atag == CICAM_AOT_PROFILE) { if (!app->cia_profile_sent) { app->cia_profile_sent = 1; tvhtrace(LS_EN50221, "%s: profile change sent", app->cia_name); - return en50221_app_pdu_send((en50221_app_t *)app, CICAM_AOT_PROFILE_CHANGE, - NULL, 0, 0); + return en50221_app_pdu_send((en50221_app_t*)app, CICAM_AOT_PROFILE_CHANGE, NULL, 0, 0); } } else { tvherror(LS_EN50221, "%s: unknown atag for resman 0x%06x", app->cia_name, atag); @@ -98,65 +94,59 @@ en50221_app_resman_handle } static en50221_app_prop_t en50221_app_resman = { - .ciap_name = "resman", - .ciap_resource_id = CICAM_RI_RESOURCE_MANAGER, - .ciap_struct_size = sizeof(en50221_app_resman_t), - .ciap_open = en50221_app_resman_open, - .ciap_handle = en50221_app_resman_handle, + .ciap_name = "resman", + .ciap_resource_id = CICAM_RI_RESOURCE_MANAGER, + .ciap_struct_size = sizeof(en50221_app_resman_t), + .ciap_open = en50221_app_resman_open, + .ciap_handle = en50221_app_resman_handle, }; /* * Conditional Access */ -#define CICAM_CAEI_POSSIBLE 0x01 -#define CICAM_CAEI_POSSIBLE_COND_PURCHASE 0x02 -#define CICAM_CAEI_POSSIBLE_COND_TECHNICAL 0x03 -#define CICAM_CAEI_NOT_POSSIBLE_ENTITLEMENT 0x71 -#define CICAM_CAEI_NOT_POSSIBLE_TECHNICAL 0x73 +#define CICAM_CAEI_POSSIBLE 0x01 +#define CICAM_CAEI_POSSIBLE_COND_PURCHASE 0x02 +#define CICAM_CAEI_POSSIBLE_COND_TECHNICAL 0x03 +#define CICAM_CAEI_NOT_POSSIBLE_ENTITLEMENT 0x71 +#define CICAM_CAEI_NOT_POSSIBLE_TECHNICAL 0x73 -#define CICAM_CA_ENABLE_FLAG 0x80 +#define CICAM_CA_ENABLE_FLAG 0x80 -#define CICAM_CA_ENABLE(x) \ - (((x) & CICAM_CA_ENABLE_FLAG) ? (x) & ~CICAM_CA_ENABLE_FLAG : 0) +#define CICAM_CA_ENABLE(x) (((x) & CICAM_CA_ENABLE_FLAG) ? (x) & ~CICAM_CA_ENABLE_FLAG : 0) typedef struct en50221_app_ca { en50221_app_t; uint16_t cia_caids[64]; - uint8_t cia_replies_to_query; - uint8_t cia_ca_possible; + uint8_t cia_replies_to_query; + uint8_t cia_ca_possible; } en50221_app_ca_t; -static void -en50221_app_ca_destroy - (void *self) -{ - en50221_app_ca_t *app = self; +static void en50221_app_ca_destroy(void* self) { + en50221_app_ca_t* app = self; CICAM_CALL_APP_CB(app, cisw_ca_close); } -static int -en50221_app_ca_open(void *self) -{ - en50221_app_t *app = self; +static int en50221_app_ca_open(void* self) { + en50221_app_t* app = self; return en50221_app_pdu_send(app, CICAM_AOT_CA_INFO_ENQ, NULL, 0, 1); } -static int -en50221_app_ca_handle - (void *self, uint8_t status, uint32_t atag, const uint8_t *data, size_t datalen) -{ - en50221_app_ca_t *app = self; - const uint8_t *p; - char buf[256]; - int count, i, j; - uint16_t caid, u16; - size_t c; +static int en50221_app_ca_handle(void* self, + uint8_t status, + uint32_t atag, + const uint8_t* data, + size_t datalen) { + en50221_app_ca_t* app = self; + const uint8_t* p; + char buf[256]; + int count, i, j; + uint16_t caid, u16; + size_t c; if (atag == CICAM_AOT_CA_INFO) { count = 0; - for (; count < ARRAY_SIZE(app->cia_caids) - 1 && datalen > 1; - data += 2, datalen -= 2, count++) + for (; count < ARRAY_SIZE(app->cia_caids) - 1 && datalen > 1; data += 2, datalen -= 2, count++) app->cia_caids[count] = (data[0] << 8) | data[1]; if (datalen) { app->cia_caids[0] = 0; @@ -165,7 +155,7 @@ en50221_app_ca_handle } app->cia_caids[count] = 0; buf[0] = buf[1] = '\0'; - for (i = 0; i < count; ) { + for (i = 0; i < count;) { for (j = 0, c = 0; j < 4 && i < count; i++, j++) { caid = app->cia_caids[i]; tvh_strlcatf(buf, sizeof(buf), c, " %04X (%s)", caid, caid2name(caid)); @@ -177,14 +167,14 @@ en50221_app_ca_handle } else if (atag == CICAM_AOT_CA_UPDATE) { /* nothing */ } else if (atag == CICAM_AOT_CA_PMT_REPLY) { - c = 0; + c = 0; app->cia_ca_possible = 0; tvh_strlcatf(buf, sizeof(buf), c, "%s: PMT REPLY", app->cia_name); if (datalen > 1) { app->cia_replies_to_query = 1; - u16 = (data[0] << 8) | data[1]; - i = datalen - 2; - p = data + 2; + u16 = (data[0] << 8) | data[1]; + i = datalen - 2; + p = data + 2; tvh_strlcatf(buf, sizeof(buf), c, " %04X", u16); if (i > 0) { tvh_strlcatf(buf, sizeof(buf), c, " %02X", *p); @@ -203,7 +193,8 @@ en50221_app_ca_handle } } tvh_strlcatf(buf, sizeof(buf), c, " %02X", *p); - p++; i--; + p++; + i--; app->cia_ca_possible = CICAM_CA_ENABLE(*p) == CICAM_CAEI_POSSIBLE; while (i > 2) { u16 = (p[0] << 8) | p[1]; @@ -221,10 +212,8 @@ en50221_app_ca_handle return 0; } -int en50221_send_capmt - (en50221_slot_t *slot, const uint8_t *capmt, size_t capmtlen) -{ - en50221_app_t *app; +int en50221_send_capmt(en50221_slot_t* slot, const uint8_t* capmt, size_t capmtlen) { + en50221_app_t* app; app = en50221_slot_find_application(slot, CICAM_RI_CONDITIONAL_ACCESS_SUPPORT, ~0); if (app) return en50221_app_pdu_send(app, CICAM_AOT_CA_PMT, capmt, capmtlen, 0); @@ -232,12 +221,12 @@ int en50221_send_capmt } static en50221_app_prop_t en50221_app_ca = { - .ciap_name = "ca", - .ciap_resource_id = CICAM_RI_CONDITIONAL_ACCESS_SUPPORT, - .ciap_struct_size = sizeof(en50221_app_ca_t), - .ciap_destroy = en50221_app_ca_destroy, - .ciap_open = en50221_app_ca_open, - .ciap_handle = en50221_app_ca_handle, + .ciap_name = "ca", + .ciap_resource_id = CICAM_RI_CONDITIONAL_ACCESS_SUPPORT, + .ciap_struct_size = sizeof(en50221_app_ca_t), + .ciap_destroy = en50221_app_ca_destroy, + .ciap_open = en50221_app_ca_open, + .ciap_handle = en50221_app_ca_handle, }; /* @@ -250,14 +239,12 @@ typedef struct en50221_app_datetime { int64_t cia_last_clock; } en50221_app_datetime_t; -static int -en50221_app_datetime_send(en50221_app_datetime_t *app, int64_t clock) -{ - time_t t = time(NULL); +static int en50221_app_datetime_send(en50221_app_datetime_t* app, int64_t clock) { + time_t t = time(NULL); struct tm tm_gmt; struct tm tm_loc; - uint8_t buf[7]; - int r = 0; + uint8_t buf[7]; + int r = 0; if (gmtime_r(&t, &tm_gmt) && localtime_r(&t, &tm_loc)) { int GMTOFF = tm_loc.tm_gmtoff / 60; @@ -265,17 +252,16 @@ en50221_app_datetime_send(en50221_app_datetime_t *app, int64_t clock) int M = tm_gmt.tm_mon + 1; int D = tm_gmt.tm_mday; int L = (M == 1 || M == 2) ? 1 : 0; - int MJD = 14956 + D + (int)((Y - L) * 365.25) - + (int)((M + 1 + L * 12) * 30.6001); - buf[0] = MJD >> 8; - buf[1] = MJD & 0xff; - buf[2] = int2bcd(tm_gmt.tm_hour); - buf[3] = int2bcd(tm_gmt.tm_min); - buf[4] = int2bcd(tm_gmt.tm_sec); - buf[5] = GMTOFF >> 8; - buf[6] = GMTOFF & 0xff; - - r = en50221_app_pdu_send((en50221_app_t *)app, CICAM_AOT_DATE_TIME, buf, 7, 0); + int MJD = 14956 + D + (int)((Y - L) * 365.25) + (int)((M + 1 + L * 12) * 30.6001); + buf[0] = MJD >> 8; + buf[1] = MJD & 0xff; + buf[2] = int2bcd(tm_gmt.tm_hour); + buf[3] = int2bcd(tm_gmt.tm_min); + buf[4] = int2bcd(tm_gmt.tm_sec); + buf[5] = GMTOFF >> 8; + buf[6] = GMTOFF & 0xff; + + r = en50221_app_pdu_send((en50221_app_t*)app, CICAM_AOT_DATE_TIME, buf, 7, 0); if (r >= 0) { tvhtrace(LS_EN50221, "%s: updated datetime was sent", app->cia_name); app->cia_last_clock = clock; @@ -284,12 +270,13 @@ en50221_app_datetime_send(en50221_app_datetime_t *app, int64_t clock) return r; } -static int -en50221_app_datetime_handle - (void *self, uint8_t status, uint32_t atag, const uint8_t *data, size_t datalen) -{ - int interval; - en50221_app_datetime_t *app = self; +static int en50221_app_datetime_handle(void* self, + uint8_t status, + uint32_t atag, + const uint8_t* data, + size_t datalen) { + int interval; + en50221_app_datetime_t* app = self; if (atag == CICAM_AOT_DATE_TIME_ENQ) { interval = 0; if (datalen == 1) @@ -303,22 +290,19 @@ en50221_app_datetime_handle return 0; } -static int -en50221_app_datetime_monitor(void *self, int64_t clock) -{ - en50221_app_datetime_t *app = self; - if (app->cia_update_interval > 0 && - app->cia_last_clock + app->cia_update_interval < clock) +static int en50221_app_datetime_monitor(void* self, int64_t clock) { + en50221_app_datetime_t* app = self; + if (app->cia_update_interval > 0 && app->cia_last_clock + app->cia_update_interval < clock) return en50221_app_datetime_send(app, clock); return 0; } static en50221_app_prop_t en50221_app_datetime = { - .ciap_name = "datetime", - .ciap_resource_id = CICAM_RI_DATE_TIME, - .ciap_struct_size = sizeof(en50221_app_datetime_t), - .ciap_handle = en50221_app_datetime_handle, - .ciap_monitor = en50221_app_datetime_monitor, + .ciap_name = "datetime", + .ciap_resource_id = CICAM_RI_DATE_TIME, + .ciap_struct_size = sizeof(en50221_app_datetime_t), + .ciap_handle = en50221_app_datetime_handle, + .ciap_monitor = en50221_app_datetime_monitor, }; /* @@ -331,46 +315,54 @@ typedef struct en50221_app_appinfo { uint8_t cia_pcmcia_data_rate; } en50221_app_appinfo_t; -static int -en50221_app_appinfo_open(void *self) -{ - en50221_app_t *app = self; +static int en50221_app_appinfo_open(void* self) { + en50221_app_t* app = self; return en50221_app_pdu_send(app, CICAM_AOT_APPLICATION_INFO_ENQ, NULL, 0, 1); } -static int -en50221_app_appinfo_handle - (void *self, uint8_t status, uint32_t atag, const uint8_t *data, size_t datalen) -{ - en50221_app_appinfo_t *app = self; - const uint8_t *p; - char *s; - size_t l; - uint16_t type, manufacturer, code; - uint8_t rate; - int r; - - if (atag >= CICAM_AOT_APPLICATION_INFO && - atag <= CICAM_AOT_APPLICATION_INFO+2) { +static int en50221_app_appinfo_handle(void* self, + uint8_t status, + uint32_t atag, + const uint8_t* data, + size_t datalen) { + en50221_app_appinfo_t* app = self; + const uint8_t* p; + char* s; + size_t l; + uint16_t type, manufacturer, code; + uint8_t rate; + int r; + + if (atag >= CICAM_AOT_APPLICATION_INFO && atag <= CICAM_AOT_APPLICATION_INFO + 2) { if (datalen < 6) { - tvherror(LS_EN50221, "%s: unknown length %zd for appinfo 0x%06x", app->cia_name, datalen, atag); + tvherror(LS_EN50221, + "%s: unknown length %zd for appinfo 0x%06x", + app->cia_name, + datalen, + atag); return -ENXIO; } - type = data[0]; + type = data[0]; manufacturer = (data[1] << 8) | data[2]; - code = (data[3] << 8) | data[4]; - r = en50221_extract_len(data + 5, datalen - 5, &p, &l, app->cia_name, "appinfo"); + code = (data[3] << 8) | data[4]; + r = en50221_extract_len(data + 5, datalen - 5, &p, &l, app->cia_name, "appinfo"); if (r < 0) return -ENXIO; s = alloca(l * 2 + 1); if (dvb_get_string(s, l * 2 + 1, p, l, NULL, NULL) < 0) return -ENXIO; - tvhinfo(LS_EN50221, "%s: CAM INFO: %s, %02X, %04X, %04X", app->cia_name, s, type, manufacturer, code); + tvhinfo(LS_EN50221, + "%s: CAM INFO: %s, %02X, %04X, %04X", + app->cia_name, + s, + type, + manufacturer, + code); app->cia_info_version = atag & 0x3f; CICAM_CALL_APP_CB(app, cisw_appinfo, atag & 0x3f, s, type, manufacturer, code); if (app->cia_info_version >= 3) /* at least CI+ v1.3 */ if (CICAM_CALL_APP_CB(app, cisw_pcmcia_data_rate, &rate) >= 0) - return en50221_app_pdu_send((en50221_app_t *)app, CICAM_AOT_PCMCIA_DATA_RATE, &rate, 1, 0); + return en50221_app_pdu_send((en50221_app_t*)app, CICAM_AOT_PCMCIA_DATA_RATE, &rate, 1, 0); } else { tvherror(LS_EN50221, "%s: unknown atag for appinfo 0x%06x", app->cia_name, atag); } @@ -378,43 +370,42 @@ en50221_app_appinfo_handle } static en50221_app_prop_t en50221_app_appinfo1 = { - .ciap_name = "appinfo1", /* EN50221 */ - .ciap_resource_id = CICAM_RI_APPLICATION_INFORMATION, - .ciap_struct_size = sizeof(en50221_app_appinfo_t), - .ciap_open = en50221_app_appinfo_open, - .ciap_handle = en50221_app_appinfo_handle, + .ciap_name = "appinfo1", /* EN50221 */ + .ciap_resource_id = CICAM_RI_APPLICATION_INFORMATION, + .ciap_struct_size = sizeof(en50221_app_appinfo_t), + .ciap_open = en50221_app_appinfo_open, + .ciap_handle = en50221_app_appinfo_handle, }; static en50221_app_prop_t en50221_app_appinfo2 = { - .ciap_name = "appinfo2", /* TS101699 */ - .ciap_resource_id = CICAM_RI_APPLICATION_INFORMATION+1, - .ciap_struct_size = sizeof(en50221_app_appinfo_t), - .ciap_open = en50221_app_appinfo_open, - .ciap_handle = en50221_app_appinfo_handle, + .ciap_name = "appinfo2", /* TS101699 */ + .ciap_resource_id = CICAM_RI_APPLICATION_INFORMATION + 1, + .ciap_struct_size = sizeof(en50221_app_appinfo_t), + .ciap_open = en50221_app_appinfo_open, + .ciap_handle = en50221_app_appinfo_handle, }; static en50221_app_prop_t en50221_app_appinfo3 = { - .ciap_name = "appinfo3", /* CIPLUS13 */ - .ciap_resource_id = CICAM_RI_APPLICATION_INFORMATION+2, - .ciap_struct_size = sizeof(en50221_app_appinfo_t), - .ciap_open = en50221_app_appinfo_open, - .ciap_handle = en50221_app_appinfo_handle, + .ciap_name = "appinfo3", /* CIPLUS13 */ + .ciap_resource_id = CICAM_RI_APPLICATION_INFORMATION + 2, + .ciap_struct_size = sizeof(en50221_app_appinfo_t), + .ciap_open = en50221_app_appinfo_open, + .ciap_handle = en50221_app_appinfo_handle, }; static en50221_app_prop_t en50221_app_appinfo5 = { - .ciap_name = "appinfo5", /* Bluebook A173-2 */ - .ciap_resource_id = CICAM_RI_APPLICATION_INFORMATION+4, - .ciap_struct_size = sizeof(en50221_app_appinfo_t), - .ciap_open = en50221_app_appinfo_open, - .ciap_handle = en50221_app_appinfo_handle, + .ciap_name = "appinfo5", /* Bluebook A173-2 */ + .ciap_resource_id = CICAM_RI_APPLICATION_INFORMATION + 4, + .ciap_struct_size = sizeof(en50221_app_appinfo_t), + .ciap_open = en50221_app_appinfo_open, + .ciap_handle = en50221_app_appinfo_handle, }; -int en50221_pcmcia_data_rate(en50221_slot_t *slot, uint8_t rate) -{ - en50221_app_t *app; +int en50221_pcmcia_data_rate(en50221_slot_t* slot, uint8_t rate) { + en50221_app_t* app; app = en50221_slot_find_application(slot, CICAM_RI_APPLICATION_INFORMATION, ~0x3f); - if (app && ((en50221_app_appinfo_t *)app)->cia_info_version >= 3) - return en50221_app_pdu_send((en50221_app_t *)app, CICAM_AOT_PCMCIA_DATA_RATE, &rate, 1, 0); + if (app && ((en50221_app_appinfo_t*)app)->cia_info_version >= 3) + return en50221_app_pdu_send((en50221_app_t*)app, CICAM_AOT_PCMCIA_DATA_RATE, &rate, 1, 0); return 0; } @@ -423,45 +414,42 @@ int en50221_pcmcia_data_rate(en50221_slot_t *slot, uint8_t rate) */ /* Display Control Commands */ -#define MMI_DCC_SET_MMI_MODE 0x01 -#define MMI_DCC_DISPLAY_CHARACTER_TABLE_LIST 0x02 -#define MMI_DCC_INPUT_CHARACTER_TABLE_LIST 0x03 -#define MMI_DCC_OVERLAY_GRAPHICS_CHARACTERISTICS 0x04 -#define MMI_DCC_FULL_SCREEN_GRAPHICS_CHARACTERISTICS 0x05 +#define MMI_DCC_SET_MMI_MODE 0x01 +#define MMI_DCC_DISPLAY_CHARACTER_TABLE_LIST 0x02 +#define MMI_DCC_INPUT_CHARACTER_TABLE_LIST 0x03 +#define MMI_DCC_OVERLAY_GRAPHICS_CHARACTERISTICS 0x04 +#define MMI_DCC_FULL_SCREEN_GRAPHICS_CHARACTERISTICS 0x05 /* MMI Modes */ -#define MMI_MM_HIGH_LEVEL 0x01 -#define MMI_MM_LOW_LEVEL_OVERLAY_GRAPHICS 0x02 -#define MMI_MM_LOW_LEVEL_FULL_SCREEN_GRAPHICS 0x03 +#define MMI_MM_HIGH_LEVEL 0x01 +#define MMI_MM_LOW_LEVEL_OVERLAY_GRAPHICS 0x02 +#define MMI_MM_LOW_LEVEL_FULL_SCREEN_GRAPHICS 0x03 /* Display Reply IDs */ -#define MMI_DRI_MMI_MODE_ACK 0x01 -#define MMI_DRI_LIST_DISPLAY_CHARACTER_TABLES 0x02 -#define MMI_DRI_LIST_INPUT_CHARACTER_TABLES 0x03 -#define MMI_DRI_LIST_GRAPHIC_OVERLAY_CHARACTERISTICS 0x04 -#define MMI_DRI_LIST_FULL_SCREEN_GRAPHIC_CHARACTERISTICS 0x05 -#define MMI_DRI_UNKNOWN_DISPLAY_CONTROL_CMD 0xF0 -#define MMI_DRI_UNKNOWN_MMI_MODE 0xF1 -#define MMI_DRI_UNKNOWN_CHARACTER_TABLE 0xF2 +#define MMI_DRI_MMI_MODE_ACK 0x01 +#define MMI_DRI_LIST_DISPLAY_CHARACTER_TABLES 0x02 +#define MMI_DRI_LIST_INPUT_CHARACTER_TABLES 0x03 +#define MMI_DRI_LIST_GRAPHIC_OVERLAY_CHARACTERISTICS 0x04 +#define MMI_DRI_LIST_FULL_SCREEN_GRAPHIC_CHARACTERISTICS 0x05 +#define MMI_DRI_UNKNOWN_DISPLAY_CONTROL_CMD 0xF0 +#define MMI_DRI_UNKNOWN_MMI_MODE 0xF1 +#define MMI_DRI_UNKNOWN_CHARACTER_TABLE 0xF2 /* Enquiry Flags */ -#define MMI_EF_BLIND 0x01 +#define MMI_EF_BLIND 0x01 /* Answer IDs */ -#define MMI_AI_CANCEL 0x00 -#define MMI_AI_ANSWER 0x01 +#define MMI_AI_CANCEL 0x00 +#define MMI_AI_ANSWER 0x01 typedef struct en50221_app_mi { en50221_app_t; - htsmsg_t *cia_menu; - htsmsg_t *cia_enquiry; + htsmsg_t* cia_menu; + htsmsg_t* cia_enquiry; } en50221_app_mmi_t; -static void -en50221_app_mmi_destroy - (void *self) -{ - en50221_app_mmi_t *app = self; +static void en50221_app_mmi_destroy(void* self) { + en50221_app_mmi_t* app = self; htsmsg_destroy(app->cia_menu); app->cia_menu = NULL; htsmsg_destroy(app->cia_enquiry); @@ -469,15 +457,13 @@ en50221_app_mmi_destroy } static int -getmenutext - (en50221_app_mmi_t *app, const char *key, int list, const uint8_t **_p, size_t *_l) -{ +getmenutext(en50221_app_mmi_t* app, const char* key, int list, const uint8_t** _p, size_t* _l) { const uint8_t *p = *_p, *p2; - size_t l = *_l, l2; - uint32_t tag; - char *txt; - htsmsg_t *c; - int r; + size_t l = *_l, l2; + uint32_t tag; + char* txt; + htsmsg_t* c; + int r; if (l == 0) return 0; @@ -486,7 +472,8 @@ getmenutext return 0; } tag = getatag(p, l); - p += 3; l -= 3; + p += 3; + l -= 3; if (tag != CICAM_AOT_TEXT_LAST) { tvherror(LS_EN50221, "%s: unexpected getmenutext tag %06X", app->cia_name, tag); return -ENXIO; @@ -516,39 +503,48 @@ getmenutext return 0; } -static int -en50221_app_mmi_handle - (void *self, uint8_t status, uint32_t atag, const uint8_t *data, size_t datalen) -{ - en50221_app_mmi_t *app = self; - const uint8_t *p; - char *txt; - size_t l; - int r, id, delay; +static int en50221_app_mmi_handle(void* self, + uint8_t status, + uint32_t atag, + const uint8_t* data, + size_t datalen) { + en50221_app_mmi_t* app = self; + const uint8_t* p; + char* txt; + size_t l; + int r, id, delay; if (atag == CICAM_AOT_DISPLAY_CONTROL) { tvhtrace(LS_EN50221, "%s: display control", app->cia_name); if (datalen > 0) { if (data[0] == MMI_DCC_SET_MMI_MODE) { - static uint8_t buf[] = { MMI_DRI_MMI_MODE_ACK, MMI_MM_HIGH_LEVEL }; + static uint8_t buf[] = {MMI_DRI_MMI_MODE_ACK, MMI_MM_HIGH_LEVEL}; tvhtrace(LS_EN50221, "%s: display control sending reply", app->cia_name); - return en50221_app_pdu_send((en50221_app_t *)app, CICAM_AOT_DISPLAY_REPLY, - buf, ARRAY_SIZE(buf), 0); + return en50221_app_pdu_send((en50221_app_t*)app, + CICAM_AOT_DISPLAY_REPLY, + buf, + ARRAY_SIZE(buf), + 0); } } } else if (atag == CICAM_AOT_LIST_LAST || atag == CICAM_AOT_MENU_LAST) { - tvhtrace(LS_EN50221, "%s: %s last", app->cia_name, - atag == CICAM_AOT_LIST_LAST ? "list" : "menu"); + tvhtrace(LS_EN50221, + "%s: %s last", + app->cia_name, + atag == CICAM_AOT_LIST_LAST ? "list" : "menu"); htsmsg_destroy(app->cia_menu); app->cia_menu = NULL; if (datalen > 0) { app->cia_menu = htsmsg_create_map(); if (atag == CICAM_AOT_LIST_LAST) htsmsg_add_bool(app->cia_menu, "selectable", 1); - p = data + 1; l = datalen - 1; /* ignore choice_nb */ + p = data + 1; + l = datalen - 1; /* ignore choice_nb */ r = getmenutext(app, "title", 0, &p, &l); - if (!r) r = getmenutext(app, "subtitle", 0, &p, &l); - if (!r) r = getmenutext(app, "bottom", 0, &p, &l); + if (!r) + r = getmenutext(app, "subtitle", 0, &p, &l); + if (!r) + r = getmenutext(app, "bottom", 0, &p, &l); while (!r && l > 0) r = getmenutext(app, "choices", 1, &p, &l); if (!r) @@ -565,15 +561,13 @@ en50221_app_mmi_handle if (data[1]) /* expected length */ htsmsg_add_s64(app->cia_enquiry, "explen", data[1]); txt = alloca(datalen * 2 + 1); - if (dvb_get_string(txt, datalen * 2 + 1, data + 2, datalen - 2, - NULL, NULL) > 0 && txt[0]) + if (dvb_get_string(txt, datalen * 2 + 1, data + 2, datalen - 2, NULL, NULL) > 0 && txt[0]) htsmsg_add_str(app->cia_enquiry, "text", txt); - tvhtrace(LS_EN50221, "%s: enquiry data %02x %02x '%s'", - app->cia_name, data[0], data[1], txt); + tvhtrace(LS_EN50221, "%s: enquiry data %02x %02x '%s'", app->cia_name, data[0], data[1], txt); CICAM_CALL_APP_CB(app, cisw_enquiry, app->cia_enquiry); } } else if (atag == CICAM_AOT_CLOSE_MMI) { - id = -1; + id = -1; delay = 0; if (datalen > 0) { id = data[0]; @@ -589,31 +583,27 @@ en50221_app_mmi_handle } static en50221_app_prop_t en50221_app_mmi = { - .ciap_name = "mmi", - .ciap_resource_id = CICAM_RI_MMI, - .ciap_struct_size = sizeof(en50221_app_mmi_t), - .ciap_destroy = en50221_app_mmi_destroy, - .ciap_handle = en50221_app_mmi_handle, + .ciap_name = "mmi", + .ciap_resource_id = CICAM_RI_MMI, + .ciap_struct_size = sizeof(en50221_app_mmi_t), + .ciap_destroy = en50221_app_mmi_destroy, + .ciap_handle = en50221_app_mmi_handle, }; -static int en50221_mmi_basic_io - (en50221_slot_t *slot, uint32_t ri, const uint8_t *data, size_t datalen) -{ - en50221_app_t *app; +static int +en50221_mmi_basic_io(en50221_slot_t* slot, uint32_t ri, const uint8_t* data, size_t datalen) { + en50221_app_t* app; app = en50221_slot_find_application(slot, CICAM_RI_MMI, ~0); if (app) - return en50221_app_pdu_send((en50221_app_t *)app, ri, data, datalen, 0); + return en50221_app_pdu_send((en50221_app_t*)app, ri, data, datalen, 0); return 0; } -int en50221_mmi_answer - (en50221_slot_t *slot, const uint8_t *data, size_t datalen) -{ +int en50221_mmi_answer(en50221_slot_t* slot, const uint8_t* data, size_t datalen) { return en50221_mmi_basic_io(slot, CICAM_AOT_ANSW, data, datalen); } -int en50221_mmi_close(en50221_slot_t *slot) -{ +int en50221_mmi_close(en50221_slot_t* slot) { return en50221_mmi_basic_io(slot, CICAM_AOT_CLOSE_MMI, NULL, 0); } @@ -621,8 +611,7 @@ int en50221_mmi_close(en50221_slot_t *slot) * */ -void en50221_register_apps(void) -{ +void en50221_register_apps(void) { en50221_register_app(&en50221_app_resman); en50221_register_app(&en50221_app_ca); en50221_register_app(&en50221_app_datetime); diff --git a/src/input/mpegts/en50221/en50221_capmt.c b/src/input/mpegts/en50221/en50221_capmt.c index 3bcd3987f..035ee289c 100644 --- a/src/input/mpegts/en50221/en50221_capmt.c +++ b/src/input/mpegts/en50221/en50221_capmt.c @@ -21,50 +21,40 @@ #include "esstream.h" #include "input.h" -#define EN50221_CAPMT_CMD_OK 1 -#define EN50221_CAPMT_CMD_OK_MMI 2 -#define EN50221_CAPMT_CMD_QUERY 3 -#define EN50221_CAPMT_CMD_NOTSEL 4 - -#define EN50221_CAPMT_LM_MORE 0 -#define EN50221_CAPMT_LM_FIRST 1 -#define EN50221_CAPMT_LM_LAST 2 -#define EN50221_CAPMT_LM_ONLY 3 -#define EN50221_CAPMT_LM_ADD 4 -#define EN50221_CAPMT_LM_UPDATE 5 +#define EN50221_CAPMT_CMD_OK 1 +#define EN50221_CAPMT_CMD_OK_MMI 2 +#define EN50221_CAPMT_CMD_QUERY 3 +#define EN50221_CAPMT_CMD_NOTSEL 4 + +#define EN50221_CAPMT_LM_MORE 0 +#define EN50221_CAPMT_LM_FIRST 1 +#define EN50221_CAPMT_LM_LAST 2 +#define EN50221_CAPMT_LM_ONLY 3 +#define EN50221_CAPMT_LM_ADD 4 +#define EN50221_CAPMT_LM_UPDATE 5 /* * */ -static inline uint16_t -extract_2byte(const uint8_t *ptr) -{ +static inline uint16_t extract_2byte(const uint8_t* ptr) { return (((uint16_t)ptr[0]) << 8) | ptr[1]; } -static inline uint16_t -extract_pid(const uint8_t *ptr) -{ +static inline uint16_t extract_pid(const uint8_t* ptr) { return ((ptr[0] & 0x1f) << 8) | ptr[1]; } -static inline uint16_t -extract_len12(const uint8_t *ptr) -{ +static inline uint16_t extract_len12(const uint8_t* ptr) { return ((ptr[0] & 0xf) << 8) | ptr[1]; } -static inline void -put_2byte(uint8_t *dst, uint16_t val) -{ +static inline void put_2byte(uint8_t* dst, uint16_t val) { dst[0] = val >> 8; dst[1] = val; } -static inline void -put_len12(uint8_t *dst, uint16_t val) -{ +static inline void put_len12(uint8_t* dst, uint16_t val) { dst[0] &= 0xf0; dst[0] |= (val >> 8) & 0x0f; dst[1] = val; @@ -74,22 +64,22 @@ put_len12(uint8_t *dst, uint16_t val) * */ -static int en50221_capmt_check_pid - (mpegts_service_t *s, uint16_t pid ) -{ - elementary_stream_t *st; +static int en50221_capmt_check_pid(mpegts_service_t* s, uint16_t pid) { + elementary_stream_t* st; - TAILQ_FOREACH(st, &s->s_components.set_filter, es_filter_link) - if (st->es_pid == pid) return 1; + TAILQ_FOREACH (st, &s->s_components.set_filter, es_filter_link) + if (st->es_pid == pid) + return 1; return 0; } -static int en50221_capmt_check_caid - (mpegts_service_t *s, uint16_t pid, uint16_t caid, - const uint16_t *caids, int caids_count) -{ - elementary_stream_t *st; - caid_t *c; +static int en50221_capmt_check_caid(mpegts_service_t* s, + uint16_t pid, + uint16_t caid, + const uint16_t* caids, + int caids_count) { + elementary_stream_t* st; + caid_t* c; for (; caids_count > 0; caids++, caids_count--) if (caid == *caids) @@ -98,11 +88,14 @@ static int en50221_capmt_check_caid if (caids_count == 0) return 0; - TAILQ_FOREACH(st, &s->s_components.set_filter, es_filter_link) { - if (st->es_type != SCT_CA) continue; - LIST_FOREACH(c, &st->es_caids, link) { - if (!c->use) continue; - if (c->caid == caid && c->pid == pid) return 1; + TAILQ_FOREACH (st, &s->s_components.set_filter, es_filter_link) { + if (st->es_type != SCT_CA) + continue; + LIST_FOREACH (c, &st->es_caids, link) { + if (!c->use) + continue; + if (c->caid == caid && c->pid == pid) + return 1; } } return 0; @@ -112,17 +105,20 @@ static int en50221_capmt_check_caid * */ -int en50221_capmt_build - (mpegts_service_t *s, int bcmd, uint16_t svcid, - const uint16_t *caids, int caids_count, - const uint8_t *pmt, size_t pmtlen, - uint8_t **capmt, size_t *capmtlen) -{ - uint8_t *d, *x, *y, dtag, dlen, cmd_id; - const uint8_t *p; - uint16_t l, caid, pid; - size_t tl; - int first = 0; +int en50221_capmt_build(mpegts_service_t* s, + int bcmd, + uint16_t svcid, + const uint16_t* caids, + int caids_count, + const uint8_t* pmt, + size_t pmtlen, + uint8_t** capmt, + size_t* capmtlen) { + uint8_t * d, *x, *y, dtag, dlen, cmd_id; + const uint8_t* p; + uint16_t l, caid, pid; + size_t tl; + int first = 0; if (pmtlen < 9) return -EINVAL; @@ -132,14 +128,20 @@ int en50221_capmt_build cmd_id = EN50221_CAPMT_CMD_OK; switch (bcmd) { - case EN50221_CAPMT_BUILD_ONLY: d[0] = 3; break; - case EN50221_CAPMT_BUILD_ADD: d[0] = 4; break; - case EN50221_CAPMT_BUILD_DELETE: - cmd_id = EN50221_CAPMT_CMD_NOTSEL; - /* fallthru */ - case EN50221_CAPMT_BUILD_UPDATE: d[0] = 5; break; - default: - goto reterr; + case EN50221_CAPMT_BUILD_ONLY: + d[0] = 3; + break; + case EN50221_CAPMT_BUILD_ADD: + d[0] = 4; + break; + case EN50221_CAPMT_BUILD_DELETE: + cmd_id = EN50221_CAPMT_CMD_NOTSEL; + /* fallthru */ + case EN50221_CAPMT_BUILD_UPDATE: + d[0] = 5; + break; + default: + goto reterr; } put_2byte(d + 1, svcid); @@ -147,10 +149,10 @@ int en50221_capmt_build d[4] = 0xf0; /* common descriptors */ - x = d + 6; - l = extract_len12(pmt + 7); - p = pmt + 9; - tl = pmtlen - 9 - l; + x = d + 6; + l = extract_len12(pmt + 7); + p = pmt + 9; + tl = pmtlen - 9 - l; first = 1; if (9 + l > pmtlen) goto reterr; @@ -162,15 +164,15 @@ int en50221_capmt_build pid = extract_pid(p + 4); if (en50221_capmt_check_caid(s, pid, caid, caids, caids_count)) { if (first) { - *x++ = cmd_id; + *x++ = cmd_id; first = 0; } memcpy(x, p, dlen + 2); x += dlen + 2; } } - p += 2 + dlen; - l -= 2 + dlen; + p += 2 + dlen; + l -= 2 + dlen; } if (l) goto reterr; @@ -182,7 +184,7 @@ int en50221_capmt_build if (l + 5 > tl) goto reterr; pid = extract_pid(p + 1); - p += 5; + p += 5; tl -= 5; if (en50221_capmt_check_pid(s, pid)) { memcpy(y = x, p - 5, 3); /* stream type, PID */ @@ -196,15 +198,15 @@ int en50221_capmt_build pid = extract_pid(p + 4); if (en50221_capmt_check_caid(s, pid, caid, caids, caids_count)) { if (first) { - *x++ = cmd_id; + *x++ = cmd_id; first = 0; } memcpy(x, p, dlen + 2); x += dlen + 2; } } - p += 2 + dlen; - l -= 2 + dlen; + p += 2 + dlen; + l -= 2 + dlen; tl -= 2 + dlen; } if (l) @@ -212,13 +214,13 @@ int en50221_capmt_build y[3] = 0xf0; put_len12(y + 3, x - y - 5); } else { - p += l; + p += l; tl -= l; } } if (tl == 0) { - *capmt = d; + *capmt = d; *capmtlen = x - d; return 0; } @@ -232,13 +234,13 @@ reterr: * rewrite capmt cmd_id - set it to 'query' */ -int en50221_capmt_build_query - (const uint8_t *capmt, size_t capmtlen, - uint8_t **dst, size_t *dstlen) -{ - uint8_t *d, *x; - uint16_t l; - size_t tl; +int en50221_capmt_build_query(const uint8_t* capmt, + size_t capmtlen, + uint8_t** dst, + size_t* dstlen) { + uint8_t * d, *x; + uint16_t l; + size_t tl; const uint8_t *p, *n; if (capmtlen < 6) @@ -249,13 +251,13 @@ int en50221_capmt_build_query d = malloc(capmtlen); memcpy(d, capmt, capmtlen); - + p = capmt + 6; n = p + l; tl = capmtlen - l - 6; if (l > 0) { - x = d + (p - capmt); + x = d + (p - capmt); x[0] = EN50221_CAPMT_CMD_QUERY; } @@ -266,15 +268,15 @@ int en50221_capmt_build_query if (l > 0) { if (l < 7) goto reterr; - x = d + (n - capmt); + x = d + (n - capmt); x[5] = EN50221_CAPMT_CMD_QUERY; } - n += 5 + l; + n += 5 + l; tl -= 5 + l; } if (tl == 0) { - *dst = d; + *dst = d; *dstlen = capmtlen; return 0; } @@ -288,22 +290,24 @@ reterr: * */ -void en50221_capmt_dump - (int subsys, const char *prefix, const uint8_t *capmt, size_t capmtlen) -{ - uint16_t l, caid, pid; - uint8_t dtag, dlen, stype; - const uint8_t *p; - char hbuf[257]; +void en50221_capmt_dump(int subsys, const char* prefix, const uint8_t* capmt, size_t capmtlen) { + uint16_t l, caid, pid; + uint8_t dtag, dlen, stype; + const uint8_t* p; + char hbuf[257]; if (capmtlen < 6) { tvhtrace(subsys, "%s: CAPMT short length %zd", prefix, capmtlen); return; } - tvhtrace(subsys, "%s: CAPMT list_management %02x sid %04x ver %02x", - prefix, capmt[0], ((int)capmt[1]) << 8 | capmt[2], capmt[3]); - l = extract_len12(capmt + 4); - p = capmt + 6; + tvhtrace(subsys, + "%s: CAPMT list_management %02x sid %04x ver %02x", + prefix, + capmt[0], + ((int)capmt[1]) << 8 | capmt[2], + capmt[3]); + l = extract_len12(capmt + 4); + p = capmt + 6; capmt = p + l; capmtlen -= l + 6; if (l > 0) { @@ -324,8 +328,13 @@ void en50221_capmt_dump } else { caid = extract_2byte(p + 2); pid = extract_pid(p + 4); - tvhtrace(subsys, "%s: CAPMT CA descriptor caid %04X pid %04x length %d (%s)", - prefix, caid, pid, dlen, bin2hex(hbuf, sizeof(hbuf), p + 6, dlen - 4)); + tvhtrace(subsys, + "%s: CAPMT CA descriptor caid %04X pid %04x length %d (%s)", + prefix, + caid, + pid, + dlen, + bin2hex(hbuf, sizeof(hbuf), p + 6, dlen - 4)); } p += dlen + 2; l -= dlen + 2; @@ -335,8 +344,8 @@ void en50221_capmt_dump stype = capmt[0]; pid = extract_pid(capmt + 1); tvhtrace(subsys, "%s: CAPMT ES stype %02x pid %04x", prefix, stype, pid); - l = extract_len12(capmt + 3); - p = capmt + 5; + l = extract_len12(capmt + 3); + p = capmt + 5; capmt += l + 5; capmtlen -= l + 5; if (l > 0) { @@ -355,8 +364,13 @@ void en50221_capmt_dump } else { caid = extract_2byte(p + 2); pid = extract_pid(p + 4); - tvhtrace(subsys, "%s: CAPMT ES CA descriptor caid %04X pid %04x length %d (%s)", - prefix, caid, pid, dlen, bin2hex(hbuf, sizeof(hbuf), p + 6, dlen - 4)); + tvhtrace(subsys, + "%s: CAPMT ES CA descriptor caid %04X pid %04x length %d (%s)", + prefix, + caid, + pid, + dlen, + bin2hex(hbuf, sizeof(hbuf), p + 6, dlen - 4)); } p += dlen + 2; l -= dlen + 2; diff --git a/src/input/mpegts/en50221/en50221_capmt.h b/src/input/mpegts/en50221/en50221_capmt.h index 20860c6ce..7d6ade15c 100644 --- a/src/input/mpegts/en50221/en50221_capmt.h +++ b/src/input/mpegts/en50221/en50221_capmt.h @@ -23,20 +23,23 @@ struct mpegts_service; -#define EN50221_CAPMT_BUILD_DELETE 0 -#define EN50221_CAPMT_BUILD_ONLY 1 -#define EN50221_CAPMT_BUILD_ADD 2 -#define EN50221_CAPMT_BUILD_UPDATE 4 - -int en50221_capmt_build - (struct mpegts_service *s, - int bcmd, uint16_t svcid, const uint16_t *caids, int caids_count, - const uint8_t *pmt, size_t pmtlen, uint8_t **capmt, size_t *capmtlen); - -int en50221_capmt_build_query(const uint8_t *capmt, size_t capmtlen, - uint8_t **dst, size_t *dstlen); - -void en50221_capmt_dump - (int subsys, const char *prefix, const uint8_t *capmt, size_t capmtlen); +#define EN50221_CAPMT_BUILD_DELETE 0 +#define EN50221_CAPMT_BUILD_ONLY 1 +#define EN50221_CAPMT_BUILD_ADD 2 +#define EN50221_CAPMT_BUILD_UPDATE 4 + +int en50221_capmt_build(struct mpegts_service* s, + int bcmd, + uint16_t svcid, + const uint16_t* caids, + int caids_count, + const uint8_t* pmt, + size_t pmtlen, + uint8_t** capmt, + size_t* capmtlen); + +int en50221_capmt_build_query(const uint8_t* capmt, size_t capmtlen, uint8_t** dst, size_t* dstlen); + +void en50221_capmt_dump(int subsys, const char* prefix, const uint8_t* capmt, size_t capmtlen); #endif /* EN50221_CAPMT_H */ diff --git a/src/input/mpegts/fastscan.c b/src/input/mpegts/fastscan.c index d9e955be4..cc68713e4 100644 --- a/src/input/mpegts/fastscan.c +++ b/src/input/mpegts/fastscan.c @@ -27,7 +27,7 @@ typedef struct dvb_fastscan_item { LIST_ENTRY(dvb_fastscan_item) ilink; - const char *name; + const char* name; int pid; } dvb_fastscan_item_t; @@ -35,51 +35,56 @@ typedef struct dvb_fastscan_item { typedef struct dvb_fastscan { RB_ENTRY(dvb_fastscan) link; - LIST_HEAD(,dvb_fastscan_item) items; + LIST_HEAD(, dvb_fastscan_item) items; - int position; - dvb_fe_delivery_system_t delsys; - dvb_polarisation_t polarisation; - uint32_t frequency; - uint32_t symbolRate; + int position; + dvb_fe_delivery_system_t delsys; + dvb_polarisation_t polarisation; + uint32_t frequency; + uint32_t symbolRate; } dvb_fastscan_t; -static RB_HEAD(,dvb_fastscan) fastscan_rb; +static RB_HEAD(, dvb_fastscan) fastscan_rb; static SKEL_DECLARE(fastscan_rb_skel, dvb_fastscan_t); -static int -_fs_cmp(const void *a, const void *b) -{ - int r = ((dvb_fastscan_t *)a)->position - ((dvb_fastscan_t *)b)->position; +static int _fs_cmp(const void* a, const void* b) { + int r = ((dvb_fastscan_t*)a)->position - ((dvb_fastscan_t*)b)->position; if (r == 0) { - r = ((dvb_fastscan_t *)a)->frequency - ((dvb_fastscan_t *)b)->frequency; + r = ((dvb_fastscan_t*)a)->frequency - ((dvb_fastscan_t*)b)->frequency; if (abs(r) < 2000) - return (((dvb_fastscan_t *)a)->polarisation - ((dvb_fastscan_t *)b)->polarisation); + return (((dvb_fastscan_t*)a)->polarisation - ((dvb_fastscan_t*)b)->polarisation); } return r; } -void -dvb_fastscan_each(void *aux, int position, uint32_t frequency, dvb_polarisation_t polarisation, - void (*job)(void *aux, bouquet_t *bq, - const char *name, int pid)) -{ - dvb_fastscan_t *fs; - dvb_fastscan_item_t *fsi; - bouquet_t *bq; - char url[64], buf[16]; +void dvb_fastscan_each(void* aux, + int position, + uint32_t frequency, + dvb_polarisation_t polarisation, + void (*job)(void* aux, bouquet_t* bq, const char* name, int pid)) { + dvb_fastscan_t* fs; + dvb_fastscan_item_t* fsi; + bouquet_t* bq; + char url[64], buf[16]; SKEL_ALLOC(fastscan_rb_skel); - fastscan_rb_skel->position = position; - fastscan_rb_skel->frequency = frequency; + fastscan_rb_skel->position = position; + fastscan_rb_skel->frequency = frequency; fastscan_rb_skel->polarisation = polarisation; - fs = RB_FIND(&fastscan_rb, fastscan_rb_skel, link, _fs_cmp); + fs = RB_FIND(&fastscan_rb, fastscan_rb_skel, link, _fs_cmp); if (!fs) return; - LIST_FOREACH(fsi, &fs->items, ilink) { + LIST_FOREACH (fsi, &fs->items, ilink) { dvb_sat_position_to_str(fs->position, buf, sizeof(buf)); - snprintf(url, sizeof(url), "dvb-fastscan://%s,%s,%u,%s,%u,%d", dvb_delsys2str(fastscan_rb_skel->delsys), - buf, fs->frequency, dvb_pol2str(fs->polarisation), fs->symbolRate, fsi->pid); + snprintf(url, + sizeof(url), + "dvb-fastscan://%s,%s,%u,%s,%u,%d", + dvb_delsys2str(fastscan_rb_skel->delsys), + buf, + fs->frequency, + dvb_pol2str(fs->polarisation), + fs->symbolRate, + fsi->pid); bq = bouquet_find_by_source(NULL, url, 0); if (bq == NULL || !bq->bq_enabled) continue; @@ -88,15 +93,13 @@ dvb_fastscan_each(void *aux, int position, uint32_t frequency, dvb_polarisation_ } } -static void -dvb_fastscan_create(htsmsg_t *e) -{ - dvb_fastscan_t *fs; - dvb_fastscan_item_t *fsi; - bouquet_t *bq; - const char *name, *polarisation, *delsys; - int pid; - char url[64], buf[16]; +static void dvb_fastscan_create(htsmsg_t* e) { + dvb_fastscan_t* fs; + dvb_fastscan_item_t* fsi; + bouquet_t* bq; + const char * name, *polarisation, *delsys; + int pid; + char url[64], buf[16]; SKEL_ALLOC(fastscan_rb_skel); if (htsmsg_get_s32(e, "position", &fastscan_rb_skel->position)) @@ -115,10 +118,17 @@ dvb_fastscan_create(htsmsg_t *e) goto fail; fastscan_rb_skel->polarisation = dvb_str2pol(polarisation); - fastscan_rb_skel->delsys = dvb_str2delsys(delsys); + fastscan_rb_skel->delsys = dvb_str2delsys(delsys); dvb_sat_position_to_str(fastscan_rb_skel->position, buf, sizeof(buf)); - snprintf(url, sizeof(url), "dvb-fastscan://%s,%s,%u,%s,%u,%d", dvb_delsys2str(fastscan_rb_skel->delsys), - buf, fastscan_rb_skel->frequency, dvb_pol2str(fastscan_rb_skel->polarisation), fastscan_rb_skel->symbolRate, pid); + snprintf(url, + sizeof(url), + "dvb-fastscan://%s,%s,%u,%s,%u,%d", + dvb_delsys2str(fastscan_rb_skel->delsys), + buf, + fastscan_rb_skel->frequency, + dvb_pol2str(fastscan_rb_skel->polarisation), + fastscan_rb_skel->symbolRate, + pid); bq = bouquet_find_by_source(name, url, 1); if (bq == NULL) goto fail; @@ -135,7 +145,7 @@ dvb_fastscan_create(htsmsg_t *e) LIST_INIT(&fs->items); } - fsi = calloc(1, sizeof(*fsi)); + fsi = calloc(1, sizeof(*fsi)); fsi->pid = pid; if ((fsi->name = htsmsg_get_str(e, "name")) == NULL) goto fail; @@ -152,18 +162,18 @@ fail: /* * Initialize the fastscan list */ -void dvb_fastscan_init ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; +void dvb_fastscan_init(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; if (!(c = hts_settings_load("fastscan"))) { tvhwarn(LS_FASTSCAN, "configuration file missing"); return; } - + HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; dvb_fastscan_create(e); } htsmsg_destroy(c); @@ -172,16 +182,15 @@ void dvb_fastscan_init ( void ) /* * */ -void dvb_fastscan_done ( void ) -{ - dvb_fastscan_t *fs; - dvb_fastscan_item_t *fsi; - +void dvb_fastscan_done(void) { + dvb_fastscan_t* fs; + dvb_fastscan_item_t* fsi; + while ((fs = RB_FIRST(&fastscan_rb)) != NULL) { RB_REMOVE(&fastscan_rb, fs, link); while ((fsi = LIST_FIRST(&fs->items)) != NULL) { LIST_REMOVE(fsi, ilink); - free((char *)fsi->name); + free((char*)fsi->name); free(fsi); } free(fs); @@ -191,12 +200,8 @@ void dvb_fastscan_done ( void ) #else -void dvb_fastscan_init ( void ) -{ -} +void dvb_fastscan_init(void) {} -void dvb_fastscan_done ( void ) -{ -} +void dvb_fastscan_done(void) {} #endif diff --git a/src/input/mpegts/fastscan.h b/src/input/mpegts/fastscan.h index ca5774200..cca1d9aa5 100644 --- a/src/input/mpegts/fastscan.h +++ b/src/input/mpegts/fastscan.h @@ -23,14 +23,15 @@ struct bouquet; -void -dvb_fastscan_each(void *aux, int position, uint32_t frequency, dvb_polarisation_t polarisation, - void (*job)(void *aux, struct bouquet *, - const char *name, int pid)); +void dvb_fastscan_each(void* aux, + int position, + uint32_t frequency, + dvb_polarisation_t polarisation, + void (*job)(void* aux, struct bouquet*, const char* name, int pid)); #endif -void dvb_fastscan_init ( void ); -void dvb_fastscan_done ( void ); +void dvb_fastscan_init(void); +void dvb_fastscan_done(void); #endif /* TVH_DVB_FASTSCAN_H */ diff --git a/src/input/mpegts/iptv.h b/src/input/mpegts/iptv.h index 05c74b2b5..b50911f47 100644 --- a/src/input/mpegts/iptv.h +++ b/src/input/mpegts/iptv.h @@ -20,10 +20,10 @@ #ifndef __IPTV_H__ #define __IPTV_H__ -void iptv_bouquet_trigger_by_uuid(const char *uuid); +void iptv_bouquet_trigger_by_uuid(const char* uuid); -void iptv_init ( void ); -void iptv_done ( void ); +void iptv_init(void); +void iptv_done(void); #endif /* __IPTV_H__ */ diff --git a/src/input/mpegts/iptv/iptv.c b/src/input/mpegts/iptv/iptv.c index b1efb0b21..820493451 100644 --- a/src/input/mpegts/iptv/iptv.c +++ b/src/input/mpegts/iptv/iptv.c @@ -36,22 +36,21 @@ tvh_mutex_t iptv_lock; typedef struct iptv_thread_pool { TAILQ_ENTRY(iptv_thread_pool) link; - pthread_t thread; - iptv_input_t *input; - tvhpoll_t *poll; - th_pipe_t pipe; - uint32_t streams; + pthread_t thread; + iptv_input_t* input; + tvhpoll_t* poll; + th_pipe_t pipe; + uint32_t streams; } iptv_thread_pool_t; TAILQ_HEAD(, iptv_thread_pool) iptv_tpool; -int iptv_tpool_count = 0; -iptv_thread_pool_t *iptv_tpool_last = NULL; -gtimer_t iptv_tpool_manage_timer; +int iptv_tpool_count = 0; +iptv_thread_pool_t* iptv_tpool_last = NULL; +gtimer_t iptv_tpool_manage_timer; -static void iptv_input_thread_manage_cb(void *aux); +static void iptv_input_thread_manage_cb(void* aux); -static inline int iptv_tpool_safe_count(void) -{ +static inline int iptv_tpool_safe_count(void) { return MINMAX(config.iptv_tpool_count, 1, 128); } @@ -59,31 +58,24 @@ static inline int iptv_tpool_safe_count(void) * IPTV handlers * *************************************************************************/ -static RB_HEAD(,iptv_handler) iptv_handlers; +static RB_HEAD(, iptv_handler) iptv_handlers; -static int -ih_cmp ( iptv_handler_t *a, iptv_handler_t *b ) -{ +static int ih_cmp(iptv_handler_t* a, iptv_handler_t* b) { return strcasecmp(a->scheme ?: "", b->scheme ?: ""); } -void -iptv_handler_register ( iptv_handler_t *ih, int num ) -{ - iptv_handler_t *r; +void iptv_handler_register(iptv_handler_t* ih, int num) { + iptv_handler_t* r; while (num) { r = RB_INSERT_SORTED(&iptv_handlers, ih, link, ih_cmp); if (r) - tvhwarn(LS_IPTV, "attempt to re-register handler for %s", - ih->scheme); + tvhwarn(LS_IPTV, "attempt to re-register handler for %s", ih->scheme); num--; ih++; } } -static iptv_handler_t * -iptv_handler_find ( const char *scheme ) -{ +static iptv_handler_t* iptv_handler_find(const char* scheme) { iptv_handler_t ih; ih.scheme = scheme; @@ -94,13 +86,11 @@ iptv_handler_find ( const char *scheme ) * IPTV input * *************************************************************************/ -static int -iptv_input_thread_number ( iptv_input_t *mi ) -{ - iptv_thread_pool_t *pool; - int num = 1; +static int iptv_input_thread_number(iptv_input_t* mi) { + iptv_thread_pool_t* pool; + int num = 1; - TAILQ_FOREACH(pool, &iptv_tpool, link) { + TAILQ_FOREACH (pool, &iptv_tpool, link) { if (pool->input == mi) break; num++; @@ -109,52 +99,50 @@ iptv_input_thread_number ( iptv_input_t *mi ) } static void -iptv_input_class_get_title - ( idnode_t *self, const char *lang, char *dst, size_t dstsize ) -{ - int num = iptv_input_thread_number((iptv_input_t *)self); +iptv_input_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + int num = iptv_input_thread_number((iptv_input_t*)self); snprintf(dst, dstsize, "%s%d", tvh_gettext_lang(lang, N_("IPTV thread #")), num); } extern const idclass_t mpegts_input_class; -const idclass_t iptv_input_class = { - .ic_super = &mpegts_input_class, - .ic_class = "iptv_input", - .ic_caption = N_("IPTV input"), - .ic_get_title = iptv_input_class_get_title, - .ic_properties = (const property_t[]){ - {} - } -}; +const idclass_t iptv_input_class = {.ic_super = &mpegts_input_class, + .ic_class = "iptv_input", + .ic_caption = N_("IPTV input"), + .ic_get_title = iptv_input_class_get_title, + .ic_properties = (const property_t[]){{}}}; typedef struct { - uint32_t active:1; - uint32_t weight:1; - uint32_t warm:1; + uint32_t active : 1; + uint32_t weight : 1; + uint32_t warm : 1; } iptv_is_free_t; -static mpegts_mux_instance_t * -iptv_input_is_free ( mpegts_input_t *mi, mpegts_mux_t *mm, - iptv_is_free_t *conf, int weight, int *lweight ) -{ - int h = 0, l = 0, mux_running = 0, w, rw = INT_MAX; +static mpegts_mux_instance_t* iptv_input_is_free(mpegts_input_t* mi, + mpegts_mux_t* mm, + iptv_is_free_t* conf, + int weight, + int* lweight) { + int h = 0, l = 0, mux_running = 0, w, rw = INT_MAX; mpegts_mux_instance_t *mmi, *rmmi = NULL; - iptv_input_t *mi2; - iptv_network_t *in = (iptv_network_t *)mm->mm_network; - iptv_thread_pool_t *pool; + iptv_input_t* mi2; + iptv_network_t* in = (iptv_network_t*)mm->mm_network; + iptv_thread_pool_t* pool; - TAILQ_FOREACH(pool, &iptv_tpool, link) { + TAILQ_FOREACH (pool, &iptv_tpool, link) { mi2 = pool->input; tvh_mutex_lock(&mi2->mi_output_lock); - LIST_FOREACH(mmi, &mi2->mi_mux_active, mmi_active_link) - if (mmi->mmi_mux->mm_network == (mpegts_network_t *)in) { + LIST_FOREACH (mmi, &mi2->mi_mux_active, mmi_active_link) + if (mmi->mmi_mux->mm_network == (mpegts_network_t*)in) { mux_running = mux_running || mmi->mmi_mux == mm; - w = mpegts_mux_instance_weight(mmi); + w = mpegts_mux_instance_weight(mmi); if (w < rw && (!conf->active || mmi->mmi_mux != mm)) { rmmi = mmi; - rw = w; + rw = w; } - if (w >= weight) h++; else l++; + if (w >= weight) + h++; + else + l++; } tvh_mutex_unlock(&mi2->mi_output_lock); } @@ -173,11 +161,12 @@ iptv_input_is_free ( mpegts_input_t *mi, mpegts_mux_t *mm, /* Limit reached */ w = h; - if (conf->weight || conf->warm) w += l; + if (conf->weight || conf->warm) + w += l; if (in->in_max_streams && w >= in->in_max_streams) if (rmmi->mmi_mux != mm) return rmmi; - + /* Bandwidth reached */ if (in->in_bw_limited && l == 0) if (rmmi->mmi_mux != mm) @@ -186,34 +175,29 @@ iptv_input_is_free ( mpegts_input_t *mi, mpegts_mux_t *mm, return NULL; } -static int -iptv_input_thread_balance(iptv_input_t *mi) -{ +static int iptv_input_thread_balance(iptv_input_t* mi) { iptv_thread_pool_t *pool, *apool = mi->mi_tpool; /* * select input with the smallest count of active threads */ - TAILQ_FOREACH(pool, &iptv_tpool, link) + TAILQ_FOREACH (pool, &iptv_tpool, link) if (pool->streams < apool->streams) return 1; return 0; } -static int -iptv_input_is_enabled - ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) -{ - int r; - mpegts_mux_instance_t *mmi; - iptv_is_free_t conf = { .active = 0, .weight = 0, .warm = 0 }; +static int iptv_input_is_enabled(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight) { + int r; + mpegts_mux_instance_t* mmi; + iptv_is_free_t conf = {.active = 0, .weight = 0, .warm = 0}; r = mpegts_input_is_enabled(mi, mm, flags, weight); if (r != MI_IS_ENABLED_OK) { tvhtrace(LS_IPTV_SUB, "enabled[%p]: generic %d", mm, r); return r; } - if (iptv_input_thread_balance((iptv_input_t *)mi)) { + if (iptv_input_thread_balance((iptv_input_t*)mi)) { tvhtrace(LS_IPTV_SUB, "enabled[%p]: balance", mm); return MI_IS_ENABLED_RETRY; } @@ -222,34 +206,26 @@ iptv_input_is_enabled return mmi == NULL ? MI_IS_ENABLED_OK : MI_IS_ENABLED_RETRY; } -static int -iptv_input_get_weight - ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) -{ - int w; - mpegts_mux_instance_t *mmi; - iptv_is_free_t conf = { .active = 1, .weight = 1, .warm = 0 }; +static int iptv_input_get_weight(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight) { + int w; + mpegts_mux_instance_t* mmi; + iptv_is_free_t conf = {.active = 1, .weight = 1, .warm = 0}; /* Find the "min" weight */ mmi = iptv_input_is_free(mi, mm, &conf, weight, &w); tvhtrace(LS_IPTV_SUB, "get weight[%p]: %p (%d)", mm, mmi, w); return mmi == NULL ? 0 : w; - } -static int -iptv_input_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ - iptv_mux_t *im = (iptv_mux_t *)mm; - iptv_network_t *in = (iptv_network_t *)im->mm_network; +static int iptv_input_get_grace(mpegts_input_t* mi, mpegts_mux_t* mm) { + iptv_mux_t* im = (iptv_mux_t*)mm; + iptv_network_t* in = (iptv_network_t*)im->mm_network; return in->in_max_timeout; } -static int -iptv_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) -{ - iptv_mux_t *im = (iptv_mux_t *)mm; - iptv_network_t *in = (iptv_network_t *)im->mm_network; +static int iptv_input_get_priority(mpegts_input_t* mi, mpegts_mux_t* mm, int flags) { + iptv_mux_t* im = (iptv_mux_t*)mm; + iptv_network_t* in = (iptv_network_t*)im->mm_network; if (flags & SUBSCRIPTION_STREAMING) { if (im->mm_iptv_streaming_priority > 0) return im->mm_iptv_streaming_priority; @@ -259,12 +235,10 @@ iptv_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) return im->mm_iptv_priority > 0 ? im->mm_iptv_priority : in->in_priority; } -static int -iptv_input_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ - iptv_mux_t *im = (iptv_mux_t*)mmi->mmi_mux; - mpegts_mux_instance_t *lmmi; - iptv_is_free_t conf = { .active = 1, .weight = 0, .warm = 1 }; +static int iptv_input_warm_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { + iptv_mux_t* im = (iptv_mux_t*)mmi->mmi_mux; + mpegts_mux_instance_t* lmmi; + iptv_is_free_t conf = {.active = 1, .weight = 0, .warm = 1}; /* Already active */ if (im->mm_active) @@ -280,13 +254,10 @@ iptv_input_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) return 0; } -static const char * -iptv_sub_url_encode(iptv_mux_t *im, const char *s, char *tmp, size_t tmplen) -{ - char *p; +static const char* iptv_sub_url_encode(iptv_mux_t* im, const char* s, char* tmp, size_t tmplen) { + char* p; if (im->mm_iptv_url && - (!strncmp(im->mm_iptv_url, "pipe://", 7) || - !strncmp(im->mm_iptv_url, "file://", 7))) + (!strncmp(im->mm_iptv_url, "pipe://", 7) || !strncmp(im->mm_iptv_url, "file://", 7))) return s; p = url_encode(s); strlcpy(tmp, p, tmplen); @@ -294,47 +265,40 @@ iptv_sub_url_encode(iptv_mux_t *im, const char *s, char *tmp, size_t tmplen) return tmp; } -static const char * -iptv_sub_mux_name(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - const mpegts_mux_instance_t *mmi = aux; - iptv_mux_t *im = (iptv_mux_t*)mmi->mmi_mux; +static const char* +iptv_sub_mux_name(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + const mpegts_mux_instance_t* mmi = aux; + iptv_mux_t* im = (iptv_mux_t*)mmi->mmi_mux; return iptv_sub_url_encode(im, im->mm_iptv_muxname, tmp, tmplen); } -static const char * -iptv_sub_service_name(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - const mpegts_mux_instance_t *mmi = aux; - iptv_mux_t *im = (iptv_mux_t*)mmi->mmi_mux; +static const char* +iptv_sub_service_name(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + const mpegts_mux_instance_t* mmi = aux; + iptv_mux_t* im = (iptv_mux_t*)mmi->mmi_mux; return iptv_sub_url_encode(im, im->mm_iptv_svcname, tmp, tmplen); } -static const char * -iptv_sub_weight(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen) -{ - const mpegts_mux_instance_t *mmi = aux; +static const char* +iptv_sub_weight(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen) { + const mpegts_mux_instance_t* mmi = aux; snprintf(tmp, tmplen, "%d", mmi->mmi_start_weight); return tmp; } -static htsstr_substitute_t iptv_input_subst[] = { - { .id = "m", .getval = iptv_sub_mux_name }, - { .id = "n", .getval = iptv_sub_service_name }, - { .id = "w", .getval = iptv_sub_weight }, - { .id = NULL, .getval = NULL } -}; - -static int -iptv_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weight ) -{ - int ret = SM_CODE_TUNING_FAILED; - iptv_mux_t *im = (iptv_mux_t*)mmi->mmi_mux; - iptv_handler_t *ih; - iptv_thread_pool_t *pool = ((iptv_input_t *)mi)->mi_tpool; - char buf[256], rawbuf[512], *raw = im->mm_iptv_url, *s; - const char *scheme; - url_t url; +static htsstr_substitute_t iptv_input_subst[] = {{.id = "m", .getval = iptv_sub_mux_name}, + {.id = "n", .getval = iptv_sub_service_name}, + {.id = "w", .getval = iptv_sub_weight}, + {.id = NULL, .getval = NULL}}; + +static int iptv_input_start_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi, int weight) { + int ret = SM_CODE_TUNING_FAILED; + iptv_mux_t* im = (iptv_mux_t*)mmi->mmi_mux; + iptv_handler_t* ih; + iptv_thread_pool_t* pool = ((iptv_input_t*)mi)->mi_tpool; + char buf[256], rawbuf[512], *raw = im->mm_iptv_url, *s; + const char* scheme; + url_t url; /* Already active */ if (im->mm_active) @@ -344,11 +308,11 @@ iptv_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weigh atomic_set(&mmi->tii_stats.unc, 0); atomic_set(&mmi->tii_stats.cc, 0); tvh_mutex_lock(&mmi->tii_stats_mutex); - mmi->tii_stats.te = 0; + mmi->tii_stats.te = 0; mmi->tii_stats.ec_block = 0; mmi->tii_stats.tc_block = 0; tvh_mutex_unlock(&mmi->tii_stats_mutex); - + /* Substitute things */ if (im->mm_iptv_substitute && raw) { htsstr_substitute(raw, rawbuf, sizeof(rawbuf), '$', iptv_input_subst, mmi, buf, sizeof(buf)); @@ -360,13 +324,13 @@ iptv_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weigh #if ENABLE_LIBAV if (im->mm_iptv_libav > 0 || - (im->mm_iptv_libav == 0 && ((iptv_network_t *)im->mm_network)->in_libav)) { + (im->mm_iptv_libav == 0 && ((iptv_network_t*)im->mm_network)->in_libav)) { scheme = "libav"; } else #endif - if (raw && !strncmp(raw, "pipe://", 7)) { + if (raw && !strncmp(raw, "pipe://", 7)) { scheme = "pipe"; @@ -387,7 +351,6 @@ iptv_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weigh return ret; } scheme = url.scheme; - } /* Find scheme handler */ @@ -399,17 +362,17 @@ iptv_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weigh /* Start */ tvh_mutex_lock(&iptv_lock); - s = im->mm_iptv_url_raw; + s = im->mm_iptv_url_raw; im->mm_iptv_url_raw = raw ? strdup(raw) : NULL; if (im->mm_iptv_url_raw) { im->mm_active = mmi; // Note: must set here else mux_started call // will not realise we're ready to accept pid open calls - ret = ih->start((iptv_input_t *)mi, im, im->mm_iptv_url_raw, &url); + ret = ih->start((iptv_input_t*)mi, im, im->mm_iptv_url_raw, &url); if (!ret) { im->im_handler = ih; pool->streams++; } else { - im->mm_active = NULL; + im->mm_active = NULL; } } tvh_mutex_unlock(&iptv_lock); @@ -420,10 +383,8 @@ iptv_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weigh return ret; } -void -iptv_input_close_fds ( iptv_input_t *mi, iptv_mux_t *im ) -{ - iptv_thread_pool_t *pool = mi->mi_tpool; +void iptv_input_close_fds(iptv_input_t* mi, iptv_mux_t* im) { + iptv_thread_pool_t* pool = mi->mi_tpool; if (im->mm_iptv_fd > 0 || im->im_rtcp_info.connection_fd > 0) tvhtrace(LS_IPTV, "iptv_input_close_fds %d %d", im->mm_iptv_fd, im->im_rtcp_info.connection_fd); @@ -431,32 +392,30 @@ iptv_input_close_fds ( iptv_input_t *mi, iptv_mux_t *im ) /* Close file */ if (im->mm_iptv_fd > 0) { tvhpoll_rem1(pool->poll, im->mm_iptv_fd); - if(im->mm_iptv_connection == NULL) + if (im->mm_iptv_connection == NULL) close(im->mm_iptv_fd); else udp_close(im->mm_iptv_connection); im->mm_iptv_connection = NULL; - im->mm_iptv_fd = -1; + im->mm_iptv_fd = -1; } /* Close file2 */ if (im->im_rtcp_info.connection_fd > 0) { tvhpoll_rem1(pool->poll, im->im_rtcp_info.connection_fd); - if(im->im_rtcp_info.connection == NULL) + if (im->im_rtcp_info.connection == NULL) close(im->im_rtcp_info.connection_fd); else udp_close(im->im_rtcp_info.connection); - im->im_rtcp_info.connection = NULL; + im->im_rtcp_info.connection = NULL; im->im_rtcp_info.connection_fd = -1; } } -static void -iptv_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ - iptv_mux_t *im = (iptv_mux_t*)mmi->mmi_mux; - iptv_thread_pool_t *pool = ((iptv_input_t *)mi)->mi_tpool; - uint32_t u32; +static void iptv_input_stop_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { + iptv_mux_t* im = (iptv_mux_t*)mmi->mmi_mux; + iptv_thread_pool_t* pool = ((iptv_input_t*)mi)->mi_tpool; + uint32_t u32; tvh_mutex_lock(&iptv_lock); @@ -464,15 +423,15 @@ iptv_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) /* Stop */ if (im->im_handler->stop) - im->im_handler->stop((iptv_input_t *)mi, im); + im->im_handler->stop((iptv_input_t*)mi, im); - iptv_input_close_fds((iptv_input_t *)mi, im); + iptv_input_close_fds((iptv_input_t*)mi, im); /* Free memory */ sbuf_free(&im->mm_iptv_buffer); /* Clear bw limit */ - ((iptv_network_t *)im->mm_network)->in_bw_limited = 0; + ((iptv_network_t*)im->mm_network)->in_bw_limited = 0; u32 = --pool->streams; @@ -482,15 +441,11 @@ iptv_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) gtimer_arm_rel(&iptv_tpool_manage_timer, iptv_input_thread_manage_cb, NULL, 0); } -static void -iptv_input_display_name ( mpegts_input_t *mi, char *buf, size_t len ) -{ - snprintf(buf, len, "IPTV #%d", iptv_input_thread_number((iptv_input_t *)mi)); +static void iptv_input_display_name(mpegts_input_t* mi, char* buf, size_t len) { + snprintf(buf, len, "IPTV #%d", iptv_input_thread_number((iptv_input_t*)mi)); } -static inline int -iptv_input_pause_check ( iptv_mux_t *im ) -{ +static inline int iptv_input_pause_check(iptv_mux_t* im) { int64_t old, s64, limit; if ((old = im->im_pcr) == PTS_UNSET) @@ -506,23 +461,25 @@ iptv_input_pause_check ( iptv_mux_t *im ) im->im_pcr += (((s64 / 10LL) * 9LL) + 4LL) / 10LL; im->im_pcr &= PTS_MASK; if (old != im->im_pcr) - tvhtrace(LS_IPTV_PCR, "updated %"PRId64", time start %"PRId64", limit %"PRId64", diff %"PRId64, - im->im_pcr, im->im_pcr_start, limit, im->im_pcr_end - im->im_pcr_start); + tvhtrace(LS_IPTV_PCR, + "updated %" PRId64 ", time start %" PRId64 ", limit %" PRId64 ", diff %" PRId64, + im->im_pcr, + im->im_pcr_start, + limit, + im->im_pcr_end - im->im_pcr_start); /* queued more than threshold? trigger the pause */ return im->im_pcr_end - im->im_pcr_start >= limit; } -void -iptv_input_unpause ( void *aux ) -{ - iptv_mux_t *im = aux; - iptv_input_t *mi; - int pause; +void iptv_input_unpause(void* aux) { + iptv_mux_t* im = aux; + iptv_input_t* mi; + int pause; tvh_mutex_lock(&iptv_lock); pause = 0; if (im->mm_active) { - mi = (iptv_input_t *)im->mm_active->mmi_input; + mi = (iptv_input_t*)im->mm_active->mmi_input; if (iptv_input_pause_check(im)) { tvhtrace(LS_IPTV_PCR, "paused (in unpause)"); pause = 1; @@ -536,26 +493,23 @@ iptv_input_unpause ( void *aux ) mtimer_arm_rel(&im->im_pause_timer, iptv_input_unpause, im, sec2mono(1)); } -static void * -iptv_input_thread ( void *aux ) -{ - iptv_thread_pool_t *pool = aux; - int nfds, r; - ssize_t n; - iptv_mux_t *im; - iptv_input_t *mi; - tvhpoll_event_t ev; - - while ( tvheadend_is_running() ) { +static void* iptv_input_thread(void* aux) { + iptv_thread_pool_t* pool = aux; + int nfds, r; + ssize_t n; + iptv_mux_t* im; + iptv_input_t* mi; + tvhpoll_event_t ev; + + while (tvheadend_is_running()) { nfds = tvhpoll_wait(pool->poll, &ev, 1, -1); - if ( nfds < 0 ) { + if (nfds < 0) { if (tvheadend_is_running() && !ERRNO_AGAIN(errno)) { - tvherror(LS_IPTV, "poll() error %s, sleeping 1 second", - strerror(errno)); + tvherror(LS_IPTV, "poll() error %s, sleeping 1 second", strerror(errno)); sleep(1); } continue; - } else if ( nfds == 0 ) { + } else if (nfds == 0) { continue; } @@ -569,7 +523,7 @@ iptv_input_thread ( void *aux ) /* Only when active */ if (im->mm_active) { - mi = (iptv_input_t *)im->mm_active->mmi_input; + mi = (iptv_input_t*)im->mm_active->mmi_input; /* Get data */ if ((n = im->im_handler->read(mi, im)) < 0) { tvherror(LS_IPTV, "read() error %s", strerror(errno)); @@ -593,10 +547,8 @@ iptv_input_thread ( void *aux ) return NULL; } -void -iptv_input_pause_handler ( iptv_input_t *mi, iptv_mux_t *im, int pause ) -{ - iptv_thread_pool_t *tpool = mi->mi_tpool; +void iptv_input_pause_handler(iptv_input_t* mi, iptv_mux_t* im, int pause) { + iptv_thread_pool_t* tpool = mi->mi_tpool; if (pause) tvhpoll_rem1(tpool->poll, im->mm_iptv_fd); @@ -604,25 +556,20 @@ iptv_input_pause_handler ( iptv_input_t *mi, iptv_mux_t *im, int pause ) tvhpoll_add1(tpool->poll, im->mm_iptv_fd, TVHPOLL_IN, im); } -void -iptv_input_recv_flush ( iptv_mux_t *im ) -{ - mpegts_mux_instance_t *mmi = im->mm_active; +void iptv_input_recv_flush(iptv_mux_t* im) { + mpegts_mux_instance_t* mmi = im->mm_active; if (mmi == NULL) return; - mpegts_input_recv_packets(mmi, &im->mm_iptv_buffer, - MPEGTS_DATA_CC_RESTART, NULL); + mpegts_input_recv_packets(mmi, &im->mm_iptv_buffer, MPEGTS_DATA_CC_RESTART, NULL); } -int -iptv_input_recv_packets ( iptv_mux_t *im, ssize_t len ) -{ - iptv_network_t *in = (iptv_network_t*)im->mm_network; - mpegts_mux_instance_t *mmi; - mpegts_pcr_t pcr; - char buf[384]; - int64_t s64; +int iptv_input_recv_packets(iptv_mux_t* im, ssize_t len) { + iptv_network_t* in = (iptv_network_t*)im->mm_network; + mpegts_mux_instance_t* mmi; + mpegts_pcr_t pcr; + char buf[384]; + int64_t s64; pcr.pcr_first = PTS_UNSET; pcr.pcr_last = PTS_UNSET; @@ -630,15 +577,15 @@ iptv_input_recv_packets ( iptv_mux_t *im, ssize_t len ) in->in_bps += len * 8; s64 = mclk(); if (mono2sec(in->in_bandwidth_clock) != mono2sec(s64)) { - if (in->in_max_bandwidth && - in->in_bps > in->in_max_bandwidth * 1024) { + if (in->in_max_bandwidth && in->in_bps > in->in_max_bandwidth * 1024) { if (!in->in_bw_limited) { - tvhinfo(LS_IPTV, "%s bandwidth limited exceeded", - idnode_get_title(&in->mn_id, NULL, buf, sizeof(buf))); + tvhinfo(LS_IPTV, + "%s bandwidth limited exceeded", + idnode_get_title(&in->mn_id, NULL, buf, sizeof(buf))); in->in_bw_limited = 1; } } - in->in_bps = 0; + in->in_bps = 0; in->in_bandwidth_clock = s64; } @@ -649,25 +596,33 @@ iptv_input_recv_packets ( iptv_mux_t *im, ssize_t len ) tvhtrace(LS_IPTV_PCR, "paused"); return 1; } - mpegts_input_recv_packets(mmi, &im->mm_iptv_buffer, - in->in_remove_scrambled_bits ? - MPEGTS_DATA_REMOVE_SCRAMBLED : 0, &pcr); + mpegts_input_recv_packets(mmi, + &im->mm_iptv_buffer, + in->in_remove_scrambled_bits ? MPEGTS_DATA_REMOVE_SCRAMBLED : 0, + &pcr); if (pcr.pcr_first != PTS_UNSET && pcr.pcr_last != PTS_UNSET) { im->im_pcr_pid = pcr.pcr_pid; if (im->im_pcr == PTS_UNSET) { s64 = pts_diff(pcr.pcr_first, pcr.pcr_last); if (s64 != PTS_UNSET) { - im->im_pcr = pcr.pcr_first; + im->im_pcr = pcr.pcr_first; im->im_pcr_start = getfastmonoclock(); - im->im_pcr_end = im->im_pcr_start + ((s64 * 100LL) + 50LL) / 9LL; - tvhtrace(LS_IPTV_PCR, "first %"PRId64" last %"PRId64", time start %"PRId64", end %"PRId64, - pcr.pcr_first, pcr.pcr_last, im->im_pcr_start, im->im_pcr_end); + im->im_pcr_end = im->im_pcr_start + ((s64 * 100LL) + 50LL) / 9LL; + tvhtrace(LS_IPTV_PCR, + "first %" PRId64 " last %" PRId64 ", time start %" PRId64 ", end %" PRId64, + pcr.pcr_first, + pcr.pcr_last, + im->im_pcr_start, + im->im_pcr_end); } } else { s64 = pts_diff(im->im_pcr, pcr.pcr_last); if (s64 != PTS_UNSET) { im->im_pcr_end = im->im_pcr_start + ((s64 * 100LL) + 50LL) / 9LL; - tvhtrace(LS_IPTV_PCR, "last %"PRId64", time end %"PRId64, pcr.pcr_last, im->im_pcr_end); + tvhtrace(LS_IPTV_PCR, + "last %" PRId64 ", time end %" PRId64, + pcr.pcr_last, + im->im_pcr_end); } } if (iptv_input_pause_check(im)) { @@ -679,10 +634,8 @@ iptv_input_recv_packets ( iptv_mux_t *im, ssize_t len ) return 0; } -int -iptv_input_fd_started ( iptv_input_t *mi, iptv_mux_t *im ) -{ - iptv_thread_pool_t *tpool = mi->mi_tpool; +int iptv_input_fd_started(iptv_input_t* mi, iptv_mux_t* im) { + iptv_thread_pool_t* tpool = mi->mi_tpool; /* Setup poll */ if (im->mm_iptv_fd > 0) { @@ -708,54 +661,45 @@ iptv_input_fd_started ( iptv_input_t *mi, iptv_mux_t *im ) return 0; } -void -iptv_input_mux_started ( iptv_input_t *mi, iptv_mux_t *im, int reset ) -{ +void iptv_input_mux_started(iptv_input_t* mi, iptv_mux_t* im, int reset) { /* Allocate input buffer */ if (reset) sbuf_reset_and_alloc(&im->mm_iptv_buffer, IPTV_BUF_SIZE); - im->im_pcr = PTS_UNSET; + im->im_pcr = PTS_UNSET; im->im_pcr_pid = MPEGTS_PID_NONE; if (iptv_input_fd_started(mi, im)) return; /* Install table handlers */ - mpegts_mux_t *mm = (mpegts_mux_t*)im; + mpegts_mux_t* mm = (mpegts_mux_t*)im; if (mm->mm_active) - psi_tables_install((mpegts_input_t *)mi, mm, - im->mm_iptv_atsc ? DVB_SYS_ATSC_ALL : DVB_SYS_DVBT); + psi_tables_install((mpegts_input_t*)mi, mm, im->mm_iptv_atsc ? DVB_SYS_ATSC_ALL : DVB_SYS_DVBT); } -static int -iptv_network_bouquet_source (mpegts_network_t *mn, char *source, size_t len) -{ - iptv_network_t *in = (iptv_network_t *)mn; - char ubuf[UUID_HEX_SIZE]; +static int iptv_network_bouquet_source(mpegts_network_t* mn, char* source, size_t len) { + iptv_network_t* in = (iptv_network_t*)mn; + char ubuf[UUID_HEX_SIZE]; snprintf(source, len, "iptv-network://%s", idnode_uuid_as_str(&in->mn_id, ubuf)); return 0; } -static int -iptv_network_bouquet_comment (mpegts_network_t *mn, char *comment, size_t len) -{ - iptv_network_t *in = (iptv_network_t *)mn; +static int iptv_network_bouquet_comment(mpegts_network_t* mn, char* comment, size_t len) { + iptv_network_t* in = (iptv_network_t*)mn; if (in->in_url == NULL || in->in_url[0] == '\0') return -1; snprintf(comment, len, "%s", in->in_url); return 0; } -static void -iptv_network_delete ( mpegts_network_t *mn, int delconf ) -{ - iptv_network_t *in = (iptv_network_t*)mn; - char *url = in->in_url; - char *sane_url = in->in_url_sane; - char *icon_url = in->in_icon_url; - char *icon_url_sane = in->in_icon_url_sane; - char ubuf[UUID_HEX_SIZE]; +static void iptv_network_delete(mpegts_network_t* mn, int delconf) { + iptv_network_t* in = (iptv_network_t*)mn; + char* url = in->in_url; + char* sane_url = in->in_url_sane; + char* icon_url = in->in_icon_url; + char* icon_url_sane = in->in_icon_url_sane; + char ubuf[UUID_HEX_SIZE]; idnode_save_check(&mn->mn_id, delconf); @@ -764,8 +708,7 @@ iptv_network_delete ( mpegts_network_t *mn, int delconf ) /* Remove config */ if (delconf) - hts_settings_remove("input/iptv/networks/%s", - idnode_uuid_as_str(&in->mn_id, ubuf)); + hts_settings_remove("input/iptv/networks/%s", idnode_uuid_as_str(&in->mn_id, ubuf)); /* delete */ free(in->in_remove_args); @@ -783,16 +726,12 @@ iptv_network_delete ( mpegts_network_t *mn, int delconf ) * IPTV network * *************************************************************************/ -static void -iptv_network_class_delete ( idnode_t *in ) -{ - return iptv_network_delete((mpegts_network_t *)in, 1); +static void iptv_network_class_delete(idnode_t* in) { + return iptv_network_delete((mpegts_network_t*)in, 1); } -static int -iptv_network_class_icon_url_set( void *in, const void *v ) -{ - iptv_network_t *mn = in; +static int iptv_network_class_icon_url_set(void* in, const void* v) { + iptv_network_t* mn = in; return iptv_url_set(&mn->in_icon_url, &mn->in_icon_url_sane, v, 1, 0); } @@ -800,289 +739,236 @@ PROP_DOC(priority) PROP_DOC(streaming_priority) extern const idclass_t mpegts_network_class; -const idclass_t iptv_network_class = { - .ic_super = &mpegts_network_class, - .ic_class = "iptv_network", - .ic_caption = N_("IPTV Network"), - .ic_delete = iptv_network_class_delete, - .ic_properties = (const property_t[]){ +const idclass_t iptv_network_class = {.ic_super = &mpegts_network_class, + .ic_class = "iptv_network", + .ic_caption = N_("IPTV Network"), + .ic_delete = iptv_network_class_delete, + .ic_properties = (const property_t[]){ #if ENABLE_LIBAV - { - .type = PT_BOOL, - .id = "use_libav", - .name = N_("Use A/V library"), - .desc = N_("The input stream is remuxed with A/V library (libav or" - " or ffmpeg) to the MPEG-TS format which is accepted by" - " Tvheadend."), - .off = offsetof(iptv_network_t, in_libav), - .opts = PO_ADVANCED - }, + {.type = PT_BOOL, + .id = "use_libav", + .name = N_("Use A/V library"), + .desc = N_("The input stream is remuxed with A/V library (libav or" + " or ffmpeg) to the MPEG-TS format which is accepted by" + " Tvheadend."), + .off = offsetof(iptv_network_t, in_libav), + .opts = PO_ADVANCED}, #endif - { - .type = PT_BOOL, - .id = "scan_create", - .name = N_("Scan after creation"), - .desc = N_("After creating the network scan it for services."), - .off = offsetof(iptv_network_t, in_scan_create), - .def.i = 1, - .opts = PO_ADVANCED - }, - { - .type = PT_U16, - .id = "service_sid", - .name = N_("Service ID"), - .desc = N_("The network's service ID"), - .off = offsetof(iptv_network_t, in_service_id), - .def.i = 0, - .opts = PO_EXPERT - }, - { - .type = PT_INT, - .id = "priority", - .name = N_("Priority"), - .desc = N_("The network's priority. The network with the " - "highest priority value will be used out of " - "preference if available. See Help for details."), - .off = offsetof(iptv_network_t, in_priority), - .doc = prop_doc_priority, - .def.i = 1, - .opts = PO_ADVANCED - }, - { - .type = PT_INT, - .id = "spriority", - .name = N_("Streaming priority"), - .desc = N_("When streaming a service (via http or htsp) " - "Tvheadend will use the network with the highest " - "streaming priority set here. See Help for details."), - .doc = prop_doc_streaming_priority, - .off = offsetof(iptv_network_t, in_streaming_priority), - .def.i = 1, - .opts = PO_ADVANCED - }, - { - .type = PT_U32, - .id = "max_streams", - .name = N_("Maximum # input streams"), - .desc = N_("The maximum number of input streams allowed " - "on this network."), - .off = offsetof(iptv_network_t, in_max_streams), - .def.i = 0, - }, - { - .type = PT_U32, - .id = "max_bandwidth", - .name = N_("Maximum bandwidth (Kbps)"), - .desc = N_("Maximum input bandwidth."), - .off = offsetof(iptv_network_t, in_max_bandwidth), - .def.i = 0, - }, - { - .type = PT_U32, - .id = "max_timeout", - .name = N_("Maximum timeout (seconds)"), - .desc = N_("Maximum time to wait (in seconds) for a stream " - "before a timeout."), - .off = offsetof(iptv_network_t, in_max_timeout), - .def.i = 15, - .opts = PO_ADVANCED - }, - { - .type = PT_STR, - .id = "icon_url", - .name = N_("Icon base URL"), - .desc = N_("Icon base URL."), - .off = offsetof(iptv_network_t, in_icon_url), - .set = iptv_network_class_icon_url_set, - .opts = PO_MULTILINE | PO_ADVANCED - }, - { - .type = PT_BOOL, - .id = "remove_scrambled", - .name = N_("Remove scrambled bits"), - .desc = N_("The scrambled bits in MPEG-TS packets are always cleared. " - "It is a workaround for the special streams which are " - "descrambled, but these bits are not touched."), - .off = offsetof(iptv_network_t, in_remove_scrambled_bits), - .def.i = 1, - .opts = PO_EXPERT, - }, - { - .id = "autodiscovery", - .type = PT_NONE, - }, - {} - } -}; - -static int -iptv_auto_network_class_url_set( void *in, const void *v ) -{ - iptv_network_t *mn = in; + {.type = PT_BOOL, + .id = "scan_create", + .name = N_("Scan after creation"), + .desc = N_("After creating the network scan it for services."), + .off = offsetof(iptv_network_t, in_scan_create), + .def.i = 1, + .opts = PO_ADVANCED}, + {.type = PT_U16, + .id = "service_sid", + .name = N_("Service ID"), + .desc = N_("The network's service ID"), + .off = offsetof(iptv_network_t, in_service_id), + .def.i = 0, + .opts = PO_EXPERT}, + {.type = PT_INT, + .id = "priority", + .name = N_("Priority"), + .desc = N_("The network's priority. The network with the " + "highest priority value will be used out of " + "preference if available. See Help for details."), + .off = offsetof(iptv_network_t, in_priority), + .doc = prop_doc_priority, + .def.i = 1, + .opts = PO_ADVANCED}, + {.type = PT_INT, + .id = "spriority", + .name = N_("Streaming priority"), + .desc = N_("When streaming a service (via http or htsp) " + "Tvheadend will use the network with the highest " + "streaming priority set here. See Help for details."), + .doc = prop_doc_streaming_priority, + .off = offsetof(iptv_network_t, in_streaming_priority), + .def.i = 1, + .opts = PO_ADVANCED}, + { + .type = PT_U32, + .id = "max_streams", + .name = N_("Maximum # input streams"), + .desc = N_("The maximum number of input streams allowed " + "on this network."), + .off = offsetof(iptv_network_t, in_max_streams), + .def.i = 0, + }, + { + .type = PT_U32, + .id = "max_bandwidth", + .name = N_("Maximum bandwidth (Kbps)"), + .desc = N_("Maximum input bandwidth."), + .off = offsetof(iptv_network_t, in_max_bandwidth), + .def.i = 0, + }, + {.type = PT_U32, + .id = "max_timeout", + .name = N_("Maximum timeout (seconds)"), + .desc = N_("Maximum time to wait (in seconds) for a stream " + "before a timeout."), + .off = offsetof(iptv_network_t, in_max_timeout), + .def.i = 15, + .opts = PO_ADVANCED}, + {.type = PT_STR, + .id = "icon_url", + .name = N_("Icon base URL"), + .desc = N_("Icon base URL."), + .off = offsetof(iptv_network_t, in_icon_url), + .set = iptv_network_class_icon_url_set, + .opts = PO_MULTILINE | PO_ADVANCED}, + { + .type = PT_BOOL, + .id = "remove_scrambled", + .name = N_("Remove scrambled bits"), + .desc = N_("The scrambled bits in MPEG-TS packets are always cleared. " + "It is a workaround for the special streams which are " + "descrambled, but these bits are not touched."), + .off = offsetof(iptv_network_t, in_remove_scrambled_bits), + .def.i = 1, + .opts = PO_EXPERT, + }, + { + .id = "autodiscovery", + .type = PT_NONE, + }, + {}}}; + +static int iptv_auto_network_class_url_set(void* in, const void* v) { + iptv_network_t* mn = in; return iptv_url_set(&mn->in_url, &mn->in_url_sane, v, 1, 1); } -static void -iptv_auto_network_class_notify_url( void *in, const char *lang ) -{ +static void iptv_auto_network_class_notify_url(void* in, const char* lang) { iptv_auto_network_trigger(in); } -static htsmsg_t * -iptv_auto_network_class_charset_list(void *o, const char *lang) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "intlconv/charsets"); +static htsmsg_t* iptv_auto_network_class_charset_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "intlconv/charsets"); return m; } PROP_DOC(ignore_path) -const idclass_t iptv_auto_network_class = { - .ic_super = &iptv_network_class, - .ic_class = "iptv_auto_network", - .ic_caption = N_("IPTV Automatic Network"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "url", - .name = N_("URL"), - .desc = N_("The URL to the playlist."), - .off = offsetof(iptv_network_t, in_url), - .set = iptv_auto_network_class_url_set, - .notify = iptv_auto_network_class_notify_url, - .opts = PO_MULTILINE - }, - { - .type = PT_STR, - .id = "ctx_charset", - .name = N_("Content character set"), - .desc = N_("The playlist's character set."), - .off = offsetof(iptv_network_t, in_ctx_charset), - .list = iptv_auto_network_class_charset_list, - .notify = iptv_auto_network_class_notify_url, - .opts = PO_ADVANCED - }, - { - .type = PT_S64, - .intextra = CHANNEL_SPLIT, - .id = "channel_number", - .name = N_("Channel numbers from"), - .desc = N_("Lowest starting channel number (when mapping). "), - .off = offsetof(iptv_network_t, in_channel_number), - }, - { - .type = PT_U32, - .id = "refetch_period", - .name = N_("Re-fetch period (mins)"), - .desc = N_("Time (in minutes) to re-fetch the playlist."), - .off = offsetof(iptv_network_t, in_refetch_period), - .def.i = 60, - .opts = PO_ADVANCED - }, - { - .type = PT_BOOL, - .id = "ssl_peer_verify", - .name = N_("SSL verify peer"), - .desc = N_("Verify the peer's SSL."), - .off = offsetof(iptv_network_t, in_ssl_peer_verify), - .opts = PO_EXPERT - }, - { - .type = PT_BOOL, - .id = "tsid_zero", - .name = N_("Accept zero value for TSID"), - .desc = N_("Accept transport ID if zero."), - .off = offsetof(iptv_network_t, in_tsid_accept_zero_value), - }, - { - .type = PT_STR, - .id = "remove_args", - .name = N_("Remove HTTP arguments"), - .desc = N_("Argument names to remove from the query " - "string in the URL."), - .off = offsetof(iptv_network_t, in_remove_args), - .def.s = "ticket", - .opts = PO_EXPERT - }, - { - .type = PT_STR, - .id = "ignore_args", - .name = N_("Ignore HTTP arguments"), - .desc = N_("Argument names to remove from the query " - "string in the URL when the identical " - "source is compared."), - .off = offsetof(iptv_network_t, in_ignore_args), - .def.s = "", - .opts = PO_EXPERT - }, - { - .type = PT_INT, - .id = "ignore_path", - .name = N_("Ignore path components"), - .desc = N_("Ignore last components in path. The defined count " - "of last path components separated by / are removed " - "when the identical source is compared - see Help for a detailed explanation."), - .doc = prop_doc_ignore_path, - .off = offsetof(iptv_network_t, in_ignore_path), - .def.i = 0, - .opts = PO_EXPERT - }, - {} - } -}; - -static mpegts_mux_t * -iptv_network_create_mux2 - ( mpegts_network_t *mn, htsmsg_t *conf ) -{ - iptv_mux_t *im = iptv_mux_create0((iptv_network_t*)mn, NULL, conf); - return mpegts_mux_post_create((mpegts_mux_t *)im); +const idclass_t iptv_auto_network_class = {.ic_super = &iptv_network_class, + .ic_class = "iptv_auto_network", + .ic_caption = N_("IPTV Automatic Network"), + .ic_properties = (const property_t[]){{.type = PT_STR, + .id = "url", + .name = N_("URL"), + .desc = N_("The URL to the playlist."), + .off = offsetof(iptv_network_t, in_url), + .set = iptv_auto_network_class_url_set, + .notify = iptv_auto_network_class_notify_url, + .opts = PO_MULTILINE}, + {.type = PT_STR, + .id = "ctx_charset", + .name = N_("Content character set"), + .desc = N_("The playlist's character set."), + .off = offsetof(iptv_network_t, in_ctx_charset), + .list = iptv_auto_network_class_charset_list, + .notify = iptv_auto_network_class_notify_url, + .opts = PO_ADVANCED}, + { + .type = PT_S64, + .intextra = CHANNEL_SPLIT, + .id = "channel_number", + .name = N_("Channel numbers from"), + .desc = N_("Lowest starting channel number (when mapping). "), + .off = offsetof(iptv_network_t, in_channel_number), + }, + {.type = PT_U32, + .id = "refetch_period", + .name = N_("Re-fetch period (mins)"), + .desc = N_("Time (in minutes) to re-fetch the playlist."), + .off = offsetof(iptv_network_t, in_refetch_period), + .def.i = 60, + .opts = PO_ADVANCED}, + {.type = PT_BOOL, + .id = "ssl_peer_verify", + .name = N_("SSL verify peer"), + .desc = N_("Verify the peer's SSL."), + .off = offsetof(iptv_network_t, in_ssl_peer_verify), + .opts = PO_EXPERT}, + { + .type = PT_BOOL, + .id = "tsid_zero", + .name = N_("Accept zero value for TSID"), + .desc = N_("Accept transport ID if zero."), + .off = offsetof(iptv_network_t, in_tsid_accept_zero_value), + }, + {.type = PT_STR, + .id = "remove_args", + .name = N_("Remove HTTP arguments"), + .desc = N_("Argument names to remove from the query " + "string in the URL."), + .off = offsetof(iptv_network_t, in_remove_args), + .def.s = "ticket", + .opts = PO_EXPERT}, + {.type = PT_STR, + .id = "ignore_args", + .name = N_("Ignore HTTP arguments"), + .desc = N_("Argument names to remove from the query " + "string in the URL when the identical " + "source is compared."), + .off = offsetof(iptv_network_t, in_ignore_args), + .def.s = "", + .opts = PO_EXPERT}, + {.type = PT_INT, + .id = "ignore_path", + .name = N_("Ignore path components"), + .desc = + N_("Ignore last components in path. The defined count " + "of last path components separated by / are removed " + "when the identical source is compared - see Help for a detailed explanation."), + .doc = prop_doc_ignore_path, + .off = offsetof(iptv_network_t, in_ignore_path), + .def.i = 0, + .opts = PO_EXPERT}, + {}}}; + +static mpegts_mux_t* iptv_network_create_mux2(mpegts_network_t* mn, htsmsg_t* conf) { + iptv_mux_t* im = iptv_mux_create0((iptv_network_t*)mn, NULL, conf); + return mpegts_mux_post_create((mpegts_mux_t*)im); } -static void -iptv_network_auto_scan ( mpegts_network_t *mn ) -{ - iptv_auto_network_trigger((iptv_network_t *)mn); +static void iptv_network_auto_scan(mpegts_network_t* mn) { + iptv_auto_network_trigger((iptv_network_t*)mn); mpegts_network_scan(mn); } -static mpegts_service_t * -iptv_network_create_service - ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid ) -{ - return (mpegts_service_t*) - iptv_service_create0((iptv_mux_t*)mm, sid, pmt_pid, NULL, NULL); +static mpegts_service_t* +iptv_network_create_service(mpegts_mux_t* mm, uint16_t sid, uint16_t pmt_pid) { + return (mpegts_service_t*)iptv_service_create0((iptv_mux_t*)mm, sid, pmt_pid, NULL, NULL); } -static const idclass_t * -iptv_network_mux_class ( mpegts_network_t *mm ) -{ +static const idclass_t* iptv_network_mux_class(mpegts_network_t* mm) { extern const idclass_t iptv_mux_class; return &iptv_mux_class; } -static htsmsg_t * -iptv_network_config_save ( mpegts_network_t *mn, char *filename, size_t fsize ) -{ - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* iptv_network_config_save(mpegts_network_t* mn, char* filename, size_t fsize) { + htsmsg_t* c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(&mn->mn_id, c); if (filename) - snprintf(filename, fsize, "input/iptv/networks/%s/config", - idnode_uuid_as_str(&mn->mn_id, ubuf)); + snprintf(filename, + fsize, + "input/iptv/networks/%s/config", + idnode_uuid_as_str(&mn->mn_id, ubuf)); return c; } -iptv_network_t * -iptv_network_create0 - ( const char *uuid, htsmsg_t *conf, const idclass_t *idc ) -{ - iptv_network_t *in = calloc(1, sizeof(*in)); - iptv_mux_t *im; - htsmsg_t *c; - char ubuf[UUID_HEX_SIZE]; +iptv_network_t* iptv_network_create0(const char* uuid, htsmsg_t* conf, const idclass_t* idc) { + iptv_network_t* in = calloc(1, sizeof(*in)); + iptv_mux_t* im; + htsmsg_t* c; + char ubuf[UUID_HEX_SIZE]; /* Init Network */ in->in_scan_create = 1; @@ -1090,58 +976,57 @@ iptv_network_create0 in->in_streaming_priority = 1; if (idc == &iptv_auto_network_class) in->in_remove_args = strdup("ticket"); - if (!mpegts_network_create0((mpegts_network_t *)in, idc, - uuid, NULL, conf)) { + if (!mpegts_network_create0((mpegts_network_t*)in, idc, uuid, NULL, conf)) { free(in->in_remove_args); free(in); return NULL; } - in->mn_bouquet_source = iptv_network_bouquet_source; - in->mn_bouquet_comment= iptv_network_bouquet_comment; - in->mn_delete = iptv_network_delete; - in->mn_create_service = iptv_network_create_service; - in->mn_mux_class = iptv_network_mux_class; - in->mn_mux_create2 = iptv_network_create_mux2; - in->mn_config_save = iptv_network_config_save; + in->mn_bouquet_source = iptv_network_bouquet_source; + in->mn_bouquet_comment = iptv_network_bouquet_comment; + in->mn_delete = iptv_network_delete; + in->mn_create_service = iptv_network_create_service; + in->mn_mux_class = iptv_network_mux_class; + in->mn_mux_create2 = iptv_network_create_mux2; + in->mn_config_save = iptv_network_config_save; if (idc == &iptv_auto_network_class) - in->mn_scan = iptv_network_auto_scan; - + in->mn_scan = iptv_network_auto_scan; + /* Defaults */ - in->mn_autodiscovery = 0; + in->mn_autodiscovery = 0; if (!conf) { in->mn_skipinitscan = 1; } /* Load muxes */ - if ((c = hts_settings_load_r(1, "input/iptv/networks/%s/muxes", - idnode_uuid_as_str(&in->mn_id, ubuf)))) { - htsmsg_field_t *f; - htsmsg_t *e; + if ((c = hts_settings_load_r(1, + "input/iptv/networks/%s/muxes", + idnode_uuid_as_str(&in->mn_id, ubuf)))) { + htsmsg_field_t* f; + htsmsg_t* e; HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_get_map_by_field(f))) continue; - if (!(e = htsmsg_get_map(e, "config"))) continue; + if (!(e = htsmsg_get_map_by_field(f))) + continue; + if (!(e = htsmsg_get_map(e, "config"))) + continue; im = iptv_mux_create0(in, htsmsg_field_name(f), e); - mpegts_mux_post_create((mpegts_mux_t *)im); + mpegts_mux_post_create((mpegts_mux_t*)im); } htsmsg_destroy(c); } if (idc == &iptv_auto_network_class) iptv_auto_network_init(in); - + return in; } -static mpegts_network_t * -iptv_network_builder - ( const idclass_t *idc, htsmsg_t *conf ) -{ - mpegts_network_t *mn; - iptv_thread_pool_t *pool; +static mpegts_network_t* iptv_network_builder(const idclass_t* idc, htsmsg_t* conf) { + mpegts_network_t* mn; + iptv_thread_pool_t* pool; - mn = (mpegts_network_t *)iptv_network_create0(NULL, conf, idc); - TAILQ_FOREACH(pool, &iptv_tpool, link) - mpegts_input_add_network((mpegts_input_t *)pool->input, mn); + mn = (mpegts_network_t*)iptv_network_create0(NULL, conf, idc); + TAILQ_FOREACH (pool, &iptv_tpool, link) + mpegts_input_add_network((mpegts_input_t*)pool->input, mn); return mn; } @@ -1149,28 +1034,26 @@ iptv_network_builder * IPTV initialise * *************************************************************************/ -static void -iptv_network_init ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; +static void iptv_network_init(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; /* Register muxes */ idclass_register(&iptv_mux_class); /* Register builders */ - mpegts_network_register_builder(&iptv_network_class, - iptv_network_builder); - mpegts_network_register_builder(&iptv_auto_network_class, - iptv_network_builder); + mpegts_network_register_builder(&iptv_network_class, iptv_network_builder); + mpegts_network_register_builder(&iptv_auto_network_class, iptv_network_builder); /* Load settings */ if (!(c = hts_settings_load_r(1, "input/iptv/networks"))) return; HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_get_map_by_field(f))) continue; - if (!(e = htsmsg_get_map(e, "config"))) continue; + if (!(e = htsmsg_get_map_by_field(f))) + continue; + if (!(e = htsmsg_get_map(e, "config"))) + continue; if (htsmsg_get_str(e, "url")) iptv_network_create0(htsmsg_field_name(f), e, &iptv_auto_network_class); else @@ -1179,76 +1062,65 @@ iptv_network_init ( void ) htsmsg_destroy(c); } -static mpegts_network_t * -iptv_input_wizard_network ( iptv_input_t *lfe ) -{ - return (mpegts_network_t *)LIST_FIRST(&lfe->mi_networks); +static mpegts_network_t* iptv_input_wizard_network(iptv_input_t* lfe) { + return (mpegts_network_t*)LIST_FIRST(&lfe->mi_networks); } -static htsmsg_t * -iptv_input_wizard_get( tvh_input_t *ti, const char *lang ) -{ - iptv_input_t *mi = (iptv_input_t*)ti; - mpegts_network_t *mn; - const idclass_t *idc = NULL; +static htsmsg_t* iptv_input_wizard_get(tvh_input_t* ti, const char* lang) { + iptv_input_t* mi = (iptv_input_t*)ti; + mpegts_network_t* mn; + const idclass_t* idc = NULL; mn = iptv_input_wizard_network(mi); if (mn == NULL || (mn && mn->mn_wizard)) idc = &iptv_auto_network_class; - return mpegts_network_wizard_get((mpegts_input_t *)mi, idc, mn, lang); + return mpegts_network_wizard_get((mpegts_input_t*)mi, idc, mn, lang); } -static void -iptv_input_wizard_set( tvh_input_t *ti, htsmsg_t *conf, const char *lang ) -{ - iptv_input_t *mi = (iptv_input_t*)ti; - const char *ntype = htsmsg_get_str(conf, "mpegts_network_type"); - mpegts_network_t *mn; +static void iptv_input_wizard_set(tvh_input_t* ti, htsmsg_t* conf, const char* lang) { + iptv_input_t* mi = (iptv_input_t*)ti; + const char* ntype = htsmsg_get_str(conf, "mpegts_network_type"); + mpegts_network_t* mn; mn = iptv_input_wizard_network(mi); if ((mn == NULL || mn->mn_wizard)) mpegts_network_wizard_create(ntype, NULL, lang); } -static iptv_input_t * -iptv_create_input ( void *tpool ) -{ - iptv_input_t *input = calloc(1, sizeof(iptv_input_t)); - mpegts_network_t *mn; +static iptv_input_t* iptv_create_input(void* tpool) { + iptv_input_t* input = calloc(1, sizeof(iptv_input_t)); + mpegts_network_t* mn; /* Init Input */ - mpegts_input_create0((mpegts_input_t*)input, - &iptv_input_class, NULL, NULL); - input->ti_wizard_get = iptv_input_wizard_get; - input->ti_wizard_set = iptv_input_wizard_set; - input->mi_warm_mux = iptv_input_warm_mux; - input->mi_start_mux = iptv_input_start_mux; - input->mi_stop_mux = iptv_input_stop_mux; - input->mi_is_enabled = iptv_input_is_enabled; - input->mi_get_weight = iptv_input_get_weight; - input->mi_get_grace = iptv_input_get_grace; - input->mi_get_priority = iptv_input_get_priority; - input->mi_display_name = iptv_input_display_name; - input->mi_enabled = 1; - - input->mi_tpool = tpool; + mpegts_input_create0((mpegts_input_t*)input, &iptv_input_class, NULL, NULL); + input->ti_wizard_get = iptv_input_wizard_get; + input->ti_wizard_set = iptv_input_wizard_set; + input->mi_warm_mux = iptv_input_warm_mux; + input->mi_start_mux = iptv_input_start_mux; + input->mi_stop_mux = iptv_input_stop_mux; + input->mi_is_enabled = iptv_input_is_enabled; + input->mi_get_weight = iptv_input_get_weight; + input->mi_get_grace = iptv_input_get_grace; + input->mi_get_priority = iptv_input_get_priority; + input->mi_display_name = iptv_input_display_name; + input->mi_enabled = 1; + + input->mi_tpool = tpool; /* Link */ - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) if (idnode_is_instance(&mn->mn_id, &iptv_network_class)) - mpegts_input_add_network((mpegts_input_t *)input, mn); + mpegts_input_add_network((mpegts_input_t*)input, mn); return input; } -static void -iptv_input_thread_manage(int count, int force) -{ - iptv_thread_pool_t *pool; +static void iptv_input_thread_manage(int count, int force) { + iptv_thread_pool_t* pool; while (iptv_tpool_count < count) { - pool = calloc(1, sizeof(*pool)); - pool->poll = tvhpoll_create(10); + pool = calloc(1, sizeof(*pool)); + pool->poll = tvhpoll_create(10); pool->input = iptv_create_input(pool); tvh_pipe(O_NONBLOCK, &pool->pipe); tvhpoll_add1(pool->poll, pool->pipe.rd, TVHPOLL_IN, &pool->pipe); @@ -1257,13 +1129,13 @@ iptv_input_thread_manage(int count, int force) iptv_tpool_count++; } while (iptv_tpool_count > count) { - TAILQ_FOREACH(pool, &iptv_tpool, link) + TAILQ_FOREACH (pool, &iptv_tpool, link) if (pool->streams == 0 || force) { tvh_write(pool->pipe.wr, "q", 1); pthread_join(pool->thread, NULL); TAILQ_REMOVE(&iptv_tpool, pool, link); mpegts_input_stop_all((mpegts_input_t*)pool->input); - mpegts_input_delete((mpegts_input_t *)pool->input, 0); + mpegts_input_delete((mpegts_input_t*)pool->input, 0); tvhpoll_rem1(pool->poll, pool->pipe.rd); tvhpoll_destroy(pool->poll); free(pool); @@ -1275,14 +1147,11 @@ iptv_input_thread_manage(int count, int force) } } -static void -iptv_input_thread_manage_cb(void *aux) -{ +static void iptv_input_thread_manage_cb(void* aux) { iptv_input_thread_manage(iptv_tpool_safe_count(), 0); } -void iptv_init ( void ) -{ +void iptv_init(void) { TAILQ_INIT(&iptv_tpool); tvh_mutex_init(&iptv_lock, NULL); @@ -1304,8 +1173,7 @@ void iptv_init ( void ) tvhinfo(LS_IPTV, "Using %d input thread(s)", iptv_tpool_count); } -void iptv_done ( void ) -{ +void iptv_done(void) { tvh_mutex_lock(&global_lock); iptv_input_thread_manage(0, 1); assert(TAILQ_EMPTY(&iptv_tpool)); diff --git a/src/input/mpegts/iptv/iptv_auto.c b/src/input/mpegts/iptv/iptv_auto.c index 5d7f1f45c..e0e793b0f 100644 --- a/src/input/mpegts/iptv/iptv_auto.c +++ b/src/input/mpegts/iptv/iptv_auto.c @@ -29,7 +29,7 @@ #include typedef struct auto_private { - iptv_network_t *in_network; + iptv_network_t* in_network; download_t in_download; mtimer_t in_auto_timer; } auto_private_t; @@ -37,24 +37,22 @@ typedef struct auto_private { /* * */ -static int _epgcfg_from_str(const char *str, char *manual, size_t manual_len) -{ - static struct strtab cfgs[] = { - { "0", MM_EPG_DISABLE }, - { "none", MM_EPG_DISABLE }, - { "disable", MM_EPG_DISABLE }, - { "off", MM_EPG_DISABLE }, - { "1", MM_EPG_ENABLE }, - { "all", MM_EPG_ENABLE }, - { "enable", MM_EPG_ENABLE }, - { "on", MM_EPG_ENABLE }, - { "force", MM_EPG_FORCE }, - { NULL } - }; - int r = str ? str2val(str, cfgs) : -1; - if (manual) *manual = '\0'; +static int _epgcfg_from_str(const char* str, char* manual, size_t manual_len) { + static struct strtab cfgs[] = {{"0", MM_EPG_DISABLE}, + {"none", MM_EPG_DISABLE}, + {"disable", MM_EPG_DISABLE}, + {"off", MM_EPG_DISABLE}, + {"1", MM_EPG_ENABLE}, + {"all", MM_EPG_ENABLE}, + {"enable", MM_EPG_ENABLE}, + {"on", MM_EPG_ENABLE}, + {"force", MM_EPG_FORCE}, + {NULL}}; + int r = str ? str2val(str, cfgs) : -1; + if (manual) + *manual = '\0'; if (r < 0) { - const char *s = epggrab_ota_check_module_id(str); + const char* s = epggrab_ota_check_module_id(str); if (s) { r = MM_EPG_MANUAL; if (manual) @@ -67,48 +65,45 @@ static int _epgcfg_from_str(const char *str, char *manual, size_t manual_len) /* * */ -static void -iptv_auto_network_process_m3u_item(iptv_network_t *in, - const char *last_url, - const http_arg_list_t *remove_args, - const http_arg_list_t *ignore_args, - int ignore_path, - int64_t chnum, htsmsg_t *item, - int *total, int *count) -{ - htsmsg_t *conf; - htsmsg_field_t *f; - mpegts_mux_t *mm; - iptv_mux_t *im; - url_t u, u2; - int change, epgcfg, muxprio, smuxprio; +static void iptv_auto_network_process_m3u_item(iptv_network_t* in, + const char* last_url, + const http_arg_list_t* remove_args, + const http_arg_list_t* ignore_args, + int ignore_path, + int64_t chnum, + htsmsg_t* item, + int* total, + int* count) { + htsmsg_t* conf; + htsmsg_field_t* f; + mpegts_mux_t* mm; + iptv_mux_t* im; + url_t u, u2; + int change, epgcfg, muxprio, smuxprio; http_arg_list_t args; - http_arg_t *ra1, *ra2, *ra2_next; - size_t l; - int64_t chnum2, vlcprog; - const char *url, *url2, *name, *logo, *epgid, *tags; - char *s; - char custom[512], name2[128], buf[32], *moduleid, *n; + http_arg_t * ra1, *ra2, *ra2_next; + size_t l; + int64_t chnum2, vlcprog; + const char * url, *url2, *name, *logo, *epgid, *tags; + char* s; + char custom[512], name2[128], buf[32], *moduleid, *n; url = htsmsg_get_str(item, "m3u-url"); if (url == NULL || - (strncmp(url, "file://", 7) && - strncmp(url, "pipe://", 7) && - strncmp(url, "http://", 7) && - strncmp(url, "https://", 8) && - strncmp(url, "rtsp://", 7) && - strncmp(url, "rtsps://", 8) && - strncmp(url, "udp://", 6) && - strncmp(url, "rtp://", 6))) + (strncmp(url, "file://", 7) && strncmp(url, "pipe://", 7) && strncmp(url, "http://", 7) && + strncmp(url, "https://", 8) && strncmp(url, "rtsp://", 7) && + strncmp(url, "rtsps://", 8) && strncmp(url, "udp://", 6) && strncmp(url, "rtp://", 6))) return; epgid = htsmsg_get_str(item, "tvh-chnum"); - if (!epgid) epgid = htsmsg_get_str(item, "tvg-chno"); - if (!epgid) epgid = htsmsg_get_str(item, "channel-number"); + if (!epgid) + epgid = htsmsg_get_str(item, "tvg-chno"); + if (!epgid) + epgid = htsmsg_get_str(item, "channel-number"); chnum2 = epgid ? channel_get_number_from_str(epgid) : 0; - muxprio = htsmsg_get_s32_or_default(item, "tvh-prio", -1); + muxprio = htsmsg_get_s32_or_default(item, "tvh-prio", -1); smuxprio = htsmsg_get_s32_or_default(item, "tvh-sprio", -1); if (chnum2 > 0) { @@ -128,11 +123,12 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in, if (logo == NULL) logo = htsmsg_get_str(item, "logo"); - epgid = htsmsg_get_str(item, "tvg-id"); + epgid = htsmsg_get_str(item, "tvg-id"); moduleid = alloca(64); - epgcfg = _epgcfg_from_str(htsmsg_get_str(item, "tvh-epg"), moduleid, 64); - tags = htsmsg_get_str(item, "tvh-tags"); - if (!tags) tags = htsmsg_get_str(item, "group-title"); + epgcfg = _epgcfg_from_str(htsmsg_get_str(item, "tvh-epg"), moduleid, 64); + tags = htsmsg_get_str(item, "tvh-tags"); + if (!tags) + tags = htsmsg_get_str(item, "group-title"); if (tags) { tags = n = tvh_strdupa(tags); while (*n) { @@ -144,20 +140,19 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in, urlinit(&u); urlinit(&u2); - url2 = url; + url2 = url; custom[0] = '\0'; if (strncmp(url, "pipe://", 7) == 0) goto skip_url; - if (strncmp(url, "http://", 7) == 0 || - strncmp(url, "https://", 8) == 0) { + if (strncmp(url, "http://", 7) == 0 || strncmp(url, "https://", 8) == 0) { conf = htsmsg_get_list(item, "m3u-http-headers"); if (conf) { l = 0; HTSMSG_FOREACH(f, conf) - if ((n = (char *)htsmsg_field_get_str(f)) != NULL) - tvh_strlcatf(custom, sizeof(custom), l, "%s\n", n); + if ((n = (char*)htsmsg_field_get_str(f)) != NULL) + tvh_strlcatf(custom, sizeof(custom), l, "%s\n", n); } } @@ -170,7 +165,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in, if (!http_args_empty(remove_args)) { http_arg_init(&args); http_parse_args(&args, u.query); - TAILQ_FOREACH(ra1, remove_args, link) + TAILQ_FOREACH (ra1, remove_args, link) for (ra2 = TAILQ_FIRST(&args); ra2; ra2 = ra2_next) { ra2_next = TAILQ_NEXT(ra2, link); if (strcmp(ra1->key, ra2->key) == 0) @@ -189,7 +184,7 @@ iptv_auto_network_process_m3u_item(iptv_network_t *in, if (!http_args_empty(ignore_args)) { http_arg_init(&args); http_parse_args(&args, u2.query); - TAILQ_FOREACH(ra1, ignore_args, link) + TAILQ_FOREACH (ra1, ignore_args, link) for (ra2 = TAILQ_FIRST(&args); ra2; ra2 = ra2_next) { ra2_next = TAILQ_NEXT(ra2, link); if (strcmp(ra1->key, ra2->key) == 0) @@ -215,67 +210,67 @@ skip_url: if (name[0]) snprintf(n = name2, sizeof(name2), "%s - %s", last_url, name); else - n = (char *)last_url; + n = (char*)last_url; } else { - n = (char *)name; + n = (char*)name; } - LIST_FOREACH(mm, &in->mn_muxes, mm_network_link) { - im = (iptv_mux_t *)mm; + LIST_FOREACH (mm, &in->mn_muxes, mm_network_link) { + im = (iptv_mux_t*)mm; if (strcmp(im->mm_iptv_url_cmpid ?: (im->mm_iptv_url ?: ""), url2) == 0) { im->im_delete_flag = 0; - change = 0; + change = 0; if (strcmp(im->mm_iptv_svcname ?: "", name)) { free(im->mm_iptv_svcname); im->mm_iptv_svcname = strdup(name); - change = 1; + change = 1; } if (im->mm_iptv_chnum != chnum) { - mpegts_network_bouquet_trigger((mpegts_network_t *)in, 0); /* propagate LCN change */ + mpegts_network_bouquet_trigger((mpegts_network_t*)in, 0); /* propagate LCN change */ im->mm_iptv_chnum = chnum; - change = 1; + change = 1; } if ((im->mm_iptv_muxname == NULL || im->mm_iptv_muxname[0] == '\0') && n && *n) { free(im->mm_iptv_muxname); im->mm_iptv_muxname = strdup(n); - change = 1; + change = 1; } if (strcmp(im->mm_iptv_icon ?: "", logo ?: "")) { free(im->mm_iptv_icon); im->mm_iptv_icon = logo ? strdup(logo) : NULL; - change = 1; + change = 1; } if (strcmp(im->mm_iptv_epgid ?: "", epgid ?: "")) { free(im->mm_iptv_epgid); im->mm_iptv_epgid = epgid ? strdup(epgid) : NULL; - change = 1; + change = 1; } if (strcmp(im->mm_iptv_hdr ?: "", custom)) { free(im->mm_iptv_hdr); im->mm_iptv_hdr = strdup(custom); - change = 1; + change = 1; } if (strcmp(im->mm_iptv_tags ?: "", tags ?: "")) { free(im->mm_iptv_tags); im->mm_iptv_tags = tags ? strdup(tags) : NULL; - change = 1; + change = 1; } if (epgcfg >= 0 && im->mm_epg != epgcfg) { im->mm_epg = epgcfg; - change = 1; + change = 1; } if (moduleid[0] && strcmp(im->mm_epg_module_id ?: "", moduleid)) { free(im->mm_epg_module_id); im->mm_epg_module_id = strdup(moduleid); - change = 1; + change = 1; } if (muxprio >= 0 && im->mm_iptv_priority != muxprio) { im->mm_iptv_priority = muxprio; - change = 1; + change = 1; } if (smuxprio >= 0 && im->mm_iptv_streaming_priority != smuxprio) { im->mm_iptv_streaming_priority = smuxprio; - change = 1; + change = 1; } if (change) idnode_notify_changed(&im->mm_id); @@ -284,7 +279,6 @@ skip_url: } } - conf = htsmsg_create_map(); htsmsg_add_str(conf, "iptv_url", url); htsmsg_add_str(conf, "iptv_url_cmpid", url2); @@ -293,8 +287,11 @@ skip_url: if (name) htsmsg_add_str(conf, "iptv_sname", name); if (chnum) { - snprintf(buf, sizeof(buf), "%ld.%ld", - (long)(chnum / CHANNEL_SPLIT), (long)(chnum % CHANNEL_SPLIT)); + snprintf(buf, + sizeof(buf), + "%ld.%ld", + (long)(chnum / CHANNEL_SPLIT), + (long)(chnum % CHANNEL_SPLIT)); htsmsg_add_str(conf, "channel_number", buf); } if (logo) @@ -313,8 +310,7 @@ skip_url: htsmsg_add_str(conf, "epg_module_id", moduleid); if (in->in_tsid_accept_zero_value) htsmsg_add_s32(conf, "tsid_zero", 1); - if (!htsmsg_get_s64(item, "vlc-program", &vlcprog) && - vlcprog > 1 && vlcprog < 8191) + if (!htsmsg_get_s64(item, "vlc-program", &vlcprog) && vlcprog > 1 && vlcprog < 8191) htsmsg_add_s32(conf, "sid_filter", vlcprog); if (muxprio >= 0) htsmsg_add_s32(conf, "priority", muxprio); @@ -322,7 +318,7 @@ skip_url: htsmsg_add_s32(conf, "spriority", smuxprio); im = iptv_mux_create0(in, NULL, conf); - mpegts_mux_post_create((mpegts_mux_t *)im); + mpegts_mux_post_create((mpegts_mux_t*)im); htsmsg_destroy(conf); if (im) { @@ -340,53 +336,62 @@ end: /* * */ -static int -iptv_auto_network_process_m3u(iptv_network_t *in, char *data, - const char *last_url, - const char *host_url, - http_arg_list_t *remove_args, - http_arg_list_t *ignore_args, - int ignore_path, - int64_t chnum) -{ - int total = 0, count = 0; - htsmsg_t *m, *items, *item; - htsmsg_field_t *f; - int ret = 0; - - m = parse_m3u(data, in->in_ctx_charset, host_url); +static int iptv_auto_network_process_m3u(iptv_network_t* in, + char* data, + const char* last_url, + const char* host_url, + http_arg_list_t* remove_args, + http_arg_list_t* ignore_args, + int ignore_path, + int64_t chnum) { + int total = 0, count = 0; + htsmsg_t * m, *items, *item; + htsmsg_field_t* f; + int ret = 0; + + m = parse_m3u(data, in->in_ctx_charset, host_url); items = htsmsg_get_list(m, "items"); if (items) { HTSMSG_FOREACH(f, items) { - if ((item = htsmsg_field_get_map(f)) == NULL) continue; - iptv_auto_network_process_m3u_item(in, last_url, - remove_args, ignore_args, ignore_path, - chnum, item, &total, &count); - + if ((item = htsmsg_field_get_map(f)) == NULL) + continue; + iptv_auto_network_process_m3u_item(in, + last_url, + remove_args, + ignore_args, + ignore_path, + chnum, + item, + &total, + &count); } } htsmsg_destroy(m); if (total == 0) ret = -1; else - tvhinfo(LS_IPTV, "m3u parse: %d new mux(es) in network '%s' (total %d)", - count, in->mn_network_name, total); + tvhinfo(LS_IPTV, + "m3u parse: %d new mux(es) in network '%s' (total %d)", + count, + in->mn_network_name, + total); return ret; } /* * */ -static int -iptv_auto_network_process(void *aux, const char *last_url, - const char *host_url, char *data, size_t len) -{ - auto_private_t *ap = aux; - iptv_network_t *in = ap->in_network; - mpegts_mux_t *mm, *mm2; - int r = -1, count, n, i; +static int iptv_auto_network_process(void* aux, + const char* last_url, + const char* host_url, + char* data, + size_t len) { + auto_private_t* ap = aux; + iptv_network_t* in = ap->in_network; + mpegts_mux_t * mm, *mm2; + int r = -1, count, n, i; http_arg_list_t remove_args, ignore_args; - char *argv[32], *removes, *ignores; + char * argv[32], *removes, *ignores; /* note that we know that data are terminated with '\0' */ @@ -396,7 +401,7 @@ iptv_auto_network_process(void *aux, const char *last_url, http_arg_init(&remove_args); if (in->in_remove_args) { removes = tvh_strdupa(in->in_remove_args); - n = http_tokenize(removes, argv, ARRAY_SIZE(argv), -1); + n = http_tokenize(removes, argv, ARRAY_SIZE(argv), -1); for (i = 0; i < n; i++) http_arg_set(&remove_args, argv[i], NULL); } @@ -404,21 +409,26 @@ iptv_auto_network_process(void *aux, const char *last_url, http_arg_init(&ignore_args); if (in->in_ignore_args) { ignores = tvh_strdupa(in->in_ignore_args); - n = http_tokenize(ignores, argv, ARRAY_SIZE(argv), -1); + n = http_tokenize(ignores, argv, ARRAY_SIZE(argv), -1); for (i = 0; i < n; i++) http_arg_set(&ignore_args, argv[i], NULL); } - LIST_FOREACH(mm, &in->mn_muxes, mm_network_link) - ((iptv_mux_t *)mm)->im_delete_flag = 1; + LIST_FOREACH (mm, &in->mn_muxes, mm_network_link) + ((iptv_mux_t*)mm)->im_delete_flag = 1; - while (*data && *data <= ' ') data++; + while (*data && *data <= ' ') + data++; if (!strncmp(data, "#EXTM3U", 7)) - r = iptv_auto_network_process_m3u(in, data, last_url, host_url, - &remove_args, &ignore_args, - in->in_ignore_path, - in->in_channel_number); + r = iptv_auto_network_process_m3u(in, + data, + last_url, + host_url, + &remove_args, + &ignore_args, + in->in_ignore_path, + in->in_channel_number); http_arg_flush(&remove_args); http_arg_flush(&ignore_args); @@ -427,7 +437,7 @@ iptv_auto_network_process(void *aux, const char *last_url, count = 0; for (mm = LIST_FIRST(&in->mn_muxes); mm; mm = mm2) { mm2 = LIST_NEXT(mm, mm_network_link); - if (((iptv_mux_t *)mm)->im_delete_flag) { + if (((iptv_mux_t*)mm)->im_delete_flag) { mm->mm_delete(mm, 1); count++; } @@ -435,8 +445,8 @@ iptv_auto_network_process(void *aux, const char *last_url, if (count > 0) tvhinfo(LS_IPTV, "removed %d mux(es) from network '%s'", count, in->mn_network_name); } else { - LIST_FOREACH(mm, &in->mn_muxes, mm_network_link) - ((iptv_mux_t *)mm)->im_delete_flag = 0; + LIST_FOREACH (mm, &in->mn_muxes, mm_network_link) + ((iptv_mux_t*)mm)->im_delete_flag = 0; tvherror(LS_IPTV, "unknown playlist format for network '%s'", in->mn_network_name); } @@ -446,35 +456,31 @@ iptv_auto_network_process(void *aux, const char *last_url, /* * */ -static void -iptv_auto_network_stop( void *aux ) -{ - auto_private_t *ap = aux; +static void iptv_auto_network_stop(void* aux) { + auto_private_t* ap = aux; mtimer_disarm(&ap->in_auto_timer); } /* * */ -static void -iptv_auto_network_trigger0(void *aux) -{ - auto_private_t *ap = aux; - iptv_network_t *in = ap->in_network; +static void iptv_auto_network_trigger0(void* aux) { + auto_private_t* ap = aux; + iptv_network_t* in = ap->in_network; if (in->mn_enabled) download_start(&ap->in_download, in->in_url, ap); - mtimer_arm_rel(&ap->in_auto_timer, iptv_auto_network_trigger0, ap, - sec2mono(MAX(1, in->in_refetch_period) * 60)); + mtimer_arm_rel(&ap->in_auto_timer, + iptv_auto_network_trigger0, + ap, + sec2mono(MAX(1, in->in_refetch_period) * 60)); } /* * */ -void -iptv_auto_network_trigger( iptv_network_t *in ) -{ - auto_private_t *ap = in->in_auto; +void iptv_auto_network_trigger(iptv_network_t* in) { + auto_private_t* ap = in->in_auto; if (ap) { ap->in_download.ssl_peer_verify = in->in_ssl_peer_verify; iptv_auto_network_trigger0(ap); @@ -484,26 +490,22 @@ iptv_auto_network_trigger( iptv_network_t *in ) /* * */ -void -iptv_auto_network_init( iptv_network_t *in ) -{ - auto_private_t *ap = calloc(1, sizeof(auto_private_t)); - ap->in_network = in; - in->in_auto = ap; +void iptv_auto_network_init(iptv_network_t* in) { + auto_private_t* ap = calloc(1, sizeof(auto_private_t)); + ap->in_network = in; + in->in_auto = ap; download_init(&ap->in_download, LS_IPTV); ap->in_download.process = iptv_auto_network_process; - ap->in_download.stop = iptv_auto_network_stop; + ap->in_download.stop = iptv_auto_network_stop; iptv_auto_network_trigger(in); } /* * */ -void -iptv_auto_network_done( iptv_network_t *in ) -{ - auto_private_t *ap = in->in_auto; - in->in_auto = NULL; +void iptv_auto_network_done(iptv_network_t* in) { + auto_private_t* ap = in->in_auto; + in->in_auto = NULL; mtimer_disarm(&ap->in_auto_timer); download_done(&ap->in_download); free(ap); diff --git a/src/input/mpegts/iptv/iptv_file.c b/src/input/mpegts/iptv/iptv_file.c index 17d6b105a..773e3e4f2 100644 --- a/src/input/mpegts/iptv/iptv_file.c +++ b/src/input/mpegts/iptv/iptv_file.c @@ -28,26 +28,24 @@ #include typedef struct file_priv { - int fd; - int shutdown; - pthread_t tid; + int fd; + int shutdown; + pthread_t tid; tvh_cond_t cond; } file_priv_t; /* * Read thread */ -static void * -iptv_file_thread ( void *aux ) -{ - iptv_mux_t *im = aux; - file_priv_t *fp = im->im_data; - ssize_t r; - int fd = fp->fd, pause = 0; - char buf[32*1024]; - off_t off = 0; - int64_t mono; - int e; +static void* iptv_file_thread(void* aux) { + iptv_mux_t* im = aux; + file_priv_t* fp = im->im_data; + ssize_t r; + int fd = fp->fd, pause = 0; + char buf[32 * 1024]; + off_t off = 0; + int64_t mono; + int e; #if defined(PLATFORM_DARWIN) fcntl(fd, F_NOCACHE, 1); @@ -92,19 +90,16 @@ iptv_file_thread ( void *aux ) /* * Open file */ -static int -iptv_file_start - ( iptv_input_t *mi, iptv_mux_t *im, const char *raw, const url_t *url ) -{ - file_priv_t *fp; - int fd = tvh_open(raw + 7, O_RDONLY | O_NONBLOCK, 0); +static int iptv_file_start(iptv_input_t* mi, iptv_mux_t* im, const char* raw, const url_t* url) { + file_priv_t* fp; + int fd = tvh_open(raw + 7, O_RDONLY | O_NONBLOCK, 0); if (fd < 0) { tvherror(LS_IPTV, "unable to open file '%s'", raw + 7); return -1; } - fp = calloc(1, sizeof(*fp)); + fp = calloc(1, sizeof(*fp)); fp->fd = fd; tvh_cond_init(&fp->cond, 1); im->im_data = fp; @@ -113,12 +108,9 @@ iptv_file_start return 0; } -static void -iptv_file_stop - ( iptv_input_t *mi, iptv_mux_t *im ) -{ - file_priv_t *fp = im->im_data; - int rd = fp->fd; +static void iptv_file_stop(iptv_input_t* mi, iptv_mux_t* im) { + file_priv_t* fp = im->im_data; + int rd = fp->fd; if (rd > 0) close(rd); fp->shutdown = 1; @@ -135,16 +127,9 @@ iptv_file_stop * Initialise file handler */ -void -iptv_file_init ( void ) -{ +void iptv_file_init(void) { static iptv_handler_t ih[] = { - { - .scheme = "file", - .buffer_limit = 5000, - .start = iptv_file_start, - .stop = iptv_file_stop - }, + {.scheme = "file", .buffer_limit = 5000, .start = iptv_file_start, .stop = iptv_file_stop}, }; iptv_handler_register(ih, ARRAY_SIZE(ih)); } diff --git a/src/input/mpegts/iptv/iptv_http.c b/src/input/mpegts/iptv/iptv_http.c index 7d599deff..8979f9fd1 100644 --- a/src/input/mpegts/iptv/iptv_http.c +++ b/src/input/mpegts/iptv/iptv_http.c @@ -28,12 +28,12 @@ #error "Wrong openssl!" #endif -#define HLS_SI_TBL_ANALYZE (4*188) +#define HLS_SI_TBL_ANALYZE (4 * 188) typedef struct http_priv { - iptv_input_t *mi; - iptv_mux_t *im; - http_client_t *hc; + iptv_input_t* mi; + iptv_mux_t* im; + http_client_t* hc; gtimer_t kick_timer; uint8_t shutdown; uint8_t started; @@ -42,15 +42,15 @@ typedef struct http_priv { sbuf_t key_sbuf; int m3u_header; uint64_t off; - char *host_url; + char* host_url; int64_t hls_seq; - char *hls_url; + char* hls_url; uint8_t hls_url2; uint8_t hls_encrypted; - char *hls_url_after_key; - char *hls_key_url; - htsmsg_t *hls_m3u; - htsmsg_t *hls_key; + char* hls_url_after_key; + char* hls_key_url; + htsmsg_t* hls_m3u; + htsmsg_t* hls_key; struct { char tmp[AES_BLOCK_SIZE]; int tmp_len; @@ -61,19 +61,17 @@ typedef struct http_priv { /***/ -static int iptv_http_complete_key ( http_client_t *hc ); +static int iptv_http_complete_key(http_client_t* hc); /* * */ -static char * -iptv_http_get_url( http_priv_t *hp, htsmsg_t *m ) -{ - htsmsg_t *items, *item, *inf, *sel = NULL, *key; - htsmsg_field_t *f; - int64_t seq, bandwidth, sel_bandwidth = 0; - int width, height, sel_width = 0, sel_height = 0; - const char *s; +static char* iptv_http_get_url(http_priv_t* hp, htsmsg_t* m) { + htsmsg_t * items, *item, *inf, *sel = NULL, *key; + htsmsg_field_t* f; + int64_t seq, bandwidth, sel_bandwidth = 0; + int width, height, sel_width = 0, sel_height = 0; + const char* s; items = htsmsg_get_list(m, "items"); @@ -84,7 +82,7 @@ iptv_http_get_url( http_priv_t *hp, htsmsg_t *m ) seq = htsmsg_get_s64_or_default(m, "media-sequence", -1); if (seq >= 0) { hp->hls_url2 = 1; - hp->hls_m3u = m; + hp->hls_m3u = m; if (hp->hls_url == NULL && hp->hc->hc_url != NULL) hp->hls_url = strdup(hp->hc->hc_url); } @@ -109,11 +107,12 @@ iptv_http_get_url( http_priv_t *hp, htsmsg_t *m ) if (items == NULL) return NULL; HTSMSG_FOREACH(f, items) { - if ((item = htsmsg_field_get_map(f)) == NULL) continue; + if ((item = htsmsg_field_get_map(f)) == NULL) + continue; inf = htsmsg_get_map(item, "stream-inf"); if (inf) { bandwidth = htsmsg_get_s64_or_default(inf, "BANDWIDTH", 0); - s = htsmsg_get_str(inf, "RESOLUTION"); + s = htsmsg_get_str(inf, "RESOLUTION"); width = height = 0; if (s) sscanf(s, "%dx%d", &width, &height); @@ -121,10 +120,10 @@ iptv_http_get_url( http_priv_t *hp, htsmsg_t *m ) if ((width == 0 && sel_bandwidth < bandwidth) || (bandwidth > 200000 && sel_width < width && sel_height < height) || (sel == NULL && bandwidth > 1000)) { - sel = item; + sel = item; sel_bandwidth = bandwidth; - sel_width = width; - sel_height = height; + sel_width = width; + sel_height = height; } } else { s = htsmsg_get_str(item, "m3u-url"); @@ -138,22 +137,23 @@ iptv_http_get_url( http_priv_t *hp, htsmsg_t *m ) htsmsg_field_destroy(items, f); if (hp->hls_url) { hp->hls_url2 = 1; - hp->hls_m3u = m; + hp->hls_m3u = m; htsmsg_destroy(hp->hls_key); hp->hls_key = key; hp->hls_seq++; } - return (char *)s; + return (char*)s; } } } if (sel && hp->hls_url == NULL) { - inf = htsmsg_get_map(sel, "stream-inf"); + inf = htsmsg_get_map(sel, "stream-inf"); bandwidth = htsmsg_get_s64_or_default(inf, "BANDWIDTH", 0); - tvhdebug(LS_IPTV, "HLS - selected stream %s, %"PRId64"kb/s, %s", - htsmsg_get_str(inf, "RESOLUTION"), - bandwidth / 1024, - htsmsg_get_str(inf, "CODECS")); + tvhdebug(LS_IPTV, + "HLS - selected stream %s, %" PRId64 "kb/s, %s", + htsmsg_get_str(inf, "RESOLUTION"), + bandwidth / 1024, + htsmsg_get_str(inf, "CODECS")); s = htsmsg_get_str(sel, "m3u-url"); if (s && s[0]) { free(hp->hls_url); @@ -167,12 +167,10 @@ iptv_http_get_url( http_priv_t *hp, htsmsg_t *m ) /* * */ -static void -iptv_http_data_aes128 ( http_priv_t *hp, sbuf_t *sb, int off ) -{ - unsigned char *in = sb->sb_data + off; - unsigned char *out = in; - size_t size = sb->sb_ptr - off; +static void iptv_http_data_aes128(http_priv_t* hp, sbuf_t* sb, int off) { + unsigned char* in = sb->sb_data + off; + unsigned char* out = in; + size_t size = sb->sb_ptr - off; AES_cbc_encrypt(in, out, size, &hp->hls_aes128.key, hp->hls_aes128.iv, AES_DECRYPT); } @@ -180,18 +178,19 @@ iptv_http_data_aes128 ( http_priv_t *hp, sbuf_t *sb, int off ) /* * */ -static void -iptv_http_kick_cb( void *aux ) -{ - http_client_t *hc = aux; - http_priv_t *hp; - iptv_mux_t *im; +static void iptv_http_kick_cb(void* aux) { + http_client_t* hc = aux; + http_priv_t* hp; + iptv_mux_t* im; - if (hc == NULL) return; + if (hc == NULL) + return; hp = hc->hc_aux; - if (hp == NULL) return; + if (hp == NULL) + return; im = hp->im; - if (im == NULL) return; + if (im == NULL) + return; if (hp->unpause) { hp->unpause = 0; @@ -203,13 +202,11 @@ iptv_http_kick_cb( void *aux ) /* * Connected */ -static int -iptv_http_header ( http_client_t *hc ) -{ - http_priv_t *hp = hc->hc_aux; - iptv_mux_t *im; - char *argv[3], *s; - int n; +static int iptv_http_header(http_client_t* hc) { + http_priv_t* hp = hc->hc_aux; + iptv_mux_t* im; + char * argv[3], *s; + int n; if (hp == NULL) return 0; @@ -225,11 +222,10 @@ iptv_http_header ( http_client_t *hc ) if (s) { n = http_tokenize(s, argv, ARRAY_SIZE(argv), ';'); if (n > 0 && - (strcasecmp(s, "audio/mpegurl") == 0 || - strcasecmp(s, "audio/x-mpegurl") == 0 || - strcasecmp(s, "application/x-mpegurl") == 0 || - strcasecmp(s, "application/apple.vnd.mpegurl") == 0 || - strcasecmp(s, "application/vnd.apple.mpegurl") == 0)) { + (strcasecmp(s, "audio/mpegurl") == 0 || strcasecmp(s, "audio/x-mpegurl") == 0 || + strcasecmp(s, "application/x-mpegurl") == 0 || + strcasecmp(s, "application/apple.vnd.mpegurl") == 0 || + strcasecmp(s, "application/vnd.apple.mpegurl") == 0)) { if (hp->m3u_header > 10) { hp->m3u_header = 0; return 0; @@ -243,7 +239,7 @@ iptv_http_header ( http_client_t *hc ) } hp->m3u_header = 0; - hp->off = 0; + hp->off = 0; tvh_mutex_lock(&iptv_lock); iptv_input_recv_flush(im); tvh_mutex_unlock(&iptv_lock); @@ -254,17 +250,13 @@ iptv_http_header ( http_client_t *hc ) /* * Receive data */ -static int -iptv_http_data - ( http_client_t *hc, void *buf, size_t len ) -{ - http_priv_t *hp = hc->hc_aux; - iptv_mux_t *im; - int pause = 0, off, rem; - sbuf_t *sb; - - if (hp == NULL || hp->shutdown || hp->im == NULL || - hc->hc_code != HTTP_STATUS_OK) +static int iptv_http_data(http_client_t* hc, void* buf, size_t len) { + http_priv_t* hp = hc->hc_aux; + iptv_mux_t* im; + int pause = 0, off, rem; + sbuf_t* sb; + + if (hp == NULL || hp->shutdown || hp->im == NULL || hc->hc_code != HTTP_STATUS_OK) return 0; im = hp->im; @@ -286,7 +278,7 @@ iptv_http_data if (hp->hls_aes128.tmp_len + len >= AES_BLOCK_SIZE) { if (hp->hls_aes128.tmp_len) { sbuf_append(sb, hp->hls_aes128.tmp, hp->hls_aes128.tmp_len); - rem = AES_BLOCK_SIZE - hp->hls_aes128.tmp_len; + rem = AES_BLOCK_SIZE - hp->hls_aes128.tmp_len; hp->hls_aes128.tmp_len = 0; sbuf_append(sb, buf, rem); len -= rem; @@ -316,7 +308,8 @@ iptv_http_data if (iptv_input_recv_packets(im, len) == 1) pause = hc->hc_pause = 1; - if (pause) hp->unpause = 1; + if (pause) + hp->unpause = 1; tvh_mutex_unlock(&iptv_lock); if (pause) @@ -327,17 +320,15 @@ iptv_http_data /* * Complete data */ -static void -iptv_http_reconnect ( http_client_t *hc, const char *url ) -{ +static void iptv_http_reconnect(http_client_t* hc, const char* url) { url_t u; - int r; + int r; urlinit(&u); if (!urlparse(url, &u)) { tvh_mutex_lock(&hc->hc_mutex); hc->hc_keepalive = 0; - r = http_client_simple_reconnect(hc, &u, HTTP_VERSION_1_1); + r = http_client_simple_reconnect(hc, &u, HTTP_VERSION_1_1); tvh_mutex_unlock(&hc->hc_mutex); if (r < 0) tvherror(LS_IPTV, "cannot reopen http client: %d'", r); @@ -347,15 +338,12 @@ iptv_http_reconnect ( http_client_t *hc, const char *url ) urlreset(&u); } -static int -iptv_http_complete - ( http_client_t *hc ) -{ - http_priv_t *hp = hc->hc_aux; - const char *s; - char *url; - htsmsg_t *m, *m2; - int r; +static int iptv_http_complete(http_client_t* hc) { + http_priv_t* hp = hc->hc_aux; + const char* s; + char* url; + htsmsg_t * m, *m2; + int r; if (hp == NULL || hp->shutdown || hp->im == NULL) return 0; @@ -369,9 +357,9 @@ iptv_http_complete free(hp->host_url); hp->host_url = strdup(hc->hc_url); } - m = parse_m3u((char *)hp->m3u_sbuf.sb_data, NULL, hp->host_url); + m = parse_m3u((char*)hp->m3u_sbuf.sb_data, NULL, hp->host_url); sbuf_free(&hp->m3u_sbuf); -url: + url: url = iptv_http_get_url(hp, m); if (hp->hls_m3u == m) m = NULL; @@ -384,8 +372,7 @@ url: memset(&hp->hls_aes128.iv, 0, sizeof(hp->hls_aes128.iv)); s = htsmsg_get_str(hp->hls_key, "IV"); if (s != NULL) { - if (s[0] != '0' || (s[1] != 'x' && s[1] != 'X') || - strlen(s) != (AES_BLOCK_SIZE * 2) + 2) { + if (s[0] != '0' || (s[1] != 'x' && s[1] != 'X') || strlen(s) != (AES_BLOCK_SIZE * 2) + 2) { tvherror(LS_IPTV, "unknown IV type or length (%s)", s); goto end; } @@ -402,8 +389,8 @@ url: hp->hls_key_url = strdup(s); free(hp->hls_url_after_key); hp->hls_url_after_key = url; - url = strdup(s); - hc->hc_data_complete = iptv_http_complete_key; + url = strdup(s); + hc->hc_data_complete = iptv_http_complete_key; sbuf_reset(&hp->key_sbuf, 32); } } @@ -412,19 +399,19 @@ url: tvherror(LS_IPTV, "m3u contents parsing failed"); goto fin; } -new_m3u: + new_m3u: iptv_http_reconnect(hc, url); -end: + end: free(url); -fin: + fin: htsmsg_destroy(m); } else { if (hp->hls_url && hp->hls_m3u) { - m = hp->hls_m3u; + m = hp->hls_m3u; hp->hls_m3u = NULL; - m2 = htsmsg_get_list(m, "items"); + m2 = htsmsg_get_list(m, "items"); if (m2 && htsmsg_is_empty(m2)) { - r = htsmsg_get_bool_or_default(m, "x-endlist", 0); + r = htsmsg_get_bool_or_default(m, "x-endlist", 0); hp->hls_url2 = 0; if (r == 0) { url = strdup(hp->hls_url); @@ -439,11 +426,8 @@ fin: return 0; } -static int -iptv_http_complete_key - ( http_client_t *hc ) -{ - http_priv_t *hp = hc->hc_aux; +static int iptv_http_complete_key(http_client_t* hc) { + http_priv_t* hp = hc->hc_aux; if (hp == NULL || hp->shutdown) return 0; @@ -466,10 +450,8 @@ iptv_http_complete_key * Custom headers */ static void -iptv_http_create_header - ( http_client_t *hc, http_arg_list_t *h, const url_t *url, int keepalive ) -{ - http_priv_t *hp = hc->hc_aux; +iptv_http_create_header(http_client_t* hc, http_arg_list_t* h, const url_t* url, int keepalive) { + http_priv_t* hp = hc->hc_aux; if (hp == NULL || hp->shutdown || hp->im == NULL) return; @@ -480,9 +462,7 @@ iptv_http_create_header /* * */ -static void -iptv_http_free( http_priv_t *hp ) -{ +static void iptv_http_free(http_priv_t* hp) { if (hp->hc) http_client_close(hp->hc); sbuf_free(&hp->m3u_sbuf); @@ -499,21 +479,17 @@ iptv_http_free( http_priv_t *hp ) /* * Setup HTTP(S) connection */ -static int -iptv_http_start - ( iptv_input_t *mi, iptv_mux_t *im, const char *raw, const url_t *u ) -{ - http_priv_t *hp; - http_client_t *hc; - int r; +static int iptv_http_start(iptv_input_t* mi, iptv_mux_t* im, const char* raw, const url_t* u) { + http_priv_t* hp; + http_client_t* hc; + int r; sbuf_reset_and_alloc(&im->mm_iptv_buffer, IPTV_BUF_SIZE); - hp = calloc(1, sizeof(*hp)); + hp = calloc(1, sizeof(*hp)); hp->mi = mi; hp->im = im; - if (!(hc = http_client_connect(hp, HTTP_VERSION_1_1, u->scheme, - u->host, u->port, NULL))) { + if (!(hc = http_client_connect(hp, HTTP_VERSION_1_1, u->scheme, u->host, u->port, NULL))) { iptv_http_free(hp); return SM_CODE_TUNING_FAILED; } @@ -521,15 +497,15 @@ iptv_http_start hc->hc_hdr_received = iptv_http_header; hc->hc_data_received = iptv_http_data; hc->hc_data_complete = iptv_http_complete; - hc->hc_handle_location = 1; /* allow redirects */ - hc->hc_io_size = 128*1024; /* increase buffering */ - hp->hc = hc; - im->im_data = hp; + hc->hc_handle_location = 1; /* allow redirects */ + hc->hc_io_size = 128 * 1024; /* increase buffering */ + hp->hc = hc; + im->im_data = hp; sbuf_init(&hp->m3u_sbuf); sbuf_init(&hp->key_sbuf); sbuf_init_fixed(&im->mm_iptv_buffer, IPTV_BUF_SIZE); iptv_input_mux_started(hp->mi, im, 1); - http_client_register(hc); /* register to the HTTP thread */ + http_client_register(hc); /* register to the HTTP thread */ r = http_client_simple(hc, u); if (r < 0) { iptv_http_free(hp); @@ -543,31 +519,24 @@ iptv_http_start /* * Stop connection */ -static void -iptv_http_stop - ( iptv_input_t *mi, iptv_mux_t *im ) -{ - http_priv_t *hp = im->im_data; +static void iptv_http_stop(iptv_input_t* mi, iptv_mux_t* im) { + http_priv_t* hp = im->im_data; hp->shutdown = 1; gtimer_disarm(&hp->kick_timer); tvh_mutex_unlock(&iptv_lock); http_client_close(hp->hc); tvh_mutex_lock(&iptv_lock); - hp->hc = NULL; + hp->hc = NULL; im->im_data = NULL; iptv_http_free(hp); } - /* * Pause/Unpause */ -static void -iptv_http_pause - ( iptv_input_t *mi, iptv_mux_t *im, int pause ) -{ - http_priv_t *hp = im->im_data; +static void iptv_http_pause(iptv_input_t* mi, iptv_mux_t* im, int pause) { + http_priv_t* hp = im->im_data; assert(pause == 0); http_client_unpause(hp->hc); @@ -577,24 +546,16 @@ iptv_http_pause * Initialise HTTP handler */ -void -iptv_http_init ( void ) -{ - static iptv_handler_t ih[] = { - { - .scheme = "http", - .buffer_limit = 5000, - .start = iptv_http_start, - .stop = iptv_http_stop, - .pause = iptv_http_pause - }, - { - .scheme = "https", - .buffer_limit = 5000, - .start = iptv_http_start, - .stop = iptv_http_stop, - .pause = iptv_http_pause - } - }; +void iptv_http_init(void) { + static iptv_handler_t ih[] = {{.scheme = "http", + .buffer_limit = 5000, + .start = iptv_http_start, + .stop = iptv_http_stop, + .pause = iptv_http_pause}, + {.scheme = "https", + .buffer_limit = 5000, + .start = iptv_http_start, + .stop = iptv_http_stop, + .pause = iptv_http_pause}}; iptv_handler_register(ih, 2); } diff --git a/src/input/mpegts/iptv/iptv_libav.c b/src/input/mpegts/iptv/iptv_libav.c index bdba7d600..7683bc2fd 100644 --- a/src/input/mpegts/iptv/iptv_libav.c +++ b/src/input/mpegts/iptv/iptv_libav.c @@ -28,32 +28,30 @@ #include #endif -#define WRITE_BUFFER_SIZE (188*500) +#define WRITE_BUFFER_SIZE (188 * 500) typedef struct { - const char *url; - iptv_mux_t *mux; - int running; - int pause; - pthread_t thread; - tvh_mutex_t lock; - th_pipe_t pipe; - AVFormatContext *ictx; - AVFormatContext *octx; - sbuf_t sbuf; + const char* url; + iptv_mux_t* mux; + int running; + int pause; + pthread_t thread; + tvh_mutex_t lock; + th_pipe_t pipe; + AVFormatContext* ictx; + AVFormatContext* octx; + sbuf_t sbuf; } iptv_libav_priv_t; /* * */ -static int -iptv_libav_write_packet(void *opaque, uint8_t *buf, int buf_size) -{ - iptv_libav_priv_t *la = opaque; +static int iptv_libav_write_packet(void* opaque, uint8_t* buf, int buf_size) { + iptv_libav_priv_t* la = opaque; if (buf_size > 0) { tvh_mutex_lock(&la->lock); - if (la->sbuf.sb_ptr < 5*1024*1024) { + if (la->sbuf.sb_ptr < 5 * 1024 * 1024) { while (atomic_get(&la->pause)) { if (!atomic_get(&la->running)) goto fin; @@ -65,7 +63,7 @@ iptv_libav_write_packet(void *opaque, uint8_t *buf, int buf_size) /* notify iptv layer that we have new data to read */ if (write(la->pipe.wr, "", 1)) {}; } -fin: + fin: tvh_mutex_unlock(&la->lock); } return 0; @@ -74,10 +72,8 @@ fin: /* * */ -static int -iptv_libav_interrupt_callback(void *opaque) -{ - iptv_libav_priv_t *la = opaque; +static int iptv_libav_interrupt_callback(void* opaque) { + iptv_libav_priv_t* la = opaque; return atomic_get(&la->running) == 0; } @@ -85,16 +81,14 @@ iptv_libav_interrupt_callback(void *opaque) /* * */ -static void * -iptv_libav_thread(void *aux) -{ - iptv_libav_priv_t *la = aux; - AVStream *in_stream, *out_stream; - AVPacket pkt; - AVCodecContext *c; - const AVCodec *codec; - uint8_t *buf = NULL; - int ret, i; +static void* iptv_libav_thread(void* aux) { + iptv_libav_priv_t* la = aux; + AVStream * in_stream, *out_stream; + AVPacket pkt; + AVCodecContext* c; + const AVCodec* codec; + uint8_t* buf = NULL; + int ret, i; buf = malloc(WRITE_BUFFER_SIZE); if (buf == NULL) @@ -105,24 +99,32 @@ iptv_libav_thread(void *aux) goto fail; } la->ictx->interrupt_callback.callback = iptv_libav_interrupt_callback; - la->ictx->interrupt_callback.opaque = la; + la->ictx->interrupt_callback.opaque = la; if ((ret = avformat_find_stream_info(la->ictx, 0)) < 0) { - tvherror(LS_IPTV, "libav: Unable to find stream info for input '%s': %s", la->url, av_err2str(ret)); + tvherror(LS_IPTV, + "libav: Unable to find stream info for input '%s': %s", + la->url, + av_err2str(ret)); goto fail; } avformat_alloc_output_context2(&la->octx, NULL, "mpegts", NULL); if (la->octx == NULL) goto fail; - la->octx->pb = avio_alloc_context(buf, WRITE_BUFFER_SIZE, AVIO_FLAG_WRITE, - la, NULL, iptv_libav_write_packet, NULL); + la->octx->pb = avio_alloc_context(buf, + WRITE_BUFFER_SIZE, + AVIO_FLAG_WRITE, + la, + NULL, + iptv_libav_write_packet, + NULL); la->octx->interrupt_callback.callback = iptv_libav_interrupt_callback; - la->octx->interrupt_callback.opaque = la; + la->octx->interrupt_callback.opaque = la; for (i = 0; i < la->ictx->nb_streams; i++) { - in_stream = la->ictx->streams[i]; - codec = avcodec_find_encoder(in_stream->codecpar->codec_id); - c = avcodec_alloc_context3(codec); + in_stream = la->ictx->streams[i]; + codec = avcodec_find_encoder(in_stream->codecpar->codec_id); + c = avcodec_alloc_context3(codec); out_stream = avformat_new_stream(la->octx, codec); if (out_stream == NULL) { tvherror(LS_IPTV, "libav: Failed allocating output stream"); @@ -131,7 +133,9 @@ iptv_libav_thread(void *aux) } ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar); if (ret < 0) { - tvherror(LS_IPTV, "libav: Failed to copy context from input to output stream codec context: %s", av_err2str(ret)); + tvherror(LS_IPTV, + "libav: Failed to copy context from input to output stream codec context: %s", + av_err2str(ret)); avcodec_free_context(&c); goto fail; } @@ -156,22 +160,27 @@ iptv_libav_thread(void *aux) } if (atomic_get(&la->running) == 0) goto unref; - if ((pkt.dts != AV_NOPTS_VALUE && pkt.dts < 0) || - (pkt.pts != AV_NOPTS_VALUE && pkt.pts < 0)) + if ((pkt.dts != AV_NOPTS_VALUE && pkt.dts < 0) || (pkt.pts != AV_NOPTS_VALUE && pkt.pts < 0)) goto unref; in_stream = la->ictx->streams[pkt.stream_index]; out_stream = la->octx->streams[pkt.stream_index]; /* copy packet */ - pkt.pts = av_rescale_q_rnd(pkt.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); - pkt.dts = av_rescale_q_rnd(pkt.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); + pkt.pts = av_rescale_q_rnd(pkt.pts, + in_stream->time_base, + out_stream->time_base, + AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); + pkt.dts = av_rescale_q_rnd(pkt.dts, + in_stream->time_base, + out_stream->time_base, + AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); pkt.duration = av_rescale_q(pkt.duration, in_stream->time_base, out_stream->time_base); - pkt.pos = -1; - ret = av_interleaved_write_frame(la->octx, &pkt); + pkt.pos = -1; + ret = av_interleaved_write_frame(la->octx, &pkt); if (ret < 0) { tvherror(LS_IPTV, "libav: Error muxing packet: %s", av_err2str(ret)); break; } -unref: + unref: av_packet_unref(&pkt); } av_write_trailer(la->octx); @@ -184,11 +193,8 @@ fail: /* * Start new thread */ -static int -iptv_libav_start - ( iptv_input_t *mi, iptv_mux_t *im, const char *raw, const url_t *url ) -{ - iptv_libav_priv_t *la = calloc(1, sizeof(*la)); +static int iptv_libav_start(iptv_input_t* mi, iptv_mux_t* im, const char* raw, const url_t* url) { + iptv_libav_priv_t* la = calloc(1, sizeof(*la)); assert(raw); tvh_mutex_init(&la->lock, NULL); @@ -209,11 +215,8 @@ iptv_libav_start return 0; } -static void -iptv_libav_stop - ( iptv_input_t *mi, iptv_mux_t *im ) -{ - iptv_libav_priv_t *la = im->im_opaque; +static void iptv_libav_stop(iptv_input_t* mi, iptv_mux_t* im) { + iptv_libav_priv_t* la = im->im_opaque; atomic_set(&la->running, 0); im->im_opaque = NULL; @@ -226,12 +229,10 @@ iptv_libav_stop free(la); } -static ssize_t -iptv_libav_read ( iptv_input_t *mi, iptv_mux_t *im ) -{ - iptv_libav_priv_t *la = im->im_opaque; - char buf[8192]; - ssize_t ret; +static ssize_t iptv_libav_read(iptv_input_t* mi, iptv_mux_t* im) { + iptv_libav_priv_t* la = im->im_opaque; + char buf[8192]; + ssize_t ret; if (la == NULL) return 0; @@ -244,10 +245,8 @@ iptv_libav_read ( iptv_input_t *mi, iptv_mux_t *im ) return ret; } -static void -iptv_libav_pause ( iptv_input_t *mi, iptv_mux_t *im, int pause ) -{ - iptv_libav_priv_t *la = im->im_opaque; +static void iptv_libav_pause(iptv_input_t* mi, iptv_mux_t* im, int pause) { + iptv_libav_priv_t* la = im->im_opaque; if (la) atomic_set(&la->pause, pause); @@ -256,18 +255,16 @@ iptv_libav_pause ( iptv_input_t *mi, iptv_mux_t *im, int pause ) /* * Initialise libav handler */ -void -iptv_libav_init ( void ) -{ +void iptv_libav_init(void) { static iptv_handler_t ih[] = { - { - .scheme = "libav", - .buffer_limit = 5000, - .start = iptv_libav_start, - .stop = iptv_libav_stop, - .read = iptv_libav_read, - .pause = iptv_libav_pause, - }, + { + .scheme = "libav", + .buffer_limit = 5000, + .start = iptv_libav_start, + .stop = iptv_libav_stop, + .read = iptv_libav_read, + .pause = iptv_libav_pause, + }, }; iptv_handler_register(ih, ARRAY_SIZE(ih)); } diff --git a/src/input/mpegts/iptv/iptv_mux.c b/src/input/mpegts/iptv/iptv_mux.c index 33b041b91..cef345df4 100644 --- a/src/input/mpegts/iptv/iptv_mux.c +++ b/src/input/mpegts/iptv/iptv_mux.c @@ -27,20 +27,16 @@ extern const idclass_t mpegts_mux_class; static inline void -iptv_url_set0 ( char **url, char **sane_url, - const char *url1, const char *sane_url1 ) -{ +iptv_url_set0(char** url, char** sane_url, const char* url1, const char* sane_url1) { free(*url); free(*sane_url); - *url = url1 ? strdup(url1) : NULL; + *url = url1 ? strdup(url1) : NULL; *sane_url = sane_url1 ? strdup(sane_url1) : NULL; } -int -iptv_url_set ( char **url, char **sane_url, const char *str, int allow_file, int allow_pipe ) -{ - const char *x; - url_t u; +int iptv_url_set(char** url, char** sane_url, const char* str, int allow_file, int allow_pipe) { + const char* x; + url_t u; if (strcmp(str ?: "", *url ?: "") == 0) return 0; @@ -57,7 +53,7 @@ iptv_url_set ( char **url, char **sane_url, const char *str, int allow_file, int x = str + strlen(str); while (x != str && *x <= ' ') x--; - ((char *)x)[1] = '\0'; + ((char*)x)[1] = '\0'; iptv_url_set0(url, sane_url, str, str); return 1; } @@ -74,258 +70,209 @@ iptv_url_set ( char **url, char **sane_url, const char *str, int allow_file, int return 0; } -static int -iptv_mux_url_set ( void *p, const void *v ) -{ - iptv_mux_t *im = p; +static int iptv_mux_url_set(void* p, const void* v) { + iptv_mux_t* im = p; return iptv_url_set(&im->mm_iptv_url, &im->mm_iptv_url_sane, v, 1, 1); } -static int -iptv_mux_ret_url_set ( void *p, const void *v ) -{ - iptv_mux_t *im = p; +static int iptv_mux_ret_url_set(void* p, const void* v) { + iptv_mux_t* im = p; return iptv_url_set(&im->mm_iptv_ret_url, &im->mm_iptv_ret_url_sane, v, 0, 0); } #if ENABLE_LIBAV -static htsmsg_t * -iptv_mux_libav_enum ( void *o, const char *lang ) -{ +static htsmsg_t* iptv_mux_libav_enum(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Network settings"), 0 }, - { N_("Use"), 1 }, - { N_("Do not use"), -1 }, + {N_("Network settings"), 0}, + {N_("Use"), 1}, + {N_("Do not use"), -1}, }; return strtab2htsmsg(tab, 1, lang); } #endif -const idclass_t iptv_mux_class = -{ - .ic_super = &mpegts_mux_class, - .ic_class = "iptv_mux", - .ic_caption = N_("IPTV Multiplex"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "priority", - .name = N_("Priority"), - .off = offsetof(iptv_mux_t, mm_iptv_priority), - .def.i = 0, - .opts = PO_ADVANCED - }, - { - .type = PT_INT, - .id = "spriority", - .name = N_("Streaming priority"), - .off = offsetof(iptv_mux_t, mm_iptv_streaming_priority), - .def.i = 0, - .opts = PO_ADVANCED - }, - { - .type = PT_STR, - .id = "iptv_url", - .name = N_("URL"), - .off = offsetof(iptv_mux_t, mm_iptv_url), - .set = iptv_mux_url_set, - .opts = PO_MULTILINE - }, - { - .type = PT_BOOL, - .id = "iptv_send_reports", - .name = N_("Send RTCP status reports"), - .off = offsetof(iptv_mux_t, mm_iptv_send_reports), - .opts = PO_ADVANCED - }, - { - .type = PT_STR, - .id = "iptv_ret_url", - .name = N_("Retransmission URL"), - .desc = N_("Manually setup a retransmission URL for Multicast streams." - " For RTSP streams this URL is automatically setup" - " if this value is not set."), - .off = offsetof(iptv_mux_t, mm_iptv_ret_url), - .set = iptv_mux_ret_url_set, - .opts = PO_ADVANCED - }, - { - .type = PT_STR, - .id = "iptv_url_cmpid", - .name = N_("URL for comparison"), - .off = offsetof(iptv_mux_t, mm_iptv_url_cmpid), - .opts = PO_MULTILINE | PO_HIDDEN | PO_NOUI, - }, - { - .type = PT_BOOL, - .id = "iptv_substitute", - .name = N_("Substitute formatters"), - .off = offsetof(iptv_mux_t, mm_iptv_substitute), - .opts = PO_ADVANCED - }, +const idclass_t iptv_mux_class = {.ic_super = &mpegts_mux_class, + .ic_class = "iptv_mux", + .ic_caption = N_("IPTV Multiplex"), + .ic_properties = (const property_t[]){{.type = PT_INT, + .id = "priority", + .name = N_("Priority"), + .off = offsetof(iptv_mux_t, mm_iptv_priority), + .def.i = 0, + .opts = PO_ADVANCED}, + {.type = PT_INT, + .id = "spriority", + .name = N_("Streaming priority"), + .off = offsetof(iptv_mux_t, mm_iptv_streaming_priority), + .def.i = 0, + .opts = PO_ADVANCED}, + {.type = PT_STR, + .id = "iptv_url", + .name = N_("URL"), + .off = offsetof(iptv_mux_t, mm_iptv_url), + .set = iptv_mux_url_set, + .opts = PO_MULTILINE}, + {.type = PT_BOOL, + .id = "iptv_send_reports", + .name = N_("Send RTCP status reports"), + .off = offsetof(iptv_mux_t, mm_iptv_send_reports), + .opts = PO_ADVANCED}, + {.type = PT_STR, + .id = "iptv_ret_url", + .name = N_("Retransmission URL"), + .desc = N_("Manually setup a retransmission URL for Multicast streams." + " For RTSP streams this URL is automatically setup" + " if this value is not set."), + .off = offsetof(iptv_mux_t, mm_iptv_ret_url), + .set = iptv_mux_ret_url_set, + .opts = PO_ADVANCED}, + { + .type = PT_STR, + .id = "iptv_url_cmpid", + .name = N_("URL for comparison"), + .off = offsetof(iptv_mux_t, mm_iptv_url_cmpid), + .opts = PO_MULTILINE | PO_HIDDEN | PO_NOUI, + }, + {.type = PT_BOOL, + .id = "iptv_substitute", + .name = N_("Substitute formatters"), + .off = offsetof(iptv_mux_t, mm_iptv_substitute), + .opts = PO_ADVANCED}, #if ENABLE_LIBAV - { - .type = PT_INT, - .id = "use_libav", - .name = N_("Use A/V library"), - .desc = N_("The input stream is remuxed with A/V library (libav or" - " or ffmpeg) to the MPEG-TS format which is accepted by" - " Tvheadend."), - .list = iptv_mux_libav_enum, - .off = offsetof(iptv_mux_t, mm_iptv_libav), - }, + { + .type = PT_INT, + .id = "use_libav", + .name = N_("Use A/V library"), + .desc = N_("The input stream is remuxed with A/V library (libav or" + " or ffmpeg) to the MPEG-TS format which is accepted by" + " Tvheadend."), + .list = iptv_mux_libav_enum, + .off = offsetof(iptv_mux_t, mm_iptv_libav), + }, #endif - { - .type = PT_STR, - .id = "iptv_interface", - .name = N_("Interface"), - .off = offsetof(iptv_mux_t, mm_iptv_interface), - .list = network_interfaces_enum, - .opts = PO_ADVANCED - }, - { - .type = PT_BOOL, - .id = "iptv_atsc", - .name = N_("ATSC"), - .off = offsetof(iptv_mux_t, mm_iptv_atsc), - }, - { - .type = PT_STR, - .id = "iptv_muxname", - .name = N_("Mux name"), - .off = offsetof(iptv_mux_t, mm_iptv_muxname), - }, - { - .type = PT_S64, - .intextra = CHANNEL_SPLIT, - .id = "channel_number", - .name = N_("Channel number"), - .off = offsetof(iptv_mux_t, mm_iptv_chnum), - }, - { - .type = PT_STR, - .id = "iptv_sname", - .name = N_("Service name"), - .off = offsetof(iptv_mux_t, mm_iptv_svcname), - }, - { - .type = PT_STR, - .id = "iptv_epgid", - .name = N_("EPG name"), - .off = offsetof(iptv_mux_t, mm_iptv_epgid), - .opts = PO_ADVANCED - }, - { - .type = PT_STR, - .id = "iptv_icon", - .name = N_("Icon URL"), - .off = offsetof(iptv_mux_t, mm_iptv_icon), - .opts = PO_ADVANCED - }, - { - .type = PT_BOOL, - .id = "iptv_respawn", - .name = N_("Respawn (pipe)"), - .off = offsetof(iptv_mux_t, mm_iptv_respawn), - .opts = PO_EXPERT - }, - { - .type = PT_INT, - .id = "iptv_kill", - .name = N_("Kill signal (pipe)"), - .off = offsetof(iptv_mux_t, mm_iptv_kill), - .list = proplib_kill_list, - .opts = PO_EXPERT - }, - { - .type = PT_INT, - .id = "iptv_kill_timeout", - .name = N_("Kill timeout (pipe/secs)"), - .off = offsetof(iptv_mux_t, mm_iptv_kill_timeout), - .opts = PO_EXPERT, - .def.i = 5 - }, - { - .type = PT_STR, - .id = "iptv_env", - .name = N_("Environment (pipe)"), - .off = offsetof(iptv_mux_t, mm_iptv_env), - .opts = PO_EXPERT | PO_MULTILINE - }, - { - .type = PT_STR, - .id = "iptv_hdr", - .name = N_("Custom HTTP headers"), - .off = offsetof(iptv_mux_t, mm_iptv_hdr), - .opts = PO_EXPERT | PO_MULTILINE - }, - { - .type = PT_STR, - .id = "iptv_tags", - .name = N_("Channel tags"), - .off = offsetof(iptv_mux_t, mm_iptv_tags), - .opts = PO_ADVANCED | PO_MULTILINE - }, - { - .type = PT_U32, - .id = "iptv_satip_dvbt_freq", - .name = N_("SAT>IP DVB-T frequency (Hz)"), - .off = offsetof(iptv_mux_t, mm_iptv_satip_dvbt_freq), - .desc = N_("For example: 658000000. This frequency is 658Mhz."), - .opts = PO_ADVANCED - }, - { - .type = PT_U32, - .id = "iptv_satip_dvbc_freq", - .name = N_("SAT>IP DVB-C frequency (Hz)"), - .off = offsetof(iptv_mux_t, mm_iptv_satip_dvbc_freq), - .desc = N_("For example: 312000000. This frequency is 312Mhz."), - .opts = PO_ADVANCED - }, - { - .type = PT_U32, - .id = "iptv_satip_dvbs_freq", - .name = N_("SAT>IP DVB-S frequency (kHz)"), - .off = offsetof(iptv_mux_t, mm_iptv_satip_dvbs_freq), - .desc = N_("For example: 12610500. This frequency is 12610.5Mhz or 12.6105Ghz."), - .opts = PO_ADVANCED - }, - { - .type = PT_U32, - .id = "iptv_buffer_limit", - .name = N_("Buffering limit (ms)"), - .desc = N_("Specifies the incoming buffering limit in " - "milliseconds (PCR based). If the PCR time " - "difference from the system clock is higher than " - "this, the incoming stream is paused."), - .off = offsetof(iptv_mux_t, mm_iptv_buffer_limit), - .opts = PO_ADVANCED, - }, - {} - } -}; + {.type = PT_STR, + .id = "iptv_interface", + .name = N_("Interface"), + .off = offsetof(iptv_mux_t, mm_iptv_interface), + .list = network_interfaces_enum, + .opts = PO_ADVANCED}, + { + .type = PT_BOOL, + .id = "iptv_atsc", + .name = N_("ATSC"), + .off = offsetof(iptv_mux_t, mm_iptv_atsc), + }, + { + .type = PT_STR, + .id = "iptv_muxname", + .name = N_("Mux name"), + .off = offsetof(iptv_mux_t, mm_iptv_muxname), + }, + { + .type = PT_S64, + .intextra = CHANNEL_SPLIT, + .id = "channel_number", + .name = N_("Channel number"), + .off = offsetof(iptv_mux_t, mm_iptv_chnum), + }, + { + .type = PT_STR, + .id = "iptv_sname", + .name = N_("Service name"), + .off = offsetof(iptv_mux_t, mm_iptv_svcname), + }, + {.type = PT_STR, + .id = "iptv_epgid", + .name = N_("EPG name"), + .off = offsetof(iptv_mux_t, mm_iptv_epgid), + .opts = PO_ADVANCED}, + {.type = PT_STR, + .id = "iptv_icon", + .name = N_("Icon URL"), + .off = offsetof(iptv_mux_t, mm_iptv_icon), + .opts = PO_ADVANCED}, + {.type = PT_BOOL, + .id = "iptv_respawn", + .name = N_("Respawn (pipe)"), + .off = offsetof(iptv_mux_t, mm_iptv_respawn), + .opts = PO_EXPERT}, + {.type = PT_INT, + .id = "iptv_kill", + .name = N_("Kill signal (pipe)"), + .off = offsetof(iptv_mux_t, mm_iptv_kill), + .list = proplib_kill_list, + .opts = PO_EXPERT}, + {.type = PT_INT, + .id = "iptv_kill_timeout", + .name = N_("Kill timeout (pipe/secs)"), + .off = offsetof(iptv_mux_t, mm_iptv_kill_timeout), + .opts = PO_EXPERT, + .def.i = 5}, + {.type = PT_STR, + .id = "iptv_env", + .name = N_("Environment (pipe)"), + .off = offsetof(iptv_mux_t, mm_iptv_env), + .opts = PO_EXPERT | PO_MULTILINE}, + {.type = PT_STR, + .id = "iptv_hdr", + .name = N_("Custom HTTP headers"), + .off = offsetof(iptv_mux_t, mm_iptv_hdr), + .opts = PO_EXPERT | PO_MULTILINE}, + {.type = PT_STR, + .id = "iptv_tags", + .name = N_("Channel tags"), + .off = offsetof(iptv_mux_t, mm_iptv_tags), + .opts = PO_ADVANCED | PO_MULTILINE}, + {.type = PT_U32, + .id = "iptv_satip_dvbt_freq", + .name = N_("SAT>IP DVB-T frequency (Hz)"), + .off = offsetof(iptv_mux_t, mm_iptv_satip_dvbt_freq), + .desc = N_("For example: 658000000. This frequency is 658Mhz."), + .opts = PO_ADVANCED}, + {.type = PT_U32, + .id = "iptv_satip_dvbc_freq", + .name = N_("SAT>IP DVB-C frequency (Hz)"), + .off = offsetof(iptv_mux_t, mm_iptv_satip_dvbc_freq), + .desc = N_("For example: 312000000. This frequency is 312Mhz."), + .opts = PO_ADVANCED}, + {.type = PT_U32, + .id = "iptv_satip_dvbs_freq", + .name = N_("SAT>IP DVB-S frequency (kHz)"), + .off = offsetof(iptv_mux_t, mm_iptv_satip_dvbs_freq), + .desc = N_("For example: 12610500. This frequency is 12610.5Mhz or 12.6105Ghz."), + .opts = PO_ADVANCED}, + { + .type = PT_U32, + .id = "iptv_buffer_limit", + .name = N_("Buffering limit (ms)"), + .desc = N_("Specifies the incoming buffering limit in " + "milliseconds (PCR based). If the PCR time " + "difference from the system clock is higher than " + "this, the incoming stream is paused."), + .off = offsetof(iptv_mux_t, mm_iptv_buffer_limit), + .opts = PO_ADVANCED, + }, + {}}}; -static htsmsg_t * -iptv_mux_config_save ( mpegts_mux_t *mm, char *filename, size_t fsize ) -{ - char ubuf1[UUID_HEX_SIZE]; - char ubuf2[UUID_HEX_SIZE]; - htsmsg_t *c = htsmsg_create_map(); +static htsmsg_t* iptv_mux_config_save(mpegts_mux_t* mm, char* filename, size_t fsize) { + char ubuf1[UUID_HEX_SIZE]; + char ubuf2[UUID_HEX_SIZE]; + htsmsg_t* c = htsmsg_create_map(); if (filename == NULL) { mpegts_mux_save(mm, c, 1); } else { mpegts_mux_save(mm, c, 0); - snprintf(filename, fsize, "input/iptv/networks/%s/muxes/%s", - idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), - idnode_uuid_as_str(&mm->mm_id, ubuf2)); + snprintf(filename, + fsize, + "input/iptv/networks/%s/muxes/%s", + idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), + idnode_uuid_as_str(&mm->mm_id, ubuf2)); } return c; } -static void -iptv_mux_free ( mpegts_mux_t *mm ) -{ - iptv_mux_t *im = (iptv_mux_t *)mm; +static void iptv_mux_free(mpegts_mux_t* mm) { + iptv_mux_t* im = (iptv_mux_t*)mm; free(im->mm_iptv_url); free(im->mm_iptv_url_sane); free(im->mm_iptv_url_raw); @@ -345,27 +292,23 @@ iptv_mux_free ( mpegts_mux_t *mm ) mpegts_mux_free(mm); } -static void -iptv_mux_delete ( mpegts_mux_t *mm, int delconf ) -{ +static void iptv_mux_delete(mpegts_mux_t* mm, int delconf) { char ubuf1[UUID_HEX_SIZE]; char ubuf2[UUID_HEX_SIZE]; if (delconf) hts_settings_remove("input/iptv/networks/%s/muxes/%s", - idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), - idnode_uuid_as_str(&mm->mm_id, ubuf2)); + idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), + idnode_uuid_as_str(&mm->mm_id, ubuf2)); mpegts_mux_delete(mm, delconf); } -static void -iptv_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len ) -{ - iptv_mux_t *im = (iptv_mux_t*)mm; - if(im->mm_iptv_muxname) { +static void iptv_mux_display_name(mpegts_mux_t* mm, char* buf, size_t len) { + iptv_mux_t* im = (iptv_mux_t*)mm; + if (im->mm_iptv_muxname) { strlcpy(buf, im->mm_iptv_muxname, len); - } else if(im->mm_iptv_url_sane) { + } else if (im->mm_iptv_url_sane) { strlcpy(buf, im->mm_iptv_url_sane, len); } else { *buf = 0; @@ -375,25 +318,26 @@ iptv_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len ) /* * Create */ -iptv_mux_t * -iptv_mux_create0 ( iptv_network_t *in, const char *uuid, htsmsg_t *conf ) -{ - htsmsg_t *c, *c2, *e; - htsmsg_field_t *f; - iptv_service_t *ms; - char ubuf1[UUID_HEX_SIZE]; - char ubuf2[UUID_HEX_SIZE]; +iptv_mux_t* iptv_mux_create0(iptv_network_t* in, const char* uuid, htsmsg_t* conf) { + htsmsg_t * c, *c2, *e; + htsmsg_field_t* f; + iptv_service_t* ms; + char ubuf1[UUID_HEX_SIZE]; + char ubuf2[UUID_HEX_SIZE]; /* Create Mux */ - iptv_mux_t *im = - mpegts_mux_create(iptv_mux, uuid, (mpegts_network_t*)in, - MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, conf); + iptv_mux_t* im = mpegts_mux_create(iptv_mux, + uuid, + (mpegts_network_t*)in, + MPEGTS_ONID_NONE, + MPEGTS_TSID_NONE, + conf); /* Callbacks */ - im->mm_display_name = iptv_mux_display_name; - im->mm_config_save = iptv_mux_config_save; - im->mm_delete = iptv_mux_delete; - im->mm_free = iptv_mux_free; + im->mm_display_name = iptv_mux_display_name; + im->mm_config_save = iptv_mux_config_save; + im->mm_delete = iptv_mux_delete; + im->mm_free = iptv_mux_free; if (!im->mm_iptv_kill_timeout) im->mm_iptv_kill_timeout = 5; @@ -402,14 +346,16 @@ iptv_mux_create0 ( iptv_network_t *in, const char *uuid, htsmsg_t *conf ) /* Services */ c2 = NULL; - c = htsmsg_get_map(conf, "services"); + c = htsmsg_get_map(conf, "services"); if (c == NULL) - c = c2 = hts_settings_load_r(1, "input/iptv/networks/%s/muxes/%s/services", - idnode_uuid_as_str(&in->mn_id, ubuf1), - idnode_uuid_as_str(&im->mm_id, ubuf2)); + c = c2 = hts_settings_load_r(1, + "input/iptv/networks/%s/muxes/%s/services", + idnode_uuid_as_str(&in->mn_id, ubuf1), + idnode_uuid_as_str(&im->mm_id, ubuf2)); if (c) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; (void)iptv_service_create0(im, 0, 0, htsmsg_field_name(f), e); } } else if (in->in_service_id) { @@ -420,7 +366,7 @@ iptv_mux_create0 ( iptv_network_t *in, const char *uuid, htsmsg_t *conf ) htsmsg_destroy(conf); if (ms) { ms->s_components.set_pmt_pid = SERVICE_PMT_AUTO; - mpegts_network_bouquet_trigger((mpegts_network_t *)in, 0); + mpegts_network_bouquet_trigger((mpegts_network_t*)in, 0); } } htsmsg_destroy(c2); diff --git a/src/input/mpegts/iptv/iptv_pipe.c b/src/input/mpegts/iptv/iptv_pipe.c index 2a5e18790..ebcf780a0 100644 --- a/src/input/mpegts/iptv/iptv_pipe.c +++ b/src/input/mpegts/iptv/iptv_pipe.c @@ -31,14 +31,11 @@ /* * Spawn task and create pipes */ -static int -iptv_pipe_start - ( iptv_input_t *mi, iptv_mux_t *im, const char *raw, const url_t *url ) -{ - char **argv = NULL, **envp = NULL; - const char *replace[] = { "${service_name}", im->mm_iptv_svcname ?: "", NULL }; - int rd; - pid_t pid; +static int iptv_pipe_start(iptv_input_t* mi, iptv_mux_t* im, const char* raw, const url_t* url) { + char ** argv = NULL, **envp = NULL; + const char* replace[] = {"${service_name}", im->mm_iptv_svcname ?: "", NULL}; + int rd; + pid_t pid; if (strncmp(raw, "pipe://", 7)) goto err; @@ -63,7 +60,7 @@ iptv_pipe_start fcntl(rd, F_SETFL, fcntl(rd, F_GETFL) | O_NONBLOCK); im->mm_iptv_fd = rd; - im->im_data = (void *)(intptr_t)pid; + im->im_data = (void*)(intptr_t)pid; im->mm_iptv_respawn_last = mclk(); @@ -79,22 +76,17 @@ err: return -1; } -static void -iptv_pipe_stop - ( iptv_input_t *mi, iptv_mux_t *im ) -{ +static void iptv_pipe_stop(iptv_input_t* mi, iptv_mux_t* im) { pid_t pid = (intptr_t)im->im_data; spawn_kill(pid, tvh_kill_to_sig(im->mm_iptv_kill), im->mm_iptv_kill_timeout); iptv_input_close_fds(mi, im); } -static ssize_t -iptv_pipe_read ( iptv_input_t *mi, iptv_mux_t *im ) -{ - int r, rd = im->mm_iptv_fd; +static ssize_t iptv_pipe_read(iptv_input_t* mi, iptv_mux_t* im) { + int r, rd = im->mm_iptv_fd; ssize_t res = 0; - char buf[64*1024]; - pid_t pid; + char buf[64 * 1024]; + pid_t pid; while (rd > 0 && res < sizeof(buf)) { r = read(rd, buf, sizeof(buf)); @@ -106,12 +98,14 @@ iptv_pipe_read ( iptv_input_t *mi, iptv_mux_t *im ) } if (r <= 0) { iptv_input_close_fds(mi, im); - pid = (intptr_t)im->im_data; + pid = (intptr_t)im->im_data; im->im_data = NULL; spawn_kill(pid, tvh_kill_to_sig(im->mm_iptv_kill), im->mm_iptv_kill_timeout); if (mclk() < im->mm_iptv_respawn_last + sec2mono(2)) { - tvherror(LS_IPTV, "stdin pipe %d unexpectedly closed: %s", - rd, r < 0 ? strerror(errno) : "No data"); + tvherror(LS_IPTV, + "stdin pipe %d unexpectedly closed: %s", + rd, + r < 0 ? strerror(errno) : "No data"); } else { /* avoid deadlock here */ tvh_mutex_unlock(&iptv_lock); @@ -142,18 +136,14 @@ iptv_pipe_read ( iptv_input_t *mi, iptv_mux_t *im ) * Initialise pipe handler */ -void -iptv_pipe_init ( void ) -{ +void iptv_pipe_init(void) { static iptv_handler_t ih[] = { - { - .scheme = "pipe", - .buffer_limit = 5000, - .start = iptv_pipe_start, - .stop = iptv_pipe_stop, - .read = iptv_pipe_read, - .pause = iptv_input_pause_handler - }, + {.scheme = "pipe", + .buffer_limit = 5000, + .start = iptv_pipe_start, + .stop = iptv_pipe_stop, + .read = iptv_pipe_read, + .pause = iptv_input_pause_handler}, }; iptv_handler_register(ih, ARRAY_SIZE(ih)); } diff --git a/src/input/mpegts/iptv/iptv_private.h b/src/input/mpegts/iptv/iptv_private.h index c5dcf1367..8897d14ed 100644 --- a/src/input/mpegts/iptv/iptv_private.h +++ b/src/input/mpegts/iptv/iptv_private.h @@ -27,7 +27,7 @@ #include "tvhpoll.h" #include "profile.h" -#define IPTV_BUF_SIZE (2000*188) +#define IPTV_BUF_SIZE (2000 * 188) #define IPTV_PKTS 32 #define IPTV_PKT_PAYLOAD 1472 @@ -37,38 +37,35 @@ typedef struct iptv_mux iptv_mux_t; typedef struct iptv_service iptv_service_t; typedef struct iptv_handler iptv_handler_t; -struct iptv_handler -{ - const char *scheme; +struct iptv_handler { + const char* scheme; uint32_t buffer_limit; - int (*start) ( iptv_input_t *mi, iptv_mux_t *im, const char *raw, const url_t *url ); - void (*stop) ( iptv_input_t *mi, iptv_mux_t *im ); - ssize_t (*read) ( iptv_input_t *mi, iptv_mux_t *im ); - void (*pause) ( iptv_input_t *mi, iptv_mux_t *im, int pause ); - + int (*start)(iptv_input_t* mi, iptv_mux_t* im, const char* raw, const url_t* url); + void (*stop)(iptv_input_t* mi, iptv_mux_t* im); + ssize_t (*read)(iptv_input_t* mi, iptv_mux_t* im); + void (*pause)(iptv_input_t* mi, iptv_mux_t* im, int pause); + RB_ENTRY(iptv_handler) link; }; -void iptv_handler_register ( iptv_handler_t *ih, int num ); +void iptv_handler_register(iptv_handler_t* ih, int num); -struct iptv_input -{ +struct iptv_input { mpegts_input_t; - void *mi_tpool; + void* mi_tpool; }; -int iptv_input_fd_started ( iptv_input_t *mi, iptv_mux_t *im ); -void iptv_input_close_fds ( iptv_input_t *mi, iptv_mux_t *im ); -void iptv_input_mux_started ( iptv_input_t *mi, iptv_mux_t *im, int reset ); -int iptv_input_recv_packets ( iptv_mux_t *im, ssize_t len ); -void iptv_input_recv_flush ( iptv_mux_t *im ); -void iptv_input_pause_handler ( iptv_input_t *mi, iptv_mux_t *im, int pause ); +int iptv_input_fd_started(iptv_input_t* mi, iptv_mux_t* im); +void iptv_input_close_fds(iptv_input_t* mi, iptv_mux_t* im); +void iptv_input_mux_started(iptv_input_t* mi, iptv_mux_t* im, int reset); +int iptv_input_recv_packets(iptv_mux_t* im, ssize_t len); +void iptv_input_recv_flush(iptv_mux_t* im); +void iptv_input_pause_handler(iptv_input_t* mi, iptv_mux_t* im, int pause); -struct iptv_network -{ +struct iptv_network { mpegts_network_t; int in_bps; @@ -85,25 +82,25 @@ struct iptv_network uint32_t in_max_bandwidth; uint32_t in_max_timeout; - char *in_url; - char *in_url_sane; - char *in_ctx_charset; + char* in_url; + char* in_url_sane; + char* in_ctx_charset; int64_t in_channel_number; uint32_t in_refetch_period; - char *in_icon_url; - char *in_icon_url_sane; + char* in_icon_url; + char* in_icon_url_sane; int in_ssl_peer_verify; - char *in_remove_args; - char *in_ignore_args; + char* in_remove_args; + char* in_ignore_args; int in_ignore_path; int in_tsid_accept_zero_value; int in_libav; int64_t in_bandwidth_clock; - void *in_auto; /* private structure for auto-network */ + void* in_auto; /* private structure for auto-network */ }; -iptv_network_t *iptv_network_create0 ( const char *uuid, htsmsg_t *conf, const idclass_t *idc ); +iptv_network_t* iptv_network_create0(const char* uuid, htsmsg_t* conf, const idclass_t* idc); typedef struct { /* Last transmitted packet timestamp */ @@ -122,139 +119,138 @@ typedef struct { uint16_t nak_req_limit; /* Connection to the RTCP remote */ - udp_connection_t *connection; - int connection_fd; - udp_multirecv_t um; + udp_connection_t* connection; + int connection_fd; + udp_multirecv_t um; uint32_t source_ssrc; uint32_t my_ssrc; } rtcp_t; -struct iptv_mux -{ +struct iptv_mux { mpegts_mux_t; - int mm_iptv_priority; - int mm_iptv_streaming_priority; - int mm_iptv_fd; - udp_connection_t *mm_iptv_connection; - char *mm_iptv_url; - char *mm_iptv_url_sane; - char *mm_iptv_url_raw; - char *mm_iptv_url_cmpid; - char *mm_iptv_ret_url; - char *mm_iptv_ret_url_sane; - char *mm_iptv_ret_url_raw; - char *mm_iptv_ret_url_cmpid; - char *mm_iptv_interface; - - int mm_iptv_send_reports; - int mm_iptv_substitute; - int mm_iptv_libav; - int mm_iptv_atsc; - - char *mm_iptv_muxname; - char *mm_iptv_svcname; - int64_t mm_iptv_chnum; - char *mm_iptv_icon; - char *mm_iptv_epgid; - - int mm_iptv_respawn; - int64_t mm_iptv_respawn_last; - int mm_iptv_kill; - int mm_iptv_kill_timeout; - char *mm_iptv_env; - char *mm_iptv_hdr; - char *mm_iptv_tags; - uint32_t mm_iptv_satip_dvbt_freq; - uint32_t mm_iptv_satip_dvbc_freq; - uint32_t mm_iptv_satip_dvbs_freq; - - uint32_t mm_iptv_rtp_seq; - - sbuf_t mm_iptv_buffer; - sbuf_t im_temp_buffer; - - uint32_t mm_iptv_buffer_limit; - - iptv_handler_t *im_handler; - mtimer_t im_pause_timer; - - int64_t im_pcr; - int64_t im_pcr_start; - int64_t im_pcr_end; - uint16_t im_pcr_pid; - - void *im_data; - - int im_delete_flag; - - void *im_opaque; - - udp_multirecv_t im_um; - - char im_use_retransmission; - char im_is_ce_detected; - - rtcp_t im_rtcp_info; + int mm_iptv_priority; + int mm_iptv_streaming_priority; + int mm_iptv_fd; + udp_connection_t* mm_iptv_connection; + char* mm_iptv_url; + char* mm_iptv_url_sane; + char* mm_iptv_url_raw; + char* mm_iptv_url_cmpid; + char* mm_iptv_ret_url; + char* mm_iptv_ret_url_sane; + char* mm_iptv_ret_url_raw; + char* mm_iptv_ret_url_cmpid; + char* mm_iptv_interface; + + int mm_iptv_send_reports; + int mm_iptv_substitute; + int mm_iptv_libav; + int mm_iptv_atsc; + + char* mm_iptv_muxname; + char* mm_iptv_svcname; + int64_t mm_iptv_chnum; + char* mm_iptv_icon; + char* mm_iptv_epgid; + + int mm_iptv_respawn; + int64_t mm_iptv_respawn_last; + int mm_iptv_kill; + int mm_iptv_kill_timeout; + char* mm_iptv_env; + char* mm_iptv_hdr; + char* mm_iptv_tags; + uint32_t mm_iptv_satip_dvbt_freq; + uint32_t mm_iptv_satip_dvbc_freq; + uint32_t mm_iptv_satip_dvbs_freq; + + uint32_t mm_iptv_rtp_seq; + + sbuf_t mm_iptv_buffer; + sbuf_t im_temp_buffer; + + uint32_t mm_iptv_buffer_limit; + + iptv_handler_t* im_handler; + mtimer_t im_pause_timer; + + int64_t im_pcr; + int64_t im_pcr_start; + int64_t im_pcr_end; + uint16_t im_pcr_pid; + + void* im_data; + + int im_delete_flag; + + void* im_opaque; + + udp_multirecv_t im_um; + + char im_use_retransmission; + char im_is_ce_detected; + + rtcp_t im_rtcp_info; }; -iptv_mux_t* iptv_mux_create0 - ( iptv_network_t *in, const char *uuid, htsmsg_t *conf ); +iptv_mux_t* iptv_mux_create0(iptv_network_t* in, const char* uuid, htsmsg_t* conf); -struct iptv_service -{ +struct iptv_service { mpegts_service_t; - char * s_iptv_svcname; + char* s_iptv_svcname; }; -iptv_service_t *iptv_service_create0 - ( iptv_mux_t *im, uint16_t sid, uint16_t pmt_pid, - const char *uuid, htsmsg_t *conf ); +iptv_service_t* iptv_service_create0(iptv_mux_t* im, + uint16_t sid, + uint16_t pmt_pid, + const char* uuid, + htsmsg_t* conf); extern const idclass_t iptv_network_class; extern const idclass_t iptv_auto_network_class; extern const idclass_t iptv_mux_class; -extern iptv_network_t *iptv_network; +extern iptv_network_t* iptv_network; extern tvh_mutex_t iptv_lock; -int iptv_url_set ( char **url, char **sane_url, const char *str, int allow_file, int allow_pipe ); +int iptv_url_set(char** url, char** sane_url, const char* str, int allow_file, int allow_pipe); -void iptv_mux_load_all ( void ); +void iptv_mux_load_all(void); -void iptv_auto_network_trigger( iptv_network_t *in ); -void iptv_auto_network_init( iptv_network_t *in ); -void iptv_auto_network_done( iptv_network_t *in ); +void iptv_auto_network_trigger(iptv_network_t* in); +void iptv_auto_network_init(iptv_network_t* in); +void iptv_auto_network_done(iptv_network_t* in); -void iptv_http_init ( void ); -void iptv_udp_init ( void ); -void iptv_rtsp_init ( void ); -void iptv_pipe_init ( void ); -void iptv_file_init ( void ); -void iptv_libav_init ( void ); +void iptv_http_init(void); +void iptv_udp_init(void); +void iptv_rtsp_init(void); +void iptv_pipe_init(void); +void iptv_file_init(void); +void iptv_libav_init(void); -ssize_t iptv_rtp_read(iptv_mux_t *im, void (*pkt_cb)(iptv_mux_t *im, uint8_t *buf, int len)); +ssize_t iptv_rtp_read(iptv_mux_t* im, void (*pkt_cb)(iptv_mux_t* im, uint8_t* buf, int len)); -void iptv_input_unpause ( void *aux ); +void iptv_input_unpause(void* aux); struct rtsp_st { // Note: input MUST BE FIRST in struct - streaming_target_t input; ///< Input source - streaming_target_t *output; ///< Output dest - streaming_target_t *tsfix; - pthread_t st_thread; - volatile int run; - volatile int rtsp_input_start; - iptv_mux_t *im; + streaming_target_t input; ///< Input source + streaming_target_t* output; ///< Output dest + streaming_target_t* tsfix; + pthread_t st_thread; + volatile int run; + volatile int rtsp_input_start; + iptv_mux_t* im; }; typedef struct rtsp_st rtsp_st_t; #if ENABLE_TIMESHIFT -void *rtsp_status_thread(void *p) ; -streaming_target_t* rtsp_st_create(streaming_target_t *out, profile_chain_t *prch); -void rtsp_st_destroy(streaming_target_t *st); +void* rtsp_status_thread(void* p); +streaming_target_t* rtsp_st_create(streaming_target_t* out, profile_chain_t* prch); +void rtsp_st_destroy(streaming_target_t* st); #endif #endif /* __IPTV_PRIVATE_H__ */ diff --git a/src/input/mpegts/iptv/iptv_rtcp.c b/src/input/mpegts/iptv/iptv_rtcp.c index 5370dc0b9..e293a8f61 100644 --- a/src/input/mpegts/iptv/iptv_rtcp.c +++ b/src/input/mpegts/iptv/iptv_rtcp.c @@ -32,41 +32,41 @@ Part of RFC 3350. Used to send SDES data */ -static char * -rtp_write_sdes(char *b, u_int32_t src, int argc, - rtcp_sdes_type_t type[], char *value[], - int length[]) -{ - rtcp_sdes_t *s = (rtcp_sdes_t *) b; - rtcp_sdes_item_t *rsp; - int i; - int len; - int pad; +static char* rtp_write_sdes(char* b, + u_int32_t src, + int argc, + rtcp_sdes_type_t type[], + char* value[], + int length[]) { + rtcp_sdes_t* s = (rtcp_sdes_t*)b; + rtcp_sdes_item_t* rsp; + int i; + int len; + int pad; /* SSRC header */ s->src = src; - rsp = &s->item[0]; + rsp = &s->item[0]; /* SDES items */ - for (i = 0; i < argc; i++) - { + for (i = 0; i < argc; i++) { rsp->type = type[i]; - len = length[i]; - if (len > RTP_MAX_SDES) - { + len = length[i]; + if (len > RTP_MAX_SDES) { /* invalid length, may want to take other action */ len = RTP_MAX_SDES; } rsp->length = len; memcpy(rsp->data, value[i], len); - rsp = (rtcp_sdes_item_t *) & rsp->data[len]; + rsp = (rtcp_sdes_item_t*)&rsp->data[len]; } /* terminate with end marker and pad to next 4-octet boundary */ - len = ((char *) rsp) - b; + len = ((char*)rsp) - b; pad = 4 - (len & 0x3); - b = (char *) rsp; - while (pad--) *b++ = RTCP_SDES_END; + b = (char*)rsp; + while (pad--) + *b++ = RTCP_SDES_END; return b; } @@ -103,9 +103,12 @@ rtp_write_sdes(char *b, u_int32_t src, int argc, initial: Flag that is true if the application has not yet sent an RTCP packet. */ -static double -rtcp_interval(int members, int senders, double rtcp_bw, int we_sent, double avg_rtcp_size, int initial) -{ +static double rtcp_interval(int members, + int senders, + double rtcp_bw, + int we_sent, + double avg_rtcp_size, + int initial) { /* * Minimum average time between RTCP packets from this site (in * seconds). This time prevents the reports from `clumping' when @@ -115,7 +118,7 @@ rtcp_interval(int members, int senders, double rtcp_bw, int we_sent, double avg_ * a network partition. */ double const RTCP_MIN_TIME = 5.; - + /* * Fraction of the RTCP bandwidth to be shared among active * senders. (This fraction was chosen so that in a typical @@ -125,16 +128,16 @@ rtcp_interval(int members, int senders, double rtcp_bw, int we_sent, double avg_ * receiver fraction must be 1 - the sender fraction. */ double const RTCP_SENDER_BW_FRACTION = 0.25; - double const RTCP_RCVR_BW_FRACTION = (1 - RTCP_SENDER_BW_FRACTION); - + double const RTCP_RCVR_BW_FRACTION = (1 - RTCP_SENDER_BW_FRACTION); + /* To compensate for "timer reconsideration" converging to a * value below the intended average. */ double const COMPENSATION = 2.71828 - 1.5; - double t; /* interval */ + double t; /* interval */ double rtcp_min_time = RTCP_MIN_TIME; - int n; /* no. of members for computation */ + int n; /* no. of members for computation */ /* * Very first call at application start-up uses half the min @@ -143,8 +146,7 @@ rtcp_interval(int members, int senders, double rtcp_bw, int we_sent, double avg_ * sources so the report interval will converge to the correct * interval more quickly. */ - if (initial) - { + if (initial) { rtcp_min_time /= 2; } /* @@ -153,14 +155,11 @@ rtcp_interval(int members, int senders, double rtcp_bw, int we_sent, double avg_ * more than that fraction. */ n = members; - if (senders <= members * RTCP_SENDER_BW_FRACTION) - { - if (we_sent) - { + if (senders <= members * RTCP_SENDER_BW_FRACTION) { + if (we_sent) { rtcp_bw *= RTCP_SENDER_BW_FRACTION; n = senders; - } else - { + } else { rtcp_bw *= RTCP_RCVR_BW_FRACTION; n -= senders; } @@ -176,7 +175,8 @@ rtcp_interval(int members, int senders, double rtcp_bw, int we_sent, double avg_ * average time between reports. */ t = avg_rtcp_size * n / rtcp_bw; - if (t < rtcp_min_time) t = rtcp_min_time; + if (t < rtcp_min_time) + t = rtcp_min_time; /* * To avoid traffic bursts from unintended synchronization with @@ -192,12 +192,10 @@ rtcp_interval(int members, int senders, double rtcp_bw, int we_sent, double avg_ Append RTCP header data to the buffer. Version and padding are set to fixed values, i.e. 2 and 0; */ -static void -rtcp_append_headers(sbuf_t *buffer, rtcp_header_t *packet) -{ - uint8_t byte = 0; +static void rtcp_append_headers(sbuf_t* buffer, rtcp_header_t* packet) { + uint8_t byte = 0; packet->version = 2; - packet->p = 0; + packet->p = 0; byte |= packet->version << 6; byte |= packet->p << 5; @@ -211,17 +209,15 @@ rtcp_append_headers(sbuf_t *buffer, rtcp_header_t *packet) /* Append RTCP receiver report data to the buffer. */ -static void -rtcp_append_rr(sbuf_t *buffer, rtcp_rr_t *packet) -{ - uint8_t byte = 0; +static void rtcp_append_rr(sbuf_t* buffer, rtcp_rr_t* packet) { + uint8_t byte = 0; rtcp_rr_block_t report = packet->rr[0]; - + sbuf_append(buffer, &packet->ssrc, sizeof(packet->ssrc)); sbuf_append(buffer, &report.ssrc, sizeof(report.ssrc)); byte = report.fraction; sbuf_put_byte(buffer, byte); - + // Set the lost number in 3 times byte = (report.lost & 0xff0000) >> 16; sbuf_put_byte(buffer, byte); @@ -229,7 +225,7 @@ rtcp_append_rr(sbuf_t *buffer, rtcp_rr_t *packet) sbuf_put_byte(buffer, byte); byte = report.lost & 0x0000ff; sbuf_put_byte(buffer, byte); - + sbuf_append(buffer, &report.last_seq, sizeof(report.last_seq)); sbuf_append(buffer, &report.jitter, sizeof(report.jitter)); sbuf_append(buffer, &report.lsr, sizeof(report.lsr)); @@ -239,9 +235,7 @@ rtcp_append_rr(sbuf_t *buffer, rtcp_rr_t *packet) /* Append RTCP NAK data to the buffer. */ -static void -rtcp_append_nak(sbuf_t *buffer, rtcp_gf_t *packet) -{ +static void rtcp_append_nak(sbuf_t* buffer, rtcp_gf_t* packet) { sbuf_append(buffer, &packet->my_ssrc, sizeof(packet->my_ssrc)); sbuf_append(buffer, &packet->ssrc, sizeof(packet->ssrc)); sbuf_append(buffer, &packet->pid, sizeof(packet->pid)); @@ -251,26 +245,22 @@ rtcp_append_nak(sbuf_t *buffer, rtcp_gf_t *packet) /* Just send the buffer to the host in the rtcp_info. */ -static void -rtcp_send(rtcp_t *info, sbuf_t *buffer) -{ +static void rtcp_send(rtcp_t* info, sbuf_t* buffer) { tvhdebug(LS_IPTV, "RTCP: Sending receiver report"); // We don't care of the result right now - udp_write(info->connection, buffer->sb_data, buffer->sb_ptr, & info->connection->peer); + udp_write(info->connection, buffer->sb_data, buffer->sb_ptr, &info->connection->peer); } /* Send a complete receiver report (RR). It uses the actual informations stored in rtcp_info. */ -static void -rtcp_send_rr(rtcp_t *info) -{ +static void rtcp_send_rr(rtcp_t* info) { rtcp_rr_block_t report; - rtcp_header_t header; - rtcp_rr_t packet; + rtcp_header_t header; + rtcp_rr_t packet; report.ssrc = htonl(info->source_ssrc); - + // Fill in the extended last sequence union { uint16_t buffer[2]; @@ -279,48 +269,46 @@ rtcp_send_rr(rtcp_t *info) join2.buffer[0] = htons(info->sequence_cycle); join2.buffer[1] = htons(info->last_received_sequence); report.last_seq = join2.result; - + // We don't compute this for now report.fraction = 0; - report.lost = -1; - report.lsr = htonl(0); - report.dlsr = htonl(0); - + report.lost = -1; + report.lsr = htonl(0); + report.dlsr = htonl(0); + // TODO: see how to put something meaningful report.jitter = htonl(12); - + // Build the full packet - header.pt = RTCP_RR; + header.pt = RTCP_RR; header.count = 1; // TODO : set the real length header.length = htons(7); - packet.ssrc = htonl(info->my_ssrc); - packet.rr[0] = report; - + packet.ssrc = htonl(info->my_ssrc); + packet.rr[0] = report; + // Build the network packet sbuf_t network_buffer; sbuf_init(&network_buffer); rtcp_append_headers(&network_buffer, &header); rtcp_append_rr(&network_buffer, &packet); - + // Send it rtcp_send(info, &network_buffer); - + // TODO : send also the SDES CNAME packet - + // Cleanup sbuf_free(&network_buffer); } -ssize_t -rtcp_send_nak(rtcp_t *rtcp_info, uint32_t ssrc, uint16_t seqn, uint16_t len) -{ - rtcp_header_t rtcp_header; - rtcp_gf_t rtcp_data; - sbuf_t network_buffer; - uint32_t n; - uint16_t blp = 0; - udp_connection_t *uc = rtcp_info->connection; +ssize_t rtcp_send_nak(rtcp_t* rtcp_info, uint32_t ssrc, uint16_t seqn, uint16_t len) { + rtcp_header_t rtcp_header; + rtcp_gf_t rtcp_data; + sbuf_t network_buffer; + uint32_t n; + uint16_t blp = 0; + udp_connection_t* uc = rtcp_info->connection; if (len > rtcp_info->nak_req_limit) { seqn += len - rtcp_info->nak_req_limit; @@ -328,19 +316,21 @@ rtcp_send_nak(rtcp_t *rtcp_info, uint32_t ssrc, uint16_t seqn, uint16_t len) } tvhinfo(LS_IPTV, "RTCP: Sending NAK report for SSRC 0x%x, missing: %d, following packets: %d", - ssrc, seqn, len - 1); + ssrc, + seqn, + len - 1); rtcp_info->last_received_sequence = seqn; - rtcp_info->ce_cnt = len; + rtcp_info->ce_cnt = len; // Build the full packet rtcp_header.version = 2; - rtcp_header.p = 0; - rtcp_header.count = 1; // Generic NAK - rtcp_header.pt = RTCP_GF; - rtcp_header.length = htons(3); - rtcp_data.my_ssrc = 0; - rtcp_data.ssrc = htonl(ssrc); + rtcp_header.p = 0; + rtcp_header.count = 1; // Generic NAK + rtcp_header.pt = RTCP_GF; + rtcp_header.length = htons(3); + rtcp_data.my_ssrc = 0; + rtcp_data.ssrc = htonl(ssrc); while (len > 0) { len--; @@ -368,7 +358,9 @@ rtcp_send_nak(rtcp_t *rtcp_info, uint32_t ssrc, uint16_t seqn, uint16_t len) if (n) { tvhwarn(LS_IPTV, "RTCP: Sending NAK report for SSRC 0x%x failed, no data send %d %d", - ssrc, n, (uint32_t )sizeof(network_buffer)); + ssrc, + n, + (uint32_t)sizeof(network_buffer)); } // Cleanup @@ -377,29 +369,24 @@ rtcp_send_nak(rtcp_t *rtcp_info, uint32_t ssrc, uint16_t seqn, uint16_t len) return 0; } -int -rtcp_connect(rtcp_t * info, char *url, char *host, int port, char *interface, char *nicename) -{ - udp_connection_t *rtcp_conn; - url_t rtcp_url; +int rtcp_connect(rtcp_t* info, char* url, char* host, int port, char* interface, char* nicename) { + udp_connection_t* rtcp_conn; + url_t rtcp_url; if (info->connection == NULL) { - rtcp_conn = udp_bind(LS_IPTV, nicename, NULL, 0, NULL, interface, - IPTV_BUF_SIZE, 1024); + rtcp_conn = udp_bind(LS_IPTV, nicename, NULL, 0, NULL, interface, IPTV_BUF_SIZE, 1024); if (rtcp_conn == NULL || rtcp_conn == UDP_FATAL_ERROR) { - tvhwarn(LS_IPTV, "%s - Unable to bind, RTCP won't be available", - nicename); + tvhwarn(LS_IPTV, "%s - Unable to bind, RTCP won't be available", nicename); return -1; } info->connection_fd = rtcp_conn->fd; - info->connection = rtcp_conn; + info->connection = rtcp_conn; } urlinit(&rtcp_url); if (host == NULL) { - if (urlparse(url ? : "", &rtcp_url)) { - tvhwarn(LS_IPTV, "%s - invalid RTCP URL, should be rtp://HOST:PORT [%s]", - nicename, url); + if (urlparse(url ?: "", &rtcp_url)) { + tvhwarn(LS_IPTV, "%s - invalid RTCP URL, should be rtp://HOST:PORT [%s]", nicename, url); goto fail; } host = rtcp_url.host; @@ -407,8 +394,7 @@ rtcp_connect(rtcp_t * info, char *url, char *host, int port, char *interface, ch } if (udp_connect(info->connection, "rtcp", host, port)) { - tvhwarn(LS_IPTV, "%s - Unable to connect, RTCP won't be available", - nicename); + tvhwarn(LS_IPTV, "%s - Unable to connect, RTCP won't be available", nicename); goto fail; } urlreset(&rtcp_url); @@ -418,70 +404,67 @@ fail: return -1; } -int -rtcp_init(rtcp_t * info) -{ - info->last_ts = 0; - info->next_ts = 0; - info->members = 2; - info->senders = 1; +int rtcp_init(rtcp_t* info) { + info->last_ts = 0; + info->next_ts = 0; + info->members = 2; + info->senders = 1; info->last_received_sequence = 0; - info->sequence_cycle = 1; - info->source_ssrc = 0; - info->average_packet_size = 52; - info->my_ssrc = 0; // Since we are not transmitting, set this to 0 - info->nak_req_limit = 128; // This appears to be a safe limit - + info->sequence_cycle = 1; + info->source_ssrc = 0; + info->average_packet_size = 52; + info->my_ssrc = 0; // Since we are not transmitting, set this to 0 + info->nak_req_limit = 128; // This appears to be a safe limit + return 0; } -int -rtcp_destroy(rtcp_t *info) -{ +int rtcp_destroy(rtcp_t* info) { return 0; } /* * Buffer is a raw RTP buffer */ -int -rtcp_receiver_update(rtcp_t *info, uint8_t *buffer) -{ +int rtcp_receiver_update(rtcp_t* info, uint8_t* buffer) { union { - uint8_t bytes[2]; + uint8_t bytes[2]; uint16_t n; } join2; - join2.bytes[0] = buffer[2]; - join2.bytes[1] = buffer[3]; + join2.bytes[0] = buffer[2]; + join2.bytes[1] = buffer[3]; int new_sequence = ntohs(join2.n); - - if(new_sequence < info->last_received_sequence) - { + + if (new_sequence < info->last_received_sequence) { ++info->sequence_cycle; } info->last_received_sequence = new_sequence; union { - uint8_t bytes[4]; + uint8_t bytes[4]; uint32_t n; } join4; - join4.bytes[0] = buffer[8]; - join4.bytes[1] = buffer[9]; - join4.bytes[2] = buffer[10]; - join4.bytes[3] = buffer[11]; + join4.bytes[0] = buffer[8]; + join4.bytes[1] = buffer[9]; + join4.bytes[2] = buffer[10]; + join4.bytes[3] = buffer[11]; info->source_ssrc = ntohl(join4.n); - + time_t current_time = time(NULL); - if(info->next_ts < current_time) - { + if (info->next_ts < current_time) { // Re-send rtcp_send_rr(info); - + // Re-schedule - double interval = rtcp_interval(info->members, info->senders, 12, 0, info->average_packet_size, info->last_ts == 0); - info->next_ts = current_time + interval; - info->last_ts = current_time; + double interval = rtcp_interval(info->members, + info->senders, + 12, + 0, + info->average_packet_size, + info->last_ts == 0); + info->next_ts = current_time + interval; + info->last_ts = current_time; } - + return 0; } diff --git a/src/input/mpegts/iptv/iptv_rtcp.h b/src/input/mpegts/iptv/iptv_rtcp.h index 7a166a76f..f47499587 100644 --- a/src/input/mpegts/iptv/iptv_rtcp.h +++ b/src/input/mpegts/iptv/iptv_rtcp.h @@ -17,7 +17,7 @@ */ #ifndef RTCP_H -#define RTCP_H +#define RTCP_H #include "iptv_private.h" #include "udp.h" @@ -25,13 +25,12 @@ /* * Current protocol version. */ -#define RTP_VERSION 2 +#define RTP_VERSION 2 -#define RTP_SEQ_MOD (1<<16) -#define RTP_MAX_SDES 255 /* maximum text length for SDES */ +#define RTP_SEQ_MOD (1 << 16) +#define RTP_MAX_SDES 255 /* maximum text length for SDES */ -typedef enum -{ +typedef enum { RTCP_SR = 200, RTCP_RR = 201, RTCP_SDES = 202, @@ -40,8 +39,7 @@ typedef enum RTCP_GF = 205 } rtcp_type_t; -typedef enum -{ +typedef enum { RTCP_SDES_END = 0, RTCP_SDES_CNAME = 1, RTCP_SDES_NAME = 2, @@ -56,73 +54,64 @@ typedef enum /* * RTCP common header word */ -typedef struct -{ - unsigned int version : 2; /* protocol version */ - unsigned int p : 1; /* padding flag */ - unsigned int count : 5; /* varies by packet type */ - unsigned int pt : 8; /* RTCP packet type */ - uint16_t length; /* pkt len in words, w/o this word */ +typedef struct { + unsigned int version : 2; /* protocol version */ + unsigned int p : 1; /* padding flag */ + unsigned int count : 5; /* varies by packet type */ + unsigned int pt : 8; /* RTCP packet type */ + uint16_t length; /* pkt len in words, w/o this word */ } rtcp_header_t; - /* * Big-endian mask for version, padding bit and packet type pair */ -#define RTCP_VALID_MASK (0xc000 | 0x2000 | 0xfe) +#define RTCP_VALID_MASK (0xc000 | 0x2000 | 0xfe) #define RTCP_VALID_VALUE ((RTP_VERSION << 14) | RTCP_SR) /* * Reception report block */ -typedef struct -{ - uint32_t ssrc; /* data source being reported */ - unsigned int fraction : 8; /* fraction lost since last SR/RR */ - - int lost : 24; /* cumul. no. pkts lost (signed!) */ - uint32_t last_seq; /* extended last seq. no. received */ - uint32_t jitter; /* interarrival jitter */ - uint32_t lsr; /* last SR packet from this source */ - uint32_t dlsr; /* delay since last SR packet */ +typedef struct { + uint32_t ssrc; /* data source being reported */ + unsigned int fraction : 8; /* fraction lost since last SR/RR */ + + int lost : 24; /* cumul. no. pkts lost (signed!) */ + uint32_t last_seq; /* extended last seq. no. received */ + uint32_t jitter; /* interarrival jitter */ + uint32_t lsr; /* last SR packet from this source */ + uint32_t dlsr; /* delay since last SR packet */ } rtcp_rr_block_t; - - /* * Generic RTC Feedback block */ -typedef struct -{ - uint32_t my_ssrc; /* not used */ - uint32_t ssrc; /* data source being reported */ - uint16_t pid; /* first missing frame id */ - uint16_t blp; /* missing frame count */ +typedef struct { + uint32_t my_ssrc; /* not used */ + uint32_t ssrc; /* data source being reported */ + uint16_t pid; /* first missing frame id */ + uint16_t blp; /* missing frame count */ } rtcp_gf_t; /* * SDES item */ -typedef struct -{ - u_int8_t type; /* type of item (rtcp_sdes_type_t) */ - u_int8_t length; /* length of item (in octets) */ - char data[1]; /* text, not null-terminated */ +typedef struct { + u_int8_t type; /* type of item (rtcp_sdes_type_t) */ + u_int8_t length; /* length of item (in octets) */ + char data[1]; /* text, not null-terminated */ } rtcp_sdes_item_t; -typedef struct rtcp_sdes -{ - uint32_t src; /* first SSRC/CSRC */ +typedef struct rtcp_sdes { + uint32_t src; /* first SSRC/CSRC */ rtcp_sdes_item_t item[1]; /* list of SDES items */ } rtcp_sdes_t; /* * reception report (RR) */ -typedef struct -{ - uint32_t ssrc; /* receiver generating this report */ - rtcp_rr_block_t rr[1]; /* variable-length list */ +typedef struct { + uint32_t ssrc; /* receiver generating this report */ + rtcp_rr_block_t rr[1]; /* variable-length list */ } rtcp_rr_t; /* @@ -130,19 +119,18 @@ typedef struct Return 0 if everything was OK. rtcp_destroy must be called when rtsp_info is destroyed. */ -int rtcp_init(rtcp_t *info); +int rtcp_init(rtcp_t* info); /* Destroy rtcp_info field of rtsp_info. */ -int rtcp_destroy(rtcp_t *info); +int rtcp_destroy(rtcp_t* info); /* Update RTCP informations. It can also send a RTCP RR packet if the timer has expired. */ -int rtcp_receiver_update(rtcp_t *info, uint8_t *rtp_packet); -ssize_t rtcp_send_nak(rtcp_t *rtcp_info, uint32_t ssrc, uint16_t seqn, uint16_t len); -int rtcp_connect(rtcp_t * info, char *url, char *host, int port, char *interface, char *nicename); -#endif /* IPTV_RTCP_H */ - +int rtcp_receiver_update(rtcp_t* info, uint8_t* rtp_packet); +ssize_t rtcp_send_nak(rtcp_t* rtcp_info, uint32_t ssrc, uint16_t seqn, uint16_t len); +int rtcp_connect(rtcp_t* info, char* url, char* host, int port, char* interface, char* nicename); +#endif /* IPTV_RTCP_H */ diff --git a/src/input/mpegts/iptv/iptv_rtsp.c b/src/input/mpegts/iptv/iptv_rtsp.c index 66d83c2c7..ac35879f3 100644 --- a/src/input/mpegts/iptv/iptv_rtsp.c +++ b/src/input/mpegts/iptv/iptv_rtsp.c @@ -26,57 +26,53 @@ #endif typedef struct { - http_client_t *hc; - char *path; - char *query; - mtimer_t alive_timer; - int play; - time_t start_position; - time_t range_start; - time_t range_end; - time_t position; + http_client_t* hc; + char* path; + char* query; + mtimer_t alive_timer; + int play; + time_t start_position; + time_t range_start; + time_t range_end; + time_t position; } rtsp_priv_t; /* * */ -static void -iptv_rtsp_close_cb ( void *aux ) -{ - http_client_close((http_client_t *)aux); +static void iptv_rtsp_close_cb(void* aux) { + http_client_close((http_client_t*)aux); } /* * Alive timeout */ -static void -iptv_rtsp_alive_cb ( void *aux ) -{ - iptv_mux_t *im = aux; - rtsp_priv_t *rp = im->im_data; - if(rp->hc->hc_rtsp_keep_alive_cmd == RTSP_CMD_GET_PARAMETER) +static void iptv_rtsp_alive_cb(void* aux) { + iptv_mux_t* im = aux; + rtsp_priv_t* rp = im->im_data; + if (rp->hc->hc_rtsp_keep_alive_cmd == RTSP_CMD_GET_PARAMETER) rtsp_get_parameter(rp->hc, "position"); - else if(rp->hc->hc_rtsp_keep_alive_cmd == RTSP_CMD_OPTIONS) + else if (rp->hc->hc_rtsp_keep_alive_cmd == RTSP_CMD_OPTIONS) rtsp_send(rp->hc, RTSP_CMD_OPTIONS, rp->path, rp->query, NULL); - else if(rp->hc->hc_rtsp_keep_alive_cmd == RTSP_CMD_DESCRIBE) { + else if (rp->hc->hc_rtsp_keep_alive_cmd == RTSP_CMD_DESCRIBE) { rtsp_send(rp->hc, RTSP_CMD_DESCRIBE, rp->path, rp->query, NULL); rtsp_get_parameter(rp->hc, "position"); } else return; - mtimer_arm_rel(&rp->alive_timer, iptv_rtsp_alive_cb, im, - sec2mono(MAX(1, (rp->hc->hc_rtp_timeout / 2) - 1))); + mtimer_arm_rel(&rp->alive_timer, + iptv_rtsp_alive_cb, + im, + sec2mono(MAX(1, (rp->hc->hc_rtp_timeout / 2) - 1))); } /* * Connected */ -static int -iptv_rtsp_header ( http_client_t *hc ) -{ - iptv_mux_t *im = hc->hc_aux; - rtsp_priv_t *rp; - int r; - char *p; +static int iptv_rtsp_header(http_client_t* hc) { + iptv_mux_t* im = hc->hc_aux; + rtsp_priv_t* rp; + int r; + char* p; if (im == NULL) { /* teardown (or teardown timeout) */ @@ -89,8 +85,11 @@ iptv_rtsp_header ( http_client_t *hc ) } if (hc->hc_cmd == RTSP_CMD_GET_PARAMETER && hc->hc_code != HTTP_STATUS_OK) { - tvhtrace(LS_IPTV, "GET_PARAMETER command returned invalid error code %d for '%s', " - "fall back to OPTIONS in keep alive loop.", hc->hc_code, im->mm_iptv_url_raw); + tvhtrace(LS_IPTV, + "GET_PARAMETER command returned invalid error code %d for '%s', " + "fall back to OPTIONS in keep alive loop.", + hc->hc_code, + im->mm_iptv_url_raw); hc->hc_rtsp_keep_alive_cmd = RTSP_CMD_OPTIONS; return 0; } @@ -101,87 +100,103 @@ iptv_rtsp_header ( http_client_t *hc ) } if (hc->hc_cmd == RTSP_CMD_DESCRIBE && hc->hc_code != HTTP_STATUS_OK && - !(hc->hc_code == HTTP_STATUS_MOVED || - hc->hc_code == HTTP_STATUS_FOUND || - hc->hc_code == HTTP_STATUS_SEE_OTHER || - hc->hc_code == HTTP_STATUS_NOT_MODIFIED)) { - tvherror(LS_IPTV, "DESCRIBE request returned an invalid error code (%d) for '%s', " - "fall back to GET_PARAMETER in keep alive loop.", hc->hc_code, im->mm_iptv_url_raw); + !(hc->hc_code == HTTP_STATUS_MOVED || hc->hc_code == HTTP_STATUS_FOUND || + hc->hc_code == HTTP_STATUS_SEE_OTHER || hc->hc_code == HTTP_STATUS_NOT_MODIFIED)) { + tvherror(LS_IPTV, + "DESCRIBE request returned an invalid error code (%d) for '%s', " + "fall back to GET_PARAMETER in keep alive loop.", + hc->hc_code, + im->mm_iptv_url_raw); hc->hc_rtsp_keep_alive_cmd = RTSP_CMD_GET_PARAMETER; return 0; } rp = im->im_data; - if(rp == NULL) + if (rp == NULL) return 0; switch (hc->hc_cmd) { - case RTSP_CMD_DESCRIBE: - if (rp->play) { - // Already active, most probably a keep-alive response - break; - } - if (hc->hc_code == HTTP_STATUS_MOVED || - hc->hc_code == HTTP_STATUS_FOUND || - hc->hc_code == HTTP_STATUS_SEE_OTHER || - hc->hc_code == HTTP_STATUS_NOT_MODIFIED) { - // Redirect from RTSP server - if (!hc->hc_handle_location) { - tvherror(LS_IPTV, "received code %d from RTSP server but redirects disabled '%s'", - hc->hc_code, im->mm_iptv_url_raw); - return -1; + case RTSP_CMD_DESCRIBE: + if (rp->play) { + // Already active, most probably a keep-alive response + break; } - p = http_arg_get(&hc->hc_args, "Location"); - if (p == NULL) { - tvherror(LS_IPTV, "received code %d from RTSP server but no new location given for '%s'", - hc->hc_code, im->mm_iptv_url_raw); - return -1; + if (hc->hc_code == HTTP_STATUS_MOVED || hc->hc_code == HTTP_STATUS_FOUND || + hc->hc_code == HTTP_STATUS_SEE_OTHER || hc->hc_code == HTTP_STATUS_NOT_MODIFIED) { + // Redirect from RTSP server + if (!hc->hc_handle_location) { + tvherror(LS_IPTV, + "received code %d from RTSP server but redirects disabled '%s'", + hc->hc_code, + im->mm_iptv_url_raw); + return -1; + } + p = http_arg_get(&hc->hc_args, "Location"); + if (p == NULL) { + tvherror(LS_IPTV, + "received code %d from RTSP server but no new location given for '%s'", + hc->hc_code, + im->mm_iptv_url_raw); + return -1; + } + tvhinfo(LS_IPTV, + "received new location from RTSP server (code: %d) '%s' was '%s'", + hc->hc_code, + p, + im->mm_iptv_url_raw); } - tvhinfo(LS_IPTV, "received new location from RTSP server (code: %d) '%s' was '%s'", - hc->hc_code, p, im->mm_iptv_url_raw); - } - break; - case RTSP_CMD_SETUP: - r = rtsp_setup_decode(hc, 0); - if (r >= 0) { - if(hc->hc_rtp_timeout > 20) - hc->hc_rtp_timeout = 20; - rtsp_play(hc, rp->path, rp->query); - rp->play = 1; - } - break; - case RTSP_CMD_PLAY: - // Now let's set peer port for RTCP - // Use the HTTP host for sending RTCP reports, NOT the hc_rtp_dest (which is where the stream is sent) - if (im->mm_iptv_ret_url) { - if (rtcp_connect(&im->im_rtcp_info, im->mm_iptv_ret_url, NULL, 0, - im->mm_iptv_interface, im->mm_nicename) == 0) { - im->im_use_retransmission = 1; + break; + case RTSP_CMD_SETUP: + r = rtsp_setup_decode(hc, 0); + if (r >= 0) { + if (hc->hc_rtp_timeout > 20) + hc->hc_rtp_timeout = 20; + rtsp_play(hc, rp->path, rp->query); + rp->play = 1; } - } else if (rtcp_connect(&im->im_rtcp_info, NULL, hc->hc_host, - hc->hc_rtcp_server_port, im->mm_iptv_interface, im->mm_nicename) == 0) { - im->im_use_retransmission = 1; - } - if (rtsp_play_decode(hc) == 0) { - if (rp->start_position == 0) - rp->position = rp->start_position = hc->hc_rtsp_stream_start; - else { - rp->position = hc->hc_rtsp_stream_start; - tvhdebug(LS_IPTV, "rtsp: position update: %" PRItime_t, - hc->hc_rtsp_stream_start); + break; + case RTSP_CMD_PLAY: + // Now let's set peer port for RTCP + // Use the HTTP host for sending RTCP reports, NOT the hc_rtp_dest (which is where the stream + // is sent) + if (im->mm_iptv_ret_url) { + if (rtcp_connect(&im->im_rtcp_info, + im->mm_iptv_ret_url, + NULL, + 0, + im->mm_iptv_interface, + im->mm_nicename) == 0) { + im->im_use_retransmission = 1; + } + } else if (rtcp_connect(&im->im_rtcp_info, + NULL, + hc->hc_host, + hc->hc_rtcp_server_port, + im->mm_iptv_interface, + im->mm_nicename) == 0) { + im->im_use_retransmission = 1; } - } else - rp->position = rp->start_position = time(NULL); - hc->hc_cmd = HTTP_CMD_NONE; - tvh_mutex_lock(&global_lock); - if (im->mm_active) - iptv_input_mux_started((iptv_input_t *)im->mm_active->mmi_input, im, 1); - mtimer_arm_rel(&rp->alive_timer, iptv_rtsp_alive_cb, im, - sec2mono(MAX(1, (hc->hc_rtp_timeout / 2) - 1))); - tvh_mutex_unlock(&global_lock); - break; - default: - break; + if (rtsp_play_decode(hc) == 0) { + if (rp->start_position == 0) + rp->position = rp->start_position = hc->hc_rtsp_stream_start; + else { + rp->position = hc->hc_rtsp_stream_start; + tvhdebug(LS_IPTV, "rtsp: position update: %" PRItime_t, hc->hc_rtsp_stream_start); + } + } else + rp->position = rp->start_position = time(NULL); + hc->hc_cmd = HTTP_CMD_NONE; + tvh_mutex_lock(&global_lock); + if (im->mm_active) + iptv_input_mux_started((iptv_input_t*)im->mm_active->mmi_input, im, 1); + mtimer_arm_rel(&rp->alive_timer, + iptv_rtsp_alive_cb, + im, + sec2mono(MAX(1, (hc->hc_rtp_timeout / 2) - 1))); + tvh_mutex_unlock(&global_lock); + break; + default: + break; } return 0; @@ -190,13 +205,10 @@ iptv_rtsp_header ( http_client_t *hc ) /* * Receive data */ -static int -iptv_rtsp_data - ( http_client_t *hc, void *buf, size_t len ) -{ - rtsp_priv_t *rp; - iptv_mux_t *im = hc->hc_aux; - int r; +static int iptv_rtsp_data(http_client_t* hc, void* buf, size_t len) { + rtsp_priv_t* rp; + iptv_mux_t* im = hc->hc_aux; + int r; if (im == NULL) return 0; @@ -204,50 +216,58 @@ iptv_rtsp_data if (hc->hc_code != HTTP_STATUS_OK) return 0; - rp = (rtsp_priv_t*) im->im_data; + rp = (rtsp_priv_t*)im->im_data; switch (hc->hc_cmd) { - case RTSP_CMD_DESCRIBE: - if (rp == NULL) - break; - if (rtsp_describe_decode(hc, buf, len) >= 0) { - if(rp->range_start == 0) - rp->range_start = hc->hc_rtsp_range_start; - rp->range_end = hc->hc_rtsp_range_end; - tvhdebug(LS_IPTV, "rtsp: buffer update, start: %" PRItime_t ", end: %" PRItime_t, - rp->range_start, rp->range_end); - } - if(rp->play) { - // Already active, most probably a keep-alive response + case RTSP_CMD_DESCRIBE: + if (rp == NULL) + break; + if (rtsp_describe_decode(hc, buf, len) >= 0) { + if (rp->range_start == 0) + rp->range_start = hc->hc_rtsp_range_start; + rp->range_end = hc->hc_rtsp_range_end; + tvhdebug(LS_IPTV, + "rtsp: buffer update, start: %" PRItime_t ", end: %" PRItime_t, + rp->range_start, + rp->range_end); + } + if (rp->play) { + // Already active, most probably a keep-alive response + break; + } + r = rtsp_setup(hc, + rp->path, + rp->query, + NULL, + ntohs(IP_PORT(im->mm_iptv_connection->ip)), + ntohs(IP_PORT(im->im_rtcp_info.connection->ip))); + if (r < 0) { + udp_close(im->im_rtcp_info.connection); + udp_close(im->mm_iptv_connection); + http_client_close(hc); + return -1; + } + udp_multirecv_init(&im->im_um, IPTV_PKTS, IPTV_PKT_PAYLOAD); + udp_multirecv_init(&im->im_rtcp_info.um, IPTV_PKTS, IPTV_PKT_PAYLOAD); + sbuf_alloc_(&im->im_temp_buffer, IPTV_BUF_SIZE); break; - } - r = rtsp_setup(hc, rp->path, rp->query, NULL, - ntohs(IP_PORT(im->mm_iptv_connection->ip)), - ntohs(IP_PORT(im->im_rtcp_info.connection->ip))); - if (r < 0) { - udp_close(im->im_rtcp_info.connection); - udp_close(im->mm_iptv_connection); - http_client_close(hc); - return -1; - } - udp_multirecv_init(&im->im_um, IPTV_PKTS, IPTV_PKT_PAYLOAD); - udp_multirecv_init(&im->im_rtcp_info.um, IPTV_PKTS, IPTV_PKT_PAYLOAD); - sbuf_alloc_(&im->im_temp_buffer, IPTV_BUF_SIZE); - break; - case RTSP_CMD_GET_PARAMETER: - if (rp == NULL) + case RTSP_CMD_GET_PARAMETER: + if (rp == NULL) + break; + // Generic position update + if (strncmp(buf, "position", 8) == 0) { + rp->position = strtoumax(buf + 10, NULL, 10); + tvhdebug(LS_IPTV, "rtsp: position update: %" PRItime_t, rp->position); + } break; - // Generic position update - if (strncmp(buf, "position", 8) == 0) { - rp->position = strtoumax(buf + 10, NULL, 10); - tvhdebug(LS_IPTV, "rtsp: position update: %" PRItime_t, rp->position); - } - break; - default: - if (len > 0) { - tvherror(LS_IPTV, "unknown data %zd received for '%s':\n%s", len, - im->mm_iptv_url_raw, (char* )buf); - } + default: + if (len > 0) { + tvherror(LS_IPTV, + "unknown data %zd received for '%s':\n%s", + len, + im->mm_iptv_url_raw, + (char*)buf); + } } return 0; } @@ -255,17 +275,13 @@ iptv_rtsp_data /* * Setup RTSP(S) connection */ -static int -iptv_rtsp_start - ( iptv_input_t *mi, iptv_mux_t *im, const char *raw, const url_t *u ) -{ - rtsp_priv_t *rp; - http_client_t *hc; +static int iptv_rtsp_start(iptv_input_t* mi, iptv_mux_t* im, const char* raw, const url_t* u) { + rtsp_priv_t* rp; + http_client_t* hc; udp_connection_t *rtp, *rtcp; - int r; + int r; - if (!(hc = http_client_connect(im, RTSP_VERSION_1_0, u->scheme, - u->host, u->port, NULL))) + if (!(hc = http_client_connect(im, RTSP_VERSION_1_0, u->scheme, u->host, u->port, NULL))) return SM_CODE_TUNING_FAILED; if (u->user) @@ -273,56 +289,61 @@ iptv_rtsp_start if (u->pass) hc->hc_rtsp_pass = strdup(u->pass); - if (udp_bind_double(&rtp, &rtcp, - LS_IPTV, "rtp", "rtcp", - NULL, 0, NULL, - 128*1024, 16384, 4*1024, 4*1024) < 0) { + if (udp_bind_double(&rtp, + &rtcp, + LS_IPTV, + "rtp", + "rtcp", + NULL, + 0, + NULL, + 128 * 1024, + 16384, + 4 * 1024, + 4 * 1024) < 0) { http_client_close(hc); return SM_CODE_TUNING_FAILED; } hc->hc_hdr_received = iptv_rtsp_header; hc->hc_data_received = iptv_rtsp_data; - hc->hc_handle_location = 1; /* allow redirects */ - hc->hc_rtsp_keep_alive_cmd = RTSP_CMD_DESCRIBE; /* start keep alive loop with DESCRIBE */ - http_client_register(hc); /* register to the HTTP thread */ + hc->hc_handle_location = 1; /* allow redirects */ + hc->hc_rtsp_keep_alive_cmd = RTSP_CMD_DESCRIBE; /* start keep alive loop with DESCRIBE */ + http_client_register(hc); /* register to the HTTP thread */ r = rtsp_describe(hc, u->path, u->query); if (r < 0) { tvherror(LS_IPTV, "rtsp: DESCRIBE failed"); return SM_CODE_TUNING_FAILED; } - rp = calloc(1, sizeof(*rp)); - rp->hc = hc; - rp->path = strdup(u->path ?: ""); + rp = calloc(1, sizeof(*rp)); + rp->hc = hc; + rp->path = strdup(u->path ?: ""); rp->query = strdup(u->query ?: ""); rtcp_init(&im->im_rtcp_info); - im->im_data = rp; - im->mm_iptv_fd = rtp->fd; - im->mm_iptv_connection = rtp; + im->im_data = rp; + im->mm_iptv_fd = rtp->fd; + im->mm_iptv_connection = rtp; im->im_rtcp_info.connection_fd = rtcp->fd; - im->im_rtcp_info.connection = rtcp; - im->mm_iptv_rtp_seq = -1; + im->im_rtcp_info.connection = rtcp; + im->mm_iptv_rtp_seq = -1; return 0; } /* * Stop connection */ -static void -iptv_rtsp_stop - ( iptv_input_t *mi, iptv_mux_t *im ) -{ - rtsp_priv_t *rp = im->im_data; - int play; +static void iptv_rtsp_stop(iptv_input_t* mi, iptv_mux_t* im) { + rtsp_priv_t* rp = im->im_data; + int play; lock_assert(&global_lock); if (rp == NULL) return; - play = rp->play; - im->im_data = NULL; + play = rp->play; + im->im_data = NULL; rp->hc->hc_aux = NULL; if (play) rtsp_teardown(rp->hc, rp->path, ""); @@ -339,10 +360,8 @@ iptv_rtsp_stop tvh_mutex_lock(&iptv_lock); } -static void -iptv_rtp_header_callback ( iptv_mux_t *im, uint8_t *rtp, int len ) -{ - rtcp_t *rtcp_info = &im->im_rtcp_info; +static void iptv_rtp_header_callback(iptv_mux_t* im, uint8_t* rtp, int len) { + rtcp_t* rtcp_info = &im->im_rtcp_info; ssize_t hlen; /* Basic headers checks */ @@ -353,9 +372,9 @@ iptv_rtp_header_callback ( iptv_mux_t *im, uint8_t *rtp, int len ) /* Header length (4bytes per CSRC) */ hlen = ((rtp[0] & 0xf) * 4) + 12; if (rtp[0] & 0x10) { - if (len < hlen+4) + if (len < hlen + 4) return; - hlen += ((rtp[hlen+2] << 8) | rtp[hlen+3]) * 4; + hlen += ((rtp[hlen + 2] << 8) | rtp[hlen + 3]) * 4; hlen += 4; } if (len < hlen || ((len - hlen) % 188) != 0) @@ -367,9 +386,7 @@ iptv_rtp_header_callback ( iptv_mux_t *im, uint8_t *rtp, int len ) /* * Read data */ -static ssize_t -iptv_rtsp_read ( iptv_input_t *mi, iptv_mux_t *im ) -{ +static ssize_t iptv_rtsp_read(iptv_input_t* mi, iptv_mux_t* im) { ssize_t r; if (im->mm_iptv_send_reports) { uint8_t buf[1500]; @@ -389,59 +406,58 @@ iptv_rtsp_read ( iptv_input_t *mi, iptv_mux_t *im ) * Send the status message */ #if ENABLE_TIMESHIFT -static void rtsp_timeshift_fill_status(rtsp_st_t *ts, rtsp_priv_t *rp, - timeshift_status_t *status) { +static void rtsp_timeshift_fill_status(rtsp_st_t* ts, rtsp_priv_t* rp, timeshift_status_t* status) { int64_t start, end, current; if (rp == NULL) { - start = 0; - end = 3600; + start = 0; + end = 3600; current = 0; } else { - start = 0; - end = rp->range_end - rp->range_start; + start = 0; + end = rp->range_end - rp->range_start; current = rp->position - rp->range_start; } status->full = 0; tvhdebug(LS_TIMESHIFT, - "remote ts status start %"PRId64" end %"PRId64 " current %"PRId64, start, end, + "remote ts status start %" PRId64 " end %" PRId64 " current %" PRId64, + start, + end, current); - status->shift = ts_rescale_inv(current, 1); + status->shift = ts_rescale_inv(current, 1); status->pts_start = ts_rescale_inv(start, 1); - status->pts_end = ts_rescale_inv(end, 1); + status->pts_end = ts_rescale_inv(end, 1); } -static void rtsp_timeshift_status - ( rtsp_st_t *pd, rtsp_priv_t *rp ) -{ +static void rtsp_timeshift_status(rtsp_st_t* pd, rtsp_priv_t* rp) { streaming_message_t *tsm, *tsm2; - timeshift_status_t *status; + timeshift_status_t* status; status = calloc(1, sizeof(timeshift_status_t)); rtsp_timeshift_fill_status(pd, rp, status); - tsm = streaming_msg_create_data(SMT_TIMESHIFT_STATUS, status); + tsm = streaming_msg_create_data(SMT_TIMESHIFT_STATUS, status); tsm2 = streaming_msg_clone(tsm); streaming_target_deliver2(pd->output, tsm); streaming_target_deliver2(pd->tsfix, tsm2); } -void *rtsp_status_thread(void *p) { - int64_t mono_now, mono_last_status = 0; - rtsp_st_t *pd = p; - rtsp_priv_t *rp; +void* rtsp_status_thread(void* p) { + int64_t mono_now, mono_last_status = 0; + rtsp_st_t* pd = p; + rtsp_priv_t* rp; while (pd->run) { - mono_now = getfastmonoclock(); - if(pd->im == NULL) + mono_now = getfastmonoclock(); + if (pd->im == NULL) continue; - rp = (rtsp_priv_t*) pd->im->im_data; - if(rp == NULL || !pd->rtsp_input_start) + rp = (rtsp_priv_t*)pd->im->im_data; + if (rp == NULL || !pd->rtsp_input_start) continue; if (mono_now >= (mono_last_status + sec2mono(1))) { // In case no buffer updates available assume the buffer is being filled - if(rp->hc && rp->hc->hc_rtsp_keep_alive_cmd != RTSP_CMD_DESCRIBE) + if (rp->hc && rp->hc->hc_rtsp_keep_alive_cmd != RTSP_CMD_DESCRIBE) rp->range_end++; rtsp_timeshift_status(pd, rp); mono_last_status = mono_now; @@ -450,112 +466,103 @@ void *rtsp_status_thread(void *p) { return NULL; } -static void rtsp_input(void *opaque, streaming_message_t *sm) { - rtsp_st_t *pd = (rtsp_st_t*) opaque; - iptv_mux_t *mux; - streaming_skip_t *data; - rtsp_priv_t *rp; +static void rtsp_input(void* opaque, streaming_message_t* sm) { + rtsp_st_t* pd = (rtsp_st_t*)opaque; + iptv_mux_t* mux; + streaming_skip_t* data; + rtsp_priv_t* rp; - if(pd == NULL || sm == NULL) + if (pd == NULL || sm == NULL) return; switch (sm->sm_type) { - case SMT_GRACE: - if (sm->sm_s != NULL) - pd->im = (iptv_mux_t*) ((mpegts_service_t*) sm->sm_s)->s_dvb_mux; - streaming_target_deliver2(pd->output, sm); - break; - case SMT_START: - pd->rtsp_input_start = 1; - streaming_target_deliver2(pd->output, sm); - break; - case SMT_SKIP: - mux = (iptv_mux_t*) pd->im; - if (mux == NULL || mux->im_data == NULL) + case SMT_GRACE: + if (sm->sm_s != NULL) + pd->im = (iptv_mux_t*)((mpegts_service_t*)sm->sm_s)->s_dvb_mux; + streaming_target_deliver2(pd->output, sm); break; - rp = (rtsp_priv_t*) mux->im_data; - if (rp->start_position == 0) - rp->start_position = rp->hc->hc_rtsp_stream_start; - rtsp_pause(rp->hc, rp->path, rp->query); - mux->mm_iptv_rtp_seq = -1; - data = (streaming_skip_t*) sm->sm_data; - rtsp_set_position(rp->hc, - rp->range_start + ts_rescale(data->time, 1)); - tvhinfo(LS_IPTV, "rtsp: skip: %" PRItime_t " + %" PRId64, rp->range_start, - ts_rescale(data->time, 1)); - streaming_msg_free(sm); - break; - case SMT_SPEED: - mux = (iptv_mux_t*) pd->im; - if (mux == NULL || mux->im_data == NULL) + case SMT_START: + pd->rtsp_input_start = 1; + streaming_target_deliver2(pd->output, sm); break; - rp = (rtsp_priv_t*) mux->im_data; - tvhinfo(LS_IPTV, "rtsp: set speed: %i", sm->sm_code); - if (sm->sm_code == 0) { + case SMT_SKIP: + mux = (iptv_mux_t*)pd->im; + if (mux == NULL || mux->im_data == NULL) + break; + rp = (rtsp_priv_t*)mux->im_data; + if (rp->start_position == 0) + rp->start_position = rp->hc->hc_rtsp_stream_start; rtsp_pause(rp->hc, rp->path, rp->query); - } else { - rtsp_set_speed(rp->hc, sm->sm_code / 100); - } - streaming_msg_free(sm); - break; - case SMT_EXIT: - pd->run = 0; - streaming_target_deliver2(pd->output, sm); - break; - default: - streaming_target_deliver2(pd->output, sm); + mux->mm_iptv_rtp_seq = -1; + data = (streaming_skip_t*)sm->sm_data; + rtsp_set_position(rp->hc, rp->range_start + ts_rescale(data->time, 1)); + tvhinfo(LS_IPTV, + "rtsp: skip: %" PRItime_t " + %" PRId64, + rp->range_start, + ts_rescale(data->time, 1)); + streaming_msg_free(sm); + break; + case SMT_SPEED: + mux = (iptv_mux_t*)pd->im; + if (mux == NULL || mux->im_data == NULL) + break; + rp = (rtsp_priv_t*)mux->im_data; + tvhinfo(LS_IPTV, "rtsp: set speed: %i", sm->sm_code); + if (sm->sm_code == 0) { + rtsp_pause(rp->hc, rp->path, rp->query); + } else { + rtsp_set_speed(rp->hc, sm->sm_code / 100); + } + streaming_msg_free(sm); + break; + case SMT_EXIT: + pd->run = 0; + streaming_target_deliver2(pd->output, sm); + break; + default: + streaming_target_deliver2(pd->output, sm); } } -static htsmsg_t* -rtsp_input_info(void *opaque, htsmsg_t *list) { +static htsmsg_t* rtsp_input_info(void* opaque, htsmsg_t* list) { return list; } -static streaming_ops_t rtsp_input_ops = -{ .st_cb = rtsp_input, .st_info = rtsp_input_info }; +static streaming_ops_t rtsp_input_ops = {.st_cb = rtsp_input, .st_info = rtsp_input_info}; -streaming_target_t* rtsp_st_create(streaming_target_t *out, profile_chain_t *prch) { - rtsp_st_t *h = calloc(1, sizeof(rtsp_st_t)); +streaming_target_t* rtsp_st_create(streaming_target_t* out, profile_chain_t* prch) { + rtsp_st_t* h = calloc(1, sizeof(rtsp_st_t)); h->output = out; - h->tsfix = prch->prch_share; - h->run = 1; + h->tsfix = prch->prch_share; + h->run = 1; tvh_thread_create(&h->st_thread, NULL, rtsp_status_thread, h, "rtsp-st"); streaming_target_init(&h->input, &rtsp_input_ops, h, 0); return &h->input; } -void rtsp_st_destroy(streaming_target_t *st) { - rtsp_st_t *h = (rtsp_st_t*)st; - h->run = 0; +void rtsp_st_destroy(streaming_target_t* st) { + rtsp_st_t* h = (rtsp_st_t*)st; + h->run = 0; free(st); } #endif /* * Initialise RTSP handler */ -void -iptv_rtsp_init ( void ) -{ - static iptv_handler_t ih[] = { - { - .scheme = "rtsp", - .buffer_limit = UINT32_MAX, /* unlimited */ - .start = iptv_rtsp_start, - .stop = iptv_rtsp_stop, - .read = iptv_rtsp_read, - .pause = iptv_input_pause_handler - }, - { - .scheme = "rtsps", - .buffer_limit = UINT32_MAX, /* unlimited */ - .start = iptv_rtsp_start, - .stop = iptv_rtsp_stop, - .read = iptv_rtsp_read, - .pause = iptv_input_pause_handler - } - }; +void iptv_rtsp_init(void) { + static iptv_handler_t ih[] = {{.scheme = "rtsp", + .buffer_limit = UINT32_MAX, /* unlimited */ + .start = iptv_rtsp_start, + .stop = iptv_rtsp_stop, + .read = iptv_rtsp_read, + .pause = iptv_input_pause_handler}, + {.scheme = "rtsps", + .buffer_limit = UINT32_MAX, /* unlimited */ + .start = iptv_rtsp_start, + .stop = iptv_rtsp_stop, + .read = iptv_rtsp_read, + .pause = iptv_input_pause_handler}}; iptv_handler_register(ih, 2); } diff --git a/src/input/mpegts/iptv/iptv_service.c b/src/input/mpegts/iptv/iptv_service.c index 2292ca178..b0a85a1e7 100644 --- a/src/input/mpegts/iptv/iptv_service.c +++ b/src/input/mpegts/iptv/iptv_service.c @@ -23,62 +23,51 @@ extern const idclass_t mpegts_service_class; -static htsmsg_t * -iptv_service_config_save ( service_t *s, char *filename, size_t fsize ) -{ +static htsmsg_t* iptv_service_config_save(service_t* s, char* filename, size_t fsize) { if (filename == NULL) { - htsmsg_t *e = htsmsg_create_map(); + htsmsg_t* e = htsmsg_create_map(); service_save(s, e); return e; } - idnode_changed(&((mpegts_service_t *)s)->s_dvb_mux->mm_id); + idnode_changed(&((mpegts_service_t*)s)->s_dvb_mux->mm_id); return NULL; } -static void -iptv_service_delete ( service_t *s, int delconf ) -{ - mpegts_mux_t *mm = ((mpegts_service_t *)s)->s_dvb_mux; +static void iptv_service_delete(service_t* s, int delconf) { + mpegts_mux_t* mm = ((mpegts_service_t*)s)->s_dvb_mux; idnode_changed(&mm->mm_id); /* Note - do no pass the delconf flag - another file location */ mpegts_service_delete(s, 0); } -static const char * -iptv_service_channel_name ( service_t *s ) -{ - iptv_service_t *is = (iptv_service_t *)s; - iptv_mux_t *im = (iptv_mux_t *)is->s_dvb_mux; +static const char* iptv_service_channel_name(service_t* s) { + iptv_service_t* is = (iptv_service_t*)s; + iptv_mux_t* im = (iptv_mux_t*)is->s_dvb_mux; if (im->mm_iptv_svcname && im->mm_iptv_svcname[0]) return im->mm_iptv_svcname; return is->s_dvb_svcname; } -static int64_t -iptv_service_channel_number ( service_t *s ) -{ - iptv_service_t *is = (iptv_service_t *)s; - iptv_mux_t *im = (iptv_mux_t *)is->s_dvb_mux; +static int64_t iptv_service_channel_number(service_t* s) { + iptv_service_t* is = (iptv_service_t*)s; + iptv_mux_t* im = (iptv_mux_t*)is->s_dvb_mux; if (im->mm_iptv_chnum) return im->mm_iptv_chnum; return mpegts_service_channel_number(s); } -static const char * -iptv_service_channel_icon ( service_t *s ) -{ - iptv_service_t *is = (iptv_service_t *)s; - iptv_mux_t *im = (iptv_mux_t *)is->s_dvb_mux; - iptv_network_t *in = (iptv_network_t *)im->mm_network; - const char *ic = im->mm_iptv_icon; - const char *dir = NULL; +static const char* iptv_service_channel_icon(service_t* s) { + iptv_service_t* is = (iptv_service_t*)s; + iptv_mux_t* im = (iptv_mux_t*)is->s_dvb_mux; + iptv_network_t* in = (iptv_network_t*)im->mm_network; + const char* ic = im->mm_iptv_icon; + const char* dir = NULL; if (ic && ic[0]) { - if (strncmp(ic, "http://", 7) == 0 || - strncmp(ic, "https://", 8) == 0 || + if (strncmp(ic, "http://", 7) == 0 || strncmp(ic, "https://", 8) == 0 || strncmp(ic, "file:///", 8) == 0) return ic; if (strncmp(ic, "file://", 7) == 0) { - const char *chicon = config.chicon_path; + const char* chicon = config.chicon_path; ic += 7; if (chicon && chicon[0] >= ' ' && chicon[0] <= 122) { dir = chicon; @@ -90,7 +79,8 @@ iptv_service_channel_icon ( service_t *s ) dir = in->in_icon_url; } if (dir && ic) { - while (ic[0] == '/') ic++; + while (ic[0] == '/') + ic++; snprintf(prop_sbuf, PROP_SBUF_LEN, "%s/%s", in->in_icon_url, ic); return prop_sbuf; } @@ -98,28 +88,29 @@ iptv_service_channel_icon ( service_t *s ) return NULL; } -static const char * -iptv_service_channel_epgid ( service_t *s ) -{ - iptv_service_t *is = (iptv_service_t *)s; - iptv_mux_t *im = (iptv_mux_t *)is->s_dvb_mux; +static const char* iptv_service_channel_epgid(service_t* s) { + iptv_service_t* is = (iptv_service_t*)s; + iptv_mux_t* im = (iptv_mux_t*)is->s_dvb_mux; return im->mm_iptv_epgid; } -static htsmsg_t * -iptv_service_channel_tags ( service_t *s ) -{ - iptv_service_t *is = (iptv_service_t *)s; - iptv_mux_t *im = (iptv_mux_t *)is->s_dvb_mux; - char *p = im->mm_iptv_tags, *x; - htsmsg_t *r = NULL; +static htsmsg_t* iptv_service_channel_tags(service_t* s) { + iptv_service_t* is = (iptv_service_t*)s; + iptv_mux_t* im = (iptv_mux_t*)is->s_dvb_mux; + char * p = im->mm_iptv_tags, *x; + htsmsg_t* r = NULL; if (p) { r = htsmsg_create_list(); while (*p) { - while (*p && *p <= ' ') p++; + while (*p && *p <= ' ') + p++; x = p; - while (*p && *p >= ' ') p++; - if (*p) { *p = '\0'; p++; } + while (*p && *p >= ' ') + p++; + if (*p) { + *p = '\0'; + p++; + } if (*x) htsmsg_add_str(r, NULL, x); } @@ -130,16 +121,16 @@ iptv_service_channel_tags ( service_t *s ) /* * Create */ -iptv_service_t * -iptv_service_create0 - ( iptv_mux_t *im, uint16_t sid, uint16_t pmt, - const char *uuid, htsmsg_t *conf ) -{ - iptv_service_t *is = (iptv_service_t*) - mpegts_service_create0(calloc(1, sizeof(mpegts_service_t)), - &mpegts_service_class, uuid, - (mpegts_mux_t*)im, sid, pmt, conf); - +iptv_service_t* +iptv_service_create0(iptv_mux_t* im, uint16_t sid, uint16_t pmt, const char* uuid, htsmsg_t* conf) { + iptv_service_t* is = (iptv_service_t*)mpegts_service_create0(calloc(1, sizeof(mpegts_service_t)), + &mpegts_service_class, + uuid, + (mpegts_mux_t*)im, + sid, + pmt, + conf); + is->s_config_save = iptv_service_config_save; is->s_delete = iptv_service_delete; is->s_channel_name = iptv_service_channel_name; diff --git a/src/input/mpegts/iptv/iptv_udp.c b/src/input/mpegts/iptv/iptv_udp.c index b2ab863ff..fbdc3aba2 100644 --- a/src/input/mpegts/iptv/iptv_udp.c +++ b/src/input/mpegts/iptv/iptv_udp.c @@ -32,17 +32,20 @@ /* * Connect UDP/RTP */ -static int -iptv_udp_start - ( iptv_input_t *mi, iptv_mux_t *im, const char *raw, const url_t *url ) -{ - udp_connection_t *conn; +static int iptv_udp_start(iptv_input_t* mi, iptv_mux_t* im, const char* raw, const url_t* url) { + udp_connection_t* conn; udp_multirecv_init(&im->im_um, IPTV_PKTS, IPTV_PKT_PAYLOAD); /* Note: url->user is used for specifying multicast source address (SSM) here. The URL format is rtp://@: */ - conn = udp_bind(LS_IPTV, im->mm_nicename, url->host, url->port, url->user, - im->mm_iptv_interface, IPTV_BUF_SIZE, 4*1024); + conn = udp_bind(LS_IPTV, + im->mm_nicename, + url->host, + url->port, + url->user, + im->mm_iptv_interface, + IPTV_BUF_SIZE, + 4 * 1024); if (conn == UDP_FATAL_ERROR) return SM_CODE_TUNING_FAILED; if (conn == NULL) @@ -53,11 +56,16 @@ iptv_udp_start /* Setup the RTCP Retransmission connection when configured */ rtcp_init(&im->im_rtcp_info); - if(im->mm_iptv_ret_url && rtcp_connect(&im->im_rtcp_info, im->mm_iptv_ret_url, - NULL, 0, im->mm_iptv_interface, im->mm_nicename) == 0) { - im->im_use_retransmission = 1; - udp_multirecv_init(&im->im_rtcp_info.um, IPTV_PKTS, IPTV_PKT_PAYLOAD); - sbuf_reset_and_alloc(&im->im_temp_buffer, IPTV_BUF_SIZE); + if (im->mm_iptv_ret_url && + rtcp_connect(&im->im_rtcp_info, + im->mm_iptv_ret_url, + NULL, + 0, + im->mm_iptv_interface, + im->mm_nicename) == 0) { + im->im_use_retransmission = 1; + udp_multirecv_init(&im->im_rtcp_info.um, IPTV_PKTS, IPTV_PKT_PAYLOAD); + sbuf_reset_and_alloc(&im->im_temp_buffer, IPTV_BUF_SIZE); } im->mm_iptv_rtp_seq = -1; @@ -66,10 +74,7 @@ iptv_udp_start return 0; } -static void -iptv_udp_stop - ( iptv_input_t *mi, iptv_mux_t *im ) -{ +static void iptv_udp_stop(iptv_input_t* mi, iptv_mux_t* im) { im->im_data = NULL; tvh_mutex_unlock(&iptv_lock); udp_multirecv_free(&im->im_um); @@ -78,12 +83,10 @@ iptv_udp_stop tvh_mutex_lock(&iptv_lock); } -static ssize_t -iptv_udp_read ( iptv_input_t *mi, iptv_mux_t *im ) -{ - int i, n; - struct iovec *iovec; - ssize_t res = 0; +static ssize_t iptv_udp_read(iptv_input_t* mi, iptv_mux_t* im) { + int i, n; + struct iovec* iovec; + ssize_t res = 0; n = udp_multirecv_read(&im->im_um, im->mm_iptv_fd, IPTV_PKTS, &iovec); if (n < 0) @@ -93,7 +96,7 @@ iptv_udp_read ( iptv_input_t *mi, iptv_mux_t *im ) for (i = 0; i < n; i++, iovec++) { if (iovec->iov_len <= 0) continue; - if (*(uint8_t *)iovec->iov_base != 0x47) { + if (*(uint8_t*)iovec->iov_base != 0x47) { im->mm_iptv_rtp_seq++; continue; } @@ -109,24 +112,20 @@ iptv_udp_read ( iptv_input_t *mi, iptv_mux_t *im ) return res; } -ssize_t -iptv_rtp_read(iptv_mux_t *im, void (*pkt_cb)(iptv_mux_t *im, uint8_t *pkt, int len)) -{ - ssize_t len, hlen; - uint8_t *rtp; - int i, n = 0; - uint32_t seq, nseq, oseq, ssrc, unc = 0; - struct iovec *iovec; - ssize_t res = 0; - char is_ret_buffer = 0; +ssize_t iptv_rtp_read(iptv_mux_t* im, void (*pkt_cb)(iptv_mux_t* im, uint8_t* pkt, int len)) { + ssize_t len, hlen; + uint8_t* rtp; + int i, n = 0; + uint32_t seq, nseq, oseq, ssrc, unc = 0; + struct iovec* iovec; + ssize_t res = 0; + char is_ret_buffer = 0; if (im->im_use_retransmission) { n = udp_multirecv_read(&im->im_rtcp_info.um, im->im_rtcp_info.connection_fd, IPTV_PKTS, &iovec); if (n > 0 && !im->im_is_ce_detected) { - tvhwarn(LS_IPTV, "RET receiving %d unexpected packets for %s", n, - im->mm_nicename); - } - else if (n > 0) { + tvhwarn(LS_IPTV, "RET receiving %d unexpected packets for %s", n, im->mm_nicename); + } else if (n > 0) { tvhtrace(LS_IPTV, "RET receiving %d packets for %s", n, im->mm_nicename); is_ret_buffer = 1; im->im_rtcp_info.ce_cnt -= n; @@ -170,9 +169,9 @@ iptv_rtp_read(iptv_mux_t *im, void (*pkt_cb)(iptv_mux_t *im, uint8_t *pkt, int l hlen += 2; } if (rtp[0] & 0x10) { - if (len < hlen+4) + if (len < hlen + 4) continue; - hlen += ((rtp[hlen+2] << 8) | rtp[hlen+3]) * 4; + hlen += ((rtp[hlen + 2] << 8) | rtp[hlen + 3]) * 4; hlen += 4; } if (len < hlen || ((len - hlen) % 188) != 0) @@ -185,20 +184,24 @@ iptv_rtp_read(iptv_mux_t *im, void (*pkt_cb)(iptv_mux_t *im, uint8_t *pkt, int l seq = nseq; /* Some sources will send the retransmission packets as part of the regular * stream, we can only detect them by checking for the expected seqn. */ - if (im->im_is_ce_detected && !is_ret_buffer && nseq == im->im_rtcp_info.last_received_sequence) { + if (im->im_is_ce_detected && !is_ret_buffer && + nseq == im->im_rtcp_info.last_received_sequence) { is_ret_buffer = 1; - im->im_rtcp_info.ce_cnt --; - im->im_rtcp_info.last_received_sequence ++; + im->im_rtcp_info.ce_cnt--; + im->im_rtcp_info.last_received_sequence++; } if (!is_ret_buffer) { - if(seq != nseq && ((seq + 1) & 0xffff) != nseq) { - unc += (len / 188) - * (uint32_t) ((uint16_t) nseq - (uint16_t) (seq + 1)); + if (seq != nseq && ((seq + 1) & 0xffff) != nseq) { + unc += (len / 188) * (uint32_t)((uint16_t)nseq - (uint16_t)(seq + 1)); ssrc = (rtp[8] << 24) | (rtp[9] << 16) | (rtp[10] << 8) | rtp[11]; - /* Use uncorrectable value to notify RTP delivery issues */ - tvhwarn(LS_IPTV, "RTP discontinuity for %s SSRC: 0x%x (%i != %i)", im->mm_nicename, - ssrc, seq + 1, nseq); + /* Use uncorrectable value to notify RTP delivery issues */ + tvhwarn(LS_IPTV, + "RTP discontinuity for %s SSRC: 0x%x (%i != %i)", + im->mm_nicename, + ssrc, + seq + 1, + nseq); if (im->im_use_retransmission && !im->im_is_ce_detected) { im->im_is_ce_detected = 1; rtcp_send_nak(&im->im_rtcp_info, ssrc, seq + 1, nseq - seq - 1); @@ -219,13 +222,13 @@ iptv_rtp_read(iptv_mux_t *im, void (*pkt_cb)(iptv_mux_t *im, uint8_t *pkt, int l /* If we received all RET packets dump the temporary buffer back into the iptv buffer, * or if it takes too long just continue as normal. RET packet rate can be a lot slower * then the main stream so this can take some time. */ - if(im->im_rtcp_info.ce_cnt > 0 && im->im_temp_buffer.sb_ptr > 1600 * IPTV_PKT_PAYLOAD) { + if (im->im_rtcp_info.ce_cnt > 0 && im->im_temp_buffer.sb_ptr > 1600 * IPTV_PKT_PAYLOAD) { tvhwarn(LS_IPTV, "RTP RET waiting for packets timeout for SSRC: 0x%x", ssrc); im->im_rtcp_info.ce_cnt = 0; } - if(im->im_rtcp_info.ce_cnt <= 0) { + if (im->im_rtcp_info.ce_cnt <= 0) { im->im_rtcp_info.ce_cnt = 0; - im->im_is_ce_detected = 0; + im->im_is_ce_detected = 0; sbuf_append_from_sbuf(&im->mm_iptv_buffer, &im->im_temp_buffer); sbuf_reset_and_alloc(&im->im_temp_buffer, IPTV_BUF_SIZE); } @@ -243,9 +246,7 @@ iptv_rtp_read(iptv_mux_t *im, void (*pkt_cb)(iptv_mux_t *im, uint8_t *pkt, int l return res; } -static ssize_t -iptv_udp_rtp_read ( iptv_input_t *mi, iptv_mux_t *im ) -{ +static ssize_t iptv_udp_rtp_read(iptv_input_t* mi, iptv_mux_t* im) { return iptv_rtp_read(im, NULL); } @@ -253,26 +254,18 @@ iptv_udp_rtp_read ( iptv_input_t *mi, iptv_mux_t *im ) * Initialise UDP handler */ -void -iptv_udp_init ( void ) -{ - static iptv_handler_t ih[] = { - { - .scheme = "udp", - .buffer_limit = UINT32_MAX, /* unlimited */ - .start = iptv_udp_start, - .stop = iptv_udp_stop, - .read = iptv_udp_read, - .pause = iptv_input_pause_handler - }, - { - .scheme = "rtp", - .buffer_limit = UINT32_MAX, /* unlimited */ - .start = iptv_udp_start, - .stop = iptv_udp_stop, - .read = iptv_udp_rtp_read, - .pause = iptv_input_pause_handler - } - }; +void iptv_udp_init(void) { + static iptv_handler_t ih[] = {{.scheme = "udp", + .buffer_limit = UINT32_MAX, /* unlimited */ + .start = iptv_udp_start, + .stop = iptv_udp_stop, + .read = iptv_udp_read, + .pause = iptv_input_pause_handler}, + {.scheme = "rtp", + .buffer_limit = UINT32_MAX, /* unlimited */ + .start = iptv_udp_start, + .stop = iptv_udp_stop, + .read = iptv_udp_rtp_read, + .pause = iptv_input_pause_handler}}; iptv_handler_register(ih, 2); } diff --git a/src/input/mpegts/linuxdvb.h b/src/input/mpegts/linuxdvb.h index 2bcd38ac0..ab908611c 100644 --- a/src/input/mpegts/linuxdvb.h +++ b/src/input/mpegts/linuxdvb.h @@ -20,11 +20,11 @@ #ifndef __TVH_LINUX_DVB_H__ #define __TVH_LINUX_DVB_H__ -void linuxdvb_init ( int mask ); +void linuxdvb_init(int mask); -void linuxdvb_done ( void ); +void linuxdvb_done(void); -idnode_set_t *linuxdvb_root ( void ); +idnode_set_t* linuxdvb_root(void); #endif /* __TVH_LINUX_DVB_H__ */ diff --git a/src/input/mpegts/linuxdvb/linuxdvb.c b/src/input/mpegts/linuxdvb/linuxdvb.c index ef0982da6..a5e97029b 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb.c +++ b/src/input/mpegts/linuxdvb/linuxdvb.c @@ -24,8 +24,7 @@ int linuxdvb_adapter_mask; -void linuxdvb_init ( int adapter_mask ) -{ +void linuxdvb_init(int adapter_mask) { linuxdvb_adapter_mask = adapter_mask; /* Initialise en50494 locks */ @@ -35,7 +34,6 @@ void linuxdvb_init ( int adapter_mask ) linuxdvb_adapter_init(); } -void linuxdvb_done ( void ) -{ +void linuxdvb_done(void) { linuxdvb_adapter_done(); } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c index cc1e6c6ab..7faae4fd9 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_adapter.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_adapter.c @@ -49,14 +49,12 @@ * DVB Adapter * **************************************************************************/ -static htsmsg_t * -linuxdvb_adapter_class_save ( idnode_t *in, char *filename, size_t fsize ) -{ - linuxdvb_adapter_t *la = (linuxdvb_adapter_t*)in; - htsmsg_t *m, *l; - linuxdvb_frontend_t *lfe; +static htsmsg_t* linuxdvb_adapter_class_save(idnode_t* in, char* filename, size_t fsize) { + linuxdvb_adapter_t* la = (linuxdvb_adapter_t*)in; + htsmsg_t * m, *l; + linuxdvb_frontend_t* lfe; #if ENABLE_LINUXDVB_CA - linuxdvb_transport_t *lcat; + linuxdvb_transport_t* lcat; #endif char ubuf[UUID_HEX_SIZE]; @@ -66,67 +64,60 @@ linuxdvb_adapter_class_save ( idnode_t *in, char *filename, size_t fsize ) if (filename) { /* Frontends */ l = htsmsg_create_map(); - LIST_FOREACH(lfe, &la->la_frontends, lfe_link) + LIST_FOREACH (lfe, &la->la_frontends, lfe_link) linuxdvb_frontend_save(lfe, l); htsmsg_add_msg(m, "frontends", l); /* CAs */ - #if ENABLE_LINUXDVB_CA +#if ENABLE_LINUXDVB_CA l = htsmsg_create_map(); - LIST_FOREACH(lcat, &la->la_ca_transports, lcat_link) + LIST_FOREACH (lcat, &la->la_ca_transports, lcat_link) linuxdvb_transport_save(lcat, l); htsmsg_add_msg(m, "ca_devices", l); - #endif +#endif /* Filename */ - snprintf(filename, fsize, "input/linuxdvb/adapters/%s", - idnode_uuid_as_str(&la->th_id, ubuf)); + snprintf(filename, fsize, "input/linuxdvb/adapters/%s", idnode_uuid_as_str(&la->th_id, ubuf)); } return m; } -static idnode_set_t * -linuxdvb_adapter_class_get_childs ( idnode_t *in ) -{ - linuxdvb_frontend_t *lfe; +static idnode_set_t* linuxdvb_adapter_class_get_childs(idnode_t* in) { + linuxdvb_frontend_t* lfe; #if ENABLE_LINUXDVB_CA - linuxdvb_transport_t *lcat; - linuxdvb_ca_t *lca; + linuxdvb_transport_t* lcat; + linuxdvb_ca_t* lca; #endif - linuxdvb_adapter_t *la = (linuxdvb_adapter_t*)in; - idnode_set_t *is = idnode_set_create(0); - LIST_FOREACH(lfe, &la->la_frontends, lfe_link) + linuxdvb_adapter_t* la = (linuxdvb_adapter_t*)in; + idnode_set_t* is = idnode_set_create(0); + LIST_FOREACH (lfe, &la->la_frontends, lfe_link) idnode_set_add(is, &lfe->ti_id, NULL, NULL); #if ENABLE_LINUXDVB_CA - LIST_FOREACH(lcat, &la->la_ca_transports, lcat_link) - LIST_FOREACH(lca, &lcat->lcat_slots, lca_link) + LIST_FOREACH (lcat, &la->la_ca_transports, lcat_link) + LIST_FOREACH (lca, &lcat->lcat_slots, lca_link) idnode_set_add(is, &lca->lca_id, NULL, NULL); #endif return is; } static void -linuxdvb_adapter_class_get_title - ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) -{ - linuxdvb_adapter_t *la = (linuxdvb_adapter_t*)in; +linuxdvb_adapter_class_get_title(idnode_t* in, const char* lang, char* dst, size_t dstsize) { + linuxdvb_adapter_t* la = (linuxdvb_adapter_t*)in; snprintf(dst, dstsize, "%s", la->la_name ?: la->la_rootpath); } -static const void * -linuxdvb_adapter_class_active_get ( void *obj ) -{ +static const void* linuxdvb_adapter_class_active_get(void* obj) { static int active; #if ENABLE_LINUXDVB_CA - linuxdvb_transport_t *lcat; - linuxdvb_ca_t *lca; + linuxdvb_transport_t* lcat; + linuxdvb_ca_t* lca; #endif - linuxdvb_adapter_t *la = (linuxdvb_adapter_t*)obj; - active = la->la_is_enabled(la); + linuxdvb_adapter_t* la = (linuxdvb_adapter_t*)obj; + active = la->la_is_enabled(la); #if ENABLE_LINUXDVB_CA if (!active) { - LIST_FOREACH(lcat, &la->la_ca_transports, lcat_link) - LIST_FOREACH(lca, &lcat->lcat_slots, lca_link) + LIST_FOREACH (lcat, &la->la_ca_transports, lcat_link) + LIST_FOREACH (lca, &lcat->lcat_slots, lca_link) if (lca->lca_enabled) { active = 1; goto caok; @@ -137,42 +128,35 @@ caok: return &active; } -const idclass_t linuxdvb_adapter_class = -{ - .ic_class = "linuxdvb_adapter", - .ic_caption = N_("LinuxDVB adapter"), - .ic_event = "linuxdvb_adapter", - .ic_save = linuxdvb_adapter_class_save, - .ic_get_childs = linuxdvb_adapter_class_get_childs, - .ic_get_title = linuxdvb_adapter_class_get_title, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "active", - .name = N_("Active"), - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, - .get = linuxdvb_adapter_class_active_get, - }, - { - .type = PT_STR, - .id = "rootpath", - .name = N_("Device path"), - .desc = N_("Path used by the device."), - .opts = PO_RDONLY, - .off = offsetof(linuxdvb_adapter_t, la_rootpath), - }, - {} - } -}; +const idclass_t linuxdvb_adapter_class = {.ic_class = "linuxdvb_adapter", + .ic_caption = N_("LinuxDVB adapter"), + .ic_event = "linuxdvb_adapter", + .ic_save = linuxdvb_adapter_class_save, + .ic_get_childs = linuxdvb_adapter_class_get_childs, + .ic_get_title = linuxdvb_adapter_class_get_title, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "active", + .name = N_("Active"), + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, + .get = linuxdvb_adapter_class_active_get, + }, + { + .type = PT_STR, + .id = "rootpath", + .name = N_("Device path"), + .desc = N_("Path used by the device."), + .opts = PO_RDONLY, + .off = offsetof(linuxdvb_adapter_t, la_rootpath), + }, + {}}}; /* * Check if enabled */ -static int -linuxdvb_adapter_is_enabled ( linuxdvb_adapter_t *la ) -{ - linuxdvb_frontend_t *lfe; - LIST_FOREACH(lfe, &la->la_frontends, lfe_link) { +static int linuxdvb_adapter_is_enabled(linuxdvb_adapter_t* la) { + linuxdvb_frontend_t* lfe; + LIST_FOREACH (lfe, &la->la_frontends, lfe_link) { if (lfe->mi_is_enabled((mpegts_input_t*)lfe, NULL, 0, -1) != MI_IS_ENABLED_NEVER) return 1; } @@ -182,18 +166,17 @@ linuxdvb_adapter_is_enabled ( linuxdvb_adapter_t *la ) /* * Create */ -static linuxdvb_adapter_t * -linuxdvb_adapter_create - ( const char *uuid, htsmsg_t *conf, - const char *path, int number, const char *name ) -{ - linuxdvb_adapter_t *la; - char buf[1024]; +static linuxdvb_adapter_t* linuxdvb_adapter_create(const char* uuid, + htsmsg_t* conf, + const char* path, + int number, + const char* name) { + linuxdvb_adapter_t* la; + char buf[1024]; /* Create */ la = calloc(1, sizeof(linuxdvb_adapter_t)); - if (!tvh_hardware_create0((tvh_hardware_t*)la, &linuxdvb_adapter_class, - uuid, conf)) { + if (!tvh_hardware_create0((tvh_hardware_t*)la, &linuxdvb_adapter_class, uuid, conf)) { /* Note: la variable is freed in tvh_hardware_create0() */ return NULL; } @@ -213,19 +196,21 @@ linuxdvb_adapter_create /* * */ -static linuxdvb_adapter_t * -linuxdvb_adapter_new(const char *path, int a, const char *name, - const char *display_name, htsmsg_t **conf, int *save) -{ - linuxdvb_adapter_t *la; - SHA_CTX sha1; - uint8_t uuidbin[20]; - char uhex[UUID_HEX_SIZE]; +static linuxdvb_adapter_t* linuxdvb_adapter_new(const char* path, + int a, + const char* name, + const char* display_name, + htsmsg_t** conf, + int* save) { + linuxdvb_adapter_t* la; + SHA_CTX sha1; + uint8_t uuidbin[20]; + char uhex[UUID_HEX_SIZE]; /* Create hash for adapter */ SHA1_Init(&sha1); - SHA1_Update(&sha1, (void*)path, strlen(path)); - SHA1_Update(&sha1, (void*)name, strlen(name)); + SHA1_Update(&sha1, (void*)path, strlen(path)); + SHA1_Update(&sha1, (void*)name, strlen(name)); SHA1_Final(uuidbin, &sha1); bin2hex(uhex, sizeof(uhex), uuidbin, sizeof(uuidbin)); @@ -251,57 +236,41 @@ linuxdvb_adapter_new(const char *path, int a, const char *name, */ static int force_dvbs; -static dvb_fe_type_t -linuxdvb_get_type(int linux_type) -{ +static dvb_fe_type_t linuxdvb_get_type(int linux_type) { /* useful for debugging with DVB-T */ if (force_dvbs) return DVB_TYPE_S; switch (linux_type) { - case FE_QPSK: - return DVB_TYPE_S; - case FE_QAM: - return DVB_TYPE_C; - case FE_OFDM: - return DVB_TYPE_T; - case FE_ATSC: - return DVB_TYPE_ATSC_T; - default: - return DVB_TYPE_NONE; + case FE_QPSK: + return DVB_TYPE_S; + case FE_QAM: + return DVB_TYPE_C; + case FE_OFDM: + return DVB_TYPE_T; + case FE_ATSC: + return DVB_TYPE_ATSC_T; + default: + return DVB_TYPE_NONE; } } /* * */ -#if DVB_VER_ATLEAST(5,5) -static void -linuxdvb_get_systems(int fd, struct dtv_property *_cmd) -{ - struct dtv_property cmd = { - .cmd = DTV_ENUM_DELSYS - }; - struct dtv_properties cmdseq = { - .num = 1, - .props = &cmd - }; - int r; +#if DVB_VER_ATLEAST(5, 5) +static void linuxdvb_get_systems(int fd, struct dtv_property* _cmd) { + struct dtv_property cmd = {.cmd = DTV_ENUM_DELSYS}; + struct dtv_properties cmdseq = {.num = 1, .props = &cmd}; + int r; r = ioctl(fd, FE_GET_PROPERTY, &cmdseq); if (!r && cmd.u.buffer.len) { - struct dtv_property fecmd[2] = { - { - .cmd = DTV_DELIVERY_SYSTEM, - .u.data = cmd.u.buffer.data[0] - }, - { - .cmd = DTV_TUNE - } - }; - cmdseq.props = fecmd; - cmdseq.num = 2; - r = ioctl(fd, FE_SET_PROPERTY, &cmdseq); + struct dtv_property fecmd[2] = {{.cmd = DTV_DELIVERY_SYSTEM, .u.data = cmd.u.buffer.data[0]}, + {.cmd = DTV_TUNE}}; + cmdseq.props = fecmd; + cmdseq.num = 2; + r = ioctl(fd, FE_SET_PROPERTY, &cmdseq); } else { cmd.u.buffer.len = 0; } @@ -314,9 +283,7 @@ linuxdvb_get_systems(int fd, struct dtv_property *_cmd) * -1 .. DDCI found but not usable * -2 .. DDCI not found */ -static int -linuxdvb_check_ddci ( const char *ci_path ) -{ +static int linuxdvb_check_ddci(const char* ci_path) { int j, fd, ret = -2; tvhtrace(LS_DDCI, "checking for DDCI %s", ci_path); @@ -324,15 +291,15 @@ linuxdvb_check_ddci ( const char *ci_path ) /* check existence */ if (!access(ci_path, R_OK | W_OK)) { for (j = 0; j < MAX_DEV_OPEN_ATTEMPTS; j++) { - if ((fd = tvh_open(ci_path, O_WRONLY, 0)) >= 0) break; + if ((fd = tvh_open(ci_path, O_WRONLY, 0)) >= 0) + break; tvh_safe_usleep(100000); } if (fd >= 0) { close(fd); tvhinfo(LS_DDCI, "DDCI found %s", ci_path); ret = 0; - } - else { + } else { ret = -1; tvherror(LS_DDCI, "unable to open %s", ci_path); } @@ -344,31 +311,29 @@ linuxdvb_check_ddci ( const char *ci_path ) /* * Add adapter by path */ -static void -linuxdvb_adapter_add ( const char *path ) -{ +static void linuxdvb_adapter_add(const char* path) { extern int linuxdvb_adapter_mask; - int a, i, j, r, fd; - char fe_path[512], dmx_path[512], dvr_path[512], name[132]; + int a, i, j, r, fd; + char fe_path[512], dmx_path[512], dvr_path[512], name[132]; #if ENABLE_LINUXDVB_CA - linuxdvb_transport_t *lcat; - char ca_path[512]; - htsmsg_t *caconf = NULL; - const char *ci_found = NULL; + linuxdvb_transport_t* lcat; + char ca_path[512]; + htsmsg_t* caconf = NULL; + const char* ci_found = NULL; #if ENABLE_DDCI - linuxdvb_adapter_t *la_fe = NULL; - char ci_path[512]; + linuxdvb_adapter_t* la_fe = NULL; + char ci_path[512]; #endif #endif - linuxdvb_adapter_t *la = NULL; + linuxdvb_adapter_t* la = NULL; struct dvb_frontend_info dfi; - ca_caps_t cac; - htsmsg_t *conf = NULL, *feconf = NULL; - int save = 0; - dvb_fe_type_t type; -#if DVB_VER_ATLEAST(5,5) - int delsys, fenum, type5; - dvb_fe_type_t fetypes[DVB_TYPE_LAST+1]; + ca_caps_t cac; + htsmsg_t * conf = NULL, *feconf = NULL; + int save = 0; + dvb_fe_type_t type; +#if DVB_VER_ATLEAST(5, 5) + int delsys, fenum, type5; + dvb_fe_type_t fetypes[DVB_TYPE_LAST + 1]; struct dtv_property cmd; #endif @@ -393,27 +358,30 @@ linuxdvb_adapter_add ( const char *path ) /* Wait for access (first FE can take a fe ms to be setup) */ if (!i) { for (j = 0; j < MAX_DEV_OPEN_ATTEMPTS; j++) { - if (!access(fe_path, R_OK | W_OK)) break; + if (!access(fe_path, R_OK | W_OK)) + break; tvh_safe_usleep(100000); } } - if (access(fe_path, R_OK | W_OK)) continue; + if (access(fe_path, R_OK | W_OK)) + continue; /* Get frontend info */ for (j = 0; j < MAX_DEV_OPEN_ATTEMPTS; j++) { - if ((fd = tvh_open(fe_path, O_RDWR, 0)) >= 0) break; + if ((fd = tvh_open(fe_path, O_RDWR, 0)) >= 0) + break; tvh_safe_usleep(100000); } if (fd < 0) { tvherror(LS_LINUXDVB, "unable to open %s", fe_path); continue; } -#if DVB_VER_ATLEAST(5,5) +#if DVB_VER_ATLEAST(5, 5) linuxdvb_get_systems(fd, &cmd); #endif r = ioctl(fd, FE_GET_INFO, &dfi); close(fd); - if(r) { + if (r) { tvherror(LS_LINUXDVB, "unable to query %s", fe_path); continue; } @@ -428,13 +396,15 @@ linuxdvb_adapter_add ( const char *path ) snprintf(dmx_path, sizeof(dmx_path), DMX_PATH, path, i); if (access(dmx_path, R_OK | W_OK)) { snprintf(dmx_path, sizeof(dmx_path), DMX_PATH, path, 0); - if (access(dmx_path, R_OK | W_OK)) continue; + if (access(dmx_path, R_OK | W_OK)) + continue; } snprintf(dvr_path, sizeof(dvr_path), DVR_PATH, path, i); if (access(dvr_path, R_OK | W_OK)) { snprintf(dvr_path, sizeof(dvr_path), DVR_PATH, path, 0); - if (access(dvr_path, R_OK | W_OK)) continue; + if (access(dvr_path, R_OK | W_OK)) + continue; } /* Create/Find adapter */ @@ -450,7 +420,7 @@ linuxdvb_adapter_add ( const char *path ) } /* Create frontend */ -#if DVB_VER_ATLEAST(5,5) +#if DVB_VER_ATLEAST(5, 5) memset(fetypes, 0, sizeof(fetypes)); for (j = fenum = 0; j < cmd.u.buffer.len; j++) { delsys = cmd.u.buffer.data[j]; @@ -470,14 +440,12 @@ linuxdvb_adapter_add ( const char *path ) continue; /* Create */ - linuxdvb_frontend_create(feconf, la, i, fe_path, dmx_path, dvr_path, - type5, name); + linuxdvb_frontend_create(feconf, la, i, fe_path, dmx_path, dvr_path, type5, name); fetypes[type5] = 1; fenum++; } if (fenum == 0) - linuxdvb_frontend_create(feconf, la, i, fe_path, dmx_path, dvr_path, - type, name); + linuxdvb_frontend_create(feconf, la, i, fe_path, dmx_path, dvr_path, type, name); #else linuxdvb_frontend_create(feconf, la, i, fe_path, dmx_path, dvr_path, type, name); #endif @@ -518,11 +486,13 @@ linuxdvb_adapter_add ( const char *path ) for (i = 0; i < 32; i++) { snprintf(ca_path, sizeof(ca_path), CA_PATH, path, i); - if (access(ca_path, R_OK | W_OK)) continue; + if (access(ca_path, R_OK | W_OK)) + continue; /* Get ca info */ for (j = 0; j < MAX_DEV_OPEN_ATTEMPTS; j++) { - if ((fd = tvh_open(ca_path, O_RDWR, 0)) >= 0) break; + if ((fd = tvh_open(ca_path, O_RDWR, 0)) >= 0) + break; tvh_safe_usleep(100000); } if (fd < 0) { @@ -534,15 +504,15 @@ linuxdvb_adapter_add ( const char *path ) if (r == 0) r = ioctl(fd, CA_GET_CAP, &cac); close(fd); - if(r) { + if (r) { tvherror(LS_LINUXDVB, "unable to query %s", ca_path); continue; } - if(cac.slot_num == 0) { + if (cac.slot_num == 0) { tvherror(LS_LINUXDVB, "CAM %s has no slots", ca_path); continue; } - if((cac.slot_type & (CA_CI_LINK|CA_CI)) == 0) { + if ((cac.slot_type & (CA_CI_LINK | CA_CI)) == 0) { tvherror(LS_LINUXDVB, "unsupported CAM type %08x", cac.slot_type); continue; } @@ -554,11 +524,11 @@ linuxdvb_adapter_add ( const char *path ) /* DD driver uses ciX */ snprintf(ci_path, sizeof(ci_path), CI_PATH, path, i); - ddci_ret = linuxdvb_check_ddci ( ci_path ); - if (ddci_ret == -2 ) { + ddci_ret = linuxdvb_check_ddci(ci_path); + if (ddci_ret == -2) { /* Mainline driver uses secX */ snprintf(ci_path, sizeof(ci_path), SEC_PATH, path, i); - ddci_ret = linuxdvb_check_ddci ( ci_path ); + ddci_ret = linuxdvb_check_ddci(ci_path); } /* The DD CI device have not been found, or was not usable, so we @@ -614,34 +584,33 @@ linuxdvb_adapter_add ( const char *path ) linuxdvb_adapter_changed(la); } -static void -linuxdvb_adapter_del ( const char *path ) -{ - int a; +static void linuxdvb_adapter_del(const char* path) { + int a; linuxdvb_frontend_t *lfe, *lfe_next; #if ENABLE_LINUXDVB_CA linuxdvb_transport_t *lcat, *lcat_next; #endif - linuxdvb_adapter_t *la = NULL; - tvh_hardware_t *th; + linuxdvb_adapter_t* la = NULL; + tvh_hardware_t* th; if (sscanf(path, "/dev/dvb/adapter%d", &a) == 1) { - LIST_FOREACH(th, &tvh_hardware, th_link) + LIST_FOREACH (th, &tvh_hardware, th_link) if (idnode_is_instance(&th->th_id, &linuxdvb_adapter_class)) { la = (linuxdvb_adapter_t*)th; if (!strcmp(path, la->la_rootpath)) break; } - if (!th) return; + if (!th) + return; idnode_save_check(&la->th_id, 0); - + /* Delete the frontends */ for (lfe = LIST_FIRST(&la->la_frontends); lfe != NULL; lfe = lfe_next) { lfe_next = LIST_NEXT(lfe, lfe_link); linuxdvb_frontend_destroy(lfe); } - + #if ENABLE_LINUXDVB_CA /* Delete the CA devices */ for (lcat = LIST_FIRST(&la->la_ca_transports); lcat != NULL; lcat = lcat_next) { @@ -653,7 +622,7 @@ linuxdvb_adapter_del ( const char *path ) /* Free memory */ free(la->la_rootpath); free(la->la_name); - + /* Delete */ tvh_hardware_delete((tvh_hardware_t*)la); @@ -668,16 +637,15 @@ linuxdvb_adapter_del ( const char *path ) /* * Scan for adapters */ -static void -linuxdvb_adapter_scan ( void ) -{ - DIR *dir; +static void linuxdvb_adapter_scan(void) { + DIR* dir; struct dirent buf, *de; - char path[1024]; + char path[1024]; if ((dir = opendir("/dev/dvb"))) { while (!readdir_r(dir, &buf, &de) && de) { - if (de->d_name[0] == '.') continue; + if (de->d_name[0] == '.') + continue; snprintf(path, sizeof(path), "/dev/dvb/%s", de->d_name); linuxdvb_adapter_add(path); } @@ -688,56 +656,40 @@ linuxdvb_adapter_scan ( void ) /* * /dev/dvb monitor */ -static void -devdvb_create ( fsmonitor_t *fsm, const char *path ) -{ +static void devdvb_create(fsmonitor_t* fsm, const char* path) { linuxdvb_adapter_add(path); } -static void -devdvb_delete ( fsmonitor_t *fsm, const char *path ) -{ +static void devdvb_delete(fsmonitor_t* fsm, const char* path) { tvhinfo(LS_LINUXDVB, "adapter removed %s", path); linuxdvb_adapter_del(path); } -static fsmonitor_t devdvbmon = { - .fsm_create = devdvb_create, - .fsm_delete = devdvb_delete -}; +static fsmonitor_t devdvbmon = {.fsm_create = devdvb_create, .fsm_delete = devdvb_delete}; /* * /dev monitor */ -static void -dev_create ( fsmonitor_t *fsm, const char *path ) -{ +static void dev_create(fsmonitor_t* fsm, const char* path) { if (!strcmp(path, "/dev/dvb")) { fsmonitor_add("/dev/dvb", &devdvbmon); linuxdvb_adapter_scan(); } } -static void -dev_delete ( fsmonitor_t *fsm, const char *path ) -{ +static void dev_delete(fsmonitor_t* fsm, const char* path) { if (!strcmp(path, "/dev/dvb")) fsmonitor_del("/dev/dvb", &devdvbmon); } -static fsmonitor_t devmon = { - .fsm_create = dev_create, - .fsm_delete = dev_delete -}; +static fsmonitor_t devmon = {.fsm_create = dev_create, .fsm_delete = dev_delete}; /* * Initialise */ -void -linuxdvb_adapter_init ( void ) -{ +void linuxdvb_adapter_init(void) { force_dvbs = getenv("TVHEADEND_DEBUG_FORCE_DVBS") != NULL; idclass_register(&linuxdvb_adapter_class); @@ -786,11 +738,9 @@ linuxdvb_adapter_init ( void ) } } -void -linuxdvb_adapter_done ( void ) -{ - linuxdvb_adapter_t *la; - tvh_hardware_t *th, *n; +void linuxdvb_adapter_done(void) { + linuxdvb_adapter_t* la; + tvh_hardware_t * th, *n; tvh_mutex_lock(&global_lock); fsmonitor_del("/dev/dvb", &devdvbmon); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_ca.c b/src/input/mpegts/linuxdvb/linuxdvb_ca.c index 1a888b01f..c06cf2436 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_ca.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_ca.c @@ -41,15 +41,15 @@ #define TRANSPORT_RECOVERY 4 /* in seconds */ -static tvh_mutex_t linuxdvb_ca_mutex = TVH_THREAD_MUTEX_INITIALIZER; +static tvh_mutex_t linuxdvb_ca_mutex = TVH_THREAD_MUTEX_INITIALIZER; static tvh_mutex_t linuxdvb_capmt_mutex = TVH_THREAD_MUTEX_INITIALIZER; -static th_pipe_t linuxdvb_ca_pipe; -static pthread_t linuxdvb_ca_threadid; -static mtimer_t linuxdvb_ca_thread_join_timer; +static th_pipe_t linuxdvb_ca_pipe; +static pthread_t linuxdvb_ca_threadid; +static mtimer_t linuxdvb_ca_thread_join_timer; static LIST_HEAD(, linuxdvb_transport) linuxdvb_all_transports; static LIST_HEAD(, linuxdvb_ca) linuxdvb_all_cas; -static int linuxdvb_transport_refresh(linuxdvb_transport_t *transport); +static int linuxdvb_transport_refresh(linuxdvb_transport_t* transport); /* * @@ -64,16 +64,20 @@ typedef enum { CA_SLOT_STATE_MODULE_READY, } ca_slot_state_t; -static const char * -ca_slot_state2str(ca_slot_state_t v) -{ - switch(v) { - case CA_SLOT_STATE_DISABLED: return N_("slot disabled"); - case CA_SLOT_STATE_EMPTY: return N_("slot empty"); - case CA_SLOT_STATE_MODULE_PRESENT: return N_("module present"); - case CA_SLOT_STATE_MODULE_INIT: return N_("module init"); - case CA_SLOT_STATE_MODULE_CONNECTED: return N_("module connected"); - case CA_SLOT_STATE_MODULE_READY: return N_("module ready"); +static const char* ca_slot_state2str(ca_slot_state_t v) { + switch (v) { + case CA_SLOT_STATE_DISABLED: + return N_("slot disabled"); + case CA_SLOT_STATE_EMPTY: + return N_("slot empty"); + case CA_SLOT_STATE_MODULE_PRESENT: + return N_("module present"); + case CA_SLOT_STATE_MODULE_INIT: + return N_("module init"); + case CA_SLOT_STATE_MODULE_CONNECTED: + return N_("module connected"); + case CA_SLOT_STATE_MODULE_READY: + return N_("module ready"); }; return "???"; } @@ -87,22 +91,22 @@ typedef enum { struct linuxdvb_ca_write { TAILQ_ENTRY(linuxdvb_ca_write) lcw_link; - int cmd; - int len; - uint8_t data[0]; + int cmd; + int len; + uint8_t data[0]; }; /* * CA thread routines */ -static int -linuxdvb_ca_slot_change_state ( linuxdvb_ca_t *lca, int state ) -{ +static int linuxdvb_ca_slot_change_state(linuxdvb_ca_t* lca, int state) { if (lca->lca_state != state) { - tvhnotice(LS_LINUXDVB, "%s: CAM slot %u status changed to %s", - lca->lca_name, lca->lca_slotnum, - ca_slot_state2str(state)); + tvhnotice(LS_LINUXDVB, + "%s: CAM slot %u status changed to %s", + lca->lca_name, + lca->lca_slotnum, + ca_slot_state2str(state)); idnode_lnotify_title_changed(&lca->lca_id); lca->lca_state = state; return 1; @@ -110,19 +114,20 @@ linuxdvb_ca_slot_change_state ( linuxdvb_ca_t *lca, int state ) return 0; } -static int -linuxdvb_ca_slot_info( int fd, linuxdvb_transport_t *lcat, linuxdvb_ca_t *lca ) -{ - ca_slot_info_t csi; - en50221_slot_t *slot; - int state; +static int linuxdvb_ca_slot_info(int fd, linuxdvb_transport_t* lcat, linuxdvb_ca_t* lca) { + ca_slot_info_t csi; + en50221_slot_t* slot; + int state; memset(&csi, 0, sizeof(csi)); csi.num = lca->lca_slotnum; if ((ioctl(fd, CA_GET_SLOT_INFO, &csi)) != 0) { - tvherror(LS_LINUXDVB, "%s: failed to get CAM slot %u info [e=%s]", - lca->lca_name, csi.num, strerror(errno)); + tvherror(LS_LINUXDVB, + "%s: failed to get CAM slot %u info [e=%s]", + lca->lca_name, + csi.num, + strerror(errno)); return -EIO; } if (csi.type & CA_CI_PHYS) { @@ -130,14 +135,16 @@ linuxdvb_ca_slot_info( int fd, linuxdvb_transport_t *lcat, linuxdvb_ca_t *lca ) } else if (csi.type & CA_CI_LINK) { lca->lca_phys_layer = 0; } else { - tvherror(LS_LINUXDVB, "%s: unable to communicated with slot type %08x", - lca->lca_name, csi.type); + tvherror(LS_LINUXDVB, + "%s: unable to communicated with slot type %08x", + lca->lca_name, + csi.type); return -EIO; } if (csi.flags & CA_CI_MODULE_READY) { if (lcat->lcat_fatal_time + sec2mono(TRANSPORT_RECOVERY) < mclk()) { state = CA_SLOT_STATE_MODULE_INIT; - slot = en50221_transport_find_slot(lcat->lcat_transport, lca->lca_slotnum); + slot = en50221_transport_find_slot(lcat->lcat_transport, lca->lca_slotnum); if (slot) { if (slot->cil_ready) state = CA_SLOT_STATE_MODULE_CONNECTED; @@ -157,11 +164,9 @@ linuxdvb_ca_slot_info( int fd, linuxdvb_transport_t *lcat, linuxdvb_ca_t *lca ) return state >= CA_SLOT_STATE_MODULE_INIT; } -static int -linuxdvb_ca_open_fd( linuxdvb_transport_t *lcat ) -{ - linuxdvb_ca_t *lca; - int fd, r; +static int linuxdvb_ca_open_fd(linuxdvb_transport_t* lcat) { + linuxdvb_ca_t* lca; + int fd, r; fd = lcat->lcat_ca_fd; if (fd > 0) @@ -169,10 +174,9 @@ linuxdvb_ca_open_fd( linuxdvb_transport_t *lcat ) if (lcat->lcat_fatal) return -1; fd = tvh_open(lcat->lcat_ca_path, O_RDWR | O_NONBLOCK, 0); - tvhtrace(LS_EN50221, "%s: opening %s (fd %d)", - lcat->lcat_name, lcat->lcat_ca_path, fd); + tvhtrace(LS_EN50221, "%s: opening %s (fd %d)", lcat->lcat_name, lcat->lcat_ca_path, fd); if (fd >= 0) { - LIST_FOREACH(lca, &lcat->lcat_slots, lca_link) { + LIST_FOREACH (lca, &lcat->lcat_slots, lca_link) { lca->lca_capmt_blocked = 0; if ((r = linuxdvb_ca_slot_info(fd, lcat, lca)) < 0) { close(fd); @@ -194,15 +198,13 @@ linuxdvb_ca_open_fd( linuxdvb_transport_t *lcat ) return 0; } -static void -linuxdvb_ca_close_fd( linuxdvb_transport_t *lcat, int reset ) -{ - const int fd = lcat->lcat_ca_fd; - linuxdvb_ca_t *lca; - linuxdvb_ca_write_t *lcw; +static void linuxdvb_ca_close_fd(linuxdvb_transport_t* lcat, int reset) { + const int fd = lcat->lcat_ca_fd; + linuxdvb_ca_t* lca; + linuxdvb_ca_write_t* lcw; tvh_mutex_lock(&linuxdvb_capmt_mutex); - LIST_FOREACH(lca, &lcat->lcat_slots, lca_link) { + LIST_FOREACH (lca, &lcat->lcat_slots, lca_link) { while ((lcw = TAILQ_FIRST(&lca->lca_write_queue)) != NULL) { TAILQ_REMOVE(&lca->lca_write_queue, lcw, lcw_link); free(lcw); @@ -213,18 +215,16 @@ linuxdvb_ca_close_fd( linuxdvb_transport_t *lcat, int reset ) if (fd < 0) return; if (ioctl(fd, CA_RESET, NULL)) - tvherror(LS_EN50221, "%s: unable to reset %s", - lcat->lcat_name, lcat->lcat_ca_path); + tvherror(LS_EN50221, "%s: unable to reset %s", lcat->lcat_name, lcat->lcat_ca_path); #if ENABLE_DDCI if (lcat->lddci) linuxdvb_ddci_close(lcat->lddci); #endif lcat->lcat_ca_fd = -1; - tvhtrace(LS_EN50221, "%s: close %s (fd %d)", - lcat->lcat_name, lcat->lcat_ca_path, fd); + tvhtrace(LS_EN50221, "%s: close %s (fd %d)", lcat->lcat_name, lcat->lcat_ca_path, fd); close(fd); tvh_mutex_lock(&linuxdvb_capmt_mutex); - LIST_FOREACH(lca, &lcat->lcat_slots, lca_link) { + LIST_FOREACH (lca, &lcat->lcat_slots, lca_link) { while ((lcw = TAILQ_FIRST(&lca->lca_write_queue)) != NULL) { TAILQ_REMOVE(&lca->lca_write_queue, lcw, lcw_link); free(lcw); @@ -236,73 +236,67 @@ linuxdvb_ca_close_fd( linuxdvb_transport_t *lcat, int reset ) } static int -linuxdvb_ca_process_cmd - ( linuxdvb_ca_t *lca, linuxdvb_ca_write_t *lcw, en50221_slot_t *slot ) -{ - int r = 0; +linuxdvb_ca_process_cmd(linuxdvb_ca_t* lca, linuxdvb_ca_write_t* lcw, en50221_slot_t* slot) { + int r = 0; int interval = lca->lca_capmt_interval; switch (lcw->cmd) { - case CA_WRITE_CMD_SLOT_DISABLE: - if (atomic_get(&lca->lca_enabled) <= 0) - en50221_slot_disable(slot); - break; - case CA_WRITE_CMD_CAPMT_QUERY: - interval = lca->lca_capmt_query_interval; - /* Fall thru */ - case CA_WRITE_CMD_CAPMT: - if (lca->lca_capmt_blocked >= mclk()) - return 1; - if (lcw->len > 0) { - r = en50221_send_capmt(slot, lcw->data, lcw->len); - if (r < 0) - tvherror(LS_EN50221, "%s: unable to write capmt (%d)", - lca->lca_name, r); - else if (interval > 0) - lca->lca_capmt_blocked = mclk() + ms2mono(interval); - } - break; - case CA_WRITE_CMD_PCMCIA_RATE: - if (lcw->len == 1) { - r = en50221_pcmcia_data_rate(slot, lcw->data[0]); - if (r < 0) - tvherror(LS_EN50221, "%s: unable to write pcmcia data rate (%d)", - lca->lca_name, r); - } - break; + case CA_WRITE_CMD_SLOT_DISABLE: + if (atomic_get(&lca->lca_enabled) <= 0) + en50221_slot_disable(slot); + break; + case CA_WRITE_CMD_CAPMT_QUERY: + interval = lca->lca_capmt_query_interval; + /* Fall thru */ + case CA_WRITE_CMD_CAPMT: + if (lca->lca_capmt_blocked >= mclk()) + return 1; + if (lcw->len > 0) { + r = en50221_send_capmt(slot, lcw->data, lcw->len); + if (r < 0) + tvherror(LS_EN50221, "%s: unable to write capmt (%d)", lca->lca_name, r); + else if (interval > 0) + lca->lca_capmt_blocked = mclk() + ms2mono(interval); + } + break; + case CA_WRITE_CMD_PCMCIA_RATE: + if (lcw->len == 1) { + r = en50221_pcmcia_data_rate(slot, lcw->data[0]); + if (r < 0) + tvherror(LS_EN50221, "%s: unable to write pcmcia data rate (%d)", lca->lca_name, r); + } + break; } return r; } -static void * -linuxdvb_ca_thread ( void *aux ) -{ - tvhpoll_t *poll; - tvhpoll_event_t *ev, *evn, *evp; - int evsize = 4, evcnt = 0; - linuxdvb_transport_t *lcat; - linuxdvb_ca_t *lca; - uint8_t buf[8192], *pbuf; - ssize_t l; - int64_t tm, tm2; - int r, monitor, quit = 0, cquit, waitms, busy; - linuxdvb_ca_write_t *lcw; - en50221_slot_t *slot; - +static void* linuxdvb_ca_thread(void* aux) { + tvhpoll_t* poll; + tvhpoll_event_t * ev, *evn, *evp; + int evsize = 4, evcnt = 0; + linuxdvb_transport_t* lcat; + linuxdvb_ca_t* lca; + uint8_t buf[8192], *pbuf; + ssize_t l; + int64_t tm, tm2; + int r, monitor, quit = 0, cquit, waitms, busy; + linuxdvb_ca_write_t* lcw; + en50221_slot_t* slot; + tvhtrace(LS_EN50221, "ca thread start"); - ev = malloc(sizeof(*ev) * evsize); - poll = tvhpoll_create(evsize + 1); - tm = mclk(); + ev = malloc(sizeof(*ev) * evsize); + poll = tvhpoll_create(evsize + 1); + tm = mclk(); waitms = 250; while (tvheadend_is_running() && !quit) { - evp = ev; - evp->fd = linuxdvb_ca_pipe.rd; + evp = ev; + evp->fd = linuxdvb_ca_pipe.rd; evp->events = TVHPOLL_IN; - evp->ptr = &linuxdvb_ca_pipe; + evp->ptr = &linuxdvb_ca_pipe; evp++; evcnt = 1; tvh_mutex_lock(&linuxdvb_ca_mutex); - LIST_FOREACH(lcat, &linuxdvb_all_transports, lcat_all_link) { + LIST_FOREACH (lcat, &linuxdvb_all_transports, lcat_all_link) { if (lcat->lcat_ca_fd < 0) { if (!lcat->lcat_enabled) continue; @@ -314,9 +308,8 @@ linuxdvb_ca_thread ( void *aux ) if (lcat->lcat_ca_fd >= 0 && lcat->lcat_close_time < mclk()) { tvh_mutex_lock(&linuxdvb_capmt_mutex); busy = 0; - LIST_FOREACH(lca, &lcat->lcat_slots, lca_link) { - slot = en50221_transport_find_slot(lcat->lcat_transport, - lca->lca_slotnum); + LIST_FOREACH (lca, &lcat->lcat_slots, lca_link) { + slot = en50221_transport_find_slot(lcat->lcat_transport, lca->lca_slotnum); if (slot) busy |= TAILQ_EMPTY(&slot->cil_write_queue) ? 0 : 2; busy |= TAILQ_EMPTY(&lca->lca_write_queue) ? 0 : 1; @@ -338,9 +331,9 @@ linuxdvb_ca_thread ( void *aux ) evsize += 2; evp = ev + evcnt; } - evp->fd = lcat->lcat_ca_fd; + evp->fd = lcat->lcat_ca_fd; evp->events = TVHPOLL_IN; - evp->ptr = lcat; + evp->ptr = lcat; evp++; evcnt++; } @@ -352,7 +345,7 @@ linuxdvb_ca_thread ( void *aux ) continue; tvh_mutex_lock(&linuxdvb_ca_mutex); - tm2 = mclk(); + tm2 = mclk(); monitor = (tm2 - tm) > (MONOCLOCK_RESOLUTION / 4); /* 250ms */ if (monitor) tm = tm2; @@ -363,15 +356,17 @@ linuxdvb_ca_thread ( void *aux ) } while (l < 0 && errno == EINTR); for (pbuf = buf; l > 0; l--, pbuf++) { switch (*pbuf) { - case 'q': - quit = 1; - break; + case 'q': + quit = 1; + break; } } } - LIST_FOREACH(lcat, &linuxdvb_all_transports, lcat_all_link) { - if (lcat->lcat_ca_fd < 0) continue; - if (lcat != evp->ptr) continue; + LIST_FOREACH (lcat, &linuxdvb_all_transports, lcat_all_link) { + if (lcat->lcat_ca_fd < 0) + continue; + if (lcat != evp->ptr) + continue; do { l = read(lcat->lcat_ca_fd, buf, sizeof(buf)); } while (l < 0 && (r = errno) == EINTR); @@ -380,18 +375,19 @@ linuxdvb_ca_thread ( void *aux ) tvhlog_hexdump(LS_EN50221, buf, l); } if (l < 5 && !(l < 0 && ERRNO_AGAIN(r))) { - tvhtrace(LS_EN50221, "%s: unable to read from device %s: %s", - lcat->lcat_name, lcat->lcat_ca_path, strerror(r)); + tvhtrace(LS_EN50221, + "%s: unable to read from device %s: %s", + lcat->lcat_name, + lcat->lcat_ca_path, + strerror(r)); lcat->lcat_fatal_time = mclk(); linuxdvb_ca_close_fd(lcat, 1); break; } if (l > 0 && buf[1]) { - r = en50221_transport_read(lcat->lcat_transport, - buf[0], buf[1], buf + 2, l - 2); + r = en50221_transport_read(lcat->lcat_transport, buf[0], buf[1], buf + 2, l - 2); if (r < 0) { - tvhtrace(LS_EN50221, "%s: transport read failed: %s", - lcat->lcat_name, strerror(-r)); + tvhtrace(LS_EN50221, "%s: transport read failed: %s", lcat->lcat_name, strerror(-r)); lcat->lcat_fatal_time = mclk(); linuxdvb_ca_close_fd(lcat, 1); break; @@ -400,18 +396,22 @@ linuxdvb_ca_thread ( void *aux ) } } waitms = 250; - LIST_FOREACH(lcat, &linuxdvb_all_transports, lcat_all_link) { - if (lcat->lcat_ca_fd < 0) continue; + LIST_FOREACH (lcat, &linuxdvb_all_transports, lcat_all_link) { + if (lcat->lcat_ca_fd < 0) + continue; if (monitor) { r = en50221_transport_monitor(lcat->lcat_transport, tm); if (r < 0) { - tvhtrace(LS_EN50221, "%s: monitor failed for device %s: %s", - lcat->lcat_name, lcat->lcat_ca_path, strerror(-r)); + tvhtrace(LS_EN50221, + "%s: monitor failed for device %s: %s", + lcat->lcat_name, + lcat->lcat_ca_path, + strerror(-r)); lcat->lcat_fatal_time = mclk(); linuxdvb_ca_close_fd(lcat, 1); } } - LIST_FOREACH(lca, &lcat->lcat_slots, lca_link) { + LIST_FOREACH (lca, &lcat->lcat_slots, lca_link) { cquit = 0; while (!cquit) { tvh_mutex_lock(&linuxdvb_capmt_mutex); @@ -423,8 +423,7 @@ linuxdvb_ca_thread ( void *aux ) lca->lca_capmt_blocked = 0; break; } - slot = en50221_transport_find_slot(lcat->lcat_transport, - lca->lca_slotnum); + slot = en50221_transport_find_slot(lcat->lcat_transport, lca->lca_slotnum); if (slot) { r = linuxdvb_ca_process_cmd(lca, lcw, slot); if (r < 0) { @@ -459,12 +458,10 @@ linuxdvb_ca_thread ( void *aux ) return NULL; } -static void linuxdvb_ca_thread_create(void) -{ +static void linuxdvb_ca_thread_create(void) { if (linuxdvb_ca_threadid) return; - tvh_thread_create(&linuxdvb_ca_threadid, NULL, linuxdvb_ca_thread, - NULL, "lnxdvb-ca"); + tvh_thread_create(&linuxdvb_ca_threadid, NULL, linuxdvb_ca_thread, NULL, "lnxdvb-ca"); if (tvh_pipe(O_NONBLOCK, &linuxdvb_ca_pipe)) { tvherror(LS_EN50221, "unable to create thread pipe"); pthread_join(linuxdvb_ca_threadid, NULL); @@ -472,8 +469,7 @@ static void linuxdvb_ca_thread_create(void) } } -static void linuxdvb_ca_thread_join(void) -{ +static void linuxdvb_ca_thread_join(void) { if (linuxdvb_ca_threadid == 0) return; tvh_write(linuxdvb_ca_pipe.wr, "q", 1); @@ -482,16 +478,13 @@ static void linuxdvb_ca_thread_join(void) tvh_pipe_close(&linuxdvb_ca_pipe); } -static void linuxdvb_ca_thread_join_cb(void *aux) -{ +static void linuxdvb_ca_thread_join_cb(void* aux) { linuxdvb_ca_thread_join(); } -static int linuxdvb_ca_write_cmd - (linuxdvb_ca_t *lca, int cmd, const uint8_t *data, size_t datalen) -{ - linuxdvb_ca_write_t *lcw; - int trigger; +static int linuxdvb_ca_write_cmd(linuxdvb_ca_t* lca, int cmd, const uint8_t* data, size_t datalen) { + linuxdvb_ca_write_t* lcw; + int trigger; lcw = calloc(1, sizeof(*lcw) + datalen); if (!lcw) @@ -514,19 +507,15 @@ static int linuxdvb_ca_write_cmd * */ -static void -linuxdvb_ca_class_changed ( idnode_t *in ) -{ - linuxdvb_adapter_t *la = ((linuxdvb_ca_t*)in)->lca_transport->lcat_adapter; +static void linuxdvb_ca_class_changed(idnode_t* in) { + linuxdvb_adapter_t* la = ((linuxdvb_ca_t*)in)->lca_transport->lcat_adapter; linuxdvb_adapter_changed(la); } -static void -linuxdvb_ca_class_enabled_notify ( void *p, const char *lang ) -{ - linuxdvb_ca_t *lca = (linuxdvb_ca_t *) p; - int notify_title = linuxdvb_transport_refresh(lca->lca_transport); - int notify = 0; +static void linuxdvb_ca_class_enabled_notify(void* p, const char* lang) { + linuxdvb_ca_t* lca = (linuxdvb_ca_t*)p; + int notify_title = linuxdvb_transport_refresh(lca->lca_transport); + int notify = 0; if (!lca->lca_enabled) { notify = linuxdvb_ca_slot_change_state(lca, CA_SLOT_STATE_DISABLED); if (notify) @@ -538,11 +527,9 @@ linuxdvb_ca_class_enabled_notify ( void *p, const char *lang ) idnode_notify_title_changed(&lca->lca_id); } -static void -linuxdvb_ca_class_high_bitrate_notify ( void *p, const char *lang ) -{ - linuxdvb_ca_t *lca = (linuxdvb_ca_t *) p; - uint8_t b; +static void linuxdvb_ca_class_high_bitrate_notify(void* p, const char* lang) { + linuxdvb_ca_t* lca = (linuxdvb_ca_t*)p; + uint8_t b; if (lca->lca_enabled) { b = lca->lca_high_bitrate_mode ? 0x01 : 0x00; @@ -550,180 +537,166 @@ linuxdvb_ca_class_high_bitrate_notify ( void *p, const char *lang ) } } -static void -linuxdvb_ca_class_get_title - ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) -{ - linuxdvb_ca_t *lca = (linuxdvb_ca_t *) in; - const int anum = lca->lca_transport->lcat_number; - const int snum = lca->lca_slotnum; - int state = atomic_get(&lca->lca_state); - const char *s; +static void linuxdvb_ca_class_get_title(idnode_t* in, const char* lang, char* dst, size_t dstsize) { + linuxdvb_ca_t* lca = (linuxdvb_ca_t*)in; + const int anum = lca->lca_transport->lcat_number; + const int snum = lca->lca_slotnum; + int state = atomic_get(&lca->lca_state); + const char* s; if (!lca->lca_enabled || state == CA_SLOT_STATE_EMPTY) { s = !lca->lca_enabled ? N_("disabled") : N_("slot empty"); - snprintf(dst, dstsize, "ca%u-%u: %s", anum, snum, - tvh_gettext_lang(lang, s)); + snprintf(dst, dstsize, "ca%u-%u: %s", anum, snum, tvh_gettext_lang(lang, s)); } else { - snprintf(dst, dstsize, "ca%u-%u: %s (%s)", anum, snum, - lca->lca_modulename ?: "", - tvh_gettext_lang(lang, ca_slot_state2str(state))); + snprintf(dst, + dstsize, + "ca%u-%u: %s (%s)", + anum, + snum, + lca->lca_modulename ?: "", + tvh_gettext_lang(lang, ca_slot_state2str(state))); } } -static const void * -linuxdvb_ca_class_active_get ( void *obj ) -{ - static int active; - linuxdvb_ca_t *lca = (linuxdvb_ca_t*)obj; - active = !!lca->lca_enabled; +static const void* linuxdvb_ca_class_active_get(void* obj) { + static int active; + linuxdvb_ca_t* lca = (linuxdvb_ca_t*)obj; + active = !!lca->lca_enabled; return &active; } -static const void * -linuxdvb_ca_class_ca_path_get ( void *obj ) -{ - linuxdvb_ca_t *lca = (linuxdvb_ca_t*)obj; +static const void* linuxdvb_ca_class_ca_path_get(void* obj) { + linuxdvb_ca_t* lca = (linuxdvb_ca_t*)obj; return &lca->lca_transport->lcat_ca_path; } -static const void * -linuxdvb_ca_class_state_get ( void *obj ) -{ - linuxdvb_ca_t *lca = (linuxdvb_ca_t*)obj; - static const char *s; +static const void* linuxdvb_ca_class_state_get(void* obj) { + linuxdvb_ca_t* lca = (linuxdvb_ca_t*)obj; + static const char* s; s = ca_slot_state2str(lca->lca_state); return &s; } -const idclass_t linuxdvb_ca_class = -{ - .ic_class = "linuxdvb_ca", - .ic_caption = N_("Linux DVB CA"), - .ic_changed = linuxdvb_ca_class_changed, - .ic_get_title = linuxdvb_ca_class_get_title, - .ic_properties = (const property_t[]) { - { - .type = PT_BOOL, - .id = "active", - .name = N_("Active"), - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, - .get = linuxdvb_ca_class_active_get, - }, - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable the device."), - .off = offsetof(linuxdvb_ca_t, lca_enabled), - .notify = linuxdvb_ca_class_enabled_notify, - }, - { - .type = PT_BOOL, - .id = "high_bitrate_mode", - .name = N_("High bitrate mode (CI+ CAMs only)"), - .desc = N_("Allow high bitrate mode (CI+ CAMs only)."), - .off = offsetof(linuxdvb_ca_t, lca_high_bitrate_mode), - .notify = linuxdvb_ca_class_high_bitrate_notify, - }, - { - .type = PT_BOOL, - .id = "pin_reply", - .name = N_("Reply to CAM PIN inquiries"), - .desc = N_("Reply to PIN inquiries."), - .off = offsetof(linuxdvb_ca_t, lca_pin_reply), - .opts = PO_ADVANCED, - }, - { - .type = PT_STR, - .id = "pin", - .name = N_("PIN"), - .desc = N_("The PIN to use."), - .off = offsetof(linuxdvb_ca_t, lca_pin_str), - .opts = PO_ADVANCED | PO_PASSWORD, - .def.s = "1234", - }, - { - .type = PT_STR, - .id = "pin_match", - .name = N_("PIN inquiry match string"), - .desc = N_("PIN inquiry match string."), - .off = offsetof(linuxdvb_ca_t, lca_pin_match_str), - .opts = PO_ADVANCED, - .def.s = "PIN", - }, - { - .type = PT_INT, - .id = "capmt_interval", - .name = N_("CAPMT interval (ms)"), - .desc = N_("A delay between CAPMT commands (in ms)."), - .off = offsetof(linuxdvb_ca_t, lca_capmt_interval), - .opts = PO_ADVANCED, - .def.i = 0, - }, - { - .type = PT_INT, - .id = "capmt_query_interval", - .name = N_("CAPMT query interval (ms)"), - .desc = N_("A delay before CAPMT after CAPMT query command (ms)."), - .off = offsetof(linuxdvb_ca_t, lca_capmt_query_interval), - .opts = PO_ADVANCED, - .def.i = 300, - }, - { - .type = PT_BOOL, - .id = "query_before_ok_descrambling", - .name = N_("Send CAPMT query"), - .desc = N_("Send CAPMT OK query before descrambling."), - .off = offsetof(linuxdvb_ca_t, lca_capmt_query), - .opts = PO_ADVANCED, - }, - { - .type = PT_STR, - .id = "ca_path", - .name = N_("Device path"), - .desc = N_("Path used by the device."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = linuxdvb_ca_class_ca_path_get, - }, - { - .type = PT_INT, - .id = "slotnum", - .name = N_("Slot number"), - .desc = N_("CAM slot number."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(linuxdvb_ca_t, lca_slotnum), - }, - { - .type = PT_STR, - .id = "slot_state", - .name = N_("Slot state"), - .desc = N_("The CAM slot status."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = linuxdvb_ca_class_state_get, - }, - {} - } -}; +const idclass_t linuxdvb_ca_class = {.ic_class = "linuxdvb_ca", + .ic_caption = N_("Linux DVB CA"), + .ic_changed = linuxdvb_ca_class_changed, + .ic_get_title = linuxdvb_ca_class_get_title, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "active", + .name = N_("Active"), + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, + .get = linuxdvb_ca_class_active_get, + }, + { + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable the device."), + .off = offsetof(linuxdvb_ca_t, lca_enabled), + .notify = linuxdvb_ca_class_enabled_notify, + }, + { + .type = PT_BOOL, + .id = "high_bitrate_mode", + .name = N_("High bitrate mode (CI+ CAMs only)"), + .desc = N_("Allow high bitrate mode (CI+ CAMs only)."), + .off = offsetof(linuxdvb_ca_t, lca_high_bitrate_mode), + .notify = linuxdvb_ca_class_high_bitrate_notify, + }, + { + .type = PT_BOOL, + .id = "pin_reply", + .name = N_("Reply to CAM PIN inquiries"), + .desc = N_("Reply to PIN inquiries."), + .off = offsetof(linuxdvb_ca_t, lca_pin_reply), + .opts = PO_ADVANCED, + }, + { + .type = PT_STR, + .id = "pin", + .name = N_("PIN"), + .desc = N_("The PIN to use."), + .off = offsetof(linuxdvb_ca_t, lca_pin_str), + .opts = PO_ADVANCED | PO_PASSWORD, + .def.s = "1234", + }, + { + .type = PT_STR, + .id = "pin_match", + .name = N_("PIN inquiry match string"), + .desc = N_("PIN inquiry match string."), + .off = offsetof(linuxdvb_ca_t, lca_pin_match_str), + .opts = PO_ADVANCED, + .def.s = "PIN", + }, + { + .type = PT_INT, + .id = "capmt_interval", + .name = N_("CAPMT interval (ms)"), + .desc = N_("A delay between CAPMT commands (in ms)."), + .off = offsetof(linuxdvb_ca_t, lca_capmt_interval), + .opts = PO_ADVANCED, + .def.i = 0, + }, + { + .type = PT_INT, + .id = "capmt_query_interval", + .name = N_("CAPMT query interval (ms)"), + .desc = N_("A delay before CAPMT after CAPMT query command (ms)."), + .off = offsetof(linuxdvb_ca_t, lca_capmt_query_interval), + .opts = PO_ADVANCED, + .def.i = 300, + }, + { + .type = PT_BOOL, + .id = "query_before_ok_descrambling", + .name = N_("Send CAPMT query"), + .desc = N_("Send CAPMT OK query before descrambling."), + .off = offsetof(linuxdvb_ca_t, lca_capmt_query), + .opts = PO_ADVANCED, + }, + { + .type = PT_STR, + .id = "ca_path", + .name = N_("Device path"), + .desc = N_("Path used by the device."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = linuxdvb_ca_class_ca_path_get, + }, + { + .type = PT_INT, + .id = "slotnum", + .name = N_("Slot number"), + .desc = N_("CAM slot number."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(linuxdvb_ca_t, lca_slotnum), + }, + { + .type = PT_STR, + .id = "slot_state", + .name = N_("Slot state"), + .desc = N_("The CAM slot status."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = linuxdvb_ca_class_state_get, + }, + {}}}; /* * */ -linuxdvb_ca_t * -linuxdvb_ca_create - ( htsmsg_t *conf, linuxdvb_transport_t *lcat, int slotnum ) -{ - linuxdvb_ca_t *lca; - char id[32], buf[32]; - const char *uuid = NULL; +linuxdvb_ca_t* linuxdvb_ca_create(htsmsg_t* conf, linuxdvb_transport_t* lcat, int slotnum) { + linuxdvb_ca_t* lca; + char id[32], buf[32]; + const char* uuid = NULL; - lca = calloc(1, sizeof(linuxdvb_ca_t)); - lca->lca_state = CA_SLOT_STATE_EMPTY; + lca = calloc(1, sizeof(linuxdvb_ca_t)); + lca->lca_state = CA_SLOT_STATE_EMPTY; lca->lca_transport = lcat; - lca->lca_adapnum = lcat->lcat_adapter->la_dvb_number; - lca->lca_slotnum = slotnum; + lca->lca_adapnum = lcat->lcat_adapter->la_dvb_number; + lca->lca_slotnum = slotnum; snprintf(buf, sizeof(buf), "dvbca%d-%d", lcat->lcat_number, slotnum); - lca->lca_name = strdup(buf); + lca->lca_name = strdup(buf); lca->lca_capmt_query_interval = 300; TAILQ_INIT(&lca->lca_write_queue); @@ -756,9 +729,8 @@ linuxdvb_ca_create return lca; } -static void linuxdvb_ca_destroy( linuxdvb_ca_t *lca ) -{ - linuxdvb_ca_write_t *lcw; +static void linuxdvb_ca_destroy(linuxdvb_ca_t* lca) { + linuxdvb_ca_write_t* lcw; if (lca == NULL) return; @@ -779,11 +751,10 @@ static void linuxdvb_ca_destroy( linuxdvb_ca_t *lca ) free(lca); } -static void linuxdvb_ca_save( linuxdvb_ca_t *lca, htsmsg_t *msg ) -{ - char id[32]; - htsmsg_t *m = htsmsg_create_map(); - linuxdvb_transport_t *lcat = lca->lca_transport; +static void linuxdvb_ca_save(linuxdvb_ca_t* lca, htsmsg_t* msg) { + char id[32]; + htsmsg_t* m = htsmsg_create_map(); + linuxdvb_transport_t* lcat = lca->lca_transport; htsmsg_add_uuid(m, "uuid", &lca->lca_id.in_uuid); idnode_save(&lca->lca_id, m); @@ -800,29 +771,24 @@ static void linuxdvb_ca_save( linuxdvb_ca_t *lca, htsmsg_t *msg ) * */ -static linuxdvb_ca_t *linuxdvb_ca_find_slot - ( linuxdvb_transport_t *lcat, en50221_slot_t *slot ) -{ - linuxdvb_ca_t *lca; - LIST_FOREACH(lca, &lcat->lcat_slots, lca_link) +static linuxdvb_ca_t* linuxdvb_ca_find_slot(linuxdvb_transport_t* lcat, en50221_slot_t* slot) { + linuxdvb_ca_t* lca; + LIST_FOREACH (lca, &lcat->lcat_slots, lca_link) if (lca->lca_slotnum == slot->cil_number) return lca; return NULL; } -static int linuxdvb_ca_ops_reset( void *aux ) -{ - linuxdvb_transport_t *lcat = aux; +static int linuxdvb_ca_ops_reset(void* aux) { + linuxdvb_transport_t* lcat = aux; linuxdvb_ca_close_fd(lcat, 0); return 0; } -static int linuxdvb_ca_ops_cam_is_ready - ( void *aux, en50221_slot_t *slot ) -{ - linuxdvb_transport_t *lcat = aux; - linuxdvb_ca_t *lca = linuxdvb_ca_find_slot(lcat, slot); - int fd, r; +static int linuxdvb_ca_ops_cam_is_ready(void* aux, en50221_slot_t* slot) { + linuxdvb_transport_t* lcat = aux; + linuxdvb_ca_t* lca = linuxdvb_ca_find_slot(lcat, slot); + int fd, r; assert(lca); if (lca->lca_enabled <= 0) @@ -840,19 +806,20 @@ static int linuxdvb_ca_ops_cam_is_ready return r; } -static int linuxdvb_ca_ops_pdu_write - ( void *aux, en50221_slot_t *slot, uint8_t tcnum, - const uint8_t *data, size_t datalen ) -{ - linuxdvb_transport_t *lcat = aux; - uint8_t *buf; - ssize_t l; - int r, fd = lcat->lcat_ca_fd; +static int linuxdvb_ca_ops_pdu_write(void* aux, + en50221_slot_t* slot, + uint8_t tcnum, + const uint8_t* data, + size_t datalen) { + linuxdvb_transport_t* lcat = aux; + uint8_t* buf; + ssize_t l; + int r, fd = lcat->lcat_ca_fd; if (fd < 0) return -EIO; - buf = alloca(datalen + 2); + buf = alloca(datalen + 2); buf[0] = slot->cil_number; buf[1] = tcnum; memcpy(buf + 2, data, datalen); @@ -863,34 +830,30 @@ static int linuxdvb_ca_ops_pdu_write } while (l < 0 && errno == EINTR); if (l < 0) { r = errno; - tvherror(LS_EN50221, "%s: unable to write: %s", - lcat->lcat_name, strerror(r)); + tvherror(LS_EN50221, "%s: unable to write: %s", lcat->lcat_name, strerror(r)); return -r; } else if (l != datalen + 2) { - tvherror(LS_EN50221, "%s: partial write %zd (of %zd)", - lcat->lcat_name, l, datalen + 2); + tvherror(LS_EN50221, "%s: partial write %zd (of %zd)", lcat->lcat_name, l, datalen + 2); return -EIO; } else { return 0; } } -static int linuxdvb_ca_ops_apdu_write - ( void *aux, en50221_slot_t *slot, const uint8_t *data, size_t datalen ) -{ - linuxdvb_transport_t *lcat = aux; - ca_msg_t ca_msg; - int r, fd = lcat->lcat_ca_fd; +static int +linuxdvb_ca_ops_apdu_write(void* aux, en50221_slot_t* slot, const uint8_t* data, size_t datalen) { + linuxdvb_transport_t* lcat = aux; + ca_msg_t ca_msg; + int r, fd = lcat->lcat_ca_fd; if (fd < 0) return -EIO; if (datalen > 256) { - tvherror(LS_EN50221, "%s: unable to write APDU with length %zd", - lcat->lcat_name, datalen); + tvherror(LS_EN50221, "%s: unable to write APDU with length %zd", lcat->lcat_name, datalen); return -E2BIG; } memset(&ca_msg, 0, sizeof(ca_msg)); - ca_msg.index = slot->cil_number; /* correct? */ + ca_msg.index = slot->cil_number; /* correct? */ ca_msg.length = datalen; memcpy(ca_msg.msg, data, datalen); do { @@ -898,136 +861,125 @@ static int linuxdvb_ca_ops_apdu_write } while (r < 0 && errno == EINTR); if (r < 0) { r = errno; - tvherror(LS_EN50221, "%s: unable to write APDU: %s", - lcat->lcat_name, strerror(r)); + tvherror(LS_EN50221, "%s: unable to write APDU: %s", lcat->lcat_name, strerror(r)); return -r; } return 0; } -static int linuxdvb_ca_ops_pcmcia_data_rate - ( void *aux, en50221_slot_t *slot, uint8_t *rate ) -{ - linuxdvb_transport_t *lcat = aux; - linuxdvb_ca_t *lca = linuxdvb_ca_find_slot(lcat, slot); - *rate = lca->lca_high_bitrate_mode ? 0x01 : 0x00; +static int linuxdvb_ca_ops_pcmcia_data_rate(void* aux, en50221_slot_t* slot, uint8_t* rate) { + linuxdvb_transport_t* lcat = aux; + linuxdvb_ca_t* lca = linuxdvb_ca_find_slot(lcat, slot); + *rate = lca->lca_high_bitrate_mode ? 0x01 : 0x00; tvhtrace(LS_EN50221, "%s: pcmcia data rate set to %02x", lca->lca_name, *rate); return 0; } -static int linuxdvb_ca_ops_appinfo - (void *aux, en50221_slot_t *slot, uint8_t ver, - char *name, uint8_t type, uint16_t manufacturer, uint16_t code) -{ - linuxdvb_transport_t *lcat = aux; - linuxdvb_ca_t *lca = linuxdvb_ca_find_slot(lcat, slot); +static int linuxdvb_ca_ops_appinfo(void* aux, + en50221_slot_t* slot, + uint8_t ver, + char* name, + uint8_t type, + uint16_t manufacturer, + uint16_t code) { + linuxdvb_transport_t* lcat = aux; + linuxdvb_ca_t* lca = linuxdvb_ca_find_slot(lcat, slot); if (lca) free(atomic_set_ptr((atomic_refptr_t)&lca->lca_modulename, strdup(name))); return 0; } -static int linuxdvb_ca_ops_caids - ( void *aux, en50221_slot_t *slot, uint16_t *list, int listsize ) -{ - linuxdvb_transport_t *lcat = aux; - linuxdvb_ca_t *lca = linuxdvb_ca_find_slot(lcat, slot); +static int linuxdvb_ca_ops_caids(void* aux, en50221_slot_t* slot, uint16_t* list, int listsize) { + linuxdvb_transport_t* lcat = aux; + linuxdvb_ca_t* lca = linuxdvb_ca_find_slot(lcat, slot); if (lca) dvbcam_register_cam(lca, list, listsize); return 0; } -static int linuxdvb_ca_ops_ca_close - ( void *aux, en50221_slot_t *slot ) -{ - linuxdvb_transport_t *lcat = aux; - linuxdvb_ca_t *lca = linuxdvb_ca_find_slot(lcat, slot); +static int linuxdvb_ca_ops_ca_close(void* aux, en50221_slot_t* slot) { + linuxdvb_transport_t* lcat = aux; + linuxdvb_ca_t* lca = linuxdvb_ca_find_slot(lcat, slot); if (lca) dvbcam_unregister_cam(lca); return 0; } -static int linuxdvb_ca_ops_menu - ( void *aux, en50221_slot_t *slot, htsmsg_t *menu ) -{ - linuxdvb_transport_t *lcat = aux; - linuxdvb_ca_t *lca = linuxdvb_ca_find_slot(lcat, slot); - char *s = htsmsg_json_serialize_to_str(menu, 0); +static int linuxdvb_ca_ops_menu(void* aux, en50221_slot_t* slot, htsmsg_t* menu) { + linuxdvb_transport_t* lcat = aux; + linuxdvb_ca_t* lca = linuxdvb_ca_find_slot(lcat, slot); + char* s = htsmsg_json_serialize_to_str(menu, 0); tvhinfo(LS_EN50221, "%s: ops menu: %s", lca->lca_name, s); free(s); en50221_mmi_close(slot); return 0; } -static int linuxdvb_ca_ops_enquiry - ( void *aux, en50221_slot_t *slot, htsmsg_t *enq ) -{ - linuxdvb_transport_t *lcat = aux; - linuxdvb_ca_t *lca = linuxdvb_ca_find_slot(lcat, slot); - const char *text; - char *s; - int explen; +static int linuxdvb_ca_ops_enquiry(void* aux, en50221_slot_t* slot, htsmsg_t* enq) { + linuxdvb_transport_t* lcat = aux; + linuxdvb_ca_t* lca = linuxdvb_ca_find_slot(lcat, slot); + const char* text; + char* s; + int explen; s = htsmsg_json_serialize_to_str(enq, 0); tvhinfo(LS_EN50221, "%s: ops enquiry: %s", lca->lca_name, s); free(s); explen = htsmsg_get_s32_or_default(enq, "explen", 0); - text = htsmsg_get_str(enq, "text"); + text = htsmsg_get_str(enq, "text"); if (text && lca->lca_pin_reply && lca->lca_pin_str && lca->lca_pin_match_str && - (strlen(lca->lca_pin_str) == explen) && - strstr(text, lca->lca_pin_match_str)) { + (strlen(lca->lca_pin_str) == explen) && strstr(text, lca->lca_pin_match_str)) { tvhtrace(LS_EN50221, "%s: answering to PIN enquiry", lca->lca_name); - en50221_mmi_answer(slot, (uint8_t *)lca->lca_pin_str, explen); + en50221_mmi_answer(slot, (uint8_t*)lca->lca_pin_str, explen); } en50221_mmi_close(slot); return 0; } -static int linuxdvb_ca_ops_close - ( void *aux, en50221_slot_t *slot, int delay ) -{ - linuxdvb_transport_t *lcat = aux; - linuxdvb_ca_t *lca = linuxdvb_ca_find_slot(lcat, slot); +static int linuxdvb_ca_ops_close(void* aux, en50221_slot_t* slot, int delay) { + linuxdvb_transport_t* lcat = aux; + linuxdvb_ca_t* lca = linuxdvb_ca_find_slot(lcat, slot); tvhinfo(LS_EN50221, "%s: ops close", lca->lca_name); return 0; } static en50221_ops_t linuxdvb_ca_ops = { - .cihw_reset = linuxdvb_ca_ops_reset, - .cihw_cam_is_ready = linuxdvb_ca_ops_cam_is_ready, - .cihw_pdu_write = linuxdvb_ca_ops_pdu_write, - .cihw_apdu_write = linuxdvb_ca_ops_apdu_write, - .cisw_appinfo = linuxdvb_ca_ops_appinfo, - .cisw_pcmcia_data_rate = linuxdvb_ca_ops_pcmcia_data_rate, - .cisw_caids = linuxdvb_ca_ops_caids, - .cisw_ca_close = linuxdvb_ca_ops_ca_close, - .cisw_menu = linuxdvb_ca_ops_menu, - .cisw_enquiry = linuxdvb_ca_ops_enquiry, - .cisw_close = linuxdvb_ca_ops_close, + .cihw_reset = linuxdvb_ca_ops_reset, + .cihw_cam_is_ready = linuxdvb_ca_ops_cam_is_ready, + .cihw_pdu_write = linuxdvb_ca_ops_pdu_write, + .cihw_apdu_write = linuxdvb_ca_ops_apdu_write, + .cisw_appinfo = linuxdvb_ca_ops_appinfo, + .cisw_pcmcia_data_rate = linuxdvb_ca_ops_pcmcia_data_rate, + .cisw_caids = linuxdvb_ca_ops_caids, + .cisw_ca_close = linuxdvb_ca_ops_ca_close, + .cisw_menu = linuxdvb_ca_ops_menu, + .cisw_enquiry = linuxdvb_ca_ops_enquiry, + .cisw_close = linuxdvb_ca_ops_close, }; -linuxdvb_transport_t *linuxdvb_transport_create - ( linuxdvb_adapter_t *la, int number, int slots, - const char *ca_path, const char *ci_path ) -{ - linuxdvb_transport_t *lcat; - char buf[32]; - int r; +linuxdvb_transport_t* linuxdvb_transport_create(linuxdvb_adapter_t* la, + int number, + int slots, + const char* ca_path, + const char* ci_path) { + linuxdvb_transport_t* lcat; + char buf[32]; + int r; lcat = calloc(1, sizeof(*lcat)); lcat->lcat_adapter = la; - lcat->lcat_number = number; - lcat->lcat_ca_path = strdup(ca_path); - lcat->lcat_ca_fd = -1; + lcat->lcat_number = number; + lcat->lcat_ca_path = strdup(ca_path); + lcat->lcat_ca_fd = -1; snprintf(buf, sizeof(buf), "dvbca%d", la->la_dvb_number); lcat->lcat_name = strdup(buf); - r = en50221_create_transport(&linuxdvb_ca_ops, lcat, slots, - buf, &lcat->lcat_transport); + r = en50221_create_transport(&linuxdvb_ca_ops, lcat, slots, buf, &lcat->lcat_transport); if (r < 0) { tvherror(LS_EN50221, "unable to create transport for %s", ca_path); return NULL; @@ -1045,9 +997,8 @@ linuxdvb_transport_t *linuxdvb_transport_create return lcat; } -void linuxdvb_transport_destroy ( linuxdvb_transport_t *lcat ) -{ - linuxdvb_ca_t *ca; +void linuxdvb_transport_destroy(linuxdvb_transport_t* lcat) { + linuxdvb_ca_t* ca; if (lcat == NULL) return; @@ -1067,20 +1018,17 @@ void linuxdvb_transport_destroy ( linuxdvb_transport_t *lcat ) free(lcat); } -void linuxdvb_transport_save - ( linuxdvb_transport_t *lcat, htsmsg_t *msg ) -{ - linuxdvb_ca_t *lca; - LIST_FOREACH(lca, &lcat->lcat_slots, lca_link) +void linuxdvb_transport_save(linuxdvb_transport_t* lcat, htsmsg_t* msg) { + linuxdvb_ca_t* lca; + LIST_FOREACH (lca, &lcat->lcat_slots, lca_link) linuxdvb_ca_save(lca, msg); } -static int linuxdvb_transport_refresh(linuxdvb_transport_t *lcat) -{ - linuxdvb_transport_t *lcat2; - linuxdvb_ca_t *lca; - int enabled = 0, r; - LIST_FOREACH(lca, &lcat->lcat_slots, lca_link) +static int linuxdvb_transport_refresh(linuxdvb_transport_t* lcat) { + linuxdvb_transport_t* lcat2; + linuxdvb_ca_t* lca; + int enabled = 0, r; + LIST_FOREACH (lca, &lcat->lcat_slots, lca_link) if (lca->lca_enabled) { enabled = 1; break; @@ -1095,18 +1043,20 @@ static int linuxdvb_transport_refresh(linuxdvb_transport_t *lcat) tvh_write(linuxdvb_ca_pipe.wr, "e", 1); } } else { - LIST_FOREACH(lca, &lcat->lcat_slots, lca_link) + LIST_FOREACH (lca, &lcat->lcat_slots, lca_link) linuxdvb_ca_slot_change_state(lca, CA_SLOT_STATE_DISABLED); if (linuxdvb_ca_threadid) { - LIST_FOREACH(lcat2, &linuxdvb_all_transports, lcat_all_link) + LIST_FOREACH (lcat2, &linuxdvb_all_transports, lcat_all_link) if (lcat2->lcat_enabled) { enabled = 1; break; } if (!enabled) { lcat->lcat_close_time = mclk() + sec2mono(3); - mtimer_arm_rel(&linuxdvb_ca_thread_join_timer, linuxdvb_ca_thread_join_cb, - NULL, sec2mono(5)); + mtimer_arm_rel(&linuxdvb_ca_thread_join_timer, + linuxdvb_ca_thread_join_cb, + NULL, + sec2mono(5)); } } } @@ -1114,12 +1064,9 @@ static int linuxdvb_transport_refresh(linuxdvb_transport_t *lcat) return r; } -void linuxdvb_ca_init ( void ) -{ -} +void linuxdvb_ca_init(void) {} -void linuxdvb_ca_done ( void ) -{ +void linuxdvb_ca_done(void) { linuxdvb_ca_thread_join(); } @@ -1127,12 +1074,12 @@ void linuxdvb_ca_done ( void ) * */ -void -linuxdvb_ca_enqueue_capmt - ( linuxdvb_ca_t *lca, const uint8_t *capmt, size_t capmtlen, int descramble ) -{ - uint8_t *capmt2; - size_t capmtlen2; +void linuxdvb_ca_enqueue_capmt(linuxdvb_ca_t* lca, + const uint8_t* capmt, + size_t capmtlen, + int descramble) { + uint8_t* capmt2; + size_t capmtlen2; if (!lca || !capmt) return; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_ddci.c b/src/input/mpegts/linuxdvb/linuxdvb_ddci.c index c9313b0b7..bf6bd9c90 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_ddci.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_ddci.c @@ -26,106 +26,97 @@ /* DD CI send Buffer size in number of 188 byte packages */ // FIXME: make a config parameter -#define LDDCI_SEND_BUF_NUM_DEF 1500 -#define LDDCI_RECV_BUF_NUM_DEF 1500 +#define LDDCI_SEND_BUF_NUM_DEF 1500 +#define LDDCI_RECV_BUF_NUM_DEF 1500 -#define LDDCI_SEND_BUFFER_POLL_TMO 150 /* ms */ +#define LDDCI_SEND_BUFFER_POLL_TMO 150 /* ms */ #define LDDCI_TS_SYNC_BYTE 0x47 #define LDDCI_TS_SIZE 188 #define LDDCI_TS_SCRAMBLING_CONTROL 0xC0 -#define LDDCI_TO_THREAD(_t) (linuxdvb_ddci_thread_t *)(_t) +#define LDDCI_TO_THREAD(_t) (linuxdvb_ddci_thread_t*)(_t) -#define LDDCI_WR_THREAD_STAT_TMO 10 /* sec */ -#define LDDCI_RD_THREAD_STAT_TMO 10 /* sec */ +#define LDDCI_WR_THREAD_STAT_TMO 10 /* sec */ +#define LDDCI_RD_THREAD_STAT_TMO 10 /* sec */ #define LDDCI_MIN_TS_PKT (100 * LDDCI_TS_SIZE) #define LDDCI_MIN_TS_SYN (5 * LDDCI_TS_SIZE) -typedef struct linuxdvb_ddci_thread -{ - linuxdvb_ddci_t *lddci; - int lddci_thread_running; - int lddci_thread_stop; - pthread_t lddci_thread; - tvh_mutex_t lddci_thread_lock; - tvh_cond_t lddci_thread_cond; +typedef struct linuxdvb_ddci_thread { + linuxdvb_ddci_t* lddci; + int lddci_thread_running; + int lddci_thread_stop; + pthread_t lddci_thread; + tvh_mutex_t lddci_thread_lock; + tvh_cond_t lddci_thread_cond; } linuxdvb_ddci_thread_t; -typedef struct linuxdvb_ddci_send_packet -{ - TAILQ_ENTRY(linuxdvb_ddci_send_packet) lddci_send_pkt_link; - size_t lddci_send_pkt_len; - uint8_t lddci_send_pkt_data[0]; +typedef struct linuxdvb_ddci_send_packet { + TAILQ_ENTRY(linuxdvb_ddci_send_packet) lddci_send_pkt_link; + size_t lddci_send_pkt_len; + uint8_t lddci_send_pkt_data[0]; } linuxdvb_ddci_send_packet_t; -typedef struct linuxdvb_ddci_send_buffer -{ - TAILQ_HEAD(,linuxdvb_ddci_send_packet) lddci_send_buf_queue; - uint64_t lddci_send_buf_size_max; - uint64_t lddci_send_buf_size; - tvh_mutex_t lddci_send_buf_lock; - tvh_cond_t lddci_send_buf_cond; - tvhlog_limit_t lddci_send_buf_loglimit; - int lddci_send_buf_pkgCntW; - int lddci_send_buf_pkgCntR; - int lddci_send_buf_pkgCntWL; - int lddci_send_buf_pkgCntRL; +typedef struct linuxdvb_ddci_send_buffer { + TAILQ_HEAD(, linuxdvb_ddci_send_packet) lddci_send_buf_queue; + uint64_t lddci_send_buf_size_max; + uint64_t lddci_send_buf_size; + tvh_mutex_t lddci_send_buf_lock; + tvh_cond_t lddci_send_buf_cond; + tvhlog_limit_t lddci_send_buf_loglimit; + int lddci_send_buf_pkgCntW; + int lddci_send_buf_pkgCntR; + int lddci_send_buf_pkgCntWL; + int lddci_send_buf_pkgCntRL; } linuxdvb_ddci_send_buffer_t; -typedef struct linuxdvb_ddci_wr_thread -{ - linuxdvb_ddci_thread_t; /* have to be at first */ - int lddci_cfg_send_buffer_sz; /* in TS packages */ - linuxdvb_ddci_send_buffer_t lddci_send_buffer; - mtimer_t lddci_send_buf_stat_tmo; +typedef struct linuxdvb_ddci_wr_thread { + linuxdvb_ddci_thread_t; /* have to be at first */ + int lddci_cfg_send_buffer_sz; /* in TS packages */ + linuxdvb_ddci_send_buffer_t lddci_send_buffer; + mtimer_t lddci_send_buf_stat_tmo; } linuxdvb_ddci_wr_thread_t; -typedef struct linuxdvb_ddci_rd_thread -{ - linuxdvb_ddci_thread_t; /* have to be at first */ - int lddci_cfg_recv_buffer_sz; /* in TS packages */ - mtimer_t lddci_recv_stat_tmo; - int lddci_recv_pkgCntR; - int lddci_recv_pkgCntW; - int lddci_recv_pkgCntRL; - int lddci_recv_pkgCntWL; - int lddci_recv_pkgCntS; - int lddci_recv_pkgCntSL; +typedef struct linuxdvb_ddci_rd_thread { + linuxdvb_ddci_thread_t; /* have to be at first */ + int lddci_cfg_recv_buffer_sz; /* in TS packages */ + mtimer_t lddci_recv_stat_tmo; + int lddci_recv_pkgCntR; + int lddci_recv_pkgCntW; + int lddci_recv_pkgCntRL; + int lddci_recv_pkgCntWL; + int lddci_recv_pkgCntS; + int lddci_recv_pkgCntSL; } linuxdvb_ddci_rd_thread_t; -struct linuxdvb_ddci -{ - linuxdvb_transport_t *lcat; /* back link to the associated CA transport */ - char *lddci_path; - char lddci_id[6]; - int lddci_fdW; - int lddci_fdR; - linuxdvb_ddci_wr_thread_t lddci_wr_thread; - linuxdvb_ddci_rd_thread_t lddci_rd_thread; +struct linuxdvb_ddci { + linuxdvb_transport_t* lcat; /* back link to the associated CA transport */ + char* lddci_path; + char lddci_id[6]; + int lddci_fdW; + int lddci_fdR; + linuxdvb_ddci_wr_thread_t lddci_wr_thread; + linuxdvb_ddci_rd_thread_t lddci_rd_thread; /* list of services assigned to this DD CI instance */ - idnode_set_t *lddci_services; + idnode_set_t* lddci_services; /* the same mux used for all services */ - mpegts_mux_t *lddci_mm; + mpegts_mux_t* lddci_mm; /* the same input used for all services */ - mpegts_input_t *lddci_mi; - const uint8_t *lddci_prev_tsb; + mpegts_input_t* lddci_mi; + const uint8_t* lddci_prev_tsb; }; - /* When a DD CI is disabled on the WEB UI, the global lock is held * when the threads are stopped. But this is not the case when THV is closed. * So it is OK to check if the global lock is held and to omit the locking * in this case. It can't happen, that the global lock is unlocked just after * the lock check. */ -static void -linuxdvb_ddci_mtimer_disarm ( mtimer_t *mti ) -{ +static void linuxdvb_ddci_mtimer_disarm(mtimer_t* mti) { int locked; - locked = ! tvh_mutex_trylock(&global_lock); + locked = !tvh_mutex_trylock(&global_lock); mtimer_disarm(mti); if (locked) tvh_mutex_unlock(&global_lock); @@ -138,62 +129,50 @@ linuxdvb_ddci_mtimer_disarm ( mtimer_t *mti ) * the lock check. */ static void -linuxdvb_ddci_mtimer_arm_rel - ( mtimer_t *mti, mti_callback_t *callback, void *opaque, int64_t delta ) -{ +linuxdvb_ddci_mtimer_arm_rel(mtimer_t* mti, mti_callback_t* callback, void* opaque, int64_t delta) { int locked; - locked = ! tvh_mutex_trylock(&global_lock); + locked = !tvh_mutex_trylock(&global_lock); mtimer_arm_rel(mti, callback, opaque, delta); if (locked) tvh_mutex_unlock(&global_lock); } - /***************************************************************************** * * DD CI Thread functions * *****************************************************************************/ -static void -linuxdvb_ddci_thread_init - ( linuxdvb_ddci_t *lddci, linuxdvb_ddci_thread_t *ddci_thread ) -{ - ddci_thread->lddci = lddci; +static void linuxdvb_ddci_thread_init(linuxdvb_ddci_t* lddci, linuxdvb_ddci_thread_t* ddci_thread) { + ddci_thread->lddci = lddci; ddci_thread->lddci_thread_running = 0; - ddci_thread->lddci_thread_stop = 0; + ddci_thread->lddci_thread_stop = 0; tvh_mutex_init(&ddci_thread->lddci_thread_lock, NULL); tvh_cond_init(&ddci_thread->lddci_thread_cond, 1); } -static inline int -linuxdvb_ddci_thread_running ( linuxdvb_ddci_thread_t *ddci_thread ) -{ +static inline int linuxdvb_ddci_thread_running(linuxdvb_ddci_thread_t* ddci_thread) { return ddci_thread->lddci_thread_running; } -static inline void -linuxdvb_ddci_thread_signal ( linuxdvb_ddci_thread_t *ddci_thread ) -{ +static inline void linuxdvb_ddci_thread_signal(linuxdvb_ddci_thread_t* ddci_thread) { tvh_cond_signal(&ddci_thread->lddci_thread_cond, 0); } -static int -linuxdvb_ddci_thread_start - ( linuxdvb_ddci_thread_t *ddci_thread, void *(*thread_routine) (void *), - void *arg, const char *name ) -{ +static int linuxdvb_ddci_thread_start(linuxdvb_ddci_thread_t* ddci_thread, + void* (*thread_routine)(void*), + void* arg, + const char* name) { int e = -1; if (!linuxdvb_ddci_thread_running(ddci_thread)) { tvh_mutex_lock(&ddci_thread->lddci_thread_lock); tvh_thread_create(&ddci_thread->lddci_thread, NULL, thread_routine, arg, name); do { - e = tvh_cond_wait(&ddci_thread->lddci_thread_cond, - &ddci_thread->lddci_thread_lock); + e = tvh_cond_wait(&ddci_thread->lddci_thread_cond, &ddci_thread->lddci_thread_lock); if (e == ETIMEDOUT) { - tvherror(LS_DDCI, "create thread %s error", name ); + tvherror(LS_DDCI, "create thread %s error", name); break; } } while (ERRNO_AGAIN(e)); @@ -203,46 +182,38 @@ linuxdvb_ddci_thread_start return e; } -static void -linuxdvb_ddci_thread_stop ( linuxdvb_ddci_thread_t *ddci_thread ) -{ +static void linuxdvb_ddci_thread_stop(linuxdvb_ddci_thread_t* ddci_thread) { if (linuxdvb_ddci_thread_running(ddci_thread)) { ddci_thread->lddci_thread_stop = 1; pthread_join(ddci_thread->lddci_thread, NULL); } } - /***************************************************************************** * * DD CI Send Buffer functions * *****************************************************************************/ -static void -linuxdvb_ddci_send_buffer_init - ( linuxdvb_ddci_send_buffer_t *ddci_snd_buf, uint64_t ddci_snd_buf_max ) -{ +static void linuxdvb_ddci_send_buffer_init(linuxdvb_ddci_send_buffer_t* ddci_snd_buf, + uint64_t ddci_snd_buf_max) { TAILQ_INIT(&ddci_snd_buf->lddci_send_buf_queue); ddci_snd_buf->lddci_send_buf_size_max = ddci_snd_buf_max; - ddci_snd_buf->lddci_send_buf_size = 0; + ddci_snd_buf->lddci_send_buf_size = 0; tvh_mutex_init(&ddci_snd_buf->lddci_send_buf_lock, NULL); tvh_cond_init(&ddci_snd_buf->lddci_send_buf_cond, 1); tvhlog_limit_reset(&ddci_snd_buf->lddci_send_buf_loglimit); - ddci_snd_buf->lddci_send_buf_pkgCntW = 0; - ddci_snd_buf->lddci_send_buf_pkgCntR = 0; + ddci_snd_buf->lddci_send_buf_pkgCntW = 0; + ddci_snd_buf->lddci_send_buf_pkgCntR = 0; ddci_snd_buf->lddci_send_buf_pkgCntWL = 0; ddci_snd_buf->lddci_send_buf_pkgCntRL = 0; - } /* must be called with locked mutex */ -static inline void -linuxdvb_ddci_send_buffer_remove - ( linuxdvb_ddci_send_buffer_t *ddci_snd_buf, linuxdvb_ddci_send_packet_t *sp ) -{ +static inline void linuxdvb_ddci_send_buffer_remove(linuxdvb_ddci_send_buffer_t* ddci_snd_buf, + linuxdvb_ddci_send_packet_t* sp) { if (sp) { - assert( ddci_snd_buf->lddci_send_buf_size >= sp->lddci_send_pkt_len); + assert(ddci_snd_buf->lddci_send_buf_size >= sp->lddci_send_pkt_len); ddci_snd_buf->lddci_send_buf_size -= sp->lddci_send_pkt_len; // memoryinfo_free(&mpegts_input_queue_memoryinfo, sizeof(mpegts_packet_t) + mp->mp_len); ddci_snd_buf->lddci_send_buf_pkgCntR += sp->lddci_send_pkt_len / LDDCI_TS_SIZE; @@ -250,11 +221,9 @@ linuxdvb_ddci_send_buffer_remove } } -static linuxdvb_ddci_send_packet_t * -linuxdvb_ddci_send_buffer_get - ( linuxdvb_ddci_send_buffer_t *ddci_snd_buf, int64_t tmo ) -{ - linuxdvb_ddci_send_packet_t *sp; +static linuxdvb_ddci_send_packet_t* +linuxdvb_ddci_send_buffer_get(linuxdvb_ddci_send_buffer_t* ddci_snd_buf, int64_t tmo) { + linuxdvb_ddci_send_packet_t* sp; tvh_mutex_lock(&ddci_snd_buf->lddci_send_buf_lock); @@ -268,7 +237,8 @@ linuxdvb_ddci_send_buffer_get /* Wait for a packet */ r = tvh_cond_timedwait(&ddci_snd_buf->lddci_send_buf_cond, - &ddci_snd_buf->lddci_send_buf_lock, mono); + &ddci_snd_buf->lddci_send_buf_lock, + mono); if (r == ETIMEDOUT) { break; } @@ -284,14 +254,13 @@ linuxdvb_ddci_send_buffer_get return sp; } -static void -linuxdvb_ddci_send_buffer_put - ( linuxdvb_ddci_send_buffer_t *ddci_snd_buf, const uint8_t *tsb, int len ) -{ +static void linuxdvb_ddci_send_buffer_put(linuxdvb_ddci_send_buffer_t* ddci_snd_buf, + const uint8_t* tsb, + int len) { tvh_mutex_lock(&ddci_snd_buf->lddci_send_buf_lock); if (ddci_snd_buf->lddci_send_buf_size < ddci_snd_buf->lddci_send_buf_size_max) { - linuxdvb_ddci_send_packet_t *sp; + linuxdvb_ddci_send_packet_t* sp; #if 0 /* Note: This debug output will work only for one DD CI instance! */ @@ -310,7 +279,7 @@ linuxdvb_ddci_send_buffer_put } #endif - sp = malloc(sizeof(linuxdvb_ddci_send_packet_t) + len); + sp = malloc(sizeof(linuxdvb_ddci_send_packet_t) + len); sp->lddci_send_pkt_len = len; memcpy(sp->lddci_send_pkt_data, tsb, len); ddci_snd_buf->lddci_send_buf_size += len; @@ -326,54 +295,45 @@ linuxdvb_ddci_send_buffer_put tvh_mutex_unlock(&ddci_snd_buf->lddci_send_buf_lock); } -static void -linuxdvb_ddci_send_buffer_clear ( linuxdvb_ddci_send_buffer_t *ddci_snd_buf ) -{ - linuxdvb_ddci_send_packet_t *sp; +static void linuxdvb_ddci_send_buffer_clear(linuxdvb_ddci_send_buffer_t* ddci_snd_buf) { + linuxdvb_ddci_send_packet_t* sp; tvh_mutex_lock(&ddci_snd_buf->lddci_send_buf_lock); - while ((sp = TAILQ_FIRST(&ddci_snd_buf->lddci_send_buf_queue))) - { + while ((sp = TAILQ_FIRST(&ddci_snd_buf->lddci_send_buf_queue))) { linuxdvb_ddci_send_buffer_remove(ddci_snd_buf, sp); free(sp); } - ddci_snd_buf->lddci_send_buf_pkgCntW = 0; - ddci_snd_buf->lddci_send_buf_pkgCntR = 0; + ddci_snd_buf->lddci_send_buf_pkgCntW = 0; + ddci_snd_buf->lddci_send_buf_pkgCntR = 0; ddci_snd_buf->lddci_send_buf_pkgCntWL = 0; ddci_snd_buf->lddci_send_buf_pkgCntRL = 0; tvh_mutex_unlock(&ddci_snd_buf->lddci_send_buf_lock); } -static void -linuxdvb_ddci_send_buffer_statistic - ( linuxdvb_ddci_send_buffer_t *ddci_snd_buf, char *ci_id ) -{ - int pkgCntR = ddci_snd_buf->lddci_send_buf_pkgCntR; - int pkgCntW = ddci_snd_buf->lddci_send_buf_pkgCntW; +static void linuxdvb_ddci_send_buffer_statistic(linuxdvb_ddci_send_buffer_t* ddci_snd_buf, + char* ci_id) { + int pkgCntR = ddci_snd_buf->lddci_send_buf_pkgCntR; + int pkgCntW = ddci_snd_buf->lddci_send_buf_pkgCntW; if ((pkgCntR != ddci_snd_buf->lddci_send_buf_pkgCntRL) || (pkgCntW != ddci_snd_buf->lddci_send_buf_pkgCntWL)) { - tvhtrace(LS_DDCI, "CAM %s send buff rd(-> CAM):%d, wr:%d", - ci_id, pkgCntR, pkgCntW); + tvhtrace(LS_DDCI, "CAM %s send buff rd(-> CAM):%d, wr:%d", ci_id, pkgCntR, pkgCntW); ddci_snd_buf->lddci_send_buf_pkgCntRL = pkgCntR; ddci_snd_buf->lddci_send_buf_pkgCntWL = pkgCntW; } } - /***************************************************************************** * * DD CI Writer Thread functions * *****************************************************************************/ -static void -linuxdvb_ddci_wr_thread_statistic ( void *aux ) -{ - linuxdvb_ddci_wr_thread_t *ddci_wr_thread = aux; - linuxdvb_ddci_thread_t *ddci_thread = aux; - char *ci_id = ddci_thread->lddci->lddci_id; +static void linuxdvb_ddci_wr_thread_statistic(void* aux) { + linuxdvb_ddci_wr_thread_t* ddci_wr_thread = aux; + linuxdvb_ddci_thread_t* ddci_thread = aux; + char* ci_id = ddci_thread->lddci->lddci_id; /* timer callback is executed with global lock */ lock_assert(&global_lock); @@ -381,43 +341,39 @@ linuxdvb_ddci_wr_thread_statistic ( void *aux ) linuxdvb_ddci_send_buffer_statistic(&ddci_wr_thread->lddci_send_buffer, ci_id); mtimer_arm_rel(&ddci_wr_thread->lddci_send_buf_stat_tmo, - linuxdvb_ddci_wr_thread_statistic, ddci_wr_thread, - sec2mono(LDDCI_WR_THREAD_STAT_TMO)); + linuxdvb_ddci_wr_thread_statistic, + ddci_wr_thread, + sec2mono(LDDCI_WR_THREAD_STAT_TMO)); } -static void -linuxdvb_ddci_wr_thread_statistic_clr ( linuxdvb_ddci_wr_thread_t *ddci_wr_thread ) -{ - linuxdvb_ddci_thread_t *ddci_thread = (linuxdvb_ddci_thread_t *)ddci_wr_thread; - char *ci_id = ddci_thread->lddci->lddci_id; +static void linuxdvb_ddci_wr_thread_statistic_clr(linuxdvb_ddci_wr_thread_t* ddci_wr_thread) { + linuxdvb_ddci_thread_t* ddci_thread = (linuxdvb_ddci_thread_t*)ddci_wr_thread; + char* ci_id = ddci_thread->lddci->lddci_id; linuxdvb_ddci_send_buffer_statistic(&ddci_wr_thread->lddci_send_buffer, ci_id); linuxdvb_ddci_send_buffer_clear(&ddci_wr_thread->lddci_send_buffer); - } -static void * -linuxdvb_ddci_write_thread ( void *arg ) -{ - linuxdvb_ddci_wr_thread_t *ddci_wr_thread = arg; - linuxdvb_ddci_thread_t *ddci_thread = arg; +static void* linuxdvb_ddci_write_thread(void* arg) { + linuxdvb_ddci_wr_thread_t* ddci_wr_thread = arg; + linuxdvb_ddci_thread_t* ddci_thread = arg; - int fd = ddci_thread->lddci->lddci_fdW; - char *ci_id = ddci_thread->lddci->lddci_id; + int fd = ddci_thread->lddci->lddci_fdW; + char* ci_id = ddci_thread->lddci->lddci_id; ddci_thread->lddci_thread_running = 1; - ddci_thread->lddci_thread_stop = 0; + ddci_thread->lddci_thread_stop = 0; linuxdvb_ddci_mtimer_arm_rel(&ddci_wr_thread->lddci_send_buf_stat_tmo, - linuxdvb_ddci_wr_thread_statistic, - ddci_wr_thread, - sec2mono(LDDCI_WR_THREAD_STAT_TMO)); + linuxdvb_ddci_wr_thread_statistic, + ddci_wr_thread, + sec2mono(LDDCI_WR_THREAD_STAT_TMO)); tvhtrace(LS_DDCI, "CAM %s write thread started", ci_id); linuxdvb_ddci_thread_signal(ddci_thread); while (tvheadend_is_running() && !ddci_thread->lddci_thread_stop) { - linuxdvb_ddci_send_packet_t *sp; + linuxdvb_ddci_send_packet_t* sp; sp = linuxdvb_ddci_send_buffer_get(&ddci_wr_thread->lddci_send_buffer, - LDDCI_SEND_BUFFER_POLL_TMO); + LDDCI_SEND_BUFFER_POLL_TMO); if (sp) { int r = tvh_write(fd, sp->lddci_send_pkt_data, sp->lddci_send_pkt_len); if (r) @@ -428,36 +384,31 @@ linuxdvb_ddci_write_thread ( void *arg ) linuxdvb_ddci_mtimer_disarm(&ddci_wr_thread->lddci_send_buf_stat_tmo); tvhtrace(LS_DDCI, "CAM %s write thread finished", ci_id); - ddci_thread->lddci_thread_stop = 0; + ddci_thread->lddci_thread_stop = 0; ddci_thread->lddci_thread_running = 0; return NULL; } -static inline void -linuxdvb_ddci_wr_thread_init ( linuxdvb_ddci_t *lddci ) -{ +static inline void linuxdvb_ddci_wr_thread_init(linuxdvb_ddci_t* lddci) { linuxdvb_ddci_thread_init(lddci, LDDCI_TO_THREAD(&lddci->lddci_wr_thread)); } -static int -linuxdvb_ddci_wr_thread_start ( linuxdvb_ddci_wr_thread_t *ddci_wr_thread ) -{ +static int linuxdvb_ddci_wr_thread_start(linuxdvb_ddci_wr_thread_t* ddci_wr_thread) { int e; // FIXME: Use a configuration parameter ddci_wr_thread->lddci_cfg_send_buffer_sz = LDDCI_SEND_BUF_NUM_DEF * LDDCI_TS_SIZE; linuxdvb_ddci_send_buffer_init(&ddci_wr_thread->lddci_send_buffer, - ddci_wr_thread->lddci_cfg_send_buffer_sz); + ddci_wr_thread->lddci_cfg_send_buffer_sz); e = linuxdvb_ddci_thread_start(LDDCI_TO_THREAD(ddci_wr_thread), - linuxdvb_ddci_write_thread, ddci_wr_thread, - "lnx-ddci-wr"); + linuxdvb_ddci_write_thread, + ddci_wr_thread, + "lnx-ddci-wr"); return e; } -static inline void -linuxdvb_ddci_wr_thread_stop ( linuxdvb_ddci_wr_thread_t *ddci_wr_thread ) -{ +static inline void linuxdvb_ddci_wr_thread_stop(linuxdvb_ddci_wr_thread_t* ddci_wr_thread) { /* See function linuxdvb_ddci_wr_thread_buffer_put why we lock here. */ @@ -467,10 +418,9 @@ linuxdvb_ddci_wr_thread_stop ( linuxdvb_ddci_wr_thread_t *ddci_wr_thread ) tvh_mutex_unlock(&ddci_wr_thread->lddci_thread_lock); } -static inline void -linuxdvb_ddci_wr_thread_buffer_put - ( linuxdvb_ddci_wr_thread_t *ddci_wr_thread, const uint8_t *tsb, int len ) -{ +static inline void linuxdvb_ddci_wr_thread_buffer_put(linuxdvb_ddci_wr_thread_t* ddci_wr_thread, + const uint8_t* tsb, + int len) { /* We need to lock this function against linuxdvb_ddci_wr_thread_stop, because * linuxdvb_ddci_wr_thread_buffer_put may be executed by another thread * simultaneously, although the stop function is already running. Due to the @@ -481,77 +431,68 @@ linuxdvb_ddci_wr_thread_buffer_put */ tvh_mutex_lock(&ddci_wr_thread->lddci_thread_lock); if (linuxdvb_ddci_thread_running(LDDCI_TO_THREAD(ddci_wr_thread))) - linuxdvb_ddci_send_buffer_put(&ddci_wr_thread->lddci_send_buffer, tsb, len ); + linuxdvb_ddci_send_buffer_put(&ddci_wr_thread->lddci_send_buffer, tsb, len); tvh_mutex_unlock(&ddci_wr_thread->lddci_thread_lock); } - /***************************************************************************** * * DD CI Reader Thread functions * *****************************************************************************/ -static void -linuxdvb_ddci_rd_thread_statistic ( void *aux ) -{ - linuxdvb_ddci_rd_thread_t *ddci_rd_thread = aux; - linuxdvb_ddci_thread_t *ddci_thread = aux; - char *ci_id = ddci_thread->lddci->lddci_id; - int pkgCntR = ddci_rd_thread->lddci_recv_pkgCntR; - int pkgCntW = ddci_rd_thread->lddci_recv_pkgCntW; - int pkgCntS = ddci_rd_thread->lddci_recv_pkgCntS; +static void linuxdvb_ddci_rd_thread_statistic(void* aux) { + linuxdvb_ddci_rd_thread_t* ddci_rd_thread = aux; + linuxdvb_ddci_thread_t* ddci_thread = aux; + char* ci_id = ddci_thread->lddci->lddci_id; + int pkgCntR = ddci_rd_thread->lddci_recv_pkgCntR; + int pkgCntW = ddci_rd_thread->lddci_recv_pkgCntW; + int pkgCntS = ddci_rd_thread->lddci_recv_pkgCntS; /* timer callback is executed with global lock */ lock_assert(&global_lock); if ((pkgCntR != ddci_rd_thread->lddci_recv_pkgCntRL) || (pkgCntW != ddci_rd_thread->lddci_recv_pkgCntWL)) { - tvhtrace(LS_DDCI, "CAM %s recv rd(CAM ->):%d, wr:%d", - ci_id, pkgCntR, pkgCntW); + tvhtrace(LS_DDCI, "CAM %s recv rd(CAM ->):%d, wr:%d", ci_id, pkgCntR, pkgCntW); ddci_rd_thread->lddci_recv_pkgCntRL = pkgCntR; ddci_rd_thread->lddci_recv_pkgCntWL = pkgCntW; } if ((pkgCntS != ddci_rd_thread->lddci_recv_pkgCntSL)) { - tvhtrace(LS_DDCI, "CAM %s got %d scrambled packets from CAM", - ci_id, pkgCntS); + tvhtrace(LS_DDCI, "CAM %s got %d scrambled packets from CAM", ci_id, pkgCntS); ddci_rd_thread->lddci_recv_pkgCntSL = pkgCntS; } mtimer_arm_rel(&ddci_rd_thread->lddci_recv_stat_tmo, - linuxdvb_ddci_rd_thread_statistic, ddci_rd_thread, - sec2mono(LDDCI_RD_THREAD_STAT_TMO)); + linuxdvb_ddci_rd_thread_statistic, + ddci_rd_thread, + sec2mono(LDDCI_RD_THREAD_STAT_TMO)); } -static void -linuxdvb_ddci_rd_thread_statistic_clr ( linuxdvb_ddci_rd_thread_t *ddci_rd_thread ) -{ - ddci_rd_thread->lddci_recv_pkgCntR = 0; - ddci_rd_thread->lddci_recv_pkgCntW = 0; +static void linuxdvb_ddci_rd_thread_statistic_clr(linuxdvb_ddci_rd_thread_t* ddci_rd_thread) { + ddci_rd_thread->lddci_recv_pkgCntR = 0; + ddci_rd_thread->lddci_recv_pkgCntW = 0; ddci_rd_thread->lddci_recv_pkgCntRL = 0; ddci_rd_thread->lddci_recv_pkgCntWL = 0; - ddci_rd_thread->lddci_recv_pkgCntS = 0; + ddci_rd_thread->lddci_recv_pkgCntS = 0; ddci_rd_thread->lddci_recv_pkgCntSL = 0; } -static inline int -ddci_ts_sync_count ( const uint8_t *tsb, int len ) -{ - const uint8_t *start = tsb; +static inline int ddci_ts_sync_count(const uint8_t* tsb, int len) { + const uint8_t* start = tsb; -#define LDDCI_TS_SIZE_10 (LDDCI_TS_SIZE * 10) +#define LDDCI_TS_SIZE_10 (LDDCI_TS_SIZE * 10) while (len >= LDDCI_TS_SIZE) { - if (len >= LDDCI_TS_SIZE_10 && - tsb[0*LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && - tsb[1*LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && - tsb[2*LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && - tsb[3*LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && - tsb[4*LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && - tsb[5*LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && - tsb[6*LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && - tsb[7*LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && - tsb[8*LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && - tsb[9*LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE) { + if (len >= LDDCI_TS_SIZE_10 && tsb[0 * LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && + tsb[1 * LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && + tsb[2 * LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && + tsb[3 * LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && + tsb[4 * LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && + tsb[5 * LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && + tsb[6 * LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && + tsb[7 * LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && + tsb[8 * LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE && + tsb[9 * LDDCI_TS_SIZE] == LDDCI_TS_SYNC_BYTE) { len -= LDDCI_TS_SIZE_10; tsb += LDDCI_TS_SIZE_10; } else if (*tsb == LDDCI_TS_SYNC_BYTE) { @@ -564,13 +505,10 @@ ddci_ts_sync_count ( const uint8_t *tsb, int len ) return tsb - start; } -static int -ddci_ts_sync_search ( const uint8_t *tsb, int len ) -{ +static int ddci_ts_sync_search(const uint8_t* tsb, int len) { int skipped = 0; - while ((len > LDDCI_MIN_TS_SYN) && - (ddci_ts_sync_count(tsb, len) < LDDCI_MIN_TS_SYN)) { + while ((len > LDDCI_MIN_TS_SYN) && (ddci_ts_sync_count(tsb, len) < LDDCI_MIN_TS_SYN)) { tsb++; len--; skipped++; @@ -578,9 +516,7 @@ ddci_ts_sync_search ( const uint8_t *tsb, int len ) return skipped; } -static inline int -ddci_ts_sync ( const uint8_t *tsb, int len ) -{ +static inline int ddci_ts_sync(const uint8_t* tsb, int len) { /* it is enough to check the first byte for sync, because the data * written into the CAM was completely in sync. In fact this check is * required only for the first synchronization phase or when another @@ -589,45 +525,43 @@ ddci_ts_sync ( const uint8_t *tsb, int len ) return *tsb == LDDCI_TS_SYNC_BYTE ? 0 : ddci_ts_sync_search(tsb, len); } -static inline int -ddci_is_scrambled(const uint8_t *tsb) -{ +static inline int ddci_is_scrambled(const uint8_t* tsb) { return tsb[3] & LDDCI_TS_SCRAMBLING_CONTROL; } -static void * -linuxdvb_ddci_read_thread ( void *arg ) -{ - linuxdvb_ddci_rd_thread_t *ddci_rd_thread = arg; - linuxdvb_ddci_thread_t *ddci_thread = arg; - int fd = ddci_thread->lddci->lddci_fdR; - char *ci_id = ddci_thread->lddci->lddci_id; - tvhpoll_event_t ev[1]; - tvhpoll_t *efd; - sbuf_t sb; +static void* linuxdvb_ddci_read_thread(void* arg) { + linuxdvb_ddci_rd_thread_t* ddci_rd_thread = arg; + linuxdvb_ddci_thread_t* ddci_thread = arg; + int fd = ddci_thread->lddci->lddci_fdR; + char* ci_id = ddci_thread->lddci->lddci_id; + tvhpoll_event_t ev[1]; + tvhpoll_t* efd; + sbuf_t sb; /* Setup poll */ efd = tvhpoll_create(1); tvhpoll_add1(efd, fd, TVHPOLL_IN, NULL); /* Allocate memory */ - sbuf_init_fixed(&sb, MINMAX(ddci_rd_thread->lddci_cfg_recv_buffer_sz, - LDDCI_TS_SIZE * 100, LDDCI_TS_SIZE * 10000)); + sbuf_init_fixed(&sb, + MINMAX(ddci_rd_thread->lddci_cfg_recv_buffer_sz, LDDCI_TS_SIZE * 100, LDDCI_TS_SIZE * 10000)); ddci_thread->lddci_thread_running = 1; - ddci_thread->lddci_thread_stop = 0; + ddci_thread->lddci_thread_stop = 0; linuxdvb_ddci_rd_thread_statistic_clr(ddci_rd_thread); linuxdvb_ddci_mtimer_arm_rel(&ddci_rd_thread->lddci_recv_stat_tmo, - linuxdvb_ddci_rd_thread_statistic, ddci_rd_thread, - sec2mono(LDDCI_RD_THREAD_STAT_TMO)); + linuxdvb_ddci_rd_thread_statistic, + ddci_rd_thread, + sec2mono(LDDCI_RD_THREAD_STAT_TMO)); tvhtrace(LS_DDCI, "CAM %s read thread started", ci_id); linuxdvb_ddci_thread_signal(ddci_thread); while (tvheadend_is_running() && !ddci_thread->lddci_thread_stop) { - int nfds, num_pkg, pkg_chk = 0, scrambled = 0; + int nfds, num_pkg, pkg_chk = 0, scrambled = 0; ssize_t n; nfds = tvhpoll_wait(efd, ev, 1, 150); - if (nfds <= 0) continue; + if (nfds <= 0) + continue; /* Read */ errno = 0; @@ -642,24 +576,23 @@ linuxdvb_ddci_read_thread ( void *arg ) } if (sb.sb_ptr > 0) { - int len, skip; - uint8_t *tsb; + int len, skip; + uint8_t* tsb; len = sb.sb_ptr; if (len < LDDCI_MIN_TS_PKT) - continue; + continue; - tsb = sb.sb_data; + tsb = sb.sb_data; skip = ddci_ts_sync(tsb, len); if (skip) { - tvhwarn(LS_DDCI, "CAM %s skipped %d bytes to sync on start of TS packet", - ci_id, skip); + tvhwarn(LS_DDCI, "CAM %s skipped %d bytes to sync on start of TS packet", ci_id, skip); sbuf_cut(&sb, skip); len = sb.sb_ptr; } if (len < LDDCI_MIN_TS_SYN) - continue; + continue; /* receive only whole packets */ len -= len % LDDCI_TS_SIZE; @@ -678,8 +611,7 @@ linuxdvb_ddci_read_thread ( void *arg ) } ddci_rd_thread->lddci_recv_pkgCntS += scrambled; - mpegts_input_postdemux(ddci_thread->lddci->lddci_mi, - ddci_thread->lddci->lddci_mm, tsb, len); + mpegts_input_postdemux(ddci_thread->lddci->lddci_mi, ddci_thread->lddci->lddci_mm, tsb, len); ddci_rd_thread->lddci_recv_pkgCntW += num_pkg; @@ -697,54 +629,45 @@ linuxdvb_ddci_read_thread ( void *arg ) tvhpoll_destroy(efd); linuxdvb_ddci_mtimer_disarm(&ddci_rd_thread->lddci_recv_stat_tmo); tvhtrace(LS_DDCI, "CAM %s read thread finished", ci_id); - ddci_thread->lddci_thread_stop = 0; + ddci_thread->lddci_thread_stop = 0; ddci_thread->lddci_thread_running = 0; return NULL; } -static inline void -linuxdvb_ddci_rd_thread_init ( linuxdvb_ddci_t *lddci ) -{ +static inline void linuxdvb_ddci_rd_thread_init(linuxdvb_ddci_t* lddci) { linuxdvb_ddci_thread_init(lddci, LDDCI_TO_THREAD(&lddci->lddci_rd_thread)); } -static int -linuxdvb_ddci_rd_thread_start ( linuxdvb_ddci_rd_thread_t *ddci_rd_thread ) -{ +static int linuxdvb_ddci_rd_thread_start(linuxdvb_ddci_rd_thread_t* ddci_rd_thread) { int e; // FIXME: Use a configuration parameter ddci_rd_thread->lddci_cfg_recv_buffer_sz = LDDCI_RECV_BUF_NUM_DEF * LDDCI_TS_SIZE; e = linuxdvb_ddci_thread_start(LDDCI_TO_THREAD(ddci_rd_thread), - linuxdvb_ddci_read_thread, ddci_rd_thread, - "ldvb-ddci-rd"); + linuxdvb_ddci_read_thread, + ddci_rd_thread, + "ldvb-ddci-rd"); return e; } -static inline void -linuxdvb_ddci_rd_thread_stop ( linuxdvb_ddci_rd_thread_t *ddci_rd_thread ) -{ +static inline void linuxdvb_ddci_rd_thread_stop(linuxdvb_ddci_rd_thread_t* ddci_rd_thread) { linuxdvb_ddci_thread_stop(LDDCI_TO_THREAD(ddci_rd_thread)); } - /***************************************************************************** * * DD CI API functions * *****************************************************************************/ -linuxdvb_ddci_t * -linuxdvb_ddci_create ( linuxdvb_transport_t *lcat, const char *ci_path) -{ - linuxdvb_ddci_t *lddci; +linuxdvb_ddci_t* linuxdvb_ddci_create(linuxdvb_transport_t* lcat, const char* ci_path) { + linuxdvb_ddci_t* lddci; - lddci = calloc(1, sizeof(*lddci)); - lddci->lcat = lcat; + lddci = calloc(1, sizeof(*lddci)); + lddci->lcat = lcat; lddci->lddci_path = strdup(ci_path); - snprintf(lddci->lddci_id, sizeof(lddci->lddci_id), "ci%u", - lcat->lcat_adapter->la_dvb_number); + snprintf(lddci->lddci_id, sizeof(lddci->lddci_id), "ci%u", lcat->lcat_adapter->la_dvb_number); lddci->lddci_fdW = -1; lddci->lddci_fdR = -1; linuxdvb_ddci_wr_thread_init(lddci); @@ -756,9 +679,7 @@ linuxdvb_ddci_create ( linuxdvb_transport_t *lcat, const char *ci_path) return lddci; } -void -linuxdvb_ddci_destroy ( linuxdvb_ddci_t *lddci ) -{ +void linuxdvb_ddci_destroy(linuxdvb_ddci_t* lddci) { if (!lddci) return; tvhtrace(LS_DDCI, "destroy %s %s", lddci->lddci_id, lddci->lddci_path); @@ -768,53 +689,63 @@ linuxdvb_ddci_destroy ( linuxdvb_ddci_t *lddci ) free(lddci); } -void -linuxdvb_ddci_close ( linuxdvb_ddci_t *lddci ) -{ +void linuxdvb_ddci_close(linuxdvb_ddci_t* lddci) { int closed = 0; if (lddci->lddci_fdW >= 0) { - tvhtrace(LS_DDCI, "closing write %s %s (fd %d)", - lddci->lddci_id, lddci->lddci_path, lddci->lddci_fdW); + tvhtrace(LS_DDCI, + "closing write %s %s (fd %d)", + lddci->lddci_id, + lddci->lddci_path, + lddci->lddci_fdW); linuxdvb_ddci_wr_thread_stop(&lddci->lddci_wr_thread); close(lddci->lddci_fdW); lddci->lddci_fdW = -1; - closed = 1; + closed = 1; } if (lddci->lddci_fdR >= 0) { - tvhtrace(LS_DDCI, "closing read %s %s (fd %d)", - lddci->lddci_id, lddci->lddci_path, lddci->lddci_fdR); + tvhtrace(LS_DDCI, + "closing read %s %s (fd %d)", + lddci->lddci_id, + lddci->lddci_path, + lddci->lddci_fdR); linuxdvb_ddci_rd_thread_stop(&lddci->lddci_rd_thread); close(lddci->lddci_fdR); lddci->lddci_fdR = -1; - closed = 1; + closed = 1; } if (closed) tvhtrace(LS_DDCI, "CAM %s closed", lddci->lddci_id); } -int -linuxdvb_ddci_open ( linuxdvb_ddci_t *lddci ) -{ +int linuxdvb_ddci_open(linuxdvb_ddci_t* lddci) { int ret = 0; if (lddci->lddci_fdW < 0) { lddci->lddci_fdW = tvh_open(lddci->lddci_path, O_WRONLY, 0); - tvhtrace(LS_DDCI, "opening %s %s for write (fd %d)", - lddci->lddci_id, lddci->lddci_path, lddci->lddci_fdW); + tvhtrace(LS_DDCI, + "opening %s %s for write (fd %d)", + lddci->lddci_id, + lddci->lddci_path, + lddci->lddci_fdW); lddci->lddci_fdR = tvh_open(lddci->lddci_path, O_RDONLY | O_NONBLOCK, 0); - tvhtrace(LS_DDCI, "opening %s %s for read (fd %d)", - lddci->lddci_id, lddci->lddci_path, lddci->lddci_fdR); + tvhtrace(LS_DDCI, + "opening %s %s for read (fd %d)", + lddci->lddci_id, + lddci->lddci_path, + lddci->lddci_fdR); if (lddci->lddci_fdW >= 0 && lddci->lddci_fdR >= 0) { ret = linuxdvb_ddci_wr_thread_start(&lddci->lddci_wr_thread); if (!ret) ret = linuxdvb_ddci_rd_thread_start(&lddci->lddci_rd_thread); - } - else { - tvhtrace(LS_DDCI, "open write/read failed %s %s (fd-W %d, fd-R %d)", - lddci->lddci_id, lddci->lddci_path, lddci->lddci_fdW, - lddci->lddci_fdR); + } else { + tvhtrace(LS_DDCI, + "open write/read failed %s %s (fd-W %d, fd-R %d)", + lddci->lddci_id, + lddci->lddci_path, + lddci->lddci_fdW, + lddci->lddci_fdR); ret = -1; } } @@ -827,10 +758,7 @@ linuxdvb_ddci_open ( linuxdvb_ddci_t *lddci ) return ret; } -void -linuxdvb_ddci_put - ( linuxdvb_ddci_t *lddci, service_t *t, const uint8_t *tsb, int len ) -{ +void linuxdvb_ddci_put(linuxdvb_ddci_t* lddci, service_t* t, const uint8_t* tsb, int len) { /* ignore duplicates * Note: Checking only the pointer is possible, because the calling * functions will execute the descrambler for the special PIDs in a @@ -841,22 +769,21 @@ linuxdvb_ddci_put * This allows to know which packed is for which service, even if the PAT, * CAT or EIT is the same, when they originally came from the same * transponder. */ - if (lddci->lddci_prev_tsb == tsb) return; + if (lddci->lddci_prev_tsb == tsb) + return; lddci->lddci_prev_tsb = tsb; /* FIXME: For MTD add here the PID translator * And also remove the CAT from the stream and generate a faked one. */ - linuxdvb_ddci_wr_thread_buffer_put(&lddci->lddci_wr_thread, tsb, len ); + linuxdvb_ddci_wr_thread_buffer_put(&lddci->lddci_wr_thread, tsb, len); } -void -linuxdvb_ddci_assign ( linuxdvb_ddci_t *lddci, service_t *t ) -{ +void linuxdvb_ddci_assign(linuxdvb_ddci_t* lddci, service_t* t) { if (!idnode_set_exists(lddci->lddci_services, &t->s_id)) { - mpegts_service_t *s = (mpegts_service_t *)t; - const char *txt = ""; + mpegts_service_t* s = (mpegts_service_t*)t; + const char* txt = ""; /* first service? -> store common data (for MCD all services have to * have the same MUX/Input */ @@ -865,21 +792,19 @@ linuxdvb_ddci_assign ( linuxdvb_ddci_t *lddci, service_t *t ) lddci->lddci_mi = s->s_dvb_active_input; } else { txt = "(MCD) "; - assert( lddci->lddci_mm == s->s_dvb_mux); - assert( lddci->lddci_mi == s->s_dvb_active_input); + assert(lddci->lddci_mm == s->s_dvb_mux); + assert(lddci->lddci_mi == s->s_dvb_active_input); } - tvhnotice(LS_DDCI, "CAM %s %sassigned to %p", lddci->lddci_id, txt, t ); + tvhnotice(LS_DDCI, "CAM %s %sassigned to %p", lddci->lddci_id, txt, t); idnode_set_add(lddci->lddci_services, &t->s_id, NULL, NULL); } } -void -linuxdvb_ddci_unassign ( linuxdvb_ddci_t *lddci, service_t *t ) -{ +void linuxdvb_ddci_unassign(linuxdvb_ddci_t* lddci, service_t* t) { if (idnode_set_exists(lddci->lddci_services, &t->s_id)) { - tvhnotice(LS_DDCI, "CAM %s unassigned from %p", lddci->lddci_id, t ); + tvhnotice(LS_DDCI, "CAM %s unassigned from %p", lddci->lddci_id, t); idnode_set_remove(lddci->lddci_services, &t->s_id); } @@ -891,16 +816,16 @@ linuxdvb_ddci_unassign ( linuxdvb_ddci_t *lddci, service_t *t ) } } -int -linuxdvb_ddci_do_not_assign ( linuxdvb_ddci_t *lddci, service_t *t, int multi ) -{ - mpegts_service_t *s = (mpegts_service_t *)t; +int linuxdvb_ddci_do_not_assign(linuxdvb_ddci_t* lddci, service_t* t, int multi) { + mpegts_service_t* s = (mpegts_service_t*)t; /* nothing assigned? */ - if (!lddci->lddci_mm) return 0; + if (!lddci->lddci_mm) + return 0; /* CAM can do multi channel decoding and new service uses the same mux? */ - if (multi && (lddci->lddci_mm == s->s_dvb_mux)) return 0; + if (multi && (lddci->lddci_mm == s->s_dvb_mux)) + return 0; return 1; } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_en50494.c b/src/input/mpegts/linuxdvb/linuxdvb_en50494.c index 9ea7f783e..2758511d2 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_en50494.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_en50494.c @@ -22,7 +22,8 @@ * * compare transport-stream-id from stream with id in config * * check continuity of the pcr-counter * * when one point is given -> retry - * * delay time is easily random, but in standard is special (complicated) way described (cap. 8). + * * delay time is easily random, but in standard is special (complicated) way described (cap. + * 8). */ #include "tvheadend.h" @@ -38,24 +39,24 @@ * Static definition * *************************************************************************/ -#define LINUXDVB_EN50494_NOPIN 256 +#define LINUXDVB_EN50494_NOPIN 256 -#define LINUXDVB_EN50494_FRAME 0xE0 +#define LINUXDVB_EN50494_FRAME 0xE0 /* addresses 0x00, 0x10 and 0x11 are possible */ -#define LINUXDVB_EN50494_ADDRESS 0x10 +#define LINUXDVB_EN50494_ADDRESS 0x10 -#define LINUXDVB_EN50494_CMD_NORMAL 0x5A -#define LINUXDVB_EN50494_CMD_NORMAL_MULTIHOME 0x5C +#define LINUXDVB_EN50494_CMD_NORMAL 0x5A +#define LINUXDVB_EN50494_CMD_NORMAL_MULTIHOME 0x5C /* special modes not implemented yet */ #define LINUXDVB_EN50494_CMD_SPECIAL 0x5B #define LINUXDVB_EN50494_CMD_SPECIAL_MULTIHOME 0x5D -#define LINUXDVB_EN50494_SAT_A 0x00 -#define LINUXDVB_EN50494_SAT_B 0x01 +#define LINUXDVB_EN50494_SAT_A 0x00 +#define LINUXDVB_EN50494_SAT_B 0x01 /* EN50607 */ -#define LINUXDVB_EN50607_FRAME_NORMAL 0x70 -#define LINUXDVB_EN50607_FRAME_MULTIHOME 0x71 +#define LINUXDVB_EN50607_FRAME_NORMAL 0x70 +#define LINUXDVB_EN50607_FRAME_MULTIHOME 0x71 /* ************************************************************************** * Class definition @@ -65,61 +66,49 @@ static tvh_mutex_t linuxdvb_en50494_lock; static void -linuxdvb_en50494_class_get_title - ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) -{ - const char *title = N_("Unicable I (EN50494)"); +linuxdvb_en50494_class_get_title(idnode_t* o, const char* lang, char* dst, size_t dstsize) { + const char* title = N_("Unicable I (EN50494)"); snprintf(dst, dstsize, "%s", tvh_gettext_lang(lang, title)); } static void -linuxdvb_en50607_class_get_title - ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) -{ - const char *title = N_("Unicable II (EN50607)"); +linuxdvb_en50607_class_get_title(idnode_t* o, const char* lang, char* dst, size_t dstsize) { + const char* title = N_("Unicable II (EN50607)"); snprintf(dst, dstsize, "%s", tvh_gettext_lang(lang, title)); } -static htsmsg_t * -linuxdvb_en50494_position_list ( void *o, const char *lang ) -{ - uint32_t i; - htsmsg_t *m = htsmsg_create_list(); +static htsmsg_t* linuxdvb_en50494_position_list(void* o, const char* lang) { + uint32_t i; + htsmsg_t* m = htsmsg_create_list(); for (i = 0; i < 2; i++) { htsmsg_add_u32(m, NULL, i); } return m; } -htsmsg_t * -linuxdvb_en50494_id_list ( void *o, const char *lang ) -{ - uint32_t i; - htsmsg_t *m = htsmsg_create_list(); +htsmsg_t* linuxdvb_en50494_id_list(void* o, const char* lang) { + uint32_t i; + htsmsg_t* m = htsmsg_create_list(); for (i = 0; i < 8; i++) { htsmsg_add_u32(m, NULL, i); } return m; } -htsmsg_t * -linuxdvb_en50607_id_list ( void *o, const char *lang ) -{ - uint32_t i; - htsmsg_t *m = htsmsg_create_list(); +htsmsg_t* linuxdvb_en50607_id_list(void* o, const char* lang) { + uint32_t i; + htsmsg_t* m = htsmsg_create_list(); for (i = 0; i < 32; i++) { htsmsg_add_u32(m, NULL, i); } return m; } -htsmsg_t * -linuxdvb_en50494_pin_list ( void *o, const char *lang ) -{ +htsmsg_t* linuxdvb_en50494_pin_list(void* o, const char* lang) { int32_t i; - htsmsg_t *m = htsmsg_create_list(); - htsmsg_t *e; + htsmsg_t* m = htsmsg_create_list(); + htsmsg_t* e; e = htsmsg_create_map(); htsmsg_add_u32(e, "key", 256); @@ -137,134 +126,122 @@ linuxdvb_en50494_pin_list ( void *o, const char *lang ) extern const idclass_t linuxdvb_diseqc_class; -const idclass_t linuxdvb_en50494_class = -{ - .ic_super = &linuxdvb_diseqc_class, - .ic_class = "linuxdvb_en50494", - .ic_caption = N_("en50494"), - .ic_get_title = linuxdvb_en50494_class_get_title, - .ic_properties = (const property_t[]) { - { - .type = PT_U32, - .id = "powerup_time", - .name = N_("Power up time (ms) (10-500)"), - .desc = N_("Time (in milliseconds) for the Unicable device to power up."), - .off = offsetof(linuxdvb_en50494_t, le_powerup_time), - .def.u32 = 15, - }, - { - .type = PT_U32, - .id = "cmd_time", - .name = N_("Command time (ms) (10-300)"), - .desc = N_("Time (in milliseconds) for a command to complete."), - .off = offsetof(linuxdvb_en50494_t, le_cmd_time), - .def.u32 = 50 - }, - { - .type = PT_U16, - .id = "id", - .name = N_("SCR (ID)"), - .desc = N_("SCR (Satellite Channel Router) ID."), - .off = offsetof(linuxdvb_en50494_t, le_id), - .list = linuxdvb_en50494_id_list, - }, - { - .type = PT_U16, - .id = "frequency", - .name = N_("Frequency (MHz)"), - .desc = N_("User Band Frequency (in MHz)."), - .off = offsetof(linuxdvb_en50494_t, le_frequency), - }, - { - .type = PT_U16, - .id = "pin", - .name = N_("PIN"), - .desc = N_("PIN."), - .off = offsetof(linuxdvb_en50494_t, le_pin), - .list = linuxdvb_en50494_pin_list, - }, - { - .type = PT_U16, - .id = "position", - .name = N_("Position"), - .desc = N_("Position ID."), - .off = offsetof(linuxdvb_en50494_t, le_position), - .list = linuxdvb_en50494_position_list, - }, - {} - } -}; - -const idclass_t linuxdvb_en50607_class = -{ - .ic_super = &linuxdvb_diseqc_class, - .ic_class = "linuxdvb_en50607", - .ic_caption = N_("en50607"), - .ic_get_title = linuxdvb_en50607_class_get_title, - .ic_properties = (const property_t[]) { - { - .type = PT_U32, - .id = "powerup_time", - .name = N_("Power up time (ms) (10-500)"), - .desc = N_("Time (in milliseconds) for the Unicable device to power up."), - .off = offsetof(linuxdvb_en50494_t, le_powerup_time), - .def.u32 = 15, - }, - { - .type = PT_U32, - .id = "cmd_time", - .name = N_("Command time (ms) (10-300)"), - .desc = N_("Time (in milliseconds) for a command to complete."), - .off = offsetof(linuxdvb_en50494_t, le_cmd_time), - .def.u32 = 50 - }, - { - .type = PT_U16, - .id = "id", - .name = N_("SCR (ID)"), - .desc = N_("SCR (Satellite Channel Router) ID."), - .off = offsetof(linuxdvb_en50494_t, le_id), - .list = linuxdvb_en50607_id_list, - }, - { - .type = PT_U16, - .id = "frequency", - .name = N_("Frequency (MHz)"), - .desc = N_("User Band Frequency (in MHz)."), - .off = offsetof(linuxdvb_en50494_t, le_frequency), - }, - { - .type = PT_U16, - .id = "pin", - .name = N_("PIN"), - .desc = N_("PIN."), - .off = offsetof(linuxdvb_en50494_t, le_pin), - .list = linuxdvb_en50494_pin_list, - }, - { - .type = PT_U16, - .id = "position", - .name = N_("Position"), - .desc = N_("Position ID."), - .off = offsetof(linuxdvb_en50494_t, le_position), - .list = linuxdvb_en50494_position_list, - }, - {} - } -}; +const idclass_t linuxdvb_en50494_class = {.ic_super = &linuxdvb_diseqc_class, + .ic_class = "linuxdvb_en50494", + .ic_caption = N_("en50494"), + .ic_get_title = linuxdvb_en50494_class_get_title, + .ic_properties = (const property_t[]){ + { + .type = PT_U32, + .id = "powerup_time", + .name = N_("Power up time (ms) (10-500)"), + .desc = N_("Time (in milliseconds) for the Unicable device to power up."), + .off = offsetof(linuxdvb_en50494_t, le_powerup_time), + .def.u32 = 15, + }, + {.type = PT_U32, + .id = "cmd_time", + .name = N_("Command time (ms) (10-300)"), + .desc = N_("Time (in milliseconds) for a command to complete."), + .off = offsetof(linuxdvb_en50494_t, le_cmd_time), + .def.u32 = 50}, + { + .type = PT_U16, + .id = "id", + .name = N_("SCR (ID)"), + .desc = N_("SCR (Satellite Channel Router) ID."), + .off = offsetof(linuxdvb_en50494_t, le_id), + .list = linuxdvb_en50494_id_list, + }, + { + .type = PT_U16, + .id = "frequency", + .name = N_("Frequency (MHz)"), + .desc = N_("User Band Frequency (in MHz)."), + .off = offsetof(linuxdvb_en50494_t, le_frequency), + }, + { + .type = PT_U16, + .id = "pin", + .name = N_("PIN"), + .desc = N_("PIN."), + .off = offsetof(linuxdvb_en50494_t, le_pin), + .list = linuxdvb_en50494_pin_list, + }, + { + .type = PT_U16, + .id = "position", + .name = N_("Position"), + .desc = N_("Position ID."), + .off = offsetof(linuxdvb_en50494_t, le_position), + .list = linuxdvb_en50494_position_list, + }, + {}}}; + +const idclass_t linuxdvb_en50607_class = {.ic_super = &linuxdvb_diseqc_class, + .ic_class = "linuxdvb_en50607", + .ic_caption = N_("en50607"), + .ic_get_title = linuxdvb_en50607_class_get_title, + .ic_properties = (const property_t[]){ + { + .type = PT_U32, + .id = "powerup_time", + .name = N_("Power up time (ms) (10-500)"), + .desc = N_("Time (in milliseconds) for the Unicable device to power up."), + .off = offsetof(linuxdvb_en50494_t, le_powerup_time), + .def.u32 = 15, + }, + {.type = PT_U32, + .id = "cmd_time", + .name = N_("Command time (ms) (10-300)"), + .desc = N_("Time (in milliseconds) for a command to complete."), + .off = offsetof(linuxdvb_en50494_t, le_cmd_time), + .def.u32 = 50}, + { + .type = PT_U16, + .id = "id", + .name = N_("SCR (ID)"), + .desc = N_("SCR (Satellite Channel Router) ID."), + .off = offsetof(linuxdvb_en50494_t, le_id), + .list = linuxdvb_en50607_id_list, + }, + { + .type = PT_U16, + .id = "frequency", + .name = N_("Frequency (MHz)"), + .desc = N_("User Band Frequency (in MHz)."), + .off = offsetof(linuxdvb_en50494_t, le_frequency), + }, + { + .type = PT_U16, + .id = "pin", + .name = N_("PIN"), + .desc = N_("PIN."), + .off = offsetof(linuxdvb_en50494_t, le_pin), + .list = linuxdvb_en50494_pin_list, + }, + { + .type = PT_U16, + .id = "position", + .name = N_("Position"), + .desc = N_("Position ID."), + .off = offsetof(linuxdvb_en50494_t, le_position), + .list = linuxdvb_en50494_position_list, + }, + {}}}; /* ************************************************************************** * Class methods * *************************************************************************/ -static int -linuxdvb_en50494_freq0 - ( linuxdvb_en50494_t *le, int freq, int *rfreq, uint16_t *t ) -{ +static int linuxdvb_en50494_freq0(linuxdvb_en50494_t* le, int freq, int* rfreq, uint16_t* t) { /* transponder value - t */ *t = round((((freq / 1000) + 2 + le->le_frequency) / 4) - 350); if (*t >= 1023) { - tvherror(LS_EN50494, "transponder value bigger than 1023 for freq %d (%d)", freq, le->le_frequency); + tvherror(LS_EN50494, + "transponder value bigger than 1023 for freq %d (%d)", + freq, + le->le_frequency); return -1; } @@ -273,14 +250,14 @@ linuxdvb_en50494_freq0 return 0; } -static int -linuxdvb_en50607_freq0 - ( linuxdvb_en50494_t *le, int freq, int *rfreq, uint16_t *t ) -{ +static int linuxdvb_en50607_freq0(linuxdvb_en50494_t* le, int freq, int* rfreq, uint16_t* t) { /* transponder value - t */ *t = round((double)freq / 1000) - 100; if (*t > 2047) { - tvherror(LS_EN50494, "transponder value bigger than 2047 for freq %d (%d)", freq, le->le_frequency); + tvherror(LS_EN50494, + "transponder value bigger than 2047 for freq %d (%d)", + freq, + le->le_frequency); return -1; } @@ -289,38 +266,33 @@ linuxdvb_en50607_freq0 return 0; } -static int -linuxdvb_en50494_freq - ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, int freq ) -{ - linuxdvb_en50494_t *le = (linuxdvb_en50494_t*) ld; - int rfreq; - uint16_t t; +static int linuxdvb_en50494_freq(linuxdvb_diseqc_t* ld, dvb_mux_t* lm, int freq) { + linuxdvb_en50494_t* le = (linuxdvb_en50494_t*)ld; + int rfreq; + uint16_t t; if (linuxdvb_en50494_freq0(le, freq, &rfreq, &t)) return -1; return rfreq; } -static int -linuxdvb_en50494_match - ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm1, dvb_mux_t *lm2 ) -{ +static int linuxdvb_en50494_match(linuxdvb_diseqc_t* ld, dvb_mux_t* lm1, dvb_mux_t* lm2) { return lm1 == lm2; } -static int -linuxdvb_en50494_tune - ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *sc, - int vol, int pol, int band, int freq ) -{ - int ret = 0, i, fd = linuxdvb_satconf_fe_fd(lsp), rfreq; - int ver2 = linuxdvb_unicable_is_en50607(ld->ld_type); - linuxdvb_en50494_t *le = (linuxdvb_en50494_t*) ld; - uint8_t data1, data2, data3; - uint16_t t; - +static int linuxdvb_en50494_tune(linuxdvb_diseqc_t* ld, + dvb_mux_t* lm, + linuxdvb_satconf_t* lsp, + linuxdvb_satconf_ele_t* sc, + int vol, + int pol, + int band, + int freq) { + int ret = 0, i, fd = linuxdvb_satconf_fe_fd(lsp), rfreq; + int ver2 = linuxdvb_unicable_is_en50607(ld->ld_type); + linuxdvb_en50494_t* le = (linuxdvb_en50494_t*)ld; + uint8_t data1, data2, data3; + uint16_t t; if (!ver2) { /* tune frequency for the frontend */ @@ -328,25 +300,25 @@ linuxdvb_en50494_tune return -1; le->le_tune_freq = rfreq; /* 2 data fields (16bit) */ - data1 = (le->le_id & 7) << 5; /* 3bit user-band */ - data1 |= (le->le_position & 1) << 4; /* 1bit position (satellite A(0)/B(1)) */ - data1 |= (pol & 1) << 3; /* 1bit polarization v(0)/h(1) */ - data1 |= (band & 1) << 2; /* 1bit band lower(0)/upper(1) */ - data1 |= (t >> 8) & 3; /* 2bit transponder value bit 1-2 */ - data2 = t & 0xff; /* 8bit transponder value bit 3-10 */ - data3 = 0; + data1 = (le->le_id & 7) << 5; /* 3bit user-band */ + data1 |= (le->le_position & 1) << 4; /* 1bit position (satellite A(0)/B(1)) */ + data1 |= (pol & 1) << 3; /* 1bit polarization v(0)/h(1) */ + data1 |= (band & 1) << 2; /* 1bit band lower(0)/upper(1) */ + data1 |= (t >> 8) & 3; /* 2bit transponder value bit 1-2 */ + data2 = t & 0xff; /* 8bit transponder value bit 3-10 */ + data3 = 0; } else { /* tune frequency for the frontend */ if (linuxdvb_en50607_freq0(le, freq, &rfreq, &t)) return -1; le->le_tune_freq = rfreq; /* 3 data fields (24bit) */ - data1 = (le->le_id & 0x1f) << 3; /* 5bit user-band */ - data1 |= (t >> 8) & 7; /* 3bit transponder value bit 1-3 */ - data2 = t & 0xff; /* 8bit transponder value bit 4-11 */ - data3 = (le->le_position & 0x3f) << 2; /* 6bit position */ - data3 |= (pol & 1) << 1; /* 1bit polarization v(0)/h(1) */ - data3 |= band & 1; /* 1bit band lower(0)/upper(1) */ + data1 = (le->le_id & 0x1f) << 3; /* 5bit user-band */ + data1 |= (t >> 8) & 7; /* 3bit transponder value bit 1-3 */ + data2 = t & 0xff; /* 8bit transponder value bit 4-11 */ + data3 = (le->le_position & 0x3f) << 2; /* 6bit position */ + data3 |= (pol & 1) << 1; /* 1bit polarization v(0)/h(1) */ + data3 |= band & 1; /* 1bit band lower(0)/upper(1) */ } /* wait until no other thread is setting up switch. @@ -354,7 +326,7 @@ linuxdvb_en50494_tune */ if (tvh_mutex_trylock(&linuxdvb_en50494_lock) != 0) { if (tvh_mutex_lock(&linuxdvb_en50494_lock) != 0) { - tvherror(LS_EN50494,"failed to lock for tuning"); + tvherror(LS_EN50494, "failed to lock for tuning"); return -1; } tvh_safe_usleep(20000); @@ -367,8 +339,8 @@ linuxdvb_en50494_tune if (i != 0) { uint8_t rnd; uuid_random(&rnd, 1); - int ms = ((int)rnd)%50 + 68; - tvh_safe_usleep(ms*1000); + int ms = ((int)rnd) % 50 + 68; + tvh_safe_usleep(ms * 1000); } /* use 18V */ @@ -384,31 +356,44 @@ linuxdvb_en50494_tune /* send tune command (with/without pin) */ tvhdebug(LS_EN50494, - "lnb=%i id=%i freq=%i pin=%i v/h=%i l/u=%i f=%i, data=0x%02X%02X%02X", - le->le_position, le->le_id, le->le_frequency, le->le_pin, pol, - band, freq, data1, data2, data3); + "lnb=%i id=%i freq=%i pin=%i v/h=%i l/u=%i f=%i, data=0x%02X%02X%02X", + le->le_position, + le->le_id, + le->le_frequency, + le->le_pin, + pol, + band, + freq, + data1, + data2, + data3); if (!ver2 && le->le_pin != LINUXDVB_EN50494_NOPIN) { ret = linuxdvb_diseqc_send(fd, - LINUXDVB_EN50494_FRAME, - LINUXDVB_EN50494_ADDRESS, - LINUXDVB_EN50494_CMD_NORMAL_MULTIHOME, - 3, - data1, data2, (uint8_t)le->le_pin); + LINUXDVB_EN50494_FRAME, + LINUXDVB_EN50494_ADDRESS, + LINUXDVB_EN50494_CMD_NORMAL_MULTIHOME, + 3, + data1, + data2, + (uint8_t)le->le_pin); } else if (!ver2) { ret = linuxdvb_diseqc_send(fd, - LINUXDVB_EN50494_FRAME, - LINUXDVB_EN50494_ADDRESS, - LINUXDVB_EN50494_CMD_NORMAL, - 2, - data1, data2); + LINUXDVB_EN50494_FRAME, + LINUXDVB_EN50494_ADDRESS, + LINUXDVB_EN50494_CMD_NORMAL, + 2, + data1, + data2); } else if (ver2 && le->le_pin != LINUXDVB_EN50494_NOPIN) { - ret = linuxdvb_diseqc_raw_send(fd, 5, - LINUXDVB_EN50607_FRAME_MULTIHOME, - data1, data2, data3, (uint8_t)le->le_pin); + ret = linuxdvb_diseqc_raw_send(fd, + 5, + LINUXDVB_EN50607_FRAME_MULTIHOME, + data1, + data2, + data3, + (uint8_t)le->le_pin); } else if (ver2) { - ret = linuxdvb_diseqc_raw_send(fd, 4, - LINUXDVB_EN50607_FRAME_NORMAL, - data1, data2, data3); + ret = linuxdvb_diseqc_raw_send(fd, 4, LINUXDVB_EN50607_FRAME_NORMAL, data1, data2, data3); } if (ret != 0) { tvherror(LS_EN50494, "error send tune command"); @@ -430,38 +415,34 @@ linuxdvb_en50494_tune return ret == 0 ? 0 : -1; } - /* ************************************************************************** * Create / Config * *************************************************************************/ -void -linuxdvb_en50494_init (void) -{ +void linuxdvb_en50494_init(void) { if (tvh_mutex_init(&linuxdvb_en50494_lock, NULL) != 0) { tvherror(LS_EN50494, "failed to init lock mutex"); } } -htsmsg_t * -linuxdvb_en50494_list ( void *o, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_list(); +htsmsg_t* linuxdvb_en50494_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_list(); htsmsg_add_msg(m, NULL, htsmsg_create_key_val("", tvh_gettext_lang(lang, N_("None")))); - htsmsg_add_msg(m, NULL, htsmsg_create_key_val(UNICABLE_I_NAME, tvh_gettext_lang(lang, N_(UNICABLE_I_NAME)))); - htsmsg_add_msg(m, NULL, htsmsg_create_key_val(UNICABLE_II_NAME, tvh_gettext_lang(lang, N_(UNICABLE_II_NAME)))); + htsmsg_add_msg(m, + NULL, + htsmsg_create_key_val(UNICABLE_I_NAME, tvh_gettext_lang(lang, N_(UNICABLE_I_NAME)))); + htsmsg_add_msg(m, + NULL, + htsmsg_create_key_val(UNICABLE_II_NAME, tvh_gettext_lang(lang, N_(UNICABLE_II_NAME)))); return m; } -linuxdvb_diseqc_t * -linuxdvb_en50494_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls, int port ) -{ - linuxdvb_diseqc_t *ld; - linuxdvb_en50494_t *le; +linuxdvb_diseqc_t* +linuxdvb_en50494_create0(const char* name, htsmsg_t* conf, linuxdvb_satconf_ele_t* ls, int port) { + linuxdvb_diseqc_t* ld; + linuxdvb_en50494_t* le; - if (strcmp(name ?: "", "Generic") && - strcmp(name ?: "", UNICABLE_I_NAME) && + if (strcmp(name ?: "", "Generic") && strcmp(name ?: "", UNICABLE_I_NAME) && strcmp(name ?: "", UNICABLE_II_NAME)) return NULL; @@ -485,16 +466,16 @@ linuxdvb_en50494_create0 le->ld_freq = linuxdvb_en50494_freq; le->ld_match = linuxdvb_en50494_match; if (le->le_powerup_time == 0) - le->le_powerup_time = 15; + le->le_powerup_time = 15; if (le->le_cmd_time == 0) - le->le_cmd_time = 50; - - ld = linuxdvb_diseqc_create0((linuxdvb_diseqc_t *)le, - NULL, - linuxdvb_unicable_is_en50607(name) ? - &linuxdvb_en50607_class : - &linuxdvb_en50494_class, - conf, name, ls); + le->le_cmd_time = 50; + + ld = linuxdvb_diseqc_create0((linuxdvb_diseqc_t*)le, + NULL, + linuxdvb_unicable_is_en50607(name) ? &linuxdvb_en50607_class : &linuxdvb_en50494_class, + conf, + name, + ls); if (ld) { ld->ld_tune = linuxdvb_en50494_tune; /* May not needed: ld->ld_grace = linuxdvb_en50494_grace; */ @@ -503,9 +484,7 @@ linuxdvb_en50494_create0 return ld; } -void -linuxdvb_en50494_destroy ( linuxdvb_diseqc_t *le ) -{ +void linuxdvb_en50494_destroy(linuxdvb_diseqc_t* le) { linuxdvb_diseqc_destroy(le); free(le); } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c index 72aaf41f1..0bf616245 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_frontend.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_frontend.c @@ -31,49 +31,40 @@ #include #include #include -#include +#include #define NOSIGNAL(x) (((x) & FE_HAS_SIGNAL) == 0) -static void -linuxdvb_frontend_monitor ( void *aux ); -static void * -linuxdvb_frontend_input_thread ( void *aux ); +static void linuxdvb_frontend_monitor(void* aux); +static void* linuxdvb_frontend_input_thread(void* aux); /* * */ -static inline int sig_multiply ( int value, int multiplier ) -{ +static inline int sig_multiply(int value, int multiplier) { return ((value * MAX(1, multiplier)) + 99) / 100; } -static inline int lfe_group ( linuxdvb_frontend_t *lfe1, - linuxdvb_frontend_t *lfe2 ) -{ +static inline int lfe_group(linuxdvb_frontend_t* lfe1, linuxdvb_frontend_t* lfe2) { return strcmp(lfe1->lfe_dmx_path, lfe2->lfe_dmx_path) == 0 || - strcmp(lfe1->lfe_fe_path, lfe2->lfe_fe_path) == 0; + strcmp(lfe1->lfe_fe_path, lfe2->lfe_fe_path) == 0; } /* ************************************************************************** * Class definition * *************************************************************************/ -static void -linuxdvb_frontend_class_changed ( idnode_t *in ) -{ - linuxdvb_adapter_t *la = ((linuxdvb_frontend_t*)in)->lfe_adapter; +static void linuxdvb_frontend_class_changed(idnode_t* in) { + linuxdvb_adapter_t* la = ((linuxdvb_frontend_t*)in)->lfe_adapter; linuxdvb_adapter_changed(la); } -const void * -linuxdvb_frontend_class_active_get ( void *obj ) -{ - int *active; +const void* linuxdvb_frontend_class_active_get(void* obj) { + int* active; linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)obj, *lfe2; - active = (int *)mpegts_input_class_active_get(obj); + active = (int*)mpegts_input_class_active_get(obj); if (!(*active)) { - LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { + LIST_FOREACH (lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { if (!lfe_group(lfe, lfe2)) continue; if (lfe2->mi_is_enabled((mpegts_input_t*)lfe2, NULL, 0, -1) != MI_IS_ENABLED_NEVER) { @@ -87,211 +78,194 @@ linuxdvb_frontend_class_active_get ( void *obj ) CLASS_DOC(linuxdvb_frontend) CLASS_DOC(linuxdvb_frontend_dvbs) -CLASS_DOC(linuxdvb_frontend_dvbt) +CLASS_DOC(linuxdvb_frontend_dvbt) CLASS_DOC(linuxdvb_frontend_dvbc) -const idclass_t linuxdvb_frontend_class = -{ - .ic_super = &mpegts_input_class, - .ic_class = "linuxdvb_frontend", - .ic_caption = N_("Linux DVB frontend"), - .ic_doc = tvh_doc_linuxdvb_frontend_class, - .ic_changed = linuxdvb_frontend_class_changed, - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "fe_path", - .name = N_("Frontend path"), - .desc = N_("Path to the frontend used by the device."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(linuxdvb_frontend_t, lfe_fe_path), - }, - { - .type = PT_STR, - .id = "dvr_path", - .name = N_("Input path"), - .desc = N_("The input path used by the device."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(linuxdvb_frontend_t, lfe_dvr_path), - }, - { - .type = PT_STR, - .id = "dmx_path", - .name = N_("Demux path"), - .desc = N_("The demux path used by the device."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(linuxdvb_frontend_t, lfe_dmx_path), - }, - { - .type = PT_INT, - .id = "fe_number", - .name = N_("Frontend number"), - .desc = N_("The frontend number given to the device."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(linuxdvb_frontend_t, lfe_number), - }, - { - .type = PT_STR, - .id = "sysfs_device", - .name = N_("Device path in sysfs"), - .desc = N_("The device path in sysfs filesystem (/sys)."), - .opts = PO_RDONLY | PO_NOSAVE | PO_MULTILINE, - .off = offsetof(linuxdvb_frontend_t, lfe_sysfs), - }, - { - .type = PT_INT, - .id = "pids_max", - .name = N_("Maximum PIDs"), - .desc = N_("The limit for the PID filter (driver or hardware)."), - .off = offsetof(linuxdvb_frontend_t, lfe_pids_max), - .opts = PO_ADVANCED, - .def.i = 32 - }, - { - .type = PT_BOOL, - .id = "pids_use_all", - .name = N_("Allow all PIDs"), - .desc = N_("Allow all PIDs (no filter) when the 'Maximum PIDs' limit is reached."), - .off = offsetof(linuxdvb_frontend_t, lfe_pids_use_all), - .opts = PO_ADVANCED, - .def.i = 1 - }, - { - .type = PT_BOOL, - .id = "powersave", - .name = N_("Power save"), - .desc = N_("Enable/disable power save mode (if supported by " - "the device)."), - .off = offsetof(linuxdvb_frontend_t, lfe_powersave), - }, - { - .type = PT_U32, - .id = "tune_repeats", - .name = N_("# tune repeats"), - .desc = N_("Number of repeats for the tune requests (default is " - "zero - no repeats). Note: this represents the " - "number of repeats, not the number of requests - " - "so 0 means 'send once: don't repeat', 1 means " - "'send twice: send once, then send one repeat'," - " etc."), - .opts = PO_ADVANCED, - .off = offsetof(linuxdvb_frontend_t, lfe_tune_repeats), - }, - { - .type = PT_U32, - .id = "skip_bytes", - .name = N_("Skip initial bytes"), - .desc = N_("If set, the first bytes from the MPEG-TS stream " - "are discarded. It may be required for some " - "drivers or hardware which do not flush the MPEG-TS " - "buffers completely after a frequency/parameter change."), - .opts = PO_ADVANCED, - .off = offsetof(linuxdvb_frontend_t, lfe_skip_bytes), - }, - { - .type = PT_U32, - .id = "ibuf_size", - .name = N_("Input buffer (bytes)"), - .desc = N_("The number of bytes to buffer. By default, " - "linuxdvb's input buffer is 18800 bytes long. The " - "accepted range is 18800-1880000 bytes."), - .opts = PO_ADVANCED, - .off = offsetof(linuxdvb_frontend_t, lfe_ibuf_size), - }, - { - .type = PT_U32, - .id = "status_period", - .name = N_("Status period (ms)"), - .desc = N_("By default, linuxdvb's status read period is " - "1000ms (one second). The accepted range is 250ms " - "to 8000ms. Note that for some hardware or drivers " - "(like USB), the status operations take too much " - "time and CPU. In this case, increase the default " - "value. For fast hardware, this value might be " - "decreased to make the decision of the re-tune " - "algorithm based on the signal status faster."), - .opts = PO_ADVANCED, - .off = offsetof(linuxdvb_frontend_t, lfe_status_period), - }, - { - .type = PT_U32, - .id = "sig_multiplier", - .name = N_("Signal multiplier"), - .desc = N_("The signal level reported by the driver is multiplied " - "with this value and divided by 100."), - .opts = PO_ADVANCED, - .off = offsetof(linuxdvb_frontend_t, lfe_sig_multiplier), - .def.u32 = 100, - }, - { - .type = PT_U32, - .id = "snr_multiplier", - .name = N_("SNR multiplier"), - .desc = N_("The SNR level reported by the driver is multiplied " - "with this value and divided by 100."), - .opts = PO_ADVANCED, - .off = offsetof(linuxdvb_frontend_t, lfe_snr_multiplier), - .def.u32 = 100, - }, - { - .type = PT_BOOL, - .id = "old_status", - .name = N_("Force old status"), - .desc = N_("Always use the old ioctls to read the linuxdvb " - "status (signal strength, SNR, error counters). " - "Some drivers are not mature enough to provide the " - "correct values using the new v5 linuxdvb API."), - .opts = PO_ADVANCED, - .off = offsetof(linuxdvb_frontend_t, lfe_old_status), - }, - { - .type = PT_U32, - .id = "grace_period", - .name = N_("Scan grace period (seconds)"), - .desc = N_("The maximum amount of time to allow this adapter " - "to complete a scan of a mux. If you're getting " - "failed or incomplete scans (for example, missing " - "services) despite a strong signal, try increasing " - "this value. Ignored for DVB-S."), - .opts = PO_ADVANCED, - .off = offsetof(linuxdvb_frontend_t, lfe_grace_period), - }, - {} - } -}; - -const idclass_t linuxdvb_frontend_dvbt_class = -{ - .ic_super = &linuxdvb_frontend_class, - .ic_class = "linuxdvb_frontend_dvbt", - .ic_doc = tvh_doc_linuxdvb_frontend_dvbt_class, - .ic_caption = N_("TV Adapters - Linux DVB-T Frontend"), - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "lna", - .name = N_("LNA (low noise amplifier)"), - .desc = N_("Enable/disable LNA."), - .off = offsetof(linuxdvb_frontend_t, lfe_lna), - }, - {} - } -}; - -static idnode_set_t * -linuxdvb_frontend_dvbs_class_get_childs ( idnode_t *self ) -{ - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)self; - idnode_set_t *is = idnode_set_create(0); +const idclass_t linuxdvb_frontend_class = {.ic_super = &mpegts_input_class, + .ic_class = "linuxdvb_frontend", + .ic_caption = N_("Linux DVB frontend"), + .ic_doc = tvh_doc_linuxdvb_frontend_class, + .ic_changed = linuxdvb_frontend_class_changed, + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "fe_path", + .name = N_("Frontend path"), + .desc = N_("Path to the frontend used by the device."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(linuxdvb_frontend_t, lfe_fe_path), + }, + { + .type = PT_STR, + .id = "dvr_path", + .name = N_("Input path"), + .desc = N_("The input path used by the device."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(linuxdvb_frontend_t, lfe_dvr_path), + }, + { + .type = PT_STR, + .id = "dmx_path", + .name = N_("Demux path"), + .desc = N_("The demux path used by the device."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(linuxdvb_frontend_t, lfe_dmx_path), + }, + { + .type = PT_INT, + .id = "fe_number", + .name = N_("Frontend number"), + .desc = N_("The frontend number given to the device."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(linuxdvb_frontend_t, lfe_number), + }, + { + .type = PT_STR, + .id = "sysfs_device", + .name = N_("Device path in sysfs"), + .desc = N_("The device path in sysfs filesystem (/sys)."), + .opts = PO_RDONLY | PO_NOSAVE | PO_MULTILINE, + .off = offsetof(linuxdvb_frontend_t, lfe_sysfs), + }, + {.type = PT_INT, + .id = "pids_max", + .name = N_("Maximum PIDs"), + .desc = N_("The limit for the PID filter (driver or hardware)."), + .off = offsetof(linuxdvb_frontend_t, lfe_pids_max), + .opts = PO_ADVANCED, + .def.i = 32}, + {.type = PT_BOOL, + .id = "pids_use_all", + .name = N_("Allow all PIDs"), + .desc = N_("Allow all PIDs (no filter) when the 'Maximum PIDs' limit is reached."), + .off = offsetof(linuxdvb_frontend_t, lfe_pids_use_all), + .opts = PO_ADVANCED, + .def.i = 1}, + { + .type = PT_BOOL, + .id = "powersave", + .name = N_("Power save"), + .desc = N_("Enable/disable power save mode (if supported by " + "the device)."), + .off = offsetof(linuxdvb_frontend_t, lfe_powersave), + }, + { + .type = PT_U32, + .id = "tune_repeats", + .name = N_("# tune repeats"), + .desc = N_("Number of repeats for the tune requests (default is " + "zero - no repeats). Note: this represents the " + "number of repeats, not the number of requests - " + "so 0 means 'send once: don't repeat', 1 means " + "'send twice: send once, then send one repeat'," + " etc."), + .opts = PO_ADVANCED, + .off = offsetof(linuxdvb_frontend_t, lfe_tune_repeats), + }, + { + .type = PT_U32, + .id = "skip_bytes", + .name = N_("Skip initial bytes"), + .desc = N_("If set, the first bytes from the MPEG-TS stream " + "are discarded. It may be required for some " + "drivers or hardware which do not flush the MPEG-TS " + "buffers completely after a frequency/parameter change."), + .opts = PO_ADVANCED, + .off = offsetof(linuxdvb_frontend_t, lfe_skip_bytes), + }, + { + .type = PT_U32, + .id = "ibuf_size", + .name = N_("Input buffer (bytes)"), + .desc = N_("The number of bytes to buffer. By default, " + "linuxdvb's input buffer is 18800 bytes long. The " + "accepted range is 18800-1880000 bytes."), + .opts = PO_ADVANCED, + .off = offsetof(linuxdvb_frontend_t, lfe_ibuf_size), + }, + { + .type = PT_U32, + .id = "status_period", + .name = N_("Status period (ms)"), + .desc = N_("By default, linuxdvb's status read period is " + "1000ms (one second). The accepted range is 250ms " + "to 8000ms. Note that for some hardware or drivers " + "(like USB), the status operations take too much " + "time and CPU. In this case, increase the default " + "value. For fast hardware, this value might be " + "decreased to make the decision of the re-tune " + "algorithm based on the signal status faster."), + .opts = PO_ADVANCED, + .off = offsetof(linuxdvb_frontend_t, lfe_status_period), + }, + { + .type = PT_U32, + .id = "sig_multiplier", + .name = N_("Signal multiplier"), + .desc = N_("The signal level reported by the driver is multiplied " + "with this value and divided by 100."), + .opts = PO_ADVANCED, + .off = offsetof(linuxdvb_frontend_t, lfe_sig_multiplier), + .def.u32 = 100, + }, + { + .type = PT_U32, + .id = "snr_multiplier", + .name = N_("SNR multiplier"), + .desc = N_("The SNR level reported by the driver is multiplied " + "with this value and divided by 100."), + .opts = PO_ADVANCED, + .off = offsetof(linuxdvb_frontend_t, lfe_snr_multiplier), + .def.u32 = 100, + }, + { + .type = PT_BOOL, + .id = "old_status", + .name = N_("Force old status"), + .desc = N_("Always use the old ioctls to read the linuxdvb " + "status (signal strength, SNR, error counters). " + "Some drivers are not mature enough to provide the " + "correct values using the new v5 linuxdvb API."), + .opts = PO_ADVANCED, + .off = offsetof(linuxdvb_frontend_t, lfe_old_status), + }, + { + .type = PT_U32, + .id = "grace_period", + .name = N_("Scan grace period (seconds)"), + .desc = N_("The maximum amount of time to allow this adapter " + "to complete a scan of a mux. If you're getting " + "failed or incomplete scans (for example, missing " + "services) despite a strong signal, try increasing " + "this value. Ignored for DVB-S."), + .opts = PO_ADVANCED, + .off = offsetof(linuxdvb_frontend_t, lfe_grace_period), + }, + {}}}; + +const idclass_t linuxdvb_frontend_dvbt_class = {.ic_super = &linuxdvb_frontend_class, + .ic_class = "linuxdvb_frontend_dvbt", + .ic_doc = tvh_doc_linuxdvb_frontend_dvbt_class, + .ic_caption = N_("TV Adapters - Linux DVB-T Frontend"), + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "lna", + .name = N_("LNA (low noise amplifier)"), + .desc = N_("Enable/disable LNA."), + .off = offsetof(linuxdvb_frontend_t, lfe_lna), + }, + {}}}; + +static idnode_set_t* linuxdvb_frontend_dvbs_class_get_childs(idnode_t* self) { + linuxdvb_frontend_t* lfe = (linuxdvb_frontend_t*)self; + idnode_set_t* is = idnode_set_create(0); idnode_set_add(is, &lfe->lfe_satconf->ls_id, NULL, NULL); return is; } -static int -linuxdvb_frontend_dvbs_class_satconf_set ( void *self, const void *str ) -{ - linuxdvb_frontend_t *lfe = self; - htsmsg_t *conf; +static int linuxdvb_frontend_dvbs_class_satconf_set(void* self, const void* str) { + linuxdvb_frontend_t* lfe = self; + htsmsg_t* conf; str = str ?: ""; if (lfe->lfe_satconf) { if (!strcmp(str, lfe->lfe_satconf->ls_type)) @@ -305,10 +279,8 @@ linuxdvb_frontend_dvbs_class_satconf_set ( void *self, const void *str ) return 1; } -static const void * -linuxdvb_frontend_dvbs_class_satconf_get ( void *self ) -{ - linuxdvb_frontend_t *lfe = self; +static const void* linuxdvb_frontend_dvbs_class_satconf_get(void* self) { + linuxdvb_frontend_t* lfe = self; if (lfe->lfe_satconf) prop_ptr = lfe->lfe_satconf->ls_type; else @@ -316,21 +288,21 @@ linuxdvb_frontend_dvbs_class_satconf_get ( void *self ) return &prop_ptr; } -static htsmsg_t * -linuxdvb_frontend_dvbs_class_master_enum( void * self, const char *lang ) -{ +static htsmsg_t* linuxdvb_frontend_dvbs_class_master_enum(void* self, const char* lang) { linuxdvb_frontend_t *lfe = self, *lfe2; - linuxdvb_adapter_t *la; - tvh_hardware_t *th; - char ubuf[UUID_HEX_SIZE]; - htsmsg_t *m = htsmsg_create_list(); - if (self == NULL) return m; - htsmsg_t *e = htsmsg_create_key_val("", N_("This tuner")); + linuxdvb_adapter_t* la; + tvh_hardware_t* th; + char ubuf[UUID_HEX_SIZE]; + htsmsg_t* m = htsmsg_create_list(); + if (self == NULL) + return m; + htsmsg_t* e = htsmsg_create_key_val("", N_("This tuner")); htsmsg_add_msg(m, NULL, e); - LIST_FOREACH(th, &tvh_hardware, th_link) { - if (!idnode_is_instance(&th->th_id, &linuxdvb_adapter_class)) continue; + LIST_FOREACH (th, &tvh_hardware, th_link) { + if (!idnode_is_instance(&th->th_id, &linuxdvb_adapter_class)) + continue; la = (linuxdvb_adapter_t*)th; - LIST_FOREACH(lfe2, &la->la_frontends, lfe_link) { + LIST_FOREACH (lfe2, &la->la_frontends, lfe_link) { if (lfe2 != lfe && lfe2->lfe_type == lfe->lfe_type) { e = htsmsg_create_key_val(idnode_uuid_as_str(&lfe2->ti_id, ubuf), lfe2->mi_name); htsmsg_add_msg(m, NULL, e); @@ -340,227 +312,168 @@ linuxdvb_frontend_dvbs_class_master_enum( void * self, const char *lang ) return m; } -const idclass_t linuxdvb_frontend_dvbs_class = -{ - .ic_super = &linuxdvb_frontend_class, - .ic_class = "linuxdvb_frontend_dvbs", - .ic_doc = tvh_doc_linuxdvb_frontend_dvbs_class, - .ic_caption = N_("TV Adapters - Linux DVB-S Frontend (Master)"), - .ic_get_childs = linuxdvb_frontend_dvbs_class_get_childs, - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "satconf", - .name = N_("Satellite config"), - .desc = N_("The satellite configuration to use."), - .opts = PO_NOSAVE, - .set = linuxdvb_frontend_dvbs_class_satconf_set, - .get = linuxdvb_frontend_dvbs_class_satconf_get, - .list = linuxdvb_satconf_type_list, - .def.s = "simple" - }, - { - .type = PT_STR, - .id = "fe_master", - .name = N_("Master tuner"), - .desc = N_("The signal from the standard universal LNB can be " - "split using a simple coaxial splitter " - "(no multiswitch) to several outputs. In this " - "case, the position, the polarization and low-high " - "band settings must be equal. If you set another " - "tuner as master, then this tuner will act as " - "a slave and Tvheadend will assure that this tuner " - "will not use incompatible parameters (position, " - "polarization, lo-hi)."), - .list = linuxdvb_frontend_dvbs_class_master_enum, - .off = offsetof(linuxdvb_frontend_t, lfe_master), - }, - { - .id = "networks", - .type = PT_NONE, - }, - {} - } -}; - -const idclass_t linuxdvb_frontend_dvbs_slave_class = -{ - .ic_super = &linuxdvb_frontend_class, - .ic_class = "linuxdvb_frontend_dvbs_slave", - .ic_doc = tvh_doc_linuxdvb_frontend_dvbs_class, - .ic_caption = N_("TV Adapters - Linux DVB-S Slave Frontend"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "fe_master", - .name = N_("Master tuner"), - .desc = N_("The signal from the standard universal LNB can be " - "split using a simple coaxial splitter " - "(no multiswitch) to several outputs. In this " - "case, the position, the polarization and low-high " - "band settings must be equal. If you set another " - "tuner as master, then this tuner will act as " - "a slave and Tvheadend will assure that this tuner " - "will not use incompatible parameters (position, " - "polarization, lo-hi)."), - .list = linuxdvb_frontend_dvbs_class_master_enum, - .off = offsetof(linuxdvb_frontend_t, lfe_master), - }, - { - .id = "networks", - .type = PT_NONE, - }, - {} - } -}; - -const idclass_t linuxdvb_frontend_dvbc_class = -{ - .ic_super = &linuxdvb_frontend_class, - .ic_class = "linuxdvb_frontend_dvbc", - .ic_doc = tvh_doc_linuxdvb_frontend_dvbc_class, - .ic_caption = N_("TV Adapters - Linux DVB-C Frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t linuxdvb_frontend_atsc_t_class = -{ - .ic_super = &linuxdvb_frontend_class, - .ic_class = "linuxdvb_frontend_atsc_t", - .ic_doc = tvh_doc_linuxdvb_frontend_dvbt_class, - .ic_caption = N_("TV Adapters - Linux ATSC-T Frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t linuxdvb_frontend_atsc_c_class = -{ - .ic_super = &linuxdvb_frontend_class, - .ic_class = "linuxdvb_frontend_atsc_c", - .ic_doc = tvh_doc_linuxdvb_frontend_dvbc_class, - .ic_caption = N_("TV Adapters - Linux ATSC-C Frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t linuxdvb_frontend_isdb_t_class = -{ - .ic_super = &linuxdvb_frontend_class, - .ic_class = "linuxdvb_frontend_isdb_t", - .ic_doc = tvh_doc_linuxdvb_frontend_dvbt_class, - .ic_caption = N_("TV Adapters - Linux ISDB-T Frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t linuxdvb_frontend_isdb_c_class = -{ - .ic_super = &linuxdvb_frontend_class, - .ic_class = "linuxdvb_frontend_isdb_c", - .ic_doc = tvh_doc_linuxdvb_frontend_dvbc_class, - .ic_caption = N_("TV Adapters - Linux ISDB-C Frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t linuxdvb_frontend_isdb_s_class = -{ - .ic_super = &linuxdvb_frontend_class, - .ic_class = "linuxdvb_frontend_isdb_s", - .ic_doc = tvh_doc_linuxdvb_frontend_dvbs_class, - .ic_caption = N_("TV Adapters - Linux ISDB-S Frontend (Master)"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t linuxdvb_frontend_dtmb_class = -{ - .ic_super = &linuxdvb_frontend_class, - .ic_class = "linuxdvb_frontend_dab", - .ic_caption = N_("TV Adapters - DTMB Frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t linuxdvb_frontend_dab_class = -{ - .ic_super = &linuxdvb_frontend_class, - .ic_class = "linuxdvb_frontend_dab", - .ic_caption = N_("TV Adapters - Linux DAB Frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; +const idclass_t linuxdvb_frontend_dvbs_class = {.ic_super = &linuxdvb_frontend_class, + .ic_class = "linuxdvb_frontend_dvbs", + .ic_doc = tvh_doc_linuxdvb_frontend_dvbs_class, + .ic_caption = N_("TV Adapters - Linux DVB-S Frontend (Master)"), + .ic_get_childs = linuxdvb_frontend_dvbs_class_get_childs, + .ic_properties = (const property_t[]){{.type = PT_STR, + .id = "satconf", + .name = N_("Satellite config"), + .desc = N_("The satellite configuration to use."), + .opts = PO_NOSAVE, + .set = linuxdvb_frontend_dvbs_class_satconf_set, + .get = linuxdvb_frontend_dvbs_class_satconf_get, + .list = linuxdvb_satconf_type_list, + .def.s = "simple"}, + { + .type = PT_STR, + .id = "fe_master", + .name = N_("Master tuner"), + .desc = N_("The signal from the standard universal LNB can be " + "split using a simple coaxial splitter " + "(no multiswitch) to several outputs. In this " + "case, the position, the polarization and low-high " + "band settings must be equal. If you set another " + "tuner as master, then this tuner will act as " + "a slave and Tvheadend will assure that this tuner " + "will not use incompatible parameters (position, " + "polarization, lo-hi)."), + .list = linuxdvb_frontend_dvbs_class_master_enum, + .off = offsetof(linuxdvb_frontend_t, lfe_master), + }, + { + .id = "networks", + .type = PT_NONE, + }, + {}}}; + +const idclass_t linuxdvb_frontend_dvbs_slave_class = {.ic_super = &linuxdvb_frontend_class, + .ic_class = "linuxdvb_frontend_dvbs_slave", + .ic_doc = tvh_doc_linuxdvb_frontend_dvbs_class, + .ic_caption = N_("TV Adapters - Linux DVB-S Slave Frontend"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "fe_master", + .name = N_("Master tuner"), + .desc = N_("The signal from the standard universal LNB can be " + "split using a simple coaxial splitter " + "(no multiswitch) to several outputs. In this " + "case, the position, the polarization and low-high " + "band settings must be equal. If you set another " + "tuner as master, then this tuner will act as " + "a slave and Tvheadend will assure that this tuner " + "will not use incompatible parameters (position, " + "polarization, lo-hi)."), + .list = linuxdvb_frontend_dvbs_class_master_enum, + .off = offsetof(linuxdvb_frontend_t, lfe_master), + }, + { + .id = "networks", + .type = PT_NONE, + }, + {}}}; + +const idclass_t linuxdvb_frontend_dvbc_class = {.ic_super = &linuxdvb_frontend_class, + .ic_class = "linuxdvb_frontend_dvbc", + .ic_doc = tvh_doc_linuxdvb_frontend_dvbc_class, + .ic_caption = N_("TV Adapters - Linux DVB-C Frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t linuxdvb_frontend_atsc_t_class = {.ic_super = &linuxdvb_frontend_class, + .ic_class = "linuxdvb_frontend_atsc_t", + .ic_doc = tvh_doc_linuxdvb_frontend_dvbt_class, + .ic_caption = N_("TV Adapters - Linux ATSC-T Frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t linuxdvb_frontend_atsc_c_class = {.ic_super = &linuxdvb_frontend_class, + .ic_class = "linuxdvb_frontend_atsc_c", + .ic_doc = tvh_doc_linuxdvb_frontend_dvbc_class, + .ic_caption = N_("TV Adapters - Linux ATSC-C Frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t linuxdvb_frontend_isdb_t_class = {.ic_super = &linuxdvb_frontend_class, + .ic_class = "linuxdvb_frontend_isdb_t", + .ic_doc = tvh_doc_linuxdvb_frontend_dvbt_class, + .ic_caption = N_("TV Adapters - Linux ISDB-T Frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t linuxdvb_frontend_isdb_c_class = {.ic_super = &linuxdvb_frontend_class, + .ic_class = "linuxdvb_frontend_isdb_c", + .ic_doc = tvh_doc_linuxdvb_frontend_dvbc_class, + .ic_caption = N_("TV Adapters - Linux ISDB-C Frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t linuxdvb_frontend_isdb_s_class = {.ic_super = &linuxdvb_frontend_class, + .ic_class = "linuxdvb_frontend_isdb_s", + .ic_doc = tvh_doc_linuxdvb_frontend_dvbs_class, + .ic_caption = N_("TV Adapters - Linux ISDB-S Frontend (Master)"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t linuxdvb_frontend_dtmb_class = {.ic_super = &linuxdvb_frontend_class, + .ic_class = "linuxdvb_frontend_dab", + .ic_caption = N_("TV Adapters - DTMB Frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t linuxdvb_frontend_dab_class = {.ic_super = &linuxdvb_frontend_class, + .ic_class = "linuxdvb_frontend_dab", + .ic_caption = N_("TV Adapters - Linux DAB Frontend"), + .ic_properties = (const property_t[]){{}}}; /* ************************************************************************** * Class methods * *************************************************************************/ -static void -linuxdvb_frontend_close_fd ( linuxdvb_frontend_t *lfe, const char *name ) -{ +static void linuxdvb_frontend_close_fd(linuxdvb_frontend_t* lfe, const char* name) { char buf[256]; if (lfe->lfe_fe_fd <= 0) return; if (name == NULL) { - lfe->mi_display_name((mpegts_input_t *)lfe, buf, sizeof(buf)); + lfe->mi_display_name((mpegts_input_t*)lfe, buf, sizeof(buf)); name = buf; } - tvhtrace(LS_LINUXDVB, "%s - closing FE %s (%d)", - name, lfe->lfe_fe_path, lfe->lfe_fe_fd); + tvhtrace(LS_LINUXDVB, "%s - closing FE %s (%d)", name, lfe->lfe_fe_path, lfe->lfe_fe_fd); close(lfe->lfe_fe_fd); lfe->lfe_fe_fd = -1; if (lfe->lfe_satconf) linuxdvb_satconf_reset(lfe->lfe_satconf); } -static int -linuxdvb_frontend_open_fd ( linuxdvb_frontend_t *lfe, const char *name ) -{ - linuxdvb_frontend_t *lfe2; - const char *extra = ""; +static int linuxdvb_frontend_open_fd(linuxdvb_frontend_t* lfe, const char* name) { + linuxdvb_frontend_t* lfe2; + const char* extra = ""; if (lfe->lfe_fe_fd > 0) return 0; /* Share FD across frontends */ - LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { + LIST_FOREACH (lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { if (lfe2 == lfe || strcmp(lfe->lfe_fe_path, lfe2->lfe_fe_path)) continue; if (lfe2->lfe_fe_fd > 0) { lfe->lfe_fe_fd = dup(lfe2->lfe_fe_fd); - extra = " (shared)"; + extra = " (shared)"; break; } } if (lfe->lfe_fe_fd <= 0) { lfe->lfe_fe_fd = tvh_open(lfe->lfe_fe_path, O_RDWR | O_NONBLOCK, 0); - extra = ""; + extra = ""; } - tvhtrace(LS_LINUXDVB, "%s - opening FE %s (%d)%s", - name, lfe->lfe_fe_path, lfe->lfe_fe_fd, extra); + tvhtrace(LS_LINUXDVB, "%s - opening FE %s (%d)%s", name, lfe->lfe_fe_path, lfe->lfe_fe_fd, extra); return lfe->lfe_fe_fd <= 0; } -static void -linuxdvb_frontend_enabled_updated ( mpegts_input_t *mi ) -{ - char buf[512]; - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi; +static void linuxdvb_frontend_enabled_updated(mpegts_input_t* mi) { + char buf[512]; + linuxdvb_frontend_t* lfe = (linuxdvb_frontend_t*)mi; mi->mi_display_name(mi, buf, sizeof(buf)); @@ -570,20 +483,18 @@ linuxdvb_frontend_enabled_updated ( mpegts_input_t *mi ) linuxdvb_frontend_close_fd(lfe, buf); mtimer_disarm(&lfe->lfe_monitor_timer); - /* Ensure FE opened (if not powersave) */ + /* Ensure FE opened (if not powersave) */ } else if (!lfe->lfe_powersave && lfe->lfe_fe_fd <= 0 && lfe->lfe_fe_path) { linuxdvb_frontend_open_fd(lfe, buf); - } } static int -linuxdvb_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) -{ - int w = 0; +linuxdvb_frontend_get_weight(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight) { + int w = 0; linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2; - LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { + LIST_FOREACH (lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { if (!lfe_group(lfe, lfe2)) continue; w = MAX(w, mpegts_input_get_weight((mpegts_input_t*)lfe2, mm, flags, weight)); @@ -591,32 +502,27 @@ linuxdvb_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, return w; } -static int -linuxdvb_frontend_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) -{ - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi; - int r = mpegts_input_get_priority(mi, mm, flags); +static int linuxdvb_frontend_get_priority(mpegts_input_t* mi, mpegts_mux_t* mm, int flags) { + linuxdvb_frontend_t* lfe = (linuxdvb_frontend_t*)mi; + int r = mpegts_input_get_priority(mi, mm, flags); if (lfe->lfe_satconf) r += linuxdvb_satconf_get_priority(lfe->lfe_satconf, mm); return r; } -static int -linuxdvb_frontend_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi; - return lfe->lfe_satconf ? linuxdvb_satconf_get_grace(lfe->lfe_satconf, mm) : lfe->lfe_grace_period; +static int linuxdvb_frontend_get_grace(mpegts_input_t* mi, mpegts_mux_t* mm) { + linuxdvb_frontend_t* lfe = (linuxdvb_frontend_t*)mi; + return lfe->lfe_satconf ? linuxdvb_satconf_get_grace(lfe->lfe_satconf, mm) + : lfe->lfe_grace_period; } static int -linuxdvb_frontend_is_enabled - ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) -{ +linuxdvb_frontend_is_enabled(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight) { linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2; - linuxdvb_adapter_t *la; - tvh_hardware_t *th; - char ubuf[UUID_HEX_SIZE]; - int w; + linuxdvb_adapter_t* la; + tvh_hardware_t* th; + char ubuf[UUID_HEX_SIZE]; + int w; if (lfe->lfe_fe_path == NULL) return MI_IS_ENABLED_NEVER; @@ -633,12 +539,15 @@ linuxdvb_frontend_is_enabled goto ok; /* check if any "blocking" tuner is running */ - LIST_FOREACH(th, &tvh_hardware, th_link) { - if (!idnode_is_instance(&th->th_id, &linuxdvb_adapter_class)) continue; + LIST_FOREACH (th, &tvh_hardware, th_link) { + if (!idnode_is_instance(&th->th_id, &linuxdvb_adapter_class)) + continue; la = (linuxdvb_adapter_t*)th; - LIST_FOREACH(lfe2, &la->la_frontends, lfe_link) { - if (lfe2 == lfe) continue; - if (lfe2->lfe_type != DVB_TYPE_S) continue; + LIST_FOREACH (lfe2, &la->la_frontends, lfe_link) { + if (lfe2 == lfe) + continue; + if (lfe2->lfe_type != DVB_TYPE_S) + continue; if (lfe->lfe_master && !strcmp(lfe->lfe_master, idnode_uuid_as_str(&lfe2->ti_id, ubuf))) { if (lfe2->lfe_satconf == NULL) return MI_IS_ENABLED_NEVER; /* invalid master */ @@ -648,8 +557,7 @@ linuxdvb_frontend_is_enabled goto ok; return MI_IS_ENABLED_RETRY; } - if (lfe2->lfe_master && - !strcmp(lfe2->lfe_master, idnode_uuid_as_str(&lfe->ti_id, ubuf)) && + if (lfe2->lfe_master && !strcmp(lfe2->lfe_master, idnode_uuid_as_str(&lfe->ti_id, ubuf)) && lfe2->lfe_refcount > 0) { if (lfe->lfe_satconf == NULL) return MI_IS_ENABLED_NEVER; @@ -660,12 +568,12 @@ linuxdvb_frontend_is_enabled } } - ok: w = -1; - LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { - if (lfe2 == lfe || !lfe_group(lfe, lfe2)) continue; - w = MAX(w, mpegts_input_get_weight((mpegts_input_t *)lfe2, mm, flags, weight)); + LIST_FOREACH (lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { + if (lfe2 == lfe || !lfe_group(lfe, lfe2)) + continue; + w = MAX(w, mpegts_input_get_weight((mpegts_input_t*)lfe2, mm, flags, weight)); } if (w >= weight) return MI_IS_ENABLED_RETRY; @@ -673,11 +581,8 @@ ok: return MI_IS_ENABLED_OK; } -static void -linuxdvb_frontend_stop_mux - ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ - char buf1[256]; +static void linuxdvb_frontend_stop_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { + char buf1[256]; linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2; if (lfe->lfe_master) @@ -708,7 +613,7 @@ linuxdvb_frontend_stop_mux linuxdvb_satconf_post_stop_mux(lfe->lfe_satconf); if (lfe->lfe_master) { - lfe2 = (linuxdvb_frontend_t *)idnode_find(lfe->lfe_master, &linuxdvb_frontend_class, NULL); + lfe2 = (linuxdvb_frontend_t*)idnode_find(lfe->lfe_master, &linuxdvb_frontend_class, NULL); if (lfe2->lfe_type != lfe->lfe_type) lfe2 = NULL; if (lfe2) { /* master tuner shutdown procedure */ @@ -723,31 +628,30 @@ linuxdvb_frontend_stop_mux if (lfe2->lfe_satconf) linuxdvb_satconf_post_stop_mux(lfe2->lfe_satconf); lfe2->lfe_in_setup = 0; - lfe2->lfe_freq = 0; + lfe2->lfe_freq = 0; } } } lfe->lfe_refcount--; lfe->lfe_in_setup = 0; - lfe->lfe_freq = 0; + lfe->lfe_freq = 0; mpegts_pid_done(&lfe->lfe_pids); } -static int -linuxdvb_frontend_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2 = NULL; - mpegts_mux_instance_t *lmmi = NULL; - int r; +static int linuxdvb_frontend_warm_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { + linuxdvb_frontend_t * lfe = (linuxdvb_frontend_t*)mi, *lfe2 = NULL; + mpegts_mux_instance_t* lmmi = NULL; + int r; r = mpegts_input_warm_mux(mi, mmi); if (r) return r; /* Stop other active frontend (should be only one) */ - LIST_FOREACH(lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { - if (lfe2 == lfe || !lfe_group(lfe, lfe2)) continue; + LIST_FOREACH (lfe2, &lfe->lfe_adapter->la_frontends, lfe_link) { + if (lfe2 == lfe || !lfe_group(lfe, lfe2)) + continue; tvh_mutex_lock(&lfe2->mi_output_lock); lmmi = LIST_FIRST(&lfe2->mi_mux_active); tvh_mutex_unlock(&lfe2->mi_output_lock); @@ -761,12 +665,9 @@ linuxdvb_frontend_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) return 0; } -static int -linuxdvb_frontend_start_mux - ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weight ) -{ +static int linuxdvb_frontend_start_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi, int weight) { linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2; - int res, f; + int res, f; assert(lfe->lfe_in_setup == 0); @@ -776,7 +677,7 @@ linuxdvb_frontend_start_mux if (lfe->lfe_master) { assert(lfe->lfe_type == DVB_TYPE_S); - lfe2 = (linuxdvb_frontend_t *)idnode_find(lfe->lfe_master, &linuxdvb_frontend_class, NULL); + lfe2 = (linuxdvb_frontend_t*)idnode_find(lfe->lfe_master, &linuxdvb_frontend_class, NULL); if (lfe2 && lfe2->lfe_type != lfe->lfe_type) lfe2 = NULL; res = SM_CODE_TUNING_FAILED; @@ -787,7 +688,7 @@ linuxdvb_frontend_start_mux if (lfe2->lfe_refcount++ == 0) { lfe2->lfe_in_setup = 1; lfe2->lfe_ioctls = 0; - res = linuxdvb_satconf_start_mux(lfe2->lfe_satconf, mmi, 0); + res = linuxdvb_satconf_start_mux(lfe2->lfe_satconf, mmi, 0); if (res) goto end; } @@ -809,21 +710,18 @@ end: return res; } -static void -linuxdvb_frontend_update_pids - ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi; - mpegts_pid_t *mp; - mpegts_pid_sub_t *mps; +static void linuxdvb_frontend_update_pids(mpegts_input_t* mi, mpegts_mux_t* mm) { + linuxdvb_frontend_t* lfe = (linuxdvb_frontend_t*)mi; + mpegts_pid_t* mp; + mpegts_pid_sub_t* mps; tvh_mutex_lock(&lfe->lfe_dvr_lock); mpegts_pid_done(&lfe->lfe_pids); - RB_FOREACH(mp, &mm->mm_pids, mp_link) { + RB_FOREACH (mp, &mm->mm_pids, mp_link) { if (mp->mp_pid == MPEGTS_FULLMUX_PID) lfe->lfe_pids.all = 1; else if (mp->mp_pid < MPEGTS_FULLMUX_PID) { - RB_FOREACH(mps, &mp->mp_subs, mps_link) + RB_FOREACH (mps, &mp->mp_subs, mps_link) mpegts_pid_add(&lfe->lfe_pids, mp->mp_pid, mps->mps_weight); } } @@ -833,34 +731,29 @@ linuxdvb_frontend_update_pids tvh_write(lfe->lfe_dvr_pipe.wr, "c", 1); } -static void -linuxdvb_frontend_create_mux_instance - ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ - tvh_hardware_t *th; - linuxdvb_adapter_t *la; - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t *)mi, *lfe2; - char ubuf[UUID_HEX_SIZE]; +static void linuxdvb_frontend_create_mux_instance(mpegts_input_t* mi, mpegts_mux_t* mm) { + tvh_hardware_t* th; + linuxdvb_adapter_t* la; + linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi, *lfe2; + char ubuf[UUID_HEX_SIZE]; idnode_uuid_as_str(&lfe->ti_id, ubuf); mpegts_input_create_mux_instance(mi, mm); /* create the instances for the slaves */ - LIST_FOREACH(th, &tvh_hardware, th_link) { - if (!idnode_is_instance(&th->th_id, &linuxdvb_adapter_class)) continue; + LIST_FOREACH (th, &tvh_hardware, th_link) { + if (!idnode_is_instance(&th->th_id, &linuxdvb_adapter_class)) + continue; la = (linuxdvb_adapter_t*)th; - LIST_FOREACH(lfe2, &la->la_frontends, lfe_link) + LIST_FOREACH (lfe2, &la->la_frontends, lfe_link) if (lfe2->lfe_master && strcmp(lfe2->lfe_master, ubuf) == 0) - mpegts_input_create_mux_instance((mpegts_input_t *)lfe2, mm); + mpegts_input_create_mux_instance((mpegts_input_t*)lfe2, mm); } } -static idnode_set_t * -linuxdvb_frontend_network_list ( mpegts_input_t *mi ) -{ - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)mi; +static idnode_set_t* linuxdvb_frontend_network_list(mpegts_input_t* mi) { + linuxdvb_frontend_t* lfe = (linuxdvb_frontend_t*)mi; - tvhtrace(LS_LINUXDVB, "%s: network list for %s", - mi->mi_name ?: "", dvb_type2str(lfe->lfe_type)); + tvhtrace(LS_LINUXDVB, "%s: network list for %s", mi->mi_name ?: "", dvb_type2str(lfe->lfe_type)); return dvb_network_list_by_fe_type(lfe->lfe_type); } @@ -869,43 +762,37 @@ linuxdvb_frontend_network_list ( mpegts_input_t *mi ) * Data processing * *************************************************************************/ -static inline int -ioctl_check( linuxdvb_frontend_t *lfe, int bit ) -{ +static inline int ioctl_check(linuxdvb_frontend_t* lfe, int bit) { return !(lfe->lfe_ioctls & (1 << bit)); } -static inline void -ioctl_bad( linuxdvb_frontend_t *lfe, int bit ) -{ +static inline void ioctl_bad(linuxdvb_frontend_t* lfe, int bit) { lfe->lfe_ioctls |= 1 << bit; } -static void -linuxdvb_frontend_monitor ( void *aux ) -{ - uint16_t u16; - uint32_t u32; - char buf[256]; - linuxdvb_frontend_t *lfe = aux; - mpegts_mux_instance_t *mmi = LIST_FIRST(&lfe->mi_mux_active); - mpegts_mux_t *mm; - fe_status_t fe_status; - signal_state_t status; - signal_status_t sigstat; - streaming_message_t sm; - service_t *s; - int logit = 0, retune, e; - uint32_t period = MINMAX(lfe->lfe_status_period, 250, 8000); -#if DVB_VER_ATLEAST(5,10) - struct dtv_property fe_properties[6]; +static void linuxdvb_frontend_monitor(void* aux) { + uint16_t u16; + uint32_t u32; + char buf[256]; + linuxdvb_frontend_t* lfe = aux; + mpegts_mux_instance_t* mmi = LIST_FIRST(&lfe->mi_mux_active); + mpegts_mux_t* mm; + fe_status_t fe_status; + signal_state_t status; + signal_status_t sigstat; + streaming_message_t sm; + service_t* s; + int logit = 0, retune, e; + uint32_t period = MINMAX(lfe->lfe_status_period, 250, 8000); +#if DVB_VER_ATLEAST(5, 10) + struct dtv_property fe_properties[6]; struct dtv_properties dtv_prop; - int gotprop; + int gotprop; #endif lfe->mi_display_name((mpegts_input_t*)lfe, buf, sizeof(buf)); tvhtrace(LS_LINUXDVB, "%s - checking FE status%s", buf, lfe->lfe_ready ? " (ready)" : ""); - + /* Disabled */ if (!lfe->mi_enabled && mmi) mmi->mmi_mux->mm_stop(mmi->mmi_mux, 1, SM_CODE_ABORTED); @@ -931,7 +818,8 @@ linuxdvb_frontend_monitor ( void *aux ) } /* Stop timer */ - if (!mmi || !lfe->lfe_ready) return; + if (!mmi || !lfe->lfe_ready) + return; /* re-arm */ mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, ms2mono(period)); @@ -953,20 +841,22 @@ linuxdvb_frontend_monitor ( void *aux ) /* Set default period */ if (fe_status != lfe->lfe_status) { - tvhdebug(LS_LINUXDVB, "%s - status %7s (%s%s%s%s%s%s)", buf, - signal2str(status), - (fe_status & FE_HAS_SIGNAL) ? "SIGNAL" : "", - (fe_status & FE_HAS_CARRIER) ? " | CARRIER" : "", - (fe_status & FE_HAS_VITERBI) ? " | VITERBI" : "", - (fe_status & FE_HAS_SYNC) ? " | SYNC" : "", - (fe_status & FE_HAS_LOCK) ? " | LOCK" : "", - (fe_status & FE_TIMEDOUT) ? "TIMEOUT" : ""); + tvhdebug(LS_LINUXDVB, + "%s - status %7s (%s%s%s%s%s%s)", + buf, + signal2str(status), + (fe_status & FE_HAS_SIGNAL) ? "SIGNAL" : "", + (fe_status & FE_HAS_CARRIER) ? " | CARRIER" : "", + (fe_status & FE_HAS_VITERBI) ? " | VITERBI" : "", + (fe_status & FE_HAS_SYNC) ? " | SYNC" : "", + (fe_status & FE_HAS_LOCK) ? " | LOCK" : "", + (fe_status & FE_TIMEDOUT) ? "TIMEOUT" : ""); } else { tvhtrace(LS_LINUXDVB, "%s - status %d (%04X)", buf, status, fe_status); } retune = NOSIGNAL(fe_status) && NOSIGNAL(lfe->lfe_status) && !NOSIGNAL(lfe->lfe_status2); lfe->lfe_status2 = lfe->lfe_status; - lfe->lfe_status = fe_status; + lfe->lfe_status = fe_status; /* Retune check - we lost signal or no data were received */ if (retune || lfe->lfe_nodata) { @@ -989,12 +879,15 @@ linuxdvb_frontend_monitor ( void *aux ) if (status == SIGNAL_GOOD) { tvhdebug(LS_LINUXDVB, "%s - locked", buf); lfe->lfe_locked = 1; - + /* Start input */ tvh_pipe(O_NONBLOCK, &lfe->lfe_dvr_pipe); tvh_mutex_lock(&lfe->lfe_dvr_lock); - tvh_thread_create(&lfe->lfe_dvr_thread, NULL, - linuxdvb_frontend_input_thread, lfe, "lnxdvb-front"); + tvh_thread_create(&lfe->lfe_dvr_thread, + NULL, + linuxdvb_frontend_input_thread, + lfe, + "lnxdvb-front"); do { e = tvh_cond_wait(&lfe->lfe_dvr_cond, &lfe->lfe_dvr_lock); if (e == ETIMEDOUT) @@ -1003,13 +896,11 @@ linuxdvb_frontend_monitor ( void *aux ) tvh_mutex_unlock(&lfe->lfe_dvr_lock); /* Table handlers */ - psi_tables_install((mpegts_input_t *)lfe, mm, - ((dvb_mux_t *)mm)->lm_tuning.dmc_fe_delsys); + psi_tables_install((mpegts_input_t*)lfe, mm, ((dvb_mux_t*)mm)->lm_tuning.dmc_fe_delsys); - /* Re-arm (quick) */ + /* Re-arm (quick) */ } else { - mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, - lfe, ms2mono(50)); + mtimer_arm_rel(&lfe->lfe_monitor_timer, linuxdvb_frontend_monitor, lfe, ms2mono(50)); /* Monitor 1 per sec */ if (mclk() < lfe->lfe_monitor) @@ -1022,11 +913,10 @@ linuxdvb_frontend_monitor ( void *aux ) lfe->lfe_monitor = mclk() + ms2mono(period); } - tvh_mutex_lock(&mmi->tii_stats_mutex); /* Statistics - New API */ -#if DVB_VER_ATLEAST(5,10) +#if DVB_VER_ATLEAST(5, 10) memset(&fe_properties, 0, sizeof(fe_properties)); /* Signal strength */ @@ -1042,14 +932,14 @@ linuxdvb_frontend_monitor ( void *aux ) /* PER / UNC */ fe_properties[4].cmd = DTV_STAT_ERROR_BLOCK_COUNT; fe_properties[5].cmd = DTV_STAT_TOTAL_BLOCK_COUNT; - dtv_prop.num = 6; - dtv_prop.props = fe_properties; + dtv_prop.num = 6; + dtv_prop.props = fe_properties; logit = tvhlog_limit(&lfe->lfe_status_log, 3600); gotprop = 0; - if(ioctl_check(lfe, 0) && !lfe->lfe_old_status && - !ioctl(lfe->lfe_fe_fd, FE_GET_PROPERTY, &dtv_prop)) { + if (ioctl_check(lfe, 0) && !lfe->lfe_old_status && + !ioctl(lfe->lfe_fe_fd, FE_GET_PROPERTY, &dtv_prop)) { for (e = 0; e < dtv_prop.num; e++) if (fe_properties[e].u.st.len > 0) { gotprop = 1; @@ -1057,75 +947,74 @@ linuxdvb_frontend_monitor ( void *aux ) } } - if(gotprop) { + if (gotprop) { /* Signal strength */ - if(ioctl_check(lfe, 1) && fe_properties[0].u.st.len > 0) { - if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_RELATIVE) { + if (ioctl_check(lfe, 1) && fe_properties[0].u.st.len > 0) { + if (fe_properties[0].u.st.stat[0].scale == FE_SCALE_RELATIVE) { mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE; - mmi->tii_stats.signal = sig_multiply(fe_properties[0].u.st.stat[0].uvalue, lfe->lfe_sig_multiplier); - } - else if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_DECIBEL) { + mmi->tii_stats.signal = + sig_multiply(fe_properties[0].u.st.stat[0].uvalue, lfe->lfe_sig_multiplier); + } else if (fe_properties[0].u.st.stat[0].scale == FE_SCALE_DECIBEL) { mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_DECIBEL; - mmi->tii_stats.signal = sig_multiply(fe_properties[0].u.st.stat[0].svalue, lfe->lfe_sig_multiplier); - } - else if(fe_properties[0].u.st.stat[0].scale == FE_SCALE_NOT_AVAILABLE) { + mmi->tii_stats.signal = + sig_multiply(fe_properties[0].u.st.stat[0].svalue, lfe->lfe_sig_multiplier); + } else if (fe_properties[0].u.st.stat[0].scale == FE_SCALE_NOT_AVAILABLE) { mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN; - } - else { + } else { ioctl_bad(lfe, 1); mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN; if (logit) - tvhwarn(LS_LINUXDVB, "Unhandled signal scale: %d", - fe_properties[0].u.st.stat[0].scale); + tvhwarn(LS_LINUXDVB, "Unhandled signal scale: %d", fe_properties[0].u.st.stat[0].scale); } } /* ERROR_BIT_COUNT */ - if(ioctl_check(lfe, 3) && fe_properties[1].u.st.len > 0) { - if(fe_properties[1].u.st.stat[0].scale == FE_SCALE_COUNTER) { + if (ioctl_check(lfe, 3) && fe_properties[1].u.st.len > 0) { + if (fe_properties[1].u.st.stat[0].scale == FE_SCALE_COUNTER) { mmi->tii_stats.ec_bit = fe_properties[1].u.st.stat[0].uvalue; } else { ioctl_bad(lfe, 3); mmi->tii_stats.ec_bit = 0; if (logit) - tvhwarn(LS_LINUXDVB, "Unhandled ERROR_BIT_COUNT scale: %d", - fe_properties[1].u.st.stat[0].scale); + tvhwarn(LS_LINUXDVB, + "Unhandled ERROR_BIT_COUNT scale: %d", + fe_properties[1].u.st.stat[0].scale); } } /* TOTAL_BIT_COUNT */ - if(fe_properties[2].u.st.len > 0) { - if(ioctl_check(lfe, 4) && fe_properties[2].u.st.stat[0].scale == FE_SCALE_COUNTER) { + if (fe_properties[2].u.st.len > 0) { + if (ioctl_check(lfe, 4) && fe_properties[2].u.st.stat[0].scale == FE_SCALE_COUNTER) { mmi->tii_stats.tc_bit = fe_properties[2].u.st.stat[0].uvalue; } else { ioctl_bad(lfe, 4); mmi->tii_stats.tc_bit = 0; if (logit && fe_properties[2].u.st.stat[0].scale == FE_SCALE_COUNTER) - tvhwarn(LS_LINUXDVB, "Unhandled TOTAL_BIT_COUNT scale: %d", - fe_properties[2].u.st.stat[0].scale); + tvhwarn(LS_LINUXDVB, + "Unhandled TOTAL_BIT_COUNT scale: %d", + fe_properties[2].u.st.stat[0].scale); } } /* SNR */ - if(ioctl_check(lfe, 6) && fe_properties[3].u.st.len > 0) { - if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_RELATIVE) { + if (ioctl_check(lfe, 6) && fe_properties[3].u.st.len > 0) { + if (fe_properties[3].u.st.stat[0].scale == FE_SCALE_RELATIVE) { mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE; - mmi->tii_stats.snr = sig_multiply(fe_properties[3].u.st.stat[0].uvalue, lfe->lfe_snr_multiplier); - } - else if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_DECIBEL) { + mmi->tii_stats.snr = + sig_multiply(fe_properties[3].u.st.stat[0].uvalue, lfe->lfe_snr_multiplier); + } else if (fe_properties[3].u.st.stat[0].scale == FE_SCALE_DECIBEL) { mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_DECIBEL; - mmi->tii_stats.snr = sig_multiply(fe_properties[3].u.st.stat[0].svalue, lfe->lfe_snr_multiplier); - } - else if(fe_properties[3].u.st.stat[0].scale == FE_SCALE_NOT_AVAILABLE) { + mmi->tii_stats.snr = + sig_multiply(fe_properties[3].u.st.stat[0].svalue, lfe->lfe_snr_multiplier); + } else if (fe_properties[3].u.st.stat[0].scale == FE_SCALE_NOT_AVAILABLE) { mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN; } else { ioctl_bad(lfe, 6); mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN; if (logit) - tvhwarn(LS_LINUXDVB, "Unhandled SNR scale: %d", - fe_properties[3].u.st.stat[0].scale); + tvhwarn(LS_LINUXDVB, "Unhandled SNR scale: %d", fe_properties[3].u.st.stat[0].scale); } } /* ERROR_BLOCK_COUNT == Uncorrected blocks (UNC) */ - if(ioctl_check(lfe, 8) && fe_properties[4].u.st.len > 0) { - if(fe_properties[4].u.st.stat[0].scale == FE_SCALE_COUNTER) { + if (ioctl_check(lfe, 8) && fe_properties[4].u.st.len > 0) { + if (fe_properties[4].u.st.stat[0].scale == FE_SCALE_COUNTER) { atomic_set(&mmi->tii_stats.unc, fe_properties[4].u.st.stat[0].uvalue); mmi->tii_stats.ec_block = fe_properties[4].u.st.stat[0].uvalue; } else { @@ -1133,32 +1022,33 @@ linuxdvb_frontend_monitor ( void *aux ) atomic_set(&mmi->tii_stats.unc, 0); mmi->tii_stats.ec_block = 0; if (logit) - tvhwarn(LS_LINUXDVB, "Unhandled ERROR_BLOCK_COUNT scale: %d", - fe_properties[4].u.st.stat[0].scale); + tvhwarn(LS_LINUXDVB, + "Unhandled ERROR_BLOCK_COUNT scale: %d", + fe_properties[4].u.st.stat[0].scale); } } /* TOTAL_BLOCK_COUNT */ - if(ioctl_check(lfe, 9) && fe_properties[5].u.st.len > 0) { - if(fe_properties[5].u.st.stat[0].scale == FE_SCALE_COUNTER) { + if (ioctl_check(lfe, 9) && fe_properties[5].u.st.len > 0) { + if (fe_properties[5].u.st.stat[0].scale == FE_SCALE_COUNTER) { mmi->tii_stats.tc_block = fe_properties[5].u.st.stat[0].uvalue; } else { ioctl_bad(lfe, 9); mmi->tii_stats.tc_block = 0; if (logit) - tvhwarn(LS_LINUXDVB, "Unhandled TOTAL_BLOCK_COUNT scale: %d", - fe_properties[5].u.st.stat[0].scale); + tvhwarn(LS_LINUXDVB, + "Unhandled TOTAL_BLOCK_COUNT scale: %d", + fe_properties[5].u.st.stat[0].scale); } } - /* Older API */ + /* Older API */ } else #endif { ioctl_bad(lfe, 0); if (ioctl_check(lfe, 1) && !ioctl(lfe->lfe_fe_fd, FE_READ_SIGNAL_STRENGTH, &u16)) { mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE; - mmi->tii_stats.signal = sig_multiply(u16, lfe->lfe_sig_multiplier); - } - else { + mmi->tii_stats.signal = sig_multiply(u16, lfe->lfe_sig_multiplier); + } else { ioctl_bad(lfe, 1); mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN; if (logit) @@ -1173,9 +1063,8 @@ linuxdvb_frontend_monitor ( void *aux ) } if (ioctl_check(lfe, 3) && !ioctl(lfe->lfe_fe_fd, FE_READ_SNR, &u16)) { mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE; - mmi->tii_stats.snr = sig_multiply(u16, lfe->lfe_snr_multiplier); - } - else { + mmi->tii_stats.snr = sig_multiply(u16, lfe->lfe_snr_multiplier); + } else { ioctl_bad(lfe, 3); mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN; if (logit) @@ -1208,7 +1097,7 @@ linuxdvb_frontend_monitor ( void *aux ) tvh_mutex_unlock(&mmi->tii_stats_mutex); - LIST_FOREACH(s, &mmi->mmi_mux->mm_transports, s_active_link) { + LIST_FOREACH (s, &mmi->mmi_mux->mm_transports, s_active_link) { tvh_mutex_lock(&s->s_stream_mutex); streaming_service_deliver(s, streaming_msg_clone(&sm)); tvh_mutex_unlock(&s->s_stream_mutex); @@ -1220,26 +1109,25 @@ typedef struct linuxdvb_pid { int pid; } linuxdvb_pid_t; -static void -linuxdvb_frontend_open_pid0 - ( linuxdvb_frontend_t *lfe, const char *name, - linuxdvb_pid_t *pids, int pids_size, int pid ) -{ +static void linuxdvb_frontend_open_pid0(linuxdvb_frontend_t* lfe, + const char* name, + linuxdvb_pid_t* pids, + int pids_size, + int pid) { struct dmx_pes_filter_params dmx_param; - int fd; + int fd; - for ( ; pids_size > 0 && pids->fd >= 0; pids_size--, pids++); + for (; pids_size > 0 && pids->fd >= 0; pids_size--, pids++) + ; if (pids_size == 0) { - tvherror(LS_LINUXDVB, "%s - maximum PID count reached, pid %d ignored", - name, pid); + tvherror(LS_LINUXDVB, "%s - maximum PID count reached, pid %d ignored", name, pid); return; } /* Open DMX */ fd = tvh_open(lfe->lfe_dmx_path, O_RDWR, 0); - if(fd == -1) { - tvherror(LS_LINUXDVB, "%s - failed to open dmx for pid %d [e=%s]", - name, pid, strerror(errno)); + if (fd == -1) { + tvherror(LS_LINUXDVB, "%s - failed to open dmx for pid %d [e=%s]", name, pid, strerror(errno)); return; } @@ -1252,36 +1140,37 @@ linuxdvb_frontend_open_pid0 dmx_param.pes_type = DMX_PES_OTHER; dmx_param.flags = DMX_IMMEDIATE_START; - if(ioctl(fd, DMX_SET_PES_FILTER, &dmx_param)) { - tvherror(LS_LINUXDVB, "%s - failed to config dmx for pid %d [e=%s]", - name, pid, strerror(errno)); + if (ioctl(fd, DMX_SET_PES_FILTER, &dmx_param)) { + tvherror(LS_LINUXDVB, + "%s - failed to config dmx for pid %d [e=%s]", + name, + pid, + strerror(errno)); close(fd); return; } /* Store */ - pids->fd = fd; + pids->fd = fd; pids->pid = pid; } -static void -linuxdvb_frontend_close_pid0 - ( linuxdvb_frontend_t *lfe, const char *name, - linuxdvb_pid_t *pids, int pids_size, int pid ) -{ - for ( ; pids_size > 0 && pids->pid != pid; - pids_size--, pids++); +static void linuxdvb_frontend_close_pid0(linuxdvb_frontend_t* lfe, + const char* name, + linuxdvb_pid_t* pids, + int pids_size, + int pid) { + for (; pids_size > 0 && pids->pid != pid; pids_size--, pids++) + ; if (pids_size == 0) return; tvhtrace(LS_LINUXDVB, "%s - close PID %04X (%d) fd %d", name, pid, pid, pids->fd); close(pids->fd); - pids->fd = -1; + pids->fd = -1; pids->pid = -1; } -static int -linuxdvb_pid_exists ( linuxdvb_pid_t *pids, int pids_size, int pid ) -{ +static int linuxdvb_pid_exists(linuxdvb_pid_t* pids, int pids_size, int pid) { int i; for (i = 0; i < pids_size; i++) if (pids[i].fd >= 0 && pids[i].pid == pid) @@ -1289,15 +1178,15 @@ linuxdvb_pid_exists ( linuxdvb_pid_t *pids, int pids_size, int pid ) return 0; } -static void -linuxdvb_update_pids ( linuxdvb_frontend_t *lfe, const char *name, - mpegts_apids_t *tuned, linuxdvb_pid_t *pids, - int pids_size ) -{ +static void linuxdvb_update_pids(linuxdvb_frontend_t* lfe, + const char* name, + mpegts_apids_t* tuned, + linuxdvb_pid_t* pids, + int pids_size) { mpegts_apids_t wpid, padd, pdel; - int i, max = MAX(14, lfe->lfe_pids_max), overlimit; - int all = lfe->lfe_pids.all; - char buf[512]; + int i, max = MAX(14, lfe->lfe_pids_max), overlimit; + int all = lfe->lfe_pids.all; + char buf[512]; tvh_mutex_lock(&lfe->lfe_dvr_lock); @@ -1317,7 +1206,7 @@ linuxdvb_update_pids ( linuxdvb_frontend_t *lfe, const char *name, for (i = 0; i < pdel.count; i++) linuxdvb_frontend_close_pid0(lfe, name, pids, pids_size, pdel.pids[i].pid); for (i = 0; i < padd.count; i++) - linuxdvb_frontend_open_pid0(lfe, name, pids, pids_size, padd.pids[i].pid); + linuxdvb_frontend_open_pid0(lfe, name, pids, pids_size, padd.pids[i].pid); mpegts_pid_done(&padd); mpegts_pid_done(&pdel); mpegts_pid_copy(tuned, &wpid); @@ -1335,25 +1224,23 @@ linuxdvb_update_pids ( linuxdvb_frontend_t *lfe, const char *name, tvh_mutex_unlock(&lfe->lfe_dvr_lock); } -static void * -linuxdvb_frontend_input_thread ( void *aux ) -{ - linuxdvb_frontend_t *lfe = aux; - mpegts_mux_instance_t *mmi; - char name[256], b; - tvhpoll_event_t ev[2]; - tvhpoll_t *efd; - ssize_t n; - size_t skip = (MIN(lfe->lfe_skip_bytes, 1024*1024) / 188) * 188; - size_t counter = 0; - linuxdvb_pid_t pids[128]; - mpegts_apids_t tuned; - sbuf_t sb; - int i, dvr = -1, nfds, nodata = 4; +static void* linuxdvb_frontend_input_thread(void* aux) { + linuxdvb_frontend_t* lfe = aux; + mpegts_mux_instance_t* mmi; + char name[256], b; + tvhpoll_event_t ev[2]; + tvhpoll_t* efd; + ssize_t n; + size_t skip = (MIN(lfe->lfe_skip_bytes, 1024 * 1024) / 188) * 188; + size_t counter = 0; + linuxdvb_pid_t pids[128]; + mpegts_apids_t tuned; + sbuf_t sb; + int i, dvr = -1, nfds, nodata = 4; mpegts_pid_init(&tuned); for (i = 0; i < ARRAY_SIZE(pids); i++) { - pids[i].fd = -1; + pids[i].fd = -1; pids[i].pid = -1; } @@ -1363,7 +1250,8 @@ linuxdvb_frontend_input_thread ( void *aux ) mmi = LIST_FIRST(&lfe->mi_mux_active); tvh_cond_signal(&lfe->lfe_dvr_cond, 0); tvh_mutex_unlock(&lfe->lfe_dvr_lock); - if (mmi == NULL) return NULL; + if (mmi == NULL) + return NULL; /* Open DVR */ dvr = tvh_open(lfe->lfe_dvr_path, O_RDONLY | O_NONBLOCK, 0); @@ -1395,13 +1283,14 @@ linuxdvb_frontend_input_thread ( void *aux ) if (nfds == 0) { /* timeout */ if (nodata == 0) { tvhwarn(LS_LINUXDVB, "%s - poll TIMEOUT", name); - nodata = 50; + nodata = 50; lfe->lfe_nodata = 1; } else { nodata--; } } - if (nfds < 1) continue; + if (nfds < 1) + continue; if (ev[0].ptr == &lfe->lfe_dvr_pipe) { if (read(lfe->lfe_dvr_pipe.rd, &b, 1) > 0) { if (b == 'c') @@ -1411,11 +1300,12 @@ linuxdvb_frontend_input_thread ( void *aux ) } continue; } - if (ev[0].ptr != lfe) break; + if (ev[0].ptr != lfe) + break; - nodata = 50; + nodata = 50; lfe->lfe_nodata = 0; - + /* Read */ if ((n = sbuf_read(&sb, dvr)) < 0) { if (ERRNO_AGAIN(errno)) @@ -1424,8 +1314,7 @@ linuxdvb_frontend_input_thread ( void *aux ) tvhwarn(LS_LINUXDVB, "%s - read() EOVERFLOW", name); continue; } - tvherror(LS_LINUXDVB, "%s - read() error %d (%s)", - name, errno, strerror(errno)); + tvherror(LS_LINUXDVB, "%s - read() error %d (%s)", name, errno, strerror(errno)); break; } @@ -1438,7 +1327,7 @@ linuxdvb_frontend_input_thread ( void *aux ) sbuf_cut(&sb, skip - (counter - n)); } } - + /* Process */ mpegts_input_recv_packets(mmi, &sb, 0, NULL); } @@ -1465,9 +1354,7 @@ typedef struct linuxdvb_tbl { #define TABLE_EOD -1 #if DVB_API_VERSION >= 5 -static int -linuxdvb2tvh ( const char *prefix, linuxdvb_tbl_t *tbl, int key, int defval ) -{ +static int linuxdvb2tvh(const char* prefix, linuxdvb_tbl_t* tbl, int key, int defval) { while (tbl->t != TABLE_EOD) { if (tbl->l == key) return tbl->t; @@ -1478,9 +1365,7 @@ linuxdvb2tvh ( const char *prefix, linuxdvb_tbl_t *tbl, int key, int defval ) } #endif -static int -tvh2linuxdvb ( const char *prefix, linuxdvb_tbl_t *tbl, int key, int defval ) -{ +static int tvh2linuxdvb(const char* prefix, linuxdvb_tbl_t* tbl, int key, int defval) { while (tbl->t != TABLE_EOD) { if (tbl->t == key) return tbl->l; @@ -1490,55 +1375,49 @@ tvh2linuxdvb ( const char *prefix, linuxdvb_tbl_t *tbl, int key, int defval ) return defval; } -#define TOSTR(s) #s -#define TR(s, t, d) tvh2linuxdvb(TOSTR(s), t, dmc->dmc_fe_##s , d) -#define TRU(s, t, d) tvh2linuxdvb(TOSTR(s), t, dmc->u.dmc_fe_##s , d) +#define TOSTR(s) #s +#define TR(s, t, d) tvh2linuxdvb(TOSTR(s), t, dmc->dmc_fe_##s, d) +#define TRU(s, t, d) tvh2linuxdvb(TOSTR(s), t, dmc->u.dmc_fe_##s, d) #if DVB_API_VERSION >= 5 -static linuxdvb_tbl_t delsys_tbl[] = { - { .t = DVB_SYS_DVBC_ANNEX_B, .l = SYS_DVBC_ANNEX_B }, -#if DVB_VER_ATLEAST(5,6) - { .t = DVB_SYS_DVBC_ANNEX_A, .l = SYS_DVBC_ANNEX_A }, - { .t = DVB_SYS_DVBC_ANNEX_C, .l = SYS_DVBC_ANNEX_C }, +static linuxdvb_tbl_t delsys_tbl[] = {{.t = DVB_SYS_DVBC_ANNEX_B, .l = SYS_DVBC_ANNEX_B}, +#if DVB_VER_ATLEAST(5, 6) + {.t = DVB_SYS_DVBC_ANNEX_A, .l = SYS_DVBC_ANNEX_A}, + {.t = DVB_SYS_DVBC_ANNEX_C, .l = SYS_DVBC_ANNEX_C}, #else - { .t = DVB_SYS_DVBC_ANNEX_A, .l = SYS_DVBC_ANNEX_AC }, - { .t = DVB_SYS_DVBC_ANNEX_C, .l = SYS_DVBC_ANNEX_AC }, + {.t = DVB_SYS_DVBC_ANNEX_A, .l = SYS_DVBC_ANNEX_AC}, + {.t = DVB_SYS_DVBC_ANNEX_C, .l = SYS_DVBC_ANNEX_AC}, #endif - { .t = DVB_SYS_DVBT, .l = SYS_DVBT }, -#if DVB_VER_ATLEAST(5,3) - { .t = DVB_SYS_DVBT2, .l = SYS_DVBT2 }, + {.t = DVB_SYS_DVBT, .l = SYS_DVBT}, +#if DVB_VER_ATLEAST(5, 3) + {.t = DVB_SYS_DVBT2, .l = SYS_DVBT2}, #endif - { .t = DVB_SYS_DVBS, .l = SYS_DVBS }, - { .t = DVB_SYS_DVBS2, .l = SYS_DVBS2 }, - { .t = DVB_SYS_DVBH, .l = SYS_DVBH }, -#if DVB_VER_ATLEAST(5,1) - { .t = DVB_SYS_DSS, .l = SYS_DSS }, + {.t = DVB_SYS_DVBS, .l = SYS_DVBS}, + {.t = DVB_SYS_DVBS2, .l = SYS_DVBS2}, + {.t = DVB_SYS_DVBH, .l = SYS_DVBH}, +#if DVB_VER_ATLEAST(5, 1) + {.t = DVB_SYS_DSS, .l = SYS_DSS}, #endif - { .t = DVB_SYS_ISDBT, .l = SYS_ISDBT }, - { .t = DVB_SYS_ISDBS, .l = SYS_ISDBS }, - { .t = DVB_SYS_ISDBC, .l = SYS_ISDBC }, - { .t = DVB_SYS_ATSC, .l = SYS_ATSC }, - { .t = DVB_SYS_ATSCMH, .l = SYS_ATSCMH }, -#if DVB_VER_ATLEAST(5,7) - { .t = DVB_SYS_DTMB, .l = SYS_DTMB }, + {.t = DVB_SYS_ISDBT, .l = SYS_ISDBT}, + {.t = DVB_SYS_ISDBS, .l = SYS_ISDBS}, + {.t = DVB_SYS_ISDBC, .l = SYS_ISDBC}, + {.t = DVB_SYS_ATSC, .l = SYS_ATSC}, + {.t = DVB_SYS_ATSCMH, .l = SYS_ATSCMH}, +#if DVB_VER_ATLEAST(5, 7) + {.t = DVB_SYS_DTMB, .l = SYS_DTMB}, #endif - { .t = DVB_SYS_CMMB, .l = SYS_CMMB }, - { .t = DVB_SYS_DAB, .l = SYS_DAB }, -#if DVB_VER_ATLEAST(5,4) - { .t = DVB_SYS_TURBO, .l = SYS_TURBO }, + {.t = DVB_SYS_CMMB, .l = SYS_CMMB}, + {.t = DVB_SYS_DAB, .l = SYS_DAB}, +#if DVB_VER_ATLEAST(5, 4) + {.t = DVB_SYS_TURBO, .l = SYS_TURBO}, #endif - { .t = TABLE_EOD } -}; -int linuxdvb2tvh_delsys ( int delsys ) -{ + {.t = TABLE_EOD}}; +int linuxdvb2tvh_delsys(int delsys) { return linuxdvb2tvh("delsys", delsys_tbl, delsys, DVB_SYS_NONE); } #endif -int -linuxdvb_frontend_clear - ( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi ) -{ +int linuxdvb_frontend_clear(linuxdvb_frontend_t* lfe, mpegts_mux_instance_t* mmi) { char buf1[256]; /* Open FE */ @@ -1554,29 +1433,26 @@ linuxdvb_frontend_clear #if DVB_API_VERSION >= 5 static struct dtv_property clear_p[] = { - { .cmd = DTV_CLEAR }, - }; - static struct dtv_properties clear_cmdseq = { - .num = 1, - .props = clear_p + {.cmd = DTV_CLEAR}, }; + static struct dtv_properties clear_cmdseq = {.num = 1, .props = clear_p}; if ((ioctl(lfe->lfe_fe_fd, FE_SET_PROPERTY, &clear_cmdseq)) != 0) { tvherror(LS_LINUXDVB, "%s - DTV_CLEAR failed [e=%s]", buf1, strerror(errno)); return -1; } if (mmi) { - dvb_mux_t *lm = (dvb_mux_t*)mmi->mmi_mux; - dvb_mux_conf_t *dmc = &lm->lm_tuning; + dvb_mux_t* lm = (dvb_mux_t*)mmi->mmi_mux; + dvb_mux_conf_t* dmc = &lm->lm_tuning; struct dtv_property delsys_p; memset(&delsys_p, 0, sizeof(delsys_p)); struct dtv_properties delsys_cmdseq; memset(&delsys_cmdseq, 0, sizeof(delsys_cmdseq)); - delsys_cmdseq.num = 1; + delsys_cmdseq.num = 1; delsys_cmdseq.props = &delsys_p; - delsys_p.cmd = DTV_DELIVERY_SYSTEM; - delsys_p.u.data = TR(delsys, delsys_tbl, SYS_UNDEFINED); + delsys_p.cmd = DTV_DELIVERY_SYSTEM; + delsys_p.u.data = TR(delsys, delsys_tbl, SYS_UNDEFINED); if ((ioctl(lfe->lfe_fe_fd, FE_SET_PROPERTY, &delsys_cmdseq)) != 0) { tvherror(LS_LINUXDVB, "%s - DTV_DELIVERY_SYSTEM failed [e=%s]", buf1, strerror(errno)); return -1; @@ -1587,177 +1463,163 @@ linuxdvb_frontend_clear return 0; } -int -linuxdvb_frontend_tune0 - ( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi, uint32_t freq ) -{ - static linuxdvb_tbl_t inv_tbl[] = { - { .t = DVB_INVERSION_AUTO, .l = INVERSION_AUTO }, - { .t = DVB_INVERSION_OFF, .l = INVERSION_OFF }, - { .t = DVB_INVERSION_ON, .l = INVERSION_ON }, - { .t = TABLE_EOD } - }; - static linuxdvb_tbl_t bw_tbl[] = { - { .t = DVB_BANDWIDTH_AUTO, .l = BANDWIDTH_AUTO }, -#if DVB_VER_ATLEAST(5,3) - { .t = DVB_BANDWIDTH_1_712_MHZ, .l = BANDWIDTH_1_712_MHZ }, - { .t = DVB_BANDWIDTH_5_MHZ, .l = BANDWIDTH_5_MHZ }, +int linuxdvb_frontend_tune0(linuxdvb_frontend_t* lfe, mpegts_mux_instance_t* mmi, uint32_t freq) { + static linuxdvb_tbl_t inv_tbl[] = {{.t = DVB_INVERSION_AUTO, .l = INVERSION_AUTO}, + {.t = DVB_INVERSION_OFF, .l = INVERSION_OFF}, + {.t = DVB_INVERSION_ON, .l = INVERSION_ON}, + {.t = TABLE_EOD}}; + static linuxdvb_tbl_t bw_tbl[] = {{.t = DVB_BANDWIDTH_AUTO, .l = BANDWIDTH_AUTO}, +#if DVB_VER_ATLEAST(5, 3) + {.t = DVB_BANDWIDTH_1_712_MHZ, .l = BANDWIDTH_1_712_MHZ}, + {.t = DVB_BANDWIDTH_5_MHZ, .l = BANDWIDTH_5_MHZ}, #endif - { .t = DVB_BANDWIDTH_6_MHZ, .l = BANDWIDTH_6_MHZ }, - { .t = DVB_BANDWIDTH_7_MHZ, .l = BANDWIDTH_7_MHZ }, - { .t = DVB_BANDWIDTH_8_MHZ, .l = BANDWIDTH_8_MHZ }, -#if DVB_VER_ATLEAST(5,3) - { .t = DVB_BANDWIDTH_10_MHZ, .l = BANDWIDTH_10_MHZ }, + {.t = DVB_BANDWIDTH_6_MHZ, .l = BANDWIDTH_6_MHZ}, + {.t = DVB_BANDWIDTH_7_MHZ, .l = BANDWIDTH_7_MHZ}, + {.t = DVB_BANDWIDTH_8_MHZ, .l = BANDWIDTH_8_MHZ}, +#if DVB_VER_ATLEAST(5, 3) + {.t = DVB_BANDWIDTH_10_MHZ, .l = BANDWIDTH_10_MHZ}, #endif - { .t = TABLE_EOD } - }; - static linuxdvb_tbl_t fec_tbl[] = { - { .t = DVB_FEC_NONE, .l = FEC_NONE }, - { .t = DVB_FEC_AUTO, .l = FEC_AUTO }, - { .t = DVB_FEC_1_2, .l = FEC_1_2 }, - { .t = DVB_FEC_2_3, .l = FEC_2_3 }, -#if DVB_VER_ATLEAST(5,7) - { .t = DVB_FEC_2_5, .l = FEC_2_5 }, + {.t = TABLE_EOD}}; + static linuxdvb_tbl_t fec_tbl[] = {{.t = DVB_FEC_NONE, .l = FEC_NONE}, + {.t = DVB_FEC_AUTO, .l = FEC_AUTO}, + {.t = DVB_FEC_1_2, .l = FEC_1_2}, + {.t = DVB_FEC_2_3, .l = FEC_2_3}, +#if DVB_VER_ATLEAST(5, 7) + {.t = DVB_FEC_2_5, .l = FEC_2_5}, #endif - { .t = DVB_FEC_3_4, .l = FEC_3_4 }, -#if DVB_VER_ATLEAST(5,0) - { .t = DVB_FEC_3_5, .l = FEC_3_5 }, + {.t = DVB_FEC_3_4, .l = FEC_3_4}, +#if DVB_VER_ATLEAST(5, 0) + {.t = DVB_FEC_3_5, .l = FEC_3_5}, #endif - { .t = DVB_FEC_4_5, .l = FEC_4_5 }, - { .t = DVB_FEC_5_6, .l = FEC_5_6 }, - { .t = DVB_FEC_6_7, .l = FEC_6_7 }, - { .t = DVB_FEC_7_8, .l = FEC_7_8 }, - { .t = DVB_FEC_8_9, .l = FEC_8_9 }, -#if DVB_VER_ATLEAST(5,0) - { .t = DVB_FEC_9_10, .l = FEC_9_10 }, + {.t = DVB_FEC_4_5, .l = FEC_4_5}, + {.t = DVB_FEC_5_6, .l = FEC_5_6}, + {.t = DVB_FEC_6_7, .l = FEC_6_7}, + {.t = DVB_FEC_7_8, .l = FEC_7_8}, + {.t = DVB_FEC_8_9, .l = FEC_8_9}, +#if DVB_VER_ATLEAST(5, 0) + {.t = DVB_FEC_9_10, .l = FEC_9_10}, #endif -#if DVB_VER_ATLEAST(5,12) - { .t = DVB_FEC_1_3, .l = FEC_1_3 }, - { .t = DVB_FEC_1_4, .l = FEC_1_4 }, - { .t = DVB_FEC_4_15, .l = FEC_4_15 }, - { .t = DVB_FEC_5_9, .l = FEC_5_9 }, - { .t = DVB_FEC_7_9, .l = FEC_7_9 }, - { .t = DVB_FEC_7_15, .l = FEC_7_15 }, - { .t = DVB_FEC_8_15, .l = FEC_8_15 }, - { .t = DVB_FEC_9_20, .l = FEC_9_20 }, - { .t = DVB_FEC_11_15, .l = FEC_11_15 }, - { .t = DVB_FEC_11_20, .l = FEC_11_20 }, - { .t = DVB_FEC_11_45, .l = FEC_11_45 }, - { .t = DVB_FEC_13_18, .l = FEC_13_18 }, - { .t = DVB_FEC_13_45, .l = FEC_13_45 }, - { .t = DVB_FEC_14_45, .l = FEC_14_45 }, - { .t = DVB_FEC_23_36, .l = FEC_23_36 }, - { .t = DVB_FEC_25_36, .l = FEC_25_36 }, - { .t = DVB_FEC_26_45, .l = FEC_26_45 }, - { .t = DVB_FEC_28_45, .l = FEC_28_45 }, - { .t = DVB_FEC_32_45, .l = FEC_32_45 }, - { .t = DVB_FEC_77_90, .l = FEC_77_90 }, +#if DVB_VER_ATLEAST(5, 12) + {.t = DVB_FEC_1_3, .l = FEC_1_3}, + {.t = DVB_FEC_1_4, .l = FEC_1_4}, + {.t = DVB_FEC_4_15, .l = FEC_4_15}, + {.t = DVB_FEC_5_9, .l = FEC_5_9}, + {.t = DVB_FEC_7_9, .l = FEC_7_9}, + {.t = DVB_FEC_7_15, .l = FEC_7_15}, + {.t = DVB_FEC_8_15, .l = FEC_8_15}, + {.t = DVB_FEC_9_20, .l = FEC_9_20}, + {.t = DVB_FEC_11_15, .l = FEC_11_15}, + {.t = DVB_FEC_11_20, .l = FEC_11_20}, + {.t = DVB_FEC_11_45, .l = FEC_11_45}, + {.t = DVB_FEC_13_18, .l = FEC_13_18}, + {.t = DVB_FEC_13_45, .l = FEC_13_45}, + {.t = DVB_FEC_14_45, .l = FEC_14_45}, + {.t = DVB_FEC_23_36, .l = FEC_23_36}, + {.t = DVB_FEC_25_36, .l = FEC_25_36}, + {.t = DVB_FEC_26_45, .l = FEC_26_45}, + {.t = DVB_FEC_28_45, .l = FEC_28_45}, + {.t = DVB_FEC_32_45, .l = FEC_32_45}, + {.t = DVB_FEC_77_90, .l = FEC_77_90}, #endif - { .t = TABLE_EOD } - }; - static linuxdvb_tbl_t mod_tbl[] = { - { .t = DVB_MOD_AUTO, .l = QAM_AUTO }, - { .t = DVB_MOD_QPSK, .l = QPSK }, - { .t = DVB_MOD_QAM_16, .l = QAM_16 }, - { .t = DVB_MOD_QAM_32, .l = QAM_32 }, - { .t = DVB_MOD_QAM_64, .l = QAM_64 }, - { .t = DVB_MOD_QAM_128, .l = QAM_128 }, - { .t = DVB_MOD_QAM_256, .l = QAM_256 }, - { .t = DVB_MOD_QAM_AUTO, .l = QAM_AUTO }, - { .t = DVB_MOD_VSB_8, .l = VSB_8 }, - { .t = DVB_MOD_VSB_16, .l = VSB_16 }, -#if DVB_VER_ATLEAST(5,1) - { .t = DVB_MOD_PSK_8, .l = PSK_8, }, - { .t = DVB_MOD_APSK_16, .l = APSK_16 }, - { .t = DVB_MOD_APSK_32, .l = APSK_32 }, + {.t = TABLE_EOD}}; + static linuxdvb_tbl_t mod_tbl[] = {{.t = DVB_MOD_AUTO, .l = QAM_AUTO}, + {.t = DVB_MOD_QPSK, .l = QPSK}, + {.t = DVB_MOD_QAM_16, .l = QAM_16}, + {.t = DVB_MOD_QAM_32, .l = QAM_32}, + {.t = DVB_MOD_QAM_64, .l = QAM_64}, + {.t = DVB_MOD_QAM_128, .l = QAM_128}, + {.t = DVB_MOD_QAM_256, .l = QAM_256}, + {.t = DVB_MOD_QAM_AUTO, .l = QAM_AUTO}, + {.t = DVB_MOD_VSB_8, .l = VSB_8}, + {.t = DVB_MOD_VSB_16, .l = VSB_16}, +#if DVB_VER_ATLEAST(5, 1) + { + .t = DVB_MOD_PSK_8, + .l = PSK_8, + }, + {.t = DVB_MOD_APSK_16, .l = APSK_16}, + {.t = DVB_MOD_APSK_32, .l = APSK_32}, #endif -#if DVB_VER_ATLEAST(5,0) - { .t = DVB_MOD_DQPSK, .l = DQPSK }, +#if DVB_VER_ATLEAST(5, 0) + {.t = DVB_MOD_DQPSK, .l = DQPSK}, #endif -#if DVB_VER_ATLEAST(5,7) - { .t = DVB_MOD_QAM_4_NR, .l = QAM_4_NR }, +#if DVB_VER_ATLEAST(5, 7) + {.t = DVB_MOD_QAM_4_NR, .l = QAM_4_NR}, #endif -#if DVB_VER_ATLEAST(5,12) - { .t = DVB_MOD_QAM_1024, .l = QAM_1024 }, - { .t = DVB_MOD_QAM_4096, .l = QAM_4096 }, - { .t = DVB_MOD_APSK_8_L, .l = APSK_8_L }, - { .t = DVB_MOD_APSK_16_L, .l = APSK_16_L}, - { .t = DVB_MOD_APSK_32_L, .l = APSK_32_L}, - { .t = DVB_MOD_APSK_64, .l = APSK_64 }, - { .t = DVB_MOD_APSK_64_L, .l = APSK_64_L}, +#if DVB_VER_ATLEAST(5, 12) + {.t = DVB_MOD_QAM_1024, .l = QAM_1024}, + {.t = DVB_MOD_QAM_4096, .l = QAM_4096}, + {.t = DVB_MOD_APSK_8_L, .l = APSK_8_L}, + {.t = DVB_MOD_APSK_16_L, .l = APSK_16_L}, + {.t = DVB_MOD_APSK_32_L, .l = APSK_32_L}, + {.t = DVB_MOD_APSK_64, .l = APSK_64}, + {.t = DVB_MOD_APSK_64_L, .l = APSK_64_L}, #endif - { .t = TABLE_EOD } - }; + {.t = TABLE_EOD}}; static linuxdvb_tbl_t trans_tbl[] = { - { .t = DVB_TRANSMISSION_MODE_AUTO, .l = TRANSMISSION_MODE_AUTO }, -#if DVB_VER_ATLEAST(5,3) - { .t = DVB_TRANSMISSION_MODE_1K, .l = TRANSMISSION_MODE_1K }, + {.t = DVB_TRANSMISSION_MODE_AUTO, .l = TRANSMISSION_MODE_AUTO}, +#if DVB_VER_ATLEAST(5, 3) + {.t = DVB_TRANSMISSION_MODE_1K, .l = TRANSMISSION_MODE_1K}, #endif - { .t = DVB_TRANSMISSION_MODE_2K, .l = TRANSMISSION_MODE_2K }, -#if DVB_VER_ATLEAST(5,1) - { .t = DVB_TRANSMISSION_MODE_4K, .l = TRANSMISSION_MODE_4K }, + {.t = DVB_TRANSMISSION_MODE_2K, .l = TRANSMISSION_MODE_2K}, +#if DVB_VER_ATLEAST(5, 1) + {.t = DVB_TRANSMISSION_MODE_4K, .l = TRANSMISSION_MODE_4K}, #endif - { .t = DVB_TRANSMISSION_MODE_8K, .l = TRANSMISSION_MODE_8K }, -#if DVB_VER_ATLEAST(5,3) - { .t = DVB_TRANSMISSION_MODE_16K, .l = TRANSMISSION_MODE_16K }, - { .t = DVB_TRANSMISSION_MODE_32K, .l = TRANSMISSION_MODE_32K }, + {.t = DVB_TRANSMISSION_MODE_8K, .l = TRANSMISSION_MODE_8K}, +#if DVB_VER_ATLEAST(5, 3) + {.t = DVB_TRANSMISSION_MODE_16K, .l = TRANSMISSION_MODE_16K}, + {.t = DVB_TRANSMISSION_MODE_32K, .l = TRANSMISSION_MODE_32K}, #endif -#if DVB_VER_ATLEAST(5,7) - { .t = DVB_TRANSMISSION_MODE_C3780, .l = TRANSMISSION_MODE_C3780 }, - { .t = DVB_TRANSMISSION_MODE_C1, .l = TRANSMISSION_MODE_C1 }, +#if DVB_VER_ATLEAST(5, 7) + {.t = DVB_TRANSMISSION_MODE_C3780, .l = TRANSMISSION_MODE_C3780}, + {.t = DVB_TRANSMISSION_MODE_C1, .l = TRANSMISSION_MODE_C1}, #endif - { .t = TABLE_EOD } - }; - static linuxdvb_tbl_t guard_tbl[] = { - { .t = DVB_GUARD_INTERVAL_AUTO, .l = GUARD_INTERVAL_AUTO }, - { .t = DVB_GUARD_INTERVAL_1_4, .l = GUARD_INTERVAL_1_4 }, - { .t = DVB_GUARD_INTERVAL_1_8, .l = GUARD_INTERVAL_1_8 }, - { .t = DVB_GUARD_INTERVAL_1_16, .l = GUARD_INTERVAL_1_16 }, - { .t = DVB_GUARD_INTERVAL_1_32, .l = GUARD_INTERVAL_1_32 }, -#if DVB_VER_ATLEAST(5,3) - { .t = DVB_GUARD_INTERVAL_1_128, .l = GUARD_INTERVAL_1_128 }, - { .t = DVB_GUARD_INTERVAL_19_128, .l = GUARD_INTERVAL_19_128 }, - { .t = DVB_GUARD_INTERVAL_19_256, .l = GUARD_INTERVAL_19_256 }, + {.t = TABLE_EOD}}; + static linuxdvb_tbl_t guard_tbl[] = {{.t = DVB_GUARD_INTERVAL_AUTO, .l = GUARD_INTERVAL_AUTO}, + {.t = DVB_GUARD_INTERVAL_1_4, .l = GUARD_INTERVAL_1_4}, + {.t = DVB_GUARD_INTERVAL_1_8, .l = GUARD_INTERVAL_1_8}, + {.t = DVB_GUARD_INTERVAL_1_16, .l = GUARD_INTERVAL_1_16}, + {.t = DVB_GUARD_INTERVAL_1_32, .l = GUARD_INTERVAL_1_32}, +#if DVB_VER_ATLEAST(5, 3) + {.t = DVB_GUARD_INTERVAL_1_128, .l = GUARD_INTERVAL_1_128}, + {.t = DVB_GUARD_INTERVAL_19_128, .l = GUARD_INTERVAL_19_128}, + {.t = DVB_GUARD_INTERVAL_19_256, .l = GUARD_INTERVAL_19_256}, #endif - { .t = TABLE_EOD } - }; - static linuxdvb_tbl_t h_tbl[] = { - { .t = DVB_HIERARCHY_NONE, .l = HIERARCHY_NONE }, - { .t = DVB_HIERARCHY_AUTO, .l = HIERARCHY_AUTO }, - { .t = DVB_HIERARCHY_1, .l = HIERARCHY_1 }, - { .t = DVB_HIERARCHY_2, .l = HIERARCHY_2 }, - { .t = DVB_HIERARCHY_4, .l = HIERARCHY_4 }, - { .t = TABLE_EOD } - }; -#if DVB_VER_ATLEAST(5,0) - static linuxdvb_tbl_t pilot_tbl[] = { - { .t = DVB_PILOT_AUTO, .l = PILOT_AUTO }, - { .t = DVB_PILOT_ON, .l = PILOT_ON }, - { .t = DVB_PILOT_OFF, .l = PILOT_OFF }, - { .t = TABLE_EOD } - }; + {.t = TABLE_EOD}}; + static linuxdvb_tbl_t h_tbl[] = {{.t = DVB_HIERARCHY_NONE, .l = HIERARCHY_NONE}, + {.t = DVB_HIERARCHY_AUTO, .l = HIERARCHY_AUTO}, + {.t = DVB_HIERARCHY_1, .l = HIERARCHY_1}, + {.t = DVB_HIERARCHY_2, .l = HIERARCHY_2}, + {.t = DVB_HIERARCHY_4, .l = HIERARCHY_4}, + {.t = TABLE_EOD}}; +#if DVB_VER_ATLEAST(5, 0) + static linuxdvb_tbl_t pilot_tbl[] = {{.t = DVB_PILOT_AUTO, .l = PILOT_AUTO}, + {.t = DVB_PILOT_ON, .l = PILOT_ON}, + {.t = DVB_PILOT_OFF, .l = PILOT_OFF}, + {.t = TABLE_EOD}}; static linuxdvb_tbl_t rolloff_tbl[] = { - { .t = DVB_HIERARCHY_AUTO, .l = ROLLOFF_AUTO }, -#if DVB_VER_ATLEAST(5,12) - { .t = DVB_ROLLOFF_5, .l = ROLLOFF_5 }, - { .t = DVB_ROLLOFF_10, .l = ROLLOFF_10 }, - { .t = DVB_ROLLOFF_15, .l = ROLLOFF_15 }, + {.t = DVB_HIERARCHY_AUTO, .l = ROLLOFF_AUTO}, +#if DVB_VER_ATLEAST(5, 12) + {.t = DVB_ROLLOFF_5, .l = ROLLOFF_5}, + {.t = DVB_ROLLOFF_10, .l = ROLLOFF_10}, + {.t = DVB_ROLLOFF_15, .l = ROLLOFF_15}, #endif - { .t = DVB_ROLLOFF_20, .l = ROLLOFF_20 }, - { .t = DVB_ROLLOFF_25, .l = ROLLOFF_25 }, - { .t = DVB_ROLLOFF_35, .l = ROLLOFF_35 }, - { .t = TABLE_EOD }, + {.t = DVB_ROLLOFF_20, .l = ROLLOFF_20}, + {.t = DVB_ROLLOFF_25, .l = ROLLOFF_25}, + {.t = DVB_ROLLOFF_35, .l = ROLLOFF_35}, + {.t = TABLE_EOD}, }; #endif - int r; - struct dvb_frontend_event ev; - char buf1[256]; - dvb_mux_t *lm = (dvb_mux_t*)mmi->mmi_mux; - dvb_mux_conf_t *dmc; + int r; + struct dvb_frontend_event ev; + char buf1[256]; + dvb_mux_t* lm = (dvb_mux_t*)mmi->mmi_mux; + dvb_mux_conf_t* dmc; struct dvb_frontend_parameters p; r = linuxdvb_frontend_clear(lfe, NULL); - if (r) return r; + if (r) + return r; lfe->mi_display_name((mpegts_input_t*)lfe, buf1, sizeof(buf1)); @@ -1772,59 +1634,61 @@ linuxdvb_frontend_tune0 tvhtrace(LS_LINUXDVB, "tuner %s tuning to %s (freq %i)", buf1, buf2, freq); } memset(&p, 0, sizeof(p)); - p.frequency = dmc->dmc_fe_freq; - p.inversion = TR(inversion, inv_tbl, INVERSION_AUTO); + p.frequency = dmc->dmc_fe_freq; + p.inversion = TR(inversion, inv_tbl, INVERSION_AUTO); switch (dmc->dmc_fe_type) { - case DVB_TYPE_T: - case DVB_TYPE_DTMB: + case DVB_TYPE_T: + case DVB_TYPE_DTMB: #define _OFDM(xyz) p.u.ofdm.xyz - _OFDM(bandwidth) = TRU(ofdm.bandwidth, bw_tbl, BANDWIDTH_AUTO); - _OFDM(code_rate_HP) = TRU(ofdm.code_rate_HP, fec_tbl, FEC_AUTO); - _OFDM(code_rate_LP) = TRU(ofdm.code_rate_LP, fec_tbl, FEC_AUTO); - _OFDM(constellation) = TR(modulation, mod_tbl, QAM_AUTO); - _OFDM(transmission_mode) = TRU(ofdm.transmission_mode, trans_tbl, TRANSMISSION_MODE_AUTO); - _OFDM(guard_interval) = TRU(ofdm.guard_interval, guard_tbl, GUARD_INTERVAL_AUTO); - _OFDM(hierarchy_information) - = TRU(ofdm.hierarchy_information, h_tbl, HIERARCHY_AUTO); + _OFDM(bandwidth) = TRU(ofdm.bandwidth, bw_tbl, BANDWIDTH_AUTO); + _OFDM(code_rate_HP) = TRU(ofdm.code_rate_HP, fec_tbl, FEC_AUTO); + _OFDM(code_rate_LP) = TRU(ofdm.code_rate_LP, fec_tbl, FEC_AUTO); + _OFDM(constellation) = TR(modulation, mod_tbl, QAM_AUTO); + _OFDM(transmission_mode) = TRU(ofdm.transmission_mode, trans_tbl, TRANSMISSION_MODE_AUTO); + _OFDM(guard_interval) = TRU(ofdm.guard_interval, guard_tbl, GUARD_INTERVAL_AUTO); + _OFDM(hierarchy_information) = TRU(ofdm.hierarchy_information, h_tbl, HIERARCHY_AUTO); #undef _OFDM - break; - case DVB_TYPE_C: - case DVB_TYPE_ATSC_C: - case DVB_TYPE_ISDB_C: - p.u.qam.symbol_rate = dmc->u.dmc_fe_qam.symbol_rate; - p.u.qam.fec_inner = TRU(qam.fec_inner, fec_tbl, FEC_AUTO); - p.u.qam.modulation = TR(modulation, mod_tbl, QAM_AUTO); - break; - case DVB_TYPE_S: - p.u.qpsk.symbol_rate = dmc->u.dmc_fe_qpsk.symbol_rate; - p.u.qpsk.fec_inner = TRU(qpsk.fec_inner, fec_tbl, FEC_AUTO); - break; - case DVB_TYPE_ATSC_T: - p.u.vsb.modulation = TR(modulation, mod_tbl, QAM_AUTO); - break; + break; + case DVB_TYPE_C: + case DVB_TYPE_ATSC_C: + case DVB_TYPE_ISDB_C: + p.u.qam.symbol_rate = dmc->u.dmc_fe_qam.symbol_rate; + p.u.qam.fec_inner = TRU(qam.fec_inner, fec_tbl, FEC_AUTO); + p.u.qam.modulation = TR(modulation, mod_tbl, QAM_AUTO); + break; + case DVB_TYPE_S: + p.u.qpsk.symbol_rate = dmc->u.dmc_fe_qpsk.symbol_rate; + p.u.qpsk.fec_inner = TRU(qpsk.fec_inner, fec_tbl, FEC_AUTO); + break; + case DVB_TYPE_ATSC_T: + p.u.vsb.modulation = TR(modulation, mod_tbl, QAM_AUTO); + break; #if DVB_API_VERSION >= 5 - case DVB_TYPE_ISDB_T: - case DVB_TYPE_DAB: - break; + case DVB_TYPE_ISDB_T: + case DVB_TYPE_DAB: + break; #endif - default: - tvherror(LS_LINUXDVB, "%s - unknown FE type %d", buf1, dmc->dmc_fe_type); - return SM_CODE_TUNING_FAILED; + default: + tvherror(LS_LINUXDVB, "%s - unknown FE type %d", buf1, dmc->dmc_fe_type); + return SM_CODE_TUNING_FAILED; } if (freq != (uint32_t)-1) p.frequency = lfe->lfe_freq = freq; if (dmc->dmc_fe_type != lfe->lfe_type) { - tvherror(LS_LINUXDVB, "%s - failed to tune [type does not match %i != %i]", buf1, dmc->dmc_fe_type, lfe->lfe_type); + tvherror(LS_LINUXDVB, + "%s - failed to tune [type does not match %i != %i]", + buf1, + dmc->dmc_fe_type, + lfe->lfe_type); return SM_CODE_TUNING_FAILED; } /* S2 tuning */ #if DVB_API_VERSION >= 5 - struct dtv_property cmds[32]; + struct dtv_property cmds[32]; struct dtv_properties cmdseq; - if (freq == (uint32_t)-1) freq = p.frequency; @@ -1832,124 +1696,126 @@ linuxdvb_frontend_tune0 memset(&cmdseq, 0, sizeof(cmdseq)); cmdseq.props = cmds; memset(&cmds, 0, sizeof(cmds)); - + /* Tune */ -#define S2CMD(c, d) do { \ - cmds[cmdseq.num].cmd = c; \ - cmds[cmdseq.num++].u.data = d; \ -} while (0) +#define S2CMD(c, d) \ + do { \ + cmds[cmdseq.num].cmd = c; \ + cmds[cmdseq.num++].u.data = d; \ + } while (0) memset(&cmds, 0, sizeof(cmds)); S2CMD(DTV_DELIVERY_SYSTEM, TR(delsys, delsys_tbl, SYS_UNDEFINED)); - S2CMD(DTV_FREQUENCY, freq); - S2CMD(DTV_INVERSION, p.inversion); + S2CMD(DTV_FREQUENCY, freq); + S2CMD(DTV_INVERSION, p.inversion); /* DVB-T */ if (lfe->lfe_type == DVB_TYPE_T || lfe->lfe_type == DVB_TYPE_DTMB) { - S2CMD(DTV_BANDWIDTH_HZ, dvb_bandwidth(dmc->u.dmc_fe_ofdm.bandwidth)); -#if DVB_VER_ATLEAST(5,1) - S2CMD(DTV_CODE_RATE_HP, p.u.ofdm.code_rate_HP); - S2CMD(DTV_CODE_RATE_LP, p.u.ofdm.code_rate_LP); + S2CMD(DTV_BANDWIDTH_HZ, dvb_bandwidth(dmc->u.dmc_fe_ofdm.bandwidth)); +#if DVB_VER_ATLEAST(5, 1) + S2CMD(DTV_CODE_RATE_HP, p.u.ofdm.code_rate_HP); + S2CMD(DTV_CODE_RATE_LP, p.u.ofdm.code_rate_LP); #endif - S2CMD(DTV_MODULATION, p.u.ofdm.constellation); -#if DVB_VER_ATLEAST(5,1) + S2CMD(DTV_MODULATION, p.u.ofdm.constellation); +#if DVB_VER_ATLEAST(5, 1) S2CMD(DTV_TRANSMISSION_MODE, p.u.ofdm.transmission_mode); - S2CMD(DTV_GUARD_INTERVAL, p.u.ofdm.guard_interval); - S2CMD(DTV_HIERARCHY, p.u.ofdm.hierarchy_information); + S2CMD(DTV_GUARD_INTERVAL, p.u.ofdm.guard_interval); + S2CMD(DTV_HIERARCHY, p.u.ofdm.hierarchy_information); #endif if (lm->lm_tuning.dmc_fe_delsys == DVB_SYS_DVBT2) { -#if DVB_VER_ATLEAST(5,9) +#if DVB_VER_ATLEAST(5, 9) S2CMD(DTV_STREAM_ID, dmc->dmc_fe_stream_id); -#elif DVB_VER_ATLEAST(5,3) +#elif DVB_VER_ATLEAST(5, 3) S2CMD(DTV_DVBT2_PLP_ID, dmc->dmc_fe_stream_id); #endif } -#if DVB_VER_ATLEAST(5,9) +#if DVB_VER_ATLEAST(5, 9) if (lfe->lfe_lna) S2CMD(DTV_LNA, 1); #endif - /* DVB-C */ - } else if (lfe->lfe_type == DVB_TYPE_C || - lfe->lfe_type == DVB_TYPE_ATSC_C || - lfe->lfe_type == DVB_TYPE_ISDB_C) { - S2CMD(DTV_SYMBOL_RATE, p.u.qam.symbol_rate); - S2CMD(DTV_MODULATION, p.u.qam.modulation); - S2CMD(DTV_INNER_FEC, p.u.qam.fec_inner); - r = dmc->dmc_fe_stream_id != DVB_NO_STREAM_ID_FILTER ? (dmc->dmc_fe_stream_id & 0xFF) | - ((dmc->dmc_fe_data_slice & 0xFF)<<8) : DVB_NO_STREAM_ID_FILTER; -#if DVB_VER_ATLEAST(5,9) - S2CMD(DTV_STREAM_ID, r); + /* DVB-C */ + } else if (lfe->lfe_type == DVB_TYPE_C || lfe->lfe_type == DVB_TYPE_ATSC_C || + lfe->lfe_type == DVB_TYPE_ISDB_C) { + S2CMD(DTV_SYMBOL_RATE, p.u.qam.symbol_rate); + S2CMD(DTV_MODULATION, p.u.qam.modulation); + S2CMD(DTV_INNER_FEC, p.u.qam.fec_inner); + r = dmc->dmc_fe_stream_id != DVB_NO_STREAM_ID_FILTER + ? (dmc->dmc_fe_stream_id & 0xFF) | ((dmc->dmc_fe_data_slice & 0xFF) << 8) + : DVB_NO_STREAM_ID_FILTER; +#if DVB_VER_ATLEAST(5, 9) + S2CMD(DTV_STREAM_ID, r); #endif - /* DVB-S */ + /* DVB-S */ } else if (lfe->lfe_type == DVB_TYPE_S) { - S2CMD(DTV_SYMBOL_RATE, p.u.qpsk.symbol_rate); - S2CMD(DTV_INNER_FEC, p.u.qpsk.fec_inner); - S2CMD(DTV_MODULATION, TR(modulation, mod_tbl, QPSK)); + S2CMD(DTV_SYMBOL_RATE, p.u.qpsk.symbol_rate); + S2CMD(DTV_INNER_FEC, p.u.qpsk.fec_inner); + S2CMD(DTV_MODULATION, TR(modulation, mod_tbl, QPSK)); if (lm->lm_tuning.dmc_fe_delsys == DVB_SYS_DVBS) { - S2CMD(DTV_ROLLOFF, ROLLOFF_35); + S2CMD(DTV_ROLLOFF, ROLLOFF_35); } else { - S2CMD(DTV_PILOT, TR(pilot, pilot_tbl, PILOT_AUTO)); - S2CMD(DTV_ROLLOFF, TR(rolloff, rolloff_tbl, ROLLOFF_AUTO)); + S2CMD(DTV_PILOT, TR(pilot, pilot_tbl, PILOT_AUTO)); + S2CMD(DTV_ROLLOFF, TR(rolloff, rolloff_tbl, ROLLOFF_AUTO)); r = dmc->dmc_fe_stream_id != DVB_NO_STREAM_ID_FILTER ? (dmc->dmc_fe_stream_id & 0xFF) | - ((dmc->dmc_fe_pls_code & 0x3FFFF)<<8) | ((dmc->dmc_fe_pls_mode & 0x3)<<26) : - DVB_NO_STREAM_ID_FILTER; -#if DVB_VER_ATLEAST(5,9) - S2CMD(DTV_STREAM_ID, r); -#if DVB_VER_ATLEAST(5,11) + ((dmc->dmc_fe_pls_code & 0x3FFFF) << 8) | ((dmc->dmc_fe_pls_mode & 0x3) << 26) + : DVB_NO_STREAM_ID_FILTER; +#if DVB_VER_ATLEAST(5, 9) + S2CMD(DTV_STREAM_ID, r); +#if DVB_VER_ATLEAST(5, 11) r = dvb_sat_pls(dmc); if (r != 0) /* default PLS gold code */ S2CMD(DTV_SCRAMBLING_SEQUENCE_INDEX, r); #endif -#elif DVB_VER_ATLEAST(5,3) - S2CMD(DTV_DVBT2_PLP_ID, r); +#elif DVB_VER_ATLEAST(5, 3) + S2CMD(DTV_DVBT2_PLP_ID, r); #endif } - /* ATSC-T */ + /* ATSC-T */ } else if (lfe->lfe_type == DVB_TYPE_ATSC_T) { - S2CMD(DTV_MODULATION, p.u.vsb.modulation); + S2CMD(DTV_MODULATION, p.u.vsb.modulation); -#if DVB_VER_ATLEAST(5,0) - /* ISDB-T */ +#if DVB_VER_ATLEAST(5, 0) + /* ISDB-T */ } else if (lfe->lfe_type == DVB_TYPE_ISDB_T) { int i, j; - S2CMD(DTV_BANDWIDTH_HZ, dvb_bandwidth(dmc->u.dmc_fe_isdbt.bandwidth)); -#if DVB_VER_ATLEAST(5,1) + S2CMD(DTV_BANDWIDTH_HZ, dvb_bandwidth(dmc->u.dmc_fe_isdbt.bandwidth)); +#if DVB_VER_ATLEAST(5, 1) S2CMD(DTV_GUARD_INTERVAL, TRU(isdbt.guard_interval, guard_tbl, GUARD_INTERVAL_AUTO)); S2CMD(DTV_TRANSMISSION_MODE, TRANSMISSION_MODE_AUTO); - S2CMD(DTV_ISDBT_LAYER_ENABLED, 7); + S2CMD(DTV_ISDBT_LAYER_ENABLED, 7); S2CMD(DTV_ISDBT_PARTIAL_RECEPTION, 1); - S2CMD(DTV_ISDBT_SOUND_BROADCASTING,0); - S2CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0); - S2CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0); - S2CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0); + S2CMD(DTV_ISDBT_SOUND_BROADCASTING, 0); + S2CMD(DTV_ISDBT_SB_SUBCHANNEL_ID, 0); + S2CMD(DTV_ISDBT_SB_SEGMENT_IDX, 0); + S2CMD(DTV_ISDBT_SB_SEGMENT_COUNT, 0); for (i = j = 0; i < 3; i++, j += DTV_ISDBT_LAYERB_FEC - DTV_ISDBT_LAYERA_FEC) { - S2CMD(DTV_ISDBT_LAYERA_FEC + j, TRU(isdbt.layers[i].fec, fec_tbl, FEC_AUTO)); - S2CMD(DTV_ISDBT_LAYERA_MODULATION + j, TRU(isdbt.layers[i].modulation, mod_tbl, QAM_AUTO)); - S2CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT + j, dmc->u.dmc_fe_isdbt.layers[i].segment_count); - S2CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING + j, dmc->u.dmc_fe_isdbt.layers[i].time_interleaving); + S2CMD(DTV_ISDBT_LAYERA_FEC + j, TRU(isdbt.layers[i].fec, fec_tbl, FEC_AUTO)); + S2CMD(DTV_ISDBT_LAYERA_MODULATION + j, TRU(isdbt.layers[i].modulation, mod_tbl, QAM_AUTO)); + S2CMD(DTV_ISDBT_LAYERA_SEGMENT_COUNT + j, dmc->u.dmc_fe_isdbt.layers[i].segment_count); + S2CMD(DTV_ISDBT_LAYERA_TIME_INTERLEAVING + j, + dmc->u.dmc_fe_isdbt.layers[i].time_interleaving); } #endif - /* ISDB-S */ + /* ISDB-S */ } else if (lfe->lfe_type == DVB_TYPE_ISDB_S) { r = dmc->dmc_fe_stream_id != DVB_NO_STREAM_ID_FILTER ? (dmc->dmc_fe_stream_id & 0xFF) | - ((dmc->dmc_fe_pls_code & 0x3FFFF)<<8) | ((dmc->dmc_fe_pls_mode & 0x3)<<26) : - DVB_NO_STREAM_ID_FILTER; -#if DVB_VER_ATLEAST(5,9) - S2CMD(DTV_STREAM_ID, r); -#if DVB_VER_ATLEAST(5,11) + ((dmc->dmc_fe_pls_code & 0x3FFFF) << 8) | ((dmc->dmc_fe_pls_mode & 0x3) << 26) + : DVB_NO_STREAM_ID_FILTER; +#if DVB_VER_ATLEAST(5, 9) + S2CMD(DTV_STREAM_ID, r); +#if DVB_VER_ATLEAST(5, 11) r = dvb_sat_pls(dmc); if (r != 0) /* default PLS gold code */ S2CMD(DTV_SCRAMBLING_SEQUENCE_INDEX, r); #endif -#elif DVB_VER_ATLEAST(5,3) - S2CMD(DTV_DVBT2_PLP_ID, r); +#elif DVB_VER_ATLEAST(5, 3) + S2CMD(DTV_DVBT2_PLP_ID, r); #endif - /* DAB */ + /* DAB */ } else if (lfe->lfe_type == DVB_TYPE_DAB) { #endif /* 5.0+ */ } @@ -1990,11 +1856,8 @@ linuxdvb_frontend_tune0 return r; } -int -linuxdvb_frontend_tune1 - ( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi, uint32_t freq ) -{ - int r = 0, i, rep; +int linuxdvb_frontend_tune1(linuxdvb_frontend_t* lfe, mpegts_mux_instance_t* mmi, uint32_t freq) { + int r = 0, i, rep; char buf1[256]; lfe->mi_display_name((mpegts_input_t*)lfe, buf1, sizeof(buf1)); @@ -2019,48 +1882,41 @@ linuxdvb_frontend_tune1 } lfe->lfe_in_setup = 0; - + return r; } - /* ************************************************************************** * Creation/Config * *************************************************************************/ -static mpegts_network_t * -linuxdvb_frontend_wizard_network ( linuxdvb_frontend_t *lfe ) -{ - linuxdvb_satconf_ele_t *ele = NULL; +static mpegts_network_t* linuxdvb_frontend_wizard_network(linuxdvb_frontend_t* lfe) { + linuxdvb_satconf_ele_t* ele = NULL; if (lfe->lfe_satconf) { ele = TAILQ_FIRST(&lfe->lfe_satconf->ls_elements); if (ele && ele->lse_networks && ele->lse_networks->is_count > 0) - return (mpegts_network_t *)ele->lse_networks->is_array[0]; + return (mpegts_network_t*)ele->lse_networks->is_array[0]; } - return (mpegts_network_t *)LIST_FIRST(&lfe->mi_networks); + return (mpegts_network_t*)LIST_FIRST(&lfe->mi_networks); } -static htsmsg_t * -linuxdvb_frontend_wizard_get( tvh_input_t *ti, const char *lang ) -{ - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ti; - mpegts_network_t *mn; - const idclass_t *idc = NULL; +static htsmsg_t* linuxdvb_frontend_wizard_get(tvh_input_t* ti, const char* lang) { + linuxdvb_frontend_t* lfe = (linuxdvb_frontend_t*)ti; + mpegts_network_t* mn; + const idclass_t* idc = NULL; mn = linuxdvb_frontend_wizard_network(lfe); if ((lfe->lfe_master == 0 && mn == NULL) || (mn && mn->mn_wizard)) idc = dvb_network_class_by_fe_type(lfe->lfe_type); - return mpegts_network_wizard_get((mpegts_input_t *)lfe, idc, mn, lang); + return mpegts_network_wizard_get((mpegts_input_t*)lfe, idc, mn, lang); } -static void -linuxdvb_frontend_wizard_set( tvh_input_t *ti, htsmsg_t *conf, const char *lang ) -{ - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ti; - const char *ntype = htsmsg_get_str(conf, "mpegts_network_type"); - mpegts_network_t *mn; - htsmsg_t *nlist; +static void linuxdvb_frontend_wizard_set(tvh_input_t* ti, htsmsg_t* conf, const char* lang) { + linuxdvb_frontend_t* lfe = (linuxdvb_frontend_t*)ti; + const char* ntype = htsmsg_get_str(conf, "mpegts_network_type"); + mpegts_network_t* mn; + htsmsg_t* nlist; if (LIST_FIRST(&lfe->mi_mux_active)) return; @@ -2068,9 +1924,9 @@ linuxdvb_frontend_wizard_set( tvh_input_t *ti, htsmsg_t *conf, const char *lang mn = linuxdvb_frontend_wizard_network(lfe); if (ntype && (mn == NULL || mn->mn_wizard)) { if (lfe->lfe_satconf) { - htsmsg_t *conf = htsmsg_create_map(); - htsmsg_t *elems = htsmsg_create_list(); - htsmsg_t *elem = htsmsg_create_map(); + htsmsg_t* conf = htsmsg_create_map(); + htsmsg_t* elems = htsmsg_create_list(); + htsmsg_t* elem = htsmsg_create_map(); htsmsg_add_str(conf, "type", "4port"); htsmsg_add_bool(elem, "enable", 1); htsmsg_add_msg(elem, "networks", nlist); @@ -2083,30 +1939,32 @@ linuxdvb_frontend_wizard_set( tvh_input_t *ti, htsmsg_t *conf, const char *lang lfe->lfe_satconf = linuxdvb_satconf_create(lfe, conf); htsmsg_destroy(conf); } else { - mpegts_input_set_networks((mpegts_input_t *)lfe, nlist); + mpegts_input_set_networks((mpegts_input_t*)lfe, nlist); htsmsg_destroy(nlist); } if (linuxdvb_frontend_wizard_network(lfe)) - mpegts_input_set_enabled((mpegts_input_t *)lfe, 1); + mpegts_input_set_enabled((mpegts_input_t*)lfe, 1); linuxdvb_adapter_changed(lfe->lfe_adapter); } else { htsmsg_destroy(nlist); } } -linuxdvb_frontend_t * -linuxdvb_frontend_create - ( htsmsg_t *conf, linuxdvb_adapter_t *la, int number, - const char *fe_path, const char *dmx_path, const char *dvr_path, - dvb_fe_type_t type, const char *name ) -{ - const idclass_t *idc; - const char *str, *uuid = NULL, *muuid = NULL; - char id[16], lname[256], buf[256]; - linuxdvb_frontend_t *lfe; - htsmsg_t *oconf = conf, *scconf; - ssize_t r; - int fd; +linuxdvb_frontend_t* linuxdvb_frontend_create(htsmsg_t* conf, + linuxdvb_adapter_t* la, + int number, + const char* fe_path, + const char* dmx_path, + const char* dvr_path, + dvb_fe_type_t type, + const char* name) { + const idclass_t* idc; + const char * str, *uuid = NULL, *muuid = NULL; + char id[16], lname[256], buf[256]; + linuxdvb_frontend_t* lfe; + htsmsg_t * oconf = conf, *scconf; + ssize_t r; + int fd; /* Internal config ID */ snprintf(id, sizeof(id), "%s #%d", dvb_type2str(type), number); @@ -2126,9 +1984,8 @@ linuxdvb_frontend_create /* Fudge configuration for old network entry */ if (conf) { - if (!htsmsg_get_list(conf, "networks") && - (str = htsmsg_get_str(conf, "network"))) { - htsmsg_t *l = htsmsg_create_list(); + if (!htsmsg_get_list(conf, "networks") && (str = htsmsg_get_str(conf, "network"))) { + htsmsg_t* l = htsmsg_create_list(); htsmsg_add_str(l, NULL, str); htsmsg_add_msg(conf, "networks", l); } @@ -2136,8 +1993,7 @@ linuxdvb_frontend_create /* Class */ if (type == DVB_TYPE_S) - idc = muuid ? &linuxdvb_frontend_dvbs_slave_class : - &linuxdvb_frontend_dvbs_class; + idc = muuid ? &linuxdvb_frontend_dvbs_slave_class : &linuxdvb_frontend_dvbs_class; else if (type == DVB_TYPE_C) idc = &linuxdvb_frontend_dvbc_class; else if (type == DVB_TYPE_T) @@ -2165,28 +2021,31 @@ linuxdvb_frontend_create // Note: there is a bit of a chicken/egg issue below, without the // correct "fe_type" we cannot set the network (which is done // in mpegts_input_create()). So we must set early. - lfe = calloc(1, sizeof(linuxdvb_frontend_t)); - lfe->lfe_number = number; - lfe->lfe_type = type; - lfe->lfe_master = muuid ? strdup(muuid) : NULL; - lfe->lfe_name = strdup(name); - lfe->lfe_ibuf_size = 188000; - lfe->lfe_status_period = 1000; - lfe->lfe_pids_max = 32; - lfe->lfe_pids_use_all = 1; + lfe = calloc(1, sizeof(linuxdvb_frontend_t)); + lfe->lfe_number = number; + lfe->lfe_type = type; + lfe->lfe_master = muuid ? strdup(muuid) : NULL; + lfe->lfe_name = strdup(name); + lfe->lfe_ibuf_size = 188000; + lfe->lfe_status_period = 1000; + lfe->lfe_pids_max = 32; + lfe->lfe_pids_use_all = 1; lfe->lfe_sig_multiplier = 100; lfe->lfe_snr_multiplier = 100; - lfe->lfe_grace_period = 5; + lfe->lfe_grace_period = 5; lfe = (linuxdvb_frontend_t*)mpegts_input_create0((mpegts_input_t*)lfe, idc, uuid, conf); - if (!lfe) return NULL; + if (!lfe) + return NULL; /* Sysfs path */ snprintf(lname, sizeof(lname), "/sys/class/dvb/dvb%d.frontend%d", la->la_dvb_number, number); r = readlink(lname, buf, sizeof(buf)); if (r > 0) { - if (r == sizeof(buf)) r--; + if (r == sizeof(buf)) + r--; buf[r] = '\0'; - if (strncmp(str = buf, "../../", 6) == 0) str += 6; + if (strncmp(str = buf, "../../", 6) == 0) + str += 6; lfe->lfe_sysfs = strdup(str); } @@ -2227,10 +2086,10 @@ linuxdvb_frontend_create tvh_mutex_init(&lfe->lfe_dvr_lock, NULL); tvh_cond_init(&lfe->lfe_dvr_cond, 1); mpegts_pid_init(&lfe->lfe_pids); - + /* Create satconf */ if (lfe->lfe_type == DVB_TYPE_S && !lfe->lfe_satconf && !muuid) { - scconf = conf ? htsmsg_get_map(conf, "satconf") : NULL; + scconf = conf ? htsmsg_get_map(conf, "satconf") : NULL; lfe->lfe_satconf = linuxdvb_satconf_create(lfe, scconf); } @@ -2247,18 +2106,16 @@ linuxdvb_frontend_create return lfe; } -void -linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *fe ) -{ - char id[16]; - htsmsg_t *m = htsmsg_create_map(); +void linuxdvb_frontend_save(linuxdvb_frontend_t* lfe, htsmsg_t* fe) { + char id[16]; + htsmsg_t* m = htsmsg_create_map(); /* Save frontend */ mpegts_input_save((mpegts_input_t*)lfe, m); htsmsg_add_str(m, "type", dvb_type2str(lfe->lfe_type)); htsmsg_add_uuid(m, "uuid", &lfe->ti_id.in_uuid); if (lfe->lfe_satconf && !lfe->lfe_master) { - htsmsg_t *s = htsmsg_create_map(); + htsmsg_t* s = htsmsg_create_map(); linuxdvb_satconf_save(lfe->lfe_satconf, s); htsmsg_add_uuid(s, "uuid", &lfe->lfe_satconf->ls_id.in_uuid); htsmsg_add_msg(m, "satconf", s); @@ -2275,10 +2132,8 @@ linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *fe ) } } -void -linuxdvb_frontend_destroy ( linuxdvb_frontend_t *lfe ) -{ - char *name; +void linuxdvb_frontend_destroy(linuxdvb_frontend_t* lfe) { + char* name; lock_assert(&global_lock); diff --git a/src/input/mpegts/linuxdvb/linuxdvb_lnb.c b/src/input/mpegts/linuxdvb/linuxdvb_lnb.c index 2a976d05e..f8f05dd3d 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_lnb.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_lnb.c @@ -33,8 +33,7 @@ * Class definition * *************************************************************************/ -typedef struct linuxdvb_lnb_conf -{ +typedef struct linuxdvb_lnb_conf { linuxdvb_lnb_t; /* Freq control */ @@ -43,47 +42,39 @@ typedef struct linuxdvb_lnb_conf int lnb_switch; } linuxdvb_lnb_conf_t; -static void -linuxdvb_lnb_class_get_title - ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) -{ - linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; +static void linuxdvb_lnb_class_get_title(idnode_t* o, const char* lang, char* dst, size_t dstsize) { + linuxdvb_diseqc_t* ld = (linuxdvb_diseqc_t*)o; snprintf(dst, dstsize, tvh_gettext_lang(lang, N_("LNB: %s")), ld->ld_type); } extern const idclass_t linuxdvb_diseqc_class; -const idclass_t linuxdvb_lnb_class = -{ - .ic_super = &linuxdvb_diseqc_class, - .ic_class = "linuxdvb_lnb_basic", - .ic_caption = N_("LNB"), - .ic_get_title = linuxdvb_lnb_class_get_title, - .ic_properties = (const property_t[]) { - { - .type = PT_INT, - .id = "lfo", - .name = N_("Low frequency offset"), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(linuxdvb_lnb_conf_t, lnb_low), - }, - { - .type = PT_INT, - .id = "hfo", - .name = N_("High frequency offset"), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(linuxdvb_lnb_conf_t, lnb_high), - }, - { - .type = PT_INT, - .id = "sfo", - .name = N_("Switch frequency offset"), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(linuxdvb_lnb_conf_t, lnb_switch), - }, - {} - } -}; +const idclass_t linuxdvb_lnb_class = {.ic_super = &linuxdvb_diseqc_class, + .ic_class = "linuxdvb_lnb_basic", + .ic_caption = N_("LNB"), + .ic_get_title = linuxdvb_lnb_class_get_title, + .ic_properties = (const property_t[]){{ + .type = PT_INT, + .id = "lfo", + .name = N_("Low frequency offset"), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(linuxdvb_lnb_conf_t, lnb_low), + }, + { + .type = PT_INT, + .id = "hfo", + .name = N_("High frequency offset"), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(linuxdvb_lnb_conf_t, lnb_high), + }, + { + .type = PT_INT, + .id = "sfo", + .name = N_("Switch frequency offset"), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(linuxdvb_lnb_conf_t, lnb_switch), + }, + {}}}; /* ************************************************************************** * Control functions @@ -93,12 +84,9 @@ const idclass_t linuxdvb_lnb_class = * Standard freq switched LNB */ -static uint32_t -linuxdvb_lnb_standard_freq - ( linuxdvb_lnb_t *l, dvb_mux_t *lm ) -{ - linuxdvb_lnb_conf_t *lnb = (linuxdvb_lnb_conf_t*)l; - int32_t f = (int32_t)lm->lm_tuning.dmc_fe_freq; +static uint32_t linuxdvb_lnb_standard_freq(linuxdvb_lnb_t* l, dvb_mux_t* lm) { + linuxdvb_lnb_conf_t* lnb = (linuxdvb_lnb_conf_t*)l; + int32_t f = (int32_t)lm->lm_tuning.dmc_fe_freq; if (lnb->lnb_switch && f > lnb->lnb_switch) f -= lnb->lnb_high; else @@ -106,21 +94,15 @@ linuxdvb_lnb_standard_freq return (uint32_t)abs(f); } -static int -linuxdvb_lnb_bandstack_match - ( linuxdvb_lnb_t *l, dvb_mux_t *lm1, dvb_mux_t *lm2 ) -{ +static int linuxdvb_lnb_bandstack_match(linuxdvb_lnb_t* l, dvb_mux_t* lm1, dvb_mux_t* lm2) { /* everything is in one cable */ return 1; } -static int -linuxdvb_lnb_standard_match - ( linuxdvb_lnb_t *l, dvb_mux_t *lm1, dvb_mux_t *lm2 ) -{ - linuxdvb_lnb_conf_t *lnb = (linuxdvb_lnb_conf_t*)l; - dvb_mux_conf_t *dmc1 = &lm1->lm_tuning; - dvb_mux_conf_t *dmc2 = &lm2->lm_tuning; +static int linuxdvb_lnb_standard_match(linuxdvb_lnb_t* l, dvb_mux_t* lm1, dvb_mux_t* lm2) { + linuxdvb_lnb_conf_t* lnb = (linuxdvb_lnb_conf_t*)l; + dvb_mux_conf_t* dmc1 = &lm1->lm_tuning; + dvb_mux_conf_t* dmc2 = &lm2->lm_tuning; if (lnb->lnb_switch) { uint32_t hi1 = dmc1->dmc_fe_freq > lnb->lnb_switch; @@ -133,37 +115,30 @@ linuxdvb_lnb_standard_match return 1; } -static int -linuxdvb_lnb_standard_band - ( linuxdvb_lnb_t *l, dvb_mux_t *lm ) -{ - linuxdvb_lnb_conf_t *lnb = (linuxdvb_lnb_conf_t*)l; - uint32_t f = lm->lm_tuning.dmc_fe_freq; +static int linuxdvb_lnb_standard_band(linuxdvb_lnb_t* l, dvb_mux_t* lm) { + linuxdvb_lnb_conf_t* lnb = (linuxdvb_lnb_conf_t*)l; + uint32_t f = lm->lm_tuning.dmc_fe_freq; return (lnb->lnb_switch && f > lnb->lnb_switch); } -static int -linuxdvb_lnb_standard_pol - ( linuxdvb_lnb_t *l, dvb_mux_t *lm ) -{ - dvb_mux_conf_t *dmc = &lm->lm_tuning; +static int linuxdvb_lnb_standard_pol(linuxdvb_lnb_t* l, dvb_mux_t* lm) { + dvb_mux_conf_t* dmc = &lm->lm_tuning; return dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_HORIZONTAL || - dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_CIRCULAR_LEFT; + dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_CIRCULAR_LEFT; } -static int -linuxdvb_lnb_inverted_pol - ( linuxdvb_lnb_t *l, dvb_mux_t *lm ) -{ +static int linuxdvb_lnb_inverted_pol(linuxdvb_lnb_t* l, dvb_mux_t* lm) { return !linuxdvb_lnb_standard_pol(l, lm); } -static int -linuxdvb_lnb_standard_tune - ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, - int vol, int pol, int band, int freq ) -{ +static int linuxdvb_lnb_standard_tune(linuxdvb_diseqc_t* ld, + dvb_mux_t* lm, + linuxdvb_satconf_t* lsp, + linuxdvb_satconf_ele_t* ls, + int vol, + int pol, + int band, + int freq) { return linuxdvb_diseqc_set_volt(ls->lse_parent, vol); } @@ -171,15 +146,12 @@ linuxdvb_lnb_standard_tune * Bandstacked polarity switch LNB */ -static uint32_t -linuxdvb_lnb_bandstack_freq - ( linuxdvb_lnb_t *l, dvb_mux_t *lm ) -{ - linuxdvb_lnb_conf_t *lnb = (linuxdvb_lnb_conf_t*)l; - int32_t f = (int32_t)lm->lm_tuning.dmc_fe_freq; - dvb_mux_conf_t *dmc = &lm->lm_tuning; - int pol = dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_HORIZONTAL || - dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_CIRCULAR_LEFT; +static uint32_t linuxdvb_lnb_bandstack_freq(linuxdvb_lnb_t* l, dvb_mux_t* lm) { + linuxdvb_lnb_conf_t* lnb = (linuxdvb_lnb_conf_t*)l; + int32_t f = (int32_t)lm->lm_tuning.dmc_fe_freq; + dvb_mux_conf_t* dmc = &lm->lm_tuning; + int pol = dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_HORIZONTAL || + dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_CIRCULAR_LEFT; if (pol) f -= lnb->lnb_high; else @@ -187,20 +159,14 @@ linuxdvb_lnb_bandstack_freq return (uint32_t)abs(f); } -static int -linuxdvb_lnb_bandstack_band - ( linuxdvb_lnb_t *l, dvb_mux_t *lm ) -{ - dvb_mux_conf_t *dmc = &lm->lm_tuning; - int pol = dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_HORIZONTAL || - dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_CIRCULAR_LEFT; +static int linuxdvb_lnb_bandstack_band(linuxdvb_lnb_t* l, dvb_mux_t* lm) { + dvb_mux_conf_t* dmc = &lm->lm_tuning; + int pol = dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_HORIZONTAL || + dmc->u.dmc_fe_qpsk.polarisation == DVB_POLARISATION_CIRCULAR_LEFT; return pol; } -static int -linuxdvb_lnb_bandstack_pol - ( linuxdvb_lnb_t *l, dvb_mux_t *lm ) -{ +static int linuxdvb_lnb_bandstack_pol(linuxdvb_lnb_t* l, dvb_mux_t* lm) { return 0; } @@ -209,223 +175,232 @@ linuxdvb_lnb_bandstack_pol * *************************************************************************/ linuxdvb_lnb_conf_t linuxdvb_lnb_all[] = { - { - { { - .ld_type = "Universal", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_match = linuxdvb_lnb_standard_match, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_standard_pol, + { + { + { + .ld_type = "Universal", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_match = linuxdvb_lnb_standard_match, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_standard_pol, + }, + .lnb_low = 9750000, + .lnb_high = 10600000, + .lnb_switch = 11700000, }, - .lnb_low = 9750000, - .lnb_high = 10600000, - .lnb_switch = 11700000, - }, - { - { { - .ld_type = "Standard", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_match = linuxdvb_lnb_standard_match, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_standard_pol, + { + { + { + .ld_type = "Standard", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_match = linuxdvb_lnb_standard_match, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_standard_pol, + }, + .lnb_low = 10000000, + .lnb_high = 0, + .lnb_switch = 0, }, - .lnb_low = 10000000, - .lnb_high = 0, - .lnb_switch = 0, - }, - { - { { - .ld_type = "Enhanced", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_match = linuxdvb_lnb_standard_match, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_standard_pol, + { + { + { + .ld_type = "Enhanced", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_match = linuxdvb_lnb_standard_match, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_standard_pol, + }, + .lnb_low = 9750000, + .lnb_high = 0, + .lnb_switch = 0, }, - .lnb_low = 9750000, - .lnb_high = 0, - .lnb_switch = 0, - }, - { - { { - .ld_type = "C-Band", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_match = linuxdvb_lnb_standard_match, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_standard_pol, + { + { + { + .ld_type = "C-Band", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_match = linuxdvb_lnb_standard_match, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_standard_pol, + }, + .lnb_low = 5150000, + .lnb_high = 0, + .lnb_switch = 0, }, - .lnb_low = 5150000, - .lnb_high = 0, - .lnb_switch = 0, - }, - { - { { - .ld_type = "C-Band (bandstack)", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_bandstack_freq, - .lnb_match = linuxdvb_lnb_bandstack_match, - .lnb_band = linuxdvb_lnb_bandstack_band, - .lnb_pol = linuxdvb_lnb_bandstack_pol, + { + { + { + .ld_type = "C-Band (bandstack)", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_bandstack_freq, + .lnb_match = linuxdvb_lnb_bandstack_match, + .lnb_band = linuxdvb_lnb_bandstack_band, + .lnb_pol = linuxdvb_lnb_bandstack_pol, + }, + .lnb_low = 5150000, + .lnb_high = 5750000, + .lnb_switch = 0, }, - .lnb_low = 5150000, - .lnb_high = 5750000, - .lnb_switch = 0, - }, - { - { { - .ld_type = "Ku 10750", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_match = linuxdvb_lnb_standard_match, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_standard_pol, + { + { + { + .ld_type = "Ku 10750", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_match = linuxdvb_lnb_standard_match, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_standard_pol, + }, + .lnb_low = 10750000, + .lnb_high = 0, + .lnb_switch = 0, }, - .lnb_low = 10750000, - .lnb_high = 0, - .lnb_switch = 0, - }, - { - { { - .ld_type = "Ku 10750 (Hi-Band)", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_match = linuxdvb_lnb_standard_match, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_standard_pol, + { + { + { + .ld_type = "Ku 10750 (Hi-Band)", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_match = linuxdvb_lnb_standard_match, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_standard_pol, + }, + .lnb_low = 10750000, + .lnb_high = 10750000, + .lnb_switch = 10750000, }, - .lnb_low = 10750000, - .lnb_high = 10750000, - .lnb_switch = 10750000, - }, - { - { { - .ld_type = "Ku 10750 (Hi-Band, Inverted-Polar.)", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_match = linuxdvb_lnb_standard_match, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_inverted_pol, + { + { + { + .ld_type = "Ku 10750 (Hi-Band, Inverted-Polar.)", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_match = linuxdvb_lnb_standard_match, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_inverted_pol, + }, + .lnb_low = 10750000, + .lnb_high = 10750000, + .lnb_switch = 10750000, }, - .lnb_low = 10750000, - .lnb_high = 10750000, - .lnb_switch = 10750000, - }, - { - { { - .ld_type = "Ku 11300", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_match = linuxdvb_lnb_standard_match, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_standard_pol, + { + { + { + .ld_type = "Ku 11300", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_match = linuxdvb_lnb_standard_match, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_standard_pol, + }, + .lnb_low = 11300000, + .lnb_high = 0, + .lnb_switch = 0, }, - .lnb_low = 11300000, - .lnb_high = 0, - .lnb_switch = 0, - }, - { - { { - .ld_type = "Ku 11300 (Hi-Band)", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_match = linuxdvb_lnb_standard_match, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_standard_pol, + { + { + { + .ld_type = "Ku 11300 (Hi-Band)", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_match = linuxdvb_lnb_standard_match, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_standard_pol, + }, + .lnb_low = 11300000, + .lnb_high = 11300000, + .lnb_switch = 11300000, }, - .lnb_low = 11300000, - .lnb_high = 11300000, - .lnb_switch = 11300000, - }, - { - { { - .ld_type = "C 5150/Ku 10750 (22kHz switch)", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_standard_pol, - }, - .lnb_low = 5150000, - .lnb_high = 10750000, - .lnb_switch = 11700000, /* 10750 + 950 (bottom of the receiver range 950Mhz-2150Mhz) */ - }, - { - { { - .ld_type = "DBS", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_match = linuxdvb_lnb_standard_match, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_standard_pol, + { + { + { + .ld_type = "C 5150/Ku 10750 (22kHz switch)", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_standard_pol, + }, + .lnb_low = 5150000, + .lnb_high = 10750000, + .lnb_switch = 11700000, /* 10750 + 950 (bottom of the receiver range 950Mhz-2150Mhz) */ }, - .lnb_low = 11250000, - .lnb_high = 0, - .lnb_switch = 0, - }, - { - { { - .ld_type = "DBS Bandstack", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_bandstack_freq, - .lnb_match = linuxdvb_lnb_bandstack_match, - .lnb_band = linuxdvb_lnb_bandstack_band, - .lnb_pol = linuxdvb_lnb_bandstack_pol, + { + { + { + .ld_type = "DBS", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_match = linuxdvb_lnb_standard_match, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_standard_pol, + }, + .lnb_low = 11250000, + .lnb_high = 0, + .lnb_switch = 0, }, - .lnb_low = 11250000, - .lnb_high = 14350000, - .lnb_switch = 0, - }, - { - { { - .ld_type = "Ku 10700 (Australia)", - .ld_tune = linuxdvb_lnb_standard_tune, - }, - .lnb_freq = linuxdvb_lnb_standard_freq, - .lnb_match = linuxdvb_lnb_standard_match, - .lnb_band = linuxdvb_lnb_standard_band, - .lnb_pol = linuxdvb_lnb_standard_pol, + { + { + { + .ld_type = "DBS Bandstack", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_bandstack_freq, + .lnb_match = linuxdvb_lnb_bandstack_match, + .lnb_band = linuxdvb_lnb_bandstack_band, + .lnb_pol = linuxdvb_lnb_bandstack_pol, + }, + .lnb_low = 11250000, + .lnb_high = 14350000, + .lnb_switch = 0, + }, + { + { + { + .ld_type = "Ku 10700 (Australia)", + .ld_tune = linuxdvb_lnb_standard_tune, + }, + .lnb_freq = linuxdvb_lnb_standard_freq, + .lnb_match = linuxdvb_lnb_standard_match, + .lnb_band = linuxdvb_lnb_standard_band, + .lnb_pol = linuxdvb_lnb_standard_pol, + }, + .lnb_low = 10700000, + .lnb_high = 10700000, + .lnb_switch = 11800000, }, - .lnb_low = 10700000, - .lnb_high = 10700000, - .lnb_switch = 11800000, - }, }; /* ************************************************************************** * Create / Config * *************************************************************************/ -htsmsg_t * -linuxdvb_lnb_list ( void *o, const char *lang ) -{ - int i; - htsmsg_t *m = htsmsg_create_list(); +htsmsg_t* linuxdvb_lnb_list(void* o, const char* lang) { + int i; + htsmsg_t* m = htsmsg_create_list(); for (i = 0; i < ARRAY_SIZE(linuxdvb_lnb_all); i++) htsmsg_add_str(m, NULL, linuxdvb_lnb_all[i].ld_type); return m; } -linuxdvb_lnb_t * -linuxdvb_lnb_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls ) -{ +linuxdvb_lnb_t* linuxdvb_lnb_create0(const char* name, htsmsg_t* conf, linuxdvb_satconf_ele_t* ls) { linuxdvb_lnb_conf_t *lsc = &linuxdvb_lnb_all[0], *lsc2; - int i; + int i; /* Find */ if (name) { @@ -436,18 +411,18 @@ linuxdvb_lnb_create0 } } - lsc2 = malloc(sizeof(linuxdvb_lnb_conf_t)); + lsc2 = malloc(sizeof(linuxdvb_lnb_conf_t)); *lsc2 = *lsc; - return (linuxdvb_lnb_t *) - linuxdvb_diseqc_create0((linuxdvb_diseqc_t *)lsc2, - NULL, &linuxdvb_lnb_class, - conf, lsc->ld_type, ls); + return (linuxdvb_lnb_t*)linuxdvb_diseqc_create0((linuxdvb_diseqc_t*)lsc2, + NULL, + &linuxdvb_lnb_class, + conf, + lsc->ld_type, + ls); } -void -linuxdvb_lnb_destroy ( linuxdvb_lnb_t *lnb ) -{ - linuxdvb_diseqc_destroy((linuxdvb_diseqc_t *)lnb); +void linuxdvb_lnb_destroy(linuxdvb_lnb_t* lnb) { + linuxdvb_diseqc_destroy((linuxdvb_diseqc_t*)lnb); free(lnb); } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_private.h b/src/input/mpegts/linuxdvb/linuxdvb_private.h index c0eb3a203..5968deeb2 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_private.h +++ b/src/input/mpegts/linuxdvb/linuxdvb_private.h @@ -31,21 +31,21 @@ #include #endif -#define DVB_VER_INT(maj,min) (((maj) << 16) + (min)) +#define DVB_VER_INT(maj, min) (((maj) << 16) + (min)) #define DVB_VER_ATLEAST(maj, min) \ - (DVB_VER_INT(DVB_API_VERSION, DVB_API_VERSION_MINOR) >= DVB_VER_INT(maj, min)) + (DVB_VER_INT(DVB_API_VERSION, DVB_API_VERSION_MINOR) >= DVB_VER_INT(maj, min)) -typedef struct linuxdvb_hardware linuxdvb_hardware_t; -typedef struct linuxdvb_adapter linuxdvb_adapter_t; -typedef struct linuxdvb_frontend linuxdvb_frontend_t; +typedef struct linuxdvb_hardware linuxdvb_hardware_t; +typedef struct linuxdvb_adapter linuxdvb_adapter_t; +typedef struct linuxdvb_frontend linuxdvb_frontend_t; #if ENABLE_LINUXDVB_CA -typedef struct linuxdvb_transport linuxdvb_transport_t; -typedef struct linuxdvb_ca linuxdvb_ca_t; -typedef struct linuxdvb_ca_write linuxdvb_ca_write_t; +typedef struct linuxdvb_transport linuxdvb_transport_t; +typedef struct linuxdvb_ca linuxdvb_ca_t; +typedef struct linuxdvb_ca_write linuxdvb_ca_write_t; #endif #if ENABLE_DDCI -typedef struct linuxdvb_ddci linuxdvb_ddci_t; +typedef struct linuxdvb_ddci linuxdvb_ddci_t; #endif typedef struct linuxdvb_satconf linuxdvb_satconf_t; typedef struct linuxdvb_satconf_ele linuxdvb_satconf_ele_t; @@ -54,159 +54,155 @@ typedef struct linuxdvb_lnb linuxdvb_lnb_t; typedef struct linuxdvb_network linuxdvb_network_t; typedef struct linuxdvb_en50494 linuxdvb_en50494_t; -typedef LIST_HEAD(,linuxdvb_hardware) linuxdvb_hardware_list_t; -typedef TAILQ_HEAD(linuxdvb_satconf_ele_list,linuxdvb_satconf_ele) linuxdvb_satconf_ele_list_t; +typedef LIST_HEAD(, linuxdvb_hardware) linuxdvb_hardware_list_t; +typedef TAILQ_HEAD(linuxdvb_satconf_ele_list, linuxdvb_satconf_ele) linuxdvb_satconf_ele_list_t; #if ENABLE_LINUXDVB_CA -typedef TAILQ_HEAD(linuxdvb_ca_write_queue,linuxdvb_ca_write) linuxdvb_ca_write_queue_t; +typedef TAILQ_HEAD(linuxdvb_ca_write_queue, linuxdvb_ca_write) linuxdvb_ca_write_queue_t; #endif -struct linuxdvb_adapter -{ +struct linuxdvb_adapter { tvh_hardware_t; /* * Adapter info */ - char *la_name; - char *la_rootpath; - int la_dvb_number; + char* la_name; + char* la_rootpath; + int la_dvb_number; /* * Frontends */ - LIST_HEAD(,linuxdvb_frontend) la_frontends; + LIST_HEAD(, linuxdvb_frontend) la_frontends; /* * CA devices */ #if ENABLE_LINUXDVB_CA - LIST_HEAD(,linuxdvb_transport) la_ca_transports; + LIST_HEAD(, linuxdvb_transport) la_ca_transports; #endif /* - * Functions - */ - int (*la_is_enabled) ( linuxdvb_adapter_t *la ); + * Functions + */ + int (*la_is_enabled)(linuxdvb_adapter_t* la); }; -struct linuxdvb_frontend -{ +struct linuxdvb_frontend { mpegts_input_t; /* * Adapter */ - linuxdvb_adapter_t *lfe_adapter; + linuxdvb_adapter_t* lfe_adapter; LIST_ENTRY(linuxdvb_frontend) lfe_link; /* * Frontend info */ - int lfe_number; - dvb_fe_type_t lfe_type; - char *lfe_name; - char *lfe_fe_path; - char *lfe_dmx_path; - char *lfe_dvr_path; - char *lfe_sysfs; + int lfe_number; + dvb_fe_type_t lfe_type; + char* lfe_name; + char* lfe_fe_path; + char* lfe_dmx_path; + char* lfe_dvr_path; + char* lfe_sysfs; /* * Reception */ - int lfe_fe_fd; - pthread_t lfe_dvr_thread; - th_pipe_t lfe_dvr_pipe; - tvh_mutex_t lfe_dvr_lock; - tvh_cond_t lfe_dvr_cond; - mpegts_apids_t lfe_pids; - int lfe_pids_max; - int lfe_pids_use_all; - + int lfe_fe_fd; + pthread_t lfe_dvr_thread; + th_pipe_t lfe_dvr_pipe; + tvh_mutex_t lfe_dvr_lock; + tvh_cond_t lfe_dvr_cond; + mpegts_apids_t lfe_pids; + int lfe_pids_max; + int lfe_pids_use_all; + /* * Tuning */ - int lfe_refcount; - int lfe_ready; - int lfe_in_setup; - int lfe_locked; - int lfe_status; - int lfe_status2; - int lfe_ioctls; - int lfe_nodata; - int lfe_freq; - int64_t lfe_monitor; - mtimer_t lfe_monitor_timer; - tvhlog_limit_t lfe_status_log; + int lfe_refcount; + int lfe_ready; + int lfe_in_setup; + int lfe_locked; + int lfe_status; + int lfe_status2; + int lfe_ioctls; + int lfe_nodata; + int lfe_freq; + int64_t lfe_monitor; + mtimer_t lfe_monitor_timer; + tvhlog_limit_t lfe_status_log; /* * Configuration */ - char *lfe_master; - int lfe_powersave; - int lfe_tune_repeats; - uint32_t lfe_skip_bytes; - uint32_t lfe_ibuf_size; - uint32_t lfe_status_period; - int lfe_old_status; - int lfe_lna; - uint32_t lfe_sig_multiplier; - uint32_t lfe_snr_multiplier; - uint32_t lfe_grace_period; + char* lfe_master; + int lfe_powersave; + int lfe_tune_repeats; + uint32_t lfe_skip_bytes; + uint32_t lfe_ibuf_size; + uint32_t lfe_status_period; + int lfe_old_status; + int lfe_lna; + uint32_t lfe_sig_multiplier; + uint32_t lfe_snr_multiplier; + uint32_t lfe_grace_period; /* * Satconf (DVB-S only) */ - linuxdvb_satconf_t *lfe_satconf; + linuxdvb_satconf_t* lfe_satconf; }; #if ENABLE_LINUXDVB_CA -struct linuxdvb_transport -{ - LIST_ENTRY(linuxdvb_transport) lcat_link; - LIST_ENTRY(linuxdvb_transport) lcat_all_link; - en50221_transport_t *lcat_transport; - LIST_HEAD(, linuxdvb_ca) lcat_slots; - char *lcat_name; +struct linuxdvb_transport { + LIST_ENTRY(linuxdvb_transport) lcat_link; + LIST_ENTRY(linuxdvb_transport) lcat_all_link; + en50221_transport_t* lcat_transport; + LIST_HEAD(, linuxdvb_ca) lcat_slots; + char* lcat_name; /* * Adapter */ - linuxdvb_adapter_t *lcat_adapter; - int lcat_number; - char *lcat_ca_path; - int lcat_ca_fd; - int lcat_fatal; - int lcat_enabled; - int64_t lcat_fatal_time; - int64_t lcat_close_time; + linuxdvb_adapter_t* lcat_adapter; + int lcat_number; + char* lcat_ca_path; + int lcat_ca_fd; + int lcat_fatal; + int lcat_enabled; + int64_t lcat_fatal_time; + int64_t lcat_close_time; #if ENABLE_DDCI - linuxdvb_ddci_t *lddci; + linuxdvb_ddci_t* lddci; #endif }; -struct linuxdvb_ca -{ - idnode_t lca_id; +struct linuxdvb_ca { + idnode_t lca_id; /* * Transport */ - LIST_ENTRY(linuxdvb_ca) lca_link; - LIST_ENTRY(linuxdvb_ca) lca_all_link; - linuxdvb_transport_t *lca_transport; + LIST_ENTRY(linuxdvb_ca) lca_link; + LIST_ENTRY(linuxdvb_ca) lca_all_link; + linuxdvb_transport_t* lca_transport; /* * CA handling */ - int lca_enabled; - int lca_phys_layer; - int lca_high_bitrate_mode; - int lca_capmt_query; - int lca_capmt_interval; - int lca_capmt_query_interval; - int64_t lca_capmt_blocked; - pthread_t lca_en50221_thread; - int lca_en50221_thread_running; + int lca_enabled; + int lca_phys_layer; + int lca_high_bitrate_mode; + int lca_capmt_query; + int lca_capmt_interval; + int lca_capmt_query_interval; + int64_t lca_capmt_blocked; + pthread_t lca_en50221_thread; + int lca_en50221_thread_running; /* * EN50221 @@ -217,153 +213,154 @@ struct linuxdvb_ca */ int lca_adapnum; uint8_t lca_slotnum; - char *lca_name; + char* lca_name; int lca_state; - char *lca_modulename; + char* lca_modulename; linuxdvb_ca_write_queue_t lca_write_queue; /* * CAM module info */ - int lca_pin_reply; - char *lca_pin_str; - char *lca_pin_match_str; + int lca_pin_reply; + char* lca_pin_str; + char* lca_pin_match_str; }; #endif -struct linuxdvb_satconf -{ - idnode_t ls_id; - const char *ls_type; +struct linuxdvb_satconf { + idnode_t ls_id; + const char* ls_type; /* * MPEG-TS hooks */ - mpegts_input_t *ls_frontend; ///< Frontend we're proxying for - mpegts_mux_instance_t *ls_mmi; ///< Used within delay diseqc handler + mpegts_input_t* ls_frontend; ///< Frontend we're proxying for + mpegts_mux_instance_t* ls_mmi; ///< Used within delay diseqc handler /* * Tuning */ - int ls_early_tune; + int ls_early_tune; /* * Diseqc handling */ - mtimer_t ls_diseqc_timer; - int ls_diseqc_idx; - int ls_diseqc_repeats; - int ls_diseqc_full; - int ls_switch_rotor; + mtimer_t ls_diseqc_timer; + int ls_diseqc_idx; + int ls_diseqc_repeats; + int ls_diseqc_full; + int ls_switch_rotor; /* * LNB settings */ - int ls_lnb_poweroff; - int ls_lnb_highvol; - uint32_t ls_max_rotor_move; - uint32_t ls_min_rotor_move; - double ls_site_lat; - double ls_site_lon; - uint32_t ls_motor_rate; - int ls_site_lat_south; - int ls_site_lon_west; - int ls_site_altitude; - char *ls_rotor_extcmd; - + int ls_lnb_poweroff; + int ls_lnb_highvol; + uint32_t ls_max_rotor_move; + uint32_t ls_min_rotor_move; + double ls_site_lat; + double ls_site_lon; + uint32_t ls_motor_rate; + int ls_site_lat_south; + int ls_site_lon_west; + int ls_site_altitude; + char* ls_rotor_extcmd; + /* * Satconf elements */ linuxdvb_satconf_ele_list_t ls_elements; - linuxdvb_satconf_ele_t *ls_last_switch; - linuxdvb_diseqc_t *ls_active_diseqc; - int ls_last_switch_pol; - int ls_last_switch_band; - int ls_last_vol; - int ls_last_toneburst; - int ls_last_tone_off; - int ls_last_orbital_pos; - int ls_last_queued_pos; + linuxdvb_satconf_ele_t* ls_last_switch; + linuxdvb_diseqc_t* ls_active_diseqc; + int ls_last_switch_pol; + int ls_last_switch_band; + int ls_last_vol; + int ls_last_toneburst; + int ls_last_tone_off; + int ls_last_orbital_pos; + int ls_last_queued_pos; }; /* * Elementary satconf entry */ -struct linuxdvb_satconf_ele -{ - idnode_t lse_id; +struct linuxdvb_satconf_ele { + idnode_t lse_id; /* * Parent */ - linuxdvb_satconf_t *lse_parent; - TAILQ_ENTRY(linuxdvb_satconf_ele) lse_link; + linuxdvb_satconf_t* lse_parent; + TAILQ_ENTRY(linuxdvb_satconf_ele) lse_link; /* * Config */ - int lse_enabled; - int lse_priority; - char *lse_name; + int lse_enabled; + int lse_priority; + char* lse_name; /* * Assigned networks to this SAT configuration */ - idnode_set_t *lse_networks; + idnode_set_t* lse_networks; /* * Diseqc kit */ - linuxdvb_lnb_t *lse_lnb; - linuxdvb_diseqc_t *lse_switch; - linuxdvb_diseqc_t *lse_rotor; - linuxdvb_diseqc_t *lse_en50494; + linuxdvb_lnb_t* lse_lnb; + linuxdvb_diseqc_t* lse_switch; + linuxdvb_diseqc_t* lse_rotor; + linuxdvb_diseqc_t* lse_en50494; }; -struct linuxdvb_diseqc -{ - idnode_t ld_id; - const char *ld_type; - linuxdvb_satconf_ele_t *ld_satconf; - int (*ld_grace) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm); - int (*ld_freq) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm, int freq); - int (*ld_match) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm1, dvb_mux_t *lm2); - int (*ld_start) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls); - int (*ld_tune) (linuxdvb_diseqc_t *ld, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, - int vol, int pol, int band, int freq); - int (*ld_post) (linuxdvb_diseqc_t *ld, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls); +struct linuxdvb_diseqc { + idnode_t ld_id; + const char* ld_type; + linuxdvb_satconf_ele_t* ld_satconf; + int (*ld_grace)(linuxdvb_diseqc_t* ld, dvb_mux_t* lm); + int (*ld_freq)(linuxdvb_diseqc_t* ld, dvb_mux_t* lm, int freq); + int (*ld_match)(linuxdvb_diseqc_t* ld, dvb_mux_t* lm1, dvb_mux_t* lm2); + int (*ld_start)(linuxdvb_diseqc_t* ld, + dvb_mux_t* lm, + linuxdvb_satconf_t* lsp, + linuxdvb_satconf_ele_t* ls); + int (*ld_tune)(linuxdvb_diseqc_t* ld, + dvb_mux_t* lm, + linuxdvb_satconf_t* lsp, + linuxdvb_satconf_ele_t* ls, + int vol, + int pol, + int band, + int freq); + int (*ld_post)(linuxdvb_diseqc_t* ld, linuxdvb_satconf_t* lsp, linuxdvb_satconf_ele_t* ls); }; -struct linuxdvb_lnb -{ +struct linuxdvb_lnb { linuxdvb_diseqc_t; - uint32_t (*lnb_freq) (linuxdvb_lnb_t*, dvb_mux_t*); - int (*lnb_match)(linuxdvb_lnb_t*, dvb_mux_t*, dvb_mux_t*); - int (*lnb_band) (linuxdvb_lnb_t*, dvb_mux_t*); - int (*lnb_pol) (linuxdvb_lnb_t*, dvb_mux_t*); + uint32_t (*lnb_freq)(linuxdvb_lnb_t*, dvb_mux_t*); + int (*lnb_match)(linuxdvb_lnb_t*, dvb_mux_t*, dvb_mux_t*); + int (*lnb_band)(linuxdvb_lnb_t*, dvb_mux_t*); + int (*lnb_pol)(linuxdvb_lnb_t*, dvb_mux_t*); }; -#define UNICABLE_EN50494 50494 -#define UNICABLE_EN50607 50607 +#define UNICABLE_EN50494 50494 +#define UNICABLE_EN50607 50607 -struct linuxdvb_en50494 -{ +struct linuxdvb_en50494 { linuxdvb_diseqc_t; /* wait times */ - uint32_t le_powerup_time; /* time to wait for power up in milliseconds */ - uint32_t le_cmd_time; /* time to wait for command to complete in milliseconds */ + uint32_t le_powerup_time; /* time to wait for power up in milliseconds */ + uint32_t le_cmd_time; /* time to wait for command to complete in milliseconds */ /* en50494 configuration */ - uint16_t le_id; /* user band ID (0-7 for EN50494, 0-31 for EN50607) */ - uint16_t le_frequency; /* user band frequency in MHz */ - uint16_t le_pin; /* 0-255 or LINUXDVB_EN50494_NOPIN */ - uint16_t le_position; /* satelitte position (0-1 for EN50494, 0-63 for EN50607) */ + uint16_t le_id; /* user band ID (0-7 for EN50494, 0-31 for EN50607) */ + uint16_t le_frequency; /* user band frequency in MHz */ + uint16_t le_pin; /* 0-255 or LINUXDVB_EN50494_NOPIN */ + uint16_t le_position; /* satelitte position (0-1 for EN50494, 0-63 for EN50607) */ /* runtime */ - uint32_t le_tune_freq; /* the real frequency to tune to */ + uint32_t le_tune_freq; /* the real frequency to tune to */ }; /* @@ -403,56 +400,59 @@ extern const idclass_t linuxdvb_satconf_ele_class; /* * Methods */ - + #define LINUXDVB_SUBSYS_FE 0x01 #define LINUXDVB_SUBSYS_DVR 0x02 -void linuxdvb_adapter_init ( void ); +void linuxdvb_adapter_init(void); -void linuxdvb_adapter_done ( void ); +void linuxdvb_adapter_done(void); -static inline void linuxdvb_adapter_changed ( linuxdvb_adapter_t *la ) - { idnode_changed(&la->th_id); } +static inline void linuxdvb_adapter_changed(linuxdvb_adapter_t* la) { + idnode_changed(&la->th_id); +} -int linuxdvb_adapter_current_weight ( linuxdvb_adapter_t *la ); +int linuxdvb_adapter_current_weight(linuxdvb_adapter_t* la); -const void *linuxdvb_frontend_class_active_get ( void *obj ); +const void* linuxdvb_frontend_class_active_get(void* obj); -linuxdvb_frontend_t * -linuxdvb_frontend_create - ( htsmsg_t *conf, linuxdvb_adapter_t *la, int number, - const char *fe_path, const char *dmx_path, const char *dvr_path, - dvb_fe_type_t type, const char *name ); +linuxdvb_frontend_t* linuxdvb_frontend_create(htsmsg_t* conf, + linuxdvb_adapter_t* la, + int number, + const char* fe_path, + const char* dmx_path, + const char* dvr_path, + dvb_fe_type_t type, + const char* name); -void linuxdvb_frontend_save ( linuxdvb_frontend_t *lfe, htsmsg_t *m ); +void linuxdvb_frontend_save(linuxdvb_frontend_t* lfe, htsmsg_t* m); -void linuxdvb_frontend_destroy ( linuxdvb_frontend_t *lfe ); +void linuxdvb_frontend_destroy(linuxdvb_frontend_t* lfe); -void linuxdvb_frontend_add_network - ( linuxdvb_frontend_t *lfe, linuxdvb_network_t *net ); +void linuxdvb_frontend_add_network(linuxdvb_frontend_t* lfe, linuxdvb_network_t* net); -int linuxdvb_frontend_clear - ( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi ); -int linuxdvb_frontend_tune0 - ( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi, uint32_t freq ); -int linuxdvb_frontend_tune1 - ( linuxdvb_frontend_t *lfe, mpegts_mux_instance_t *mmi, uint32_t freq ); +int linuxdvb_frontend_clear(linuxdvb_frontend_t* lfe, mpegts_mux_instance_t* mmi); +int linuxdvb_frontend_tune0(linuxdvb_frontend_t* lfe, mpegts_mux_instance_t* mmi, uint32_t freq); +int linuxdvb_frontend_tune1(linuxdvb_frontend_t* lfe, mpegts_mux_instance_t* mmi, uint32_t freq); -int linuxdvb2tvh_delsys ( int delsys ); +int linuxdvb2tvh_delsys(int delsys); #if ENABLE_LINUXDVB_CA -linuxdvb_transport_t * -linuxdvb_transport_create( linuxdvb_adapter_t *la, int number, int slots, - const char *ca_path, const char *ci_path ); -void linuxdvb_transport_destroy( linuxdvb_transport_t *lcat ); -void linuxdvb_transport_save( linuxdvb_transport_t *lcat, htsmsg_t *m ); +linuxdvb_transport_t* linuxdvb_transport_create(linuxdvb_adapter_t* la, + int number, + int slots, + const char* ca_path, + const char* ci_path); +void linuxdvb_transport_destroy(linuxdvb_transport_t* lcat); +void linuxdvb_transport_save(linuxdvb_transport_t* lcat, htsmsg_t* m); -linuxdvb_ca_t * linuxdvb_ca_create - ( htsmsg_t *conf, linuxdvb_transport_t *lcat, int slotnum ); +linuxdvb_ca_t* linuxdvb_ca_create(htsmsg_t* conf, linuxdvb_transport_t* lcat, int slotnum); -void linuxdvb_ca_enqueue_capmt - (linuxdvb_ca_t *lca, const uint8_t *capmt, size_t capmtlen, int descramble); +void linuxdvb_ca_enqueue_capmt(linuxdvb_ca_t* lca, + const uint8_t* capmt, + size_t capmtlen, + int descramble); void linuxdvb_ca_init(void); void linuxdvb_ca_done(void); @@ -461,120 +461,107 @@ void linuxdvb_ca_done(void); #if ENABLE_DDCI -linuxdvb_ddci_t * -linuxdvb_ddci_create ( linuxdvb_transport_t *lcat, const char *ci_path); -void -linuxdvb_ddci_destroy ( linuxdvb_ddci_t *lddci ); -int -linuxdvb_ddci_open ( linuxdvb_ddci_t *lddci ); -void -linuxdvb_ddci_close ( linuxdvb_ddci_t *lddci ); -void -linuxdvb_ddci_put ( linuxdvb_ddci_t *lddci, service_t *t, - const uint8_t *tsb, int len ); -void -linuxdvb_ddci_assign ( linuxdvb_ddci_t *lddci, service_t *t ); -void -linuxdvb_ddci_unassign ( linuxdvb_ddci_t *lddci, service_t *t ); +linuxdvb_ddci_t* linuxdvb_ddci_create(linuxdvb_transport_t* lcat, const char* ci_path); +void linuxdvb_ddci_destroy(linuxdvb_ddci_t* lddci); +int linuxdvb_ddci_open(linuxdvb_ddci_t* lddci); +void linuxdvb_ddci_close(linuxdvb_ddci_t* lddci); +void linuxdvb_ddci_put(linuxdvb_ddci_t* lddci, service_t* t, const uint8_t* tsb, int len); +void linuxdvb_ddci_assign(linuxdvb_ddci_t* lddci, service_t* t); +void linuxdvb_ddci_unassign(linuxdvb_ddci_t* lddci, service_t* t); /* return 0, if ddci can be assigned to the given service */ -int -linuxdvb_ddci_do_not_assign ( linuxdvb_ddci_t *lddci, service_t *t, int multi ); +int linuxdvb_ddci_do_not_assign(linuxdvb_ddci_t* lddci, service_t* t, int multi); #endif /* * Diseqc gear */ -linuxdvb_diseqc_t *linuxdvb_diseqc_create0 - ( linuxdvb_diseqc_t *ld, const char *uuid, const idclass_t *idc, - htsmsg_t *conf, const char *type, linuxdvb_satconf_ele_t *parent ); - -void linuxdvb_diseqc_destroy ( linuxdvb_diseqc_t *ld ); - -#define linuxdvb_diseqc_create(_d, _u, _c, _t, _p)\ - linuxdvb_diseqc_create0(calloc(1, sizeof(struct _d)),\ - _u, &_d##_class, _c, _t, _p) - -linuxdvb_lnb_t *linuxdvb_lnb_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls ); -linuxdvb_diseqc_t *linuxdvb_switch_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls, int c, int u ); -linuxdvb_diseqc_t *linuxdvb_rotor_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls ); - -#define UNICABLE_I_NAME "Unicable I (EN50494)" -#define UNICABLE_II_NAME "Unicable II (EN50607)" - -linuxdvb_diseqc_t *linuxdvb_en50494_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls, int port ); - -void linuxdvb_lnb_destroy ( linuxdvb_lnb_t *lnb ); -void linuxdvb_switch_destroy ( linuxdvb_diseqc_t *ld ); -void linuxdvb_rotor_destroy ( linuxdvb_diseqc_t *ld ); -void linuxdvb_en50494_destroy ( linuxdvb_diseqc_t *ld ); - -htsmsg_t *linuxdvb_lnb_list ( void *o, const char *lang ); -htsmsg_t *linuxdvb_switch_list ( void *o, const char *lang ); -htsmsg_t *linuxdvb_rotor_list ( void *o, const char *lang ); -htsmsg_t *linuxdvb_en50494_list ( void *o, const char *lang ); - -htsmsg_t *linuxdvb_en50494_id_list ( void *o, const char *lang ); -htsmsg_t *linuxdvb_en50607_id_list ( void *o, const char *lang ); -htsmsg_t *linuxdvb_en50494_pin_list ( void *o, const char *lang ); - -static inline int linuxdvb_unicable_is_en50607( const char *str ) - { return str && strcmp(str, UNICABLE_II_NAME) == 0; } -static inline int linuxdvb_unicable_is_en50494( const char *str ) - { return !linuxdvb_unicable_is_en50607(str); } - -void linuxdvb_en50494_init (void); - -int linuxdvb_diseqc_raw_send (int fd, int len, ...); -int -linuxdvb_diseqc_send - (int fd, uint8_t framing, uint8_t addr, uint8_t cmd, int len, ...); -int linuxdvb_diseqc_set_volt ( linuxdvb_satconf_t *ls, int volt ); +linuxdvb_diseqc_t* linuxdvb_diseqc_create0(linuxdvb_diseqc_t* ld, + const char* uuid, + const idclass_t* idc, + htsmsg_t* conf, + const char* type, + linuxdvb_satconf_ele_t* parent); + +void linuxdvb_diseqc_destroy(linuxdvb_diseqc_t* ld); + +#define linuxdvb_diseqc_create(_d, _u, _c, _t, _p) \ + linuxdvb_diseqc_create0(calloc(1, sizeof(struct _d)), _u, &_d##_class, _c, _t, _p) + +linuxdvb_lnb_t* linuxdvb_lnb_create0(const char* name, htsmsg_t* conf, linuxdvb_satconf_ele_t* ls); +linuxdvb_diseqc_t* +linuxdvb_switch_create0(const char* name, htsmsg_t* conf, linuxdvb_satconf_ele_t* ls, int c, int u); +linuxdvb_diseqc_t* +linuxdvb_rotor_create0(const char* name, htsmsg_t* conf, linuxdvb_satconf_ele_t* ls); + +#define UNICABLE_I_NAME "Unicable I (EN50494)" +#define UNICABLE_II_NAME "Unicable II (EN50607)" + +linuxdvb_diseqc_t* +linuxdvb_en50494_create0(const char* name, htsmsg_t* conf, linuxdvb_satconf_ele_t* ls, int port); + +void linuxdvb_lnb_destroy(linuxdvb_lnb_t* lnb); +void linuxdvb_switch_destroy(linuxdvb_diseqc_t* ld); +void linuxdvb_rotor_destroy(linuxdvb_diseqc_t* ld); +void linuxdvb_en50494_destroy(linuxdvb_diseqc_t* ld); + +htsmsg_t* linuxdvb_lnb_list(void* o, const char* lang); +htsmsg_t* linuxdvb_switch_list(void* o, const char* lang); +htsmsg_t* linuxdvb_rotor_list(void* o, const char* lang); +htsmsg_t* linuxdvb_en50494_list(void* o, const char* lang); + +htsmsg_t* linuxdvb_en50494_id_list(void* o, const char* lang); +htsmsg_t* linuxdvb_en50607_id_list(void* o, const char* lang); +htsmsg_t* linuxdvb_en50494_pin_list(void* o, const char* lang); + +static inline int linuxdvb_unicable_is_en50607(const char* str) { + return str && strcmp(str, UNICABLE_II_NAME) == 0; +} +static inline int linuxdvb_unicable_is_en50494(const char* str) { + return !linuxdvb_unicable_is_en50607(str); +} + +void linuxdvb_en50494_init(void); + +int linuxdvb_diseqc_raw_send(int fd, int len, ...); +int linuxdvb_diseqc_send(int fd, uint8_t framing, uint8_t addr, uint8_t cmd, int len, ...); +int linuxdvb_diseqc_set_volt(linuxdvb_satconf_t* ls, int volt); /* * Satconf */ -void linuxdvb_satconf_save ( linuxdvb_satconf_t *ls, htsmsg_t *m ); +void linuxdvb_satconf_save(linuxdvb_satconf_t* ls, htsmsg_t* m); -linuxdvb_satconf_ele_t *linuxdvb_satconf_ele_create0 - (const char *uuid, htsmsg_t *conf, linuxdvb_satconf_t *ls); +linuxdvb_satconf_ele_t* +linuxdvb_satconf_ele_create0(const char* uuid, htsmsg_t* conf, linuxdvb_satconf_t* ls); -void linuxdvb_satconf_ele_destroy ( linuxdvb_satconf_ele_t *ls ); +void linuxdvb_satconf_ele_destroy(linuxdvb_satconf_ele_t* ls); -htsmsg_t *linuxdvb_satconf_type_list ( void *o, const char *lang ); +htsmsg_t* linuxdvb_satconf_type_list(void* o, const char* lang); -linuxdvb_satconf_t *linuxdvb_satconf_create - ( linuxdvb_frontend_t *lfe, htsmsg_t *conf ); +linuxdvb_satconf_t* linuxdvb_satconf_create(linuxdvb_frontend_t* lfe, htsmsg_t* conf); -void linuxdvb_satconf_destroy ( linuxdvb_satconf_t *ls, int delconf ); +void linuxdvb_satconf_destroy(linuxdvb_satconf_t* ls, int delconf); -int linuxdvb_satconf_get_priority - ( linuxdvb_satconf_t *ls, mpegts_mux_t *mm ); +int linuxdvb_satconf_get_priority(linuxdvb_satconf_t* ls, mpegts_mux_t* mm); -int linuxdvb_satconf_get_grace - ( linuxdvb_satconf_t *ls, mpegts_mux_t *mm ); +int linuxdvb_satconf_get_grace(linuxdvb_satconf_t* ls, mpegts_mux_t* mm); -int linuxdvb_satconf_lnb_freq - ( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi ); +int linuxdvb_satconf_lnb_freq(linuxdvb_satconf_t* ls, mpegts_mux_instance_t* mmi); -void linuxdvb_satconf_post_stop_mux( linuxdvb_satconf_t *ls ); +void linuxdvb_satconf_post_stop_mux(linuxdvb_satconf_t* ls); -int linuxdvb_satconf_power_save( linuxdvb_satconf_t *ls ); +int linuxdvb_satconf_power_save(linuxdvb_satconf_t* ls); -int linuxdvb_satconf_start_mux - ( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi, int skip_diseqc ); +int linuxdvb_satconf_start_mux(linuxdvb_satconf_t* ls, mpegts_mux_instance_t* mmi, int skip_diseqc); -int linuxdvb_satconf_match_mux - ( linuxdvb_satconf_t *ls, mpegts_mux_t *mm ); +int linuxdvb_satconf_match_mux(linuxdvb_satconf_t* ls, mpegts_mux_t* mm); -int linuxdvb_satconf_start ( linuxdvb_satconf_t *ls, int delay, int vol ); +int linuxdvb_satconf_start(linuxdvb_satconf_t* ls, int delay, int vol); -void linuxdvb_satconf_reset ( linuxdvb_satconf_t *ls ); +void linuxdvb_satconf_reset(linuxdvb_satconf_t* ls); -static inline int linuxdvb_satconf_fe_fd ( linuxdvb_satconf_t *ls ) - { return ((linuxdvb_frontend_t *)ls->ls_frontend)->lfe_fe_fd; } +static inline int linuxdvb_satconf_fe_fd(linuxdvb_satconf_t* ls) { + return ((linuxdvb_frontend_t*)ls->ls_frontend)->lfe_fe_fd; +} #endif /* __TVH_LINUXDVB_PRIVATE_H__ */ diff --git a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c index faa9cbc53..91b65b570 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_rotor.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_rotor.c @@ -40,15 +40,15 @@ #include typedef struct { - double ls_site_lat; - double ls_site_lon; - double ls_site_altitude; - int ls_site_lat_south; - int ls_site_lon_west; + double ls_site_lat; + double ls_site_lon; + double ls_site_altitude; + int ls_site_lat_south; + int ls_site_lon_west; } linuxdvb_satconf_t; typedef struct { - linuxdvb_satconf_t *lse_parent; + linuxdvb_satconf_t* lse_parent; } linuxdvb_satconf_ele_t; double gazimuth, gelevation; @@ -61,27 +61,24 @@ double gazimuth, gelevation; * Class definition * *************************************************************************/ -typedef struct linuxdvb_rotor -{ +typedef struct linuxdvb_rotor { #ifndef ROTOR_TEST linuxdvb_diseqc_t; #endif - uint32_t lr_powerup_time; - uint32_t lr_cmd_time; + uint32_t lr_powerup_time; + uint32_t lr_cmd_time; - double lr_sat_lon; - uint32_t lr_position; + double lr_sat_lon; + uint32_t lr_position; } linuxdvb_rotor_t; #ifndef ROTOR_TEST static void -linuxdvb_rotor_class_get_title - ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) -{ - linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; +linuxdvb_rotor_class_get_title(idnode_t* o, const char* lang, char* dst, size_t dstsize) { + linuxdvb_diseqc_t* ld = (linuxdvb_diseqc_t*)o; snprintf(dst, dstsize, tvh_gettext_lang(lang, N_("Rotor: %s")), ld->ld_type); } @@ -89,98 +86,80 @@ extern const idclass_t linuxdvb_diseqc_class; CLASS_DOC(linuxdvb_satconf) -const idclass_t linuxdvb_rotor_class = { - .ic_super = &linuxdvb_diseqc_class, - .ic_class = "linuxdvb_rotor", - .ic_doc = tvh_doc_linuxdvb_satconf_class, - .ic_caption = N_("TV Adapters - SatConfig - DiseqC Rotor"), - .ic_get_title = linuxdvb_rotor_class_get_title, - .ic_properties = (const property_t[]) { - { - .type = PT_U32, - .id = "powerup_time", - .name = N_("Power up time (ms) (10-500)"), - .desc = N_("Time (in milliseconds) for the rotor to power up."), - .off = offsetof(linuxdvb_rotor_t, lr_powerup_time), - .def.u32 = 100, - }, - { - .type = PT_U32, - .id = "cmd_time", - .name = N_("Command time (ms) (10-300)"), - .desc = N_("Time (in milliseconds) for a command to complete."), - .off = offsetof(linuxdvb_rotor_t, lr_cmd_time), - .def.u32 = 25 - }, - {} - } -}; - -const idclass_t linuxdvb_rotor_gotox_class = -{ - .ic_super = &linuxdvb_rotor_class, - .ic_class = "linuxdvb_rotor_gotox", - .ic_caption = N_("TV Adapters - SatConfig - GOTOX Rotor"), - .ic_properties = (const property_t[]) { - { - .type = PT_U16, - .id = "position", - .name = N_("GOTOX position"), - .desc = N_("Satellite position."), - .off = offsetof(linuxdvb_rotor_t, lr_position), - }, - { - .type = PT_DBL, - .id = "sat_lon", - .name = N_("Satellite longitude"), - .desc = N_("Satellite longitude (like 9.0 (east) or -33.0 (west))."), - .off = offsetof(linuxdvb_rotor_t, lr_sat_lon), - }, - {} - } -}; - -const idclass_t linuxdvb_rotor_external_class = -{ - .ic_super = &linuxdvb_rotor_class, - .ic_class = "linuxdvb_rotor_external", - .ic_caption = N_("TV Adapters - SatConfig - External Rotor"), - .ic_properties = (const property_t[]) { - { - .type = PT_U16, - .id = "position", - .name = N_("External position"), - .desc = N_("Position to send to the external command"), - .off = offsetof(linuxdvb_rotor_t, lr_position), - }, - { - .type = PT_DBL, - .id = "sat_lon", - .name = N_("Satellite longitude"), - .desc = N_("Satellite longitude (like 9.0 (east) or -33.0 (west))."), - .off = offsetof(linuxdvb_rotor_t, lr_sat_lon), - }, - {} - } -}; - -const idclass_t linuxdvb_rotor_usals_class = -{ - .ic_super = &linuxdvb_rotor_class, - .ic_class = "linuxdvb_rotor_usals", - .ic_caption = N_("TV Adapters - SatConfig - USALS Rotor"), - .ic_properties = (const property_t[]) { - { - .type = PT_DBL, - .id = "sat_lon", - .name = N_("Satellite longitude"), - .desc = N_("Satellite longitude (like 9.0 (east) or -33.0 (west))."), - .off = offsetof(linuxdvb_rotor_t, lr_sat_lon), - }, - - {} - } -}; +const idclass_t linuxdvb_rotor_class = {.ic_super = &linuxdvb_diseqc_class, + .ic_class = "linuxdvb_rotor", + .ic_doc = tvh_doc_linuxdvb_satconf_class, + .ic_caption = N_("TV Adapters - SatConfig - DiseqC Rotor"), + .ic_get_title = linuxdvb_rotor_class_get_title, + .ic_properties = + (const property_t[]){{ + .type = PT_U32, + .id = "powerup_time", + .name = N_("Power up time (ms) (10-500)"), + .desc = N_("Time (in milliseconds) for the rotor to power up."), + .off = offsetof(linuxdvb_rotor_t, lr_powerup_time), + .def.u32 = 100, + }, + {.type = PT_U32, + .id = "cmd_time", + .name = N_("Command time (ms) (10-300)"), + .desc = N_("Time (in milliseconds) for a command to complete."), + .off = offsetof(linuxdvb_rotor_t, lr_cmd_time), + .def.u32 = 25}, + {}}}; + +const idclass_t linuxdvb_rotor_gotox_class = {.ic_super = &linuxdvb_rotor_class, + .ic_class = "linuxdvb_rotor_gotox", + .ic_caption = N_("TV Adapters - SatConfig - GOTOX Rotor"), + .ic_properties = (const property_t[]){{ + .type = PT_U16, + .id = "position", + .name = N_("GOTOX position"), + .desc = N_("Satellite position."), + .off = offsetof(linuxdvb_rotor_t, lr_position), + }, + { + .type = PT_DBL, + .id = "sat_lon", + .name = N_("Satellite longitude"), + .desc = N_("Satellite longitude (like 9.0 (east) or -33.0 (west))."), + .off = offsetof(linuxdvb_rotor_t, lr_sat_lon), + }, + {}}}; + +const idclass_t linuxdvb_rotor_external_class = {.ic_super = &linuxdvb_rotor_class, + .ic_class = "linuxdvb_rotor_external", + .ic_caption = N_("TV Adapters - SatConfig - External Rotor"), + .ic_properties = + (const property_t[]){{ + .type = PT_U16, + .id = "position", + .name = N_("External position"), + .desc = N_("Position to send to the external command"), + .off = offsetof(linuxdvb_rotor_t, lr_position), + }, + { + .type = PT_DBL, + .id = "sat_lon", + .name = N_("Satellite longitude"), + .desc = N_("Satellite longitude (like 9.0 (east) or -33.0 (west))."), + .off = offsetof(linuxdvb_rotor_t, lr_sat_lon), + }, + {}}}; + +const idclass_t linuxdvb_rotor_usals_class = {.ic_super = &linuxdvb_rotor_class, + .ic_class = "linuxdvb_rotor_usals", + .ic_caption = N_("TV Adapters - SatConfig - USALS Rotor"), + .ic_properties = (const property_t[]){ + { + .type = PT_DBL, + .id = "sat_lon", + .name = N_("Satellite longitude"), + .desc = N_("Satellite longitude (like 9.0 (east) or -33.0 (west))."), + .off = offsetof(linuxdvb_rotor_t, lr_sat_lon), + }, + + {}}}; #endif /* ROTOR_TEST */ @@ -188,75 +167,69 @@ const idclass_t linuxdvb_rotor_usals_class = * */ -static inline -int pos_to_integer( double pos ) -{ +static inline int pos_to_integer(double pos) { if (pos < 0) return (pos - 0.05) * 10; else return (pos + 0.05) * 10; } -static inline -double to_radians( double val ) -{ +static inline double to_radians(double val) { return ((val * M_PI) / 180.0); } -static inline -double to_degrees( double val ) -{ +static inline double to_degrees(double val) { return ((val * 180.0) / M_PI); } -static inline -double to_rev( double val ) -{ +static inline double to_rev(double val) { return val - floor(val / 360.0) * 360; } -static -void sat_azimuth_and_elevation - ( double site_lat, double site_lon, double site_alt, double sat_lon, - double *azimuth, double *elevation ) -{ - const double f = 1.00 / 298.257; // Earth flattening factor - const double r_sat = 42164.57; // Distance from earth centre to satellite - const double r_eq = 6378.14; // Earth radius - - const double a0 = 0.58804392; - const double a1 = -0.17941557; - const double a2 = 0.29906946E-1; - const double a3 = -0.25187400E-2; - const double a4 = 0.82622101E-4; - - double sin_site_lat = sin(to_radians(site_lat)); - double cos_site_lat = cos(to_radians(site_lat)); - double Rstation = r_eq / sqrt(1.00 - f*(2.00-f)*sin_site_lat*sin_site_lat); - double Ra = (Rstation+site_alt)*cos_site_lat; - double Rz = Rstation*(1.00-f)*(1.00-f)*sin_site_lat; - double alfa_rx = r_sat*cos(to_radians(sat_lon-site_lon)) - Ra; - double alfa_ry = r_sat*sin(to_radians(sat_lon-site_lon)); - double alfa_rz = -Rz; - double alfa_r_north = -alfa_rx*sin_site_lat + alfa_rz*cos_site_lat; - - double alfa_r_zenith = alfa_rx*cos_site_lat + alfa_rz*sin_site_lat; - double El_geometric = to_degrees(atan(alfa_r_zenith/sqrt(alfa_r_north*alfa_r_north+alfa_ry*alfa_ry))); - double x = fabs(El_geometric+0.589); - double refraction = fabs(a0+a1*x+a2*x*x+a3*x*x*x+a4*x*x*x*x); +static void sat_azimuth_and_elevation(double site_lat, + double site_lon, + double site_alt, + double sat_lon, + double* azimuth, + double* elevation) { + const double f = 1.00 / 298.257; // Earth flattening factor + const double r_sat = 42164.57; // Distance from earth centre to satellite + const double r_eq = 6378.14; // Earth radius + + const double a0 = 0.58804392; + const double a1 = -0.17941557; + const double a2 = 0.29906946E-1; + const double a3 = -0.25187400E-2; + const double a4 = 0.82622101E-4; + + double sin_site_lat = sin(to_radians(site_lat)); + double cos_site_lat = cos(to_radians(site_lat)); + double Rstation = r_eq / sqrt(1.00 - f * (2.00 - f) * sin_site_lat * sin_site_lat); + double Ra = (Rstation + site_alt) * cos_site_lat; + double Rz = Rstation * (1.00 - f) * (1.00 - f) * sin_site_lat; + double alfa_rx = r_sat * cos(to_radians(sat_lon - site_lon)) - Ra; + double alfa_ry = r_sat * sin(to_radians(sat_lon - site_lon)); + double alfa_rz = -Rz; + double alfa_r_north = -alfa_rx * sin_site_lat + alfa_rz * cos_site_lat; + + double alfa_r_zenith = alfa_rx * cos_site_lat + alfa_rz * sin_site_lat; + double El_geometric = + to_degrees(atan(alfa_r_zenith / sqrt(alfa_r_north * alfa_r_north + alfa_ry * alfa_ry))); + double x = fabs(El_geometric + 0.589); + double refraction = fabs(a0 + a1 * x + a2 * x * x + a3 * x * x * x + a4 * x * x * x * x); *azimuth = 0.00; if (alfa_r_north < 0) - *azimuth = 180+to_degrees(atan(alfa_ry/alfa_r_north)); + *azimuth = 180 + to_degrees(atan(alfa_ry / alfa_r_north)); else - *azimuth = to_rev(360+to_degrees(atan(alfa_ry/alfa_r_north))); + *azimuth = to_rev(360 + to_degrees(atan(alfa_ry / alfa_r_north))); *elevation = 0.00; if (El_geometric > 10.2) - *elevation = El_geometric+0.01617*(cos(to_radians(fabs(El_geometric)))/ - sin(to_radians(fabs(El_geometric)))); + *elevation = El_geometric + + 0.01617 * (cos(to_radians(fabs(El_geometric))) / sin(to_radians(fabs(El_geometric)))); else - *elevation = El_geometric+refraction; + *elevation = El_geometric + refraction; if (alfa_r_zenith < -3000) *elevation = -99; } @@ -267,14 +240,12 @@ void sat_azimuth_and_elevation * Site Altitude * Satellite Longtitute */ -static double -sat_angle( linuxdvb_rotor_t *lr, linuxdvb_satconf_ele_t *ls ) -{ - linuxdvb_satconf_t *lsp = ls->lse_parent; - double site_lat = lsp->ls_site_lat; - double site_lon = lsp->ls_site_lon; - double site_alt = lsp->ls_site_altitude; - double sat_lon = lr->lr_sat_lon; +static double sat_angle(linuxdvb_rotor_t* lr, linuxdvb_satconf_ele_t* ls) { + linuxdvb_satconf_t* lsp = ls->lse_parent; + double site_lat = lsp->ls_site_lat; + double site_lon = lsp->ls_site_lon; + double site_alt = lsp->ls_site_altitude; + double sat_lon = lr->lr_sat_lon; if (lsp->ls_site_lat_south) site_lat = -site_lat; @@ -286,17 +257,20 @@ sat_angle( linuxdvb_rotor_t *lr, linuxdvb_satconf_ele_t *ls ) double azimuth, elevation; #ifndef ROTOR_TEST - tvhtrace(LS_DISEQC, "site: lat %.4f, lon %.4f, alt %.4f; sat lon %.4f", - site_lat, site_lon, site_alt, sat_lon); + tvhtrace(LS_DISEQC, + "site: lat %.4f, lon %.4f, alt %.4f; sat lon %.4f", + site_lat, + site_lon, + site_alt, + sat_lon); #endif - sat_azimuth_and_elevation(site_lat, site_lon, site_alt, sat_lon, - &azimuth, &elevation); + sat_azimuth_and_elevation(site_lat, site_lon, site_alt, sat_lon, &azimuth, &elevation); #ifndef ROTOR_TEST tvhtrace(LS_DISEQC, "rotor angle azimuth %.4f elevation %.4f", azimuth, elevation); #else - gazimuth = azimuth; + gazimuth = azimuth; gelevation = elevation; #endif @@ -307,15 +281,14 @@ sat_angle( linuxdvb_rotor_t *lr, linuxdvb_satconf_ele_t *ls ) double a, b, value; a = -cos_elevation * sin(rad_azimuth); - b = sin(rad_elevation) * cos(rad_site_lat) - - cos_elevation * sin(rad_site_lat) * cos(rad_azimuth); + b = sin(rad_elevation) * cos(rad_site_lat) - cos_elevation * sin(rad_site_lat) * cos(rad_azimuth); - value = 180 + to_degrees(atan(a/b)); + value = 180 + to_degrees(atan(a / b)); if (azimuth > 270) { value = value + 180; if (value > 360) - value = 360 - (value-360); + value = 360 - (value - 360); } if (azimuth < 90) value = 180 - value; @@ -341,32 +314,29 @@ sat_angle( linuxdvb_rotor_t *lr, linuxdvb_satconf_ele_t *ls ) * Class methods * *************************************************************************/ -static int -linuxdvb_rotor_extcmd - (linuxdvb_rotor_t *lr, linuxdvb_satconf_ele_t *lse) -{ - int outlen = -1, rd = -1; +static int linuxdvb_rotor_extcmd(linuxdvb_rotor_t* lr, linuxdvb_satconf_ele_t* lse) { + int outlen = -1, rd = -1; char outbuf[100]; char satpos[10]; char satlon[10]; char satangle[10]; - char *argv[] = {NULL, satpos, satlon, satangle, NULL}; - int ret = -1; - int angle=sat_angle(lr,lse); + char* argv[] = {NULL, satpos, satlon, satangle, NULL}; + int ret = -1; + int angle = sat_angle(lr, lse); snprintf(satpos, sizeof(satpos), "%u", lr->lr_position); snprintf(satlon, sizeof(satlon), "%.1f", lr->lr_sat_lon); snprintf(satangle, sizeof(satangle), "%d", angle); if (spawn_and_give_stdout(lse->lse_parent->ls_rotor_extcmd, argv, NULL, &rd, NULL, 1) >= 0) { outlen = read(rd, outbuf, 99); - if (outlen>0) { - outbuf[outlen]=0; - tvhdebug(LS_DISEQC, "external command replied %s",outbuf); - if (outbuf[0]>='0' && outbuf[0]<='9') - ret=atoi(outbuf); + if (outlen > 0) { + outbuf[outlen] = 0; + tvhdebug(LS_DISEQC, "external command replied %s", outbuf); + if (outbuf[0] >= '0' && outbuf[0] <= '9') + ret = atoi(outbuf); } else { - if (outlen==0) + if (outlen == 0) tvherror(LS_DISEQC, "no output from external command"); else tvherror(LS_DISEQC, "error reading from external command"); @@ -374,29 +344,23 @@ linuxdvb_rotor_extcmd } else { tvherror(LS_DISEQC, "cannot spawn external command"); } - if (rd>=0) + if (rd >= 0) close(rd); tvhinfo(LS_DISEQC, "linuxdvb_rotor_extcmd moving to %d returned %d", lr->lr_position, ret); return ret; } -static int -linuxdvb_external_grace - ( linuxdvb_rotor_t *lr, linuxdvb_satconf_ele_t *lse) -{ +static int linuxdvb_external_grace(linuxdvb_rotor_t* lr, linuxdvb_satconf_ele_t* lse) { int ret = linuxdvb_rotor_extcmd(lr, lse); - if (ret<0) + if (ret < 0) return lse->lse_parent->ls_max_rotor_move; return ret; } -static int -linuxdvb_rotor_grace - ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm ) -{ - linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld; - linuxdvb_satconf_t *ls = ld->ld_satconf->lse_parent; - int newpos, delta, tunit, min, res; +static int linuxdvb_rotor_grace(linuxdvb_diseqc_t* ld, dvb_mux_t* lm) { + linuxdvb_rotor_t* lr = (linuxdvb_rotor_t*)ld; + linuxdvb_satconf_t* ls = ld->ld_satconf->lse_parent; + int newpos, delta, tunit, min, res; if (idnode_is_instance(&lr->ld_id, &linuxdvb_rotor_external_class)) return linuxdvb_external_grace(lr, ld->ld_satconf); @@ -406,16 +370,16 @@ linuxdvb_rotor_grace newpos = pos_to_integer(lr->lr_sat_lon); - tunit = 10000; /* 1/1000 sec per one degree */ + tunit = 10000; /* 1/1000 sec per one degree */ - delta = abs(deltaI32(ls->ls_last_orbital_pos, newpos)); + delta = abs(deltaI32(ls->ls_last_orbital_pos, newpos)); /* ignore very small movements like 0.8W and 1W */ if (delta <= 2) return 0; /* add one extra second, because of the rounding issue */ - res = ((ls->ls_motor_rate*delta+(tunit-1))/tunit) + 1; + res = ((ls->ls_motor_rate * delta + (tunit - 1)) / tunit) + 1; min = 1 + ls->ls_min_rotor_move; if (res < min) @@ -425,12 +389,10 @@ linuxdvb_rotor_grace } static int -linuxdvb_rotor_check_orbital_pos - ( linuxdvb_rotor_t *lr, dvb_mux_t *lm, linuxdvb_satconf_ele_t *ls ) -{ - linuxdvb_satconf_t *lsp = ls->lse_parent; - int pos = lsp->ls_last_orbital_pos; - char dir; +linuxdvb_rotor_check_orbital_pos(linuxdvb_rotor_t* lr, dvb_mux_t* lm, linuxdvb_satconf_ele_t* ls) { + linuxdvb_satconf_t* lsp = ls->lse_parent; + int pos = lsp->ls_last_orbital_pos; + char dir; if (!pos) return 0; @@ -443,17 +405,15 @@ linuxdvb_rotor_check_orbital_pos pos = -(pos); dir = 'W'; } - tvhdebug(LS_DISEQC, "rotor already positioned to %i.%i%c", - pos / 10, pos % 10, dir); + tvhdebug(LS_DISEQC, "rotor already positioned to %i.%i%c", pos / 10, pos % 10, dir); return 1; } /* GotoX */ -static int -linuxdvb_rotor_gotox_tune - ( linuxdvb_rotor_t *lr, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls ) -{ +static int linuxdvb_rotor_gotox_tune(linuxdvb_rotor_t* lr, + dvb_mux_t* lm, + linuxdvb_satconf_t* lsp, + linuxdvb_satconf_ele_t* ls) { int i, fd = linuxdvb_satconf_fe_fd(lsp); for (i = 0; i <= ls->lse_parent->ls_diseqc_repeats; i++) { @@ -466,60 +426,61 @@ linuxdvb_rotor_gotox_tune tvhdebug(LS_DISEQC, "rotor GOTOX pos %d sent", lr->lr_position); - return linuxdvb_rotor_grace((linuxdvb_diseqc_t*)lr,lm); + return linuxdvb_rotor_grace((linuxdvb_diseqc_t*)lr, lm); } /* External */ -static int -linuxdvb_rotor_external_tune - ( linuxdvb_rotor_t *lr, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls ) -{ +static int linuxdvb_rotor_external_tune(linuxdvb_rotor_t* lr, + dvb_mux_t* lm, + linuxdvb_satconf_t* lsp, + linuxdvb_satconf_ele_t* ls) { return linuxdvb_rotor_extcmd(lr, ls); } /* USALS */ -static int -linuxdvb_rotor_usals_tune - ( linuxdvb_rotor_t *lr, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls ) -{ - static const uint8_t xtable[10] = - { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E }; - - int i, angle = sat_angle(lr, ls), fd = linuxdvb_satconf_fe_fd(lsp); +static int linuxdvb_rotor_usals_tune(linuxdvb_rotor_t* lr, + dvb_mux_t* lm, + linuxdvb_satconf_t* lsp, + linuxdvb_satconf_ele_t* ls) { + static const uint8_t xtable[10] = {0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E}; + + int i, angle = sat_angle(lr, ls), fd = linuxdvb_satconf_fe_fd(lsp); uint32_t cmd = 0xE000; if (angle < 0) { angle = -(angle); - cmd = 0xD000; + cmd = 0xD000; } cmd |= (angle / 10) * 0x10 + xtable[angle % 10]; - tvhdebug(LS_DISEQC, "rotor USALS goto %0.1f%c (motor %0.1f %sclockwise)", - fabs(lr->lr_sat_lon), (lr->lr_sat_lon > 0.0) ? 'E' : 'W', - ((double)angle / 10.0), (cmd & 0xF000) == 0xD000 ? "counter-" : ""); + tvhdebug(LS_DISEQC, + "rotor USALS goto %0.1f%c (motor %0.1f %sclockwise)", + fabs(lr->lr_sat_lon), + (lr->lr_sat_lon > 0.0) ? 'E' : 'W', + ((double)angle / 10.0), + (cmd & 0xF000) == 0xD000 ? "counter-" : ""); for (i = 0; i <= lsp->ls_diseqc_repeats; i++) { - if (linuxdvb_diseqc_send(fd, 0xE0, 0x31, 0x6E, 2, - (cmd >> 8) & 0xff, cmd & 0xff)) { + if (linuxdvb_diseqc_send(fd, 0xE0, 0x31, 0x6E, 2, (cmd >> 8) & 0xff, cmd & 0xff)) { tvherror(LS_DISEQC, "failed to send USALS command"); return -1; } tvh_safe_usleep(MINMAX(lr->lr_cmd_time, 10, 300) * 1000); } - return linuxdvb_rotor_grace((linuxdvb_diseqc_t*)lr,lm); + return linuxdvb_rotor_grace((linuxdvb_diseqc_t*)lr, lm); } -static int -linuxdvb_rotor_tune - ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls, - int vol, int pol, int band, int freq ) -{ - linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld; - int res; +static int linuxdvb_rotor_tune(linuxdvb_diseqc_t* ld, + dvb_mux_t* lm, + linuxdvb_satconf_t* lsp, + linuxdvb_satconf_ele_t* ls, + int vol, + int pol, + int band, + int freq) { + linuxdvb_rotor_t* lr = (linuxdvb_rotor_t*)ld; + int res; if (linuxdvb_rotor_check_orbital_pos(lr, lm, ls)) return 0; @@ -545,13 +506,12 @@ linuxdvb_rotor_tune return res; } -static int -linuxdvb_rotor_start - ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls ) -{ - linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld; - int pos = pos_to_integer(lr->lr_sat_lon); +static int linuxdvb_rotor_start(linuxdvb_diseqc_t* ld, + dvb_mux_t* lm, + linuxdvb_satconf_t* lsp, + linuxdvb_satconf_ele_t* ls) { + linuxdvb_rotor_t* lr = (linuxdvb_rotor_t*)ld; + int pos = pos_to_integer(lr->lr_sat_lon); if (lsp->ls_last_queued_pos == pos) return 1; lsp->ls_last_queued_pos = 0; @@ -559,14 +519,11 @@ linuxdvb_rotor_start } static int -linuxdvb_rotor_post - ( linuxdvb_diseqc_t *ld, - linuxdvb_satconf_t *lsp, linuxdvb_satconf_ele_t *ls ) -{ - linuxdvb_rotor_t *lr = (linuxdvb_rotor_t*)ld; +linuxdvb_rotor_post(linuxdvb_diseqc_t* ld, linuxdvb_satconf_t* lsp, linuxdvb_satconf_ele_t* ls) { + linuxdvb_rotor_t* lr = (linuxdvb_rotor_t*)ld; lsp->ls_last_orbital_pos = pos_to_integer(lr->lr_sat_lon); - lsp->ls_last_queued_pos = 0; + lsp->ls_last_queued_pos = 0; return 0; } @@ -575,53 +532,44 @@ linuxdvb_rotor_post * *************************************************************************/ struct { - const char *name; - const idclass_t *idc; -} linuxdvb_rotor_all[] = { - { - .name = N_("GOTOX"), - .idc = &linuxdvb_rotor_gotox_class - }, - { - .name = N_("EXTERNAL"), - .idc = &linuxdvb_rotor_external_class - }, - { - .name = N_("USALS"), - .idc = &linuxdvb_rotor_usals_class - } -}; - -htsmsg_t * -linuxdvb_rotor_list ( void *o, const char *lang ) -{ - int i; - htsmsg_t *m = htsmsg_create_list(); + const char* name; + const idclass_t* idc; +} linuxdvb_rotor_all[] = {{.name = N_("GOTOX"), .idc = &linuxdvb_rotor_gotox_class}, + {.name = N_("EXTERNAL"), .idc = &linuxdvb_rotor_external_class}, + {.name = N_("USALS"), .idc = &linuxdvb_rotor_usals_class}}; + +htsmsg_t* linuxdvb_rotor_list(void* o, const char* lang) { + int i; + htsmsg_t* m = htsmsg_create_list(); htsmsg_add_msg(m, NULL, htsmsg_create_key_val("", tvh_gettext_lang(lang, N_("None")))); for (i = 0; i < ARRAY_SIZE(linuxdvb_rotor_all); i++) - htsmsg_add_msg(m, NULL, htsmsg_create_key_val(linuxdvb_rotor_all[i].name, tvh_gettext_lang(lang, linuxdvb_rotor_all[i].name))); + htsmsg_add_msg(m, + NULL, + htsmsg_create_key_val(linuxdvb_rotor_all[i].name, + tvh_gettext_lang(lang, linuxdvb_rotor_all[i].name))); return m; } -linuxdvb_diseqc_t * -linuxdvb_rotor_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls ) -{ - int i; - linuxdvb_diseqc_t *ld = NULL; - linuxdvb_rotor_t *lr; +linuxdvb_diseqc_t* +linuxdvb_rotor_create0(const char* name, htsmsg_t* conf, linuxdvb_satconf_ele_t* ls) { + int i; + linuxdvb_diseqc_t* ld = NULL; + linuxdvb_rotor_t* lr; for (i = 0; i < ARRAY_SIZE(linuxdvb_rotor_all); i++) { if (!strcmp(name ?: "", linuxdvb_rotor_all[i].name)) { ld = linuxdvb_diseqc_create0(calloc(1, sizeof(linuxdvb_rotor_t)), - NULL, linuxdvb_rotor_all[i].idc, conf, - linuxdvb_rotor_all[i].name, ls); + NULL, + linuxdvb_rotor_all[i].idc, + conf, + linuxdvb_rotor_all[i].name, + ls); if (ld) { ld->ld_start = linuxdvb_rotor_start; ld->ld_tune = linuxdvb_rotor_tune; ld->ld_grace = linuxdvb_rotor_grace; ld->ld_post = linuxdvb_rotor_post; - lr = (linuxdvb_rotor_t *)ld; + lr = (linuxdvb_rotor_t*)ld; if (lr->lr_powerup_time == 0) lr->lr_powerup_time = 100; if (lr->lr_cmd_time == 0) @@ -629,29 +577,26 @@ linuxdvb_rotor_create0 } } } - + return ld; } -void -linuxdvb_rotor_destroy ( linuxdvb_diseqc_t *lr ) -{ +void linuxdvb_rotor_destroy(linuxdvb_diseqc_t* lr) { linuxdvb_diseqc_destroy(lr); free(lr); } #else /* ROTOR_TEST */ -int main(int argc, char *argv[]) -{ +int main(int argc, char* argv[]) { if (argc < 5) { fprintf(stderr, "Usage: \n"); return 1; } - linuxdvb_rotor_t lr; - linuxdvb_satconf_t ls; + linuxdvb_rotor_t lr; + linuxdvb_satconf_t ls; linuxdvb_satconf_ele_t lse; - int angle; + int angle; memset(&lr, 0, sizeof(lr)); memset(&ls, 0, sizeof(ls)); @@ -659,10 +604,10 @@ int main(int argc, char *argv[]) lse.lse_parent = &ls; - ls.ls_site_lat = atof(argv[1]); - ls.ls_site_lon = atof(argv[2]); + ls.ls_site_lat = atof(argv[1]); + ls.ls_site_lon = atof(argv[2]); ls.ls_site_altitude = atof(argv[3]); - lr.lr_sat_lon = atof(argv[4]); + lr.lr_sat_lon = atof(argv[4]); angle = sat_angle(&lr, &lse); @@ -674,7 +619,10 @@ int main(int argc, char *argv[]) printf("\nResult:\n"); printf(" %20s: %.4f\n", "Azimuth", gazimuth); printf(" %20s: %.4f\n", "Elevation", gelevation); - printf(" %20s: %.1f %sclockwise\n", "Angle", (double)abs(angle) / 10.0, angle < 0 ? "counter-" : ""); + printf(" %20s: %.1f %sclockwise\n", + "Angle", + (double)abs(angle) / 10.0, + angle < 0 ? "counter-" : ""); return 0; } diff --git a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c index 599b3d734..9ac76a36b 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_satconf.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_satconf.c @@ -31,30 +31,27 @@ #include #include -static struct linuxdvb_satconf_type * -linuxdvb_satconf_type_find ( const char *type ); +static struct linuxdvb_satconf_type* linuxdvb_satconf_type_find(const char* type); struct linuxdvb_satconf_type { - int enable; - int ports; - const char *type; - const char *name; - const idclass_t *idc; + int enable; + int ports; + const char* type; + const char* name; + const idclass_t* idc; }; /* ************************************************************************** * Types * *************************************************************************/ -static const void * -linuxdvb_satconf_class_active_get ( void *obj ) -{ - static int active; - linuxdvb_satconf_t *ls = obj; - linuxdvb_satconf_ele_t *lse; +static const void* linuxdvb_satconf_class_active_get(void* obj) { + static int active; + linuxdvb_satconf_t* ls = obj; + linuxdvb_satconf_ele_t* lse; active = 0; - if (*(int *)linuxdvb_frontend_class_active_get(ls->ls_frontend)) { - TAILQ_FOREACH(lse, &ls->ls_elements, lse_link) { + if (*(int*)linuxdvb_frontend_class_active_get(ls->ls_frontend)) { + TAILQ_FOREACH (lse, &ls->ls_elements, lse_link) { if (lse->lse_enabled) { active = 1; break; @@ -64,83 +61,67 @@ linuxdvb_satconf_class_active_get ( void *obj ) return &active; } -static linuxdvb_satconf_ele_t * -linuxdvb_satconf_class_find_ele( linuxdvb_satconf_t *ls, int idx ) -{ - int i = 0; - linuxdvb_satconf_ele_t *lse; - TAILQ_FOREACH(lse, &ls->ls_elements, lse_link) { - if (i == idx) break; +static linuxdvb_satconf_ele_t* linuxdvb_satconf_class_find_ele(linuxdvb_satconf_t* ls, int idx) { + int i = 0; + linuxdvb_satconf_ele_t* lse; + TAILQ_FOREACH (lse, &ls->ls_elements, lse_link) { + if (i == idx) + break; i++; } return lse; } -static const void * -linuxdvb_satconf_class_network_get( linuxdvb_satconf_t *ls, int idx ) -{ - linuxdvb_satconf_ele_t *lse = linuxdvb_satconf_class_find_ele(ls, idx); +static const void* linuxdvb_satconf_class_network_get(linuxdvb_satconf_t* ls, int idx) { + linuxdvb_satconf_ele_t* lse = linuxdvb_satconf_class_find_ele(ls, idx); if (lse) return idnode_set_as_htsmsg(lse->lse_networks); return NULL; } -static int -linuxdvb_satconf_ele_class_network_set( void *o, const void *p ); +static int linuxdvb_satconf_ele_class_network_set(void* o, const void* p); static int -linuxdvb_satconf_class_network_set - ( linuxdvb_satconf_t *ls, int idx, const void *networks ) -{ - linuxdvb_satconf_ele_t *lse = linuxdvb_satconf_class_find_ele(ls, idx); +linuxdvb_satconf_class_network_set(linuxdvb_satconf_t* ls, int idx, const void* networks) { + linuxdvb_satconf_ele_t* lse = linuxdvb_satconf_class_find_ele(ls, idx); if (lse) return linuxdvb_satconf_ele_class_network_set(lse, networks); return 0; } -static htsmsg_t * -linuxdvb_satconf_class_network_enum( void *o, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_t *p = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "idnode/load"); +static htsmsg_t* linuxdvb_satconf_class_network_enum(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_t* p = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "idnode/load"); htsmsg_add_str(m, "event", "mpegts_network"); - htsmsg_add_u32(p, "enum", 1); + htsmsg_add_u32(p, "enum", 1); htsmsg_add_str(p, "class", dvb_network_dvbs_class.ic_class); htsmsg_add_msg(m, "params", p); return m; } -static char * -linuxdvb_satconf_ele_class_network_rend( void *o, const char *lang ); +static char* linuxdvb_satconf_ele_class_network_rend(void* o, const char* lang); -static char * -linuxdvb_satconf_class_network_rend( linuxdvb_satconf_t *ls, int idx, const char *lang ) -{ - linuxdvb_satconf_ele_t *lse = linuxdvb_satconf_class_find_ele(ls, idx); +static char* +linuxdvb_satconf_class_network_rend(linuxdvb_satconf_t* ls, int idx, const char* lang) { + linuxdvb_satconf_ele_t* lse = linuxdvb_satconf_class_find_ele(ls, idx); if (lse) return linuxdvb_satconf_ele_class_network_rend(lse, lang); return NULL; } -#define linuxdvb_satconf_class_network_getset(x)\ -static int \ -linuxdvb_satconf_class_network_set##x ( void *o, const void *v )\ -{\ - return linuxdvb_satconf_class_network_set(o, x, (void*)v);\ -}\ -static const void * \ -linuxdvb_satconf_class_network_get##x ( void *o )\ -{\ - return linuxdvb_satconf_class_network_get(o, x);\ -}\ -static char * \ -linuxdvb_satconf_class_network_rend##x ( void *o, const char *lang )\ -{\ - return linuxdvb_satconf_class_network_rend(o, x, lang);\ -} +#define linuxdvb_satconf_class_network_getset(x) \ + static int linuxdvb_satconf_class_network_set##x(void* o, const void* v) { \ + return linuxdvb_satconf_class_network_set(o, x, (void*)v); \ + } \ + static const void* linuxdvb_satconf_class_network_get##x(void* o) { \ + return linuxdvb_satconf_class_network_get(o, x); \ + } \ + static char* linuxdvb_satconf_class_network_rend##x(void* o, const char* lang) { \ + return linuxdvb_satconf_class_network_rend(o, x, lang); \ + } linuxdvb_satconf_class_network_getset(0); linuxdvb_satconf_class_network_getset(1); @@ -148,45 +129,35 @@ linuxdvb_satconf_class_network_getset(2); linuxdvb_satconf_class_network_getset(3); static void -linuxdvb_satconf_class_get_title - ( idnode_t *p, const char *lang, char *dst, size_t dstsize ) -{ - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)p; - struct linuxdvb_satconf_type *lst = - linuxdvb_satconf_type_find(ls->ls_type); +linuxdvb_satconf_class_get_title(idnode_t* p, const char* lang, char* dst, size_t dstsize) { + linuxdvb_satconf_t* ls = (linuxdvb_satconf_t*)p; + struct linuxdvb_satconf_type* lst = linuxdvb_satconf_type_find(ls->ls_type); snprintf(dst, dstsize, "%s", lst ? lst->name : ls->ls_type); } -static void -linuxdvb_satconf_class_changed ( idnode_t *s ) -{ - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)s; - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend; - linuxdvb_adapter_t *la = lfe->lfe_adapter; +static void linuxdvb_satconf_class_changed(idnode_t* s) { + linuxdvb_satconf_t* ls = (linuxdvb_satconf_t*)s; + linuxdvb_frontend_t* lfe = (linuxdvb_frontend_t*)ls->ls_frontend; + linuxdvb_adapter_t* la = lfe->lfe_adapter; linuxdvb_adapter_changed(la); } -static const void * -linuxdvb_satconf_class_orbitalpos_get ( void *p ) -{ - static int n; - linuxdvb_satconf_t *ls = p; - linuxdvb_satconf_ele_t *lse; +static const void* linuxdvb_satconf_class_orbitalpos_get(void* p) { + static int n; + linuxdvb_satconf_t* ls = p; + linuxdvb_satconf_ele_t* lse; n = 0; - TAILQ_FOREACH(lse, &ls->ls_elements, lse_link) + TAILQ_FOREACH (lse, &ls->ls_elements, lse_link) n++; return &n; } -static int -linuxdvb_satconf_class_orbitalpos_set - ( void *p, const void *v ) -{ - linuxdvb_satconf_ele_t *lse; - linuxdvb_satconf_t *ls = p; - int c = *(int*)linuxdvb_satconf_class_orbitalpos_get(p); - int n = *(int*)v; - char buf[22]; +static int linuxdvb_satconf_class_orbitalpos_set(void* p, const void* v) { + linuxdvb_satconf_ele_t* lse; + linuxdvb_satconf_t* ls = p; + int c = *(int*)linuxdvb_satconf_class_orbitalpos_get(p); + int n = *(int*)v; + char buf[22]; if (n == c) return 0; @@ -202,7 +173,7 @@ linuxdvb_satconf_class_orbitalpos_set c++; } - /* Remove */ + /* Remove */ } else { while (c > n) { lse = TAILQ_LAST(&ls->ls_elements, linuxdvb_satconf_ele_list); @@ -210,639 +181,556 @@ linuxdvb_satconf_class_orbitalpos_set c--; } } - + return 1; } -static idnode_set_t * -linuxdvb_satconf_class_get_childs ( idnode_t *o ) -{ - linuxdvb_satconf_t *ls = (linuxdvb_satconf_t*)o; - linuxdvb_satconf_ele_t *lse; - idnode_set_t *is = idnode_set_create(0); - TAILQ_FOREACH(lse, &ls->ls_elements, lse_link) +static idnode_set_t* linuxdvb_satconf_class_get_childs(idnode_t* o) { + linuxdvb_satconf_t* ls = (linuxdvb_satconf_t*)o; + linuxdvb_satconf_ele_t* lse; + idnode_set_t* is = idnode_set_create(0); + TAILQ_FOREACH (lse, &ls->ls_elements, lse_link) idnode_set_add(is, &lse->lse_id, NULL, NULL); return is; } -static htsmsg_t * -linuxdvb_satconf_class_highvol_list ( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("Do not set"), 0 }, - { N_("Normal"), 1 }, - { N_("Higher"), 2 } - }; +static htsmsg_t* linuxdvb_satconf_class_highvol_list(void* o, const char* lang) { + static const struct strtab tab[] = {{N_("Do not set"), 0}, {N_("Normal"), 1}, {N_("Higher"), 2}}; return strtab2htsmsg(tab, 1, lang); } /* * Generic satconf */ - + CLASS_DOC(linuxdvb_satconf) /* Referenced by multiple classes. */ - -const idclass_t linuxdvb_satconf_class = -{ - .ic_class = "linuxdvb_satconf", - .ic_caption = N_("DVB-S Satellite Configuration"), - .ic_event = "linuxdvb_satconf", - .ic_get_title = linuxdvb_satconf_class_get_title, - .ic_doc = tvh_doc_linuxdvb_satconf_class, - .ic_changed = linuxdvb_satconf_class_changed, - .ic_properties = (const property_t[]) { - { - .type = PT_BOOL, - .id = "active", - .name = N_("Active"), - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, - .get = linuxdvb_satconf_class_active_get, - }, - { - .type = PT_BOOL, - .id = "early_tune", - .name = N_("Tune before DiseqC"), - .desc = N_("One tune request (setup) is sent before the " - "DiseqC sequence (voltage, tone settings). " - "Some linux drivers require this procedure."), - .off = offsetof(linuxdvb_satconf_t, ls_early_tune), - .opts = PO_ADVANCED, - .def.i = 1 - }, - { - .type = PT_INT, - .id = "diseqc_repeats", - .name = N_("DiseqC repeats"), - .desc = N_("Number of repeats for the DiseqC commands " - "(default is zero - no DiseqC repeats). " - "Note: this represents the number of repeats, not " - "the number of requests - so 0 means 'send once: " - "don't repeat', 1 means 'send twice: send once, " - "then send one repeat', etc."), - .off = offsetof(linuxdvb_satconf_t, ls_diseqc_repeats), - .opts = PO_ADVANCED, - .def.i = 0 - }, - { - .type = PT_BOOL, - .id = "diseqc_full", - .name = N_("Full DiseqC"), - .desc = N_("Always send the whole DiseqC sequence including " - "LNB setup (voltage, tone). If this is not " - "checked, only changed settings are sent, which " - "may cause issues with some drivers. If the tuning " - "is not reliable, try activating this option."), - .off = offsetof(linuxdvb_satconf_t, ls_diseqc_full), - .opts = PO_ADVANCED, - .def.i = 1 - }, - { - .type = PT_BOOL, - .id = "lnb_poweroff", - .name = N_("Turn off LNB when idle"), - .desc = N_("Switch off the power to the LNB when idle. Note: " - "this may cause interference with other devices " - "when the LNB is powered back up."), - .off = offsetof(linuxdvb_satconf_t, ls_lnb_poweroff), - .opts = PO_ADVANCED, - .def.i = 1 - }, - { - .type = PT_INT, - .id = "lnb_highvol", - .name = N_("Higher LNB voltage"), - .desc = N_("Some DVB devices have an optional ioctl that allows " - "changing between normal voltage for LNB (13V/18V) to " - "a higher voltage mode (usually, 14V/19V), meant to " - "compensate for voltage loss on long cabling. " - "Without that, it is not possible to properly switch " - "the polarization."), - .list = linuxdvb_satconf_class_highvol_list, - .off = offsetof(linuxdvb_satconf_t, ls_lnb_highvol), - .opts = PO_ADVANCED, - .def.i = 1 - }, - {} - } -}; + +const idclass_t linuxdvb_satconf_class = {.ic_class = "linuxdvb_satconf", + .ic_caption = N_("DVB-S Satellite Configuration"), + .ic_event = "linuxdvb_satconf", + .ic_get_title = linuxdvb_satconf_class_get_title, + .ic_doc = tvh_doc_linuxdvb_satconf_class, + .ic_changed = linuxdvb_satconf_class_changed, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "active", + .name = N_("Active"), + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, + .get = linuxdvb_satconf_class_active_get, + }, + {.type = PT_BOOL, + .id = "early_tune", + .name = N_("Tune before DiseqC"), + .desc = N_("One tune request (setup) is sent before the " + "DiseqC sequence (voltage, tone settings). " + "Some linux drivers require this procedure."), + .off = offsetof(linuxdvb_satconf_t, ls_early_tune), + .opts = PO_ADVANCED, + .def.i = 1}, + {.type = PT_INT, + .id = "diseqc_repeats", + .name = N_("DiseqC repeats"), + .desc = N_("Number of repeats for the DiseqC commands " + "(default is zero - no DiseqC repeats). " + "Note: this represents the number of repeats, not " + "the number of requests - so 0 means 'send once: " + "don't repeat', 1 means 'send twice: send once, " + "then send one repeat', etc."), + .off = offsetof(linuxdvb_satconf_t, ls_diseqc_repeats), + .opts = PO_ADVANCED, + .def.i = 0}, + {.type = PT_BOOL, + .id = "diseqc_full", + .name = N_("Full DiseqC"), + .desc = N_("Always send the whole DiseqC sequence including " + "LNB setup (voltage, tone). If this is not " + "checked, only changed settings are sent, which " + "may cause issues with some drivers. If the tuning " + "is not reliable, try activating this option."), + .off = offsetof(linuxdvb_satconf_t, ls_diseqc_full), + .opts = PO_ADVANCED, + .def.i = 1}, + {.type = PT_BOOL, + .id = "lnb_poweroff", + .name = N_("Turn off LNB when idle"), + .desc = N_("Switch off the power to the LNB when idle. Note: " + "this may cause interference with other devices " + "when the LNB is powered back up."), + .off = offsetof(linuxdvb_satconf_t, ls_lnb_poweroff), + .opts = PO_ADVANCED, + .def.i = 1}, + {.type = PT_INT, + .id = "lnb_highvol", + .name = N_("Higher LNB voltage"), + .desc = N_("Some DVB devices have an optional ioctl that allows " + "changing between normal voltage for LNB (13V/18V) to " + "a higher voltage mode (usually, 14V/19V), meant to " + "compensate for voltage loss on long cabling. " + "Without that, it is not possible to properly switch " + "the polarization."), + .list = linuxdvb_satconf_class_highvol_list, + .off = offsetof(linuxdvb_satconf_t, ls_lnb_highvol), + .opts = PO_ADVANCED, + .def.i = 1}, + {}}}; /* * Simple LNB only */ -const idclass_t linuxdvb_satconf_lnbonly_class = -{ - .ic_super = &linuxdvb_satconf_class, - .ic_class = "linuxdvb_satconf_lnbonly", - .ic_doc = tvh_doc_linuxdvb_satconf_class, - .ic_caption = N_("TV Adapters - SatConfig - Universal LNB (Simple)"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "networks", - .name = N_("Networks"), - .desc = N_("The networks assigned to the device."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get0, - .set = linuxdvb_satconf_class_network_set0, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend0, - .opts = PO_NOSAVE, - }, - {} - } -}; +const idclass_t linuxdvb_satconf_lnbonly_class = {.ic_super = &linuxdvb_satconf_class, + .ic_class = "linuxdvb_satconf_lnbonly", + .ic_doc = tvh_doc_linuxdvb_satconf_class, + .ic_caption = N_("TV Adapters - SatConfig - Universal LNB (Simple)"), + .ic_properties = (const property_t[]){{ + .type = PT_STR, + .id = "networks", + .name = N_("Networks"), + .desc = N_("The networks assigned to the device."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get0, + .set = linuxdvb_satconf_class_network_set0, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend0, + .opts = PO_NOSAVE, + }, + {}}}; /* * 2 port switch */ -const idclass_t linuxdvb_satconf_2port_class = -{ - .ic_super = &linuxdvb_satconf_class, - .ic_class = "linuxdvb_satconf_2port", - .ic_doc = tvh_doc_linuxdvb_satconf_class, - .ic_caption = N_("TV Adapters - SatConfig - Tone Burst/2 Port"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "network_a", - .name = N_("A"), - .desc = N_("Network for port A."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get0, - .set = linuxdvb_satconf_class_network_set0, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend0, - .opts = PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "network_b", - .name = N_("B"), - .desc = N_("Network for port B."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get1, - .set = linuxdvb_satconf_class_network_set1, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend1, - .opts = PO_NOSAVE, - }, - {} - } -}; +const idclass_t linuxdvb_satconf_2port_class = {.ic_super = &linuxdvb_satconf_class, + .ic_class = "linuxdvb_satconf_2port", + .ic_doc = tvh_doc_linuxdvb_satconf_class, + .ic_caption = N_("TV Adapters - SatConfig - Tone Burst/2 Port"), + .ic_properties = (const property_t[]){{ + .type = PT_STR, + .id = "network_a", + .name = N_("A"), + .desc = N_("Network for port A."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get0, + .set = linuxdvb_satconf_class_network_set0, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend0, + .opts = PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "network_b", + .name = N_("B"), + .desc = N_("Network for port B."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get1, + .set = linuxdvb_satconf_class_network_set1, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend1, + .opts = PO_NOSAVE, + }, + {}}}; /* * 4 port switch */ -const idclass_t linuxdvb_satconf_4port_class = -{ - .ic_super = &linuxdvb_satconf_class, - .ic_class = "linuxdvb_satconf_4port", - .ic_doc = tvh_doc_linuxdvb_satconf_class, - .ic_caption = N_("TV Adapters - SatConfig - 4-Port"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "network_aa", - .name = N_("AA"), - .desc = N_("Network for port AA."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get0, - .set = linuxdvb_satconf_class_network_set0, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend0, - .opts = PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "network_ab", - .name = N_("AB"), - .desc = N_("Network for port AB."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get1, - .set = linuxdvb_satconf_class_network_set1, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend1, - .opts = PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "network_ba", - .name = N_("BA"), - .desc = N_("Network for port BA."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get2, - .set = linuxdvb_satconf_class_network_set2, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend2, - .opts = PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "network_bb", - .name = N_("BB"), - .desc = N_("Network for port BB."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get3, - .set = linuxdvb_satconf_class_network_set3, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend3, - .opts = PO_NOSAVE, - }, - {} - } -}; +const idclass_t linuxdvb_satconf_4port_class = {.ic_super = &linuxdvb_satconf_class, + .ic_class = "linuxdvb_satconf_4port", + .ic_doc = tvh_doc_linuxdvb_satconf_class, + .ic_caption = N_("TV Adapters - SatConfig - 4-Port"), + .ic_properties = (const property_t[]){{ + .type = PT_STR, + .id = "network_aa", + .name = N_("AA"), + .desc = N_("Network for port AA."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get0, + .set = linuxdvb_satconf_class_network_set0, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend0, + .opts = PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "network_ab", + .name = N_("AB"), + .desc = N_("Network for port AB."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get1, + .set = linuxdvb_satconf_class_network_set1, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend1, + .opts = PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "network_ba", + .name = N_("BA"), + .desc = N_("Network for port BA."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get2, + .set = linuxdvb_satconf_class_network_set2, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend2, + .opts = PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "network_bb", + .name = N_("BB"), + .desc = N_("Network for port BB."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get3, + .set = linuxdvb_satconf_class_network_set3, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend3, + .opts = PO_NOSAVE, + }, + {}}}; /* * Unicable (EN50494) */ -static const void * -linuxdvb_satconf_class_en50494_id_get ( void *p ) -{ - linuxdvb_satconf_t *ls = p; - linuxdvb_satconf_ele_t *lse = TAILQ_FIRST(&ls->ls_elements); +static const void* linuxdvb_satconf_class_en50494_id_get(void* p) { + linuxdvb_satconf_t* ls = p; + linuxdvb_satconf_ele_t* lse = TAILQ_FIRST(&ls->ls_elements); return &(((linuxdvb_en50494_t*)lse->lse_en50494)->le_id); } -static int -linuxdvb_satconf_class_en50494_id_set - ( void *p, const void *v ) -{ - linuxdvb_satconf_t *ls = p; - linuxdvb_satconf_ele_t *lse; - TAILQ_FOREACH(lse, &ls->ls_elements, lse_link) +static int linuxdvb_satconf_class_en50494_id_set(void* p, const void* v) { + linuxdvb_satconf_t* ls = p; + linuxdvb_satconf_ele_t* lse; + TAILQ_FOREACH (lse, &ls->ls_elements, lse_link) (((linuxdvb_en50494_t*)lse->lse_en50494)->le_id) = *(uint16_t*)v; return 1; } -static const void * -linuxdvb_satconf_class_en50494_pin_get ( void *p ) -{ - linuxdvb_satconf_t *ls = p; - linuxdvb_satconf_ele_t *lse = TAILQ_FIRST(&ls->ls_elements); +static const void* linuxdvb_satconf_class_en50494_pin_get(void* p) { + linuxdvb_satconf_t* ls = p; + linuxdvb_satconf_ele_t* lse = TAILQ_FIRST(&ls->ls_elements); return &(((linuxdvb_en50494_t*)lse->lse_en50494)->le_pin); } -static int -linuxdvb_satconf_class_en50494_pin_set - ( void *p, const void *v ) -{ - linuxdvb_satconf_t *ls = p; - linuxdvb_satconf_ele_t *lse; - TAILQ_FOREACH(lse, &ls->ls_elements, lse_link) +static int linuxdvb_satconf_class_en50494_pin_set(void* p, const void* v) { + linuxdvb_satconf_t* ls = p; + linuxdvb_satconf_ele_t* lse; + TAILQ_FOREACH (lse, &ls->ls_elements, lse_link) (((linuxdvb_en50494_t*)lse->lse_en50494)->le_pin) = *(uint16_t*)v; return 1; } -static const void * -linuxdvb_satconf_class_en50494_freq_get ( void *p ) -{ - linuxdvb_satconf_t *ls = p; - linuxdvb_satconf_ele_t *lse = TAILQ_FIRST(&ls->ls_elements); +static const void* linuxdvb_satconf_class_en50494_freq_get(void* p) { + linuxdvb_satconf_t* ls = p; + linuxdvb_satconf_ele_t* lse = TAILQ_FIRST(&ls->ls_elements); return &(((linuxdvb_en50494_t*)lse->lse_en50494)->le_frequency); } -static int -linuxdvb_satconf_class_en50494_freq_set - ( void *p, const void *v ) -{ - linuxdvb_satconf_t *ls = p; - linuxdvb_satconf_ele_t *lse; - TAILQ_FOREACH(lse, &ls->ls_elements, lse_link) +static int linuxdvb_satconf_class_en50494_freq_set(void* p, const void* v) { + linuxdvb_satconf_t* ls = p; + linuxdvb_satconf_ele_t* lse; + TAILQ_FOREACH (lse, &ls->ls_elements, lse_link) (((linuxdvb_en50494_t*)lse->lse_en50494)->le_frequency) = *(uint16_t*)v; return 1; } -const idclass_t linuxdvb_satconf_en50494_class = -{ - .ic_super = &linuxdvb_satconf_class, - .ic_class = "linuxdvb_satconf_en50494", - .ic_doc = tvh_doc_linuxdvb_satconf_class, - .ic_caption = N_("TV Adapters - SatConfig - EN50494/UniCable I"), - .ic_properties = (const property_t[]) { - { - .type = PT_U16, - .id = "id", - .name = N_("SCR (ID)"), - .desc = N_("SCR (Satellite Channel Router) ID."), - .get = linuxdvb_satconf_class_en50494_id_get, - .set = linuxdvb_satconf_class_en50494_id_set, - .list = linuxdvb_en50494_id_list, - .opts = PO_NOSAVE, - }, - { - .type = PT_U16, - .id = "frequency", - .name = N_("Frequency (MHz)"), - .desc = N_("User Band Frequency (in MHz)."), - .get = linuxdvb_satconf_class_en50494_freq_get, - .set = linuxdvb_satconf_class_en50494_freq_set, - .opts = PO_NOSAVE, - }, - { - .type = PT_U16, - .id = "pin", - .name = N_("PIN"), - .desc = N_("PIN."), - .get = linuxdvb_satconf_class_en50494_pin_get, - .set = linuxdvb_satconf_class_en50494_pin_set, - .list = linuxdvb_en50494_pin_list, - .opts = PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "network_a", - .name = N_("Network A"), - .desc = N_("Network for port A."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get0, - .set = linuxdvb_satconf_class_network_set0, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend0, - .opts = PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "network_b", - .name = N_("Network B"), - .desc = N_("Network for port B."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get1, - .set = linuxdvb_satconf_class_network_set1, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend1, - .opts = PO_NOSAVE, - }, - {} - } -}; - -const idclass_t linuxdvb_satconf_en50607_class = -{ - .ic_super = &linuxdvb_satconf_class, - .ic_class = "linuxdvb_satconf_en50607", - .ic_doc = tvh_doc_linuxdvb_satconf_class, - .ic_caption = N_("TV Adapters - SatConfig - EN50607/UniCable II"), - .ic_properties = (const property_t[]) { - { - .type = PT_U16, - .id = "id", - .name = N_("SCR (ID)"), - .desc = N_("SCR (Satellite Channel Router) ID."), - .get = linuxdvb_satconf_class_en50494_id_get, - .set = linuxdvb_satconf_class_en50494_id_set, - .list = linuxdvb_en50607_id_list, - .opts = PO_NOSAVE, - }, - { - .type = PT_U16, - .id = "frequency", - .name = N_("Frequency (MHz)"), - .desc = N_("User Band Frequency (in MHz)."), - .get = linuxdvb_satconf_class_en50494_freq_get, - .set = linuxdvb_satconf_class_en50494_freq_set, - .opts = PO_NOSAVE, - }, - { - .type = PT_U16, - .id = "pin", - .name = N_("PIN"), - .desc = N_("PIN."), - .get = linuxdvb_satconf_class_en50494_pin_get, - .set = linuxdvb_satconf_class_en50494_pin_set, - .list = linuxdvb_en50494_pin_list, - .opts = PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "network_a", - .name = N_("Network A"), - .desc = N_("Network for port A."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get0, - .set = linuxdvb_satconf_class_network_set0, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend0, - .opts = PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "network_b", - .name = N_("Network B"), - .desc = N_("Network for port B."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get1, - .set = linuxdvb_satconf_class_network_set1, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend1, - .opts = PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "network_c", - .name = N_("Network C"), - .desc = N_("Network for port C."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get2, - .set = linuxdvb_satconf_class_network_set2, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend2, - .opts = PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "network_d", - .name = N_("Network D"), - .desc = N_("Network for port D."), - .islist = 1, - .get = linuxdvb_satconf_class_network_get3, - .set = linuxdvb_satconf_class_network_set3, - .list = linuxdvb_satconf_class_network_enum, - .rend = linuxdvb_satconf_class_network_rend3, - .opts = PO_NOSAVE, - }, - {} - } -}; +const idclass_t linuxdvb_satconf_en50494_class = {.ic_super = &linuxdvb_satconf_class, + .ic_class = "linuxdvb_satconf_en50494", + .ic_doc = tvh_doc_linuxdvb_satconf_class, + .ic_caption = N_("TV Adapters - SatConfig - EN50494/UniCable I"), + .ic_properties = (const property_t[]){{ + .type = PT_U16, + .id = "id", + .name = N_("SCR (ID)"), + .desc = N_("SCR (Satellite Channel Router) ID."), + .get = linuxdvb_satconf_class_en50494_id_get, + .set = linuxdvb_satconf_class_en50494_id_set, + .list = linuxdvb_en50494_id_list, + .opts = PO_NOSAVE, + }, + { + .type = PT_U16, + .id = "frequency", + .name = N_("Frequency (MHz)"), + .desc = N_("User Band Frequency (in MHz)."), + .get = linuxdvb_satconf_class_en50494_freq_get, + .set = linuxdvb_satconf_class_en50494_freq_set, + .opts = PO_NOSAVE, + }, + { + .type = PT_U16, + .id = "pin", + .name = N_("PIN"), + .desc = N_("PIN."), + .get = linuxdvb_satconf_class_en50494_pin_get, + .set = linuxdvb_satconf_class_en50494_pin_set, + .list = linuxdvb_en50494_pin_list, + .opts = PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "network_a", + .name = N_("Network A"), + .desc = N_("Network for port A."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get0, + .set = linuxdvb_satconf_class_network_set0, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend0, + .opts = PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "network_b", + .name = N_("Network B"), + .desc = N_("Network for port B."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get1, + .set = linuxdvb_satconf_class_network_set1, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend1, + .opts = PO_NOSAVE, + }, + {}}}; + +const idclass_t linuxdvb_satconf_en50607_class = {.ic_super = &linuxdvb_satconf_class, + .ic_class = "linuxdvb_satconf_en50607", + .ic_doc = tvh_doc_linuxdvb_satconf_class, + .ic_caption = N_("TV Adapters - SatConfig - EN50607/UniCable II"), + .ic_properties = (const property_t[]){{ + .type = PT_U16, + .id = "id", + .name = N_("SCR (ID)"), + .desc = N_("SCR (Satellite Channel Router) ID."), + .get = linuxdvb_satconf_class_en50494_id_get, + .set = linuxdvb_satconf_class_en50494_id_set, + .list = linuxdvb_en50607_id_list, + .opts = PO_NOSAVE, + }, + { + .type = PT_U16, + .id = "frequency", + .name = N_("Frequency (MHz)"), + .desc = N_("User Band Frequency (in MHz)."), + .get = linuxdvb_satconf_class_en50494_freq_get, + .set = linuxdvb_satconf_class_en50494_freq_set, + .opts = PO_NOSAVE, + }, + { + .type = PT_U16, + .id = "pin", + .name = N_("PIN"), + .desc = N_("PIN."), + .get = linuxdvb_satconf_class_en50494_pin_get, + .set = linuxdvb_satconf_class_en50494_pin_set, + .list = linuxdvb_en50494_pin_list, + .opts = PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "network_a", + .name = N_("Network A"), + .desc = N_("Network for port A."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get0, + .set = linuxdvb_satconf_class_network_set0, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend0, + .opts = PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "network_b", + .name = N_("Network B"), + .desc = N_("Network for port B."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get1, + .set = linuxdvb_satconf_class_network_set1, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend1, + .opts = PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "network_c", + .name = N_("Network C"), + .desc = N_("Network for port C."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get2, + .set = linuxdvb_satconf_class_network_set2, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend2, + .opts = PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "network_d", + .name = N_("Network D"), + .desc = N_("Network for port D."), + .islist = 1, + .get = linuxdvb_satconf_class_network_get3, + .set = linuxdvb_satconf_class_network_set3, + .list = linuxdvb_satconf_class_network_enum, + .rend = linuxdvb_satconf_class_network_rend3, + .opts = PO_NOSAVE, + }, + {}}}; /* * Advanced */ -const idclass_t linuxdvb_satconf_advanced_class = -{ - .ic_super = &linuxdvb_satconf_class, - .ic_class = "linuxdvb_satconf_advanced", - .ic_doc = tvh_doc_linuxdvb_satconf_class, - .ic_caption = N_("TV Adapters - SatConfig - Advanced"), - .ic_get_childs = linuxdvb_satconf_class_get_childs, - .ic_properties = (const property_t[]) { - { - .type = PT_INT, - .id = "orbital_pos", - .name = N_("Orbital positions"), - .desc = N_("Orbital positions."), - .get = linuxdvb_satconf_class_orbitalpos_get, - .set = linuxdvb_satconf_class_orbitalpos_set, - }, - { - .type = PT_BOOL, - .id = "switch_rotor", - .name = N_("Switch before rotor"), - .desc = N_("If the DiseqC switch is located before the rotor " - "(i.e. tuner - switch - rotor), enable this."), - .off = offsetof(linuxdvb_satconf_t, ls_switch_rotor), - .opts = PO_ADVANCED, - }, - { - .type = PT_U32, - .id = "max_rotor_move", - .name = N_("Rotor initialization time (seconds)"), - .desc = N_("Upon start, Tvheadend doesn't know the last rotor " - "position. This value defines the initial rotor " - "movement. TVHeadend waits the specified time when " - "the first movement is requested."), - .off = offsetof(linuxdvb_satconf_t, ls_max_rotor_move), - .opts = PO_ADVANCED, - .def.u32 = 120 - }, - { - .type = PT_U32, - .id = "min_rotor_move", - .name = N_("Minimum rotor time (seconds)"), - .desc = N_("The minimum delay after the rotor movement " - "command is sent."), - .off = offsetof(linuxdvb_satconf_t, ls_min_rotor_move), - .opts = PO_ADVANCED, - }, - { - .type = PT_DBL, - .id = "site_lat", - .name = N_("Site latitude"), - .desc = N_("Site latitude."), - .off = offsetof(linuxdvb_satconf_t, ls_site_lat), - .opts = PO_ADVANCED, - }, +const idclass_t linuxdvb_satconf_advanced_class = {.ic_super = &linuxdvb_satconf_class, + .ic_class = "linuxdvb_satconf_advanced", + .ic_doc = tvh_doc_linuxdvb_satconf_class, + .ic_caption = N_("TV Adapters - SatConfig - Advanced"), + .ic_get_childs = linuxdvb_satconf_class_get_childs, + .ic_properties = (const property_t[]){{ + .type = PT_INT, + .id = "orbital_pos", + .name = N_("Orbital positions"), + .desc = N_("Orbital positions."), + .get = linuxdvb_satconf_class_orbitalpos_get, + .set = linuxdvb_satconf_class_orbitalpos_set, + }, + { + .type = PT_BOOL, + .id = "switch_rotor", + .name = N_("Switch before rotor"), + .desc = N_("If the DiseqC switch is located before the rotor " + "(i.e. tuner - switch - rotor), enable this."), + .off = offsetof(linuxdvb_satconf_t, ls_switch_rotor), + .opts = PO_ADVANCED, + }, + {.type = PT_U32, + .id = "max_rotor_move", + .name = N_("Rotor initialization time (seconds)"), + .desc = N_("Upon start, Tvheadend doesn't know the last rotor " + "position. This value defines the initial rotor " + "movement. TVHeadend waits the specified time when " + "the first movement is requested."), + .off = offsetof(linuxdvb_satconf_t, ls_max_rotor_move), + .opts = PO_ADVANCED, + .def.u32 = 120}, + { + .type = PT_U32, + .id = "min_rotor_move", + .name = N_("Minimum rotor time (seconds)"), + .desc = N_("The minimum delay after the rotor movement " + "command is sent."), + .off = offsetof(linuxdvb_satconf_t, ls_min_rotor_move), + .opts = PO_ADVANCED, + }, + { + .type = PT_DBL, + .id = "site_lat", + .name = N_("Site latitude"), + .desc = N_("Site latitude."), + .off = offsetof(linuxdvb_satconf_t, ls_site_lat), + .opts = PO_ADVANCED, + }, + { + .type = PT_DBL, + .id = "site_lon", + .name = N_("Site longitude"), + .desc = N_("Site longitude."), + .off = offsetof(linuxdvb_satconf_t, ls_site_lon), + .opts = PO_ADVANCED, + }, + {.type = PT_BOOL, + .id = "site_lat_south", + .name = N_("Southern hemisphere (latitude direction)"), + .desc = N_("Southern hemisphere (latitude direction)."), + .off = offsetof(linuxdvb_satconf_t, ls_site_lat_south), + .opts = PO_ADVANCED, + .def.i = 0}, + {.type = PT_BOOL, + .id = "site_lon_west", + .name = N_("Western hemisphere (latitude direction)"), + .desc = N_("Western hemisphere (latitude direction)."), + .off = offsetof(linuxdvb_satconf_t, ls_site_lon_west), + .opts = PO_ADVANCED, + .def.i = 0}, + {.type = PT_INT, + .id = "site_altitude", + .name = N_("Altitude (meters)"), + .desc = N_("Altitude (in meters)."), + .off = offsetof(linuxdvb_satconf_t, ls_site_altitude), + .opts = PO_ADVANCED, + .def.i = 0}, + {.type = PT_STR, + .id = "external_cmd", + .name = N_("External rotor command"), + .desc = N_("Command to move the dish with an external command."), + .off = offsetof(linuxdvb_satconf_t, ls_rotor_extcmd), + .opts = PO_ADVANCED, + .def.i = 0}, + { + .type = PT_U32, + .id = "motor_rate", + .name = N_("Motor rate (milliseconds/deg)"), + .desc = N_("Motor rate (in milliseconds/deg)."), + .off = offsetof(linuxdvb_satconf_t, ls_motor_rate), + }, + {}}}; + +/* ************************************************************************** + * Types + * *************************************************************************/ + +/* Types/classes */ +static struct linuxdvb_satconf_type linuxdvb_satconf_types[] = { { - .type = PT_DBL, - .id = "site_lon", - .name = N_("Site longitude"), - .desc = N_("Site longitude."), - .off = offsetof(linuxdvb_satconf_t, ls_site_lon), - .opts = PO_ADVANCED, + .type = "simple", + .name = N_("Universal LNB only"), + .idc = &linuxdvb_satconf_lnbonly_class, + .ports = 1, + .enable = 1, }, { - .type = PT_BOOL, - .id = "site_lat_south", - .name = N_("Southern hemisphere (latitude direction)"), - .desc = N_("Southern hemisphere (latitude direction)."), - .off = offsetof(linuxdvb_satconf_t, ls_site_lat_south), - .opts = PO_ADVANCED, - .def.i = 0 + .type = "2port", + .name = N_("2-Port switch (universal LNB)"), + .idc = &linuxdvb_satconf_2port_class, + .ports = 2, + .enable = 1, }, { - .type = PT_BOOL, - .id = "site_lon_west", - .name = N_("Western hemisphere (latitude direction)"), - .desc = N_("Western hemisphere (latitude direction)."), - .off = offsetof(linuxdvb_satconf_t, ls_site_lon_west), - .opts = PO_ADVANCED, - .def.i = 0 + .type = "4port", + .name = N_("4-Port switch (universal LNB)"), + .idc = &linuxdvb_satconf_4port_class, + .ports = 4, + .enable = 1, }, { - .type = PT_INT, - .id = "site_altitude", - .name = N_("Altitude (meters)"), - .desc = N_("Altitude (in meters)."), - .off = offsetof(linuxdvb_satconf_t, ls_site_altitude), - .opts = PO_ADVANCED, - .def.i = 0 + .type = "en50494", + .name = N_("Unicable I switch (universal LNB)"), + .idc = &linuxdvb_satconf_en50494_class, + .ports = 2, + .enable = 1, }, { - .type = PT_STR, - .id = "external_cmd", - .name = N_("External rotor command"), - .desc = N_("Command to move the dish with an external command."), - .off = offsetof(linuxdvb_satconf_t, ls_rotor_extcmd), - .opts = PO_ADVANCED, - .def.i = 0 + .type = "en50607", + .name = N_("Unicable II switch (universal LNB)"), + .idc = &linuxdvb_satconf_en50607_class, + .ports = 4, + .enable = 1, }, { - .type = PT_U32, - .id = "motor_rate", - .name = N_("Motor rate (milliseconds/deg)"), - .desc = N_("Motor rate (in milliseconds/deg)."), - .off = offsetof(linuxdvb_satconf_t, ls_motor_rate), + .type = "advanced", + .name = N_("Advanced (non-universal LNBs, rotors, etc.)"), + .idc = &linuxdvb_satconf_advanced_class, + .ports = 0, + .enable = 0, }, - {} - } -}; - - -/* ************************************************************************** - * Types - * *************************************************************************/ - -/* Types/classes */ -static struct linuxdvb_satconf_type linuxdvb_satconf_types[] = { - { - .type = "simple", - .name = N_("Universal LNB only"), - .idc = &linuxdvb_satconf_lnbonly_class, - .ports = 1, - .enable = 1, - }, - { - .type = "2port", - .name = N_("2-Port switch (universal LNB)"), - .idc = &linuxdvb_satconf_2port_class, - .ports = 2, - .enable = 1, - }, - { - .type = "4port", - .name = N_("4-Port switch (universal LNB)"), - .idc = &linuxdvb_satconf_4port_class, - .ports = 4, - .enable = 1, - }, - { - .type = "en50494", - .name = N_("Unicable I switch (universal LNB)"), - .idc = &linuxdvb_satconf_en50494_class, - .ports = 2, - .enable = 1, - }, - { - .type = "en50607", - .name = N_("Unicable II switch (universal LNB)"), - .idc = &linuxdvb_satconf_en50607_class, - .ports = 4, - .enable = 1, - }, - { - .type = "advanced", - .name = N_("Advanced (non-universal LNBs, rotors, etc.)"), - .idc = &linuxdvb_satconf_advanced_class, - .ports = 0, - .enable = 0, - }, }; /* Find type (with default) */ -static struct linuxdvb_satconf_type * -linuxdvb_satconf_type_find ( const char *type ) -{ +static struct linuxdvb_satconf_type* linuxdvb_satconf_type_find(const char* type) { int i; for (i = 0; i < ARRAY_SIZE(linuxdvb_satconf_types); i++) if (!strcmp(type ?: "", linuxdvb_satconf_types[i].type)) - return linuxdvb_satconf_types+i; + return linuxdvb_satconf_types + i; return linuxdvb_satconf_types; } /* List of types */ -htsmsg_t * -linuxdvb_satconf_type_list ( void *p, const char *lang ) -{ - int i; +htsmsg_t* linuxdvb_satconf_type_list(void* p, const char* lang) { + int i; htsmsg_t *e, *m = htsmsg_create_list(); for (i = 0; i < ARRAY_SIZE(linuxdvb_satconf_types); i++) { e = htsmsg_create_map(); @@ -857,36 +745,26 @@ linuxdvb_satconf_type_list ( void *p, const char *lang ) * Frontend callbacks */ -static linuxdvb_satconf_ele_t * -linuxdvb_satconf_find_ele( linuxdvb_satconf_t *ls, mpegts_mux_t *mux ) -{ - linuxdvb_satconf_ele_t *lse; - TAILQ_FOREACH(lse, &ls->ls_elements, lse_link) { +static linuxdvb_satconf_ele_t* linuxdvb_satconf_find_ele(linuxdvb_satconf_t* ls, + mpegts_mux_t* mux) { + linuxdvb_satconf_ele_t* lse; + TAILQ_FOREACH (lse, &ls->ls_elements, lse_link) { if (idnode_set_exists(lse->lse_networks, &mux->mm_network->mn_id)) return lse; } return NULL; } -int -linuxdvb_satconf_get_priority - ( linuxdvb_satconf_t *ls, mpegts_mux_t *mm ) -{ - linuxdvb_satconf_ele_t *lse = linuxdvb_satconf_find_ele(ls, mm); +int linuxdvb_satconf_get_priority(linuxdvb_satconf_t* ls, mpegts_mux_t* mm) { + linuxdvb_satconf_ele_t* lse = linuxdvb_satconf_find_ele(ls, mm); return lse ? lse->lse_priority : 0; } -void -linuxdvb_satconf_post_stop_mux - ( linuxdvb_satconf_t *ls ) -{ +void linuxdvb_satconf_post_stop_mux(linuxdvb_satconf_t* ls) { ls->ls_mmi = NULL; } -int -linuxdvb_satconf_power_save - ( linuxdvb_satconf_t *ls ) -{ +int linuxdvb_satconf_power_save(linuxdvb_satconf_t* ls) { if (ls->ls_active_diseqc) /* wait for the timer to finish things */ return 1; mtimer_disarm(&ls->ls_diseqc_timer); @@ -897,21 +775,16 @@ linuxdvb_satconf_power_save return 0; } -int -linuxdvb_satconf_get_grace - ( linuxdvb_satconf_t *ls, mpegts_mux_t *mm ) -{ - linuxdvb_satconf_ele_t *lse = linuxdvb_satconf_find_ele(ls, mm); +int linuxdvb_satconf_get_grace(linuxdvb_satconf_t* ls, mpegts_mux_t* mm) { + linuxdvb_satconf_ele_t* lse = linuxdvb_satconf_find_ele(ls, mm); if (lse == NULL) return 0; - int i, r = 10; - linuxdvb_diseqc_t *lds[] = { - (linuxdvb_diseqc_t*)lse->lse_en50494, - (linuxdvb_diseqc_t*)lse->lse_switch, - (linuxdvb_diseqc_t*)lse->lse_rotor, - (linuxdvb_diseqc_t*)lse->lse_lnb - }; + int i, r = 10; + linuxdvb_diseqc_t* lds[] = {(linuxdvb_diseqc_t*)lse->lse_en50494, + (linuxdvb_diseqc_t*)lse->lse_switch, + (linuxdvb_diseqc_t*)lse->lse_rotor, + (linuxdvb_diseqc_t*)lse->lse_lnb}; /* Add diseqc delay */ for (i = 0; i < 3; i++) { @@ -922,9 +795,7 @@ linuxdvb_satconf_get_grace return r; } -int -linuxdvb_satconf_start ( linuxdvb_satconf_t *ls, int delay, int vol ) -{ +int linuxdvb_satconf_start(linuxdvb_satconf_t* ls, int delay, int vol) { if (vol >= 0 && linuxdvb_diseqc_set_volt(ls, vol)) return -1; @@ -939,22 +810,20 @@ linuxdvb_satconf_start ( linuxdvb_satconf_t *ls, int delay, int vol ) /* the linuxdvb_diseqc_set_volt() fcn already sleeps for 15ms */ if (delay > 15) { tvhtrace(LS_DISEQC, "initial sleep %dms", delay); - tvh_safe_usleep((delay-15)*1000); + tvh_safe_usleep((delay - 15) * 1000); } return 0; } -static void linuxdvb_satconf_ele_tune_cb ( void *o ); +static void linuxdvb_satconf_ele_tune_cb(void* o); -static int -linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) -{ - int r, i, vol, pol, band, freq; - uint32_t f; - linuxdvb_satconf_t *ls = lse->lse_parent; +static int linuxdvb_satconf_ele_tune(linuxdvb_satconf_ele_t* lse) { + int r, i, vol, pol, band, freq; + uint32_t f; + linuxdvb_satconf_t* ls = lse->lse_parent; /* Get beans in a row */ - mpegts_mux_instance_t *mmi = ls->ls_mmi; + mpegts_mux_instance_t* mmi = ls->ls_mmi; if (mmi == NULL && ls->ls_active_diseqc) { /* handle the rotor position update */ @@ -965,19 +834,17 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) return 0; } - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend; - dvb_mux_t *lm = (dvb_mux_t*)mmi->mmi_mux; - linuxdvb_diseqc_t *lds[] = { - ls->ls_switch_rotor ? (linuxdvb_diseqc_t*)lse->lse_switch : - (linuxdvb_diseqc_t*)lse->lse_rotor, - ls->ls_switch_rotor ? (linuxdvb_diseqc_t*)lse->lse_rotor : - (linuxdvb_diseqc_t*)lse->lse_switch, - (linuxdvb_diseqc_t*)lse->lse_en50494, - (linuxdvb_diseqc_t*)lse->lse_lnb - }; + linuxdvb_frontend_t* lfe = (linuxdvb_frontend_t*)ls->ls_frontend; + dvb_mux_t* lm = (dvb_mux_t*)mmi->mmi_mux; + linuxdvb_diseqc_t* lds[] = {ls->ls_switch_rotor ? (linuxdvb_diseqc_t*)lse->lse_switch + : (linuxdvb_diseqc_t*)lse->lse_rotor, + ls->ls_switch_rotor ? (linuxdvb_diseqc_t*)lse->lse_rotor + : (linuxdvb_diseqc_t*)lse->lse_switch, + (linuxdvb_diseqc_t*)lse->lse_en50494, + (linuxdvb_diseqc_t*)lse->lse_lnb}; if (lse->lse_lnb) { - pol = lse->lse_lnb->lnb_pol (lse->lse_lnb, lm) & 0x1; + pol = lse->lse_lnb->lnb_pol(lse->lse_lnb, lm) & 0x1; band = lse->lse_lnb->lnb_band(lse->lse_lnb, lm) & 0x1; freq = lse->lse_lnb->lnb_freq(lse->lse_lnb, lm); } else { @@ -987,7 +854,7 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) if (!lse->lse_en50494) { vol = pol; } else { - vol = 0; /* 13V */ + vol = 0; /* 13V */ } /* @@ -1005,14 +872,16 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) } } - /* Diseqc */ + /* Diseqc */ ls->ls_active_diseqc = NULL; for (i = ls->ls_diseqc_idx; i < ARRAY_SIZE(lds); i++) { - if (!lds[i]) continue; + if (!lds[i]) + continue; r = lds[i]->ld_tune(lds[i], lm, ls, lse, vol, pol, band, freq); /* Error */ - if (r < 0) return r; + if (r < 0) + return r; /* Pending */ if (r != 0) { @@ -1051,26 +920,19 @@ linuxdvb_satconf_ele_tune ( linuxdvb_satconf_ele_t *lse ) /* Frontend */ /* use en50494 tuning frequency, if needed (not channel frequency) */ - f = lse->lse_en50494 - ? ((linuxdvb_en50494_t*)lse->lse_en50494)->le_tune_freq - : freq; + f = lse->lse_en50494 ? ((linuxdvb_en50494_t*)lse->lse_en50494)->le_tune_freq : freq; return linuxdvb_frontend_tune1(lfe, mmi, f); } -static void -linuxdvb_satconf_ele_tune_cb ( void *o ) -{ +static void linuxdvb_satconf_ele_tune_cb(void* o) { (void)linuxdvb_satconf_ele_tune(o); // TODO: how to signal error } -int -linuxdvb_satconf_lnb_freq - ( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi ) -{ - int f; - linuxdvb_satconf_ele_t *lse = linuxdvb_satconf_find_ele(ls, mmi->mmi_mux); - dvb_mux_t *lm = (dvb_mux_t*)mmi->mmi_mux; +int linuxdvb_satconf_lnb_freq(linuxdvb_satconf_t* ls, mpegts_mux_instance_t* mmi) { + int f; + linuxdvb_satconf_ele_t* lse = linuxdvb_satconf_find_ele(ls, mmi->mmi_mux); + dvb_mux_t* lm = (dvb_mux_t*)mmi->mmi_mux; if (!lse->lse_lnb) return -1; @@ -1090,16 +952,16 @@ linuxdvb_satconf_lnb_freq return f; } -int -linuxdvb_satconf_start_mux - ( linuxdvb_satconf_t *ls, mpegts_mux_instance_t *mmi, int skip_diseqc ) -{ - int r, f; - linuxdvb_satconf_ele_t *lse = linuxdvb_satconf_find_ele(ls, mmi->mmi_mux); - linuxdvb_frontend_t *lfe = (linuxdvb_frontend_t*)ls->ls_frontend; +int linuxdvb_satconf_start_mux(linuxdvb_satconf_t* ls, + mpegts_mux_instance_t* mmi, + int skip_diseqc) { + int r, f; + linuxdvb_satconf_ele_t* lse = linuxdvb_satconf_find_ele(ls, mmi->mmi_mux); + linuxdvb_frontend_t* lfe = (linuxdvb_frontend_t*)ls->ls_frontend; /* Not fully configured */ - if (!lse) return SM_CODE_TUNING_FAILED; + if (!lse) + return SM_CODE_TUNING_FAILED; /* Test run */ // Note: basically this ensures the tuning params are acceptable @@ -1120,18 +982,20 @@ linuxdvb_satconf_start_mux if (f < 0) return SM_CODE_TUNING_FAILED; r = linuxdvb_frontend_tune0(lfe, mmi, f); - if (r) return r; + if (r) + return r; } else { /* Clear the frontend settings, open frontend fd */ r = linuxdvb_frontend_clear(lfe, mmi); - if (r) return r; + if (r) + return r; } /* Diseqc */ ls->ls_mmi = mmi; ls->ls_diseqc_idx = 0; if (lse->lse_rotor) - if (lse->lse_rotor->ld_start(lse->lse_rotor, (dvb_mux_t *)mmi->mmi_mux, ls, lse)) + if (lse->lse_rotor->ld_start(lse->lse_rotor, (dvb_mux_t*)mmi->mmi_mux, ls, lse)) return 0; return linuxdvb_satconf_ele_tune(lse); @@ -1140,33 +1004,27 @@ linuxdvb_satconf_start_mux /* * */ -void -linuxdvb_satconf_reset - ( linuxdvb_satconf_t *ls ) -{ - ls->ls_last_switch = NULL; - ls->ls_last_vol = 0; +void linuxdvb_satconf_reset(linuxdvb_satconf_t* ls) { + ls->ls_last_switch = NULL; + ls->ls_last_vol = 0; ls->ls_last_toneburst = 0; - ls->ls_last_tone_off = 0; + ls->ls_last_tone_off = 0; } /* * return 0 if passed mux cannot be used simultanously with given * diseqc config */ -int -linuxdvb_satconf_match_mux - ( linuxdvb_satconf_t *ls, mpegts_mux_t *mm ) -{ - mpegts_mux_instance_t *mmi = ls->ls_mmi; +int linuxdvb_satconf_match_mux(linuxdvb_satconf_t* ls, mpegts_mux_t* mm) { + mpegts_mux_instance_t* mmi = ls->ls_mmi; if (mmi == NULL || mmi->mmi_mux == NULL) return 1; - linuxdvb_satconf_ele_t *lse1 = linuxdvb_satconf_find_ele(ls, mm); - linuxdvb_satconf_ele_t *lse2 = linuxdvb_satconf_find_ele(ls, mmi->mmi_mux); - dvb_mux_t *lm1 = (dvb_mux_t*)mmi->mmi_mux; - dvb_mux_t *lm2 = (dvb_mux_t*)mm; + linuxdvb_satconf_ele_t* lse1 = linuxdvb_satconf_find_ele(ls, mm); + linuxdvb_satconf_ele_t* lse2 = linuxdvb_satconf_find_ele(ls, mmi->mmi_mux); + dvb_mux_t* lm1 = (dvb_mux_t*)mmi->mmi_mux; + dvb_mux_t* lm2 = (dvb_mux_t*)mm; #if ENABLE_TRACE char buf1[256], buf2[256]; @@ -1195,16 +1053,13 @@ linuxdvb_satconf_match_mux * Create/Delete satconf * *************************************************************************/ -linuxdvb_satconf_t * -linuxdvb_satconf_create - ( linuxdvb_frontend_t *lfe, htsmsg_t *conf ) -{ - int i; - htsmsg_t *l, *e; - htsmsg_field_t *f; - linuxdvb_satconf_ele_t *lse; - const char *str, *type = NULL, *uuid = NULL; - struct linuxdvb_satconf_type *lst; +linuxdvb_satconf_t* linuxdvb_satconf_create(linuxdvb_frontend_t* lfe, htsmsg_t* conf) { + int i; + htsmsg_t * l, *e; + htsmsg_field_t* f; + linuxdvb_satconf_ele_t* lse; + const char * str, *type = NULL, *uuid = NULL; + struct linuxdvb_satconf_type* lst; if (conf) { type = htsmsg_get_str(conf, "type"); @@ -1213,14 +1068,14 @@ linuxdvb_satconf_create lst = linuxdvb_satconf_type_find(type); assert(lst); - - linuxdvb_satconf_t *ls = calloc(1, sizeof(linuxdvb_satconf_t)); - ls->ls_frontend = (mpegts_input_t*)lfe; - ls->ls_type = lst->type; + + linuxdvb_satconf_t* ls = calloc(1, sizeof(linuxdvb_satconf_t)); + ls->ls_frontend = (mpegts_input_t*)lfe; + ls->ls_type = lst->type; TAILQ_INIT(&ls->ls_elements); - ls->ls_early_tune = 1; - ls->ls_diseqc_full = 1; + ls->ls_early_tune = 1; + ls->ls_diseqc_full = 1; ls->ls_max_rotor_move = 120; /* Create node */ @@ -1237,12 +1092,12 @@ linuxdvb_satconf_create // will result in extra elements if ((l = htsmsg_get_list(conf, "elements"))) { HTSMSG_FOREACH(f, l) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; /* Fix config */ - if ((str = htsmsg_get_str(e, "network")) && - !htsmsg_get_list(e, "networks")) { - htsmsg_t *l = htsmsg_create_list(); + if ((str = htsmsg_get_str(e, "network")) && !htsmsg_get_list(e, "networks")) { + htsmsg_t* l = htsmsg_create_list(); htsmsg_add_str(l, NULL, str); htsmsg_add_msg(e, "networks", l); } @@ -1251,11 +1106,11 @@ linuxdvb_satconf_create lse = linuxdvb_satconf_ele_create0(htsmsg_get_str(e, "uuid"), e, ls); } } - + /* Load node */ idnode_load(&ls->ls_id, conf); } - + /* Create elements */ lse = TAILQ_FIRST(&ls->ls_elements); for (i = 0; i < lst->ports; i++) { @@ -1283,16 +1138,14 @@ linuxdvb_satconf_create return ls; } -void -linuxdvb_satconf_save ( linuxdvb_satconf_t *ls, htsmsg_t *m ) -{ - linuxdvb_satconf_ele_t *lse; - htsmsg_t *l, *e, *c; - char ubuf[UUID_HEX_SIZE]; +void linuxdvb_satconf_save(linuxdvb_satconf_t* ls, htsmsg_t* m) { + linuxdvb_satconf_ele_t* lse; + htsmsg_t * l, *e, *c; + char ubuf[UUID_HEX_SIZE]; htsmsg_add_str(m, "type", ls->ls_type); idnode_save(&ls->ls_id, m); l = htsmsg_create_list(); - TAILQ_FOREACH(lse, &ls->ls_elements, lse_link){ + TAILQ_FOREACH (lse, &ls->ls_elements, lse_link) { e = htsmsg_create_map(); idnode_save(&lse->lse_id, e); htsmsg_add_str(e, "uuid", idnode_uuid_as_str(&lse->lse_id, ubuf)); @@ -1327,28 +1180,26 @@ linuxdvb_satconf_save ( linuxdvb_satconf_t *ls, htsmsg_t *m ) extern const idclass_t mpegts_input_class; -static const void * -linuxdvb_satconf_ele_class_network_get( void *o ) -{ - linuxdvb_satconf_ele_t *ls = o; +static const void* linuxdvb_satconf_ele_class_network_get(void* o) { + linuxdvb_satconf_ele_t* ls = o; return idnode_set_as_htsmsg(ls->lse_networks); } -static int -linuxdvb_satconf_ele_class_network_set( void *o, const void *p ) -{ - linuxdvb_satconf_ele_t *ls = o; - const htsmsg_t *msg = p; - mpegts_network_t *mn; - idnode_set_t *n = idnode_set_create(0); - htsmsg_field_t *f; - const char *str; - int i, save; - char ubuf[UUID_HEX_SIZE]; +static int linuxdvb_satconf_ele_class_network_set(void* o, const void* p) { + linuxdvb_satconf_ele_t* ls = o; + const htsmsg_t* msg = p; + mpegts_network_t* mn; + idnode_set_t* n = idnode_set_create(0); + htsmsg_field_t* f; + const char* str; + int i, save; + char ubuf[UUID_HEX_SIZE]; HTSMSG_FOREACH(f, msg) { - if (!(str = htsmsg_field_get_str(f))) continue; - if (!(mn = mpegts_network_find(str))) continue; + if (!(str = htsmsg_field_get_str(f))) + continue; + if (!(mn = mpegts_network_find(str))) + continue; idnode_set_add(n, &mn->mn_id, NULL, NULL); } @@ -1365,14 +1216,14 @@ linuxdvb_satconf_ele_class_network_set( void *o, const void *p ) idnode_set_free(ls->lse_networks); ls->lse_networks = n; /* update the input (frontend) network list */ - htsmsg_t *l = htsmsg_create_list(); - linuxdvb_satconf_t *sc = ls->lse_parent; - linuxdvb_satconf_ele_t *lse; - TAILQ_FOREACH(lse, &sc->ls_elements, lse_link) { + htsmsg_t* l = htsmsg_create_list(); + linuxdvb_satconf_t* sc = ls->lse_parent; + linuxdvb_satconf_ele_t* lse; + TAILQ_FOREACH (lse, &sc->ls_elements, lse_link) { for (i = 0; i < lse->lse_networks->is_count; i++) { - if (!lse->lse_enabled) continue; - htsmsg_add_str(l, NULL, - idnode_uuid_as_str(lse->lse_networks->is_array[i], ubuf)); + if (!lse->lse_enabled) + continue; + htsmsg_add_str(l, NULL, idnode_uuid_as_str(lse->lse_networks->is_array[i], ubuf)); } } mpegts_input_class_network_set(ls->lse_parent->ls_frontend, l); @@ -1383,49 +1234,41 @@ linuxdvb_satconf_ele_class_network_set( void *o, const void *p ) return save; } -static htsmsg_t * -linuxdvb_satconf_ele_class_network_enum( void *o, const char *lang ) -{ - linuxdvb_satconf_ele_t *ls = o; - if (ls == NULL) return NULL; +static htsmsg_t* linuxdvb_satconf_ele_class_network_enum(void* o, const char* lang) { + linuxdvb_satconf_ele_t* ls = o; + if (ls == NULL) + return NULL; return mpegts_input_class_network_enum(ls->lse_parent->ls_frontend, lang); } -static char * -linuxdvb_satconf_ele_class_network_rend( void *o, const char *lang ) -{ - linuxdvb_satconf_ele_t *ls = o; - htsmsg_t *l = idnode_set_as_htsmsg(ls->lse_networks); - char *str = htsmsg_list_2_csv(l, ',', 1); +static char* linuxdvb_satconf_ele_class_network_rend(void* o, const char* lang) { + linuxdvb_satconf_ele_t* ls = o; + htsmsg_t* l = idnode_set_as_htsmsg(ls->lse_networks); + char* str = htsmsg_list_2_csv(l, ',', 1); htsmsg_destroy(l); return str; } -static int -linuxdvb_satconf_ele_class_lnbtype_set ( void *o, const void *p ) -{ - linuxdvb_satconf_ele_t *ls = o; - const char *str = p; +static int linuxdvb_satconf_ele_class_lnbtype_set(void* o, const void* p) { + linuxdvb_satconf_ele_t* ls = o; + const char* str = p; if (ls->lse_lnb && !strcmp(str ?: "", ls->lse_lnb->ld_type)) return 0; - if (ls->lse_lnb) linuxdvb_lnb_destroy(ls->lse_lnb); + if (ls->lse_lnb) + linuxdvb_lnb_destroy(ls->lse_lnb); ls->lse_lnb = linuxdvb_lnb_create0(str, NULL, ls); return 1; } -static const void * -linuxdvb_satconf_ele_class_lnbtype_get ( void *o ) -{ - linuxdvb_satconf_ele_t *ls = o; - prop_ptr = ls->lse_lnb ? ls->lse_lnb->ld_type : NULL; +static const void* linuxdvb_satconf_ele_class_lnbtype_get(void* o) { + linuxdvb_satconf_ele_t* ls = o; + prop_ptr = ls->lse_lnb ? ls->lse_lnb->ld_type : NULL; return &prop_ptr; } -static int -linuxdvb_satconf_ele_class_en50494type_set ( void *o, const void *p ) -{ - linuxdvb_satconf_ele_t *ls = o; - const char *str = p; +static int linuxdvb_satconf_ele_class_en50494type_set(void* o, const void* p) { + linuxdvb_satconf_ele_t* ls = o; + const char* str = p; if (ls->lse_en50494 && !strcmp(str ?: "", ls->lse_en50494->ld_type)) return 0; if (ls->lse_en50494) @@ -1434,66 +1277,54 @@ linuxdvb_satconf_ele_class_en50494type_set ( void *o, const void *p ) return 1; } -static const void * -linuxdvb_satconf_ele_class_en50494type_get ( void *o ) -{ - linuxdvb_satconf_ele_t *ls = o; - prop_ptr = ls->lse_en50494 ? ls->lse_en50494->ld_type : NULL; +static const void* linuxdvb_satconf_ele_class_en50494type_get(void* o) { + linuxdvb_satconf_ele_t* ls = o; + prop_ptr = ls->lse_en50494 ? ls->lse_en50494->ld_type : NULL; return &prop_ptr; } -static int -linuxdvb_satconf_ele_class_switchtype_set ( void *o, const void *p ) -{ - linuxdvb_satconf_ele_t *ls = o; - const char *str = p; +static int linuxdvb_satconf_ele_class_switchtype_set(void* o, const void* p) { + linuxdvb_satconf_ele_t* ls = o; + const char* str = p; if (ls->lse_switch && !strcmp(str ?: "", ls->lse_switch->ld_type)) return 0; - if (ls->lse_switch) linuxdvb_switch_destroy(ls->lse_switch); + if (ls->lse_switch) + linuxdvb_switch_destroy(ls->lse_switch); ls->lse_switch = linuxdvb_switch_create0(str, NULL, ls, -1, -1); return 1; } -static const void * -linuxdvb_satconf_ele_class_switchtype_get ( void *o ) -{ - linuxdvb_satconf_ele_t *ls = o; - prop_ptr = ls->lse_switch ? ls->lse_switch->ld_type : NULL; +static const void* linuxdvb_satconf_ele_class_switchtype_get(void* o) { + linuxdvb_satconf_ele_t* ls = o; + prop_ptr = ls->lse_switch ? ls->lse_switch->ld_type : NULL; return &prop_ptr; } -static int -linuxdvb_satconf_ele_class_rotortype_set ( void *o, const void *p ) -{ - linuxdvb_satconf_ele_t *ls = o; - const char *str = p; +static int linuxdvb_satconf_ele_class_rotortype_set(void* o, const void* p) { + linuxdvb_satconf_ele_t* ls = o; + const char* str = p; if (ls->lse_rotor && !strcmp(str ?: "", ls->lse_rotor->ld_type)) return 0; - if (ls->lse_rotor) linuxdvb_rotor_destroy(ls->lse_rotor); + if (ls->lse_rotor) + linuxdvb_rotor_destroy(ls->lse_rotor); ls->lse_rotor = linuxdvb_rotor_create0(str, NULL, ls); return 1; } -static const void * -linuxdvb_satconf_ele_class_rotortype_get ( void *o ) -{ - linuxdvb_satconf_ele_t *ls = o; - prop_ptr = ls->lse_rotor ? ls->lse_rotor->ld_type : NULL; +static const void* linuxdvb_satconf_ele_class_rotortype_get(void* o) { + linuxdvb_satconf_ele_t* ls = o; + prop_ptr = ls->lse_rotor ? ls->lse_rotor->ld_type : NULL; return &prop_ptr; } static void -linuxdvb_satconf_ele_class_get_title - ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) -{ - snprintf(dst, dstsize, "%s", ((linuxdvb_satconf_ele_t *)o)->lse_name); +linuxdvb_satconf_ele_class_get_title(idnode_t* o, const char* lang, char* dst, size_t dstsize) { + snprintf(dst, dstsize, "%s", ((linuxdvb_satconf_ele_t*)o)->lse_name); } -static idnode_set_t * -linuxdvb_satconf_ele_class_get_childs ( idnode_t *o ) -{ - linuxdvb_satconf_ele_t *ls = (linuxdvb_satconf_ele_t*)o; - idnode_set_t *is = idnode_set_create(0); +static idnode_set_t* linuxdvb_satconf_ele_class_get_childs(idnode_t* o) { + linuxdvb_satconf_ele_t* ls = (linuxdvb_satconf_ele_t*)o; + idnode_set_t* is = idnode_set_create(0); if (ls->lse_lnb) idnode_set_add(is, &ls->lse_lnb->ld_id, NULL, NULL); if (ls->lse_switch) @@ -1505,143 +1336,134 @@ linuxdvb_satconf_ele_class_get_childs ( idnode_t *o ) return is; } -static void -linuxdvb_satconf_ele_class_changed ( idnode_t *in ) -{ - linuxdvb_satconf_ele_t *lse = (linuxdvb_satconf_ele_t*)in; +static void linuxdvb_satconf_ele_class_changed(idnode_t* in) { + linuxdvb_satconf_ele_t* lse = (linuxdvb_satconf_ele_t*)in; linuxdvb_satconf_class_changed(&lse->lse_parent->ls_id); } -static const void * -linuxdvb_satconf_ele_class_active_get ( void *obj ) -{ - static int active; - linuxdvb_satconf_ele_t *lse = obj; - active = 0; - if (*(int *)linuxdvb_frontend_class_active_get(lse->lse_parent->ls_frontend)) +static const void* linuxdvb_satconf_ele_class_active_get(void* obj) { + static int active; + linuxdvb_satconf_ele_t* lse = obj; + active = 0; + if (*(int*)linuxdvb_frontend_class_active_get(lse->lse_parent->ls_frontend)) active = lse->lse_enabled; return &active; } -const idclass_t linuxdvb_satconf_ele_class = -{ - .ic_class = "linuxdvb_satconf_ele", - .ic_caption = N_("Satconf"), - .ic_doc = tvh_doc_linuxdvb_satconf_class, - .ic_event = "linuxdvb_satconf_ele", - .ic_get_title = linuxdvb_satconf_ele_class_get_title, - .ic_get_childs = linuxdvb_satconf_ele_class_get_childs, - .ic_changed = linuxdvb_satconf_ele_class_changed, - .ic_properties = (const property_t[]) { - { - .type = PT_BOOL, - .id = "active", - .name = N_("Active"), - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, - .get = linuxdvb_satconf_ele_class_active_get, - }, - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .off = offsetof(linuxdvb_satconf_ele_t, lse_enabled), - }, - { - .type = PT_STR, - .id = "displayname", - .name = N_("Name"), - .off = offsetof(linuxdvb_satconf_ele_t, lse_name), - .notify = idnode_notify_title_changed_lang, - }, - { - .type = PT_INT, - .id = "priority", - .name = N_("Priority"), - .off = offsetof(linuxdvb_satconf_ele_t, lse_priority), - .def.i = 1, - .opts = PO_ADVANCED, - }, - { - .type = PT_STR, - .id = "networks", - .name = N_("Networks"), - .islist = 1, - .set = linuxdvb_satconf_ele_class_network_set, - .get = linuxdvb_satconf_ele_class_network_get, - .list = linuxdvb_satconf_ele_class_network_enum, - .rend = linuxdvb_satconf_ele_class_network_rend, - }, - { - .type = PT_STR, - .id = "lnb_type", - .name = N_("LNB type"), - .set = linuxdvb_satconf_ele_class_lnbtype_set, - .get = linuxdvb_satconf_ele_class_lnbtype_get, - .list = linuxdvb_lnb_list, - .def.s = "Universal", - }, - { - .type = PT_STR, - .id = "switch_type", - .name = N_("Switch type"), - .set = linuxdvb_satconf_ele_class_switchtype_set, - .get = linuxdvb_satconf_ele_class_switchtype_get, - .list = linuxdvb_switch_list, - .def.s = "None", - }, - { - .type = PT_STR, - .id = "rotor_type", - .name = N_("Rotor type"), - .set = linuxdvb_satconf_ele_class_rotortype_set, - .get = linuxdvb_satconf_ele_class_rotortype_get, - .list = linuxdvb_rotor_list, - .def.s = "None", - }, - { - .type = PT_STR, - .id = "en50494_type", - .name = N_("Unicable type"), - .set = linuxdvb_satconf_ele_class_en50494type_set, - .get = linuxdvb_satconf_ele_class_en50494type_get, - .list = linuxdvb_en50494_list, - .def.s = "None", - }, - {} - } -}; +const idclass_t linuxdvb_satconf_ele_class = {.ic_class = "linuxdvb_satconf_ele", + .ic_caption = N_("Satconf"), + .ic_doc = tvh_doc_linuxdvb_satconf_class, + .ic_event = "linuxdvb_satconf_ele", + .ic_get_title = linuxdvb_satconf_ele_class_get_title, + .ic_get_childs = linuxdvb_satconf_ele_class_get_childs, + .ic_changed = linuxdvb_satconf_ele_class_changed, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "active", + .name = N_("Active"), + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, + .get = linuxdvb_satconf_ele_class_active_get, + }, + { + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .off = offsetof(linuxdvb_satconf_ele_t, lse_enabled), + }, + { + .type = PT_STR, + .id = "displayname", + .name = N_("Name"), + .off = offsetof(linuxdvb_satconf_ele_t, lse_name), + .notify = idnode_notify_title_changed_lang, + }, + { + .type = PT_INT, + .id = "priority", + .name = N_("Priority"), + .off = offsetof(linuxdvb_satconf_ele_t, lse_priority), + .def.i = 1, + .opts = PO_ADVANCED, + }, + { + .type = PT_STR, + .id = "networks", + .name = N_("Networks"), + .islist = 1, + .set = linuxdvb_satconf_ele_class_network_set, + .get = linuxdvb_satconf_ele_class_network_get, + .list = linuxdvb_satconf_ele_class_network_enum, + .rend = linuxdvb_satconf_ele_class_network_rend, + }, + { + .type = PT_STR, + .id = "lnb_type", + .name = N_("LNB type"), + .set = linuxdvb_satconf_ele_class_lnbtype_set, + .get = linuxdvb_satconf_ele_class_lnbtype_get, + .list = linuxdvb_lnb_list, + .def.s = "Universal", + }, + { + .type = PT_STR, + .id = "switch_type", + .name = N_("Switch type"), + .set = linuxdvb_satconf_ele_class_switchtype_set, + .get = linuxdvb_satconf_ele_class_switchtype_get, + .list = linuxdvb_switch_list, + .def.s = "None", + }, + { + .type = PT_STR, + .id = "rotor_type", + .name = N_("Rotor type"), + .set = linuxdvb_satconf_ele_class_rotortype_set, + .get = linuxdvb_satconf_ele_class_rotortype_get, + .list = linuxdvb_rotor_list, + .def.s = "None", + }, + { + .type = PT_STR, + .id = "en50494_type", + .name = N_("Unicable type"), + .set = linuxdvb_satconf_ele_class_en50494type_set, + .get = linuxdvb_satconf_ele_class_en50494type_get, + .list = linuxdvb_en50494_list, + .def.s = "None", + }, + {}}}; /* ************************************************************************** * Creation/Config * *************************************************************************/ -void -linuxdvb_satconf_ele_destroy ( linuxdvb_satconf_ele_t *ls ) -{ +void linuxdvb_satconf_ele_destroy(linuxdvb_satconf_ele_t* ls) { TAILQ_REMOVE(&ls->lse_parent->ls_elements, ls, lse_link); idnode_save_check(&ls->lse_id, 1); idnode_unlink(&ls->lse_id); - if (ls->lse_lnb) linuxdvb_lnb_destroy(ls->lse_lnb); - if (ls->lse_switch) linuxdvb_switch_destroy(ls->lse_switch); - if (ls->lse_rotor) linuxdvb_rotor_destroy(ls->lse_rotor); - if (ls->lse_en50494) linuxdvb_en50494_destroy(ls->lse_en50494); + if (ls->lse_lnb) + linuxdvb_lnb_destroy(ls->lse_lnb); + if (ls->lse_switch) + linuxdvb_switch_destroy(ls->lse_switch); + if (ls->lse_rotor) + linuxdvb_rotor_destroy(ls->lse_rotor); + if (ls->lse_en50494) + linuxdvb_en50494_destroy(ls->lse_en50494); idnode_set_free(ls->lse_networks); free(ls->lse_name); free(ls); } -linuxdvb_satconf_ele_t * -linuxdvb_satconf_ele_create0 - ( const char *uuid, htsmsg_t *conf, linuxdvb_satconf_t *ls ) -{ - htsmsg_t *e; - linuxdvb_satconf_ele_t *lse = calloc(1, sizeof(*lse)); +linuxdvb_satconf_ele_t* +linuxdvb_satconf_ele_create0(const char* uuid, htsmsg_t* conf, linuxdvb_satconf_t* ls) { + htsmsg_t* e; + linuxdvb_satconf_ele_t* lse = calloc(1, sizeof(*lse)); if (idnode_insert(&lse->lse_id, uuid, &linuxdvb_satconf_ele_class, 0)) { free(lse); return NULL; } lse->lse_networks = idnode_set_create(0); - lse->lse_parent = ls; + lse->lse_parent = ls; TAILQ_INSERT_TAIL(&ls->ls_elements, lse, lse_link); if (conf) idnode_load(&lse->lse_id, conf); @@ -1673,11 +1495,9 @@ linuxdvb_satconf_ele_create0 return lse; } -void -linuxdvb_satconf_destroy ( linuxdvb_satconf_t *ls, int delconf ) -{ +void linuxdvb_satconf_destroy(linuxdvb_satconf_t* ls, int delconf) { linuxdvb_satconf_ele_t *lse, *nxt; - char ubuf[UUID_HEX_SIZE]; + char ubuf[UUID_HEX_SIZE]; if (delconf) hts_settings_remove("input/linuxdvb/satconfs/%s", idnode_uuid_as_str(&ls->ls_id, ubuf)); mtimer_disarm(&ls->ls_diseqc_timer); @@ -1696,56 +1516,46 @@ linuxdvb_satconf_destroy ( linuxdvb_satconf_t *ls, int delconf ) *****************************************************************************/ static void -linuxdvb_diseqc_class_get_title - ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) -{ - linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; +linuxdvb_diseqc_class_get_title(idnode_t* o, const char* lang, char* dst, size_t dstsize) { + linuxdvb_diseqc_t* ld = (linuxdvb_diseqc_t*)o; snprintf(dst, dstsize, "%s", ld->ld_type); } -static void -linuxdvb_diseqc_class_changed ( idnode_t *o ) -{ - linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; +static void linuxdvb_diseqc_class_changed(idnode_t* o) { + linuxdvb_diseqc_t* ld = (linuxdvb_diseqc_t*)o; if (ld->ld_satconf) linuxdvb_satconf_ele_class_changed(&ld->ld_satconf->lse_id); } -static const void * -linuxdvb_diseqc_class_active_get ( void *obj ) -{ - static int active; - linuxdvb_diseqc_t *ld = obj; +static const void* linuxdvb_diseqc_class_active_get(void* obj) { + static int active; + linuxdvb_diseqc_t* ld = obj; if (ld->ld_satconf) return linuxdvb_satconf_ele_class_active_get(ld->ld_satconf); active = 1; return &active; } -const idclass_t linuxdvb_diseqc_class = -{ - .ic_class = "linuxdvb_diseqc", - .ic_caption = N_("DiseqC"), - .ic_event = "linuxdvb_diseqc", - .ic_get_title = linuxdvb_diseqc_class_get_title, - .ic_changed = linuxdvb_diseqc_class_changed, - .ic_properties = (const property_t[]) { - { - .type = PT_BOOL, - .id = "active", - .name = N_("Active"), - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, - .get = linuxdvb_diseqc_class_active_get, - }, - {} - } -}; - -linuxdvb_diseqc_t * -linuxdvb_diseqc_create0 - ( linuxdvb_diseqc_t *ld, const char *uuid, const idclass_t *idc, - htsmsg_t *conf, const char *type, linuxdvb_satconf_ele_t *parent ) -{ +const idclass_t linuxdvb_diseqc_class = {.ic_class = "linuxdvb_diseqc", + .ic_caption = N_("DiseqC"), + .ic_event = "linuxdvb_diseqc", + .ic_get_title = linuxdvb_diseqc_class_get_title, + .ic_changed = linuxdvb_diseqc_class_changed, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "active", + .name = N_("Active"), + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, + .get = linuxdvb_diseqc_class_active_get, + }, + {}}}; + +linuxdvb_diseqc_t* linuxdvb_diseqc_create0(linuxdvb_diseqc_t* ld, + const char* uuid, + const idclass_t* idc, + htsmsg_t* conf, + const char* type, + linuxdvb_satconf_ele_t* parent) { /* Insert */ if (idnode_insert(&ld->ld_id, uuid, idc, 0)) { free(ld); @@ -1755,7 +1565,7 @@ linuxdvb_diseqc_create0 assert(type != NULL); ld->ld_type = strdup(type); ld->ld_satconf = parent; - + /* Load config */ if (conf) idnode_load(&ld->ld_id, conf); @@ -1763,23 +1573,18 @@ linuxdvb_diseqc_create0 return ld; } -void -linuxdvb_diseqc_destroy ( linuxdvb_diseqc_t *ld ) -{ +void linuxdvb_diseqc_destroy(linuxdvb_diseqc_t* ld) { idnode_save_check(&ld->ld_id, 1); idnode_unlink(&ld->ld_id); - free((void *)ld->ld_type); + free((void*)ld->ld_type); } -int -linuxdvb_diseqc_raw_send - (int fd, int len, ...) -{ - int i; - va_list ap; +int linuxdvb_diseqc_raw_send(int fd, int len, ...) { + int i; + va_list ap; struct dvb_diseqc_master_cmd message; - char buf[256]; - size_t c = 0; + char buf[256]; + size_t c = 0; /* Build message */ message.msg_len = len; @@ -1802,15 +1607,12 @@ linuxdvb_diseqc_raw_send return 0; } -int -linuxdvb_diseqc_send - (int fd, uint8_t framing, uint8_t addr, uint8_t cmd, int len, ...) -{ - int i; - va_list ap; +int linuxdvb_diseqc_send(int fd, uint8_t framing, uint8_t addr, uint8_t cmd, int len, ...) { + int i; + va_list ap; struct dvb_diseqc_master_cmd message; - char buf[256]; - size_t c = 0; + char buf[256]; + size_t c = 0; /* Build message */ memset(&message, 0, sizeof(message)); @@ -1827,8 +1629,13 @@ linuxdvb_diseqc_send va_end(ap); if (tvhtrace_enabled()) - tvhtrace(LS_DISEQC, "sending diseqc (len %d) %02X %02X %02X %s", - len + 3, framing, addr, cmd, buf); + tvhtrace(LS_DISEQC, + "sending diseqc (len %d) %02X %02X %02X %s", + len + 3, + framing, + addr, + cmd, + buf); /* Send */ if (ioctl(fd, FE_DISEQC_SEND_MASTER_CMD, &message)) { @@ -1838,9 +1645,7 @@ linuxdvb_diseqc_send return 0; } -int -linuxdvb_diseqc_set_volt ( linuxdvb_satconf_t *ls, int vol ) -{ +int linuxdvb_diseqc_set_volt(linuxdvb_satconf_t* ls, int vol) { vol = vol < 0 ? -1 : !!(vol > 0); /* Already set ? */ if (vol >= 0 && ls->ls_last_vol == vol + 1) @@ -1854,8 +1659,9 @@ linuxdvb_diseqc_set_volt ( linuxdvb_satconf_t *ls, int vol ) } /* Set voltage */ tvhtrace(LS_DISEQC, "set voltage %dV", vol ? (vol < 0 ? 0 : 18) : 13); - if (ioctl(linuxdvb_satconf_fe_fd(ls), FE_SET_VOLTAGE, - vol ? (vol < 0 ? SEC_VOLTAGE_OFF : SEC_VOLTAGE_18) : SEC_VOLTAGE_13)) { + if (ioctl(linuxdvb_satconf_fe_fd(ls), + FE_SET_VOLTAGE, + vol ? (vol < 0 ? SEC_VOLTAGE_OFF : SEC_VOLTAGE_18) : SEC_VOLTAGE_13)) { tvherror(LS_DISEQC, "failed to set voltage (e=%s)", strerror(errno)); ls->ls_last_vol = 0; return -1; diff --git a/src/input/mpegts/linuxdvb/linuxdvb_switch.c b/src/input/mpegts/linuxdvb/linuxdvb_switch.c index f12ab7013..e3bcda517 100644 --- a/src/input/mpegts/linuxdvb/linuxdvb_switch.c +++ b/src/input/mpegts/linuxdvb/linuxdvb_switch.c @@ -35,74 +35,65 @@ * Class definition * *************************************************************************/ -typedef struct linuxdvb_switch -{ +typedef struct linuxdvb_switch { linuxdvb_diseqc_t; /* Port settings */ - int ls_toneburst; - int ls_committed; - int ls_uncommitted; - int ls_uncommitted_first; + int ls_toneburst; + int ls_committed; + int ls_uncommitted; + int ls_uncommitted_first; uint32_t ls_powerup_time; /* in ms */ uint32_t ls_cmd_time; /* in ms */ } linuxdvb_switch_t; -static htsmsg_t * -linuxdvb_switch_class_committed_list ( void *o, const char *lang ) -{ +static htsmsg_t* linuxdvb_switch_class_committed_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("NONE"), -1 }, - { N_("AA"), 0 }, - { N_("AB"), 1 }, - { N_("BA"), 2 }, - { N_("BB"), 3 }, + {N_("NONE"), -1}, + {N_("AA"), 0}, + {N_("AB"), 1}, + {N_("BA"), 2}, + {N_("BB"), 3}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -linuxdvb_switch_class_uncommitted_list ( void *o, const char *lang ) -{ +static htsmsg_t* linuxdvb_switch_class_uncommitted_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("NONE"), -1 }, - { N_( "0"), 0 }, - { N_( "1"), 1 }, - { N_( "2"), 2 }, - { N_( "3"), 3 }, - { N_( "4"), 4 }, - { N_( "5"), 5 }, - { N_( "6"), 6 }, - { N_( "7"), 7 }, - { N_( "8"), 8 }, - { N_( "9"), 9 }, - { N_("10"), 10 }, - { N_("11"), 11 }, - { N_("12"), 12 }, - { N_("13"), 13 }, - { N_("14"), 14 }, - { N_("15"), 15 }, + {N_("NONE"), -1}, + {N_("0"), 0}, + {N_("1"), 1}, + {N_("2"), 2}, + {N_("3"), 3}, + {N_("4"), 4}, + {N_("5"), 5}, + {N_("6"), 6}, + {N_("7"), 7}, + {N_("8"), 8}, + {N_("9"), 9}, + {N_("10"), 10}, + {N_("11"), 11}, + {N_("12"), 12}, + {N_("13"), 13}, + {N_("14"), 14}, + {N_("15"), 15}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -linuxdvb_switch_class_toneburst_list ( void *o, const char *lang ) -{ +static htsmsg_t* linuxdvb_switch_class_toneburst_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("NONE"), -1 }, - { N_("A"), 0 }, - { N_("B"), 1 }, + {N_("NONE"), -1}, + {N_("A"), 0}, + {N_("B"), 1}, }; return strtab2htsmsg(tab, 1, lang); } static void -linuxdvb_switch_class_get_title - ( idnode_t *o, const char *lang, char *dst, size_t dstsize ) -{ - linuxdvb_diseqc_t *ld = (linuxdvb_diseqc_t*)o; +linuxdvb_switch_class_get_title(idnode_t* o, const char* lang, char* dst, size_t dstsize) { + linuxdvb_diseqc_t* ld = (linuxdvb_diseqc_t*)o; snprintf(dst, dstsize, tvh_gettext_lang(lang, N_("Switch: %s")), ld->ld_type); } @@ -110,78 +101,68 @@ extern const idclass_t linuxdvb_diseqc_class; CLASS_DOC(linuxdvb_satconf) -const idclass_t linuxdvb_switch_class = -{ - .ic_super = &linuxdvb_diseqc_class, - .ic_class = "linuxdvb_switch", - .ic_caption = N_("TV Adapters - SatConfig - DiseqC Switch"), - .ic_doc = tvh_doc_linuxdvb_satconf_class, - .ic_get_title = linuxdvb_switch_class_get_title, - .ic_properties = (const property_t[]) { - { - .type = PT_U32, - .id = "powerup_time", - .name = N_("Power up time (ms) (10-500)"), - .desc = N_("Time (in milliseconds) for the switch to power up."), - .off = offsetof(linuxdvb_switch_t, ls_powerup_time), - .def.u32 = 100, - }, - { - .type = PT_U32, - .id = "cmd_time", - .name = N_("Command time (ms) (10-300)"), - .desc = N_("Time (in milliseconds) for a command to complete."), - .off = offsetof(linuxdvb_switch_t, ls_cmd_time), - .def.u32 = 25 - }, - { - .type = PT_INT, - .id = "committed", - .name = N_("Committed"), - .off = offsetof(linuxdvb_switch_t, ls_committed), - .list = linuxdvb_switch_class_committed_list - }, - { - .type = PT_INT, - .id = "uncommitted", - .name = N_("Uncommitted"), - .off = offsetof(linuxdvb_switch_t, ls_uncommitted), - .list = linuxdvb_switch_class_uncommitted_list - }, - { - .type = PT_INT, - .id = "toneburst", - .name = N_("Tone burst"), - .off = offsetof(linuxdvb_switch_t, ls_toneburst), - .list = linuxdvb_switch_class_toneburst_list - }, - { - .type = PT_BOOL, - .id = "preferun", - .name = N_("Uncommitted first"), - .off = offsetof(linuxdvb_switch_t, ls_uncommitted_first), - }, - {} - } -}; +const idclass_t linuxdvb_switch_class = {.ic_super = &linuxdvb_diseqc_class, + .ic_class = "linuxdvb_switch", + .ic_caption = N_("TV Adapters - SatConfig - DiseqC Switch"), + .ic_doc = tvh_doc_linuxdvb_satconf_class, + .ic_get_title = linuxdvb_switch_class_get_title, + .ic_properties = + (const property_t[]){{ + .type = PT_U32, + .id = "powerup_time", + .name = N_("Power up time (ms) (10-500)"), + .desc = N_("Time (in milliseconds) for the switch to power up."), + .off = offsetof(linuxdvb_switch_t, ls_powerup_time), + .def.u32 = 100, + }, + {.type = PT_U32, + .id = "cmd_time", + .name = N_("Command time (ms) (10-300)"), + .desc = N_("Time (in milliseconds) for a command to complete."), + .off = offsetof(linuxdvb_switch_t, ls_cmd_time), + .def.u32 = 25}, + {.type = PT_INT, + .id = "committed", + .name = N_("Committed"), + .off = offsetof(linuxdvb_switch_t, ls_committed), + .list = linuxdvb_switch_class_committed_list}, + {.type = PT_INT, + .id = "uncommitted", + .name = N_("Uncommitted"), + .off = offsetof(linuxdvb_switch_t, ls_uncommitted), + .list = linuxdvb_switch_class_uncommitted_list}, + {.type = PT_INT, + .id = "toneburst", + .name = N_("Tone burst"), + .off = offsetof(linuxdvb_switch_t, ls_toneburst), + .list = linuxdvb_switch_class_toneburst_list}, + { + .type = PT_BOOL, + .id = "preferun", + .name = N_("Uncommitted first"), + .off = offsetof(linuxdvb_switch_t, ls_uncommitted_first), + }, + {}}}; /* ************************************************************************** * Class methods * *************************************************************************/ -static int -linuxdvb_switch_tune - ( linuxdvb_diseqc_t *ld, dvb_mux_t *lm, linuxdvb_satconf_t *lsp, - linuxdvb_satconf_ele_t *sc, int vol, int pol, int band, int freq ) -{ - int i, com, r1 = 0, r2 = 0, slp; - int fd = linuxdvb_satconf_fe_fd(lsp); - linuxdvb_switch_t *ls = (linuxdvb_switch_t*)ld; +static int linuxdvb_switch_tune(linuxdvb_diseqc_t* ld, + dvb_mux_t* lm, + linuxdvb_satconf_t* lsp, + linuxdvb_satconf_ele_t* sc, + int vol, + int pol, + int band, + int freq) { + int i, com, r1 = 0, r2 = 0, slp; + int fd = linuxdvb_satconf_fe_fd(lsp); + linuxdvb_switch_t* ls = (linuxdvb_switch_t*)ld; if (lsp->ls_diseqc_full || lsp->ls_last_switch != sc || (ls->ls_committed >= 0 && - (pol + 1 != lsp->ls_last_switch_pol || - band + 1 != lsp->ls_last_switch_band))) { + (pol + 1 != lsp->ls_last_switch_pol || band + 1 != lsp->ls_last_switch_band))) { lsp->ls_last_switch = NULL; @@ -197,8 +178,7 @@ linuxdvb_switch_tune if (ls->ls_uncommitted_first) /* Uncommitted */ if (ls->ls_uncommitted >= 0) { - if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1, - 0xF0 | ls->ls_uncommitted)) + if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1, 0xF0 | ls->ls_uncommitted)) return -1; tvh_safe_usleep(slp); } @@ -213,8 +193,7 @@ linuxdvb_switch_tune if (!ls->ls_uncommitted_first) { /* Uncommitted */ if (ls->ls_uncommitted >= 0) { - if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1, - 0xF0 | ls->ls_uncommitted)) + if (linuxdvb_diseqc_send(fd, 0xE0 | r2, 0x10, 0x39, 1, 0xF0 | ls->ls_uncommitted)) return -1; tvh_safe_usleep(slp); } @@ -229,7 +208,7 @@ linuxdvb_switch_tune lsp->ls_last_switch_band = band + 1; /* port was changed, new LNB has not received toneburst yet */ - lsp->ls_last_toneburst = 0; + lsp->ls_last_toneburst = 0; } /* Tone burst */ @@ -241,8 +220,7 @@ linuxdvb_switch_tune lsp->ls_last_toneburst = 0; tvhtrace(LS_DISEQC, "toneburst %s", ls->ls_toneburst ? "B" : "A"); - if (ioctl(fd, FE_DISEQC_SEND_BURST, - ls->ls_toneburst ? SEC_MINI_B : SEC_MINI_A)) { + if (ioctl(fd, FE_DISEQC_SEND_BURST, ls->ls_toneburst ? SEC_MINI_B : SEC_MINI_A)) { tvherror(LS_DISEQC, "failed to set toneburst (e=%s)", strerror(errno)); return -1; } @@ -256,31 +234,30 @@ linuxdvb_switch_tune * Create / Config * *************************************************************************/ -htsmsg_t * -linuxdvb_switch_list ( void *o, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_list(); +htsmsg_t* linuxdvb_switch_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_list(); htsmsg_add_msg(m, NULL, htsmsg_create_key_val("", tvh_gettext_lang(lang, N_("None")))); htsmsg_add_msg(m, NULL, htsmsg_create_key_val("Generic", tvh_gettext_lang(lang, N_("Generic")))); return m; } -linuxdvb_diseqc_t * -linuxdvb_switch_create0 - ( const char *name, htsmsg_t *conf, linuxdvb_satconf_ele_t *ls, int c, int u ) -{ - linuxdvb_switch_t *ld = NULL; +linuxdvb_diseqc_t* linuxdvb_switch_create0(const char* name, + htsmsg_t* conf, + linuxdvb_satconf_ele_t* ls, + int c, + int u) { + linuxdvb_switch_t* ld = NULL; if (!strcmp(name ?: "", "Generic")) { ld = (linuxdvb_switch_t*)linuxdvb_diseqc_create(linuxdvb_switch, NULL, conf, "Generic", ls); if (ld) { ld->ld_tune = linuxdvb_switch_tune; if (!conf) { - ld->ls_committed = -1; - ld->ls_uncommitted = -1; - ld->ls_toneburst = -1; + ld->ls_committed = -1; + ld->ls_uncommitted = -1; + ld->ls_toneburst = -1; if (c >= 0) { - ld->ls_committed = c; - ld->ls_toneburst = c % 2; + ld->ls_committed = c; + ld->ls_toneburst = c % 2; } if (u >= 0) ld->ls_uncommitted = u; @@ -295,9 +272,7 @@ linuxdvb_switch_create0 return (linuxdvb_diseqc_t*)ld; } -void -linuxdvb_switch_destroy ( linuxdvb_diseqc_t *ld ) -{ +void linuxdvb_switch_destroy(linuxdvb_diseqc_t* ld) { linuxdvb_diseqc_destroy(ld); free(ld); } diff --git a/src/input/mpegts/mpegts_dvb.h b/src/input/mpegts/mpegts_dvb.h index 1ded80b58..a827b0159 100644 --- a/src/input/mpegts/mpegts_dvb.h +++ b/src/input/mpegts/mpegts_dvb.h @@ -20,8 +20,7 @@ #ifndef __TVH_MPEGTS_DVB_H__ #define __TVH_MPEGTS_DVB_H__ -typedef struct dvb_network -{ +typedef struct dvb_network { mpegts_network_t; /* @@ -30,8 +29,7 @@ typedef struct dvb_network dvb_fe_type_t ln_type; } dvb_network_t; -typedef struct dvb_mux -{ +typedef struct dvb_mux { mpegts_mux_t; /* @@ -64,29 +62,33 @@ extern const idclass_t dvb_network_isdb_s_class; extern const idclass_t dvb_network_dtmb_class; extern const idclass_t dvb_network_dab_class; -void dvb_network_init ( void ); -void dvb_network_done ( void ); +void dvb_network_init(void); +void dvb_network_done(void); -static inline dvb_network_t *dvb_network_find_by_uuid(const char *uuid) - { return idnode_find(uuid, &dvb_network_class, NULL); } +static inline dvb_network_t* dvb_network_find_by_uuid(const char* uuid) { + return idnode_find(uuid, &dvb_network_class, NULL); +} -const idclass_t *dvb_network_class_by_fe_type(dvb_fe_type_t type); -dvb_fe_type_t dvb_fe_type_by_network_class(const idclass_t *idc); +const idclass_t* dvb_network_class_by_fe_type(dvb_fe_type_t type); +dvb_fe_type_t dvb_fe_type_by_network_class(const idclass_t* idc); -idnode_set_t *dvb_network_list_by_fe_type(dvb_fe_type_t type); +idnode_set_t* dvb_network_list_by_fe_type(dvb_fe_type_t type); -dvb_network_t *dvb_network_create0 - ( const char *uuid, const idclass_t *idc, htsmsg_t *conf ); +dvb_network_t* dvb_network_create0(const char* uuid, const idclass_t* idc, htsmsg_t* conf); -dvb_mux_t *dvb_network_find_mux - ( dvb_network_t *ln, dvb_mux_conf_t *dmc, uint32_t onid, uint32_t tsid, int check, int approx_match ); +dvb_mux_t* dvb_network_find_mux(dvb_network_t* ln, + dvb_mux_conf_t* dmc, + uint32_t onid, + uint32_t tsid, + int check, + int approx_match); -const idclass_t *dvb_network_mux_class(mpegts_network_t *mn); -int dvb_network_get_orbital_pos(mpegts_network_t *mn); +const idclass_t* dvb_network_mux_class(mpegts_network_t* mn); +int dvb_network_get_orbital_pos(mpegts_network_t* mn); -void dvb_network_scanfile_set ( dvb_network_t *ln, const char *id ); +void dvb_network_scanfile_set(dvb_network_t* ln, const char* id); -htsmsg_t * dvb_network_class_scanfile_list ( void *o, const char *lang ); +htsmsg_t* dvb_network_class_scanfile_list(void* o, const char* lang); /* * @@ -103,11 +105,13 @@ extern const idclass_t dvb_mux_isdb_s_class; extern const idclass_t dvb_mux_dtmb_class; extern const idclass_t dvb_mux_dab_class; -dvb_mux_t *dvb_mux_create0 - (dvb_network_t *ln, uint32_t onid, uint32_t tsid, - const dvb_mux_conf_t *dmc, const char *uuid, htsmsg_t *conf); +dvb_mux_t* dvb_mux_create0(dvb_network_t* ln, + uint32_t onid, + uint32_t tsid, + const dvb_mux_conf_t* dmc, + const char* uuid, + htsmsg_t* conf); -#define dvb_mux_create1(n, u, c)\ - dvb_mux_create0(n, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, NULL, u, c) +#define dvb_mux_create1(n, u, c) dvb_mux_create0(n, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, NULL, u, c) #endif /* __TVH_MPEGTS_DVB_H__ */ diff --git a/src/input/mpegts/mpegts_input.c b/src/input/mpegts/mpegts_input.c index c4856b08c..6086c0590 100644 --- a/src/input/mpegts/mpegts_input.c +++ b/src/input/mpegts/mpegts_input.c @@ -24,27 +24,24 @@ #include "dbus.h" #include "memoryinfo.h" -memoryinfo_t mpegts_input_queue_memoryinfo = { .my_name = "MPEG-TS input queue" }; -memoryinfo_t mpegts_input_table_memoryinfo = { .my_name = "MPEG-TS table queue" }; +memoryinfo_t mpegts_input_queue_memoryinfo = {.my_name = "MPEG-TS input queue"}; +memoryinfo_t mpegts_input_table_memoryinfo = {.my_name = "MPEG-TS table queue"}; -static void -mpegts_input_del_network ( mpegts_network_link_t *mnl ); +static void mpegts_input_del_network(mpegts_network_link_t* mnl); /* * DBUS */ -static void -mpegts_input_dbus_notify(mpegts_input_t *mi, int64_t subs) -{ +static void mpegts_input_dbus_notify(mpegts_input_t* mi, int64_t subs) { #if ENABLE_DBUS_1 - char buf[256], ubuf[UUID_HEX_SIZE]; - htsmsg_t *msg; + char buf[256], ubuf[UUID_HEX_SIZE]; + htsmsg_t* msg; if (mi->mi_dbus_subs == subs) return; mi->mi_dbus_subs = subs; - msg = htsmsg_create_list(); + msg = htsmsg_create_list(); mi->mi_display_name(mi, buf, sizeof(buf)); htsmsg_add_str(msg, NULL, buf); htsmsg_add_s64(msg, NULL, subs); @@ -58,72 +55,60 @@ mpegts_input_dbus_notify(mpegts_input_t *mi, int64_t subs) * *************************************************************************/ static void -mpegts_input_class_get_title - ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) -{ - mpegts_input_t *mi = (mpegts_input_t*)in; +mpegts_input_class_get_title(idnode_t* in, const char* lang, char* dst, size_t dstsize) { + mpegts_input_t* mi = (mpegts_input_t*)in; mi->mi_display_name(mi, dst, dstsize); } -const void * -mpegts_input_class_active_get ( void *obj ) -{ - static int active; - mpegts_input_t *mi = obj; - active = mi->mi_enabled ? 1 : 0; +const void* mpegts_input_class_active_get(void* obj) { + static int active; + mpegts_input_t* mi = obj; + active = mi->mi_enabled ? 1 : 0; return &active; } -const void * -mpegts_input_class_network_get ( void *obj ) -{ - mpegts_network_link_t *mnl; - mpegts_input_t *mi = obj; - htsmsg_t *l = htsmsg_create_list(); +const void* mpegts_input_class_network_get(void* obj) { + mpegts_network_link_t* mnl; + mpegts_input_t* mi = obj; + htsmsg_t* l = htsmsg_create_list(); - LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link) + LIST_FOREACH (mnl, &mi->mi_networks, mnl_mi_link) htsmsg_add_uuid(l, NULL, &mnl->mnl_network->mn_id.in_uuid); return l; } -int -mpegts_input_class_network_set ( void *obj, const void *p ) -{ +int mpegts_input_class_network_set(void* obj, const void* p) { return mpegts_input_set_networks(obj, (htsmsg_t*)p); } -htsmsg_t * -mpegts_input_class_network_enum ( void *obj, const char *lang ) -{ +htsmsg_t* mpegts_input_class_network_enum(void* obj, const char* lang) { htsmsg_t *p, *m; if (!obj) return NULL; p = htsmsg_create_map(); - htsmsg_add_uuid(p, "uuid", &((idnode_t*)obj)->in_uuid); - htsmsg_add_bool(p, "enum", 1); + htsmsg_add_uuid(p, "uuid", &((idnode_t*)obj)->in_uuid); + htsmsg_add_bool(p, "enum", 1); m = htsmsg_create_map(); - htsmsg_add_str (m, "type", "api"); - htsmsg_add_str (m, "uri", "mpegts/input/network_list"); - htsmsg_add_str (m, "event", "mpegts_network"); - htsmsg_add_msg (m, "params", p); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "mpegts/input/network_list"); + htsmsg_add_str(m, "event", "mpegts_network"); + htsmsg_add_msg(m, "params", p); return m; } -char * -mpegts_input_class_network_rend ( void *obj, const char *lang ) -{ - char *str; - mpegts_network_link_t *mnl; - mpegts_network_t *mn; - mpegts_input_t *mi = obj; - htsmsg_t *l = htsmsg_create_list(); - char buf[384]; - - LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link) { +char* mpegts_input_class_network_rend(void* obj, const char* lang) { + char* str; + mpegts_network_link_t* mnl; + mpegts_network_t* mn; + mpegts_input_t* mi = obj; + htsmsg_t* l = htsmsg_create_list(); + char buf[384]; + + LIST_FOREACH (mnl, &mi->mi_networks, mnl_mi_link) { mn = mnl->mnl_network; htsmsg_add_str(l, NULL, idnode_get_title(&mn->mn_id, lang, buf, sizeof(buf))); } @@ -134,14 +119,12 @@ mpegts_input_class_network_rend ( void *obj, const char *lang ) return str; } -static void -mpegts_input_enabled_notify ( void *p, const char *lang ) -{ - mpegts_input_t *mi = p; - mpegts_mux_instance_t *mmi; +static void mpegts_input_enabled_notify(void* p, const char* lang) { + mpegts_input_t* mi = p; + mpegts_mux_instance_t* mmi; /* Stop */ - LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link) + LIST_FOREACH (mmi, &mi->mi_mux_active, mmi_active_link) mmi->mmi_mux->mm_stop(mmi->mmi_mux, 1, SM_CODE_ABORTED); /* Alert */ @@ -149,11 +132,9 @@ mpegts_input_enabled_notify ( void *p, const char *lang ) mi->mi_enabled_updated(mi); } -static int -mpegts_input_class_linked_set ( void *self, const void *val ) -{ +static int mpegts_input_class_linked_set(void* self, const void* val) { mpegts_input_t *mi = self, *mi2; - char ubuf[UUID_HEX_SIZE]; + char ubuf[UUID_HEX_SIZE]; if (strcmp(val ?: "", mi->mi_linked ?: "")) { mi2 = mpegts_input_find(mi->mi_linked); @@ -165,9 +146,9 @@ mpegts_input_class_linked_set ( void *self, const void *val ) mpegts_mux_unsubscribe_linked(mi2, NULL); } mpegts_mux_unsubscribe_linked(mi, NULL); - if (val && ((char *)val)[0]) { - mi->mi_linked = strdup((char *)val); - mi2 = mpegts_input_find((char *)val); + if (val && ((char*)val)[0]) { + mi->mi_linked = strdup((char*)val); + mi2 = mpegts_input_find((char*)val); if (mi2) { free(mi2->mi_linked); mi2->mi_linked = strdup(idnode_uuid_as_str(&mi->ti_id, ubuf)); @@ -180,11 +161,9 @@ mpegts_input_class_linked_set ( void *self, const void *val ) return 0; } -static const void * -mpegts_input_class_linked_get ( void *self ) -{ - mpegts_input_t *mi = self; - prop_sbuf[0] = '\0'; +static const void* mpegts_input_class_linked_get(void* self) { + mpegts_input_t* mi = self; + prop_sbuf[0] = '\0'; if (mi->mi_linked) { mi = mpegts_input_find(mi->mi_linked); if (mi) @@ -193,181 +172,167 @@ mpegts_input_class_linked_get ( void *self ) return &prop_sbuf_ptr; } -static htsmsg_t * -mpegts_input_class_linked_enum( void * self, const char *lang ) -{ +static htsmsg_t* mpegts_input_class_linked_enum(void* self, const char* lang) { mpegts_input_t *mi = self, *mi2; - tvh_input_t *ti; - char ubuf[UUID_HEX_SIZE], buf[384]; - htsmsg_t *m = htsmsg_create_list(); - htsmsg_t *e = htsmsg_create_key_val("", tvh_gettext_lang(lang, N_("Not linked"))); + tvh_input_t* ti; + char ubuf[UUID_HEX_SIZE], buf[384]; + htsmsg_t* m = htsmsg_create_list(); + htsmsg_t* e = htsmsg_create_key_val("", tvh_gettext_lang(lang, N_("Not linked"))); htsmsg_add_msg(m, NULL, e); - TVH_INPUT_FOREACH(ti) + TVH_INPUT_FOREACH (ti) if (idnode_is_instance(&ti->ti_id, &mpegts_input_class)) { - mi2 = (mpegts_input_t *)ti; + mi2 = (mpegts_input_t*)ti; if (mi2 != mi) { e = htsmsg_create_key_val(idnode_uuid_as_str(&ti->ti_id, ubuf), - idnode_get_title(&mi2->ti_id, lang, buf, sizeof(buf))); + idnode_get_title(&mi2->ti_id, lang, buf, sizeof(buf))); htsmsg_add_msg(m, NULL, e); } - } + } return m; } PROP_DOC(priority) PROP_DOC(streaming_priority) -const idclass_t mpegts_input_class = -{ - .ic_super = &tvh_input_class, - .ic_class = "mpegts_input", - .ic_caption = N_("MPEG-TS input"), - .ic_event = "mpegts_input", - .ic_perm_def = ACCESS_ADMIN, - .ic_get_title = mpegts_input_class_get_title, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "active", - .name = N_("Active"), - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, - .get = mpegts_input_class_active_get, - }, - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable tuner/adapter."), - .off = offsetof(mpegts_input_t, mi_enabled), - .notify = mpegts_input_enabled_notify, - .def.i = 1, - }, - { - .type = PT_INT, - .id = "priority", - .name = N_("Priority"), - .desc = N_("The tuner priority value (a higher value means to " - "use this tuner out of preference). See Help for details."), - .doc = prop_doc_priority, - .off = offsetof(mpegts_input_t, mi_priority), - .def.i = 1, - .opts = PO_ADVANCED - }, - { - .type = PT_INT, - .id = "spriority", - .name = N_("Streaming priority"), - .desc = N_("The tuner priority value for streamed channels " - "through HTTP or HTSP (a higher value means to use " - "this tuner out of preference). If not set (zero), " - "the standard priority value is used. See Help for details."), - .doc = prop_doc_streaming_priority, - .off = offsetof(mpegts_input_t, mi_streaming_priority), - .def.i = 1, - .opts = PO_ADVANCED - }, - { - .type = PT_STR, - .id = "displayname", - .name = N_("Name"), - .desc = N_("Name of the tuner/adapter."), - .off = offsetof(mpegts_input_t, mi_name), - .notify = idnode_notify_title_changed_lang, - }, - { - .type = PT_BOOL, - .id = "ota_epg", - .name = N_("Over-the-air EPG"), - .desc = N_("Enable over-the-air program guide (EPG) scanning " - "on this input device."), - .off = offsetof(mpegts_input_t, mi_ota_epg), - .def.i = 1, - }, - { - .type = PT_BOOL, - .id = "initscan", - .name = N_("Initial scan"), - .desc = N_("Allow the initial scan tuning on this device " - "(scan when Tvheadend starts or when a new multiplex " - "is added automatically). At least one tuner or input " - "should have this settings turned on. " - "See also 'Skip Startup Scan' in the network settings " - "for further details."), - .off = offsetof(mpegts_input_t, mi_initscan), - .def.i = 1, - .opts = PO_ADVANCED, - }, - { - .type = PT_BOOL, - .id = "idlescan", - .name = N_("Idle scan"), - .desc = N_("Allow idle scan tuning on this device."), - .off = offsetof(mpegts_input_t, mi_idlescan), - .def.i = 1, - .opts = PO_ADVANCED, - }, - { - .type = PT_U32, - .id = "free_weight", - .name = N_("Free subscription weight"), - .desc = N_("If the subscription weight for the input is below " - "the specified threshold, the tuner is handled as free " - "(according the priority settings). Otherwise, the next " - "tuner (without any subscriptions) is used. Set this value " - "to 10, if you are willing to override scan and epggrab " - "subscriptions."), - .off = offsetof(mpegts_input_t, mi_free_weight), - .def.i = 1, - .opts = PO_ADVANCED, - }, - { - .type = PT_BOOL, - .id = "remove_scrambled", - .name = N_("Remove scrambled bits"), - .desc = N_("The scrambled bits in MPEG-TS packets are always cleared. " - "It is a workaround for the special streams which are " - "descrambled, but these bits are not touched."), - .off = offsetof(mpegts_input_t, mi_remove_scrambled_bits), - .def.i = 1, - .opts = PO_EXPERT, - }, - { - .type = PT_STR, - .id = "networks", - .name = N_("Networks"), - .desc = N_("Associate this device with one or more networks."), - .islist = 1, - .set = mpegts_input_class_network_set, - .get = mpegts_input_class_network_get, - .list = mpegts_input_class_network_enum, - .rend = mpegts_input_class_network_rend, - }, - { - .type = PT_STR, - .id = "linked", - .name = N_("Linked input"), - .desc = N_("Wake up the linked input whenever this adapter " - "is used. The subscriptions are named as \"keep\". " - "Note that this isn't normally needed, and is here " - "simply as a workaround to driver bugs in certain " - "dual tuner cards that otherwise lock the second tuner."), - .set = mpegts_input_class_linked_set, - .get = mpegts_input_class_linked_get, - .list = mpegts_input_class_linked_enum, - .opts = PO_ADVANCED, - }, - {} - } -}; +const idclass_t mpegts_input_class = {.ic_super = &tvh_input_class, + .ic_class = "mpegts_input", + .ic_caption = N_("MPEG-TS input"), + .ic_event = "mpegts_input", + .ic_perm_def = ACCESS_ADMIN, + .ic_get_title = mpegts_input_class_get_title, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "active", + .name = N_("Active"), + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, + .get = mpegts_input_class_active_get, + }, + { + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable tuner/adapter."), + .off = offsetof(mpegts_input_t, mi_enabled), + .notify = mpegts_input_enabled_notify, + .def.i = 1, + }, + {.type = PT_INT, + .id = "priority", + .name = N_("Priority"), + .desc = N_("The tuner priority value (a higher value means to " + "use this tuner out of preference). See Help for details."), + .doc = prop_doc_priority, + .off = offsetof(mpegts_input_t, mi_priority), + .def.i = 1, + .opts = PO_ADVANCED}, + {.type = PT_INT, + .id = "spriority", + .name = N_("Streaming priority"), + .desc = N_("The tuner priority value for streamed channels " + "through HTTP or HTSP (a higher value means to use " + "this tuner out of preference). If not set (zero), " + "the standard priority value is used. See Help for details."), + .doc = prop_doc_streaming_priority, + .off = offsetof(mpegts_input_t, mi_streaming_priority), + .def.i = 1, + .opts = PO_ADVANCED}, + { + .type = PT_STR, + .id = "displayname", + .name = N_("Name"), + .desc = N_("Name of the tuner/adapter."), + .off = offsetof(mpegts_input_t, mi_name), + .notify = idnode_notify_title_changed_lang, + }, + { + .type = PT_BOOL, + .id = "ota_epg", + .name = N_("Over-the-air EPG"), + .desc = N_("Enable over-the-air program guide (EPG) scanning " + "on this input device."), + .off = offsetof(mpegts_input_t, mi_ota_epg), + .def.i = 1, + }, + { + .type = PT_BOOL, + .id = "initscan", + .name = N_("Initial scan"), + .desc = N_("Allow the initial scan tuning on this device " + "(scan when Tvheadend starts or when a new multiplex " + "is added automatically). At least one tuner or input " + "should have this settings turned on. " + "See also 'Skip Startup Scan' in the network settings " + "for further details."), + .off = offsetof(mpegts_input_t, mi_initscan), + .def.i = 1, + .opts = PO_ADVANCED, + }, + { + .type = PT_BOOL, + .id = "idlescan", + .name = N_("Idle scan"), + .desc = N_("Allow idle scan tuning on this device."), + .off = offsetof(mpegts_input_t, mi_idlescan), + .def.i = 1, + .opts = PO_ADVANCED, + }, + { + .type = PT_U32, + .id = "free_weight", + .name = N_("Free subscription weight"), + .desc = N_("If the subscription weight for the input is below " + "the specified threshold, the tuner is handled as free " + "(according the priority settings). Otherwise, the next " + "tuner (without any subscriptions) is used. Set this value " + "to 10, if you are willing to override scan and epggrab " + "subscriptions."), + .off = offsetof(mpegts_input_t, mi_free_weight), + .def.i = 1, + .opts = PO_ADVANCED, + }, + { + .type = PT_BOOL, + .id = "remove_scrambled", + .name = N_("Remove scrambled bits"), + .desc = N_("The scrambled bits in MPEG-TS packets are always cleared. " + "It is a workaround for the special streams which are " + "descrambled, but these bits are not touched."), + .off = offsetof(mpegts_input_t, mi_remove_scrambled_bits), + .def.i = 1, + .opts = PO_EXPERT, + }, + { + .type = PT_STR, + .id = "networks", + .name = N_("Networks"), + .desc = N_("Associate this device with one or more networks."), + .islist = 1, + .set = mpegts_input_class_network_set, + .get = mpegts_input_class_network_get, + .list = mpegts_input_class_network_enum, + .rend = mpegts_input_class_network_rend, + }, + { + .type = PT_STR, + .id = "linked", + .name = N_("Linked input"), + .desc = N_("Wake up the linked input whenever this adapter " + "is used. The subscriptions are named as \"keep\". " + "Note that this isn't normally needed, and is here " + "simply as a workaround to driver bugs in certain " + "dual tuner cards that otherwise lock the second tuner."), + .set = mpegts_input_class_linked_set, + .get = mpegts_input_class_linked_get, + .list = mpegts_input_class_linked_enum, + .opts = PO_ADVANCED, + }, + {}}}; /* ************************************************************************** * Class methods * *************************************************************************/ -int -mpegts_input_is_enabled - ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) -{ +int mpegts_input_is_enabled(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight) { if ((flags & SUBSCRIPTION_EPG) != 0 && !mi->mi_ota_epg) return MI_IS_ENABLED_NEVER; if ((flags & SUBSCRIPTION_USERSCAN) == 0) { @@ -379,21 +344,17 @@ mpegts_input_is_enabled return mi->mi_enabled ? MI_IS_ENABLED_OK : MI_IS_ENABLED_NEVER; } -void -mpegts_input_set_enabled ( mpegts_input_t *mi, int enabled ) -{ +void mpegts_input_set_enabled(mpegts_input_t* mi, int enabled) { enabled = !!enabled; if (mi->mi_enabled != enabled) { - htsmsg_t *conf = htsmsg_create_map(); + htsmsg_t* conf = htsmsg_create_map(); htsmsg_add_bool(conf, "enabled", enabled); idnode_update(&mi->ti_id, conf); htsmsg_destroy(conf); } } -static void -mpegts_input_display_name ( mpegts_input_t *mi, char *buf, size_t len ) -{ +static void mpegts_input_display_name(mpegts_input_t* mi, char* buf, size_t len) { if (mi->mi_name) { strlcpy(buf, mi->mi_name, len); } else { @@ -401,19 +362,17 @@ mpegts_input_display_name ( mpegts_input_t *mi, char *buf, size_t len ) } } -int -mpegts_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) -{ - const mpegts_mux_instance_t *mmi; - const service_t *s; - const th_subscription_t *ths; - int w = 0, count = 0; +int mpegts_input_get_weight(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight) { + const mpegts_mux_instance_t* mmi; + const service_t* s; + const th_subscription_t* ths; + int w = 0, count = 0; /* Service subs */ tvh_mutex_lock(&mi->mi_output_lock); - LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link) - LIST_FOREACH(s, &mmi->mmi_mux->mm_transports, s_active_link) - LIST_FOREACH(ths, &s->s_subscriptions, ths_service_link) { + LIST_FOREACH (mmi, &mi->mi_mux_active, mmi_active_link) + LIST_FOREACH (s, &mmi->mmi_mux->mm_transports, s_active_link) + LIST_FOREACH (ths, &s->s_subscriptions, ths_service_link) { w = MAX(w, ths->ths_weight); count++; } @@ -421,9 +380,7 @@ mpegts_input_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int w return w > 0 ? w + count - 1 : 0; } -int -mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) -{ +int mpegts_input_get_priority(mpegts_input_t* mi, mpegts_mux_t* mm, int flags) { if (flags & SUBSCRIPTION_STREAMING) { if (mi->mi_streaming_priority > 0) return mi->mi_streaming_priority; @@ -431,10 +388,8 @@ mpegts_input_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) return mi->mi_priority; } -int -mpegts_input_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ - mpegts_mux_instance_t *cur; +int mpegts_input_warm_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { + mpegts_mux_instance_t* cur; cur = LIST_FIRST(&mi->mi_mux_active); if (cur != NULL) { @@ -450,66 +405,62 @@ mpegts_input_warm_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) return 0; } -static int -mpegts_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weight ) -{ +static int mpegts_input_start_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi, int weight) { return SM_CODE_TUNING_FAILED; } -static void -mpegts_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ -} +static void mpegts_input_stop_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) {} -int -mpegts_mps_cmp ( mpegts_pid_sub_t *a, mpegts_pid_sub_t *b ) -{ +int mpegts_mps_cmp(mpegts_pid_sub_t* a, mpegts_pid_sub_t* b) { const int mask = MPS_SERVICE; if ((a->mps_type & mask) != (b->mps_type & mask)) return (a->mps_type & mask) ? 1 : -1; - if (a->mps_owner < b->mps_owner) return -1; - if (a->mps_owner > b->mps_owner) return 1; + if (a->mps_owner < b->mps_owner) + return -1; + if (a->mps_owner > b->mps_owner) + return 1; return 0; } -void -mpegts_input_close_pids - ( mpegts_input_t *mi, mpegts_mux_t *mm, void *owner, int all ) -{ - mpegts_pid_t *mp, *mp_next; +void mpegts_input_close_pids(mpegts_input_t* mi, mpegts_mux_t* mm, void* owner, int all) { + mpegts_pid_t * mp, *mp_next; mpegts_pid_sub_t *mps, *mps_next; - int pid; + int pid; if (all) for (mps = LIST_FIRST(&mm->mm_all_subs); mps; mps = mps_next) { mps_next = LIST_NEXT(mps, mps_svcraw_link); - if (mps->mps_owner != owner) continue; + if (mps->mps_owner != owner) + continue; pid = MPEGTS_FULLMUX_PID; - if (mps->mps_type & MPS_TABLES) pid = MPEGTS_TABLES_PID; + if (mps->mps_type & MPS_TABLES) + pid = MPEGTS_TABLES_PID; mpegts_input_close_pid(mi, mm, pid, mps->mps_type, mps->mps_owner); } for (mp = RB_FIRST(&mm->mm_pids); mp; mp = mp_next) { mp_next = RB_NEXT(mp, mp_link); for (mps = RB_FIRST(&mp->mp_subs); mps; mps = mps_next) { mps_next = RB_NEXT(mps, mps_link); - if (mps->mps_owner != owner) continue; + if (mps->mps_owner != owner) + continue; mpegts_input_close_pid(mi, mm, mp->mp_pid, mps->mps_type, mps->mps_owner); } } } -mpegts_pid_t * -mpegts_input_open_pid - ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, - void *owner, int reopen ) -{ - mpegts_pid_t *mp; +mpegts_pid_t* mpegts_input_open_pid(mpegts_input_t* mi, + mpegts_mux_t* mm, + int pid, + int type, + int weight, + void* owner, + int reopen) { + mpegts_pid_t* mp; mpegts_pid_sub_t *mps, *mps2; assert(owner != NULL); - assert((type & (MPS_STREAM|MPS_SERVICE|MPS_RAW)) == 0 || - (((type & MPS_STREAM) ? 1 : 0) + - ((type & MPS_SERVICE) ? 1 : 0) + + assert((type & (MPS_STREAM | MPS_SERVICE | MPS_RAW)) == 0 || + (((type & MPS_STREAM) ? 1 : 0) + ((type & MPS_SERVICE) ? 1 : 0) + ((type & MPS_RAW) ? 1 : 0)) == 1); lock_assert(&mi->mi_output_lock); @@ -517,24 +468,32 @@ mpegts_input_open_pid mpegts_input_close_pids(mi, mm, owner, 1); if ((mp = mpegts_mux_find_pid(mm, pid, 1))) { - mps = calloc(1, sizeof(*mps)); + mps = calloc(1, sizeof(*mps)); mps->mps_type = type; mps->mps_weight = weight; mps->mps_owner = owner; if (pid == MPEGTS_FULLMUX_PID || pid == MPEGTS_TABLES_PID) { mp->mp_type |= type; - LIST_FOREACH(mps2, &mm->mm_all_subs, mps_svcraw_link) - if (mps2->mps_owner == owner) break; + LIST_FOREACH (mps2, &mm->mm_all_subs, mps_svcraw_link) + if (mps2->mps_owner == owner) + break; if (mps2 == NULL) { LIST_INSERT_HEAD(&mm->mm_all_subs, mps, mps_svcraw_link); - tvhdebug(LS_MPEGTS, "%s - open PID %s subscription [%04x/%p]", - mm->mm_nicename, (type & MPS_TABLES) ? "tables" : "fullmux", type, owner); + tvhdebug(LS_MPEGTS, + "%s - open PID %s subscription [%04x/%p]", + mm->mm_nicename, + (type & MPS_TABLES) ? "tables" : "fullmux", + type, + owner); mm->mm_update_pids_flag = 1; } else { if (!reopen) { tvherror(LS_MPEGTS, - "%s - open PID %04x (%d) failed, dupe sub (owner %p)", - mm->mm_nicename, mp->mp_pid, mp->mp_pid, owner); + "%s - open PID %04x (%d) failed, dupe sub (owner %p)", + mm->mm_nicename, + mp->mp_pid, + mp->mp_pid, + owner); } free(mps); mp = NULL; @@ -545,13 +504,22 @@ mpegts_input_open_pid LIST_INSERT_HEAD(&mp->mp_raw_subs, mps, mps_raw_link); if (type & MPS_SERVICE) LIST_INSERT_HEAD(&mp->mp_svc_subs, mps, mps_svcraw_link); - tvhdebug(LS_MPEGTS, "%s - open PID %04X (%d) [%d/%p]", - mm->mm_nicename, mp->mp_pid, mp->mp_pid, type, owner); + tvhdebug(LS_MPEGTS, + "%s - open PID %04X (%d) [%d/%p]", + mm->mm_nicename, + mp->mp_pid, + mp->mp_pid, + type, + owner); mm->mm_update_pids_flag = 1; } else { if (!reopen) { - tvherror(LS_MPEGTS, "%s - open PID %04x (%d) failed, dupe sub (owner %p)", - mm->mm_nicename, mp->mp_pid, mp->mp_pid, owner); + tvherror(LS_MPEGTS, + "%s - open PID %04x (%d) failed, dupe sub (owner %p)", + mm->mm_nicename, + mp->mp_pid, + mp->mp_pid, + owner); } free(mps); mp = NULL; @@ -560,45 +528,54 @@ mpegts_input_open_pid return mp; } -int -mpegts_input_close_pid - ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, void *owner ) -{ +int mpegts_input_close_pid(mpegts_input_t* mi, mpegts_mux_t* mm, int pid, int type, void* owner) { mpegts_pid_sub_t *mps, skel; - mpegts_pid_t *mp; - int mask; + mpegts_pid_t* mp; + int mask; assert(owner != NULL); lock_assert(&mi->mi_output_lock); if (!(mp = mpegts_mux_find_pid(mm, pid, 0))) return -1; if (pid == MPEGTS_FULLMUX_PID || pid == MPEGTS_TABLES_PID) { - LIST_FOREACH(mps, &mm->mm_all_subs, mps_svcraw_link) - if (mps->mps_owner == owner) break; - if (mps == NULL) return -1; - tvhdebug(LS_MPEGTS, "%s - close PID %s subscription [%04x/%p]", - mm->mm_nicename, pid == MPEGTS_TABLES_PID ? "tables" : "fullmux", - type, owner); + LIST_FOREACH (mps, &mm->mm_all_subs, mps_svcraw_link) + if (mps->mps_owner == owner) + break; + if (mps == NULL) + return -1; + tvhdebug(LS_MPEGTS, + "%s - close PID %s subscription [%04x/%p]", + mm->mm_nicename, + pid == MPEGTS_TABLES_PID ? "tables" : "fullmux", + type, + owner); if (pid == MPEGTS_FULLMUX_PID) mpegts_input_close_pids(mi, mm, owner, 0); LIST_REMOVE(mps, mps_svcraw_link); free(mps); mm->mm_update_pids_flag = 1; - mask = pid == MPEGTS_FULLMUX_PID ? MPS_ALL : MPS_TABLES; - LIST_FOREACH(mps, &mm->mm_all_subs, mps_svcraw_link) - if (mps->mps_type & mask) break; - if (mps) return 0; + mask = pid == MPEGTS_FULLMUX_PID ? MPS_ALL : MPS_TABLES; + LIST_FOREACH (mps, &mm->mm_all_subs, mps_svcraw_link) + if (mps->mps_type & mask) + break; + if (mps) + return 0; } else { skel.mps_type = type; skel.mps_weight = -1; skel.mps_owner = owner; - mps = RB_FIND(&mp->mp_subs, &skel, mps_link, mpegts_mps_cmp); + mps = RB_FIND(&mp->mp_subs, &skel, mps_link, mpegts_mps_cmp); if (pid == mm->mm_last_pid) { mm->mm_last_pid = -1; - mm->mm_last_mp = NULL; + mm->mm_last_mp = NULL; } if (mps) { - tvhdebug(LS_MPEGTS, "%s - close PID %04X (%d) [%d/%p]", - mm->mm_nicename, mp->mp_pid, mp->mp_pid, type, owner); + tvhdebug(LS_MPEGTS, + "%s - close PID %04X (%d) [%d/%p]", + mm->mm_nicename, + mp->mp_pid, + mp->mp_pid, + type, + owner); if (type & MPS_RAW) LIST_REMOVE(mps, mps_raw_link); if (type & MPS_SERVICE) @@ -611,60 +588,75 @@ mpegts_input_close_pid if (!RB_FIRST(&mp->mp_subs)) { if (mm->mm_last_pid == mp->mp_pid) { mm->mm_last_pid = -1; - mm->mm_last_mp = NULL; + mm->mm_last_mp = NULL; } RB_REMOVE(&mm->mm_pids, mp, mp_link); free(mp); return 1; } else { type = 0; - RB_FOREACH(mps, &mp->mp_subs, mps_link) + RB_FOREACH (mps, &mp->mp_subs, mps_link) type |= mps->mps_type; mp->mp_type = type; } return 0; } -mpegts_pid_t * -mpegts_input_update_pid_weight - ( mpegts_input_t *mi, mpegts_mux_t *mm, int pid, int type, int weight, - void *owner ) -{ +mpegts_pid_t* mpegts_input_update_pid_weight(mpegts_input_t* mi, + mpegts_mux_t* mm, + int pid, + int type, + int weight, + void* owner) { mpegts_pid_sub_t *mps, skel; - mpegts_pid_t *mp; + mpegts_pid_t* mp; assert(owner != NULL); lock_assert(&mi->mi_output_lock); if (!(mp = mpegts_mux_find_pid(mm, pid, 0))) return NULL; if (pid == MPEGTS_FULLMUX_PID || pid == MPEGTS_TABLES_PID) { - LIST_FOREACH(mps, &mm->mm_all_subs, mps_svcraw_link) - if (mps->mps_owner == owner) break; - if (mps == NULL) return NULL; - tvhdebug(LS_MPEGTS, "%s - update PID %s weight %d subscription [%04x/%p]", - mm->mm_nicename, pid == MPEGTS_TABLES_PID ? "tables" : "fullmux", - weight, type, owner); + LIST_FOREACH (mps, &mm->mm_all_subs, mps_svcraw_link) + if (mps->mps_owner == owner) + break; + if (mps == NULL) + return NULL; + tvhdebug(LS_MPEGTS, + "%s - update PID %s weight %d subscription [%04x/%p]", + mm->mm_nicename, + pid == MPEGTS_TABLES_PID ? "tables" : "fullmux", + weight, + type, + owner); mps->mps_weight = weight; } else { skel.mps_type = type; skel.mps_weight = -1; skel.mps_owner = owner; - mps = RB_FIND(&mp->mp_subs, &skel, mps_link, mpegts_mps_cmp); - if (mps == NULL) return NULL; - tvhdebug(LS_MPEGTS, "%s - update PID %04X (%d) weight %d [%d/%p]", - mm->mm_nicename, mp->mp_pid, mp->mp_pid, weight, type, owner); - mps->mps_weight = weight; + mps = RB_FIND(&mp->mp_subs, &skel, mps_link, mpegts_mps_cmp); + if (mps == NULL) + return NULL; + tvhdebug(LS_MPEGTS, + "%s - update PID %04X (%d) weight %d [%d/%p]", + mm->mm_nicename, + mp->mp_pid, + mp->mp_pid, + weight, + type, + owner); + mps->mps_weight = weight; mm->mm_update_pids_flag = 1; } return mp; } -elementary_stream_t * -mpegts_input_open_service_pid - ( mpegts_input_t *mi, mpegts_mux_t *mm, - service_t *s, streaming_component_type_t stype, - int pid, int weight, int create ) -{ - elementary_stream_t *es; +elementary_stream_t* mpegts_input_open_service_pid(mpegts_input_t* mi, + mpegts_mux_t* mm, + service_t* s, + streaming_component_type_t stype, + int pid, + int weight, + int create) { + elementary_stream_t* es; lock_assert(&s->s_stream_mutex); @@ -672,70 +664,71 @@ mpegts_input_open_service_pid if (elementary_stream_find(&s->s_components, pid) == NULL) { if (!create) return NULL; - es = elementary_stream_create(&s->s_components, pid, stype); + es = elementary_stream_create(&s->s_components, pid, stype); es->es_pid_opened = 1; } if (es && mm->mm_active) { - mpegts_input_open_pid(mi, mm, pid, - MPS_SERVICE, weight, s, 0); + mpegts_input_open_pid(mi, mm, pid, MPS_SERVICE, weight, s, 0); } return es; } -static void -mpegts_input_update_pids - ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ +static void mpegts_input_update_pids(mpegts_input_t* mi, mpegts_mux_t* mm) { /* nothing - override */ } -int mpegts_mps_weight(elementary_stream_t *st) -{ - if (SCT_ISVIDEO(st->es_type)) - return MPS_WEIGHT_VIDEO + MIN(st->es_index, 49); - else if (SCT_ISAUDIO(st->es_type)) - return MPS_WEIGHT_AUDIO + MIN(st->es_index, 49); - else if (SCT_ISSUBTITLE(st->es_type)) - return MPS_WEIGHT_SUBTITLE + MIN(st->es_index, 49); - else - return MPS_WEIGHT_ESOTHER + MIN(st->es_index, 49); +int mpegts_mps_weight(elementary_stream_t* st) { + if (SCT_ISVIDEO(st->es_type)) + return MPS_WEIGHT_VIDEO + MIN(st->es_index, 49); + else if (SCT_ISAUDIO(st->es_type)) + return MPS_WEIGHT_AUDIO + MIN(st->es_index, 49); + else if (SCT_ISSUBTITLE(st->es_type)) + return MPS_WEIGHT_SUBTITLE + MIN(st->es_index, 49); + else + return MPS_WEIGHT_ESOTHER + MIN(st->es_index, 49); } typedef struct __cat_pass_aux { - mpegts_input_t *mi; - mpegts_mux_t *mm; - service_t *service; + mpegts_input_t* mi; + mpegts_mux_t* mm; + service_t* service; } __cat_pass_aux_t; -static void -mpegts_input_cat_pass_entry - (void *_aux, uint16_t caid, uint32_t prov, uint16_t pid) -{ - __cat_pass_aux_t *aux = _aux; - elementary_stream_t *es; - caid_t *c; - - tvhdebug(LS_TBL_BASE, "cat: pass: caid %04X (%d) pid %04X (%d)", - (uint16_t)caid, (uint16_t)caid, pid, pid); - es = mpegts_input_open_service_pid(aux->mi, aux->mm, aux->service, - SCT_CAT, pid, MPS_WEIGHT_CAT, 1); +static void mpegts_input_cat_pass_entry(void* _aux, uint16_t caid, uint32_t prov, uint16_t pid) { + __cat_pass_aux_t* aux = _aux; + elementary_stream_t* es; + caid_t* c; + + tvhdebug(LS_TBL_BASE, + "cat: pass: caid %04X (%d) pid %04X (%d)", + (uint16_t)caid, + (uint16_t)caid, + pid, + pid); + es = mpegts_input_open_service_pid(aux->mi, + aux->mm, + aux->service, + SCT_CAT, + pid, + MPS_WEIGHT_CAT, + 1); if (es) { - LIST_FOREACH(c, &es->es_caids, link) { + LIST_FOREACH (c, &es->es_caids, link) { if (c->pid == pid) { - c->caid = caid; - c->delete_me = 0; + c->caid = caid; + c->delete_me = 0; es->es_delete_me = 0; break; } } if (c == NULL) { - c = malloc(sizeof(caid_t)); - c->caid = caid; + c = malloc(sizeof(caid_t)); + c->caid = caid; c->providerid = 0; - c->use = 1; - c->pid = pid; - c->delete_me = 0; - c->filter = 0; + c->use = 1; + c->pid = pid; + c->delete_me = 0; + c->filter = 0; LIST_INSERT_HEAD(&es->es_caids, c, link); es->es_delete_me = 0; } @@ -743,22 +736,20 @@ mpegts_input_cat_pass_entry } static int -mpegts_input_cat_pass_callback - (mpegts_table_t *mt, const uint8_t *ptr, int len, int tableid) -{ - int r, sect, last, ver; - mpegts_mux_t *mm = mt->mt_mux; - mpegts_psi_table_state_t *st = NULL; - service_t *s = mt->mt_opaque; - mpegts_input_t *mi; - elementary_stream_t *es, *next; - caid_t *c, *cn; - __cat_pass_aux_t aux; +mpegts_input_cat_pass_callback(mpegts_table_t* mt, const uint8_t* ptr, int len, int tableid) { + int r, sect, last, ver; + mpegts_mux_t* mm = mt->mt_mux; + mpegts_psi_table_state_t* st = NULL; + service_t* s = mt->mt_opaque; + mpegts_input_t* mi; + elementary_stream_t * es, *next; + caid_t * c, *cn; + __cat_pass_aux_t aux; /* Start */ - r = dvb_table_begin((mpegts_psi_table_t *)mt, ptr, len, - tableid, 0, 5, &st, §, &last, &ver, 0); - if (r != 1) return r; + r = dvb_table_begin((mpegts_psi_table_t*)mt, ptr, len, tableid, 0, 5, &st, §, &last, &ver, 0); + if (r != 1) + return r; ptr += 5; len -= 5; @@ -766,26 +757,29 @@ mpegts_input_cat_pass_callback descrambler_cat_data(mm, ptr, len); mi = mm->mm_active ? mm->mm_active->mmi_input : NULL; - if (mi == NULL) goto fin; + if (mi == NULL) + goto fin; tvh_mutex_lock(&mi->mi_output_lock); tvh_mutex_lock(&s->s_stream_mutex); - TAILQ_FOREACH(es, &s->s_components.set_all, es_link) { - if (es->es_type != SCT_CAT) continue; + TAILQ_FOREACH (es, &s->s_components.set_all, es_link) { + if (es->es_type != SCT_CAT) + continue; es->es_delete_me = 1; - LIST_FOREACH(c, &es->es_caids, link) + LIST_FOREACH (c, &es->es_caids, link) c->delete_me = 1; } - aux.mi = mi; - aux.mm = mm; + aux.mi = mi; + aux.mm = mm; aux.service = s; dvb_cat_decode(ptr, len, mpegts_input_cat_pass_entry, &aux); for (es = TAILQ_FIRST(&s->s_components.set_all); es != NULL; es = next) { next = TAILQ_NEXT(es, es_link); - if (es->es_type != SCT_CAT) continue; + if (es->es_type != SCT_CAT) + continue; for (c = LIST_FIRST(&es->es_caids); c != NULL; c = cn) { cn = LIST_NEXT(c, link); if (c->delete_me) { @@ -802,43 +796,49 @@ mpegts_input_cat_pass_callback /* Finish */ fin: - return dvb_table_end((mpegts_psi_table_t *)mt, st, sect); + return dvb_table_end((mpegts_psi_table_t*)mt, st, sect); } -void -mpegts_input_open_pmt_monitor - ( mpegts_mux_t *mm, mpegts_service_t *s ) -{ - if (s->s_pmt_mon) - mpegts_table_destroy(s->s_pmt_mon); - s->s_pmt_mon = - mpegts_table_add(mm, DVB_PMT_BASE, DVB_PMT_MASK, - dvb_pmt_callback, s, "pmt", LS_TBL_BASE, - MT_CRC, s->s_components.set_pmt_pid, MPS_WEIGHT_PMT); +void mpegts_input_open_pmt_monitor(mpegts_mux_t* mm, mpegts_service_t* s) { + if (s->s_pmt_mon) + mpegts_table_destroy(s->s_pmt_mon); + s->s_pmt_mon = mpegts_table_add(mm, + DVB_PMT_BASE, + DVB_PMT_MASK, + dvb_pmt_callback, + s, + "pmt", + LS_TBL_BASE, + MT_CRC, + s->s_components.set_pmt_pid, + MPS_WEIGHT_PMT); } -void -mpegts_input_open_cat_monitor - ( mpegts_mux_t *mm, mpegts_service_t *s ) -{ +void mpegts_input_open_cat_monitor(mpegts_mux_t* mm, mpegts_service_t* s) { if (s->s_cat_mon) mpegts_table_destroy(s->s_cat_mon); - s->s_cat_mon = - mpegts_table_add(mm, DVB_CAT_BASE, DVB_CAT_MASK, - mpegts_input_cat_pass_callback, s, "cat", - LS_TBL_BASE, MT_QUICKREQ | MT_CRC, DVB_CAT_PID, - MPS_WEIGHT_CAT); -} - -void -mpegts_input_open_service - ( mpegts_input_t *mi, mpegts_service_t *s, int flags, int init, int weight ) -{ - mpegts_mux_t *mm = s->s_dvb_mux; - elementary_stream_t *st; - mpegts_apids_t *pids; - mpegts_apid_t *p; - int i, reopen = !init; + s->s_cat_mon = mpegts_table_add(mm, + DVB_CAT_BASE, + DVB_CAT_MASK, + mpegts_input_cat_pass_callback, + s, + "cat", + LS_TBL_BASE, + MT_QUICKREQ | MT_CRC, + DVB_CAT_PID, + MPS_WEIGHT_CAT); +} + +void mpegts_input_open_service(mpegts_input_t* mi, + mpegts_service_t* s, + int flags, + int init, + int weight) { + mpegts_mux_t* mm = s->s_dvb_mux; + elementary_stream_t* st; + mpegts_apids_t* pids; + mpegts_apid_t* p; + int i, reopen = !init; /* Add to list */ tvh_mutex_lock(&mi->mi_output_lock); @@ -853,19 +853,28 @@ mpegts_input_open_service if (s->s_components.set_pmt_pid == SERVICE_PMT_AUTO) goto no_pids; - mpegts_input_open_pid(mi, mm, s->s_components.set_pmt_pid, - MPS_SERVICE, MPS_WEIGHT_PMT, s, reopen); - mpegts_input_open_pid(mi, mm, s->s_components.set_pcr_pid, - MPS_SERVICE, MPS_WEIGHT_PCR, s, reopen); + mpegts_input_open_pid(mi, + mm, + s->s_components.set_pmt_pid, + MPS_SERVICE, + MPS_WEIGHT_PMT, + s, + reopen); + mpegts_input_open_pid(mi, + mm, + s->s_components.set_pcr_pid, + MPS_SERVICE, + MPS_WEIGHT_PCR, + s, + reopen); if (s->s_scrambled_pass) { mpegts_input_open_pid(mi, mm, DVB_CAT_PID, MPS_SERVICE, MPS_WEIGHT_CAT, s, reopen); s->s_cat_opened = 1; } /* Open only filtered components here */ - TAILQ_FOREACH(st, &s->s_components.set_filter, es_filter_link) + TAILQ_FOREACH (st, &s->s_components.set_filter, es_filter_link) if ((s->s_scrambled_pass || st->es_type != SCT_CA) && - st->es_pid != s->s_components.set_pmt_pid && - st->es_pid != s->s_components.set_pcr_pid && + st->es_pid != s->s_components.set_pmt_pid && st->es_pid != s->s_components.set_pcr_pid && st->es_pid < 8192) { st->es_pid_opened = 1; mpegts_input_open_pid(mi, mm, st->es_pid, MPS_SERVICE, mpegts_mps_weight(st), s, reopen); @@ -876,7 +885,13 @@ mpegts_input_open_service } else { if ((pids = s->s_pids) != NULL) { if (pids->all) { - mpegts_input_open_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW | MPS_ALL, MPS_WEIGHT_RAW, s, reopen); + mpegts_input_open_pid(mi, + mm, + MPEGTS_FULLMUX_PID, + MPS_RAW | MPS_ALL, + MPS_WEIGHT_RAW, + s, + reopen); } else { for (i = 0; i < pids->count; i++) { p = &pids->pids[i]; @@ -884,7 +899,13 @@ mpegts_input_open_service } } } else if (flags & SUBSCRIPTION_TABLES) { - mpegts_input_open_pid(mi, mm, MPEGTS_TABLES_PID, MPS_RAW | MPS_TABLES, MPS_WEIGHT_PAT, s, reopen); + mpegts_input_open_pid(mi, + mm, + MPEGTS_TABLES_PID, + MPS_RAW | MPS_TABLES, + MPS_WEIGHT_PAT, + s, + reopen); } else if (flags & SUBSCRIPTION_MINIMAL) { mpegts_input_open_pid(mi, mm, DVB_PAT_PID, MPS_RAW, MPS_WEIGHT_PAT, s, reopen); } @@ -904,11 +925,9 @@ no_pids: mpegts_mux_update_pids(mm); } -void -mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s ) -{ - mpegts_mux_t *mm = s->s_dvb_mux; - elementary_stream_t *st; +void mpegts_input_close_service(mpegts_input_t* mi, mpegts_service_t* s) { + mpegts_mux_t* mm = s->s_dvb_mux; + elementary_stream_t* st; /* Close PMT/CAT tables */ if (s->s_type == STYPE_STD) { @@ -940,7 +959,7 @@ mpegts_input_close_service ( mpegts_input_t *mi, mpegts_service_t *s ) s->s_cat_opened = 0; } /* Close all opened PIDs (the component filter may be changed at runtime) */ - TAILQ_FOREACH(st, &s->s_components.set_all, es_link) { + TAILQ_FOREACH (st, &s->s_components.set_all, es_link) { if (st->es_pid_opened) { st->es_pid_opened = 0; mpegts_input_close_pid(mi, mm, st->es_pid, MPS_SERVICE, s); @@ -963,23 +982,18 @@ no_pids: s->s_dvb_mux->mm_stop(s->s_dvb_mux, 0, SM_CODE_OK); } -void -mpegts_input_create_mux_instance - ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ +void mpegts_input_create_mux_instance(mpegts_input_t* mi, mpegts_mux_t* mm) { extern const idclass_t mpegts_mux_instance_class; - tvh_input_instance_t *tii; - LIST_FOREACH(tii, &mi->mi_mux_instances, tii_input_link) - if (((mpegts_mux_instance_t *)tii)->mmi_mux == mm) break; + tvh_input_instance_t* tii; + LIST_FOREACH (tii, &mi->mi_mux_instances, tii_input_link) + if (((mpegts_mux_instance_t*)tii)->mmi_mux == mm) + break; if (!tii) mpegts_mux_instance_create(mpegts_mux_instance, NULL, mi, mm); } -static void -mpegts_input_started_mux - ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ - mpegts_mux_t *mm = mmi->mmi_mux; +static void mpegts_input_started_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { + mpegts_mux_t* mm = mmi->mmi_mux; /* Deliver first TS packets as fast as possible */ atomic_set_s64(&mi->mi_last_dispatch, 0); @@ -997,10 +1011,7 @@ mpegts_input_started_mux mpegts_input_dbus_notify(mi, 1); } -static void -mpegts_input_stopping_mux - ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ +static void mpegts_input_stopping_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { assert(mmi->mmi_mux->mm_active); tvh_mutex_lock(&mi->mi_output_lock); @@ -1010,13 +1021,10 @@ mpegts_input_stopping_mux tvh_mutex_unlock(&mi->mi_output_lock); } -static void -mpegts_input_stopped_mux - ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ - char buf[256]; - service_t *s, *s_next; - mpegts_mux_t *mm = mmi->mmi_mux; +static void mpegts_input_stopped_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { + char buf[256]; + service_t * s, *s_next; + mpegts_mux_t* mm = mmi->mmi_mux; /* no longer active */ LIST_REMOVE(mmi, mmi_active_link); @@ -1035,18 +1043,18 @@ mpegts_input_stopped_mux mpegts_input_dbus_notify(mi, 0); } -static int -mpegts_input_has_subscription ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ - int ret = 0; - const service_t *t; - const th_subscription_t *ths; +static int mpegts_input_has_subscription(mpegts_input_t* mi, mpegts_mux_t* mm) { + int ret = 0; + const service_t* t; + const th_subscription_t* ths; tvh_mutex_lock(&mi->mi_output_lock); - LIST_FOREACH(t, &mm->mm_transports, s_active_link) { + LIST_FOREACH (t, &mm->mm_transports, s_active_link) { if (t->s_type == STYPE_RAW) { - LIST_FOREACH(ths, &t->s_subscriptions, ths_service_link) - if (!strcmp(ths->ths_title, "keep")) break; - if (ths) continue; + LIST_FOREACH (ths, &t->s_subscriptions, ths_service_link) + if (!strcmp(ths->ths_title, "keep")) + break; + if (ths) + continue; } ret = 1; break; @@ -1055,9 +1063,7 @@ mpegts_input_has_subscription ( mpegts_input_t *mi, mpegts_mux_t *mm ) return ret; } -static void -mpegts_input_error ( mpegts_input_t *mi, mpegts_mux_t *mm, int tss_flags ) -{ +static void mpegts_input_error(mpegts_input_t* mi, mpegts_mux_t* mm, int tss_flags) { service_t *t, *t_next; tvh_mutex_lock(&mi->mi_output_lock); for (t = LIST_FIRST(&mm->mm_transports); t; t = t_next) { @@ -1073,24 +1079,28 @@ mpegts_input_error ( mpegts_input_t *mi, mpegts_mux_t *mm, int tss_flags ) * Data processing * *************************************************************************/ -static void mpegts_input_analyze_table_queue ( mpegts_input_t *mi ) -{ - mpegts_table_feed_t *mtf; - uint32_t sizes[8192]; - uint16_t counters[8192]; - uint16_t pid; +static void mpegts_input_analyze_table_queue(mpegts_input_t* mi) { + mpegts_table_feed_t* mtf; + uint32_t sizes[8192]; + uint16_t counters[8192]; + uint16_t pid; memset(&sizes, 0, sizeof(sizes)); memset(&counters, 0, sizeof(counters)); - TAILQ_FOREACH(mtf, &mi->mi_table_queue, mtf_link) { - const uint8_t *tsb = mtf->mtf_tsb; - pid = ((tsb[1] & 0x1f) << 8) | tsb[2]; + TAILQ_FOREACH (mtf, &mi->mi_table_queue, mtf_link) { + const uint8_t* tsb = mtf->mtf_tsb; + pid = ((tsb[1] & 0x1f) << 8) | tsb[2]; sizes[pid] += mtf->mtf_len; counters[pid]++; } for (pid = 0; pid < 8192; pid++) if (counters[pid]) - tvhtrace(LS_MPEGTS, "table queue pid=%04X (%d) cnt %u len %u", pid, pid, counters[pid], sizes[pid]); + tvhtrace(LS_MPEGTS, + "table queue pid=%04X (%d) cnt %u len %u", + pid, + pid, + counters[pid], + sizes[pid]); } #if 0 @@ -1120,42 +1130,36 @@ static int data_noise ( mpegts_packet_t *mp ) return 0; } #else -static inline int data_noise( mpegts_packet_t *mp ) { return 0; } +static inline int data_noise(mpegts_packet_t* mp) { + return 0; +} #endif -static inline int -get_pcr ( const uint8_t *tsb, int64_t *rpcr ) -{ +static inline int get_pcr(const uint8_t* tsb, int64_t* rpcr) { int_fast64_t pcr; if (tsb[1] & 0x80) /* error bit */ return 0; - if ((tsb[3] & 0x20) == 0 || - tsb[4] <= 5 || - (tsb[5] & 0x10) == 0) + if ((tsb[3] & 0x20) == 0 || tsb[4] <= 5 || (tsb[5] & 0x10) == 0) return 0; - pcr = (uint64_t)tsb[6] << 25; - pcr |= (uint64_t)tsb[7] << 17; - pcr |= (uint64_t)tsb[8] << 9; - pcr |= (uint64_t)tsb[9] << 1; + pcr = (uint64_t)tsb[6] << 25; + pcr |= (uint64_t)tsb[7] << 17; + pcr |= (uint64_t)tsb[8] << 9; + pcr |= (uint64_t)tsb[9] << 1; pcr |= ((uint64_t)tsb[10] >> 7) & 0x01; *rpcr = pcr; return 1; } -static inline int -ts_sync_count ( const uint8_t *tsb, int len ) -{ - const uint8_t *start = tsb; +static inline int ts_sync_count(const uint8_t* tsb, int len) { + const uint8_t* start = tsb; while (len >= 188) { - if (len >= 1880 && - tsb[0*188] == 0x47 && tsb[1*188] == 0x47 && - tsb[2*188] == 0x47 && tsb[3*188] == 0x47 && - tsb[4*188] == 0x47 && tsb[5*188] == 0x47 && - tsb[6*188] == 0x47 && tsb[7*188] == 0x47 && - tsb[8*188] == 0x47 && tsb[9*188] == 0x47) { + if (len >= 1880 && tsb[0 * 188] == 0x47 && tsb[1 * 188] == 0x47 && tsb[2 * 188] == 0x47 && + tsb[3 * 188] == 0x47 && tsb[4 * 188] == 0x47 && tsb[5 * 188] == 0x47 && + tsb[6 * 188] == 0x47 && tsb[7 * 188] == 0x47 && tsb[8 * 188] == 0x47 && + tsb[9 * 188] == 0x47) { len -= 1880; tsb += 1880; } else if (*tsb == 0x47) { @@ -1168,17 +1172,14 @@ ts_sync_count ( const uint8_t *tsb, int len ) return tsb - start; } -static void -mpegts_input_queue_packets - ( mpegts_mux_instance_t *mmi, mpegts_packet_t *mp ) -{ - mpegts_input_t *mi = mmi->mmi_input; - const char *id = SRCLINEID(); - int len = mp->mp_len; +static void mpegts_input_queue_packets(mpegts_mux_instance_t* mmi, mpegts_packet_t* mp) { + mpegts_input_t* mi = mmi->mmi_input; + const char* id = SRCLINEID(); + int len = mp->mp_len; tvh_mutex_lock(&mi->mi_input_lock); if (mmi->mmi_mux->mm_active == mmi) { - if (mi->mi_input_queue_size < 50*1024*1024) { + if (mi->mi_input_queue_size < 50 * 1024 * 1024) { mi->mi_input_queue_size += len; memoryinfo_alloc(&mpegts_input_queue_memoryinfo, sizeof(mpegts_packet_t) + len); mpegts_mux_grab(mp->mp_mux); @@ -1188,7 +1189,9 @@ mpegts_input_queue_packets tvh_cond_signal(&mi->mi_input_cond, 0); } else { if (tvhlog_limit(&mi->mi_input_queue_loglimit, 10)) - tvhwarn(LS_MPEGTS, "too much queued input data (over 50MB) for %s, discarding new", mi->mi_name); + tvhwarn(LS_MPEGTS, + "too much queued input data (over 50MB) for %s, discarding new", + mi->mi_name); tprofile_queue_drop(&mi->mi_qprofile, id, len); free(mp); } @@ -1198,17 +1201,16 @@ mpegts_input_queue_packets tvh_mutex_unlock(&mi->mi_input_lock); } -void -mpegts_input_recv_packets - ( mpegts_mux_instance_t *mmi, sbuf_t *sb, - int flags, mpegts_pcr_t *pcr ) -{ - mpegts_input_t *mi = mmi->mmi_input; - int len, len2, off; - mpegts_packet_t *mp; - uint8_t *tsb; +void mpegts_input_recv_packets(mpegts_mux_instance_t* mmi, + sbuf_t* sb, + int flags, + mpegts_pcr_t* pcr) { + mpegts_input_t* mi = mmi->mmi_input; + int len, len2, off; + mpegts_packet_t* mp; + uint8_t* tsb; #define MIN_TS_PKT 100 -#define MIN_TS_SYN (5*188) +#define MIN_TS_SYN (5 * 188) if (sb->sb_ptr == 0) return; @@ -1225,8 +1227,7 @@ retry: atomic_set_s64(&mi->mi_last_dispatch, mclk()); /* Check for sync */ - while ( (len >= MIN_TS_SYN) && - ((len2 = ts_sync_count(tsb, len)) < MIN_TS_SYN) ) { + while ((len >= MIN_TS_SYN) && ((len2 = ts_sync_count(tsb, len)) < MIN_TS_SYN)) { atomic_add(&mmi->tii_stats.unc, 1); --len; ++tsb; @@ -1266,7 +1267,7 @@ retry: /* Pass */ if (len2 >= MIN_TS_SYN || (flags & MPEGTS_DATA_CC_RESTART)) { - mp = malloc(sizeof(mpegts_packet_t) + len2); + mp = malloc(sizeof(mpegts_packet_t) + len2); mp->mp_mux = mmi->mmi_mux; mp->mp_len = len2; mp->mp_cc_restart = (flags & MPEGTS_DATA_CC_RESTART) ? 1 : 0; @@ -1296,23 +1297,24 @@ end: if (sb->sb_ptr >= MIN_TS_PKT * 188) goto retry; } else - sb->sb_ptr = 0; // clear + sb->sb_ptr = 0; // clear } -static void -mpegts_input_table_dispatch - ( mpegts_mux_t *mm, const char *logprefix, const uint8_t *tsb, int tsb_len, int fast ) -{ - int i, len = 0, c = 0; - const uint8_t *tsb2, *tsb2_end; - uint16_t pid = ((tsb[1] & 0x1f) << 8) | tsb[2]; +static void mpegts_input_table_dispatch(mpegts_mux_t* mm, + const char* logprefix, + const uint8_t* tsb, + int tsb_len, + int fast) { + int i, len = 0, c = 0; + const uint8_t * tsb2, *tsb2_end; + uint16_t pid = ((tsb[1] & 0x1f) << 8) | tsb[2]; mpegts_table_t *mt, **vec; /* Collate - tables may be removed during callbacks */ tvh_mutex_lock(&mm->mm_tables_lock); - i = mm->mm_num_tables; - vec = alloca(i * sizeof(mpegts_table_t *)); - LIST_FOREACH(mt, &mm->mm_tables, mt_link) { + i = mm->mm_num_tables; + vec = alloca(i * sizeof(mpegts_table_t*)); + LIST_FOREACH (mt, &mm->mm_tables, mt_link) { c++; if (mt->mt_destroyed || !mt->mt_subscribed || mt->mt_pid != pid) continue; @@ -1336,21 +1338,21 @@ mpegts_input_table_dispatch mt = vec[i]; if (!mt->mt_destroyed && mt->mt_pid == pid) for (tsb2 = tsb, tsb2_end = tsb + tsb_len; tsb2 < tsb2_end; tsb2 += 188) - mpegts_psi_section_reassemble((mpegts_psi_table_t *)mt, logprefix, - tsb2, mt->mt_flags & MT_CRC, - mpegts_table_dispatch, mt); + mpegts_psi_section_reassemble((mpegts_psi_table_t*)mt, + logprefix, + tsb2, + mt->mt_flags & MT_CRC, + mpegts_table_dispatch, + mt); tprofile_finish(&mt->mt_profile); mpegts_table_release(mt); } } -static void -mpegts_input_table_restart - ( mpegts_mux_t *mm, const char *logprefix, int fast ) -{ - mpegts_table_t *mt; +static void mpegts_input_table_restart(mpegts_mux_t* mm, const char* logprefix, int fast) { + mpegts_table_t* mt; tvh_mutex_lock(&mm->mm_tables_lock); - LIST_FOREACH(mt, &mm->mm_tables, mt_link) { + LIST_FOREACH (mt, &mm->mm_tables, mt_link) { if (fast && (mt->mt_flags & MT_FAST) == 0) continue; if (!fast && (mt->mt_flags & MT_FAST) != 0) @@ -1360,14 +1362,13 @@ mpegts_input_table_restart tvh_mutex_unlock(&mm->mm_tables_lock); } -static mpegts_table_feed_t * -mpegts_input_table_feed_create ( mpegts_input_t *mi, mpegts_mux_t *mm, uint8_t *tsb, int llen ) -{ - mpegts_table_feed_t *mtf; +static mpegts_table_feed_t* +mpegts_input_table_feed_create(mpegts_input_t* mi, mpegts_mux_t* mm, uint8_t* tsb, int llen) { + mpegts_table_feed_t* mtf; - mtf = malloc(sizeof(mpegts_table_feed_t) + MAX(llen, MPEGTS_MTF_ALLOC_CHUNK)); + mtf = malloc(sizeof(mpegts_table_feed_t) + MAX(llen, MPEGTS_MTF_ALLOC_CHUNK)); mtf->mtf_cc_restart = 0; - mtf->mtf_len = llen; + mtf->mtf_len = llen; memcpy(mtf->mtf_tsb, tsb, llen); mtf->mtf_mux = mm; mi->mi_table_queue_size += llen; @@ -1376,10 +1377,8 @@ mpegts_input_table_feed_create ( mpegts_input_t *mi, mpegts_mux_t *mm, uint8_t * return mtf; } -static void -mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ - mpegts_table_t *mt; +static void mpegts_input_table_waiting(mpegts_input_t* mi, mpegts_mux_t* mm) { + mpegts_table_t* mt; if (!mm || !mm->mm_active) return; @@ -1415,24 +1414,21 @@ mpegts_input_table_waiting ( mpegts_input_t *mi, mpegts_mux_t *mm ) tvh_mutex_unlock(&mm->mm_tables_lock); } -static int -mpegts_input_process - ( mpegts_input_t *mi, mpegts_packet_t *mpkt ) -{ - uint16_t pid, pid2; - uint8_t cc, cc2; - uint8_t *tsb = mpkt->mp_data, *tsb2, *tsb2_end; - int len = mpkt->mp_len, llen; - int type = 0, f; - mpegts_pid_t *mp; - mpegts_pid_sub_t *mps; - service_t *s; - elementary_stream_t *st; - int table_wakeup = 0; - mpegts_mux_t *mm = mpkt->mp_mux; - mpegts_mux_instance_t *mmi; - mpegts_table_feed_t *mtf; - uint64_t tspos; +static int mpegts_input_process(mpegts_input_t* mi, mpegts_packet_t* mpkt) { + uint16_t pid, pid2; + uint8_t cc, cc2; + uint8_t * tsb = mpkt->mp_data, *tsb2, *tsb2_end; + int len = mpkt->mp_len, llen; + int type = 0, f; + mpegts_pid_t* mp; + mpegts_pid_sub_t* mps; + service_t* s; + elementary_stream_t* st; + int table_wakeup = 0; + mpegts_mux_t* mm = mpkt->mp_mux; + mpegts_mux_instance_t* mmi; + mpegts_table_feed_t* mtf; + uint64_t tspos; if (mm == NULL || (mmi = mm->mm_active) == NULL) return 0; @@ -1440,15 +1436,15 @@ mpegts_input_process assert(mm == mmi->mmi_mux); if (mpkt->mp_cc_restart) { - LIST_FOREACH(s, &mm->mm_transports, s_active_link) - TAILQ_FOREACH(st, &s->s_components.set_all, es_link) + LIST_FOREACH (s, &mm->mm_transports, s_active_link) + TAILQ_FOREACH (st, &s->s_components.set_all, es_link) st->es_cc = -1; - RB_FOREACH(mp, &mm->mm_pids, mp_link) { + RB_FOREACH (mp, &mm->mm_pids, mp_link) { mp->mp_cc = 0xff; if (mp->mp_type & MPS_FTABLE) { mpegts_input_table_restart(mm, mm->mm_nicename, 1); } else { - mtf = mpegts_input_table_feed_create(mi, mm, NULL, 0); + mtf = mpegts_input_table_feed_create(mi, mm, NULL, 0); mtf->mtf_cc_restart = 1; } } @@ -1492,8 +1488,7 @@ mpegts_input_process /* Low level CC check */ if (tsb[3] & 0x10) { - for (tsb2 = tsb, tsb2_end = tsb + llen, cc2 = mp->mp_cc; - tsb2 < tsb2_end; tsb2 += 188) { + for (tsb2 = tsb, tsb2_end = tsb + llen, cc2 = mp->mp_cc; tsb2 < tsb2_end; tsb2 += 188) { cc = tsb2[3] & 0x0f; if (cc2 != 0xff && cc2 != cc) { tvhtrace(LS_MPEGTS, "%s: pid %04X cc err %2d != %2d", mm->mm_nicename, pid, cc, cc2); @@ -1505,38 +1500,37 @@ mpegts_input_process } type = mp->mp_type; - + /* Stream all PIDs */ - LIST_FOREACH(mps, &mm->mm_all_subs, mps_svcraw_link) - if ((mps->mps_type & MPS_ALL) || (type & (MPS_TABLE|MPS_FTABLE))) - ts_recv_raw((mpegts_service_t *)mps->mps_owner, tspos, tsb, llen); + LIST_FOREACH (mps, &mm->mm_all_subs, mps_svcraw_link) + if ((mps->mps_type & MPS_ALL) || (type & (MPS_TABLE | MPS_FTABLE))) + ts_recv_raw((mpegts_service_t*)mps->mps_owner, tspos, tsb, llen); /* Stream raw PIDs */ if (type & MPS_RAW) { - LIST_FOREACH(mps, &mp->mp_raw_subs, mps_raw_link) - ts_recv_raw((mpegts_service_t *)mps->mps_owner, tspos, tsb, llen); + LIST_FOREACH (mps, &mp->mp_raw_subs, mps_raw_link) + ts_recv_raw((mpegts_service_t*)mps->mps_owner, tspos, tsb, llen); } /* Stream service data */ if (type & MPS_SERVICE) { - LIST_FOREACH(mps, &mp->mp_svc_subs, mps_svcraw_link) { + LIST_FOREACH (mps, &mp->mp_svc_subs, mps_svcraw_link) { s = mps->mps_owner; - f = (type & (MPS_TABLE|MPS_FTABLE)) || - (pid == s->s_components.set_pmt_pid) || + f = (type & (MPS_TABLE | MPS_FTABLE)) || (pid == s->s_components.set_pmt_pid) || (pid == s->s_components.set_pcr_pid); ts_recv_packet1((mpegts_service_t*)s, tspos, pid, tsb, llen, f); } } else - /* Stream table data */ - if (type & MPS_STREAM) { - LIST_FOREACH(s, &mm->mm_transports, s_active_link) { - if (s->s_type != STYPE_STD) continue; - f = (type & (MPS_TABLE|MPS_FTABLE)) || - (pid == s->s_components.set_pmt_pid) || - (pid == s->s_components.set_pcr_pid); - ts_recv_packet1((mpegts_service_t*)s, tspos, pid, tsb, llen, f); + /* Stream table data */ + if (type & MPS_STREAM) { + LIST_FOREACH (s, &mm->mm_transports, s_active_link) { + if (s->s_type != STYPE_STD) + continue; + f = (type & (MPS_TABLE | MPS_FTABLE)) || (pid == s->s_components.set_pmt_pid) || + (pid == s->s_components.set_pcr_pid); + ts_recv_packet1((mpegts_service_t*)s, tspos, pid, tsb, llen, f); + } } - } /* Table data */ if (type & (MPS_TABLE | MPS_FTABLE)) { @@ -1544,9 +1538,11 @@ mpegts_input_process if (type & MPS_FTABLE) mpegts_input_table_dispatch(mm, mm->mm_nicename, tsb, llen, 1); if (type & MPS_TABLE) { - if (mi->mi_table_queue_size >= 2*1024*1024) { + if (mi->mi_table_queue_size >= 2 * 1024 * 1024) { if (tvhlog_limit(&mi->mi_input_queue_loglimit, 10)) { - tvhwarn(LS_MPEGTS, "too much queued table input data (over 2MB) for %s, discarding new", mi->mi_name); + tvhwarn(LS_MPEGTS, + "too much queued table input data (over 2MB) for %s, discarding new", + mi->mi_name); if (tvhtrace_enabled()) mpegts_input_analyze_table_queue(mi); } @@ -1556,10 +1552,12 @@ mpegts_input_process pid2 = (mtf->mtf_tsb[1] << 8) | mtf->mtf_tsb[2]; if (pid == pid2) { memcpy(mtf->mtf_tsb + mtf->mtf_len, tsb, llen); - memoryinfo_free(&mpegts_input_table_memoryinfo, sizeof(mpegts_table_feed_t) + mtf->mtf_len); + memoryinfo_free(&mpegts_input_table_memoryinfo, + sizeof(mpegts_table_feed_t) + mtf->mtf_len); mtf->mtf_len += llen; mi->mi_table_queue_size += llen; - memoryinfo_alloc(&mpegts_input_table_memoryinfo, sizeof(mpegts_table_feed_t) + mtf->mtf_len); + memoryinfo_alloc(&mpegts_input_table_memoryinfo, + sizeof(mpegts_table_feed_t) + mtf->mtf_len); } else { mtf = NULL; } @@ -1572,30 +1570,28 @@ mpegts_input_process } } } else { - //tvhdebug("tsdemux", "%s - SI packet had errors", name); + // tvhdebug("tsdemux", "%s - SI packet had errors", name); } } } else { /* Stream to all fullmux subscribers */ - LIST_FOREACH(mps, &mm->mm_all_subs, mps_svcraw_link) - ts_recv_raw((mpegts_service_t *)mps->mps_owner, tspos, tsb, llen); - + LIST_FOREACH (mps, &mm->mm_all_subs, mps_svcraw_link) + ts_recv_raw((mpegts_service_t*)mps->mps_owner, tspos, tsb, llen); } -done: + done: tsb += llen; len -= llen; tspos += llen; } /* Raw stream */ - if (tsb != mpkt->mp_data && - LIST_FIRST(&mmi->mmi_streaming_pad.sp_targets) != NULL) { + if (tsb != mpkt->mp_data && LIST_FIRST(&mmi->mmi_streaming_pad.sp_targets) != NULL) { streaming_message_t sm; - pktbuf_t *pb = pktbuf_alloc(mpkt->mp_data, tsb - mpkt->mp_data); + pktbuf_t* pb = pktbuf_alloc(mpkt->mp_data, tsb - mpkt->mp_data); memset(&sm, 0, sizeof(sm)); sm.sm_type = SMT_MPEGTS; sm.sm_data = pb; @@ -1618,17 +1614,14 @@ done: * Demux again data from one mpeg-ts stream. * Might be used for hardware descramblers. */ -void -mpegts_input_postdemux - ( mpegts_input_t *mi, mpegts_mux_t *mm, uint8_t *tsb, int len ) -{ - uint16_t pid; - int llen, type = 0; - mpegts_pid_t *mp; - mpegts_pid_sub_t *mps; - service_t *s; - elementary_stream_t *st; - mpegts_mux_instance_t *mmi; +void mpegts_input_postdemux(mpegts_input_t* mi, mpegts_mux_t* mm, uint8_t* tsb, int len) { + uint16_t pid; + int llen, type = 0; + mpegts_pid_t* mp; + mpegts_pid_sub_t* mps; + service_t* s; + elementary_stream_t* st; + mpegts_mux_instance_t* mmi; tvh_mutex_lock(&mi->mi_output_lock); if (mm == NULL || (mmi = mm->mm_active) == NULL) @@ -1669,7 +1662,7 @@ mpegts_input_postdemux /* Stream service data */ if (type & MPS_SERVICE) { - LIST_FOREACH(mps, &mp->mp_svc_subs, mps_svcraw_link) { + LIST_FOREACH (mps, &mp->mp_svc_subs, mps_svcraw_link) { s = mps->mps_owner; tvh_mutex_lock(&s->s_stream_mutex); st = elementary_stream_find(&s->s_components, pid); @@ -1677,19 +1670,19 @@ mpegts_input_postdemux tvh_mutex_unlock(&s->s_stream_mutex); } } else - /* Stream table data */ - if (type & MPS_STREAM) { - LIST_FOREACH(s, &mm->mm_transports, s_active_link) { - if (s->s_type != STYPE_STD) continue; - tvh_mutex_lock(&s->s_stream_mutex); - ts_recv_packet0((mpegts_service_t*)s, NULL, tsb, llen); - tvh_mutex_unlock(&s->s_stream_mutex); + /* Stream table data */ + if (type & MPS_STREAM) { + LIST_FOREACH (s, &mm->mm_transports, s_active_link) { + if (s->s_type != STYPE_STD) + continue; + tvh_mutex_lock(&s->s_stream_mutex); + ts_recv_packet0((mpegts_service_t*)s, NULL, tsb, llen); + tvh_mutex_unlock(&s->s_stream_mutex); + } } - } - } -done: + done: tsb += llen; len -= llen; } @@ -1697,15 +1690,13 @@ unlock: tvh_mutex_unlock(&mi->mi_output_lock); } -static void * -mpegts_input_thread ( void * p ) -{ - mpegts_packet_t *mp; - mpegts_input_t *mi = p; - size_t bytes = 0; - int update_pids; - tprofile_t tprofile; - char buf[256]; +static void* mpegts_input_thread(void* p) { + mpegts_packet_t* mp; + mpegts_input_t* mi = p; + size_t bytes = 0; + int update_pids; + tprofile_t tprofile; + char buf[256]; tvh_mutex_lock(&global_lock); mi->mi_display_name(mi, buf, sizeof(buf)); @@ -1729,7 +1720,7 @@ mpegts_input_thread ( void * p ) memoryinfo_free(&mpegts_input_queue_memoryinfo, sizeof(mpegts_packet_t) + mp->mp_len); TAILQ_REMOVE(&mi->mi_input_queue, mp, mp_link); tvh_mutex_unlock(&mi->mi_input_lock); - + /* Process */ tvh_mutex_lock(&mi->mi_output_lock); mpegts_input_table_waiting(mi, mp->mp_mux); @@ -1784,12 +1775,10 @@ mpegts_input_thread ( void * p ) return NULL; } -static void * -mpegts_input_table_thread ( void *aux ) -{ - mpegts_table_feed_t *mtf; - mpegts_input_t *mi = aux; - mpegts_mux_t *mm = NULL; +static void* mpegts_input_table_thread(void* aux) { + mpegts_table_feed_t* mtf; + mpegts_input_t* mi = aux; + mpegts_mux_t* mm = NULL; tvh_mutex_lock(&mi->mi_output_lock); while (atomic_get(&mi->mi_running)) { @@ -1833,12 +1822,9 @@ mpegts_input_table_thread ( void *aux ) return NULL; } -void -mpegts_input_flush_mux - ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ - mpegts_table_feed_t *mtf; - mpegts_packet_t *mp; +void mpegts_input_flush_mux(mpegts_input_t* mi, mpegts_mux_t* mm) { + mpegts_table_feed_t* mtf; + mpegts_packet_t* mp; lock_assert(&global_lock); @@ -1848,7 +1834,7 @@ mpegts_input_flush_mux /* Flush input Q */ tvh_mutex_lock(&mi->mi_input_lock); - TAILQ_FOREACH(mp, &mi->mi_input_queue, mp_link) { + TAILQ_FOREACH (mp, &mi->mi_input_queue, mp_link) { if (mp->mp_mux == mm) { mpegts_mux_release(mm); mp->mp_mux = NULL; @@ -1858,7 +1844,7 @@ mpegts_input_flush_mux /* Flush table Q */ tvh_mutex_lock(&mi->mi_output_lock); - TAILQ_FOREACH(mtf, &mi->mi_table_queue, mtf_link) { + TAILQ_FOREACH (mtf, &mi->mi_table_queue, mtf_link) { if (mtf->mtf_mux == mm) mtf->mtf_mux = NULL; } @@ -1868,35 +1854,32 @@ mpegts_input_flush_mux assert(mm->mm_active == NULL); } -static void -mpegts_input_stream_status - ( mpegts_mux_instance_t *mmi, tvh_input_stream_t *st ) -{ - int s = 0, w = 0; - char buf[512], ubuf[UUID_HEX_SIZE]; - th_subscription_t *ths; - const service_t *t; - mpegts_mux_t *mm = mmi->mmi_mux; - mpegts_input_t *mi = mmi->mmi_input; - mpegts_pid_t *mp; - - LIST_FOREACH(t, &mm->mm_transports, s_active_link) - if (((mpegts_service_t *)t)->s_dvb_mux == mm) - LIST_FOREACH(ths, &t->s_subscriptions, ths_service_link) { +static void mpegts_input_stream_status(mpegts_mux_instance_t* mmi, tvh_input_stream_t* st) { + int s = 0, w = 0; + char buf[512], ubuf[UUID_HEX_SIZE]; + th_subscription_t* ths; + const service_t* t; + mpegts_mux_t* mm = mmi->mmi_mux; + mpegts_input_t* mi = mmi->mmi_input; + mpegts_pid_t* mp; + + LIST_FOREACH (t, &mm->mm_transports, s_active_link) + if (((mpegts_service_t*)t)->s_dvb_mux == mm) + LIST_FOREACH (ths, &t->s_subscriptions, ths_service_link) { s++; w = MAX(w, ths->ths_weight); } - st->uuid = strdup(idnode_uuid_as_str(&mmi->tii_id, ubuf)); + st->uuid = strdup(idnode_uuid_as_str(&mmi->tii_id, ubuf)); mi->mi_display_name(mi, buf, sizeof(buf)); - st->input_name = strdup(buf); + st->input_name = strdup(buf); mpegts_mux_nice_name(mm, buf, sizeof(buf)); st->stream_name = strdup(buf); st->subs_count = s; st->max_weight = w; st->pids = mpegts_pid_alloc(); - RB_FOREACH(mp, &mm->mm_pids, mp_link) { + RB_FOREACH (mp, &mm->mm_pids, mp_link) { if (mp->mp_pid == MPEGTS_TABLES_PID) continue; if (mp->mp_pid == MPEGTS_FULLMUX_PID) @@ -1906,35 +1889,32 @@ mpegts_input_stream_status } tvh_mutex_lock(&mmi->tii_stats_mutex); - st->stats.signal = mmi->tii_stats.signal; - st->stats.snr = mmi->tii_stats.snr; - st->stats.ber = mmi->tii_stats.ber; + st->stats.signal = mmi->tii_stats.signal; + st->stats.snr = mmi->tii_stats.snr; + st->stats.ber = mmi->tii_stats.ber; st->stats.signal_scale = mmi->tii_stats.signal_scale; st->stats.snr_scale = mmi->tii_stats.snr_scale; - st->stats.ec_bit = mmi->tii_stats.ec_bit; - st->stats.tc_bit = mmi->tii_stats.tc_bit; - st->stats.ec_block = mmi->tii_stats.ec_block; - st->stats.tc_block = mmi->tii_stats.tc_block; + st->stats.ec_bit = mmi->tii_stats.ec_bit; + st->stats.tc_bit = mmi->tii_stats.tc_bit; + st->stats.ec_block = mmi->tii_stats.ec_block; + st->stats.tc_block = mmi->tii_stats.tc_block; tvh_mutex_unlock(&mmi->tii_stats_mutex); - st->stats.unc = atomic_get(&mmi->tii_stats.unc); - st->stats.cc = atomic_get(&mmi->tii_stats.cc); - st->stats.te = atomic_get(&mmi->tii_stats.te); - st->stats.bps = atomic_exchange(&mmi->tii_stats.bps, 0) * 8; + st->stats.unc = atomic_get(&mmi->tii_stats.unc); + st->stats.cc = atomic_get(&mmi->tii_stats.cc); + st->stats.te = atomic_get(&mmi->tii_stats.te); + st->stats.bps = atomic_exchange(&mmi->tii_stats.bps, 0) * 8; } -void -mpegts_input_empty_status - ( mpegts_input_t *mi, tvh_input_stream_t *st ) -{ - char buf[512], ubuf[UUID_HEX_SIZE]; - tvh_input_instance_t *mmi_; - mpegts_mux_instance_t *mmi; +void mpegts_input_empty_status(mpegts_input_t* mi, tvh_input_stream_t* st) { + char buf[512], ubuf[UUID_HEX_SIZE]; + tvh_input_instance_t* mmi_; + mpegts_mux_instance_t* mmi; - st->uuid = strdup(idnode_uuid_as_str(&mi->ti_id, ubuf)); + st->uuid = strdup(idnode_uuid_as_str(&mi->ti_id, ubuf)); mi->mi_display_name(mi, buf, sizeof(buf)); - st->input_name = strdup(buf); - LIST_FOREACH(mmi_, &mi->mi_mux_instances, tii_input_link) { - mmi = (mpegts_mux_instance_t *)mmi_; + st->input_name = strdup(buf); + LIST_FOREACH (mmi_, &mi->mi_mux_instances, tii_input_link) { + mmi = (mpegts_mux_instance_t*)mmi_; st->stats.unc += atomic_get(&mmi->tii_stats.unc); st->stats.cc += atomic_get(&mmi->tii_stats.cc); tvh_mutex_lock(&mmi->tii_stats_mutex); @@ -1945,16 +1925,13 @@ mpegts_input_empty_status } } -static void -mpegts_input_get_streams - ( tvh_input_t *i, tvh_input_stream_list_t *isl ) -{ - tvh_input_stream_t *st = NULL; - mpegts_input_t *mi = (mpegts_input_t*)i; - mpegts_mux_instance_t *mmi; +static void mpegts_input_get_streams(tvh_input_t* i, tvh_input_stream_list_t* isl) { + tvh_input_stream_t* st = NULL; + mpegts_input_t* mi = (mpegts_input_t*)i; + mpegts_mux_instance_t* mmi; tvh_mutex_lock(&mi->mi_output_lock); - LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link) { + LIST_FOREACH (mmi, &mi->mi_mux_active, mmi_active_link) { st = calloc(1, sizeof(tvh_input_stream_t)); mpegts_input_stream_status(mmi, st); LIST_INSERT_HEAD(isl, st, link); @@ -1967,20 +1944,18 @@ mpegts_input_get_streams tvh_mutex_unlock(&mi->mi_output_lock); } -static void -mpegts_input_clear_stats ( tvh_input_t *i ) -{ - mpegts_input_t *mi = (mpegts_input_t*)i; - tvh_input_instance_t *mmi_; - mpegts_mux_instance_t *mmi; +static void mpegts_input_clear_stats(tvh_input_t* i) { + mpegts_input_t* mi = (mpegts_input_t*)i; + tvh_input_instance_t* mmi_; + mpegts_mux_instance_t* mmi; tvh_mutex_lock(&mi->mi_output_lock); - LIST_FOREACH(mmi_, &mi->mi_mux_instances, tii_input_link) { - mmi = (mpegts_mux_instance_t *)mmi_; + LIST_FOREACH (mmi_, &mi->mi_mux_instances, tii_input_link) { + mmi = (mpegts_mux_instance_t*)mmi_; atomic_set(&mmi->tii_stats.unc, 0); atomic_set(&mmi->tii_stats.cc, 0); tvh_mutex_lock(&mmi->tii_stats_mutex); - mmi->tii_stats.te = 0; + mmi->tii_stats.te = 0; mmi->tii_stats.ec_block = 0; mmi->tii_stats.tc_block = 0; tvh_mutex_unlock(&mmi->tii_stats_mutex); @@ -1989,21 +1964,15 @@ mpegts_input_clear_stats ( tvh_input_t *i ) notify_reload("input_status"); } -static void -mpegts_input_thread_start ( void *aux ) -{ - mpegts_input_t *mi = aux; +static void mpegts_input_thread_start(void* aux) { + mpegts_input_t* mi = aux; atomic_set(&mi->mi_running, 1); - - tvh_thread_create(&mi->mi_table_tid, NULL, - mpegts_input_table_thread, mi, "mi-table"); - tvh_thread_create(&mi->mi_input_tid, NULL, - mpegts_input_thread, mi, "mi-main"); + + tvh_thread_create(&mi->mi_table_tid, NULL, mpegts_input_table_thread, mi, "mi-table"); + tvh_thread_create(&mi->mi_input_tid, NULL, mpegts_input_thread, mi, "mi-main"); } -static void -mpegts_input_thread_stop ( mpegts_input_t *mi ) -{ +static void mpegts_input_thread_stop(mpegts_input_t* mi) { atomic_set(&mi->mi_running, 0); mtimer_disarm(&mi->mi_input_thread_start); @@ -2030,17 +1999,15 @@ mpegts_input_thread_stop ( mpegts_input_t *mi ) * Status monitoring * *************************************************************************/ -void -mpegts_input_status_timer ( void *p ) -{ - tvh_input_stream_t st; - mpegts_input_t *mi = p; - mpegts_mux_instance_t *mmi; - htsmsg_t *e; - int64_t subs = 0; +void mpegts_input_status_timer(void* p) { + tvh_input_stream_t st; + mpegts_input_t* mi = p; + mpegts_mux_instance_t* mmi; + htsmsg_t* e; + int64_t subs = 0; tvh_mutex_lock(&mi->mi_output_lock); - LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link) { + LIST_FOREACH (mmi, &mi->mi_mux_active, mmi_active_link) { memset(&st, 0, sizeof(st)); mpegts_input_stream_status(mmi, &st); e = tvh_input_stream_create_msg(&st); @@ -2058,14 +2025,11 @@ mpegts_input_status_timer ( void *p ) * Creation/Config * *************************************************************************/ -static int mpegts_input_idx = 0; +static int mpegts_input_idx = 0; mpegts_input_list_t mpegts_input_all; mpegts_input_t* -mpegts_input_create0 - ( mpegts_input_t *mi, const idclass_t *class, const char *uuid, - htsmsg_t *c ) -{ +mpegts_input_create0(mpegts_input_t* mi, const idclass_t* class, const char* uuid, htsmsg_t* c) { char buf[32]; if (idnode_insert(&mi->ti_id, uuid, class, 0)) { @@ -2077,29 +2041,29 @@ mpegts_input_create0 snprintf(buf, sizeof(buf), "input %p", mi); tprofile_queue_init(&mi->mi_qprofile, buf); LIST_INSERT_HEAD(&tvh_inputs, (tvh_input_t*)mi, ti_link); - + /* Defaults */ - mi->mi_is_enabled = mpegts_input_is_enabled; - mi->mi_display_name = mpegts_input_display_name; - mi->mi_get_weight = mpegts_input_get_weight; - mi->mi_get_priority = mpegts_input_get_priority; - mi->mi_warm_mux = mpegts_input_warm_mux; - mi->mi_start_mux = mpegts_input_start_mux; - mi->mi_stop_mux = mpegts_input_stop_mux; - mi->mi_open_service = mpegts_input_open_service; - mi->mi_close_service = mpegts_input_close_service; - mi->mi_update_pids = mpegts_input_update_pids; - mi->mi_create_mux_instance = mpegts_input_create_mux_instance; - mi->mi_started_mux = mpegts_input_started_mux; - mi->mi_stopping_mux = mpegts_input_stopping_mux; - mi->mi_stopped_mux = mpegts_input_stopped_mux; - mi->mi_has_subscription = mpegts_input_has_subscription; - mi->mi_error = mpegts_input_error; - mi->ti_get_streams = mpegts_input_get_streams; - mi->ti_clear_stats = mpegts_input_clear_stats; + mi->mi_is_enabled = mpegts_input_is_enabled; + mi->mi_display_name = mpegts_input_display_name; + mi->mi_get_weight = mpegts_input_get_weight; + mi->mi_get_priority = mpegts_input_get_priority; + mi->mi_warm_mux = mpegts_input_warm_mux; + mi->mi_start_mux = mpegts_input_start_mux; + mi->mi_stop_mux = mpegts_input_stop_mux; + mi->mi_open_service = mpegts_input_open_service; + mi->mi_close_service = mpegts_input_close_service; + mi->mi_update_pids = mpegts_input_update_pids; + mi->mi_create_mux_instance = mpegts_input_create_mux_instance; + mi->mi_started_mux = mpegts_input_started_mux; + mi->mi_stopping_mux = mpegts_input_stopping_mux; + mi->mi_stopped_mux = mpegts_input_stopped_mux; + mi->mi_has_subscription = mpegts_input_has_subscription; + mi->mi_error = mpegts_input_error; + mi->ti_get_streams = mpegts_input_get_streams; + mi->ti_clear_stats = mpegts_input_clear_stats; /* Index */ - mi->mi_instance = ++mpegts_input_idx; + mi->mi_instance = ++mpegts_input_idx; /* Init input/output structures */ tvh_mutex_init(&mi->mi_input_lock, NULL); @@ -2111,7 +2075,7 @@ mpegts_input_create0 TAILQ_INIT(&mi->mi_table_queue); /* Defaults */ - mi->mi_ota_epg = 1; + mi->mi_ota_epg = 1; mi->mi_initscan = 1; mi->mi_idlescan = 1; @@ -2128,19 +2092,15 @@ mpegts_input_create0 return mi; } -void -mpegts_input_stop_all ( mpegts_input_t *mi ) -{ - mpegts_mux_instance_t *mmi; +void mpegts_input_stop_all(mpegts_input_t* mi) { + mpegts_mux_instance_t* mmi; while ((mmi = LIST_FIRST(&mi->mi_mux_active))) mmi->mmi_mux->mm_stop(mmi->mmi_mux, 1, SM_CODE_OK); } -void -mpegts_input_delete ( mpegts_input_t *mi, int delconf ) -{ - mpegts_network_link_t *mnl; - tvh_input_instance_t *tii, *tii_next; +void mpegts_input_delete(mpegts_input_t* mi, int delconf) { + mpegts_network_link_t* mnl; + tvh_input_instance_t * tii, *tii_next; /* Early shutdown flag */ atomic_set(&mi->mi_running, 0); @@ -2155,7 +2115,7 @@ mpegts_input_delete ( mpegts_input_t *mi, int delconf ) tii = LIST_FIRST(&mi->mi_mux_instances); while (tii) { tii_next = LIST_NEXT(tii, tii_input_link); - if (((mpegts_mux_instance_t *)tii)->mmi_input == mi) + if (((mpegts_mux_instance_t*)tii)->mmi_input == mi) tii->tii_delete(tii); tii = tii_next; } @@ -2176,19 +2136,15 @@ mpegts_input_delete ( mpegts_input_t *mi, int delconf ) free(mi); } -void -mpegts_input_save ( mpegts_input_t *mi, htsmsg_t *m ) -{ +void mpegts_input_save(mpegts_input_t* mi, htsmsg_t* m) { idnode_save(&mi->ti_id, m); } -int -mpegts_input_add_network ( mpegts_input_t *mi, mpegts_network_t *mn ) -{ - mpegts_network_link_t *mnl; +int mpegts_input_add_network(mpegts_input_t* mi, mpegts_network_t* mn) { + mpegts_network_link_t* mnl; /* Find existing */ - LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link) + LIST_FOREACH (mnl, &mi->mi_networks, mnl_mi_link) if (mnl->mnl_network == mn) break; @@ -2199,41 +2155,39 @@ mpegts_input_add_network ( mpegts_input_t *mi, mpegts_network_t *mn ) } /* Create new */ - mnl = calloc(1, sizeof(mpegts_network_link_t)); - mnl->mnl_input = mi; - mnl->mnl_network = mn; + mnl = calloc(1, sizeof(mpegts_network_link_t)); + mnl->mnl_input = mi; + mnl->mnl_network = mn; LIST_INSERT_HEAD(&mi->mi_networks, mnl, mnl_mi_link); - LIST_INSERT_HEAD(&mn->mn_inputs, mnl, mnl_mn_link); + LIST_INSERT_HEAD(&mn->mn_inputs, mnl, mnl_mn_link); idnode_notify_changed(&mnl->mnl_network->mn_id); return 1; } -static void -mpegts_input_del_network ( mpegts_network_link_t *mnl ) -{ +static void mpegts_input_del_network(mpegts_network_link_t* mnl) { idnode_notify_changed(&mnl->mnl_network->mn_id); LIST_REMOVE(mnl, mnl_mn_link); LIST_REMOVE(mnl, mnl_mi_link); free(mnl); } -int -mpegts_input_set_networks ( mpegts_input_t *mi, htsmsg_t *msg ) -{ - int save = 0; - const char *str; - htsmsg_field_t *f; - mpegts_network_t *mn; +int mpegts_input_set_networks(mpegts_input_t* mi, htsmsg_t* msg) { + int save = 0; + const char* str; + htsmsg_field_t* f; + mpegts_network_t* mn; mpegts_network_link_t *mnl, *nxt; /* Mark for deletion */ - LIST_FOREACH(mnl, &mi->mi_networks, mnl_mi_link) + LIST_FOREACH (mnl, &mi->mi_networks, mnl_mi_link) mnl->mnl_mark = 1; /* Link */ HTSMSG_FOREACH(f, msg) { - if (!(str = htsmsg_field_get_str(f))) continue; - if (!(mn = mpegts_network_find(str))) continue; + if (!(str = htsmsg_field_get_str(f))) + continue; + if (!(mn = mpegts_network_find(str))) + continue; save |= mpegts_input_add_network(mi, mn); } @@ -2245,18 +2199,17 @@ mpegts_input_set_networks ( mpegts_input_t *mi, htsmsg_t *msg ) save = 1; } } - + return save; } -int -mpegts_input_grace( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ +int mpegts_input_grace(mpegts_input_t* mi, mpegts_mux_t* mm) { /* Get timeout */ int t = 0; if (mi && mi->mi_get_grace) t = mi->mi_get_grace(mi, mm); - if (t < 5) t = 5; // lower bound + if (t < 5) + t = 5; // lower bound return t; } diff --git a/src/input/mpegts/mpegts_mux.c b/src/input/mpegts/mpegts_mux.c index fa966fdce..5c36b688c 100644 --- a/src/input/mpegts/mpegts_mux.c +++ b/src/input/mpegts/mpegts_mux.c @@ -30,27 +30,20 @@ #include -static void mpegts_mux_scan_timeout ( void *p ); -static void mpegts_mux_do_stop ( mpegts_mux_t *mm, int delconf ); - +static void mpegts_mux_scan_timeout(void* p); +static void mpegts_mux_do_stop(mpegts_mux_t* mm, int delconf); /* **************************************************************************** * Mux instance (input linkage) * ***************************************************************************/ -const idclass_t mpegts_mux_instance_class = -{ - .ic_super = &tvh_input_instance_class, - .ic_class = "mpegts_mux_instance", - .ic_caption = N_("MPEG-TS multiplex PHY"), - .ic_perm_def = ACCESS_ADMIN -}; +const idclass_t mpegts_mux_instance_class = {.ic_super = &tvh_input_instance_class, + .ic_class = "mpegts_mux_instance", + .ic_caption = N_("MPEG-TS multiplex PHY"), + .ic_perm_def = ACCESS_ADMIN}; -void -mpegts_mux_instance_delete - ( tvh_input_instance_t *tii ) -{ - mpegts_mux_instance_t *mmi = (mpegts_mux_instance_t *)tii; +void mpegts_mux_instance_delete(tvh_input_instance_t* tii) { + mpegts_mux_instance_t* mmi = (mpegts_mux_instance_t*)tii; idnode_save_check(&tii->tii_id, 1); idnode_unlink(&tii->tii_id); @@ -60,11 +53,11 @@ mpegts_mux_instance_delete free(mmi); } -mpegts_mux_instance_t * -mpegts_mux_instance_create0 - ( mpegts_mux_instance_t *mmi, const idclass_t *class, const char *uuid, - mpegts_input_t *mi, mpegts_mux_t *mm ) -{ +mpegts_mux_instance_t* mpegts_mux_instance_create0(mpegts_mux_instance_t* mmi, + const idclass_t* class, + const char* uuid, + mpegts_input_t* mi, + mpegts_mux_t* mm) { // TODO: does this need to be an idnode? if (idnode_insert(&mmi->tii_id, uuid, class, 0)) { free(mmi); @@ -76,44 +69,37 @@ mpegts_mux_instance_create0 /* Setup links */ mmi->mmi_mux = mm; mmi->mmi_input = mi; - + /* Callbacks */ - mmi->tii_delete = mpegts_mux_instance_delete; + mmi->tii_delete = mpegts_mux_instance_delete; mmi->tii_clear_stats = tvh_input_instance_clear_stats; LIST_INSERT_HEAD(&mm->mm_instances, mmi, mmi_mux_link); - LIST_INSERT_HEAD(&mi->mi_mux_instances, (tvh_input_instance_t *)mmi, tii_input_link); + LIST_INSERT_HEAD(&mi->mi_mux_instances, (tvh_input_instance_t*)mmi, tii_input_link); return mmi; } -static void -mpegts_mux_scan_active - ( mpegts_mux_t *mm, const char *buf, mpegts_input_t *mi ) -{ +static void mpegts_mux_scan_active(mpegts_mux_t* mm, const char* buf, mpegts_input_t* mi) { int t; /* Setup scan */ - if (mm->mm_scan_state == MM_SCAN_STATE_PEND || - mm->mm_scan_state == MM_SCAN_STATE_IPEND) { + if (mm->mm_scan_state == MM_SCAN_STATE_PEND || mm->mm_scan_state == MM_SCAN_STATE_IPEND) { mpegts_network_scan_mux_active(mm); /* Get timeout */ t = mpegts_input_grace(mi, mm); - + /* Setup timeout */ mtimer_arm_rel(&mm->mm_scan_timeout, mpegts_mux_scan_timeout, mm, sec2mono(t)); } } -static int -mpegts_mux_keep_exists - ( mpegts_input_t *mi ) -{ - const mpegts_mux_instance_t *mmi; - const service_t *s; - const th_subscription_t *ths; - int ret; +static int mpegts_mux_keep_exists(mpegts_input_t* mi) { + const mpegts_mux_instance_t* mmi; + const service_t* s; + const th_subscription_t* ths; + int ret; lock_assert(&global_lock); @@ -121,8 +107,8 @@ mpegts_mux_keep_exists return 0; ret = 0; - LIST_FOREACH(mmi, &mi->mi_mux_active, mmi_active_link) - LIST_FOREACH(ths, &mmi->mmi_mux->mm_raw_subs, ths_mux_link) { + LIST_FOREACH (mmi, &mi->mi_mux_active, mmi_active_link) + LIST_FOREACH (ths, &mmi->mmi_mux->mm_raw_subs, ths_mux_link) { s = ths->ths_service; if (s && s->s_type == STYPE_RAW && !strcmp(ths->ths_title, "keep")) { ret = 1; @@ -132,39 +118,36 @@ mpegts_mux_keep_exists return ret; } -static int -mpegts_mux_subscribe_keep - ( mpegts_mux_t *mm, mpegts_input_t *mi ) -{ - char *s; - int r; +static int mpegts_mux_subscribe_keep(mpegts_mux_t* mm, mpegts_input_t* mi) { + char* s; + int r; - s = mi->mi_linked; + s = mi->mi_linked; mi->mi_linked = NULL; tvhtrace(LS_MPEGTS, "subscribe keep for '%s' (%p)", mi->mi_name, mm); - r = mpegts_mux_subscribe(mm, mi, "keep", SUBSCRIPTION_PRIO_KEEP, - SUBSCRIPTION_ONESHOT | SUBSCRIPTION_MINIMAL); + r = mpegts_mux_subscribe(mm, + mi, + "keep", + SUBSCRIPTION_PRIO_KEEP, + SUBSCRIPTION_ONESHOT | SUBSCRIPTION_MINIMAL); mi->mi_linked = s; return r; } -static void -mpegts_mux_subscribe_linked - ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ - mpegts_input_t *mi2 = mpegts_input_find(mi->mi_linked); - mpegts_mux_instance_t *mmi2; - mpegts_network_link_t *mnl2; - mpegts_mux_t *mm2; - char buf1[128], buf2[128]; - const char *serr = "All"; - int r = 0; +static void mpegts_mux_subscribe_linked(mpegts_input_t* mi, mpegts_mux_t* mm) { + mpegts_input_t* mi2 = mpegts_input_find(mi->mi_linked); + mpegts_mux_instance_t* mmi2; + mpegts_network_link_t* mnl2; + mpegts_mux_t* mm2; + char buf1[128], buf2[128]; + const char* serr = "All"; + int r = 0; tvhtrace(LS_MPEGTS, "subscribe linked"); if (!mi2) return; - + if (!mpegts_mux_keep_exists(mi) && (r = mpegts_mux_subscribe_keep(mm, mi))) { serr = "active1"; goto fatal; @@ -182,33 +165,28 @@ mpegts_mux_subscribe_linked } /* Try muxes within same network */ - LIST_FOREACH(mnl2, &mi2->mi_networks, mnl_mi_link) + LIST_FOREACH (mnl2, &mi2->mi_networks, mnl_mi_link) if (mnl2->mnl_network == mm->mm_network) - LIST_FOREACH(mm2, &mnl2->mnl_network->mn_muxes, mm_network_link) - if (!mm2->mm_active && MM_SCAN_CHECK_OK(mm) && - !LIST_EMPTY(&mm2->mm_services)) + LIST_FOREACH (mm2, &mnl2->mnl_network->mn_muxes, mm_network_link) + if (!mm2->mm_active && MM_SCAN_CHECK_OK(mm) && !LIST_EMPTY(&mm2->mm_services)) if (!mpegts_mux_subscribe_keep(mm2, mi2)) return; /* Try all other muxes */ - LIST_FOREACH(mnl2, &mi2->mi_networks, mnl_mi_link) + LIST_FOREACH (mnl2, &mi2->mi_networks, mnl_mi_link) if (mnl2->mnl_network != mm->mm_network) - LIST_FOREACH(mm2, &mnl2->mnl_network->mn_muxes, mm_network_link) - if (!mm2->mm_active && MM_SCAN_CHECK_OK(mm) && - !LIST_EMPTY(&mm2->mm_services)) + LIST_FOREACH (mm2, &mnl2->mnl_network->mn_muxes, mm_network_link) + if (!mm2->mm_active && MM_SCAN_CHECK_OK(mm) && !LIST_EMPTY(&mm2->mm_services)) if (!mpegts_mux_subscribe_keep(mm2, mi2)) return; fatal: - mi ->mi_display_name(mi, buf1, sizeof(buf1)); + mi->mi_display_name(mi, buf1, sizeof(buf1)); mi2->mi_display_name(mi2, buf2, sizeof(buf2)); tvherror(LS_MPEGTS, "%s - %s - linked input cannot be started (%s: %i)", buf1, buf2, serr, r); } -void -mpegts_mux_unsubscribe_linked - ( mpegts_input_t *mi, service_t *t ) -{ +void mpegts_mux_unsubscribe_linked(mpegts_input_t* mi, service_t* t) { th_subscription_t *ths, *ths_next; if (mi) { @@ -216,23 +194,20 @@ mpegts_mux_unsubscribe_linked for (ths = LIST_FIRST(&subscriptions); ths; ths = ths_next) { ths_next = LIST_NEXT(ths, ths_global_link); - if (ths->ths_source == (tvh_input_t *)mi && !strcmp(ths->ths_title, "keep") && + if (ths->ths_source == (tvh_input_t*)mi && !strcmp(ths->ths_title, "keep") && ths->ths_service != t) subscription_unsubscribe(ths, UNSUBSCRIBE_FINAL); } } } -int -mpegts_mux_instance_start - ( mpegts_mux_instance_t **mmiptr, service_t *t, int weight ) -{ - int r; - char buf[256]; - mpegts_mux_instance_t *mmi = *mmiptr; - mpegts_mux_t * mm = mmi->mmi_mux; - mpegts_input_t * mi = mmi->mmi_input; - mpegts_service_t * s; +int mpegts_mux_instance_start(mpegts_mux_instance_t** mmiptr, service_t* t, int weight) { + int r; + char buf[256]; + mpegts_mux_instance_t* mmi = *mmiptr; + mpegts_mux_t* mm = mmi->mmi_mux; + mpegts_input_t* mi = mmi->mmi_input; + mpegts_service_t* s; /* Already active */ if (mm->mm_active) { @@ -246,7 +221,7 @@ mpegts_mux_instance_start mpegts_mux_update_nice_name(mm); /* Dead service check */ - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) s->s_dvb_check_seen = s->s_dvb_last_seen; mm->mm_tsid_checks = 0; @@ -259,10 +234,12 @@ mpegts_mux_instance_start mpegts_mux_unsubscribe_linked(mi, t); r = mi->mi_warm_mux(mi, mmi); - if (r) return r; + if (r) + return r; mm->mm_input_pos = 0; - r = mi->mi_start_mux(mi, mmi, weight); - if (r) return r; + r = mi->mi_start_mux(mi, mmi, weight); + if (r) + return r; /* Start */ tvhdebug(LS_MPEGTS, "%s - started", mm->mm_nicename); @@ -281,18 +258,16 @@ mpegts_mux_instance_start return 0; } -int -mpegts_mux_instance_weight ( mpegts_mux_instance_t *mmi ) -{ - int w = 0; - const service_t *s; - const th_subscription_t *ths; - mpegts_mux_t *mm = mmi->mmi_mux; +int mpegts_mux_instance_weight(mpegts_mux_instance_t* mmi) { + int w = 0; + const service_t* s; + const th_subscription_t* ths; + mpegts_mux_t* mm = mmi->mmi_mux; lock_assert(&mmi->mmi_input->mi_output_lock); /* Service subs */ - LIST_FOREACH(s, &mm->mm_transports, s_active_link) - LIST_FOREACH(ths, &s->s_subscriptions, ths_service_link) + LIST_FOREACH (s, &mm->mm_transports, s_active_link) + LIST_FOREACH (ths, &s->s_subscriptions, ths_service_link) w = MAX(w, ths->ths_weight); return w; @@ -302,64 +277,53 @@ mpegts_mux_instance_weight ( mpegts_mux_instance_t *mmi ) * Class definition * ***************************************************************************/ -static htsmsg_t * -mpegts_mux_class_save ( idnode_t *self, char *filename, size_t fsize ) -{ - mpegts_mux_t *mm = (mpegts_mux_t*)self; +static htsmsg_t* mpegts_mux_class_save(idnode_t* self, char* filename, size_t fsize) { + mpegts_mux_t* mm = (mpegts_mux_t*)self; if (mm->mm_config_save) return mm->mm_config_save(mm, filename, fsize); return NULL; } -static void -mpegts_mux_class_delete ( idnode_t *self ) -{ - mpegts_mux_t *mm = (mpegts_mux_t*)self; - if (mm->mm_delete) mm->mm_delete(mm, 1); +static void mpegts_mux_class_delete(idnode_t* self) { + mpegts_mux_t* mm = (mpegts_mux_t*)self; + if (mm->mm_delete) + mm->mm_delete(mm, 1); } static void -mpegts_mux_class_get_title - ( idnode_t *self, const char *lang, char *dst, size_t dstsize ) -{ +mpegts_mux_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { mpegts_mux_nice_name((mpegts_mux_t*)self, dst, dstsize); } -static const void * -mpegts_mux_class_get_num_svc ( void *ptr ) -{ - static int n; - mpegts_mux_t *mm = ptr; - mpegts_service_t *s; +static const void* mpegts_mux_class_get_num_svc(void* ptr) { + static int n; + mpegts_mux_t* mm = ptr; + mpegts_service_t* s; n = 0; - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) n++; return &n; } -static const void * -mpegts_mux_class_get_num_chn ( void *ptr ) -{ - static int n; - mpegts_mux_t *mm = ptr; - mpegts_service_t *s; - idnode_list_mapping_t *ilm; +static const void* mpegts_mux_class_get_num_chn(void* ptr) { + static int n; + mpegts_mux_t* mm = ptr; + mpegts_service_t* s; + idnode_list_mapping_t* ilm; n = 0; - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) - LIST_FOREACH(ilm, &s->s_channels, ilm_in1_link) + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) + LIST_FOREACH (ilm, &s->s_channels, ilm_in1_link) n++; return &n; } -static const void * -mpegts_mux_class_get_network ( void *ptr ) -{ - static char buf[512], *s = buf; - mpegts_mux_t *mm = ptr; +static const void* mpegts_mux_class_get_network(void* ptr) { + static char buf[512], *s = buf; + mpegts_mux_t* mm = ptr; if (mm && mm->mm_network && mm->mm_network->mn_display_name) mm->mm_network->mn_display_name(mm->mm_network, buf, sizeof(buf)); else @@ -367,10 +331,8 @@ mpegts_mux_class_get_network ( void *ptr ) return &s; } -static const void * -mpegts_mux_class_get_network_uuid ( void *ptr ) -{ - mpegts_mux_t *mm = ptr; +static const void* mpegts_mux_class_get_network_uuid(void* ptr) { + mpegts_mux_t* mm = ptr; if (mm && mm->mm_network) idnode_uuid_as_str(&mm->mm_network->mn_id, prop_sbuf); else @@ -378,11 +340,9 @@ mpegts_mux_class_get_network_uuid ( void *ptr ) return &prop_sbuf_ptr; } -static const void * -mpegts_mux_class_get_name ( void *ptr ) -{ - static char buf[512], *s = buf; - mpegts_mux_t *mm = ptr; +static const void* mpegts_mux_class_get_name(void* ptr) { + static char buf[512], *s = buf; + mpegts_mux_t* mm = ptr; if (mm && mm->mm_display_name) mm->mm_display_name(mm, buf, sizeof(buf)); else @@ -390,43 +350,37 @@ mpegts_mux_class_get_name ( void *ptr ) return &s; } -static struct strtab -scan_state_tab[] = { - { N_("IDLE"), MM_SCAN_STATE_IDLE }, - { N_("PEND"), MM_SCAN_STATE_PEND }, - { N_("IDLE PEND"), MM_SCAN_STATE_IPEND }, - { N_("ACTIVE"), MM_SCAN_STATE_ACTIVE }, +static struct strtab scan_state_tab[] = { + {N_("IDLE"), MM_SCAN_STATE_IDLE}, + {N_("PEND"), MM_SCAN_STATE_PEND}, + {N_("IDLE PEND"), MM_SCAN_STATE_IPEND}, + {N_("ACTIVE"), MM_SCAN_STATE_ACTIVE}, }; -static struct strtab -scan_result_tab[] = { - { N_("NONE"), MM_SCAN_NONE }, - { N_("OK"), MM_SCAN_OK }, - { N_("FAIL"), MM_SCAN_FAIL }, - { N_("OK (partial)"), MM_SCAN_PARTIAL }, - { N_("IGNORE"), MM_SCAN_IGNORE }, +static struct strtab scan_result_tab[] = { + {N_("NONE"), MM_SCAN_NONE}, + {N_("OK"), MM_SCAN_OK}, + {N_("FAIL"), MM_SCAN_FAIL}, + {N_("OK (partial)"), MM_SCAN_PARTIAL}, + {N_("IGNORE"), MM_SCAN_IGNORE}, }; -int -mpegts_mux_class_scan_state_set ( void *o, const void *p ) -{ - mpegts_mux_t *mm = o; - int state = *(int*)p; +int mpegts_mux_class_scan_state_set(void* o, const void* p) { + mpegts_mux_t* mm = o; + int state = *(int*)p; /* Ignore */ if (!mm->mm_is_enabled(mm)) return 0; - + /* Start */ - if (state == MM_SCAN_STATE_PEND || - state == MM_SCAN_STATE_IPEND || + if (state == MM_SCAN_STATE_PEND || state == MM_SCAN_STATE_IPEND || state == MM_SCAN_STATE_ACTIVE) { /* Start (only if required) */ - mpegts_network_scan_queue_add(mm, SUBSCRIPTION_PRIO_SCAN_USER, - SUBSCRIPTION_USERSCAN, 0); + mpegts_network_scan_queue_add(mm, SUBSCRIPTION_PRIO_SCAN_USER, SUBSCRIPTION_USERSCAN, 0); - /* Stop */ + /* Stop */ } else if (state == MM_SCAN_STATE_IDLE) { /* No change */ @@ -436,29 +390,23 @@ mpegts_mux_class_scan_state_set ( void *o, const void *p ) /* Update */ mpegts_network_scan_mux_cancel(mm, 0); - /* Invalid */ + /* Invalid */ } else { } return 1; } -static htsmsg_t * -mpegts_mux_class_scan_state_enum ( void *p, const char *lang ) -{ +static htsmsg_t* mpegts_mux_class_scan_state_enum(void* p, const char* lang) { return strtab2htsmsg(scan_state_tab, 1, lang); } -static htsmsg_t * -mpegts_mux_class_scan_result_enum ( void *p, const char *lang ) -{ +static htsmsg_t* mpegts_mux_class_scan_result_enum(void* p, const char* lang) { return strtab2htsmsg(scan_result_tab, 1, lang); } -static void -mpegts_mux_class_enabled_notify ( void *p, const char *lang ) -{ - mpegts_mux_t *mm = p; +static void mpegts_mux_class_enabled_notify(void* p, const char* lang) { + mpegts_mux_t* mm = p; if (!mm->mm_is_enabled(mm)) { mm->mm_stop(mm, 1, SM_CODE_MUX_NOT_ENABLED); mpegts_network_scan_mux_cancel(mm, 0); @@ -469,286 +417,260 @@ mpegts_mux_class_enabled_notify ( void *p, const char *lang ) } } -static htsmsg_t * -mpegts_mux_enable_list ( void *o, const char *lang ) -{ +static htsmsg_t* mpegts_mux_enable_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Ignore"), MM_IGNORE }, - { N_("Disable"), MM_DISABLE }, - { N_("Enable"), MM_ENABLE }, + {N_("Ignore"), MM_IGNORE}, + {N_("Disable"), MM_DISABLE}, + {N_("Enable"), MM_ENABLE}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -mpegts_mux_epg_list ( void *o, const char *lang ) -{ +static htsmsg_t* mpegts_mux_epg_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Disable"), MM_EPG_DISABLE }, - { N_("Enable (auto)"), MM_EPG_ENABLE }, - { N_("Force (auto)"), MM_EPG_FORCE }, - { N_("Manual selection"), MM_EPG_MANUAL }, - { N_("Auto-Detected"), MM_EPG_DETECTED }, + {N_("Disable"), MM_EPG_DISABLE}, + {N_("Enable (auto)"), MM_EPG_ENABLE}, + {N_("Force (auto)"), MM_EPG_FORCE}, + {N_("Manual selection"), MM_EPG_MANUAL}, + {N_("Auto-Detected"), MM_EPG_DETECTED}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -mpegts_mux_epg_module_id_list ( void *o, const char *lang ) -{ +static htsmsg_t* mpegts_mux_epg_module_id_list(void* o, const char* lang) { return epggrab_ota_module_id_list(lang); } -static htsmsg_t * -mpegts_mux_ac3_list ( void *o, const char *lang ) -{ +static htsmsg_t* mpegts_mux_ac3_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Standard"), MM_AC3_STANDARD }, - { N_("AC-3 = descriptor 6"), MM_AC3_PMT_06 }, - { N_("Ignore descriptor 5"), MM_AC3_PMT_N05 }, + {N_("Standard"), MM_AC3_STANDARD}, + {N_("AC-3 = descriptor 6"), MM_AC3_PMT_06}, + {N_("Ignore descriptor 5"), MM_AC3_PMT_N05}, }; return strtab2htsmsg(tab, 1, lang); } CLASS_DOC(mpegts_mux) -const idclass_t mpegts_mux_class = -{ - .ic_class = "mpegts_mux", - .ic_caption = N_("DVB Inputs - Multiplex"), - .ic_event = "mpegts_mux", - .ic_doc = tvh_doc_mpegts_mux_class, - .ic_perm_def = ACCESS_ADMIN, - .ic_save = mpegts_mux_class_save, - .ic_delete = mpegts_mux_class_delete, - .ic_get_title = mpegts_mux_class_get_title, - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable, disable or ignore the mux. " - "When the mux is marked as ignore, " - "all discovered services are removed."), - .off = offsetof(mpegts_mux_t, mm_enabled), - .def.i = MM_ENABLE, - .list = mpegts_mux_enable_list, - .notify = mpegts_mux_class_enabled_notify, - .opts = PO_DOC_NLIST - }, - { - .type = PT_INT, - .id = "epg", - .name = N_("EPG scan"), - .desc = N_("The EPG grabber to use on the mux. " - "Enable (auto) is the recommended value."), - .off = offsetof(mpegts_mux_t, mm_epg), - .def.i = MM_EPG_ENABLE, - .list = mpegts_mux_epg_list, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "epg_module_id", - .name = N_("EPG module id"), - .desc = N_("The EPG grabber to use on the mux. " - "The 'EPG scan' field must be set to 'manual'."), - .off = offsetof(mpegts_mux_t, mm_epg_module_id), - .list = mpegts_mux_epg_module_id_list, - .opts = PO_DOC_NLIST, - }, - { - .type = PT_STR, - .id = "network", - .name = N_("Network"), - .desc = N_("The network the mux is on."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = mpegts_mux_class_get_network, - }, - { - .type = PT_STR, - .id = "network_uuid", - .name = N_("Network UUID"), - .desc = N_("The networks' universally unique identifier (UUID)."), - .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_EXPERT, - .get = mpegts_mux_class_get_network_uuid, - }, - { - .type = PT_STR, - .id = "name", - .name = N_("Name"), - .desc = N_("The name (or frequency) the mux is on."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = mpegts_mux_class_get_name, - }, - { - .type = PT_STR, - .id = "pnetwork_name", - .name = N_("Provider network name"), - .desc = N_("The provider's network name."), - .off = offsetof(mpegts_mux_t, mm_provider_network_name), - .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, - }, - { - .type = PT_U32, - .id = "onid", - .name = N_("Original network ID"), - .desc = N_("The provider's network ID."), - .opts = PO_RDONLY | PO_ADVANCED, - .off = offsetof(mpegts_mux_t, mm_onid), - }, - { - .type = PT_U32, - .id = "tsid", - .name = N_("Transport stream ID"), - .desc = N_("The transport stream ID of the mux within the " - "network."), - .opts = PO_RDONLY | PO_ADVANCED, - .off = offsetof(mpegts_mux_t, mm_tsid), - }, - { - .type = PT_STR, - .id = "cridauth", - .name = N_("CRID authority"), - .desc = N_("The Content reference identifier (CRID) authority."), - .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, - .off = offsetof(mpegts_mux_t, mm_crid_authority), - }, - { - .type = PT_INT, - .id = "scan_state", - .name = N_("Scan status"), - .desc = N_("The scan state. New muxes will automatically be " - "changed to the PEND state. You can change this to " - "ACTIVE to queue a scan of this mux."), - .off = offsetof(mpegts_mux_t, mm_scan_state), - .set = mpegts_mux_class_scan_state_set, - .list = mpegts_mux_class_scan_state_enum, - .opts = PO_ADVANCED | PO_NOSAVE | PO_SORTKEY | PO_DOC_NLIST, - }, - { - .type = PT_INT, - .id = "scan_result", - .name = N_("Scan result"), - .desc = N_("The outcome of the last scan performed."), - .off = offsetof(mpegts_mux_t, mm_scan_result), - .opts = PO_RDONLY | PO_SORTKEY | PO_DOC_NLIST, - .list = mpegts_mux_class_scan_result_enum, - }, - { - .type = PT_STR, - .id = "charset", - .name = N_("Character set"), - .desc = N_("The character set to use/used. You should " - "not have to change this unless channel names " - "and EPG data appear garbled."), - .off = offsetof(mpegts_mux_t, mm_charset), - .list = dvb_charset_enum, - .opts = PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_INT, - .id = "num_svc", - .name = N_("Services"), - .desc = N_("The total number of services found."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = mpegts_mux_class_get_num_svc, - }, - { - .type = PT_INT, - .id = "num_chn", - .name = N_("Mapped"), - .desc = N_("The number of services currently mapped to " - "channels."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = mpegts_mux_class_get_num_chn, - }, - { - .type = PT_BOOL, - .id = "tsid_zero", - .name = N_("Accept zero value for TSID"), - .off = offsetof(mpegts_mux_t, mm_tsid_accept_zero_value), - .opts = PO_EXPERT - }, - { - .type = PT_INT, - .id = "pmt_06_ac3", - .name = N_("AC-3 detection"), - .desc = N_("Use AC-3 detection."), - .off = offsetof(mpegts_mux_t, mm_pmt_ac3), - .def.i = MM_AC3_STANDARD, - .list = mpegts_mux_ac3_list, - .opts = PO_HIDDEN | PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_BOOL, - .id = "eit_tsid_nocheck", - .name = N_("EIT - skip TSID check"), - .desc = N_("Skip TSID checking. For when providers use invalid " - "Transport Stream IDs."), - .off = offsetof(mpegts_mux_t, mm_eit_tsid_nocheck), - .opts = PO_HIDDEN | PO_EXPERT - }, - { - .type = PT_U16, - .id = "sid_filter", - .name = N_("Service ID"), - .desc = N_("Use only this service ID, filter out others."), - .off = offsetof(mpegts_mux_t, mm_sid_filter), - .opts = PO_HIDDEN | PO_EXPERT - }, - { - .type = PT_TIME, - .id = "created", - .name = N_("Created"), - .desc = N_("When the mux was created."), - .off = offsetof(mpegts_mux_t, mm_created), - .opts = PO_ADVANCED | PO_RDONLY, - }, - { - .type = PT_TIME, - .id = "scan_first", - .name = N_("First scan"), - .desc = N_("When the mux was successfully scanned for the first time."), - .off = offsetof(mpegts_mux_t, mm_scan_first), - .opts = PO_ADVANCED | PO_RDONLY, - }, - { - .type = PT_TIME, - .id = "scan_last", - .name = N_("Last scan"), - .desc = N_("When the mux was successfully scanned."), - .off = offsetof(mpegts_mux_t, mm_scan_last_seen), - .opts = PO_ADVANCED | PO_RDONLY, - }, - {} - } -}; +const idclass_t mpegts_mux_class = {.ic_class = "mpegts_mux", + .ic_caption = N_("DVB Inputs - Multiplex"), + .ic_event = "mpegts_mux", + .ic_doc = tvh_doc_mpegts_mux_class, + .ic_perm_def = ACCESS_ADMIN, + .ic_save = mpegts_mux_class_save, + .ic_delete = mpegts_mux_class_delete, + .ic_get_title = mpegts_mux_class_get_title, + .ic_properties = (const property_t[]){{.type = PT_INT, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable, disable or ignore the mux. " + "When the mux is marked as ignore, " + "all discovered services are removed."), + .off = offsetof(mpegts_mux_t, mm_enabled), + .def.i = MM_ENABLE, + .list = mpegts_mux_enable_list, + .notify = mpegts_mux_class_enabled_notify, + .opts = PO_DOC_NLIST}, + { + .type = PT_INT, + .id = "epg", + .name = N_("EPG scan"), + .desc = N_("The EPG grabber to use on the mux. " + "Enable (auto) is the recommended value."), + .off = offsetof(mpegts_mux_t, mm_epg), + .def.i = MM_EPG_ENABLE, + .list = mpegts_mux_epg_list, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "epg_module_id", + .name = N_("EPG module id"), + .desc = N_("The EPG grabber to use on the mux. " + "The 'EPG scan' field must be set to 'manual'."), + .off = offsetof(mpegts_mux_t, mm_epg_module_id), + .list = mpegts_mux_epg_module_id_list, + .opts = PO_DOC_NLIST, + }, + { + .type = PT_STR, + .id = "network", + .name = N_("Network"), + .desc = N_("The network the mux is on."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = mpegts_mux_class_get_network, + }, + { + .type = PT_STR, + .id = "network_uuid", + .name = N_("Network UUID"), + .desc = N_("The networks' universally unique identifier (UUID)."), + .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_EXPERT, + .get = mpegts_mux_class_get_network_uuid, + }, + { + .type = PT_STR, + .id = "name", + .name = N_("Name"), + .desc = N_("The name (or frequency) the mux is on."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = mpegts_mux_class_get_name, + }, + { + .type = PT_STR, + .id = "pnetwork_name", + .name = N_("Provider network name"), + .desc = N_("The provider's network name."), + .off = offsetof(mpegts_mux_t, mm_provider_network_name), + .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, + }, + { + .type = PT_U32, + .id = "onid", + .name = N_("Original network ID"), + .desc = N_("The provider's network ID."), + .opts = PO_RDONLY | PO_ADVANCED, + .off = offsetof(mpegts_mux_t, mm_onid), + }, + { + .type = PT_U32, + .id = "tsid", + .name = N_("Transport stream ID"), + .desc = N_("The transport stream ID of the mux within the " + "network."), + .opts = PO_RDONLY | PO_ADVANCED, + .off = offsetof(mpegts_mux_t, mm_tsid), + }, + { + .type = PT_STR, + .id = "cridauth", + .name = N_("CRID authority"), + .desc = N_("The Content reference identifier (CRID) authority."), + .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, + .off = offsetof(mpegts_mux_t, mm_crid_authority), + }, + { + .type = PT_INT, + .id = "scan_state", + .name = N_("Scan status"), + .desc = N_("The scan state. New muxes will automatically be " + "changed to the PEND state. You can change this to " + "ACTIVE to queue a scan of this mux."), + .off = offsetof(mpegts_mux_t, mm_scan_state), + .set = mpegts_mux_class_scan_state_set, + .list = mpegts_mux_class_scan_state_enum, + .opts = PO_ADVANCED | PO_NOSAVE | PO_SORTKEY | PO_DOC_NLIST, + }, + { + .type = PT_INT, + .id = "scan_result", + .name = N_("Scan result"), + .desc = N_("The outcome of the last scan performed."), + .off = offsetof(mpegts_mux_t, mm_scan_result), + .opts = PO_RDONLY | PO_SORTKEY | PO_DOC_NLIST, + .list = mpegts_mux_class_scan_result_enum, + }, + { + .type = PT_STR, + .id = "charset", + .name = N_("Character set"), + .desc = N_("The character set to use/used. You should " + "not have to change this unless channel names " + "and EPG data appear garbled."), + .off = offsetof(mpegts_mux_t, mm_charset), + .list = dvb_charset_enum, + .opts = PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_INT, + .id = "num_svc", + .name = N_("Services"), + .desc = N_("The total number of services found."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = mpegts_mux_class_get_num_svc, + }, + { + .type = PT_INT, + .id = "num_chn", + .name = N_("Mapped"), + .desc = N_("The number of services currently mapped to " + "channels."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = mpegts_mux_class_get_num_chn, + }, + {.type = PT_BOOL, + .id = "tsid_zero", + .name = N_("Accept zero value for TSID"), + .off = offsetof(mpegts_mux_t, mm_tsid_accept_zero_value), + .opts = PO_EXPERT}, + { + .type = PT_INT, + .id = "pmt_06_ac3", + .name = N_("AC-3 detection"), + .desc = N_("Use AC-3 detection."), + .off = offsetof(mpegts_mux_t, mm_pmt_ac3), + .def.i = MM_AC3_STANDARD, + .list = mpegts_mux_ac3_list, + .opts = PO_HIDDEN | PO_EXPERT | PO_DOC_NLIST, + }, + {.type = PT_BOOL, + .id = "eit_tsid_nocheck", + .name = N_("EIT - skip TSID check"), + .desc = N_("Skip TSID checking. For when providers use invalid " + "Transport Stream IDs."), + .off = offsetof(mpegts_mux_t, mm_eit_tsid_nocheck), + .opts = PO_HIDDEN | PO_EXPERT}, + {.type = PT_U16, + .id = "sid_filter", + .name = N_("Service ID"), + .desc = N_("Use only this service ID, filter out others."), + .off = offsetof(mpegts_mux_t, mm_sid_filter), + .opts = PO_HIDDEN | PO_EXPERT}, + { + .type = PT_TIME, + .id = "created", + .name = N_("Created"), + .desc = N_("When the mux was created."), + .off = offsetof(mpegts_mux_t, mm_created), + .opts = PO_ADVANCED | PO_RDONLY, + }, + { + .type = PT_TIME, + .id = "scan_first", + .name = N_("First scan"), + .desc = N_("When the mux was successfully scanned for the first time."), + .off = offsetof(mpegts_mux_t, mm_scan_first), + .opts = PO_ADVANCED | PO_RDONLY, + }, + { + .type = PT_TIME, + .id = "scan_last", + .name = N_("Last scan"), + .desc = N_("When the mux was successfully scanned."), + .off = offsetof(mpegts_mux_t, mm_scan_last_seen), + .opts = PO_ADVANCED | PO_RDONLY, + }, + {}}}; /* **************************************************************************** * Class methods * ***************************************************************************/ -static void -mpegts_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len ) -{ - snprintf(buf, len, "Multiplex [onid:%04X tsid:%04X]", - mm->mm_onid, mm->mm_tsid); +static void mpegts_mux_display_name(mpegts_mux_t* mm, char* buf, size_t len) { + snprintf(buf, len, "Multiplex [onid:%04X tsid:%04X]", mm->mm_onid, mm->mm_tsid); } -static void -mpegts_mux_do_stop ( mpegts_mux_t *mm, int delconf ) -{ - mpegts_mux_instance_t *mmi; - th_subscription_t *ths; - mpegts_service_t *s; +static void mpegts_mux_do_stop(mpegts_mux_t* mm, int delconf) { + mpegts_mux_instance_t* mmi; + th_subscription_t* ths; + mpegts_service_t* s; /* Cancel scan */ mpegts_network_scan_queue_del(mm); /* Remove instances */ while ((mmi = LIST_FIRST(&mm->mm_instances))) { - mmi->tii_delete((tvh_input_instance_t *)mmi); + mmi->tii_delete((tvh_input_instance_t*)mmi); } /* Remove raw subscribers */ @@ -762,9 +684,7 @@ mpegts_mux_do_stop ( mpegts_mux_t *mm, int delconf ) } } -void -mpegts_mux_free ( mpegts_mux_t *mm ) -{ +void mpegts_mux_free(mpegts_mux_t* mm) { free(mm->mm_provider_network_name); free(mm->mm_crid_authority); free(mm->mm_charset); @@ -773,9 +693,7 @@ mpegts_mux_free ( mpegts_mux_t *mm ) free(mm); } -void -mpegts_mux_delete ( mpegts_mux_t *mm, int delconf ) -{ +void mpegts_mux_delete(mpegts_mux_t* mm, int delconf) { idnode_save_check(&mm->mm_id, delconf); tvhinfo(LS_MPEGTS, "%s (%p) - deleting", mm->mm_nicename, mm); @@ -795,39 +713,29 @@ mpegts_mux_delete ( mpegts_mux_t *mm, int delconf ) mpegts_mux_release(mm); } -static htsmsg_t * -mpegts_mux_config_save ( mpegts_mux_t *mm, char *filename, size_t fsize ) -{ +static htsmsg_t* mpegts_mux_config_save(mpegts_mux_t* mm, char* filename, size_t fsize) { return NULL; } -static int -mpegts_mux_is_enabled ( mpegts_mux_t *mm ) -{ +static int mpegts_mux_is_enabled(mpegts_mux_t* mm) { return mm->mm_network->mn_enabled && mm->mm_enabled == MM_ENABLE; } -static int -mpegts_mux_is_epg ( mpegts_mux_t *mm ) -{ +static int mpegts_mux_is_epg(mpegts_mux_t* mm) { return mm->mm_epg; } -static void -mpegts_mux_create_instances ( mpegts_mux_t *mm ) -{ - mpegts_network_link_t *mnl; - LIST_FOREACH(mnl, &mm->mm_network->mn_inputs, mnl_mn_link) { - mpegts_input_t *mi = mnl->mnl_input; +static void mpegts_mux_create_instances(mpegts_mux_t* mm) { + mpegts_network_link_t* mnl; + LIST_FOREACH (mnl, &mm->mm_network->mn_inputs, mnl_mn_link) { + mpegts_input_t* mi = mnl->mnl_input; if (mi->mi_is_enabled(mi, mm, 0, -1) != MI_IS_ENABLED_NEVER) mi->mi_create_mux_instance(mi, mm); } } -static int -mpegts_mux_has_subscribers ( mpegts_mux_t *mm, const char *name ) -{ - mpegts_mux_instance_t *mmi = mm->mm_active; +static int mpegts_mux_has_subscribers(mpegts_mux_t* mm, const char* name) { + mpegts_mux_instance_t* mmi = mm->mm_active; if (mmi) { if (mmi->mmi_input->mi_has_subscription(mmi->mmi_input, mm)) { tvhtrace(LS_MPEGTS, "%s - keeping mux", name); @@ -837,20 +745,19 @@ mpegts_mux_has_subscribers ( mpegts_mux_t *mm, const char *name ) return 0; } -static void -mpegts_mux_stop ( mpegts_mux_t *mm, int force, int reason ) -{ - char *s; +static void mpegts_mux_stop(mpegts_mux_t* mm, int force, int reason) { + char* s; mpegts_mux_instance_t *mmi = mm->mm_active, *mmi2; - mpegts_input_t *mi = NULL, *mi2; - mpegts_pid_t *mp; - mpegts_pid_sub_t *mps; + mpegts_input_t * mi = NULL, *mi2; + mpegts_pid_t* mp; + mpegts_pid_sub_t* mps; if (!force && mpegts_mux_has_subscribers(mm, mm->mm_nicename)) return; /* Stop possible recursion */ - if (!mmi) return; + if (!mmi) + return; tvhdebug(LS_MPEGTS, "%s - stopping mux%s", mm->mm_nicename, force ? " (forced)" : ""); @@ -862,7 +769,7 @@ mpegts_mux_stop ( mpegts_mux_t *mm, int force, int reason ) mi2 = mpegts_input_find(mi->mi_linked); if (mi2 && (mmi2 = LIST_FIRST(&mi2->mi_mux_active)) != NULL) { if (mmi2 && !mpegts_mux_has_subscribers(mmi2->mmi_mux, mmi2->mmi_mux->mm_nicename)) { - s = mi2->mi_linked; + s = mi2->mi_linked; mi2->mi_linked = NULL; mpegts_mux_unsubscribe_linked(mi2, NULL); mi2->mi_linked = s; @@ -889,33 +796,38 @@ mpegts_mux_stop ( mpegts_mux_t *mm, int force, int reason ) tvhtrace(LS_MPEGTS, "%s - flush tables", mm->mm_nicename); mpegts_table_flush_all(mm); - tvhtrace(LS_MPEGTS, "%s - mi=%p", mm->mm_nicename, (void *)mi); + tvhtrace(LS_MPEGTS, "%s - mi=%p", mm->mm_nicename, (void*)mi); /* Flush table data queue */ mpegts_input_flush_mux(mi, mm); /* Ensure PIDs are cleared */ tvh_mutex_lock(&mi->mi_output_lock); mm->mm_last_pid = -1; - mm->mm_last_mp = NULL; + mm->mm_last_mp = NULL; while ((mp = RB_FIRST(&mm->mm_pids))) { assert(mi); - if (mp->mp_pid == MPEGTS_FULLMUX_PID || - mp->mp_pid == MPEGTS_TABLES_PID) { + if (mp->mp_pid == MPEGTS_FULLMUX_PID || mp->mp_pid == MPEGTS_TABLES_PID) { while ((mps = LIST_FIRST(&mm->mm_all_subs))) { - tvhdebug(LS_MPEGTS, "%s - close PID %s subscription [%d/%p]", - mm->mm_nicename, - mp->mp_pid == MPEGTS_TABLES_PID ? "tables" : "fullmux", - mps->mps_type, mps->mps_owner); + tvhdebug(LS_MPEGTS, + "%s - close PID %s subscription [%d/%p]", + mm->mm_nicename, + mp->mp_pid == MPEGTS_TABLES_PID ? "tables" : "fullmux", + mps->mps_type, + mps->mps_owner); LIST_REMOVE(mps, mps_svcraw_link); free(mps); } } else { while ((mps = RB_FIRST(&mp->mp_subs))) { - tvhdebug(LS_MPEGTS, "%s - close PID %04X (%d) [%d/%p]", - mm->mm_nicename, - mp->mp_pid, mp->mp_pid, mps->mps_type, mps->mps_owner); + tvhdebug(LS_MPEGTS, + "%s - close PID %04X (%d) [%d/%p]", + mm->mm_nicename, + mp->mp_pid, + mp->mp_pid, + mps->mps_type, + mps->mps_owner); RB_REMOVE(&mp->mp_subs, mps, mps_link); - if (mps->mps_type & (MPS_SERVICE|MPS_ALL)) + if (mps->mps_type & (MPS_SERVICE | MPS_ALL)) LIST_REMOVE(mps, mps_svcraw_link); if (mps->mps_type & MPS_RAW) LIST_REMOVE(mps, mps_raw_link); @@ -937,11 +849,9 @@ mpegts_mux_stop ( mpegts_mux_t *mm, int force, int reason ) mm->mm_fastscan_muxes = NULL; } -static void -mpegts_mux_update_pids_cb ( void *aux ) -{ - mpegts_mux_t *mm = aux; - mpegts_input_t *mi; +static void mpegts_mux_update_pids_cb(void* aux) { + mpegts_mux_t* mm = aux; + mpegts_input_t* mi; if (mm && mm->mm_active) { mi = mm->mm_active->mmi_input; @@ -954,17 +864,13 @@ mpegts_mux_update_pids_cb ( void *aux ) } } -void -mpegts_mux_update_pids ( mpegts_mux_t *mm ) -{ +void mpegts_mux_update_pids(mpegts_mux_t* mm) { if (mm && mm->mm_active) mtimer_arm_rel(&mm->mm_update_pids_timer, mpegts_mux_update_pids_cb, mm, 0); } -void -mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe ) -{ - mpegts_input_t *mi; +void mpegts_mux_open_table(mpegts_mux_t* mm, mpegts_table_t* mt, int subscribe) { + mpegts_input_t* mi; lock_assert(&mm->mm_tables_lock); @@ -1001,10 +907,8 @@ mpegts_mux_open_table ( mpegts_mux_t *mm, mpegts_table_t *mt, int subscribe ) } } -void -mpegts_mux_unsubscribe_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) -{ - mpegts_input_t *mi; +void mpegts_mux_unsubscribe_table(mpegts_mux_t* mm, mpegts_table_t* mt) { + mpegts_input_t* mi; lock_assert(&mm->mm_tables_lock); @@ -1026,9 +930,7 @@ mpegts_mux_unsubscribe_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) } } -void -mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) -{ +void mpegts_mux_close_table(mpegts_mux_t* mm, mpegts_table_t* mt) { lock_assert(&mm->mm_tables_lock); if (!mm->mm_active || !mm->mm_active->mmi_input) { @@ -1068,11 +970,9 @@ mpegts_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt ) * Scanning * *************************************************************************/ -static void -mpegts_mux_scan_service_check ( mpegts_mux_t *mm ) -{ +static void mpegts_mux_scan_service_check(mpegts_mux_t* mm) { mpegts_service_t *s, *snext; - time_t last_seen; + time_t last_seen; /* * Disable "not seen" services. It's quite easy algorithm which @@ -1083,35 +983,35 @@ mpegts_mux_scan_service_check ( mpegts_mux_t *mm ) * fully completed (all live services are known at this point). */ last_seen = 0; - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) if (last_seen < s->s_dvb_check_seen) last_seen = s->s_dvb_check_seen; for (s = LIST_FIRST(&mm->mm_services); s; s = snext) { snext = LIST_NEXT(s, s_dvb_mux_link); if (s->s_enabled && s->s_auto != SERVICE_AUTO_OFF && s->s_dvb_check_seen + 24 * 3600 < last_seen) { - tvhinfo(LS_MPEGTS, "disabling service %s [sid %04X/%d] (missing in PAT/SDT)", - s->s_nicename ?: "", - service_id16(s), service_id16(s)); - service_set_enabled((service_t *)s, 0, SERVICE_AUTO_PAT_MISSING); + tvhinfo(LS_MPEGTS, + "disabling service %s [sid %04X/%d] (missing in PAT/SDT)", + s->s_nicename ?: "", + service_id16(s), + service_id16(s)); + service_set_enabled((service_t*)s, 0, SERVICE_AUTO_PAT_MISSING); } } } -void -mpegts_mux_scan_done ( mpegts_mux_t *mm, const char *buf, int res ) -{ - mpegts_table_t *mt; - int total = 0, incomplete = 0; +void mpegts_mux_scan_done(mpegts_mux_t* mm, const char* buf, int res) { + mpegts_table_t* mt; + int total = 0, incomplete = 0; assert(mm->mm_scan_state == MM_SCAN_STATE_ACTIVE); /* Log */ tvh_mutex_lock(&mm->mm_tables_lock); mpegts_table_consistency_check(mm); - LIST_FOREACH(mt, &mm->mm_tables, mt_link) { + LIST_FOREACH (mt, &mm->mm_tables, mt_link) { if (mt->mt_flags & MT_QUICKREQ) { - const char *s = "not found"; + const char* s = "not found"; if (mt->mt_complete) { s = "complete"; total++; @@ -1148,12 +1048,10 @@ mpegts_mux_scan_done ( mpegts_mux_t *mm, const char *buf, int res ) } } -static void -mpegts_mux_scan_timeout ( void *aux ) -{ - int c, q, w; - mpegts_mux_t *mm = aux; - mpegts_table_t *mt; +static void mpegts_mux_scan_timeout(void* aux) { + int c, q, w; + mpegts_mux_t* mm = aux; + mpegts_table_t* mt; /* Timeout */ if (mm->mm_scan_init) { @@ -1161,14 +1059,15 @@ mpegts_mux_scan_timeout ( void *aux ) return; } mm->mm_scan_init = 1; - + /* Check tables */ again: tvh_mutex_lock(&mm->mm_tables_lock); mpegts_table_consistency_check(mm); c = q = w = 0; - LIST_FOREACH(mt, &mm->mm_tables, mt_link) { - if (!(mt->mt_flags & MT_QUICKREQ) && !mt->mt_working) continue; + LIST_FOREACH (mt, &mm->mm_tables, mt_link) { + if (!(mt->mt_flags & MT_QUICKREQ) && !mt->mt_working) + continue; if (!mt->mt_count) { mpegts_table_grab(mt); tvh_mutex_unlock(&mm->mm_tables_lock); @@ -1184,18 +1083,18 @@ again: } } tvh_mutex_unlock(&mm->mm_tables_lock); - + /* No DATA - give up now */ if (!c) { mpegts_mux_scan_done(mm, mm->mm_nicename, 0); - /* Pending tables (another 20s or 30s - bit arbitrary) */ + /* Pending tables (another 20s or 30s - bit arbitrary) */ } else if (q) { tvhtrace(LS_MPEGTS, "%s - scan needs more time", mm->mm_nicename); mtimer_arm_rel(&mm->mm_scan_timeout, mpegts_mux_scan_timeout, mm, sec2mono(w ? 30 : 20)); return; - /* Complete */ + /* Complete */ } else { mpegts_mux_scan_done(mm, mm->mm_nicename, 1); } @@ -1205,11 +1104,13 @@ again: * Creation / Config * *************************************************************************/ -mpegts_mux_t * -mpegts_mux_create0 - ( mpegts_mux_t *mm, const idclass_t *class, const char *uuid, - mpegts_network_t *mn, uint32_t onid, uint32_t tsid, htsmsg_t *conf ) -{ +mpegts_mux_t* mpegts_mux_create0(mpegts_mux_t* mm, + const idclass_t* class, + const char* uuid, + mpegts_network_t* mn, + uint32_t onid, + uint32_t tsid, + htsmsg_t* conf) { if (idnode_insert(&mm->mm_id, uuid, class, 0)) { if (uuid) tvherror(LS_MPEGTS, "invalid mux uuid '%s'", uuid); @@ -1217,36 +1118,36 @@ mpegts_mux_create0 return NULL; } - mm->mm_refcount = 1; + mm->mm_refcount = 1; /* Enabled by default */ - mm->mm_enabled = MM_ENABLE; - mm->mm_epg = MM_EPG_ENABLE; + mm->mm_enabled = MM_ENABLE; + mm->mm_epg = MM_EPG_ENABLE; /* Identification */ - mm->mm_onid = onid; - mm->mm_tsid = tsid; + mm->mm_onid = onid; + mm->mm_tsid = tsid; /* Add to network */ LIST_INSERT_HEAD(&mn->mn_muxes, mm, mm_network_link); - mm->mm_network = mn; + mm->mm_network = mn; /* Debug/Config */ - mm->mm_delete = mpegts_mux_delete; - mm->mm_free = mpegts_mux_free; - mm->mm_display_name = mpegts_mux_display_name; - mm->mm_config_save = mpegts_mux_config_save; - mm->mm_is_enabled = mpegts_mux_is_enabled; - mm->mm_is_epg = mpegts_mux_is_epg; + mm->mm_delete = mpegts_mux_delete; + mm->mm_free = mpegts_mux_free; + mm->mm_display_name = mpegts_mux_display_name; + mm->mm_config_save = mpegts_mux_config_save; + mm->mm_is_enabled = mpegts_mux_is_enabled; + mm->mm_is_epg = mpegts_mux_is_epg; /* Start/stop */ - mm->mm_stop = mpegts_mux_stop; - mm->mm_create_instances = mpegts_mux_create_instances; + mm->mm_stop = mpegts_mux_stop; + mm->mm_create_instances = mpegts_mux_create_instances; /* Table processing */ - mm->mm_open_table = mpegts_mux_open_table; - mm->mm_unsubscribe_table = mpegts_mux_unsubscribe_table; - mm->mm_close_table = mpegts_mux_close_table; + mm->mm_open_table = mpegts_mux_open_table; + mm->mm_unsubscribe_table = mpegts_mux_unsubscribe_table; + mm->mm_close_table = mpegts_mux_close_table; tvh_mutex_init(&mm->mm_tables_lock, NULL); TAILQ_INIT(&mm->mm_table_queue); TAILQ_INIT(&mm->mm_defer_tables); @@ -1255,8 +1156,8 @@ mpegts_mux_create0 TAILQ_INIT(&mm->mm_descrambler_emms); tvh_mutex_init(&mm->mm_descrambler_lock, NULL); - mm->mm_last_pid = -1; - mm->mm_created = gclk(); + mm->mm_last_pid = -1; + mm->mm_created = gclk(); /* Configuration */ if (conf) @@ -1265,10 +1166,8 @@ mpegts_mux_create0 return mm; } -mpegts_mux_t * -mpegts_mux_post_create ( mpegts_mux_t *mm ) -{ - mpegts_network_t *mn; +mpegts_mux_t* mpegts_mux_post_create(mpegts_mux_t* mm) { + mpegts_network_t* mn; if (mm == NULL) return NULL; @@ -1282,31 +1181,27 @@ mpegts_mux_post_create ( mpegts_mux_t *mm ) /* Initial scan */ if (mm->mm_scan_result == MM_SCAN_NONE || !mn->mn_skipinitscan) - mpegts_network_scan_queue_add(mm, SUBSCRIPTION_PRIO_SCAN_INIT, - SUBSCRIPTION_INITSCAN, 10); + mpegts_network_scan_queue_add(mm, SUBSCRIPTION_PRIO_SCAN_INIT, SUBSCRIPTION_INITSCAN, 10); else if (mm->mm_network->mn_idlescan) - mpegts_network_scan_queue_add(mm, SUBSCRIPTION_PRIO_SCAN_IDLE, - SUBSCRIPTION_IDLESCAN, 10); + mpegts_network_scan_queue_add(mm, SUBSCRIPTION_PRIO_SCAN_IDLE, SUBSCRIPTION_IDLESCAN, 10); return mm; } -void -mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c, int refs ) -{ - mpegts_service_t *ms; - htsmsg_t *root = !refs ? htsmsg_create_map() : c; - htsmsg_t *services = !refs ? htsmsg_create_map() : htsmsg_create_list(); - htsmsg_t *e; - char ubuf[UUID_HEX_SIZE]; +void mpegts_mux_save(mpegts_mux_t* mm, htsmsg_t* c, int refs) { + mpegts_service_t* ms; + htsmsg_t* root = !refs ? htsmsg_create_map() : c; + htsmsg_t* services = !refs ? htsmsg_create_map() : htsmsg_create_list(); + htsmsg_t* e; + char ubuf[UUID_HEX_SIZE]; idnode_save(&mm->mm_id, root); - LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) { + LIST_FOREACH (ms, &mm->mm_services, s_dvb_mux_link) { if (refs) { htsmsg_add_uuid(services, NULL, &ms->s_id.in_uuid); } else { e = htsmsg_create_map(); - service_save((service_t *)ms, e); + service_save((service_t*)ms, e); htsmsg_add_msg(services, idnode_uuid_as_str(&ms->s_id, ubuf), e); } } @@ -1315,9 +1210,7 @@ mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c, int refs ) htsmsg_add_msg(c, "config", root); } -int -mpegts_mux_set_network_name ( mpegts_mux_t *mm, const char *name ) -{ +int mpegts_mux_set_network_name(mpegts_mux_t* mm, const char* name) { if (strcmp(mm->mm_provider_network_name ?: "", name ?: "")) { tvh_str_update(&mm->mm_provider_network_name, name ?: ""); return 1; @@ -1325,9 +1218,7 @@ mpegts_mux_set_network_name ( mpegts_mux_t *mm, const char *name ) return 0; } -int -mpegts_mux_set_onid ( mpegts_mux_t *mm, uint32_t onid ) -{ +int mpegts_mux_set_onid(mpegts_mux_t* mm, uint32_t onid) { if (onid == mm->mm_onid) return 0; mm->mm_onid = onid; @@ -1336,9 +1227,7 @@ mpegts_mux_set_onid ( mpegts_mux_t *mm, uint32_t onid ) return 1; } -int -mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint32_t tsid, int force ) -{ +int mpegts_mux_set_tsid(mpegts_mux_t* mm, uint32_t tsid, int force) { if (tsid == mm->mm_tsid) return 0; if (!force && mm->mm_tsid != MPEGTS_TSID_NONE) @@ -1350,9 +1239,7 @@ mpegts_mux_set_tsid ( mpegts_mux_t *mm, uint32_t tsid, int force ) return 1; } -int -mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth ) -{ +int mpegts_mux_set_crid_authority(mpegts_mux_t* mm, const char* defauth) { if (defauth && !strcmp(defauth, mm->mm_crid_authority ?: "")) return 0; tvh_str_update(&mm->mm_crid_authority, defauth); @@ -1361,15 +1248,13 @@ mpegts_mux_set_crid_authority ( mpegts_mux_t *mm, const char *defauth ) return 1; } -int -mpegts_mux_set_epg_module ( mpegts_mux_t *mm, const char *modid ) -{ +int mpegts_mux_set_epg_module(mpegts_mux_t* mm, const char* modid) { switch (mm->mm_epg) { - case MM_EPG_ENABLE: - case MM_EPG_DETECTED: - break; - default: - return 0; + case MM_EPG_ENABLE: + case MM_EPG_DETECTED: + break; + default: + return 0; } if (modid && !strcmp(modid, mm->mm_epg_module_id ?: "")) return 0; @@ -1380,9 +1265,7 @@ mpegts_mux_set_epg_module ( mpegts_mux_t *mm, const char *modid ) return 1; } -void -mpegts_mux_nice_name( mpegts_mux_t *mm, char *buf, size_t len ) -{ +void mpegts_mux_nice_name(mpegts_mux_t* mm, char* buf, size_t len) { size_t len2; if (len == 0 || buf == NULL || mm == NULL) { @@ -1406,9 +1289,7 @@ mpegts_mux_nice_name( mpegts_mux_t *mm, char *buf, size_t len ) mm->mm_network->mn_display_name(mm->mm_network, buf, len); } -void -mpegts_mux_update_nice_name( mpegts_mux_t *mm ) -{ +void mpegts_mux_update_nice_name(mpegts_mux_t* mm) { char buf[256]; mpegts_mux_nice_name(mm, buf, sizeof(buf)); @@ -1420,36 +1301,35 @@ mpegts_mux_update_nice_name( mpegts_mux_t *mm ) * Subscriptions * *************************************************************************/ -void -mpegts_mux_remove_subscriber - ( mpegts_mux_t *mm, th_subscription_t *s, int reason ) -{ +void mpegts_mux_remove_subscriber(mpegts_mux_t* mm, th_subscription_t* s, int reason) { tvhtrace(LS_MPEGTS, "%s - remove subscriber (reason %i)", mm->mm_nicename, reason); mm->mm_stop(mm, 0, reason); } -int -mpegts_mux_subscribe - ( mpegts_mux_t *mm, mpegts_input_t *mi, - const char *name, int weight, int flags ) -{ - profile_chain_t prch; - th_subscription_t *s; - int err = 0; +int mpegts_mux_subscribe(mpegts_mux_t* mm, + mpegts_input_t* mi, + const char* name, + int weight, + int flags) { + profile_chain_t prch; + th_subscription_t* s; + int err = 0; memset(&prch, 0, sizeof(prch)); prch.prch_id = mm; - s = subscription_create_from_mux(&prch, (tvh_input_t *)mi, - weight, name, - SUBSCRIPTION_NONE | flags, - NULL, NULL, NULL, &err); + s = subscription_create_from_mux(&prch, + (tvh_input_t*)mi, + weight, + name, + SUBSCRIPTION_NONE | flags, + NULL, + NULL, + NULL, + &err); return s ? 0 : (err ? err : SM_CODE_UNDEFINED_ERROR); } -void -mpegts_mux_unsubscribe_by_name - ( mpegts_mux_t *mm, const char *name ) -{ - const service_t *t; +void mpegts_mux_unsubscribe_by_name(mpegts_mux_t* mm, const char* name) { + const service_t* t; th_subscription_t *s, *n; s = LIST_FIRST(&mm->mm_raw_subs); @@ -1462,14 +1342,11 @@ mpegts_mux_unsubscribe_by_name } } -th_subscription_t * -mpegts_mux_find_subscription_by_name - ( mpegts_mux_t *mm, const char *name ) -{ - const service_t *t; - th_subscription_t *s; +th_subscription_t* mpegts_mux_find_subscription_by_name(mpegts_mux_t* mm, const char* name) { + const service_t* t; + th_subscription_t* s; - LIST_FOREACH(s, &mm->mm_raw_subs, ths_mux_link) { + LIST_FOREACH (s, &mm->mm_raw_subs, ths_mux_link) { t = s->ths_service; if (t && t->s_type == STYPE_RAW && !strcmp(s->ths_title, name)) return s; @@ -1477,11 +1354,9 @@ mpegts_mux_find_subscription_by_name return NULL; } -void -mpegts_mux_tuning_error ( const char *mux_uuid, mpegts_mux_instance_t *mmi_match ) -{ - mpegts_mux_t *mm; - mpegts_mux_instance_t *mmi; +void mpegts_mux_tuning_error(const char* mux_uuid, mpegts_mux_instance_t* mmi_match) { + mpegts_mux_t* mm; + mpegts_mux_instance_t* mmi; if (!tvh_mutex_timedlock(&global_lock, 2000000)) { mm = mpegts_mux_find(mux_uuid); @@ -1498,33 +1373,29 @@ mpegts_mux_tuning_error ( const char *mux_uuid, mpegts_mux_instance_t *mmi_match * Search * *************************************************************************/ -mpegts_service_t * -mpegts_mux_find_service ( mpegts_mux_t *mm, uint16_t sid ) -{ - mpegts_service_t *ms; - LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) +mpegts_service_t* mpegts_mux_find_service(mpegts_mux_t* mm, uint16_t sid) { + mpegts_service_t* ms; + LIST_FOREACH (ms, &mm->mm_services, s_dvb_mux_link) if (service_id16(ms) == sid && ms->s_enabled) break; return ms; } -static int mp_cmp ( mpegts_pid_t *a, mpegts_pid_t *b ) -{ +static int mp_cmp(mpegts_pid_t* a, mpegts_pid_t* b) { return a->mp_pid - b->mp_pid; } -mpegts_pid_t * -mpegts_mux_find_pid_ ( mpegts_mux_t *mm, int pid, int create ) -{ +mpegts_pid_t* mpegts_mux_find_pid_(mpegts_mux_t* mm, int pid, int create) { mpegts_pid_t skel, *mp; - if (pid < 0 || pid > MPEGTS_TABLES_PID) return NULL; + if (pid < 0 || pid > MPEGTS_TABLES_PID) + return NULL; skel.mp_pid = pid; - mp = RB_FIND(&mm->mm_pids, &skel, mp_link, mp_cmp); + mp = RB_FIND(&mm->mm_pids, &skel, mp_link, mp_cmp); if (mp == NULL) { if (create) { - mp = calloc(1, sizeof(*mp)); + mp = calloc(1, sizeof(*mp)); mp->mp_pid = pid; if (!RB_INSERT_SORTED(&mm->mm_pids, mp, mp_link, mp_cmp)) { mp->mp_cc = -1; @@ -1536,7 +1407,7 @@ mpegts_mux_find_pid_ ( mpegts_mux_t *mm, int pid, int create ) } if (mp) { mm->mm_last_pid = pid; - mm->mm_last_mp = mp; + mm->mm_last_mp = mp; } return mp; } @@ -1545,22 +1416,18 @@ mpegts_mux_find_pid_ ( mpegts_mux_t *mm, int pid, int create ) * Misc * *************************************************************************/ -int -mpegts_mux_compare ( mpegts_mux_t *a, mpegts_mux_t *b ) -{ - int r = uuid_cmp(&a->mm_network->mn_id.in_uuid, - &b->mm_network->mn_id.in_uuid); +int mpegts_mux_compare(mpegts_mux_t* a, mpegts_mux_t* b) { + int r = uuid_cmp(&a->mm_network->mn_id.in_uuid, &b->mm_network->mn_id.in_uuid); if (r) return r; #if ENABLE_MPEGTS_DVB if (idnode_is_instance(&a->mm_id, &dvb_mux_dvbs_class) && idnode_is_instance(&b->mm_id, &dvb_mux_dvbs_class)) { - dvb_mux_conf_t *mc1 = &((dvb_mux_t *)a)->lm_tuning; - dvb_mux_conf_t *mc2 = &((dvb_mux_t *)b)->lm_tuning; + dvb_mux_conf_t* mc1 = &((dvb_mux_t*)a)->lm_tuning; + dvb_mux_conf_t* mc2 = &((dvb_mux_t*)b)->lm_tuning; assert(mc1->dmc_fe_type == DVB_TYPE_S); assert(mc2->dmc_fe_type == DVB_TYPE_S); - r = (int)mc1->u.dmc_fe_qpsk.polarisation - - (int)mc2->u.dmc_fe_qpsk.polarisation; + r = (int)mc1->u.dmc_fe_qpsk.polarisation - (int)mc2->u.dmc_fe_qpsk.polarisation; if (r == 0) r = mc1->dmc_fe_freq - mc2->dmc_fe_freq; } diff --git a/src/input/mpegts/mpegts_mux_dvb.c b/src/input/mpegts/mpegts_mux_dvb.c index 454019dba..931d7cb43 100644 --- a/src/input/mpegts/mpegts_mux_dvb.c +++ b/src/input/mpegts/mpegts_mux_dvb.c @@ -35,8 +35,7 @@ * Class definition * *************************************************************************/ -static void -dvb_mux_delete ( mpegts_mux_t *mm, int delconf ); +static void dvb_mux_delete(mpegts_mux_t* mm, int delconf); extern const idclass_t mpegts_mux_class; @@ -45,83 +44,62 @@ extern const idclass_t mpegts_mux_class; */ /* Macro to define mux class str get/set */ -#define dvb_mux_class_R(c, f, l, t, ...)\ -static const void * \ -dvb_mux_##c##_class_##l##_get (void *o)\ -{\ - dvb_mux_t *lm = o;\ - prop_ptr = dvb_##t##2str(lm->lm_tuning.dmc_fe_##f);\ - return &prop_ptr;\ -}\ -static int \ -dvb_mux_##c##_class_##l##_set (void *o, const void *v)\ -{\ - dvb_mux_t *lm = o;\ - lm->lm_tuning.dmc_fe_##f = dvb_str2##t ((const char*)v);\ - return 1;\ -}\ -static htsmsg_t *\ -dvb_mux_##c##_class_##l##_enum (void *o, const char *lang)\ -{\ - static const int t[] = { __VA_ARGS__ };\ - int i;\ - htsmsg_t *m = htsmsg_create_list(), *e;\ - for (i = 0; i < ARRAY_SIZE(t); i++) {\ - e = htsmsg_create_key_val(dvb_##t##2str(t[i]), tvh_gettext_lang(lang, dvb_##t##2str(t[i]))); \ - htsmsg_add_msg(m, NULL, e);\ - }\ - return m;\ -} -#define dvb_mux_class_X(c, f, p, l, t, ...)\ -static const void * \ -dvb_mux_##c##_class_##l##_get (void *o)\ -{\ - dvb_mux_t *lm = o;\ - prop_ptr = dvb_##t##2str(lm->lm_tuning.u.dmc_fe_##f.p);\ - return &prop_ptr;\ -}\ -static int \ -dvb_mux_##c##_class_##l##_set (void *o, const void *v)\ -{\ - dvb_mux_t *lm = o;\ - lm->lm_tuning.u.dmc_fe_##f.p = dvb_str2##t ((const char*)v);\ - return 1;\ -}\ -static htsmsg_t *\ -dvb_mux_##c##_class_##l##_enum (void *o, const char *lang)\ -{\ - static const int t[] = { __VA_ARGS__ };\ - int i;\ - htsmsg_t *m = htsmsg_create_list(), *e;\ - for (i = 0; i < ARRAY_SIZE(t); i++) {\ - e = htsmsg_create_key_val(dvb_##t##2str(t[i]), tvh_gettext_lang(lang, dvb_##t##2str(t[i]))); \ - htsmsg_add_msg(m, NULL, e);\ - }\ - return m;\ -} -#define MUX_PROP_STR(_id, _name, t, l, d)\ - .type = PT_STR,\ - .id = _id,\ - .name = _name,\ - .get = dvb_mux_##t##_class_##l##_get,\ - .set = dvb_mux_##t##_class_##l##_set,\ - .list = dvb_mux_##t##_class_##l##_enum,\ - .def.s = d - -static const void * -dvb_mux_class_delsys_get (void *o) -{ - dvb_mux_t *lm = o; - prop_ptr = dvb_delsys2str(lm->lm_tuning.dmc_fe_delsys); +#define dvb_mux_class_R(c, f, l, t, ...) \ + static const void* dvb_mux_##c##_class_##l##_get(void* o) { \ + dvb_mux_t* lm = o; \ + prop_ptr = dvb_##t##2str(lm->lm_tuning.dmc_fe_##f); \ + return &prop_ptr; \ + } \ + static int dvb_mux_##c##_class_##l##_set(void* o, const void* v) { \ + dvb_mux_t* lm = o; \ + lm->lm_tuning.dmc_fe_##f = dvb_str2##t((const char*)v); \ + return 1; \ + } \ + static htsmsg_t* dvb_mux_##c##_class_##l##_enum(void* o, const char* lang) { \ + static const int t[] = {__VA_ARGS__}; \ + int i; \ + htsmsg_t * m = htsmsg_create_list(), *e; \ + for (i = 0; i < ARRAY_SIZE(t); i++) { \ + e = htsmsg_create_key_val(dvb_##t##2str(t[i]), tvh_gettext_lang(lang, dvb_##t##2str(t[i]))); \ + htsmsg_add_msg(m, NULL, e); \ + } \ + return m; \ + } +#define dvb_mux_class_X(c, f, p, l, t, ...) \ + static const void* dvb_mux_##c##_class_##l##_get(void* o) { \ + dvb_mux_t* lm = o; \ + prop_ptr = dvb_##t##2str(lm->lm_tuning.u.dmc_fe_##f.p); \ + return &prop_ptr; \ + } \ + static int dvb_mux_##c##_class_##l##_set(void* o, const void* v) { \ + dvb_mux_t* lm = o; \ + lm->lm_tuning.u.dmc_fe_##f.p = dvb_str2##t((const char*)v); \ + return 1; \ + } \ + static htsmsg_t* dvb_mux_##c##_class_##l##_enum(void* o, const char* lang) { \ + static const int t[] = {__VA_ARGS__}; \ + int i; \ + htsmsg_t * m = htsmsg_create_list(), *e; \ + for (i = 0; i < ARRAY_SIZE(t); i++) { \ + e = htsmsg_create_key_val(dvb_##t##2str(t[i]), tvh_gettext_lang(lang, dvb_##t##2str(t[i]))); \ + htsmsg_add_msg(m, NULL, e); \ + } \ + return m; \ + } +#define MUX_PROP_STR(_id, _name, t, l, d) \ + .type = PT_STR, .id = _id, .name = _name, .get = dvb_mux_##t##_class_##l##_get, \ + .set = dvb_mux_##t##_class_##l##_set, .list = dvb_mux_##t##_class_##l##_enum, .def.s = d + +static const void* dvb_mux_class_delsys_get(void* o) { + dvb_mux_t* lm = o; + prop_ptr = dvb_delsys2str(lm->lm_tuning.dmc_fe_delsys); return &prop_ptr; } -static int -dvb_mux_class_delsys_set (void *o, const void *v) -{ - const char *s = v; - int delsys = dvb_str2delsys(s); - dvb_mux_t *lm = o; +static int dvb_mux_class_delsys_set(void* o, const void* v) { + const char* s = v; + int delsys = dvb_str2delsys(s); + dvb_mux_t* lm = o; if (delsys != lm->lm_tuning.dmc_fe_delsys) { lm->lm_tuning.dmc_fe_delsys = dvb_str2delsys(s); return 1; @@ -129,65 +107,111 @@ dvb_mux_class_delsys_set (void *o, const void *v) return 0; } -const idclass_t dvb_mux_class = -{ - .ic_super = &mpegts_mux_class, - .ic_class = "dvb_mux", - .ic_caption = N_("DVB multiplex"), - .ic_properties = (const property_t[]){ - {} - } -}; +const idclass_t dvb_mux_class = {.ic_super = &mpegts_mux_class, + .ic_class = "dvb_mux", + .ic_caption = N_("DVB multiplex"), + .ic_properties = (const property_t[]){{}}}; /* * DVB-T */ -dvb_mux_class_X(dvbt, ofdm, bandwidth, bw, bw, - DVB_BANDWIDTH_AUTO, DVB_BANDWIDTH_10_MHZ, - DVB_BANDWIDTH_8_MHZ, DVB_BANDWIDTH_7_MHZ, - DVB_BANDWIDTH_6_MHZ, DVB_BANDWIDTH_5_MHZ, - DVB_BANDWIDTH_1_712_MHZ); -dvb_mux_class_R(dvbt, modulation, qam, qam, - DVB_MOD_QAM_AUTO, DVB_MOD_QPSK, DVB_MOD_QAM_16, - DVB_MOD_QAM_64, DVB_MOD_QAM_256); -dvb_mux_class_X(dvbt, ofdm, transmission_mode, mode, mode, - DVB_TRANSMISSION_MODE_AUTO, DVB_TRANSMISSION_MODE_32K, - DVB_TRANSMISSION_MODE_16K, DVB_TRANSMISSION_MODE_8K, - DVB_TRANSMISSION_MODE_2K, DVB_TRANSMISSION_MODE_1K); -dvb_mux_class_X(dvbt, ofdm, guard_interval, guard, guard, - DVB_GUARD_INTERVAL_AUTO, DVB_GUARD_INTERVAL_1_32, - DVB_GUARD_INTERVAL_1_16, DVB_GUARD_INTERVAL_1_8, - DVB_GUARD_INTERVAL_1_4, DVB_GUARD_INTERVAL_1_128, - DVB_GUARD_INTERVAL_19_128, DVB_GUARD_INTERVAL_19_256); -dvb_mux_class_X(dvbt, ofdm, hierarchy_information, hier, hier, - DVB_HIERARCHY_AUTO, DVB_HIERARCHY_NONE, - DVB_HIERARCHY_1, DVB_HIERARCHY_2, DVB_HIERARCHY_4); -dvb_mux_class_X(dvbt, ofdm, code_rate_HP, fechi, fechi, - DVB_FEC_AUTO, DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, - DVB_FEC_3_5, DVB_FEC_4_5, DVB_FEC_5_6, DVB_FEC_7_8); -dvb_mux_class_X(dvbt, ofdm, code_rate_LP, feclo, feclo, - DVB_FEC_AUTO, DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, - DVB_FEC_3_5, DVB_FEC_4_5, DVB_FEC_5_6, DVB_FEC_7_8); +dvb_mux_class_X(dvbt, + ofdm, + bandwidth, + bw, + bw, + DVB_BANDWIDTH_AUTO, + DVB_BANDWIDTH_10_MHZ, + DVB_BANDWIDTH_8_MHZ, + DVB_BANDWIDTH_7_MHZ, + DVB_BANDWIDTH_6_MHZ, + DVB_BANDWIDTH_5_MHZ, + DVB_BANDWIDTH_1_712_MHZ); +dvb_mux_class_R(dvbt, + modulation, + qam, + qam, + DVB_MOD_QAM_AUTO, + DVB_MOD_QPSK, + DVB_MOD_QAM_16, + DVB_MOD_QAM_64, + DVB_MOD_QAM_256); +dvb_mux_class_X(dvbt, + ofdm, + transmission_mode, + mode, + mode, + DVB_TRANSMISSION_MODE_AUTO, + DVB_TRANSMISSION_MODE_32K, + DVB_TRANSMISSION_MODE_16K, + DVB_TRANSMISSION_MODE_8K, + DVB_TRANSMISSION_MODE_2K, + DVB_TRANSMISSION_MODE_1K); +dvb_mux_class_X(dvbt, + ofdm, + guard_interval, + guard, + guard, + DVB_GUARD_INTERVAL_AUTO, + DVB_GUARD_INTERVAL_1_32, + DVB_GUARD_INTERVAL_1_16, + DVB_GUARD_INTERVAL_1_8, + DVB_GUARD_INTERVAL_1_4, + DVB_GUARD_INTERVAL_1_128, + DVB_GUARD_INTERVAL_19_128, + DVB_GUARD_INTERVAL_19_256); +dvb_mux_class_X(dvbt, + ofdm, + hierarchy_information, + hier, + hier, + DVB_HIERARCHY_AUTO, + DVB_HIERARCHY_NONE, + DVB_HIERARCHY_1, + DVB_HIERARCHY_2, + DVB_HIERARCHY_4); +dvb_mux_class_X(dvbt, + ofdm, + code_rate_HP, + fechi, + fechi, + DVB_FEC_AUTO, + DVB_FEC_1_2, + DVB_FEC_2_3, + DVB_FEC_3_4, + DVB_FEC_3_5, + DVB_FEC_4_5, + DVB_FEC_5_6, + DVB_FEC_7_8); +dvb_mux_class_X(dvbt, + ofdm, + code_rate_LP, + feclo, + feclo, + DVB_FEC_AUTO, + DVB_FEC_1_2, + DVB_FEC_2_3, + DVB_FEC_3_4, + DVB_FEC_3_5, + DVB_FEC_4_5, + DVB_FEC_5_6, + DVB_FEC_7_8); #define dvb_mux_dvbt_class_delsys_get dvb_mux_class_delsys_get #define dvb_mux_dvbt_class_delsys_set dvb_mux_class_delsys_set -static htsmsg_t * -dvb_mux_dvbt_class_delsys_enum (void *o, const char *lang) -{ - htsmsg_t *list = htsmsg_create_list(); +static htsmsg_t* dvb_mux_dvbt_class_delsys_enum(void* o, const char* lang) { + htsmsg_t* list = htsmsg_create_list(); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBT)); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBT2)); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_TURBO)); return list; } -static int -dvb_mux_dvbt_class_frequency_set ( void *o, const void *v ) -{ - dvb_mux_t *lm = o; - uint32_t val = *(uint32_t *)v; +static int dvb_mux_dvbt_class_frequency_set(void* o, const void* v) { + dvb_mux_t* lm = o; + uint32_t val = *(uint32_t*)v; if (val < 1000) val *= 1000000; @@ -201,194 +225,247 @@ dvb_mux_dvbt_class_frequency_set ( void *o, const void *v ) return 0; } -const idclass_t dvb_mux_dvbt_class = -{ - .ic_super = &dvb_mux_class, - .ic_class = "dvb_mux_dvbt", - .ic_caption = N_("DVB-T multiplex"), - .ic_properties = (const property_t[]){ - { - MUX_PROP_STR("delsys", N_("Delivery system"), dvbt, delsys, "DVBT"), - .desc = N_("The delivery system the mux uses. " - "Make sure that your tuner supports the delivery " - "system selected here."), - }, - { - .type = PT_U32, - .id = "frequency", - .name = N_("Frequency (Hz)"), - .desc = N_("The frequency of the mux (in Hertz)."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), - .set = dvb_mux_dvbt_class_frequency_set, - }, - { - MUX_PROP_STR("bandwidth", N_("Bandwidth"), dvbt, bw, N_("AUTO")), - .desc = N_("The bandwidth the mux uses. " - "If you're not sure of the value leave as AUTO " - "but be aware that tuning may fail as some drivers " - "do not like the AUTO setting."), - }, - { - MUX_PROP_STR("constellation", N_("Constellation"), dvbt, qam, N_("AUTO")), - .desc = N_("The COFDM modulation used by the mux. " - "If you're not sure of the value leave as AUTO."), - }, - { - MUX_PROP_STR("transmission_mode", N_("Transmission mode"), dvbt, mode, N_("AUTO")), - .desc = N_("The transmission/OFDM mode used by the mux. " - "If you're not sure of the value leave as AUTO " - "but be aware that tuning may fail as some drivers " - "do not like the AUTO setting."), - }, - { - MUX_PROP_STR("guard_interval", N_("Guard interval"), dvbt, guard, N_("AUTO")), - .desc = N_("The guard interval used by the mux. " - "If you're not sure of the value leave as AUTO."), - }, - { - MUX_PROP_STR("hierarchy", N_("Hierarchy"), dvbt, hier, N_("AUTO")), - .desc = N_("The hierarchical modulation used by the mux. " - "Most people will not need to change this setting."), - }, - { - MUX_PROP_STR("fec_hi", N_("FEC high"), dvbt, fechi, N_("AUTO")), - .desc = N_("The forward error correction high value. " - "Most people will not need to change this setting."), - }, - { - MUX_PROP_STR("fec_lo", N_("FEC low"), dvbt, feclo, N_("AUTO")), - .desc = N_("The forward error correction low value. " - "Most people will not need to change this setting."), - }, - { - .type = PT_INT, - .id = "plp_id", - .name = N_("PLP ID"), - .desc = N_("The physical layer pipe ID. " - "Most people will not need to change this setting."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), - .def.i = DVB_NO_STREAM_ID_FILTER, - }, - {} - } -}; +const idclass_t dvb_mux_dvbt_class = {.ic_super = &dvb_mux_class, + .ic_class = "dvb_mux_dvbt", + .ic_caption = N_("DVB-T multiplex"), + .ic_properties = (const property_t[]){ + { + MUX_PROP_STR("delsys", N_("Delivery system"), dvbt, delsys, "DVBT"), + .desc = N_("The delivery system the mux uses. " + "Make sure that your tuner supports the delivery " + "system selected here."), + }, + { + .type = PT_U32, + .id = "frequency", + .name = N_("Frequency (Hz)"), + .desc = N_("The frequency of the mux (in Hertz)."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), + .set = dvb_mux_dvbt_class_frequency_set, + }, + { + MUX_PROP_STR("bandwidth", N_("Bandwidth"), dvbt, bw, N_("AUTO")), + .desc = N_("The bandwidth the mux uses. " + "If you're not sure of the value leave as AUTO " + "but be aware that tuning may fail as some drivers " + "do not like the AUTO setting."), + }, + { + MUX_PROP_STR("constellation", N_("Constellation"), dvbt, qam, N_("AUTO")), + .desc = N_("The COFDM modulation used by the mux. " + "If you're not sure of the value leave as AUTO."), + }, + { + MUX_PROP_STR("transmission_mode", N_("Transmission mode"), dvbt, mode, N_("AUTO")), + .desc = N_("The transmission/OFDM mode used by the mux. " + "If you're not sure of the value leave as AUTO " + "but be aware that tuning may fail as some drivers " + "do not like the AUTO setting."), + }, + { + MUX_PROP_STR("guard_interval", N_("Guard interval"), dvbt, guard, N_("AUTO")), + .desc = N_("The guard interval used by the mux. " + "If you're not sure of the value leave as AUTO."), + }, + { + MUX_PROP_STR("hierarchy", N_("Hierarchy"), dvbt, hier, N_("AUTO")), + .desc = N_("The hierarchical modulation used by the mux. " + "Most people will not need to change this setting."), + }, + { + MUX_PROP_STR("fec_hi", N_("FEC high"), dvbt, fechi, N_("AUTO")), + .desc = N_("The forward error correction high value. " + "Most people will not need to change this setting."), + }, + { + MUX_PROP_STR("fec_lo", N_("FEC low"), dvbt, feclo, N_("AUTO")), + .desc = N_("The forward error correction low value. " + "Most people will not need to change this setting."), + }, + { + .type = PT_INT, + .id = "plp_id", + .name = N_("PLP ID"), + .desc = N_("The physical layer pipe ID. " + "Most people will not need to change this setting."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), + .def.i = DVB_NO_STREAM_ID_FILTER, + }, + {}}}; /* * DVB-C */ -dvb_mux_class_R(dvbc, modulation, qam, qam, - DVB_MOD_QAM_AUTO, DVB_MOD_QAM_16, DVB_MOD_QAM_32, - DVB_MOD_QAM_64, DVB_MOD_QAM_128, DVB_MOD_QAM_256); -dvb_mux_class_X(dvbc, qam, fec_inner, fec, fec, - DVB_FEC_AUTO, DVB_FEC_NONE, - DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, DVB_FEC_4_5, - DVB_FEC_5_6, DVB_FEC_8_9, DVB_FEC_9_10); +dvb_mux_class_R(dvbc, + modulation, + qam, + qam, + DVB_MOD_QAM_AUTO, + DVB_MOD_QAM_16, + DVB_MOD_QAM_32, + DVB_MOD_QAM_64, + DVB_MOD_QAM_128, + DVB_MOD_QAM_256); +dvb_mux_class_X(dvbc, + qam, + fec_inner, + fec, + fec, + DVB_FEC_AUTO, + DVB_FEC_NONE, + DVB_FEC_1_2, + DVB_FEC_2_3, + DVB_FEC_3_4, + DVB_FEC_4_5, + DVB_FEC_5_6, + DVB_FEC_8_9, + DVB_FEC_9_10); #define dvb_mux_dvbc_class_delsys_get dvb_mux_class_delsys_get #define dvb_mux_dvbc_class_delsys_set dvb_mux_class_delsys_set -static htsmsg_t * -dvb_mux_dvbc_class_delsys_enum (void *o, const char *lang) -{ - htsmsg_t *list = htsmsg_create_list(); +static htsmsg_t* dvb_mux_dvbc_class_delsys_enum(void* o, const char* lang) { + htsmsg_t* list = htsmsg_create_list(); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBC_ANNEX_A)); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBC_ANNEX_B)); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBC_ANNEX_C)); return list; } -const idclass_t dvb_mux_dvbc_class = -{ - .ic_super = &dvb_mux_class, - .ic_class = "dvb_mux_dvbc", - .ic_caption = N_("DVB-C multiplex"), - .ic_properties = (const property_t[]){ - { - MUX_PROP_STR("delsys", N_("Delivery system"), dvbc, delsys, "DVB-C"), - .desc = N_("The delivery system used by your cable provider."), - }, - { - .type = PT_U32, - .id = "frequency", - .name = N_("Frequency (Hz)"), - .desc = N_("The frequency of the mux (in Hertz)."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), - .set = dvb_mux_dvbt_class_frequency_set, - }, - { - .type = PT_U32, - .id = "symbolrate", - .name = N_("Symbol rate (Sym/s)"), - .desc = N_("The symbol rate used on the mux."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_qam.symbol_rate), - }, - { - MUX_PROP_STR("constellation", N_("Constellation"), dvbc, qam, N_("AUTO")), - .desc = N_("The quadrature amplitude modulation (QAM) used by the mux. " - "If you're not sure of the value leave as AUTO."), - }, - { - MUX_PROP_STR("fec", N_("FEC"), dvbc, fec, N_("AUTO")), - .desc = N_("The forward error correction used on the mux."), - }, - { - .type = PT_INT, - .id = "plp_id", - .name = N_("PLP ID"), - .desc = N_("The physical layer pipe ID. " - "Most people will not need to change this setting."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), - .def.i = DVB_NO_STREAM_ID_FILTER, - }, - { - .type = PT_U32, - .id = "data_slice", - .name = N_("Data slice"), - .desc = N_("Data slice code."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_data_slice), - .def.u32 = 0, - .opts = PO_EXPERT - }, - {} - } -}; +const idclass_t dvb_mux_dvbc_class = {.ic_super = &dvb_mux_class, + .ic_class = "dvb_mux_dvbc", + .ic_caption = N_("DVB-C multiplex"), + .ic_properties = (const property_t[]){ + { + MUX_PROP_STR("delsys", N_("Delivery system"), dvbc, delsys, "DVB-C"), + .desc = N_("The delivery system used by your cable provider."), + }, + { + .type = PT_U32, + .id = "frequency", + .name = N_("Frequency (Hz)"), + .desc = N_("The frequency of the mux (in Hertz)."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), + .set = dvb_mux_dvbt_class_frequency_set, + }, + { + .type = PT_U32, + .id = "symbolrate", + .name = N_("Symbol rate (Sym/s)"), + .desc = N_("The symbol rate used on the mux."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_qam.symbol_rate), + }, + { + MUX_PROP_STR("constellation", N_("Constellation"), dvbc, qam, N_("AUTO")), + .desc = N_("The quadrature amplitude modulation (QAM) used by the mux. " + "If you're not sure of the value leave as AUTO."), + }, + { + MUX_PROP_STR("fec", N_("FEC"), dvbc, fec, N_("AUTO")), + .desc = N_("The forward error correction used on the mux."), + }, + { + .type = PT_INT, + .id = "plp_id", + .name = N_("PLP ID"), + .desc = N_("The physical layer pipe ID. " + "Most people will not need to change this setting."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), + .def.i = DVB_NO_STREAM_ID_FILTER, + }, + {.type = PT_U32, + .id = "data_slice", + .name = N_("Data slice"), + .desc = N_("Data slice code."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_data_slice), + .def.u32 = 0, + .opts = PO_EXPERT}, + {}}}; /* * DVB-S */ -dvb_mux_class_X(dvbs, qpsk, fec_inner, fec, fec, - DVB_FEC_AUTO, DVB_FEC_NONE, - DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, DVB_FEC_3_5, - DVB_FEC_4_5, DVB_FEC_5_6, DVB_FEC_7_8, DVB_FEC_8_9, - DVB_FEC_9_10, DVB_FEC_1_3, DVB_FEC_1_4, DVB_FEC_4_15, - DVB_FEC_5_9, DVB_FEC_7_9, DVB_FEC_7_15, DVB_FEC_8_15, - DVB_FEC_9_20, DVB_FEC_11_15, DVB_FEC_11_20, DVB_FEC_11_45, - DVB_FEC_13_18, DVB_FEC_13_45, DVB_FEC_14_45, DVB_FEC_23_36, - DVB_FEC_25_36, DVB_FEC_26_45, DVB_FEC_28_45, DVB_FEC_32_45, - DVB_FEC_77_90); -dvb_mux_class_R(dvbs, modulation, qam, qam, - DVB_MOD_AUTO, DVB_MOD_QPSK, DVB_MOD_QAM_16, DVB_MOD_QAM_1024, - DVB_MOD_QAM_4096, DVB_MOD_PSK_8, DVB_MOD_APSK_16, DVB_MOD_APSK_32, - DVB_MOD_APSK_64, DVB_MOD_APSK_8_L, DVB_MOD_APSK_16_L, - DVB_MOD_APSK_32_L, DVB_MOD_APSK_64_L); -dvb_mux_class_R(dvbs, rolloff, rolloff, rolloff, - DVB_HIERARCHY_AUTO, DVB_ROLLOFF_5, DVB_ROLLOFF_10, DVB_ROLLOFF_15, - DVB_ROLLOFF_20, DVB_ROLLOFF_25, DVB_ROLLOFF_35); -dvb_mux_class_R(dvbs, pilot, pilot, pilot, - DVB_PILOT_AUTO, DVB_PILOT_ON, DVB_PILOT_OFF); -dvb_mux_class_X(dvbs, qpsk, polarisation, polarisation, pol, - DVB_POLARISATION_VERTICAL, DVB_POLARISATION_HORIZONTAL, - DVB_POLARISATION_CIRCULAR_LEFT, DVB_POLARISATION_CIRCULAR_RIGHT); -dvb_mux_class_R(dvbs, pls_mode, pls_mode, plsmode, - DVB_PLS_ROOT, DVB_PLS_GOLD, DVB_PLS_COMBO); - -static int -dvb_mux_dvbs_class_frequency_set ( void *o, const void *v ) -{ - dvb_mux_t *lm = o; - uint32_t val = *(uint32_t *)v; +dvb_mux_class_X(dvbs, + qpsk, + fec_inner, + fec, + fec, + DVB_FEC_AUTO, + DVB_FEC_NONE, + DVB_FEC_1_2, + DVB_FEC_2_3, + DVB_FEC_3_4, + DVB_FEC_3_5, + DVB_FEC_4_5, + DVB_FEC_5_6, + DVB_FEC_7_8, + DVB_FEC_8_9, + DVB_FEC_9_10, + DVB_FEC_1_3, + DVB_FEC_1_4, + DVB_FEC_4_15, + DVB_FEC_5_9, + DVB_FEC_7_9, + DVB_FEC_7_15, + DVB_FEC_8_15, + DVB_FEC_9_20, + DVB_FEC_11_15, + DVB_FEC_11_20, + DVB_FEC_11_45, + DVB_FEC_13_18, + DVB_FEC_13_45, + DVB_FEC_14_45, + DVB_FEC_23_36, + DVB_FEC_25_36, + DVB_FEC_26_45, + DVB_FEC_28_45, + DVB_FEC_32_45, + DVB_FEC_77_90); +dvb_mux_class_R(dvbs, + modulation, + qam, + qam, + DVB_MOD_AUTO, + DVB_MOD_QPSK, + DVB_MOD_QAM_16, + DVB_MOD_QAM_1024, + DVB_MOD_QAM_4096, + DVB_MOD_PSK_8, + DVB_MOD_APSK_16, + DVB_MOD_APSK_32, + DVB_MOD_APSK_64, + DVB_MOD_APSK_8_L, + DVB_MOD_APSK_16_L, + DVB_MOD_APSK_32_L, + DVB_MOD_APSK_64_L); +dvb_mux_class_R(dvbs, + rolloff, + rolloff, + rolloff, + DVB_HIERARCHY_AUTO, + DVB_ROLLOFF_5, + DVB_ROLLOFF_10, + DVB_ROLLOFF_15, + DVB_ROLLOFF_20, + DVB_ROLLOFF_25, + DVB_ROLLOFF_35); +dvb_mux_class_R(dvbs, pilot, pilot, pilot, DVB_PILOT_AUTO, DVB_PILOT_ON, DVB_PILOT_OFF); +dvb_mux_class_X(dvbs, + qpsk, + polarisation, + polarisation, + pol, + DVB_POLARISATION_VERTICAL, + DVB_POLARISATION_HORIZONTAL, + DVB_POLARISATION_CIRCULAR_LEFT, + DVB_POLARISATION_CIRCULAR_RIGHT); +dvb_mux_class_R(dvbs, pls_mode, pls_mode, plsmode, DVB_PLS_ROOT, DVB_PLS_GOLD, DVB_PLS_COMBO); + +static int dvb_mux_dvbs_class_frequency_set(void* o, const void* v) { + dvb_mux_t* lm = o; + uint32_t val = *(uint32_t*)v; if (val < 100000) val *= 1000; @@ -400,11 +477,9 @@ dvb_mux_dvbs_class_frequency_set ( void *o, const void *v ) return 0; } -static int -dvb_mux_dvbs_class_symbol_rate_set ( void *o, const void *v ) -{ - dvb_mux_t *lm = o; - uint32_t val = *(uint32_t *)v; +static int dvb_mux_dvbs_class_symbol_rate_set(void* o, const void* v) { + dvb_mux_t* lm = o; + uint32_t val = *(uint32_t*)v; if (val < 100000) val *= 1000; @@ -419,20 +494,16 @@ dvb_mux_dvbs_class_symbol_rate_set ( void *o, const void *v ) #define dvb_mux_dvbs_class_delsys_get dvb_mux_class_delsys_get #define dvb_mux_dvbs_class_delsys_set dvb_mux_class_delsys_set -static htsmsg_t * -dvb_mux_dvbs_class_delsys_enum (void *o, const char *lang) -{ - htsmsg_t *list = htsmsg_create_list(); +static htsmsg_t* dvb_mux_dvbs_class_delsys_enum(void* o, const char* lang) { + htsmsg_t* list = htsmsg_create_list(); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBS)); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBS2)); return list; } -static const void * -dvb_mux_dvbs_class_orbital_get ( void *o ) -{ +static const void* dvb_mux_dvbs_class_orbital_get(void* o) { static char buf[16], *s = buf; - dvb_mux_t *lm = o; + dvb_mux_t* lm = o; if (lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos == INT_MAX) buf[0] = '\0'; else @@ -440,13 +511,11 @@ dvb_mux_dvbs_class_orbital_get ( void *o ) return &s; } -static int -dvb_mux_dvbs_class_orbital_set ( void *o, const void *s ) -{ - dvb_mux_t *lm = o; - int pos; +static int dvb_mux_dvbs_class_orbital_set(void* o, const void* s) { + dvb_mux_t* lm = o; + int pos; - pos = dvb_sat_position_from_str((const char *)s); + pos = dvb_sat_position_from_str((const char*)s); if (pos != lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos) { lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos = pos; @@ -455,108 +524,94 @@ dvb_mux_dvbs_class_orbital_set ( void *o, const void *s ) return 0; } -const idclass_t dvb_mux_dvbs_class = -{ - .ic_super = &dvb_mux_class, - .ic_class = "dvb_mux_dvbs", - .ic_caption = N_("DVB-S multiplex"), - .ic_properties = (const property_t[]){ - { - MUX_PROP_STR("delsys", N_("Delivery system"), dvbs, delsys, "DVBS"), - .desc = N_("The delivery system used by your provider."), - }, - { - .type = PT_U32, - .id = "frequency", - .name = N_("Frequency (kHz)"), - .desc = N_("The frequency of the mux/transponder in Hertz."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), - .set = dvb_mux_dvbs_class_frequency_set, - }, - { - .type = PT_U32, - .id = "symbolrate", - .name = N_("Symbol rate (Sym/s)"), - .desc = N_("The symbol rate used on the mux/transponder."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_qpsk.symbol_rate), - .set = dvb_mux_dvbs_class_symbol_rate_set, - }, - { - MUX_PROP_STR("polarisation", N_("Polarization"), dvbs, polarisation, NULL), - .desc = N_("The polarization used on the mux."), - }, - { - MUX_PROP_STR("modulation", N_("Modulation"), dvbs, qam, NULL), - .desc = N_("The modulation used on the mux."), - }, - { - MUX_PROP_STR("fec", N_("FEC"), dvbs, fec, "AUTO"), - .desc = N_("The forward error correction. " - "Most people will not need to change this setting."), - }, - { - MUX_PROP_STR("rolloff", N_("Rolloff"), dvbs, rolloff, "AUTO"), - .desc = N_("The rolloff used on the mux."), - .opts = PO_ADVANCED, - }, - { - MUX_PROP_STR("pilot", N_("Pilot"), dvbs, pilot, "AUTO"), - .desc = N_("Enable/disable pilot tone."), - .opts = PO_ADVANCED, - }, - { - .type = PT_INT, - .id = "stream_id", - .name = N_("ISI (Stream ID)"), - .desc = N_("The stream ID used for the mux."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), - .def.i = DVB_NO_STREAM_ID_FILTER, - .opts = PO_EXPERT - }, - { - MUX_PROP_STR("pls_mode", N_("PLS mode"), dvbs, pls_mode, "ROOT"), - .desc = N_("The Physical Layer Scrambling (PLS) mode " - "used on the mux."), - .opts = PO_EXPERT, - }, - { - .type = PT_U32, - .id = "pls_code", - .name = N_("PLS code"), - .desc = N_("The Physical Layer Scrambling (PLS) code " - "used on the mux."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_pls_code), - .def.u32 = 1, - .opts = PO_EXPERT - }, - { - .type = PT_STR, - .id = "orbital", - .name = N_("Orbital position"), - .desc = N_("The orbital position of the satellite the mux is on."), - .set = dvb_mux_dvbs_class_orbital_set, - .get = dvb_mux_dvbs_class_orbital_get, - .opts = PO_ADVANCED | PO_RDONLY - }, - { - .type = PT_U32, - .id = "dvb_satip_dvbc_freq", - .name = N_("SAT>IP DVB-C frequency (Hz)"), - .off = offsetof(dvb_mux_t, mm_dvb_satip_dvbc_freq), - .desc = N_("For example: 312000000. This frequency is 312Mhz."), - .opts = PO_ADVANCED - }, - { - .type = PT_U32, - .id = "dvb_satip_dvbt_freq", - .name = N_("SAT>IP DVB-T frequency (Hz)"), - .off = offsetof(dvb_mux_t, mm_dvb_satip_dvbt_freq), - .desc = N_("For example: 312000000. This frequency is 312Mhz."), - .opts = PO_ADVANCED - }, - {} - } -}; +const idclass_t dvb_mux_dvbs_class = {.ic_super = &dvb_mux_class, + .ic_class = "dvb_mux_dvbs", + .ic_caption = N_("DVB-S multiplex"), + .ic_properties = (const property_t[]){ + { + MUX_PROP_STR("delsys", N_("Delivery system"), dvbs, delsys, "DVBS"), + .desc = N_("The delivery system used by your provider."), + }, + { + .type = PT_U32, + .id = "frequency", + .name = N_("Frequency (kHz)"), + .desc = N_("The frequency of the mux/transponder in Hertz."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), + .set = dvb_mux_dvbs_class_frequency_set, + }, + { + .type = PT_U32, + .id = "symbolrate", + .name = N_("Symbol rate (Sym/s)"), + .desc = N_("The symbol rate used on the mux/transponder."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_qpsk.symbol_rate), + .set = dvb_mux_dvbs_class_symbol_rate_set, + }, + { + MUX_PROP_STR("polarisation", N_("Polarization"), dvbs, polarisation, NULL), + .desc = N_("The polarization used on the mux."), + }, + { + MUX_PROP_STR("modulation", N_("Modulation"), dvbs, qam, NULL), + .desc = N_("The modulation used on the mux."), + }, + { + MUX_PROP_STR("fec", N_("FEC"), dvbs, fec, "AUTO"), + .desc = N_("The forward error correction. " + "Most people will not need to change this setting."), + }, + { + MUX_PROP_STR("rolloff", N_("Rolloff"), dvbs, rolloff, "AUTO"), + .desc = N_("The rolloff used on the mux."), + .opts = PO_ADVANCED, + }, + { + MUX_PROP_STR("pilot", N_("Pilot"), dvbs, pilot, "AUTO"), + .desc = N_("Enable/disable pilot tone."), + .opts = PO_ADVANCED, + }, + {.type = PT_INT, + .id = "stream_id", + .name = N_("ISI (Stream ID)"), + .desc = N_("The stream ID used for the mux."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), + .def.i = DVB_NO_STREAM_ID_FILTER, + .opts = PO_EXPERT}, + { + MUX_PROP_STR("pls_mode", N_("PLS mode"), dvbs, pls_mode, "ROOT"), + .desc = N_("The Physical Layer Scrambling (PLS) mode " + "used on the mux."), + .opts = PO_EXPERT, + }, + {.type = PT_U32, + .id = "pls_code", + .name = N_("PLS code"), + .desc = N_("The Physical Layer Scrambling (PLS) code " + "used on the mux."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_pls_code), + .def.u32 = 1, + .opts = PO_EXPERT}, + {.type = PT_STR, + .id = "orbital", + .name = N_("Orbital position"), + .desc = N_("The orbital position of the satellite the mux is on."), + .set = dvb_mux_dvbs_class_orbital_set, + .get = dvb_mux_dvbs_class_orbital_get, + .opts = PO_ADVANCED | PO_RDONLY}, + {.type = PT_U32, + .id = "dvb_satip_dvbc_freq", + .name = N_("SAT>IP DVB-C frequency (Hz)"), + .off = offsetof(dvb_mux_t, mm_dvb_satip_dvbc_freq), + .desc = N_("For example: 312000000. This frequency is 312Mhz."), + .opts = PO_ADVANCED}, + {.type = PT_U32, + .id = "dvb_satip_dvbt_freq", + .name = N_("SAT>IP DVB-T frequency (Hz)"), + .off = offsetof(dvb_mux_t, mm_dvb_satip_dvbt_freq), + .desc = N_("For example: 312000000. This frequency is 312Mhz."), + .opts = PO_ADVANCED}, + {}}}; /* * ATSC-T @@ -565,43 +620,36 @@ const idclass_t dvb_mux_dvbs_class = #define dvb_mux_atsc_t_class_delsys_get dvb_mux_class_delsys_get #define dvb_mux_atsc_t_class_delsys_set dvb_mux_class_delsys_set -static htsmsg_t * -dvb_mux_atsc_t_class_delsys_enum (void *o, const char *lang) -{ - htsmsg_t *list = htsmsg_create_list(); +static htsmsg_t* dvb_mux_atsc_t_class_delsys_enum(void* o, const char* lang) { + htsmsg_t* list = htsmsg_create_list(); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_ATSC)); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_ATSCMH)); return list; } -dvb_mux_class_R(atsc_t, modulation, qam, qam, - DVB_MOD_QAM_AUTO, DVB_MOD_QAM_256, DVB_MOD_VSB_8); - -const idclass_t dvb_mux_atsc_t_class = -{ - .ic_super = &dvb_mux_class, - .ic_class = "dvb_mux_atsc_t", - .ic_caption = N_("ATSC-T multiplex"), - .ic_properties = (const property_t[]){ - { - MUX_PROP_STR("delsys", N_("Delivery system"), atsc_t, delsys, "ATSC-T"), - .desc = N_("The delivery system used by your provider."), - }, - { - .type = PT_U32, - .id = "frequency", - .name = N_("Frequency (Hz)"), - .desc = N_("The frequency of the mux (in Hertz)."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), - .set = dvb_mux_dvbt_class_frequency_set, - }, - { - MUX_PROP_STR("modulation", N_("Modulation"), atsc_t, qam, N_("AUTO")), - .desc = N_("The modulation used on the mux."), - }, - {} - } -}; +dvb_mux_class_R(atsc_t, modulation, qam, qam, DVB_MOD_QAM_AUTO, DVB_MOD_QAM_256, DVB_MOD_VSB_8); + +const idclass_t dvb_mux_atsc_t_class = {.ic_super = &dvb_mux_class, + .ic_class = "dvb_mux_atsc_t", + .ic_caption = N_("ATSC-T multiplex"), + .ic_properties = (const property_t[]){ + { + MUX_PROP_STR("delsys", N_("Delivery system"), atsc_t, delsys, "ATSC-T"), + .desc = N_("The delivery system used by your provider."), + }, + { + .type = PT_U32, + .id = "frequency", + .name = N_("Frequency (Hz)"), + .desc = N_("The frequency of the mux (in Hertz)."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), + .set = dvb_mux_dvbt_class_frequency_set, + }, + { + MUX_PROP_STR("modulation", N_("Modulation"), atsc_t, qam, N_("AUTO")), + .desc = N_("The modulation used on the mux."), + }, + {}}}; /* * ATSC-C @@ -610,87 +658,77 @@ const idclass_t dvb_mux_atsc_t_class = #define dvb_mux_atsc_c_class_delsys_get dvb_mux_class_delsys_get #define dvb_mux_atsc_c_class_delsys_set dvb_mux_class_delsys_set -static htsmsg_t * -dvb_mux_atsc_c_class_delsys_enum (void *o, const char *lang) -{ - htsmsg_t *list = htsmsg_create_list(); +static htsmsg_t* dvb_mux_atsc_c_class_delsys_enum(void* o, const char* lang) { + htsmsg_t* list = htsmsg_create_list(); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DVBC_ANNEX_B)); return list; } -const idclass_t dvb_mux_atsc_c_class = -{ - .ic_super = &dvb_mux_class, - .ic_class = "dvb_mux_atsc_c", - .ic_caption = N_("ATSC-C multiplex"), - .ic_properties = (const property_t[]){ - { - MUX_PROP_STR("delsys", N_("Delivery system"), atsc_c, delsys, "ATSC-C"), - .desc = N_("The delivery system used by your provider."), - }, - { - .type = PT_U32, - .id = "frequency", - .name = N_("Frequency (Hz)"), - .desc = N_("The frequency of the mux (in Hertz)."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), - .set = dvb_mux_dvbt_class_frequency_set, - }, - { - .type = PT_U32, - .id = "symbolrate", - .name = N_("Symbol rate (Sym/s)"), - .desc = N_("The symbol rate."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_qam.symbol_rate), - }, - { - MUX_PROP_STR("constellation", N_("Constellation"), dvbc, qam, N_("AUTO")), - .desc = N_("The quadrature amplitude modulation (QAM) used by the mux. " - "If you're not sure of the value leave as AUTO."), - }, - { - MUX_PROP_STR("fec", N_("FEC"), dvbc, fec, N_("AUTO")), - .desc = N_("The forward error correction used on the mux."), - }, - {} - } -}; +const idclass_t dvb_mux_atsc_c_class = {.ic_super = &dvb_mux_class, + .ic_class = "dvb_mux_atsc_c", + .ic_caption = N_("ATSC-C multiplex"), + .ic_properties = (const property_t[]){ + { + MUX_PROP_STR("delsys", N_("Delivery system"), atsc_c, delsys, "ATSC-C"), + .desc = N_("The delivery system used by your provider."), + }, + { + .type = PT_U32, + .id = "frequency", + .name = N_("Frequency (Hz)"), + .desc = N_("The frequency of the mux (in Hertz)."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), + .set = dvb_mux_dvbt_class_frequency_set, + }, + { + .type = PT_U32, + .id = "symbolrate", + .name = N_("Symbol rate (Sym/s)"), + .desc = N_("The symbol rate."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_qam.symbol_rate), + }, + { + MUX_PROP_STR("constellation", N_("Constellation"), dvbc, qam, N_("AUTO")), + .desc = N_("The quadrature amplitude modulation (QAM) used by the mux. " + "If you're not sure of the value leave as AUTO."), + }, + { + MUX_PROP_STR("fec", N_("FEC"), dvbc, fec, N_("AUTO")), + .desc = N_("The forward error correction used on the mux."), + }, + {}}}; /* * CableCARD */ -const idclass_t dvb_mux_cablecard_class = -{ - .ic_super = &dvb_mux_class, - .ic_class = "dvb_mux_cablecard", - .ic_caption = N_("CableCARD multiplex"), - .ic_properties = (const property_t[]){ - { - .type = PT_U32, - .id = "vchan", - .name = N_("Channel"), - .desc = N_("The channel on the cable provider's network."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_cablecard.vchannel), - }, - { - .type = PT_U32, - .id = "frequency", - .name = N_("Frequency (Hz)"), - .desc = N_("The frequency of the mux (in Hertz)."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), - .opts = PO_RDONLY, - }, - { - .type = PT_STR, - .id = "vchan_name", - .name = N_("Callsign"), - .desc = N_("The channel's name or callsign as set by the cable provider."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_cablecard.name), - .opts = PO_RDONLY, - }, - {} - } -}; +const idclass_t dvb_mux_cablecard_class = {.ic_super = &dvb_mux_class, + .ic_class = "dvb_mux_cablecard", + .ic_caption = N_("CableCARD multiplex"), + .ic_properties = + (const property_t[]){{ + .type = PT_U32, + .id = "vchan", + .name = N_("Channel"), + .desc = N_("The channel on the cable provider's network."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_cablecard.vchannel), + }, + { + .type = PT_U32, + .id = "frequency", + .name = N_("Frequency (Hz)"), + .desc = N_("The frequency of the mux (in Hertz)."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), + .opts = PO_RDONLY, + }, + { + .type = PT_STR, + .id = "vchan_name", + .name = N_("Callsign"), + .desc = N_("The channel's name or callsign as set by the cable provider."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_cablecard.name), + .opts = PO_RDONLY, + }, + {}}}; /* * ISDB-T @@ -699,208 +737,274 @@ const idclass_t dvb_mux_cablecard_class = #define dvb_mux_isdb_t_class_delsys_get dvb_mux_class_delsys_get #define dvb_mux_isdb_t_class_delsys_set dvb_mux_class_delsys_set -static htsmsg_t * -dvb_mux_isdb_t_class_delsys_enum (void *o, const char *lang) -{ - htsmsg_t *list = htsmsg_create_list(); +static htsmsg_t* dvb_mux_isdb_t_class_delsys_enum(void* o, const char* lang) { + htsmsg_t* list = htsmsg_create_list(); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_ISDBT)); return list; } -dvb_mux_class_X(isdb_t, isdbt, bandwidth, bw, bw, - DVB_BANDWIDTH_AUTO, DVB_BANDWIDTH_10_MHZ, - DVB_BANDWIDTH_8_MHZ, DVB_BANDWIDTH_7_MHZ, - DVB_BANDWIDTH_6_MHZ, DVB_BANDWIDTH_5_MHZ, - DVB_BANDWIDTH_1_712_MHZ); -dvb_mux_class_X(isdb_t, isdbt, guard_interval, guard, guard, - DVB_GUARD_INTERVAL_AUTO, DVB_GUARD_INTERVAL_1_32, - DVB_GUARD_INTERVAL_1_16, DVB_GUARD_INTERVAL_1_8, - DVB_GUARD_INTERVAL_1_4, DVB_GUARD_INTERVAL_1_128, - DVB_GUARD_INTERVAL_19_128, DVB_GUARD_INTERVAL_19_256); -dvb_mux_class_X(isdb_t, isdbt, layers[0].modulation, isdbt_mod_a, qam, - DVB_MOD_QAM_AUTO, DVB_MOD_QPSK, DVB_MOD_QAM_16, - DVB_MOD_QAM_64, DVB_MOD_QAM_256); -dvb_mux_class_X(isdb_t, isdbt, layers[0].fec, isdbt_fec_a, fec, - DVB_FEC_AUTO, DVB_FEC_NONE, - DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, DVB_FEC_4_5, - DVB_FEC_5_6, DVB_FEC_8_9, DVB_FEC_9_10); -dvb_mux_class_X(isdb_t, isdbt, layers[1].modulation, isdbt_mod_b, qam, - DVB_MOD_QAM_AUTO, DVB_MOD_QPSK, DVB_MOD_QAM_16, - DVB_MOD_QAM_64, DVB_MOD_QAM_256); -dvb_mux_class_X(isdb_t, isdbt, layers[1].fec, isdbt_fec_b, fec, - DVB_FEC_AUTO, DVB_FEC_NONE, - DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, DVB_FEC_4_5, - DVB_FEC_5_6, DVB_FEC_8_9, DVB_FEC_9_10); -dvb_mux_class_X(isdb_t, isdbt, layers[2].modulation, isdbt_mod_c, qam, - DVB_MOD_QAM_AUTO, DVB_MOD_QPSK, DVB_MOD_QAM_16, - DVB_MOD_QAM_64, DVB_MOD_QAM_256); -dvb_mux_class_X(isdb_t, isdbt, layers[2].fec, isdbt_fec_c, fec, - DVB_FEC_AUTO, DVB_FEC_NONE, - DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, DVB_FEC_4_5, - DVB_FEC_5_6, DVB_FEC_8_9, DVB_FEC_9_10); - -const idclass_t dvb_mux_isdb_t_class = -{ - .ic_super = &dvb_mux_class, - .ic_class = "dvb_mux_isdbt", - .ic_caption = N_("ISDB-T multiplex"), - .ic_properties = (const property_t[]){ - { - MUX_PROP_STR("delsys", N_("Delivery system"), isdb_t, delsys, "ISDB-T"), - .desc = N_("The delivery system used by your provider."), - }, - { - .type = PT_U32, - .id = "frequency", - .name = N_("Frequency (Hz)"), - .desc = N_("The frequency of the mux (in Hertz)."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), - .set = dvb_mux_dvbt_class_frequency_set, - }, - { - MUX_PROP_STR("bandwidth", N_("Bandwidth"), isdb_t, bw, N_("AUTO")), - .desc = N_("The bandwidth the mux uses. " - "If you're not sure of the value leave as AUTO " - "but be aware that tuning may fail as some drivers " - "do not like the AUTO setting."), - }, - { - MUX_PROP_STR("guard_interval", N_("Guard interval"), isdb_t, guard, N_("AUTO")), - .desc = N_("The guard interval used by the mux. " - "If you're not sure of the value leave as AUTO."), - }, - /* Layer A */ - { - MUX_PROP_STR("layera_fec", N_("Layer A: FEC"), isdb_t, isdbt_fec_a, N_("AUTO")), - .desc = N_("The layer A forward error correction."), - }, - { - MUX_PROP_STR("layera_mod", N_("Layer A: Constellation"), isdb_t, isdbt_mod_a, N_("AUTO")), - .desc = N_("The layer A constellation."), - }, - { - .type = PT_U32, - .id = "layera_segcnt", - .name = N_("Layer A: Segment count"), - .desc = N_("The layer A segment count."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[0].segment_count), - }, - { - .type = PT_U32, - .id = "layera_timint", - .name = N_("Layer A: Time interleaving"), - .desc = N_("The layer A time interleaving."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[0].time_interleaving), - }, - /* Layer B */ - { - MUX_PROP_STR("layerb_fec", N_("Layer B: FEC"), isdb_t, isdbt_fec_b, N_("AUTO")), - .desc = N_("The layer B forward error correction."), - }, - { - MUX_PROP_STR("layerb_mod", N_("Layer B: Constellation"), isdb_t, isdbt_mod_b, N_("AUTO")), - .desc = N_("The layer B constellation."), - }, - { - .type = PT_U32, - .id = "layerb_segcnt", - .name = N_("Layer B: Segment count"), - .desc = N_("The layer B segment count."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[1].segment_count), - }, - { - .type = PT_U32, - .id = "layerb_timint", - .name = N_("Layer B: Time interleaving"), - .desc = N_("The layer B time interleaving."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[1].time_interleaving), - }, - /* Layer C */ - { - MUX_PROP_STR("layerc_fec", N_("Layer C: FEC"), isdb_t, isdbt_fec_c, N_("AUTO")), - .desc = N_("The layer C forward error correction."), - }, - { - MUX_PROP_STR("layerc_mod", N_("Layer C: Constellation"), isdb_t, isdbt_mod_c, N_("AUTO")), - .desc = N_("The layer C constellation."), - }, - { - .type = PT_U32, - .id = "layerc_segcnt", - .name = N_("Layer C: Segment count"), - .desc = N_("The layer C segment count."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[2].segment_count), - }, - { - .type = PT_U32, - .id = "layerc_timint", - .name = N_("Layer C: Time interleaving"), - .desc = N_("The layer C time interleaving."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[2].time_interleaving), - }, - {} - } -}; +dvb_mux_class_X(isdb_t, + isdbt, + bandwidth, + bw, + bw, + DVB_BANDWIDTH_AUTO, + DVB_BANDWIDTH_10_MHZ, + DVB_BANDWIDTH_8_MHZ, + DVB_BANDWIDTH_7_MHZ, + DVB_BANDWIDTH_6_MHZ, + DVB_BANDWIDTH_5_MHZ, + DVB_BANDWIDTH_1_712_MHZ); +dvb_mux_class_X(isdb_t, + isdbt, + guard_interval, + guard, + guard, + DVB_GUARD_INTERVAL_AUTO, + DVB_GUARD_INTERVAL_1_32, + DVB_GUARD_INTERVAL_1_16, + DVB_GUARD_INTERVAL_1_8, + DVB_GUARD_INTERVAL_1_4, + DVB_GUARD_INTERVAL_1_128, + DVB_GUARD_INTERVAL_19_128, + DVB_GUARD_INTERVAL_19_256); +dvb_mux_class_X(isdb_t, + isdbt, + layers[0].modulation, + isdbt_mod_a, + qam, + DVB_MOD_QAM_AUTO, + DVB_MOD_QPSK, + DVB_MOD_QAM_16, + DVB_MOD_QAM_64, + DVB_MOD_QAM_256); +dvb_mux_class_X(isdb_t, + isdbt, + layers[0].fec, + isdbt_fec_a, + fec, + DVB_FEC_AUTO, + DVB_FEC_NONE, + DVB_FEC_1_2, + DVB_FEC_2_3, + DVB_FEC_3_4, + DVB_FEC_4_5, + DVB_FEC_5_6, + DVB_FEC_8_9, + DVB_FEC_9_10); +dvb_mux_class_X(isdb_t, + isdbt, + layers[1].modulation, + isdbt_mod_b, + qam, + DVB_MOD_QAM_AUTO, + DVB_MOD_QPSK, + DVB_MOD_QAM_16, + DVB_MOD_QAM_64, + DVB_MOD_QAM_256); +dvb_mux_class_X(isdb_t, + isdbt, + layers[1].fec, + isdbt_fec_b, + fec, + DVB_FEC_AUTO, + DVB_FEC_NONE, + DVB_FEC_1_2, + DVB_FEC_2_3, + DVB_FEC_3_4, + DVB_FEC_4_5, + DVB_FEC_5_6, + DVB_FEC_8_9, + DVB_FEC_9_10); +dvb_mux_class_X(isdb_t, + isdbt, + layers[2].modulation, + isdbt_mod_c, + qam, + DVB_MOD_QAM_AUTO, + DVB_MOD_QPSK, + DVB_MOD_QAM_16, + DVB_MOD_QAM_64, + DVB_MOD_QAM_256); +dvb_mux_class_X(isdb_t, + isdbt, + layers[2].fec, + isdbt_fec_c, + fec, + DVB_FEC_AUTO, + DVB_FEC_NONE, + DVB_FEC_1_2, + DVB_FEC_2_3, + DVB_FEC_3_4, + DVB_FEC_4_5, + DVB_FEC_5_6, + DVB_FEC_8_9, + DVB_FEC_9_10); + +const idclass_t dvb_mux_isdb_t_class = {.ic_super = &dvb_mux_class, + .ic_class = "dvb_mux_isdbt", + .ic_caption = N_("ISDB-T multiplex"), + .ic_properties = (const property_t[]){ + { + MUX_PROP_STR("delsys", N_("Delivery system"), isdb_t, delsys, "ISDB-T"), + .desc = N_("The delivery system used by your provider."), + }, + { + .type = PT_U32, + .id = "frequency", + .name = N_("Frequency (Hz)"), + .desc = N_("The frequency of the mux (in Hertz)."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), + .set = dvb_mux_dvbt_class_frequency_set, + }, + { + MUX_PROP_STR("bandwidth", N_("Bandwidth"), isdb_t, bw, N_("AUTO")), + .desc = N_("The bandwidth the mux uses. " + "If you're not sure of the value leave as AUTO " + "but be aware that tuning may fail as some drivers " + "do not like the AUTO setting."), + }, + { + MUX_PROP_STR("guard_interval", N_("Guard interval"), isdb_t, guard, N_("AUTO")), + .desc = N_("The guard interval used by the mux. " + "If you're not sure of the value leave as AUTO."), + }, + /* Layer A */ + { + MUX_PROP_STR("layera_fec", N_("Layer A: FEC"), isdb_t, isdbt_fec_a, N_("AUTO")), + .desc = N_("The layer A forward error correction."), + }, + { + MUX_PROP_STR("layera_mod", + N_("Layer A: Constellation"), + isdb_t, + isdbt_mod_a, + N_("AUTO")), + .desc = N_("The layer A constellation."), + }, + { + .type = PT_U32, + .id = "layera_segcnt", + .name = N_("Layer A: Segment count"), + .desc = N_("The layer A segment count."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[0].segment_count), + }, + { + .type = PT_U32, + .id = "layera_timint", + .name = N_("Layer A: Time interleaving"), + .desc = N_("The layer A time interleaving."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[0].time_interleaving), + }, + /* Layer B */ + { + MUX_PROP_STR("layerb_fec", N_("Layer B: FEC"), isdb_t, isdbt_fec_b, N_("AUTO")), + .desc = N_("The layer B forward error correction."), + }, + { + MUX_PROP_STR("layerb_mod", + N_("Layer B: Constellation"), + isdb_t, + isdbt_mod_b, + N_("AUTO")), + .desc = N_("The layer B constellation."), + }, + { + .type = PT_U32, + .id = "layerb_segcnt", + .name = N_("Layer B: Segment count"), + .desc = N_("The layer B segment count."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[1].segment_count), + }, + { + .type = PT_U32, + .id = "layerb_timint", + .name = N_("Layer B: Time interleaving"), + .desc = N_("The layer B time interleaving."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[1].time_interleaving), + }, + /* Layer C */ + { + MUX_PROP_STR("layerc_fec", N_("Layer C: FEC"), isdb_t, isdbt_fec_c, N_("AUTO")), + .desc = N_("The layer C forward error correction."), + }, + { + MUX_PROP_STR("layerc_mod", + N_("Layer C: Constellation"), + isdb_t, + isdbt_mod_c, + N_("AUTO")), + .desc = N_("The layer C constellation."), + }, + { + .type = PT_U32, + .id = "layerc_segcnt", + .name = N_("Layer C: Segment count"), + .desc = N_("The layer C segment count."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[2].segment_count), + }, + { + .type = PT_U32, + .id = "layerc_timint", + .name = N_("Layer C: Time interleaving"), + .desc = N_("The layer C time interleaving."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_isdbt.layers[2].time_interleaving), + }, + {}}}; /* * ISDB-C */ -const idclass_t dvb_mux_isdb_c_class = -{ - .ic_super = &dvb_mux_class, - .ic_class = "dvb_mux_isdbc", - .ic_caption = N_("ISDB-C multiplex"), - .ic_properties = (const property_t[]){ - { - MUX_PROP_STR("delsys", N_("Delivery system"), dvbc, delsys, "DVB-C"), - .desc = N_("The delivery system used by your cable provider."), - }, - { - .type = PT_U32, - .id = "frequency", - .name = N_("Frequency (Hz)"), - .desc = N_("The frequency of the mux (in Hertz)."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), - .set = dvb_mux_dvbt_class_frequency_set, - }, - { - .type = PT_U32, - .id = "symbolrate", - .name = N_("Symbol rate (Sym/s)"), - .desc = N_("The symbol rate."), - .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_qam.symbol_rate), - }, - { - MUX_PROP_STR("constellation", N_("Constellation"), dvbc, qam, N_("AUTO")), - .desc = N_("The quadrature amplitude modulation (QAM) used by the mux. " - "If you're not sure of the value leave as AUTO."), - }, - { - MUX_PROP_STR("fec", N_("FEC"), dvbc, fec, N_("AUTO")), - .desc = N_("The forward error correction used on the mux."), - }, - { - .type = PT_INT, - .id = "plp_id", - .name = N_("PLP ID"), - .desc = N_("The physical layer pipe ID. " - "Most people will not need to change this setting."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), - .def.i = DVB_NO_STREAM_ID_FILTER, - }, - { - .type = PT_U32, - .id = "data_slice", - .name = N_("Data slice"), - .desc = N_("Data slice code."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_data_slice), - .def.u32 = 0, - .opts = PO_EXPERT - }, - {} - } -}; +const idclass_t dvb_mux_isdb_c_class = {.ic_super = &dvb_mux_class, + .ic_class = "dvb_mux_isdbc", + .ic_caption = N_("ISDB-C multiplex"), + .ic_properties = (const property_t[]){ + { + MUX_PROP_STR("delsys", N_("Delivery system"), dvbc, delsys, "DVB-C"), + .desc = N_("The delivery system used by your cable provider."), + }, + { + .type = PT_U32, + .id = "frequency", + .name = N_("Frequency (Hz)"), + .desc = N_("The frequency of the mux (in Hertz)."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), + .set = dvb_mux_dvbt_class_frequency_set, + }, + { + .type = PT_U32, + .id = "symbolrate", + .name = N_("Symbol rate (Sym/s)"), + .desc = N_("The symbol rate."), + .off = offsetof(dvb_mux_t, lm_tuning.u.dmc_fe_qam.symbol_rate), + }, + { + MUX_PROP_STR("constellation", N_("Constellation"), dvbc, qam, N_("AUTO")), + .desc = N_("The quadrature amplitude modulation (QAM) used by the mux. " + "If you're not sure of the value leave as AUTO."), + }, + { + MUX_PROP_STR("fec", N_("FEC"), dvbc, fec, N_("AUTO")), + .desc = N_("The forward error correction used on the mux."), + }, + { + .type = PT_INT, + .id = "plp_id", + .name = N_("PLP ID"), + .desc = N_("The physical layer pipe ID. " + "Most people will not need to change this setting."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), + .def.i = DVB_NO_STREAM_ID_FILTER, + }, + {.type = PT_U32, + .id = "data_slice", + .name = N_("Data slice"), + .desc = N_("Data slice code."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_data_slice), + .def.u32 = 0, + .opts = PO_EXPERT}, + {}}}; /* * ISDB-S @@ -909,92 +1013,135 @@ const idclass_t dvb_mux_isdb_c_class = #define dvb_mux_isdb_s_class_delsys_get dvb_mux_class_delsys_get #define dvb_mux_isdb_s_class_delsys_set dvb_mux_class_delsys_set -static htsmsg_t * -dvb_mux_isdb_s_class_delsys_enum (void *o, const char *lang) -{ - htsmsg_t *list = htsmsg_create_list(); +static htsmsg_t* dvb_mux_isdb_s_class_delsys_enum(void* o, const char* lang) { + htsmsg_t* list = htsmsg_create_list(); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_ISDBS)); return list; } -const idclass_t dvb_mux_isdb_s_class = -{ - .ic_super = &dvb_mux_class, - .ic_class = "dvb_mux_isdbs", - .ic_caption = N_("ISDB-S multiplex"), - .ic_properties = (const property_t[]){ - { - MUX_PROP_STR("delsys", N_("Delivery system"), isdb_s, delsys, "ISDBS"), - .desc = N_("The delivery system used by your provider."), - }, - { - .type = PT_U32, - .id = "frequency", - .name = N_("Frequency (kHz)"), - .desc = N_("The frequency of the mux (in Hertz)."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), - .set = dvb_mux_dvbs_class_frequency_set, - }, - { - .type = PT_INT, - .id = "stream_id", - .name = N_("Stream ID"), - .desc = N_("The stream ID used for the mux."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), - .def.i = DVB_NO_STREAM_ID_FILTER, - .opts = PO_ADVANCED - }, - {} - } -}; +const idclass_t dvb_mux_isdb_s_class = {.ic_super = &dvb_mux_class, + .ic_class = "dvb_mux_isdbs", + .ic_caption = N_("ISDB-S multiplex"), + .ic_properties = (const property_t[]){ + { + MUX_PROP_STR("delsys", N_("Delivery system"), isdb_s, delsys, "ISDBS"), + .desc = N_("The delivery system used by your provider."), + }, + { + .type = PT_U32, + .id = "frequency", + .name = N_("Frequency (kHz)"), + .desc = N_("The frequency of the mux (in Hertz)."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), + .set = dvb_mux_dvbs_class_frequency_set, + }, + {.type = PT_INT, + .id = "stream_id", + .name = N_("Stream ID"), + .desc = N_("The stream ID used for the mux."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), + .def.i = DVB_NO_STREAM_ID_FILTER, + .opts = PO_ADVANCED}, + {}}}; /* * DTMB, fixme: review actually used parameters! */ -dvb_mux_class_X(dtmb, ofdm, bandwidth, bw, bw, - DVB_BANDWIDTH_AUTO, DVB_BANDWIDTH_10_MHZ, - DVB_BANDWIDTH_8_MHZ, DVB_BANDWIDTH_7_MHZ, - DVB_BANDWIDTH_6_MHZ, DVB_BANDWIDTH_5_MHZ, - DVB_BANDWIDTH_1_712_MHZ); -dvb_mux_class_R(dtmb, modulation, qam, qam, - DVB_MOD_QAM_AUTO, DVB_MOD_QPSK, DVB_MOD_QAM_16, - DVB_MOD_QAM_64, DVB_MOD_QAM_256); -dvb_mux_class_X(dtmb, ofdm, transmission_mode, mode, mode, - DVB_TRANSMISSION_MODE_AUTO, DVB_TRANSMISSION_MODE_32K, - DVB_TRANSMISSION_MODE_16K, DVB_TRANSMISSION_MODE_8K, - DVB_TRANSMISSION_MODE_2K, DVB_TRANSMISSION_MODE_1K); -dvb_mux_class_X(dtmb, ofdm, guard_interval, guard, guard, - DVB_GUARD_INTERVAL_AUTO, DVB_GUARD_INTERVAL_1_32, - DVB_GUARD_INTERVAL_1_16, DVB_GUARD_INTERVAL_1_8, - DVB_GUARD_INTERVAL_1_4, DVB_GUARD_INTERVAL_1_128, - DVB_GUARD_INTERVAL_19_128, DVB_GUARD_INTERVAL_19_256); -dvb_mux_class_X(dtmb, ofdm, hierarchy_information, hier, hier, - DVB_HIERARCHY_AUTO, DVB_HIERARCHY_NONE, - DVB_HIERARCHY_1, DVB_HIERARCHY_2, DVB_HIERARCHY_4); -dvb_mux_class_X(dtmb, ofdm, code_rate_HP, fechi, fechi, - DVB_FEC_AUTO, DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, - DVB_FEC_3_5, DVB_FEC_4_5, DVB_FEC_5_6, DVB_FEC_7_8); -dvb_mux_class_X(dtmb, ofdm, code_rate_LP, feclo, feclo, - DVB_FEC_AUTO, DVB_FEC_1_2, DVB_FEC_2_3, DVB_FEC_3_4, - DVB_FEC_3_5, DVB_FEC_4_5, DVB_FEC_5_6, DVB_FEC_7_8); +dvb_mux_class_X(dtmb, + ofdm, + bandwidth, + bw, + bw, + DVB_BANDWIDTH_AUTO, + DVB_BANDWIDTH_10_MHZ, + DVB_BANDWIDTH_8_MHZ, + DVB_BANDWIDTH_7_MHZ, + DVB_BANDWIDTH_6_MHZ, + DVB_BANDWIDTH_5_MHZ, + DVB_BANDWIDTH_1_712_MHZ); +dvb_mux_class_R(dtmb, + modulation, + qam, + qam, + DVB_MOD_QAM_AUTO, + DVB_MOD_QPSK, + DVB_MOD_QAM_16, + DVB_MOD_QAM_64, + DVB_MOD_QAM_256); +dvb_mux_class_X(dtmb, + ofdm, + transmission_mode, + mode, + mode, + DVB_TRANSMISSION_MODE_AUTO, + DVB_TRANSMISSION_MODE_32K, + DVB_TRANSMISSION_MODE_16K, + DVB_TRANSMISSION_MODE_8K, + DVB_TRANSMISSION_MODE_2K, + DVB_TRANSMISSION_MODE_1K); +dvb_mux_class_X(dtmb, + ofdm, + guard_interval, + guard, + guard, + DVB_GUARD_INTERVAL_AUTO, + DVB_GUARD_INTERVAL_1_32, + DVB_GUARD_INTERVAL_1_16, + DVB_GUARD_INTERVAL_1_8, + DVB_GUARD_INTERVAL_1_4, + DVB_GUARD_INTERVAL_1_128, + DVB_GUARD_INTERVAL_19_128, + DVB_GUARD_INTERVAL_19_256); +dvb_mux_class_X(dtmb, + ofdm, + hierarchy_information, + hier, + hier, + DVB_HIERARCHY_AUTO, + DVB_HIERARCHY_NONE, + DVB_HIERARCHY_1, + DVB_HIERARCHY_2, + DVB_HIERARCHY_4); +dvb_mux_class_X(dtmb, + ofdm, + code_rate_HP, + fechi, + fechi, + DVB_FEC_AUTO, + DVB_FEC_1_2, + DVB_FEC_2_3, + DVB_FEC_3_4, + DVB_FEC_3_5, + DVB_FEC_4_5, + DVB_FEC_5_6, + DVB_FEC_7_8); +dvb_mux_class_X(dtmb, + ofdm, + code_rate_LP, + feclo, + feclo, + DVB_FEC_AUTO, + DVB_FEC_1_2, + DVB_FEC_2_3, + DVB_FEC_3_4, + DVB_FEC_3_5, + DVB_FEC_4_5, + DVB_FEC_5_6, + DVB_FEC_7_8); #define dvb_mux_dtmb_class_delsys_get dvb_mux_class_delsys_get #define dvb_mux_dtmb_class_delsys_set dvb_mux_class_delsys_set -static htsmsg_t * -dvb_mux_dtmb_class_delsys_enum (void *o, const char *lang) -{ - htsmsg_t *list = htsmsg_create_list(); +static htsmsg_t* dvb_mux_dtmb_class_delsys_enum(void* o, const char* lang) { + htsmsg_t* list = htsmsg_create_list(); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DTMB)); return list; } -static int -dvb_mux_dtmb_class_frequency_set ( void *o, const void *v ) -{ - dvb_mux_t *lm = o; - uint32_t val = *(uint32_t *)v; +static int dvb_mux_dtmb_class_frequency_set(void* o, const void* v) { + dvb_mux_t* lm = o; + uint32_t val = *(uint32_t*)v; if (val < 1000) val *= 1000000; @@ -1008,77 +1155,73 @@ dvb_mux_dtmb_class_frequency_set ( void *o, const void *v ) return 0; } -const idclass_t dvb_mux_dtmb_class = -{ - .ic_super = &dvb_mux_class, - .ic_class = "dvb_mux_dtmb", - .ic_caption = N_("DTMB multiplex"), - .ic_properties = (const property_t[]){ - { - MUX_PROP_STR("delsys", N_("Delivery system"), dtmb, delsys, "DVBT"), - .desc = N_("The delivery system the mux uses. " - "Make sure that your tuner supports the delivery " - "system selected here."), - }, - { - .type = PT_U32, - .id = "frequency", - .name = N_("Frequency (Hz)"), - .desc = N_("The frequency of the mux (in Hertz)."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), - .set = dvb_mux_dtmb_class_frequency_set, - }, - { - MUX_PROP_STR("bandwidth", N_("Bandwidth"), dtmb, bw, N_("AUTO")), - .desc = N_("The bandwidth the mux uses. " - "If you're not sure of the value leave as AUTO " - "but be aware that tuning may fail as some drivers " - "do not like the AUTO setting."), - }, - { - MUX_PROP_STR("constellation", N_("Constellation"), dtmb, qam, N_("AUTO")), - .desc = N_("The COFDM modulation used by the mux. " - "If you're not sure of the value leave as AUTO."), - }, - { - MUX_PROP_STR("transmission_mode", N_("Transmission mode"), dtmb, mode, N_("AUTO")), - .desc = N_("The transmission/OFDM mode used by the mux. " - "If you're not sure of the value leave as AUTO " - "but be aware that tuning may fail as some drivers " - "do not like the AUTO setting."), - }, - { - MUX_PROP_STR("guard_interval", N_("Guard interval"), dtmb, guard, N_("AUTO")), - .desc = N_("The guard interval used by the mux. " - "If you're not sure of the value leave as AUTO."), - }, - { - MUX_PROP_STR("hierarchy", N_("Hierarchy"), dtmb, hier, N_("AUTO")), - .desc = N_("The hierarchical modulation used by the mux. " - "Most people will not need to change this setting."), - }, - { - MUX_PROP_STR("fec_hi", N_("FEC high"), dtmb, fechi, N_("AUTO")), - .desc = N_("The forward error correction high value. " - "Most people will not need to change this setting."), - }, - { - MUX_PROP_STR("fec_lo", N_("FEC low"), dtmb, feclo, N_("AUTO")), - .desc = N_("The forward error correction low value. " - "Most people will not need to change this setting."), - }, - { - .type = PT_INT, - .id = "plp_id", - .name = N_("PLP ID"), - .desc = N_("The physical layer pipe ID. " - "Most people will not need to change this setting."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), - .def.i = DVB_NO_STREAM_ID_FILTER, - }, - {} - } -}; +const idclass_t dvb_mux_dtmb_class = {.ic_super = &dvb_mux_class, + .ic_class = "dvb_mux_dtmb", + .ic_caption = N_("DTMB multiplex"), + .ic_properties = (const property_t[]){ + { + MUX_PROP_STR("delsys", N_("Delivery system"), dtmb, delsys, "DVBT"), + .desc = N_("The delivery system the mux uses. " + "Make sure that your tuner supports the delivery " + "system selected here."), + }, + { + .type = PT_U32, + .id = "frequency", + .name = N_("Frequency (Hz)"), + .desc = N_("The frequency of the mux (in Hertz)."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), + .set = dvb_mux_dtmb_class_frequency_set, + }, + { + MUX_PROP_STR("bandwidth", N_("Bandwidth"), dtmb, bw, N_("AUTO")), + .desc = N_("The bandwidth the mux uses. " + "If you're not sure of the value leave as AUTO " + "but be aware that tuning may fail as some drivers " + "do not like the AUTO setting."), + }, + { + MUX_PROP_STR("constellation", N_("Constellation"), dtmb, qam, N_("AUTO")), + .desc = N_("The COFDM modulation used by the mux. " + "If you're not sure of the value leave as AUTO."), + }, + { + MUX_PROP_STR("transmission_mode", N_("Transmission mode"), dtmb, mode, N_("AUTO")), + .desc = N_("The transmission/OFDM mode used by the mux. " + "If you're not sure of the value leave as AUTO " + "but be aware that tuning may fail as some drivers " + "do not like the AUTO setting."), + }, + { + MUX_PROP_STR("guard_interval", N_("Guard interval"), dtmb, guard, N_("AUTO")), + .desc = N_("The guard interval used by the mux. " + "If you're not sure of the value leave as AUTO."), + }, + { + MUX_PROP_STR("hierarchy", N_("Hierarchy"), dtmb, hier, N_("AUTO")), + .desc = N_("The hierarchical modulation used by the mux. " + "Most people will not need to change this setting."), + }, + { + MUX_PROP_STR("fec_hi", N_("FEC high"), dtmb, fechi, N_("AUTO")), + .desc = N_("The forward error correction high value. " + "Most people will not need to change this setting."), + }, + { + MUX_PROP_STR("fec_lo", N_("FEC low"), dtmb, feclo, N_("AUTO")), + .desc = N_("The forward error correction low value. " + "Most people will not need to change this setting."), + }, + { + .type = PT_INT, + .id = "plp_id", + .name = N_("PLP ID"), + .desc = N_("The physical layer pipe ID. " + "Most people will not need to change this setting."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_stream_id), + .def.i = DVB_NO_STREAM_ID_FILTER, + }, + {}}}; /* * DAB @@ -1087,71 +1230,64 @@ const idclass_t dvb_mux_dtmb_class = #define dvb_mux_dab_class_delsys_get dvb_mux_class_delsys_get #define dvb_mux_dab_class_delsys_set dvb_mux_class_delsys_set -static htsmsg_t * -dvb_mux_dab_class_delsys_enum (void *o, const char *lang) -{ - htsmsg_t *list = htsmsg_create_list(); +static htsmsg_t* dvb_mux_dab_class_delsys_enum(void* o, const char* lang) { + htsmsg_t* list = htsmsg_create_list(); htsmsg_add_str(list, NULL, dvb_delsys2str(DVB_SYS_DAB)); return list; } -const idclass_t dvb_mux_dab_class = -{ - .ic_super = &dvb_mux_class, - .ic_class = "dvb_mux_dab", - .ic_caption = N_("DAB multiplex"), - .ic_properties = (const property_t[]){ - { - MUX_PROP_STR("delsys", N_("Delivery system"), dab, delsys, "DAB"), - .desc = N_("The delivery system used by the mux."), - }, - { - .type = PT_U32, - .id = "frequency", - .name = N_("Frequency (Hz)"), - .desc = N_("The frequency of the mux (in Hertz)."), - .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), - .set = dvb_mux_dvbt_class_frequency_set, - }, - {} - } -}; +const idclass_t dvb_mux_dab_class = {.ic_super = &dvb_mux_class, + .ic_class = "dvb_mux_dab", + .ic_caption = N_("DAB multiplex"), + .ic_properties = + (const property_t[]){{ + MUX_PROP_STR("delsys", N_("Delivery system"), dab, delsys, "DAB"), + .desc = N_("The delivery system used by the mux."), + }, + { + .type = PT_U32, + .id = "frequency", + .name = N_("Frequency (Hz)"), + .desc = N_("The frequency of the mux (in Hertz)."), + .off = offsetof(dvb_mux_t, lm_tuning.dmc_fe_freq), + .set = dvb_mux_dvbt_class_frequency_set, + }, + {}}}; /* ************************************************************************** * Class methods * *************************************************************************/ -static htsmsg_t * -dvb_mux_config_save ( mpegts_mux_t *mm, char *filename, size_t fsize ) -{ - char ubuf1[UUID_HEX_SIZE]; - char ubuf2[UUID_HEX_SIZE]; - htsmsg_t *c = htsmsg_create_map(); +static htsmsg_t* dvb_mux_config_save(mpegts_mux_t* mm, char* filename, size_t fsize) { + char ubuf1[UUID_HEX_SIZE]; + char ubuf2[UUID_HEX_SIZE]; + htsmsg_t* c = htsmsg_create_map(); if (filename == NULL) { mpegts_mux_save(mm, c, 1); } else { mpegts_mux_save(mm, c, 0); - snprintf(filename, fsize, "input/dvb/networks/%s/muxes/%s", - idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), - idnode_uuid_as_str(&mm->mm_id, ubuf2)); + snprintf(filename, + fsize, + "input/dvb/networks/%s/muxes/%s", + idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), + idnode_uuid_as_str(&mm->mm_id, ubuf2)); } return c; } -static void -dvb_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len ) -{ - dvb_mux_t *lm = (dvb_mux_t*)mm; - dvb_network_t *ln = (dvb_network_t*)mm->mm_network; - uint32_t freq = lm->lm_tuning.dmc_fe_freq, freq2; - char extra[8], buf2[5], *p; +static void dvb_mux_display_name(mpegts_mux_t* mm, char* buf, size_t len) { + dvb_mux_t* lm = (dvb_mux_t*)mm; + dvb_network_t* ln = (dvb_network_t*)mm->mm_network; + uint32_t freq = lm->lm_tuning.dmc_fe_freq, freq2; + char extra[8], buf2[5], *p; if (lm->lm_tuning.dmc_fe_type == DVB_TYPE_CABLECARD) snprintf(buf, len, "%u", lm->lm_tuning.u.dmc_fe_cablecard.vchannel); else { if (ln->ln_type == DVB_TYPE_S) { - const char *s = dvb_pol2str(lm->lm_tuning.u.dmc_fe_qpsk.polarisation); - if (s) extra[0] = *s; + const char* s = dvb_pol2str(lm->lm_tuning.u.dmc_fe_qpsk.polarisation); + if (s) + extra[0] = *s; extra[1] = '\0'; } else { freq /= 1000; @@ -1172,17 +1308,15 @@ dvb_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len ) } } -static void -dvb_mux_delete ( mpegts_mux_t *mm, int delconf ) -{ +static void dvb_mux_delete(mpegts_mux_t* mm, int delconf) { char ubuf1[UUID_HEX_SIZE]; char ubuf2[UUID_HEX_SIZE]; /* Remove config */ if (delconf) hts_settings_remove("input/dvb/networks/%s/muxes/%s", - idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), - idnode_uuid_as_str(&mm->mm_id, ubuf2)); + idnode_uuid_as_str(&mm->mm_network->mn_id, ubuf1), + idnode_uuid_as_str(&mm->mm_id, ubuf2)); /* Delete the mux */ mpegts_mux_delete(mm, delconf); @@ -1192,54 +1326,54 @@ dvb_mux_delete ( mpegts_mux_t *mm, int delconf ) * Creation/Config * *************************************************************************/ -dvb_mux_t * -dvb_mux_create0 - ( dvb_network_t *ln, - uint32_t onid, uint32_t tsid, const dvb_mux_conf_t *dmc, - const char *uuid, htsmsg_t *conf ) -{ - const idclass_t *idc; - mpegts_mux_t *mm; - dvb_mux_t *lm; - htsmsg_t *c, *c2, *e; - htsmsg_field_t *f; +dvb_mux_t* dvb_mux_create0(dvb_network_t* ln, + uint32_t onid, + uint32_t tsid, + const dvb_mux_conf_t* dmc, + const char* uuid, + htsmsg_t* conf) { + const idclass_t* idc; + mpegts_mux_t* mm; + dvb_mux_t* lm; + htsmsg_t * c, *c2, *e; + htsmsg_field_t* f; dvb_fe_delivery_system_t delsys; - char ubuf1[UUID_HEX_SIZE]; - char ubuf2[UUID_HEX_SIZE]; + char ubuf1[UUID_HEX_SIZE]; + char ubuf2[UUID_HEX_SIZE]; /* Class */ if (ln->ln_type == DVB_TYPE_S) { - idc = &dvb_mux_dvbs_class; + idc = &dvb_mux_dvbs_class; delsys = DVB_SYS_DVBS; } else if (ln->ln_type == DVB_TYPE_C) { - idc = &dvb_mux_dvbc_class; + idc = &dvb_mux_dvbc_class; delsys = DVB_SYS_DVBC_ANNEX_A; } else if (ln->ln_type == DVB_TYPE_T) { - idc = &dvb_mux_dvbt_class; + idc = &dvb_mux_dvbt_class; delsys = DVB_SYS_DVBT; } else if (ln->ln_type == DVB_TYPE_ATSC_T) { - idc = &dvb_mux_atsc_t_class; + idc = &dvb_mux_atsc_t_class; delsys = DVB_SYS_ATSC; } else if (ln->ln_type == DVB_TYPE_ATSC_C) { - idc = &dvb_mux_atsc_c_class; + idc = &dvb_mux_atsc_c_class; delsys = DVB_SYS_DVBC_ANNEX_B; } else if (ln->ln_type == DVB_TYPE_CABLECARD) { - idc = &dvb_mux_cablecard_class; + idc = &dvb_mux_cablecard_class; delsys = DVB_SYS_DVBC_ANNEX_B; } else if (ln->ln_type == DVB_TYPE_ISDB_T) { - idc = &dvb_mux_isdb_t_class; + idc = &dvb_mux_isdb_t_class; delsys = DVB_SYS_ISDBT; } else if (ln->ln_type == DVB_TYPE_ISDB_C) { - idc = &dvb_mux_isdb_c_class; + idc = &dvb_mux_isdb_c_class; delsys = DVB_SYS_ISDBC; } else if (ln->ln_type == DVB_TYPE_ISDB_S) { - idc = &dvb_mux_isdb_s_class; + idc = &dvb_mux_isdb_s_class; delsys = DVB_SYS_ISDBS; } else if (ln->ln_type == DVB_TYPE_DTMB) { - idc = &dvb_mux_dtmb_class; + idc = &dvb_mux_dtmb_class; delsys = DVB_SYS_DTMB; } else if (ln->ln_type == DVB_TYPE_DAB) { - idc = &dvb_mux_dab_class; + idc = &dvb_mux_dab_class; delsys = DVB_SYS_DAB; } else { tvherror(LS_DVB, "unknown FE type %d", ln->ln_type); @@ -1254,8 +1388,7 @@ dvb_mux_create0 dvb_mux_conf_init((mpegts_network_t*)ln, &lm->lm_tuning, delsys); /* Parent init and load config */ - if (!(mm = mpegts_mux_create0(mm, idc, uuid, - (mpegts_network_t*)ln, onid, tsid, conf))) { + if (!(mm = mpegts_mux_create0(mm, idc, uuid, (mpegts_network_t*)ln, onid, tsid, conf))) { free(mm); return NULL; } @@ -1266,27 +1399,30 @@ dvb_mux_create0 lm->lm_tuning.dmc_fe_type = ln->ln_type; /* Callbacks */ - lm->mm_delete = dvb_mux_delete; - lm->mm_display_name = dvb_mux_display_name; - lm->mm_config_save = dvb_mux_config_save; + lm->mm_delete = dvb_mux_delete; + lm->mm_display_name = dvb_mux_display_name; + lm->mm_config_save = dvb_mux_config_save; mpegts_mux_update_nice_name(mm); /* No config */ - if (!conf) return lm; + if (!conf) + return lm; /* Services */ c2 = NULL; - c = htsmsg_get_map(conf, "services"); + c = htsmsg_get_map(conf, "services"); if (c == NULL) - c = c2 = hts_settings_load_r(1, "input/dvb/networks/%s/muxes/%s/services", - idnode_uuid_as_str(&ln->mn_id, ubuf1), - idnode_uuid_as_str(&mm->mm_id, ubuf2)); + c = c2 = hts_settings_load_r(1, + "input/dvb/networks/%s/muxes/%s/services", + idnode_uuid_as_str(&ln->mn_id, ubuf1), + idnode_uuid_as_str(&mm->mm_id, ubuf2)); if (c) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_get_map_by_field(f))) continue; - mpegts_service_create1(htsmsg_field_name(f), (mpegts_mux_t *)lm, 0, 0, e); + if (!(e = htsmsg_get_map_by_field(f))) + continue; + mpegts_service_create1(htsmsg_field_name(f), (mpegts_mux_t*)lm, 0, 0, e); } htsmsg_destroy(c2); } @@ -1296,8 +1432,7 @@ dvb_mux_create0 /* Update the satellite position for the network settings */ if (lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos != INT_MAX) ln->mn_satpos = lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos; - } - else { + } else { /* Update the satellite position for the mux setting */ lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos = ln->mn_satpos; } diff --git a/src/input/mpegts/mpegts_mux_sched.c b/src/input/mpegts/mpegts_mux_sched.c index c7a1a4d41..381f58e65 100644 --- a/src/input/mpegts/mpegts_mux_sched.c +++ b/src/input/mpegts/mpegts_mux_sched.c @@ -24,7 +24,7 @@ #include "settings.h" #include "profile.h" -static void mpegts_mux_sched_timer ( void *p ); +static void mpegts_mux_sched_timer(void* p); mpegts_mux_sched_list_t mpegts_mux_sched_all; @@ -32,9 +32,7 @@ mpegts_mux_sched_list_t mpegts_mux_sched_all; * Class *****************************************************************************/ -static void -mpegts_mux_sched_set_timer ( mpegts_mux_sched_t *mms ) -{ +static void mpegts_mux_sched_set_timer(mpegts_mux_sched_t* mms) { /* Update timer */ if (!mms->mms_enabled) { if (mms->mms_sub) @@ -46,8 +44,7 @@ mpegts_mux_sched_set_timer ( mpegts_mux_sched_t *mms ) if (mms->mms_timeout <= 0) gtimer_disarm(&mms->mms_timer); else { - gtimer_arm_rel(&mms->mms_timer, mpegts_mux_sched_timer, mms, - mms->mms_timeout); + gtimer_arm_rel(&mms->mms_timer, mpegts_mux_sched_timer, mms, mms->mms_timeout); } } else { time_t nxt; @@ -58,55 +55,45 @@ mpegts_mux_sched_set_timer ( mpegts_mux_sched_t *mms ) } } -static void -mpegts_mux_sched_class_changed ( idnode_t *in ) -{ - mpegts_mux_sched_t *mms = (mpegts_mux_sched_t*)in; +static void mpegts_mux_sched_class_changed(idnode_t* in) { + mpegts_mux_sched_t* mms = (mpegts_mux_sched_t*)in; /* Update timer */ mpegts_mux_sched_set_timer(mms); } -static htsmsg_t * -mpegts_mux_sched_class_save ( idnode_t *in, char *filename, size_t fsize ) -{ - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* mpegts_mux_sched_class_save(idnode_t* in, char* filename, size_t fsize) { + htsmsg_t* c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(in, c); if (filename) snprintf(filename, fsize, "muxsched/%s", idnode_uuid_as_str(in, ubuf)); return c; } -static void -mpegts_mux_sched_class_delete ( idnode_t *in ) -{ +static void mpegts_mux_sched_class_delete(idnode_t* in) { mpegts_mux_sched_delete((mpegts_mux_sched_t*)in, 1); } -static htsmsg_t * -mpegts_mux_sched_class_mux_list ( void *o, const char *lang ) -{ +static htsmsg_t* mpegts_mux_sched_class_mux_list(void* o, const char* lang) { htsmsg_t *m, *p; p = htsmsg_create_map(); - htsmsg_add_str (p, "class", "mpegts_mux"); - htsmsg_add_bool(p, "enum", 1); + htsmsg_add_str(p, "class", "mpegts_mux"); + htsmsg_add_bool(p, "enum", 1); m = htsmsg_create_map(); - htsmsg_add_str (m, "type", "api"); - htsmsg_add_str (m, "uri", "idnode/load"); - htsmsg_add_str (m, "event", "mpegts_mux"); - htsmsg_add_msg (m, "params", p); - + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "idnode/load"); + htsmsg_add_str(m, "event", "mpegts_mux"); + htsmsg_add_msg(m, "params", p); + return m; } -static int -mpegts_mux_sched_class_cron_set ( void *p, const void *v ) -{ - mpegts_mux_sched_t *mms = p; - const char *str = v; +static int mpegts_mux_sched_class_cron_set(void* p, const void* v) { + mpegts_mux_sched_t* mms = p; + const char* str = v; if (strcmp(str, mms->mms_cronstr ?: "")) { if (!cron_set(&mms->mms_cronjob, str)) { free(mms->mms_cronstr); @@ -122,69 +109,63 @@ mpegts_mux_sched_class_cron_set ( void *p, const void *v ) CLASS_DOC(mpegts_mux_sched) PROP_DOC(cron) -const idclass_t mpegts_mux_sched_class = -{ - .ic_class = "mpegts_mux_sched", - .ic_caption = N_("DVB Inputs - Mux Schedulers"), - .ic_event = "mpegts_mux_sched", - .ic_doc = tvh_doc_mpegts_mux_sched_class, - .ic_changed = mpegts_mux_sched_class_changed, - .ic_save = mpegts_mux_sched_class_save, - .ic_delete = mpegts_mux_sched_class_delete, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable the entry."), - .off = offsetof(mpegts_mux_sched_t, mms_enabled), - .def.i = 1, - }, - { - .type = PT_STR, - .id = "mux", - .name = N_("Mux"), - .desc = N_("The mux to play when the entry is triggered."), - .off = offsetof(mpegts_mux_sched_t, mms_mux), - .list = mpegts_mux_sched_class_mux_list, - }, - { - .type = PT_STR, - .id = "cron", - .name = N_("Cron"), - .desc = N_("Schedule frequency (in cron format)."), - .doc = prop_doc_cron, - .off = offsetof(mpegts_mux_sched_t, mms_cronstr), - .set = mpegts_mux_sched_class_cron_set, - }, - { - .type = PT_INT, - .id = "timeout", - .name = N_("Timeout (secs)"), - .desc = N_("The length of time (in seconds) to play the mux " - "(1 hour = 3600)."), - .off = offsetof(mpegts_mux_sched_t, mms_timeout), - }, - { - .type = PT_BOOL, - .id = "restart", - .name = N_("Restart"), - .desc = N_("Restart when the subscription is overriden (in then timeout time window)."), - .off = offsetof(mpegts_mux_sched_t, mms_restart), - }, - { - }, - } -}; +const idclass_t mpegts_mux_sched_class = {.ic_class = "mpegts_mux_sched", + .ic_caption = N_("DVB Inputs - Mux Schedulers"), + .ic_event = "mpegts_mux_sched", + .ic_doc = tvh_doc_mpegts_mux_sched_class, + .ic_changed = mpegts_mux_sched_class_changed, + .ic_save = mpegts_mux_sched_class_save, + .ic_delete = mpegts_mux_sched_class_delete, + .ic_properties = (const property_t[]){ + { + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable the entry."), + .off = offsetof(mpegts_mux_sched_t, mms_enabled), + .def.i = 1, + }, + { + .type = PT_STR, + .id = "mux", + .name = N_("Mux"), + .desc = N_("The mux to play when the entry is triggered."), + .off = offsetof(mpegts_mux_sched_t, mms_mux), + .list = mpegts_mux_sched_class_mux_list, + }, + { + .type = PT_STR, + .id = "cron", + .name = N_("Cron"), + .desc = N_("Schedule frequency (in cron format)."), + .doc = prop_doc_cron, + .off = offsetof(mpegts_mux_sched_t, mms_cronstr), + .set = mpegts_mux_sched_class_cron_set, + }, + { + .type = PT_INT, + .id = "timeout", + .name = N_("Timeout (secs)"), + .desc = N_("The length of time (in seconds) to play the mux " + "(1 hour = 3600)."), + .off = offsetof(mpegts_mux_sched_t, mms_timeout), + }, + { + .type = PT_BOOL, + .id = "restart", + .name = N_("Restart"), + .desc = N_("Restart when the subscription is overriden (in then timeout time window)."), + .off = offsetof(mpegts_mux_sched_t, mms_restart), + }, + {}, + }}; /****************************************************************************** * Input *****************************************************************************/ -static void -mpegts_mux_sched_input ( void *p, streaming_message_t *sm ) -{ - mpegts_mux_sched_t *mms = p; +static void mpegts_mux_sched_input(void* p, streaming_message_t* sm) { + mpegts_mux_sched_t* mms = p; switch (sm->sm_type) { case SMT_STOP: @@ -197,28 +178,22 @@ mpegts_mux_sched_input ( void *p, streaming_message_t *sm ) streaming_msg_free(sm); } -static htsmsg_t * -mpegts_mux_sched_input_info ( void *p, htsmsg_t *list ) -{ +static htsmsg_t* mpegts_mux_sched_input_info(void* p, htsmsg_t* list) { htsmsg_add_str(list, NULL, "mux sched input"); return list; } -static streaming_ops_t mpegts_mux_sched_input_ops = { - .st_cb = mpegts_mux_sched_input, - .st_info = mpegts_mux_sched_input_info -}; +static streaming_ops_t mpegts_mux_sched_input_ops = {.st_cb = mpegts_mux_sched_input, + .st_info = mpegts_mux_sched_input_info}; /****************************************************************************** * Timer *****************************************************************************/ -static void -mpegts_mux_sched_timer ( void *p ) -{ - mpegts_mux_t *mm; - mpegts_mux_sched_t *mms = p; - time_t nxt; +static void mpegts_mux_sched_timer(void* p) { + mpegts_mux_t* mm; + mpegts_mux_sched_t* mms = p; + time_t nxt; /* Not enabled (shouldn't be running) */ if (!mms->mms_enabled) @@ -227,7 +202,7 @@ mpegts_mux_sched_timer ( void *p ) /* Invalid config (creating?) */ if (!mms->mms_mux) return; - + /* Find mux */ if (!(mm = mpegts_mux_find(mms->mms_mux))) { tvhdebug(LS_MUXSCHED, "mux has been removed, delete sched entry"); @@ -244,26 +219,29 @@ mpegts_mux_sched_timer ( void *p ) mms->mms_prch->prch_id = mm; mms->mms_prch->prch_st = &mms->mms_input; - mms->mms_sub - = subscription_create_from_mux(mms->mms_prch, NULL, mms->mms_weight, - mms->mms_creator ?: "", - SUBSCRIPTION_MINIMAL, - NULL, NULL, NULL, NULL); + mms->mms_sub = subscription_create_from_mux(mms->mms_prch, + NULL, + mms->mms_weight, + mms->mms_creator ?: "", + SUBSCRIPTION_MINIMAL, + NULL, + NULL, + NULL, + NULL); /* Failed (try-again soon) */ if (!mms->mms_sub) { gtimer_arm_rel(&mms->mms_timer, mpegts_mux_sched_timer, mms, 60); - /* OK */ + /* OK */ } else { mms->mms_active = 1; if (mms->mms_timeout > 0) { - gtimer_arm_rel(&mms->mms_timer, mpegts_mux_sched_timer, mms, - mms->mms_timeout); - } + gtimer_arm_rel(&mms->mms_timer, mpegts_mux_sched_timer, mms, mms->mms_timeout); + } } - /* Cancel sub */ + /* Cancel sub */ } else { if (mms->mms_sub) { subscription_unsubscribe(mms->mms_sub, UNSUBSCRIBE_FINAL); @@ -272,8 +250,7 @@ mpegts_mux_sched_timer ( void *p ) mms->mms_active = 0; if (mms->mms_restart && - (mms->mms_timeout <= 0 || - mms->mms_start + mms->mms_timeout < gclk() - 60)) { + (mms->mms_timeout <= 0 || mms->mms_start + mms->mms_timeout < gclk() - 60)) { gtimer_arm_rel(&mms->mms_timer, mpegts_mux_sched_timer, mms, 15); return; } @@ -294,10 +271,8 @@ mpegts_mux_sched_timer ( void *p ) * Init / Create *****************************************************************************/ -mpegts_mux_sched_t * -mpegts_mux_sched_create ( const char *uuid, htsmsg_t *conf ) -{ - mpegts_mux_sched_t *mms; +mpegts_mux_sched_t* mpegts_mux_sched_create(const char* uuid, htsmsg_t* conf) { + mpegts_mux_sched_t* mms; if (!(mms = calloc(1, sizeof(mpegts_mux_sched_t)))) { tvherror(LS_MUXSCHED, "calloc() failed"); @@ -324,8 +299,7 @@ mpegts_mux_sched_create ( const char *uuid, htsmsg_t *conf ) idnode_load(&mms->mms_id, conf); /* Validate */ - if (!mpegts_mux_find(mms->mms_mux ?: "") || - !mms->mms_cronstr) { + if (!mpegts_mux_find(mms->mms_mux ?: "") || !mms->mms_cronstr) { mpegts_mux_sched_delete(mms, 1); return NULL; } @@ -336,9 +310,7 @@ mpegts_mux_sched_create ( const char *uuid, htsmsg_t *conf ) return mms; } -void -mpegts_mux_sched_delete ( mpegts_mux_sched_t *mms, int delconf ) -{ +void mpegts_mux_sched_delete(mpegts_mux_sched_t* mms, int delconf) { char ubuf[UUID_HEX_SIZE]; LIST_REMOVE(mms, mms_link); @@ -355,28 +327,25 @@ mpegts_mux_sched_delete ( mpegts_mux_sched_t *mms, int delconf ) free(mms); } -void -mpegts_mux_sched_init ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; +void mpegts_mux_sched_init(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; idclass_register(&mpegts_mux_sched_class); /* Load settings */ if ((c = hts_settings_load_r(1, "muxsched"))) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; mpegts_mux_sched_create(htsmsg_field_name(f), e); } htsmsg_destroy(c); } } -void -mpegts_mux_sched_done ( void ) -{ - mpegts_mux_sched_t *mms; +void mpegts_mux_sched_done(void) { + mpegts_mux_sched_t* mms; tvh_mutex_lock(&global_lock); while ((mms = LIST_FIRST(&mpegts_mux_sched_all))) mpegts_mux_sched_delete(mms, 0); diff --git a/src/input/mpegts/mpegts_mux_sched.h b/src/input/mpegts/mpegts_mux_sched.h index b5e664f08..843671d5e 100644 --- a/src/input/mpegts/mpegts_mux_sched.h +++ b/src/input/mpegts/mpegts_mux_sched.h @@ -27,14 +27,13 @@ struct profile_chain; -typedef LIST_HEAD(,mpegts_mux_sched) mpegts_mux_sched_list_t; +typedef LIST_HEAD(, mpegts_mux_sched) mpegts_mux_sched_list_t; extern mpegts_mux_sched_list_t mpegts_mux_sched_all; extern const idclass_t mpegts_mux_sched_class; -typedef struct mpegts_mux_sched -{ +typedef struct mpegts_mux_sched { idnode_t mms_id; LIST_ENTRY(mpegts_mux_sched) mms_link; @@ -42,37 +41,36 @@ typedef struct mpegts_mux_sched /* * Configuration */ - int mms_enabled; ///< Enabled - char *mms_cronstr; ///< Cron configuration string - char *mms_mux; ///< Mux UUID - char *mms_creator; ///< Creator of entry - int mms_timeout; ///< Timeout (in seconds) - int mms_restart; ///< Restart subscription when overriden - int mms_weight; ///< Weighting + int mms_enabled; ///< Enabled + char* mms_cronstr; ///< Cron configuration string + char* mms_mux; ///< Mux UUID + char* mms_creator; ///< Creator of entry + int mms_timeout; ///< Timeout (in seconds) + int mms_restart; ///< Restart subscription when overriden + int mms_weight; ///< Weighting /* * Cron handling */ - int mms_active; ///< Subscription is active - time_t mms_start; ///< Start time - gtimer_t mms_timer; ///< Timer for start/end - cron_t mms_cronjob; ///< Cron spec - + int mms_active; ///< Subscription is active + time_t mms_start; ///< Start time + gtimer_t mms_timer; ///< Timer for start/end + cron_t mms_cronjob; ///< Cron spec + /* * Subscription */ - struct profile_chain *mms_prch; ///< Dummy profile chain - th_subscription_t *mms_sub; ///< Subscription handler - streaming_target_t mms_input; ///< Streaming input + struct profile_chain* mms_prch; ///< Dummy profile chain + th_subscription_t* mms_sub; ///< Subscription handler + streaming_target_t mms_input; ///< Streaming input } mpegts_mux_sched_t; -mpegts_mux_sched_t *mpegts_mux_sched_create ( const char *uuid, htsmsg_t *c ); -void mpegts_mux_sched_delete ( mpegts_mux_sched_t *mms, int delconf ); - -void mpegts_mux_sched_init ( void ); -void mpegts_mux_sched_done ( void ); +mpegts_mux_sched_t* mpegts_mux_sched_create(const char* uuid, htsmsg_t* c); +void mpegts_mux_sched_delete(mpegts_mux_sched_t* mms, int delconf); +void mpegts_mux_sched_init(void); +void mpegts_mux_sched_done(void); #endif /* __TVH_MPEGTS_H__ */ diff --git a/src/input/mpegts/mpegts_network.c b/src/input/mpegts/mpegts_network.c index 0d52bebd7..84a6c52c7 100644 --- a/src/input/mpegts/mpegts_network.c +++ b/src/input/mpegts/mpegts_network.c @@ -25,144 +25,123 @@ #include -static bouquet_t * mpegts_network_bouquet_get (mpegts_network_t *, int); +static bouquet_t* mpegts_network_bouquet_get(mpegts_network_t*, int); /* **************************************************************************** * Class definition * ***************************************************************************/ -static void -mpegts_network_class_notify_enabled ( void *obj, const char *lang ) -{ - mpegts_network_t *mn = (mpegts_network_t*)obj; - mpegts_mux_instance_t *mmi; - mpegts_mux_t *mm; +static void mpegts_network_class_notify_enabled(void* obj, const char* lang) { + mpegts_network_t* mn = (mpegts_network_t*)obj; + mpegts_mux_instance_t* mmi; + mpegts_mux_t* mm; if (!mn->mn_enabled) { - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) { mmi = mm->mm_active; - if (!mmi) continue; + if (!mmi) + continue; assert(mm == mmi->mmi_mux); mm->mm_stop(mm, 1, SM_CODE_ABORTED); } } } -static htsmsg_t * -mpegts_network_class_save - ( idnode_t *in, char *filename, size_t fsize ) -{ - mpegts_network_t *mn = (mpegts_network_t*)in; +static htsmsg_t* mpegts_network_class_save(idnode_t* in, char* filename, size_t fsize) { + mpegts_network_t* mn = (mpegts_network_t*)in; if (mn->mn_config_save) return mn->mn_config_save(mn, filename, fsize); return NULL; } static void -mpegts_network_class_get_title - ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) -{ - mpegts_network_t *mn = (mpegts_network_t*)in; - *dst = 0; +mpegts_network_class_get_title(idnode_t* in, const char* lang, char* dst, size_t dstsize) { + mpegts_network_t* mn = (mpegts_network_t*)in; + *dst = 0; if (mn->mn_display_name) mn->mn_display_name(mn, dst, dstsize); } -static const void * -mpegts_network_class_get_num_mux ( void *ptr ) -{ - static int n; - mpegts_mux_t *mm; - mpegts_network_t *mn = ptr; +static const void* mpegts_network_class_get_num_mux(void* ptr) { + static int n; + mpegts_mux_t* mm; + mpegts_network_t* mn = ptr; n = 0; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) n++; return &n; } -static const void * -mpegts_network_class_get_num_svc ( void *ptr ) -{ - static int n; - mpegts_mux_t *mm; - mpegts_service_t *s; - mpegts_network_t *mn = ptr; +static const void* mpegts_network_class_get_num_svc(void* ptr) { + static int n; + mpegts_mux_t* mm; + mpegts_service_t* s; + mpegts_network_t* mn = ptr; n = 0; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) n++; return &n; } -static const void * -mpegts_network_class_get_num_chn ( void *ptr ) -{ - static int n; - mpegts_mux_t *mm; - mpegts_service_t *s; - mpegts_network_t *mn = ptr; - idnode_list_mapping_t *ilm; +static const void* mpegts_network_class_get_num_chn(void* ptr) { + static int n; + mpegts_mux_t* mm; + mpegts_service_t* s; + mpegts_network_t* mn = ptr; + idnode_list_mapping_t* ilm; n = 0; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) - LIST_FOREACH(ilm, &s->s_channels, ilm_in1_link) + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) + LIST_FOREACH (ilm, &s->s_channels, ilm_in1_link) n++; return &n; } -static const void * -mpegts_network_class_get_scanq_length ( void *ptr ) -{ - static int n; - mpegts_mux_t *mm; - mpegts_network_t *mn = ptr; +static const void* mpegts_network_class_get_scanq_length(void* ptr) { + static int n; + mpegts_mux_t* mm; + mpegts_network_t* mn = ptr; n = 0; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) if (mm->mm_scan_state != MM_SCAN_STATE_IDLE) n++; return &n; } -static void -mpegts_network_class_idlescan_notify ( void *p, const char *lang ) -{ - mpegts_network_t *mn = p; - mpegts_mux_t *mm; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { +static void mpegts_network_class_idlescan_notify(void* p, const char* lang) { + mpegts_network_t* mn = p; + mpegts_mux_t* mm; + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) { if (mn->mn_idlescan) - mpegts_network_scan_queue_add(mm, SUBSCRIPTION_PRIO_SCAN_IDLE, - SUBSCRIPTION_IDLESCAN, 0); - else if (mm->mm_scan_state == MM_SCAN_STATE_PEND && - mm->mm_scan_weight == SUBSCRIPTION_PRIO_SCAN_IDLE) { + mpegts_network_scan_queue_add(mm, SUBSCRIPTION_PRIO_SCAN_IDLE, SUBSCRIPTION_IDLESCAN, 0); + else if (mm->mm_scan_state == MM_SCAN_STATE_PEND && + mm->mm_scan_weight == SUBSCRIPTION_PRIO_SCAN_IDLE) { mm->mm_scan_flags = 0; mpegts_network_scan_queue_del(mm); } } } -static htsmsg_t * -mpegts_network_discovery_enum ( void *o, const char *lang ) -{ +static htsmsg_t* mpegts_network_discovery_enum(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Disable"), MN_DISCOVERY_DISABLE }, - { N_("New muxes only"), MN_DISCOVERY_NEW }, - { N_("New muxes + changed muxes"), MN_DISCOVERY_CHANGE }, + {N_("Disable"), MN_DISCOVERY_DISABLE}, + {N_("New muxes only"), MN_DISCOVERY_NEW}, + {N_("New muxes + changed muxes"), MN_DISCOVERY_CHANGE}, }; return strtab2htsmsg(tab, 1, lang); } -static void -mpegts_network_class_notify_bouquet( void *in, const char *lang ) -{ - mpegts_network_t *mn = in; - bouquet_t *bq; +static void mpegts_network_class_notify_bouquet(void* in, const char* lang) { + mpegts_network_t* mn = in; + bouquet_t* bq; if (mn->mn_bouquet) { mpegts_network_bouquet_trigger(mn, 0); } else { @@ -175,320 +154,273 @@ mpegts_network_class_notify_bouquet( void *in, const char *lang ) CLASS_DOC(mpegts_network) PROP_DOC(network_discovery) -const idclass_t mpegts_network_class = -{ - .ic_class = "mpegts_network", - .ic_caption = N_("DVB Inputs - Networks"), - .ic_doc = tvh_doc_mpegts_network_class, - .ic_event = "mpegts_network", - .ic_perm_def = ACCESS_ADMIN, - .ic_save = mpegts_network_class_save, - .ic_get_title = mpegts_network_class_get_title, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/Disable network."), - .off = offsetof(mpegts_network_t, mn_enabled), - .notify = mpegts_network_class_notify_enabled, - }, - { - .type = PT_STR, - .id = "networkname", - .name = N_("Network name"), - .desc = N_("Name of the network."), - .off = offsetof(mpegts_network_t, mn_network_name), - .notify = idnode_notify_title_changed_lang, - }, - { - .type = PT_STR, - .id = "pnetworkname", - .name = N_("Provider network name"), - .desc = N_("Provider's network name."), - .off = offsetof(mpegts_network_t, mn_provider_network_name), - .opts = PO_ADVANCED | PO_HIDDEN, - }, - { - .type = PT_U16, - .id = "nid", - .name = N_("Network ID (limit scanning)"), - .desc = N_("Limited/limit scanning to this network ID only."), - .opts = PO_ADVANCED, - .off = offsetof(mpegts_network_t, mn_nid), - }, - { - .type = PT_INT, - .id = "autodiscovery", - .name = N_("Network discovery"), - .desc = N_("Discover more muxes using the Network " - "Information Table (if available)."), - .doc = prop_doc_network_discovery, - .off = offsetof(mpegts_network_t, mn_autodiscovery), - .list = mpegts_network_discovery_enum, - .opts = PO_ADVANCED | PO_DOC_NLIST, - .def.i = MN_DISCOVERY_NEW - }, - { - .type = PT_BOOL, - .id = "bouquet", - .name = N_("Create bouquet"), - .desc = N_("Create a bouquet with all services in the network."), - .off = offsetof(mpegts_network_t, mn_bouquet), - .notify = mpegts_network_class_notify_bouquet, - }, - - { - .type = PT_BOOL, - .id = "skipinitscan", - .name = N_("Skip startup scan"), - .desc = N_("Skip scanning known muxes when Tvheadend starts. " - "If \"startup scan\" is allowed and new muxes are " - "found then they will still be scanned. See Help for " - "more details."), - .off = offsetof(mpegts_network_t, mn_skipinitscan), - .opts = PO_EXPERT, - .def.i = 1 - }, - { - .type = PT_BOOL, - .id = "idlescan", - .name = N_("Idle scan muxes"), - .desc = N_("When nothing else is happening Tvheadend will " - "continuously rotate among all muxes and tune to " - "them to verify that they are still working when " - "the inputs are not used for streaming. If your " - "adapters have problems with lots of (endless) " - "tuning, disable this. Note that this option " - "should be OFF for the normal operation. This type " - "of mux probing is not required and it may cause " - "issues for SAT>IP (limited number of PID filters)."), - .off = offsetof(mpegts_network_t, mn_idlescan), - .def.i = 0, - .notify = mpegts_network_class_idlescan_notify, - .opts = PO_EXPERT | PO_HIDDEN, - }, - { - .type = PT_BOOL, - .id = "sid_chnum", - .name = N_("Use service IDs as channel numbers"), - .desc = N_("Use the provider's service IDs as channel numbers."), - .off = offsetof(mpegts_network_t, mn_sid_chnum), - .opts = PO_EXPERT, - .def.i = 0, - }, - { - .type = PT_BOOL, - .id = "ignore_chnum", - .name = N_("Ignore provider's channel numbers"), - .desc = N_("Don't use the provider's channel numbers."), - .off = offsetof(mpegts_network_t, mn_ignore_chnum), - .opts = PO_ADVANCED, - .def.i = 0, - }, +const idclass_t mpegts_network_class = {.ic_class = "mpegts_network", + .ic_caption = N_("DVB Inputs - Networks"), + .ic_doc = tvh_doc_mpegts_network_class, + .ic_event = "mpegts_network", + .ic_perm_def = ACCESS_ADMIN, + .ic_save = mpegts_network_class_save, + .ic_get_title = mpegts_network_class_get_title, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/Disable network."), + .off = offsetof(mpegts_network_t, mn_enabled), + .notify = mpegts_network_class_notify_enabled, + }, + { + .type = PT_STR, + .id = "networkname", + .name = N_("Network name"), + .desc = N_("Name of the network."), + .off = offsetof(mpegts_network_t, mn_network_name), + .notify = idnode_notify_title_changed_lang, + }, + { + .type = PT_STR, + .id = "pnetworkname", + .name = N_("Provider network name"), + .desc = N_("Provider's network name."), + .off = offsetof(mpegts_network_t, mn_provider_network_name), + .opts = PO_ADVANCED | PO_HIDDEN, + }, + { + .type = PT_U16, + .id = "nid", + .name = N_("Network ID (limit scanning)"), + .desc = N_("Limited/limit scanning to this network ID only."), + .opts = PO_ADVANCED, + .off = offsetof(mpegts_network_t, mn_nid), + }, + {.type = PT_INT, + .id = "autodiscovery", + .name = N_("Network discovery"), + .desc = N_("Discover more muxes using the Network " + "Information Table (if available)."), + .doc = prop_doc_network_discovery, + .off = offsetof(mpegts_network_t, mn_autodiscovery), + .list = mpegts_network_discovery_enum, + .opts = PO_ADVANCED | PO_DOC_NLIST, + .def.i = MN_DISCOVERY_NEW}, + { + .type = PT_BOOL, + .id = "bouquet", + .name = N_("Create bouquet"), + .desc = N_("Create a bouquet with all services in the network."), + .off = offsetof(mpegts_network_t, mn_bouquet), + .notify = mpegts_network_class_notify_bouquet, + }, + + {.type = PT_BOOL, + .id = "skipinitscan", + .name = N_("Skip startup scan"), + .desc = N_("Skip scanning known muxes when Tvheadend starts. " + "If \"startup scan\" is allowed and new muxes are " + "found then they will still be scanned. See Help for " + "more details."), + .off = offsetof(mpegts_network_t, mn_skipinitscan), + .opts = PO_EXPERT, + .def.i = 1}, + { + .type = PT_BOOL, + .id = "idlescan", + .name = N_("Idle scan muxes"), + .desc = N_("When nothing else is happening Tvheadend will " + "continuously rotate among all muxes and tune to " + "them to verify that they are still working when " + "the inputs are not used for streaming. If your " + "adapters have problems with lots of (endless) " + "tuning, disable this. Note that this option " + "should be OFF for the normal operation. This type " + "of mux probing is not required and it may cause " + "issues for SAT>IP (limited number of PID filters)."), + .off = offsetof(mpegts_network_t, mn_idlescan), + .def.i = 0, + .notify = mpegts_network_class_idlescan_notify, + .opts = PO_EXPERT | PO_HIDDEN, + }, + { + .type = PT_BOOL, + .id = "sid_chnum", + .name = N_("Use service IDs as channel numbers"), + .desc = N_("Use the provider's service IDs as channel numbers."), + .off = offsetof(mpegts_network_t, mn_sid_chnum), + .opts = PO_EXPERT, + .def.i = 0, + }, + { + .type = PT_BOOL, + .id = "ignore_chnum", + .name = N_("Ignore provider's channel numbers"), + .desc = N_("Don't use the provider's channel numbers."), + .off = offsetof(mpegts_network_t, mn_ignore_chnum), + .opts = PO_ADVANCED, + .def.i = 0, + }, #if ENABLE_SATIP_SERVER - { - .type = PT_U16, - .id = "satip_source", - .name = N_("SAT>IP source number"), - .desc = N_("The SAT>IP source number."), - .off = offsetof(mpegts_network_t, mn_satip_source), - .opts = PO_ADVANCED - }, + {.type = PT_U16, + .id = "satip_source", + .name = N_("SAT>IP source number"), + .desc = N_("The SAT>IP source number."), + .off = offsetof(mpegts_network_t, mn_satip_source), + .opts = PO_ADVANCED}, #endif - { - .type = PT_STR, - .id = "charset", - .name = N_("Character set"), - .desc = N_("The character encoding for this network " - "(e.g. UTF-8)."), - .off = offsetof(mpegts_network_t, mn_charset), - .list = dvb_charset_enum, - .opts = PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_INT, - .id = "localtime", - .name = N_("EIT time offset"), - .desc = N_("Select the time offset for EIT events."), - .off = offsetof(mpegts_network_t, mn_localtime), - .list = dvb_timezone_enum, - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_INT, - .id = "num_mux", - .name = N_("# Muxes"), - .desc = N_("Total number of muxes found on this network."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = mpegts_network_class_get_num_mux, - }, - { - .type = PT_INT, - .id = "num_svc", - .name = N_("# Services"), - .desc = N_("Total number of services found on this network."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = mpegts_network_class_get_num_svc, - }, - { - .type = PT_INT, - .id = "num_chn", - .name = N_("# Mapped channels"), - .desc = N_("Total number of mapped channels on this network."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = mpegts_network_class_get_num_chn, - }, - { - .type = PT_INT, - .id = "scanq_length", - .name = N_("Scan queue length"), - .desc = N_("The number of muxes left to scan on this network."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = mpegts_network_class_get_scanq_length, - }, - { - .type = PT_BOOL, - .id = "wizard", - .name = N_("Wizard"), - .off = offsetof(mpegts_network_t, mn_wizard), - .opts = PO_NOUI - }, - {} - } -}; + { + .type = PT_STR, + .id = "charset", + .name = N_("Character set"), + .desc = N_("The character encoding for this network " + "(e.g. UTF-8)."), + .off = offsetof(mpegts_network_t, mn_charset), + .list = dvb_charset_enum, + .opts = PO_ADVANCED | PO_DOC_NLIST, + }, + { + .type = PT_INT, + .id = "localtime", + .name = N_("EIT time offset"), + .desc = N_("Select the time offset for EIT events."), + .off = offsetof(mpegts_network_t, mn_localtime), + .list = dvb_timezone_enum, + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_INT, + .id = "num_mux", + .name = N_("# Muxes"), + .desc = N_("Total number of muxes found on this network."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = mpegts_network_class_get_num_mux, + }, + { + .type = PT_INT, + .id = "num_svc", + .name = N_("# Services"), + .desc = N_("Total number of services found on this network."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = mpegts_network_class_get_num_svc, + }, + { + .type = PT_INT, + .id = "num_chn", + .name = N_("# Mapped channels"), + .desc = N_("Total number of mapped channels on this network."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = mpegts_network_class_get_num_chn, + }, + { + .type = PT_INT, + .id = "scanq_length", + .name = N_("Scan queue length"), + .desc = N_("The number of muxes left to scan on this network."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = mpegts_network_class_get_scanq_length, + }, + {.type = PT_BOOL, + .id = "wizard", + .name = N_("Wizard"), + .off = offsetof(mpegts_network_t, mn_wizard), + .opts = PO_NOUI}, + {}}}; /* **************************************************************************** * Class methods * ***************************************************************************/ -static void -mpegts_network_display_name - ( mpegts_network_t *mn, char *buf, size_t len ) -{ +static void mpegts_network_display_name(mpegts_network_t* mn, char* buf, size_t len) { strlcpy(buf, tvh_str_default(mn->mn_network_name, "unknown"), len); } -static bouquet_t * -mpegts_network_bouquet_get (mpegts_network_t *mn, int create) -{ +static bouquet_t* mpegts_network_bouquet_get(mpegts_network_t* mn, int create) { char buf[128]; if (mn->mn_bouquet_source(mn, buf, sizeof(buf))) return NULL; return bouquet_find_by_source(mn->mn_network_name, buf, create); } -static void -mpegts_network_bouquet_update(void *aux) -{ - mpegts_network_t *mn = aux; - mpegts_mux_t *mm; - mpegts_service_t *ms; - int64_t chnum; - char buf[128]; - uint32_t seen = 0; - bouquet_t *bq = mn->mn_bouquet ? mpegts_network_bouquet_get(mn, 1) : NULL; +static void mpegts_network_bouquet_update(void* aux) { + mpegts_network_t* mn = aux; + mpegts_mux_t* mm; + mpegts_service_t* ms; + int64_t chnum; + char buf[128]; + uint32_t seen = 0; + bouquet_t* bq = mn->mn_bouquet ? mpegts_network_bouquet_get(mn, 1) : NULL; if (bq == NULL) return; if (!mn->mn_bouquet_comment(mn, buf, sizeof(buf))) bouquet_change_comment(bq, buf, 1); - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) - LIST_FOREACH(ms, &mm->mm_services, s_dvb_mux_link) { - chnum = ms->s_channel_number((service_t *)ms); - bouquet_add_service(bq, (service_t *)ms, chnum, NULL); + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) + LIST_FOREACH (ms, &mm->mm_services, s_dvb_mux_link) { + chnum = ms->s_channel_number((service_t*)ms); + bouquet_add_service(bq, (service_t*)ms, chnum, NULL); seen++; } bouquet_completed(bq, seen); } -void -mpegts_network_bouquet_trigger0(mpegts_network_t *mn, int timeout) -{ - mtimer_arm_rel(&mn->mn_bouquet_timer, mpegts_network_bouquet_update, - mn, sec2mono(timeout)); +void mpegts_network_bouquet_trigger0(mpegts_network_t* mn, int timeout) { + mtimer_arm_rel(&mn->mn_bouquet_timer, mpegts_network_bouquet_update, mn, sec2mono(timeout)); } -static int -mpegts_network_bouquet_source - ( mpegts_network_t *mn, char *source, size_t len) -{ +static int mpegts_network_bouquet_source(mpegts_network_t* mn, char* source, size_t len) { char ubuf[UUID_HEX_SIZE]; - snprintf(source, len, "mpegts-network://%s", - idnode_uuid_as_str(&mn->mn_id, ubuf)); + snprintf(source, len, "mpegts-network://%s", idnode_uuid_as_str(&mn->mn_id, ubuf)); return 0; } -static int -mpegts_network_bouquet_comment - ( mpegts_network_t *mn, char *comment, size_t len) -{ +static int mpegts_network_bouquet_comment(mpegts_network_t* mn, char* comment, size_t len) { if (tvh_str_default(mn->mn_provider_network_name, NULL) == NULL) return -1; snprintf(comment, len, "%s", mn->mn_provider_network_name); return 0; } -static htsmsg_t * -mpegts_network_config_save - ( mpegts_network_t *mn, char *filename, size_t size ) -{ +static htsmsg_t* mpegts_network_config_save(mpegts_network_t* mn, char* filename, size_t size) { // Nothing - leave to child classes return NULL; } -static mpegts_mux_t * -mpegts_network_create_mux - ( mpegts_network_t *mn, void *origin, uint32_t sid, uint32_t tsid, - void *aux, int force ) -{ +static mpegts_mux_t* mpegts_network_create_mux(mpegts_network_t* mn, + void* origin, + uint32_t sid, + uint32_t tsid, + void* aux, + int force) { return NULL; } -static mpegts_service_t * -mpegts_network_create_service - ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid ) -{ +static mpegts_service_t* +mpegts_network_create_service(mpegts_mux_t* mm, uint16_t sid, uint16_t pmt_pid) { return NULL; } -static const idclass_t * -mpegts_network_mux_class - ( mpegts_network_t *mn ) -{ +static const idclass_t* mpegts_network_mux_class(mpegts_network_t* mn) { extern const idclass_t mpegts_mux_class; return &mpegts_mux_class; } -static mpegts_mux_t * -mpegts_network_mux_create2 - ( mpegts_network_t *mn, htsmsg_t *conf ) -{ +static mpegts_mux_t* mpegts_network_mux_create2(mpegts_network_t* mn, htsmsg_t* conf) { return NULL; } -void -mpegts_network_scan ( mpegts_network_t *mn ) -{ - mpegts_mux_t *mm; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) +void mpegts_network_scan(mpegts_network_t* mn) { + mpegts_mux_t* mm; + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) mpegts_mux_scan_state_set(mm, MM_SCAN_STATE_PEND); } -static void -mpegts_network_link_delete ( mpegts_network_link_t *mnl ) -{ +static void mpegts_network_link_delete(mpegts_network_link_t* mnl) { idnode_notify_changed(&mnl->mnl_input->ti_id); LIST_REMOVE(mnl, mnl_mn_link); LIST_REMOVE(mnl, mnl_mi_link); free(mnl); } -void -mpegts_network_delete - ( mpegts_network_t *mn, int delconf ) -{ - mpegts_mux_t *mm; - mpegts_network_link_t *mnl; +void mpegts_network_delete(mpegts_network_t* mn, int delconf) { + mpegts_mux_t* mm; + mpegts_network_link_t* mnl; idnode_save_check(&mn->mn_id, delconf); @@ -526,11 +458,11 @@ mpegts_network_delete mpegts_network_list_t mpegts_network_all; -mpegts_network_t * -mpegts_network_create0 - ( mpegts_network_t *mn, const idclass_t *idc, const char *uuid, - const char *netname, htsmsg_t *conf ) -{ +mpegts_network_t* mpegts_network_create0(mpegts_network_t* mn, + const idclass_t* idc, + const char* uuid, + const char* netname, + htsmsg_t* conf) { char buf[256]; /* Setup idnode */ @@ -542,16 +474,16 @@ mpegts_network_create0 } /* Default callbacks */ - mn->mn_display_name = mpegts_network_display_name; - mn->mn_bouquet_source = mpegts_network_bouquet_source; - mn->mn_bouquet_comment= mpegts_network_bouquet_comment; - mn->mn_config_save = mpegts_network_config_save; - mn->mn_create_mux = mpegts_network_create_mux; - mn->mn_create_service = mpegts_network_create_service; - mn->mn_mux_class = mpegts_network_mux_class; - mn->mn_mux_create2 = mpegts_network_mux_create2; - mn->mn_scan = mpegts_network_scan; - mn->mn_delete = mpegts_network_delete; + mn->mn_display_name = mpegts_network_display_name; + mn->mn_bouquet_source = mpegts_network_bouquet_source; + mn->mn_bouquet_comment = mpegts_network_bouquet_comment; + mn->mn_config_save = mpegts_network_config_save; + mn->mn_create_mux = mpegts_network_create_mux; + mn->mn_create_service = mpegts_network_create_service; + mn->mn_mux_class = mpegts_network_mux_class; + mn->mn_mux_create2 = mpegts_network_mux_create2; + mn->mn_scan = mpegts_network_scan; + mn->mn_delete = mpegts_network_delete; /* Add to global list */ LIST_INSERT_HEAD(&mpegts_network_all, mn, mn_global_link); @@ -563,9 +495,9 @@ mpegts_network_create0 mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, 0); /* Defaults */ - mn->mn_enabled = 1; - mn->mn_satpos = INT_MAX; - mn->mn_skipinitscan = 1; + mn->mn_enabled = 1; + mn->mn_satpos = INT_MAX; + mn->mn_skipinitscan = 1; mn->mn_autodiscovery = MN_DISCOVERY_NEW; /* Load config */ @@ -573,16 +505,15 @@ mpegts_network_create0 idnode_load(&mn->mn_id, conf); /* Name */ - if (netname) mn->mn_network_name = strdup(netname); + if (netname) + mn->mn_network_name = strdup(netname); mn->mn_display_name(mn, buf, sizeof(buf)); tvhtrace(LS_MPEGTS, "created network %s", buf); return mn; } -void -mpegts_network_class_delete(const idclass_t *idc, int delconf) -{ +void mpegts_network_class_delete(const idclass_t* idc, int delconf) { mpegts_network_t *mn, *n; for (mn = LIST_FIRST(&mpegts_network_all); mn != NULL; mn = n) { @@ -592,10 +523,7 @@ mpegts_network_class_delete(const idclass_t *idc, int delconf) } } -int -mpegts_network_set_nid - ( mpegts_network_t *mn, uint16_t nid ) -{ +int mpegts_network_set_nid(mpegts_network_t* mn, uint16_t nid) { char buf[256]; if (mn->mn_nid == nid) return 0; @@ -605,12 +533,9 @@ mpegts_network_set_nid return 1; } -int -mpegts_network_set_network_name - ( mpegts_network_t *mn, const char *name ) -{ +int mpegts_network_set_network_name(mpegts_network_t* mn, const char* name) { char buf[256]; - int save = 0; + int save = 0; if (tvh_str_default(mn->mn_network_name, NULL) == NULL) { if (name && name[0] && strcmp(name, mn->mn_network_name ?: "")) { tvh_str_update(&mn->mn_network_name, name); @@ -626,10 +551,8 @@ mpegts_network_set_network_name return save; } -void -mpegts_network_get_type_str( mpegts_network_t *mn, char *buf, size_t buflen ) -{ - const char *s = "IPTV"; +void mpegts_network_get_type_str(mpegts_network_t* mn, char* buf, size_t buflen) { + const char* s = "IPTV"; #if ENABLE_MPEGTS_DVB dvb_fe_type_t ftype; ftype = dvb_fe_type_by_network_class(mn->mn_id.in_class); @@ -643,13 +566,12 @@ mpegts_network_get_type_str( mpegts_network_t *mn, char *buf, size_t buflen ) * Wizard *****************************************************************************/ -htsmsg_t * -mpegts_network_wizard_get - ( mpegts_input_t *mi, const idclass_t *idc, - mpegts_network_t *mn, const char *lang ) -{ +htsmsg_t* mpegts_network_wizard_get(mpegts_input_t* mi, + const idclass_t* idc, + mpegts_network_t* mn, + const char* lang) { htsmsg_t *m = htsmsg_create_map(), *l, *e; - char buf[256]; + char buf[256]; if (mi && idc) { mi->mi_display_name(mi, buf, sizeof(buf)); @@ -664,13 +586,10 @@ mpegts_network_wizard_get return m; } -void -mpegts_network_wizard_create - ( const char *clazz, htsmsg_t **nlist, const char *lang ) -{ - mpegts_network_t *mn; - mpegts_network_builder_t *mnb; - htsmsg_t *conf; +void mpegts_network_wizard_create(const char* clazz, htsmsg_t** nlist, const char* lang) { + mpegts_network_t* mn; + mpegts_network_builder_t* mnb; + htsmsg_t* conf; if (nlist) *nlist = NULL; @@ -680,7 +599,7 @@ mpegts_network_wizard_create return; /* only one network per type */ - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) if (mn->mn_id.in_class == mnb->idc && mn->mn_wizard) goto found; @@ -705,24 +624,18 @@ found: mpegts_network_builder_list_t mpegts_network_builders; -void -mpegts_network_register_builder - ( const idclass_t *idc, - mpegts_network_t *(*build) (const idclass_t *idc, htsmsg_t *conf) ) -{ - mpegts_network_builder_t *mnb = calloc(1, sizeof(mpegts_network_builder_t)); - mnb->idc = idc; - mnb->build = build; +void mpegts_network_register_builder(const idclass_t* idc, + mpegts_network_t* (*build)(const idclass_t* idc, htsmsg_t* conf)) { + mpegts_network_builder_t* mnb = calloc(1, sizeof(mpegts_network_builder_t)); + mnb->idc = idc; + mnb->build = build; LIST_INSERT_HEAD(&mpegts_network_builders, mnb, link); idclass_register(idc); } -void -mpegts_network_unregister_builder - ( const idclass_t *idc ) -{ - mpegts_network_builder_t *mnb; - LIST_FOREACH(mnb, &mpegts_network_builders, link) { +void mpegts_network_unregister_builder(const idclass_t* idc) { + mpegts_network_builder_t* mnb; + LIST_FOREACH (mnb, &mpegts_network_builders, link) { if (mnb->idc == idc) { LIST_REMOVE(mnb, link); free(mnb); @@ -731,25 +644,19 @@ mpegts_network_unregister_builder } } -mpegts_network_builder_t * -mpegts_network_builder_find - ( const char *clazz ) -{ - mpegts_network_builder_t *mnb; +mpegts_network_builder_t* mpegts_network_builder_find(const char* clazz) { + mpegts_network_builder_t* mnb; if (clazz == NULL) return NULL; - LIST_FOREACH(mnb, &mpegts_network_builders, link) { + LIST_FOREACH (mnb, &mpegts_network_builders, link) { if (!strcmp(mnb->idc->ic_class, clazz)) return mnb; } return NULL; } -mpegts_network_t * -mpegts_network_build - ( const char *clazz, htsmsg_t *conf ) -{ - mpegts_network_builder_t *mnb; +mpegts_network_t* mpegts_network_build(const char* clazz, htsmsg_t* conf) { + mpegts_network_builder_t* mnb; mnb = mpegts_network_builder_find(clazz); if (mnb) return mnb->build(mnb->idc, conf); @@ -760,14 +667,13 @@ mpegts_network_build * Search *****************************************************************************/ -mpegts_mux_t * -mpegts_network_find_mux - ( mpegts_network_t *mn, uint32_t onid, uint32_t tsid, int check ) -{ - mpegts_mux_t *mm; +mpegts_mux_t* +mpegts_network_find_mux(mpegts_network_t* mn, uint32_t onid, uint32_t tsid, int check) { + mpegts_mux_t* mm; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { - if (mm->mm_onid && onid && mm->mm_onid != onid) continue; + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) { + if (mm->mm_onid && onid && mm->mm_onid != onid) + continue; if (mm->mm_tsid == tsid) { if (!check || mm->mm_enabled == MM_ENABLE) break; @@ -776,19 +682,20 @@ mpegts_network_find_mux return mm; } -mpegts_service_t * -mpegts_network_find_active_service - ( mpegts_network_t *mn, uint16_t sid, mpegts_mux_t **rmm ) -{ - mpegts_mux_t *mm; - mpegts_service_t *s; +mpegts_service_t* +mpegts_network_find_active_service(mpegts_network_t* mn, uint16_t sid, mpegts_mux_t** rmm) { + mpegts_mux_t* mm; + mpegts_service_t* s; - if (!mn->mn_enabled) return NULL; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { - if (mm->mm_enabled != MM_ENABLE) continue; + if (!mn->mn_enabled) + return NULL; + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) { + if (mm->mm_enabled != MM_ENABLE) + continue; s = mpegts_mux_find_service(mm, sid); if (s && s->s_enabled) { - if (rmm) *rmm = mm; + if (rmm) + *rmm = mm; return s; } } diff --git a/src/input/mpegts/mpegts_network_dvb.c b/src/input/mpegts/mpegts_network_dvb.c index 07c8a1dcd..7b2b484f1 100644 --- a/src/input/mpegts/mpegts_network_dvb.c +++ b/src/input/mpegts/mpegts_network_dvb.c @@ -40,33 +40,26 @@ extern const idclass_t mpegts_network_class; -static void -dvb_network_class_delete ( idnode_t *in ) -{ - mpegts_network_t *mn = (mpegts_network_t*)in; - char ubuf[UUID_HEX_SIZE]; +static void dvb_network_class_delete(idnode_t* in) { + mpegts_network_t* mn = (mpegts_network_t*)in; + char ubuf[UUID_HEX_SIZE]; /* remove config */ - hts_settings_remove("input/dvb/networks/%s", - idnode_uuid_as_str(in, ubuf)); + hts_settings_remove("input/dvb/networks/%s", idnode_uuid_as_str(in, ubuf)); /* Parent delete */ mpegts_network_delete(mn, 1); } -static const void * -dvb_network_class_scanfile_get ( void *o ) -{ +static const void* dvb_network_class_scanfile_get(void* o) { prop_ptr = NULL; return &prop_ptr; } -void -dvb_network_scanfile_set ( dvb_network_t *ln, const char *id ) -{ - dvb_mux_conf_t *dmc; - scanfile_network_t *sfn; - dvb_mux_t *mm; +void dvb_network_scanfile_set(dvb_network_t* ln, const char* id) { + dvb_mux_conf_t* dmc; + scanfile_network_t* sfn; + dvb_mux_t* mm; /* Find */ if (!id) @@ -79,12 +72,11 @@ dvb_network_scanfile_set ( dvb_network_t *ln, const char *id ) ln->mn_satpos = sfn->sfn_satpos; /* Create */ - LIST_FOREACH(dmc, &sfn->sfn_muxes, dmc_link) { + LIST_FOREACH (dmc, &sfn->sfn_muxes, dmc_link) { if (!(mm = dvb_network_find_mux(ln, dmc, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, 0, 0))) { - mm = dvb_mux_create0(ln, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, - dmc, NULL, NULL); + mm = dvb_mux_create0(ln, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, dmc, NULL, NULL); if (mm) { - mpegts_mux_post_create((mpegts_mux_t *)mm); + mpegts_mux_post_create((mpegts_mux_t*)mm); idnode_changed(&mm->mm_id); } if (tvhtrace_enabled()) { @@ -97,7 +89,7 @@ dvb_network_scanfile_set ( dvb_network_t *ln, const char *id ) char buf[128]; dvb_mux_conf_str(dmc, buf, sizeof(buf)); tvhtrace(LS_SCANFILE, "mux %p skipped %s in network %s", mm, buf, ln->mn_network_name); - dvb_mux_conf_str(&((dvb_mux_t *)mm)->lm_tuning, buf, sizeof(buf)); + dvb_mux_conf_str(&((dvb_mux_t*)mm)->lm_tuning, buf, sizeof(buf)); tvhtrace(LS_SCANFILE, "mux %p exists %s in network %s", mm, buf, ln->mn_network_name); } } @@ -106,18 +98,14 @@ dvb_network_scanfile_set ( dvb_network_t *ln, const char *id ) return; } -static int -dvb_network_class_scanfile_set ( void *o, const void *s ) -{ +static int dvb_network_class_scanfile_set(void* o, const void* s) { dvb_network_scanfile_set(o, s); return 0; } -static htsmsg_t * -dvb_network_class_scanfile_list0 -( const idclass_t *clazz, dvb_network_t *ln, const char *lang ) -{ - const char *type; +static htsmsg_t* +dvb_network_class_scanfile_list0(const idclass_t* clazz, dvb_network_t* ln, const char* lang) { + const char* type; if (clazz == NULL) return NULL; @@ -155,20 +143,16 @@ dvb_network_class_scanfile_list0 return m; } -htsmsg_t * -dvb_network_class_scanfile_list ( void *o, const char *lang ) -{ +htsmsg_t* dvb_network_class_scanfile_list(void* o, const char* lang) { if (o == NULL) return NULL; - return dvb_network_class_scanfile_list0(((mpegts_network_t *)o)->mn_id.in_class, o, lang); + return dvb_network_class_scanfile_list0(((mpegts_network_t*)o)->mn_id.in_class, o, lang); } -#define SCANFILE_LIST(name) \ -static htsmsg_t * \ -dvb_network_class_scanfile_list_##name ( void *o, const char *lang ) \ -{ \ - return dvb_network_class_scanfile_list0(&dvb_network_##name##_class, o, lang); \ -} +#define SCANFILE_LIST(name) \ + static htsmsg_t* dvb_network_class_scanfile_list_##name(void* o, const char* lang) { \ + return dvb_network_class_scanfile_list0(&dvb_network_##name##_class, o, lang); \ + } SCANFILE_LIST(dvbt); SCANFILE_LIST(dvbc); @@ -181,21 +165,17 @@ SCANFILE_LIST(isdb_s); SCANFILE_LIST(dtmb); SCANFILE_LIST(dab); -static const void * -dvb_network_class_orbital_pos_get ( void *o ) -{ - dvb_network_t *ln = o; - prop_sbuf[0] = '\0'; +static const void* dvb_network_class_orbital_pos_get(void* o) { + dvb_network_t* ln = o; + prop_sbuf[0] = '\0'; if (ln->mn_satpos != INT_MAX) dvb_sat_position_to_str(ln->mn_satpos, prop_sbuf, PROP_SBUF_LEN); return &prop_sbuf_ptr; } -static int -dvb_network_class_orbital_pos_set ( void *o, const void *s ) -{ - dvb_network_t *ln = o; - int satpos; +static int dvb_network_class_orbital_pos_set(void* o, const void* s) { + dvb_network_t* ln = o; + int satpos; /* Find */ if (!s) @@ -210,9 +190,7 @@ dvb_network_class_orbital_pos_set ( void *o, const void *s ) return 0; } -static htsmsg_t * -dvb_network_class_orbital_pos_list ( void *o, const char *lang ) -{ +static htsmsg_t* dvb_network_class_orbital_pos_list(void* o, const char* lang) { htsmsg_t *e, *m = htsmsg_create_map(); htsmsg_add_str(m, "type", "api"); htsmsg_add_str(m, "uri", "dvb/orbitalpos/list"); @@ -224,305 +202,249 @@ dvb_network_class_orbital_pos_list ( void *o, const char *lang ) PROP_DOC(predefinedmuxlist) -const idclass_t dvb_network_class = -{ - .ic_super = &mpegts_network_class, - .ic_class = "dvb_network", - .ic_caption = N_("LinuxDVB network"), - .ic_delete = dvb_network_class_delete, - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t dvb_network_dvbt_class = -{ - .ic_super = &dvb_network_class, - .ic_class = "dvb_network_dvbt", - .ic_caption = N_("DVB-T Network"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "scanfile", - .name = N_("Pre-defined muxes"), - .desc = N_("Use a pre-defined list of DVB-T muxes. " - "Note: these lists can sometimes be outdated and " - "may cause scanning to take longer than usual."), - .doc = prop_doc_predefinedmuxlist, - .set = dvb_network_class_scanfile_set, - .get = dvb_network_class_scanfile_get, - .list = dvb_network_class_scanfile_list_dvbt, - .opts = PO_NOSAVE, - }, - {} - } -}; - -const idclass_t dvb_network_dvbc_class = -{ - .ic_super = &dvb_network_class, - .ic_class = "dvb_network_dvbc", - .ic_caption = N_("DVB-C Network"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "scanfile", - .name = N_("Pre-defined muxes"), - .desc = N_("Use a pre-defined list of DVB-C muxes. " - "Note: these lists can sometimes be outdated and " - "may cause scanning to take longer than usual."), - .doc = prop_doc_predefinedmuxlist, - .set = dvb_network_class_scanfile_set, - .get = dvb_network_class_scanfile_get, - .list = dvb_network_class_scanfile_list_dvbc, - .opts = PO_NOSAVE, - }, - {} - } -}; - -const idclass_t dvb_network_dvbs_class = -{ - .ic_super = &dvb_network_class, - .ic_class = "dvb_network_dvbs", - .ic_caption = N_("DVB-S Network"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "scanfile", - .name = N_("Pre-defined muxes"), - .desc = N_("Use a pre-defined list of DVB-S/S2 muxes. " - "Note: these lists can sometimes be outdated and " - "may cause scanning to take longer than usual."), - .doc = prop_doc_predefinedmuxlist, - .set = dvb_network_class_scanfile_set, - .get = dvb_network_class_scanfile_get, - .list = dvb_network_class_scanfile_list_dvbs, - .opts = PO_NOSAVE, - }, - { - .type = PT_STR, - .id = "orbital_pos", - .name = N_("Orbital position"), - .desc = N_("The orbital position of the satellite " - "your dish is pointing at."), - .set = dvb_network_class_orbital_pos_set, - .get = dvb_network_class_orbital_pos_get, - .list = dvb_network_class_orbital_pos_list, - }, - {} - } -}; - -const idclass_t dvb_network_atsc_t_class = -{ - .ic_super = &dvb_network_class, - .ic_class = "dvb_network_atsc_t", - .ic_caption = N_("ATSC-T Network"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "scanfile", - .name = N_("Pre-defined muxes"), - .desc = N_("Use a pre-defined list of ATSC-T muxes. " - "Note: these lists can sometimes be outdated and " - "may cause scanning to take longer than usual."), - .doc = prop_doc_predefinedmuxlist, - .set = dvb_network_class_scanfile_set, - .get = dvb_network_class_scanfile_get, - .list = dvb_network_class_scanfile_list_atsc_t, - .opts = PO_NOSAVE, - }, - {} - } -}; - -const idclass_t dvb_network_atsc_c_class = -{ - .ic_super = &dvb_network_class, - .ic_class = "dvb_network_atsc_c", - .ic_caption = N_("ATSC-C Network"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "scanfile", - .name = N_("Pre-defined muxes"), - .desc = N_("Use a pre-defined list of ATSC-C muxes. " - "Note: these lists can sometimes be outdated and " - "may cause scanning to take longer than usual."), - .doc = prop_doc_predefinedmuxlist, - .set = dvb_network_class_scanfile_set, - .get = dvb_network_class_scanfile_get, - .list = dvb_network_class_scanfile_list_atsc_c, - .opts = PO_NOSAVE, - }, - {} - } -}; - -const idclass_t dvb_network_cablecard_class = -{ - .ic_super = &dvb_network_class, - .ic_class = "dvb_network_cablecard", - .ic_caption = N_("CableCARD Network"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t dvb_network_isdb_t_class = -{ - .ic_super = &dvb_network_class, - .ic_class = "dvb_network_isdb_t", - .ic_caption = N_("ISDB-T Network"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "scanfile", - .name = N_("Pre-defined muxes"), - .desc = N_("Use a pre-defined list of ISDB-T muxes. " - "Note: these lists can sometimes be outdated and " - "may cause scanning to take longer than usual."), - .doc = prop_doc_predefinedmuxlist, - .set = dvb_network_class_scanfile_set, - .get = dvb_network_class_scanfile_get, - .list = dvb_network_class_scanfile_list_isdb_t, - .opts = PO_NOSAVE, - }, - {} - } -}; - -const idclass_t dvb_network_isdb_c_class = -{ - .ic_super = &dvb_network_class, - .ic_class = "dvb_network_isdb_c", - .ic_caption = N_("ISDB-C Network"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "scanfile", - .name = N_("Pre-defined muxes"), - .desc = N_("Use a pre-defined list of ISDB-C muxes. " - "Note: these lists can sometimes be outdated and " - "may cause scanning to take longer than usual."), - .doc = prop_doc_predefinedmuxlist, - .set = dvb_network_class_scanfile_set, - .get = dvb_network_class_scanfile_get, - .list = dvb_network_class_scanfile_list_isdb_c, - .opts = PO_NOSAVE, - }, - {} - } -}; - -const idclass_t dvb_network_isdb_s_class = -{ - .ic_super = &dvb_network_class, - .ic_class = "dvb_network_isdb_s", - .ic_caption = N_("ISDB-S Network"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "scanfile", - .name = N_("Pre-defined muxes"), - .desc = N_("Use a pre-defined list of ISDB-S muxes. " - "Note: these lists can sometimes be outdated and " - "may cause scanning to take longer than usual."), - .doc = prop_doc_predefinedmuxlist, - .set = dvb_network_class_scanfile_set, - .get = dvb_network_class_scanfile_get, - .list = dvb_network_class_scanfile_list_isdb_s, - .opts = PO_NOSAVE, - }, - {} - } -}; - -const idclass_t dvb_network_dtmb_class = -{ - .ic_super = &dvb_network_class, - .ic_class = "dvb_network_dtmb", - .ic_caption = N_("DTMB Network"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "scanfile", - .name = N_("Pre-defined muxes"), - .desc = N_("Use a pre-defined list of DTMB muxes. " - "Note: these lists can sometimes be outdated and " - "may cause scanning to take longer than usual."), - .doc = prop_doc_predefinedmuxlist, - .set = dvb_network_class_scanfile_set, - .get = dvb_network_class_scanfile_get, - .list = dvb_network_class_scanfile_list_dtmb, - .opts = PO_NOSAVE, - }, - {} - } -}; - -const idclass_t dvb_network_dab_class = -{ - .ic_super = &dvb_network_class, - .ic_class = "dvb_network_dab", - .ic_caption = N_("DAB Network"), - .ic_properties = (const property_t[]) { - { - .type = PT_STR, - .id = "scanfile", - .name = N_("Pre-defined muxes"), - .desc = N_("Use a pre-defined list of DAB muxes. " - "Note: these lists can sometimes be outdated and " - "may cause scanning to take longer than usual."), - .doc = prop_doc_predefinedmuxlist, - .set = dvb_network_class_scanfile_set, - .get = dvb_network_class_scanfile_get, - .list = dvb_network_class_scanfile_list_dab, - .opts = PO_NOSAVE, - }, - {} - } -}; +const idclass_t dvb_network_class = {.ic_super = &mpegts_network_class, + .ic_class = "dvb_network", + .ic_caption = N_("LinuxDVB network"), + .ic_delete = dvb_network_class_delete, + .ic_properties = (const property_t[]){{}}}; + +const idclass_t dvb_network_dvbt_class = {.ic_super = &dvb_network_class, + .ic_class = "dvb_network_dvbt", + .ic_caption = N_("DVB-T Network"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "scanfile", + .name = N_("Pre-defined muxes"), + .desc = N_("Use a pre-defined list of DVB-T muxes. " + "Note: these lists can sometimes be outdated and " + "may cause scanning to take longer than usual."), + .doc = prop_doc_predefinedmuxlist, + .set = dvb_network_class_scanfile_set, + .get = dvb_network_class_scanfile_get, + .list = dvb_network_class_scanfile_list_dvbt, + .opts = PO_NOSAVE, + }, + {}}}; + +const idclass_t dvb_network_dvbc_class = {.ic_super = &dvb_network_class, + .ic_class = "dvb_network_dvbc", + .ic_caption = N_("DVB-C Network"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "scanfile", + .name = N_("Pre-defined muxes"), + .desc = N_("Use a pre-defined list of DVB-C muxes. " + "Note: these lists can sometimes be outdated and " + "may cause scanning to take longer than usual."), + .doc = prop_doc_predefinedmuxlist, + .set = dvb_network_class_scanfile_set, + .get = dvb_network_class_scanfile_get, + .list = dvb_network_class_scanfile_list_dvbc, + .opts = PO_NOSAVE, + }, + {}}}; + +const idclass_t dvb_network_dvbs_class = {.ic_super = &dvb_network_class, + .ic_class = "dvb_network_dvbs", + .ic_caption = N_("DVB-S Network"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "scanfile", + .name = N_("Pre-defined muxes"), + .desc = N_("Use a pre-defined list of DVB-S/S2 muxes. " + "Note: these lists can sometimes be outdated and " + "may cause scanning to take longer than usual."), + .doc = prop_doc_predefinedmuxlist, + .set = dvb_network_class_scanfile_set, + .get = dvb_network_class_scanfile_get, + .list = dvb_network_class_scanfile_list_dvbs, + .opts = PO_NOSAVE, + }, + { + .type = PT_STR, + .id = "orbital_pos", + .name = N_("Orbital position"), + .desc = N_("The orbital position of the satellite " + "your dish is pointing at."), + .set = dvb_network_class_orbital_pos_set, + .get = dvb_network_class_orbital_pos_get, + .list = dvb_network_class_orbital_pos_list, + }, + {}}}; + +const idclass_t dvb_network_atsc_t_class = {.ic_super = &dvb_network_class, + .ic_class = "dvb_network_atsc_t", + .ic_caption = N_("ATSC-T Network"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "scanfile", + .name = N_("Pre-defined muxes"), + .desc = N_("Use a pre-defined list of ATSC-T muxes. " + "Note: these lists can sometimes be outdated and " + "may cause scanning to take longer than usual."), + .doc = prop_doc_predefinedmuxlist, + .set = dvb_network_class_scanfile_set, + .get = dvb_network_class_scanfile_get, + .list = dvb_network_class_scanfile_list_atsc_t, + .opts = PO_NOSAVE, + }, + {}}}; + +const idclass_t dvb_network_atsc_c_class = {.ic_super = &dvb_network_class, + .ic_class = "dvb_network_atsc_c", + .ic_caption = N_("ATSC-C Network"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "scanfile", + .name = N_("Pre-defined muxes"), + .desc = N_("Use a pre-defined list of ATSC-C muxes. " + "Note: these lists can sometimes be outdated and " + "may cause scanning to take longer than usual."), + .doc = prop_doc_predefinedmuxlist, + .set = dvb_network_class_scanfile_set, + .get = dvb_network_class_scanfile_get, + .list = dvb_network_class_scanfile_list_atsc_c, + .opts = PO_NOSAVE, + }, + {}}}; + +const idclass_t dvb_network_cablecard_class = {.ic_super = &dvb_network_class, + .ic_class = "dvb_network_cablecard", + .ic_caption = N_("CableCARD Network"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t dvb_network_isdb_t_class = {.ic_super = &dvb_network_class, + .ic_class = "dvb_network_isdb_t", + .ic_caption = N_("ISDB-T Network"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "scanfile", + .name = N_("Pre-defined muxes"), + .desc = N_("Use a pre-defined list of ISDB-T muxes. " + "Note: these lists can sometimes be outdated and " + "may cause scanning to take longer than usual."), + .doc = prop_doc_predefinedmuxlist, + .set = dvb_network_class_scanfile_set, + .get = dvb_network_class_scanfile_get, + .list = dvb_network_class_scanfile_list_isdb_t, + .opts = PO_NOSAVE, + }, + {}}}; + +const idclass_t dvb_network_isdb_c_class = {.ic_super = &dvb_network_class, + .ic_class = "dvb_network_isdb_c", + .ic_caption = N_("ISDB-C Network"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "scanfile", + .name = N_("Pre-defined muxes"), + .desc = N_("Use a pre-defined list of ISDB-C muxes. " + "Note: these lists can sometimes be outdated and " + "may cause scanning to take longer than usual."), + .doc = prop_doc_predefinedmuxlist, + .set = dvb_network_class_scanfile_set, + .get = dvb_network_class_scanfile_get, + .list = dvb_network_class_scanfile_list_isdb_c, + .opts = PO_NOSAVE, + }, + {}}}; + +const idclass_t dvb_network_isdb_s_class = {.ic_super = &dvb_network_class, + .ic_class = "dvb_network_isdb_s", + .ic_caption = N_("ISDB-S Network"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "scanfile", + .name = N_("Pre-defined muxes"), + .desc = N_("Use a pre-defined list of ISDB-S muxes. " + "Note: these lists can sometimes be outdated and " + "may cause scanning to take longer than usual."), + .doc = prop_doc_predefinedmuxlist, + .set = dvb_network_class_scanfile_set, + .get = dvb_network_class_scanfile_get, + .list = dvb_network_class_scanfile_list_isdb_s, + .opts = PO_NOSAVE, + }, + {}}}; + +const idclass_t dvb_network_dtmb_class = {.ic_super = &dvb_network_class, + .ic_class = "dvb_network_dtmb", + .ic_caption = N_("DTMB Network"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "scanfile", + .name = N_("Pre-defined muxes"), + .desc = N_("Use a pre-defined list of DTMB muxes. " + "Note: these lists can sometimes be outdated and " + "may cause scanning to take longer than usual."), + .doc = prop_doc_predefinedmuxlist, + .set = dvb_network_class_scanfile_set, + .get = dvb_network_class_scanfile_get, + .list = dvb_network_class_scanfile_list_dtmb, + .opts = PO_NOSAVE, + }, + {}}}; + +const idclass_t dvb_network_dab_class = {.ic_super = &dvb_network_class, + .ic_class = "dvb_network_dab", + .ic_caption = N_("DAB Network"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "scanfile", + .name = N_("Pre-defined muxes"), + .desc = N_("Use a pre-defined list of DAB muxes. " + "Note: these lists can sometimes be outdated and " + "may cause scanning to take longer than usual."), + .doc = prop_doc_predefinedmuxlist, + .set = dvb_network_class_scanfile_set, + .get = dvb_network_class_scanfile_get, + .list = dvb_network_class_scanfile_list_dab, + .opts = PO_NOSAVE, + }, + {}}}; /* **************************************************************************** * Class methods * ***************************************************************************/ -static int -dvb_network_check_bandwidth( int bw1, int bw2 ) -{ - if (bw1 == DVB_BANDWIDTH_NONE || bw1 == DVB_BANDWIDTH_AUTO || - bw2 == DVB_BANDWIDTH_NONE || bw2 == DVB_BANDWIDTH_AUTO) +static int dvb_network_check_bandwidth(int bw1, int bw2) { + if (bw1 == DVB_BANDWIDTH_NONE || bw1 == DVB_BANDWIDTH_AUTO || bw2 == DVB_BANDWIDTH_NONE || + bw2 == DVB_BANDWIDTH_AUTO) return 0; return bw1 != bw2; } -static int -dvb_network_check_symbol_rate( dvb_mux_t *lm, dvb_mux_conf_t *dmc, int deltar ) -{ +static int dvb_network_check_symbol_rate(dvb_mux_t* lm, dvb_mux_conf_t* dmc, int deltar) { switch (dmc->dmc_fe_type) { - case DVB_TYPE_T: - case DVB_TYPE_DTMB: - return dvb_network_check_bandwidth(lm->lm_tuning.u.dmc_fe_ofdm.bandwidth, - dmc->u.dmc_fe_ofdm.bandwidth); - case DVB_TYPE_C: - case DVB_TYPE_ATSC_C: - return deltaU32(lm->lm_tuning.u.dmc_fe_qam.symbol_rate, - dmc->u.dmc_fe_qam.symbol_rate) > deltar; - case DVB_TYPE_S: - return deltaU32(lm->lm_tuning.u.dmc_fe_qpsk.symbol_rate, - dmc->u.dmc_fe_qpsk.symbol_rate) > deltar; - case DVB_TYPE_ATSC_T: - return 0; - default: - return 0; + case DVB_TYPE_T: + case DVB_TYPE_DTMB: + return dvb_network_check_bandwidth(lm->lm_tuning.u.dmc_fe_ofdm.bandwidth, + dmc->u.dmc_fe_ofdm.bandwidth); + case DVB_TYPE_C: + case DVB_TYPE_ATSC_C: + return deltaU32(lm->lm_tuning.u.dmc_fe_qam.symbol_rate, dmc->u.dmc_fe_qam.symbol_rate) > + deltar; + case DVB_TYPE_S: + return deltaU32(lm->lm_tuning.u.dmc_fe_qpsk.symbol_rate, dmc->u.dmc_fe_qpsk.symbol_rate) > + deltar; + case DVB_TYPE_ATSC_T: + return 0; + default: + return 0; } } -static int -dvb_network_check_orbital_pos ( int satpos1, int satpos2 ) -{ +static int dvb_network_check_orbital_pos(int satpos1, int satpos2) { if (satpos1 != INT_MAX && satpos2 != INT_MAX) { /* 1W and 0.8W */ if (abs(satpos1 - satpos2) > 2) @@ -531,26 +453,31 @@ dvb_network_check_orbital_pos ( int satpos1, int satpos2 ) return 0; } -dvb_mux_t * -dvb_network_find_mux - ( dvb_network_t *ln, dvb_mux_conf_t *dmc, uint32_t onid, uint32_t tsid, int check, int approx_match ) -{ - int deltaf, deltar; +dvb_mux_t* dvb_network_find_mux(dvb_network_t* ln, + dvb_mux_conf_t* dmc, + uint32_t onid, + uint32_t tsid, + int check, + int approx_match) { + int deltaf, deltar; mpegts_mux_t *mm, *mm_alt = NULL; - LIST_FOREACH(mm, &ln->mn_muxes, mm_network_link) { + LIST_FOREACH (mm, &ln->mn_muxes, mm_network_link) { - if (check && mm->mm_enabled != MM_ENABLE) continue; + if (check && mm->mm_enabled != MM_ENABLE) + continue; - deltaf = 2000; // 2K/MHz - deltar = 1000; - dvb_mux_t *lm = (dvb_mux_t*)mm; + deltaf = 2000; // 2K/MHz + deltar = 1000; + dvb_mux_t* lm = (dvb_mux_t*)mm; /* Same FE type - this REALLY should match! */ - if (lm->lm_tuning.dmc_fe_type != dmc->dmc_fe_type) continue; + if (lm->lm_tuning.dmc_fe_type != dmc->dmc_fe_type) + continue; /* Also, the system type should match (DVB-S/DVB-S2) */ - if (!approx_match && (lm->lm_tuning.dmc_fe_delsys != dmc->dmc_fe_delsys)) continue; + if (!approx_match && (lm->lm_tuning.dmc_fe_delsys != dmc->dmc_fe_delsys)) + continue; /* if ONID/TSID are a perfect match (and this is DVB-S, allow greater deltaf) */ if (lm->lm_tuning.dmc_fe_type == DVB_TYPE_S) { @@ -569,13 +496,16 @@ dvb_network_find_mux } /* Reject if not same frequency (some tolerance due to changes and diff in NIT) */ - if (deltaU32(lm->lm_tuning.dmc_fe_freq, dmc->dmc_fe_freq) > deltaf) continue; + if (deltaU32(lm->lm_tuning.dmc_fe_freq, dmc->dmc_fe_freq) > deltaf) + continue; /* Reject if not same symbol rate (some tolerance due to changes and diff in NIT) */ - if (dvb_network_check_symbol_rate(lm, dmc, deltar)) continue; + if (dvb_network_check_symbol_rate(lm, dmc, deltar)) + continue; /* Reject if not same polarisation */ - if (lm->lm_tuning.u.dmc_fe_qpsk.polarisation != dmc->u.dmc_fe_qpsk.polarisation) continue; + if (lm->lm_tuning.u.dmc_fe_qpsk.polarisation != dmc->u.dmc_fe_qpsk.polarisation) + continue; /* DVB-S extra checks */ if (!approx_match && (lm->lm_tuning.dmc_fe_type == DVB_TYPE_S)) { @@ -583,24 +513,30 @@ dvb_network_find_mux /* Same modulation */ if (!dvb_modulation_is_none_or_auto(lm->lm_tuning.dmc_fe_modulation) && !dvb_modulation_is_none_or_auto(dmc->dmc_fe_modulation) && - lm->lm_tuning.dmc_fe_modulation != dmc->dmc_fe_modulation) continue; + lm->lm_tuning.dmc_fe_modulation != dmc->dmc_fe_modulation) + continue; /* Same FEC */ - if (lm->lm_tuning.u.dmc_fe_qpsk.fec_inner != dmc->u.dmc_fe_qpsk.fec_inner) continue; + if (lm->lm_tuning.u.dmc_fe_qpsk.fec_inner != dmc->u.dmc_fe_qpsk.fec_inner) + continue; /* Same orbital position */ if (dvb_network_check_orbital_pos(lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos, - dmc->u.dmc_fe_qpsk.orbital_pos)) continue; + dmc->u.dmc_fe_qpsk.orbital_pos)) + continue; } /* Same PLP/ISI */ - if (lm->lm_tuning.dmc_fe_stream_id != dmc->dmc_fe_stream_id) continue; + if (lm->lm_tuning.dmc_fe_stream_id != dmc->dmc_fe_stream_id) + continue; mm_alt = mm; /* Reject if not same ID */ - if (onid != MPEGTS_ONID_NONE && mm->mm_onid != MPEGTS_ONID_NONE && mm->mm_onid != onid) continue; - if (tsid != MPEGTS_TSID_NONE && mm->mm_tsid != MPEGTS_TSID_NONE && mm->mm_tsid != tsid) continue; + if (onid != MPEGTS_ONID_NONE && mm->mm_onid != MPEGTS_ONID_NONE && mm->mm_onid != onid) + continue; + if (tsid != MPEGTS_TSID_NONE && mm->mm_tsid != MPEGTS_TSID_NONE && mm->mm_tsid != tsid) + continue; break; } @@ -610,26 +546,20 @@ dvb_network_find_mux /* in the NIT table information and real mux feed */ mm = mm_alt; } - return (dvb_mux_t *)mm; + return (dvb_mux_t*)mm; } -static htsmsg_t * -dvb_network_config_save ( mpegts_network_t *mn, char *filename, size_t fsize ) -{ - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* dvb_network_config_save(mpegts_network_t* mn, char* filename, size_t fsize) { + htsmsg_t* c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(&mn->mn_id, c); htsmsg_add_str(c, "class", mn->mn_id.in_class->ic_class); if (filename) - snprintf(filename, fsize, "input/dvb/networks/%s/config", - idnode_uuid_as_str(&mn->mn_id, ubuf)); + snprintf(filename, fsize, "input/dvb/networks/%s/config", idnode_uuid_as_str(&mn->mn_id, ubuf)); return c; } -const idclass_t * -dvb_network_mux_class - ( mpegts_network_t *mn ) -{ +const idclass_t* dvb_network_mux_class(mpegts_network_t* mn) { if (idnode_is_instance(&mn->mn_id, &dvb_network_dvbt_class)) return &dvb_mux_dvbt_class; if (idnode_is_instance(&mn->mn_id, &dvb_network_dvbc_class)) @@ -655,45 +585,48 @@ dvb_network_mux_class return NULL; } -#define CBIT_ORBITAL_POS (1<<0) -#define CBIT_POLARISATION (1<<1) -#define CBIT_FREQ (1<<2) -#define CBIT_RATE (1<<3) -#define CBIT_RATE_HP (1<<4) -#define CBIT_RATE_LP (1<<5) -#define CBIT_MODULATION (1<<6) -#define CBIT_INVERSION (1<<7) -#define CBIT_ROLLOFF (1<<8) -#define CBIT_PILOT (1<<9) -#define CBIT_STREAM_ID (1<<10) -#define CBIT_BANDWIDTH (1<<11) -#define CBIT_TRANS_MODE (1<<12) -#define CBIT_GUARD (1<<13) -#define CBIT_HIERARCHY (1<<14) -#define CBIT_PLS_MODE (1<<15) -#define CBIT_PLS_CODE (1<<16) -#define CBIT_FEC_INNER (1<<17) - -static mpegts_mux_t * -dvb_network_create_mux - ( mpegts_network_t *mn, void *origin, uint32_t onid, uint32_t tsid, - void *p, int force ) -{ - int save = 0, satpos; - dvb_mux_t *mm; - dvb_network_t *ln; - dvb_mux_conf_t *dmc = p; - const idclass_t *cls = dvb_network_mux_class(mn); +#define CBIT_ORBITAL_POS (1 << 0) +#define CBIT_POLARISATION (1 << 1) +#define CBIT_FREQ (1 << 2) +#define CBIT_RATE (1 << 3) +#define CBIT_RATE_HP (1 << 4) +#define CBIT_RATE_LP (1 << 5) +#define CBIT_MODULATION (1 << 6) +#define CBIT_INVERSION (1 << 7) +#define CBIT_ROLLOFF (1 << 8) +#define CBIT_PILOT (1 << 9) +#define CBIT_STREAM_ID (1 << 10) +#define CBIT_BANDWIDTH (1 << 11) +#define CBIT_TRANS_MODE (1 << 12) +#define CBIT_GUARD (1 << 13) +#define CBIT_HIERARCHY (1 << 14) +#define CBIT_PLS_MODE (1 << 15) +#define CBIT_PLS_CODE (1 << 16) +#define CBIT_FEC_INNER (1 << 17) + +static mpegts_mux_t* dvb_network_create_mux(mpegts_network_t* mn, + void* origin, + uint32_t onid, + uint32_t tsid, + void* p, + int force) { + int save = 0, satpos; + dvb_mux_t* mm; + dvb_network_t* ln; + dvb_mux_conf_t* dmc = p; + const idclass_t* cls = dvb_network_mux_class(mn); /* when forced - try to look also to another DVB-S networks */ if (force && cls == &dvb_mux_dvbs_class && dmc->dmc_fe_type == DVB_TYPE_S && dmc->u.dmc_fe_qpsk.orbital_pos != INT_MAX) { satpos = dvb_network_get_orbital_pos(mn); if (dvb_network_check_orbital_pos(satpos, dmc->u.dmc_fe_qpsk.orbital_pos)) { - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { - if (!idnode_is_instance(&mn->mn_id, &dvb_network_dvbs_class)) continue; + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) { + if (!idnode_is_instance(&mn->mn_id, &dvb_network_dvbs_class)) + continue; satpos = dvb_network_get_orbital_pos(mn); - if (satpos == INT_MAX) continue; + if (satpos == INT_MAX) + continue; if (!dvb_network_check_orbital_pos(satpos, dmc->u.dmc_fe_qpsk.orbital_pos)) break; } @@ -714,50 +647,70 @@ dvb_network_create_mux } if (save) { mm = dvb_mux_create0(ln, onid, tsid, dmc, NULL, NULL); - mpegts_mux_post_create((mpegts_mux_t *)mm); + mpegts_mux_post_create((mpegts_mux_t*)mm); if (tvhtrace_enabled()) { char buf[128]; - dvb_mux_conf_str(&((dvb_mux_t *)mm)->lm_tuning, buf, sizeof(buf)); - tvhtrace(LS_MPEGTS, "mux %p %s onid %i tsid %i added to network %s (autodiscovery)", - mm, buf, onid, tsid, mm->mm_network->mn_network_name); + dvb_mux_conf_str(&((dvb_mux_t*)mm)->lm_tuning, buf, sizeof(buf)); + tvhtrace(LS_MPEGTS, + "mux %p %s onid %i tsid %i added to network %s (autodiscovery)", + mm, + buf, + onid, + tsid, + mm->mm_network->mn_network_name); } } } else if (mm) { - char buf[128]; + char buf[128]; dvb_mux_conf_t tuning_new, tuning_old; - dvb_mux_t *lm = (dvb_mux_t*)mm; - int change = (ln->mn_autodiscovery == MN_DISCOVERY_CHANGE) || force; + dvb_mux_t* lm = (dvb_mux_t*)mm; + int change = (ln->mn_autodiscovery == MN_DISCOVERY_CHANGE) || force; /* the nit tables may be inconsistent (like rolloff ping-pong) */ /* accept information only from one origin mux */ if (mm->mm_dmc_origin_expire > mclk() && mm->mm_dmc_origin && mm->mm_dmc_origin != origin) goto noop; - #define COMPARE(x, cbit) ({ \ - int xr = dmc->x != lm->lm_tuning.x; \ - if (xr) { \ - tvhtrace(LS_MPEGTS, "create mux dmc->" #x " (%li) != lm->lm_tuning." #x \ - " (%li)", (long)dmc->x, (long)tuning_new.x); \ - tuning_new.x = dmc->x; \ - } xr ? cbit : 0; }) - #define COMPAREN(x, cbit) ({ \ - int xr = dmc->x != 0 && dmc->x != 1 && dmc->x != tuning_new.x; \ - if (xr) { \ - tvhtrace(LS_MPEGTS, "create mux dmc->" #x " (%li) != lm->lm_tuning." #x \ - " (%li)", (long)dmc->x, (long)tuning_new.x); \ - tuning_new.x = dmc->x; \ - } xr ? cbit : 0; }) - #define COMPAREN0(x, cbit) ({ \ - int xr = dmc->x != 1 && dmc->x != tuning_new.x; \ - if (xr) { \ - tvhtrace(LS_MPEGTS, "create mux dmc->" #x " (%li) != lm->lm_tuning." #x \ - " (%li)", (long)dmc->x, (long)tuning_new.x); \ - tuning_new.x = dmc->x; \ - } xr ? cbit : 0; }) +#define COMPARE(x, cbit) \ + ({ \ + int xr = dmc->x != lm->lm_tuning.x; \ + if (xr) { \ + tvhtrace(LS_MPEGTS, \ + "create mux dmc->" #x " (%li) != lm->lm_tuning." #x " (%li)", \ + (long)dmc->x, \ + (long)tuning_new.x); \ + tuning_new.x = dmc->x; \ + } \ + xr ? cbit : 0; \ + }) +#define COMPAREN(x, cbit) \ + ({ \ + int xr = dmc->x != 0 && dmc->x != 1 && dmc->x != tuning_new.x; \ + if (xr) { \ + tvhtrace(LS_MPEGTS, \ + "create mux dmc->" #x " (%li) != lm->lm_tuning." #x " (%li)", \ + (long)dmc->x, \ + (long)tuning_new.x); \ + tuning_new.x = dmc->x; \ + } \ + xr ? cbit : 0; \ + }) +#define COMPAREN0(x, cbit) \ + ({ \ + int xr = dmc->x != 1 && dmc->x != tuning_new.x; \ + if (xr) { \ + tvhtrace(LS_MPEGTS, \ + "create mux dmc->" #x " (%li) != lm->lm_tuning." #x " (%li)", \ + (long)dmc->x, \ + (long)tuning_new.x); \ + tuning_new.x = dmc->x; \ + } \ + xr ? cbit : 0; \ + }) tuning_new = tuning_old = lm->lm_tuning; /* Always save the orbital position */ if (dmc->dmc_fe_type == DVB_TYPE_S) { if (dmc->u.dmc_fe_qpsk.orbital_pos == INT_MAX || dvb_network_check_orbital_pos(tuning_new.u.dmc_fe_qpsk.orbital_pos, - dmc->u.dmc_fe_qpsk.orbital_pos)) { + dmc->u.dmc_fe_qpsk.orbital_pos)) { save |= COMPARE(u.dmc_fe_qpsk.orbital_pos, CBIT_ORBITAL_POS); tuning_new.u.dmc_fe_qpsk.orbital_pos = dmc->u.dmc_fe_qpsk.orbital_pos; } @@ -775,52 +728,62 @@ dvb_network_create_mux save |= COMPAREN(dmc_fe_rolloff, CBIT_ROLLOFF); save |= COMPAREN(dmc_fe_pilot, CBIT_PILOT); switch (dmc->dmc_fe_type) { - case DVB_TYPE_T: - case DVB_TYPE_DTMB: - save |= COMPARE(dmc_fe_stream_id, CBIT_STREAM_ID); - save |= COMPAREN(u.dmc_fe_ofdm.bandwidth, CBIT_BANDWIDTH); - save |= COMPAREN(u.dmc_fe_ofdm.hierarchy_information, CBIT_HIERARCHY); - save |= COMPAREN(u.dmc_fe_ofdm.code_rate_HP, CBIT_RATE_HP); - save |= COMPAREN0(u.dmc_fe_ofdm.code_rate_LP, CBIT_RATE_LP); - save |= COMPAREN(u.dmc_fe_ofdm.transmission_mode, CBIT_TRANS_MODE); - save |= COMPAREN(u.dmc_fe_ofdm.guard_interval, CBIT_GUARD); - break; - case DVB_TYPE_S: - save |= COMPARE(u.dmc_fe_qpsk.polarisation, CBIT_POLARISATION); - save |= COMPARE(u.dmc_fe_qpsk.symbol_rate, CBIT_RATE); - save |= COMPARE(dmc_fe_stream_id, CBIT_STREAM_ID); - save |= COMPAREN(dmc_fe_pls_mode, CBIT_PLS_MODE); - save |= COMPAREN(dmc_fe_pls_code, CBIT_PLS_CODE); - save |= COMPAREN(u.dmc_fe_qpsk.fec_inner, CBIT_FEC_INNER); - break; - case DVB_TYPE_C: - case DVB_TYPE_ATSC_C: - save |= COMPARE(u.dmc_fe_qam.symbol_rate, CBIT_RATE); - save |= COMPAREN(u.dmc_fe_qam.fec_inner, CBIT_FEC_INNER); - break; - case DVB_TYPE_ATSC_T: - break; - default: - abort(); + case DVB_TYPE_T: + case DVB_TYPE_DTMB: + save |= COMPARE(dmc_fe_stream_id, CBIT_STREAM_ID); + save |= COMPAREN(u.dmc_fe_ofdm.bandwidth, CBIT_BANDWIDTH); + save |= COMPAREN(u.dmc_fe_ofdm.hierarchy_information, CBIT_HIERARCHY); + save |= COMPAREN(u.dmc_fe_ofdm.code_rate_HP, CBIT_RATE_HP); + save |= COMPAREN0(u.dmc_fe_ofdm.code_rate_LP, CBIT_RATE_LP); + save |= COMPAREN(u.dmc_fe_ofdm.transmission_mode, CBIT_TRANS_MODE); + save |= COMPAREN(u.dmc_fe_ofdm.guard_interval, CBIT_GUARD); + break; + case DVB_TYPE_S: + save |= COMPARE(u.dmc_fe_qpsk.polarisation, CBIT_POLARISATION); + save |= COMPARE(u.dmc_fe_qpsk.symbol_rate, CBIT_RATE); + save |= COMPARE(dmc_fe_stream_id, CBIT_STREAM_ID); + save |= COMPAREN(dmc_fe_pls_mode, CBIT_PLS_MODE); + save |= COMPAREN(dmc_fe_pls_code, CBIT_PLS_CODE); + save |= COMPAREN(u.dmc_fe_qpsk.fec_inner, CBIT_FEC_INNER); + break; + case DVB_TYPE_C: + case DVB_TYPE_ATSC_C: + save |= COMPARE(u.dmc_fe_qam.symbol_rate, CBIT_RATE); + save |= COMPAREN(u.dmc_fe_qam.fec_inner, CBIT_FEC_INNER); + break; + case DVB_TYPE_ATSC_T: + break; + default: + abort(); } - #undef COMPARE - #undef COMPAREN +#undef COMPARE +#undef COMPAREN /* ignore rolloff only changes (don't save) */ save &= ~CBIT_ROLLOFF; if (save) { char muxname[128]; - mpegts_mux_nice_name((mpegts_mux_t *)mm, muxname, sizeof(muxname)); + mpegts_mux_nice_name((mpegts_mux_t*)mm, muxname, sizeof(muxname)); dvb_mux_conf_str(&tuning_old, buf, sizeof(buf)); - tvhlog(change ? LOG_WARNING : LOG_NOTICE, LS_MPEGTS, - "mux %s%s %s (%08x)", muxname, - change ? " changed from" : " old params", buf, save); + tvhlog(change ? LOG_WARNING : LOG_NOTICE, + LS_MPEGTS, + "mux %s%s %s (%08x)", + muxname, + change ? " changed from" : " old params", + buf, + save); dvb_mux_conf_str(&tuning_new, buf, sizeof(buf)); - tvhlog(change ? LOG_WARNING : LOG_NOTICE, LS_MPEGTS, - "mux %s%s %s (%08x)", muxname, - change ? " changed to " : " new params", buf, save); - if (!change) save = 0; + tvhlog(change ? LOG_WARNING : LOG_NOTICE, + LS_MPEGTS, + "mux %s%s %s (%08x)", + muxname, + change ? " changed to " : " new params", + buf, + save); + if (!change) + save = 0; } - if (save) lm->lm_tuning = tuning_new; + if (save) + lm->lm_tuning = tuning_new; } save: if (mm && save) { @@ -829,21 +792,19 @@ save: idnode_changed(&mm->mm_id); } noop: - return (mpegts_mux_t *)mm; + return (mpegts_mux_t*)mm; } -static mpegts_service_t * -dvb_network_create_service - ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid ) -{ - dvb_mux_t *lm = (dvb_mux_t *)mm; - mpegts_service_t *s; +static mpegts_service_t* +dvb_network_create_service(mpegts_mux_t* mm, uint16_t sid, uint16_t pmt_pid) { + dvb_mux_t* lm = (dvb_mux_t*)mm; + mpegts_service_t* s; s = mpegts_service_create1(NULL, mm, sid, pmt_pid, NULL); /* Set service values from mux if CableCARD */ if (lm->lm_tuning.dmc_fe_type == DVB_TYPE_CABLECARD) { - mpegts_network_t *ln = mm->mm_network; + mpegts_network_t* ln = mm->mm_network; if (!s->s_dvb_provider && lm->mm_provider_network_name) s->s_dvb_provider = strdup(lm->mm_provider_network_name); if (!s->s_dvb_provider && ln->mn_provider_network_name) @@ -857,38 +818,30 @@ dvb_network_create_service return s; } -static mpegts_mux_t * -dvb_network_mux_create2 - ( mpegts_network_t *mn, htsmsg_t *conf ) -{ - dvb_network_t *ln = (dvb_network_t*)mn; - dvb_mux_t *mm; - mm = dvb_mux_create0(ln, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, - NULL, NULL, conf); - return mpegts_mux_post_create((mpegts_mux_t *)mm); +static mpegts_mux_t* dvb_network_mux_create2(mpegts_network_t* mn, htsmsg_t* conf) { + dvb_network_t* ln = (dvb_network_t*)mn; + dvb_mux_t* mm; + mm = dvb_mux_create0(ln, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, NULL, NULL, conf); + return mpegts_mux_post_create((mpegts_mux_t*)mm); } /* **************************************************************************** * Creation/Config * ***************************************************************************/ -dvb_network_t * -dvb_network_create0 - ( const char *uuid, const idclass_t *idc, htsmsg_t *conf ) -{ - dvb_network_t *ln; - dvb_mux_t *lm; - htsmsg_t *c, *e; - htsmsg_field_t *f; - const char *s; - - ln = calloc(1, sizeof(dvb_network_t)); +dvb_network_t* dvb_network_create0(const char* uuid, const idclass_t* idc, htsmsg_t* conf) { + dvb_network_t* ln; + dvb_mux_t* lm; + htsmsg_t * c, *e; + htsmsg_field_t* f; + const char* s; + + ln = calloc(1, sizeof(dvb_network_t)); ln->ln_type = dvb_fe_type_by_network_class(idc); assert(ln->ln_type != DVB_TYPE_NONE); /* Create */ - if (!(ln = (dvb_network_t*)mpegts_network_create0((void*)ln, - idc, uuid, NULL, conf))) + if (!(ln = (dvb_network_t*)mpegts_network_create0((void*)ln, idc, uuid, NULL, conf))) return NULL; /* Callbacks */ @@ -910,10 +863,12 @@ dvb_network_create0 /* Load muxes */ if ((c = hts_settings_load_r(1, "input/dvb/networks/%s/muxes", uuid))) { HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_get_map_by_field(f))) continue; - if (!(e = htsmsg_get_map(e, "config"))) continue; + if (!(e = htsmsg_get_map_by_field(f))) + continue; + if (!(e = htsmsg_get_map(e, "config"))) + continue; lm = dvb_mux_create1(ln, htsmsg_field_name(f), e); - mpegts_mux_post_create((mpegts_mux_t *)lm); + mpegts_mux_post_create((mpegts_mux_t*)lm); } htsmsg_destroy(c); } @@ -921,49 +876,45 @@ dvb_network_create0 return ln; } -static mpegts_network_t * -dvb_network_builder - ( const idclass_t *idc, htsmsg_t *conf ) -{ +static mpegts_network_t* dvb_network_builder(const idclass_t* idc, htsmsg_t* conf) { return (mpegts_network_t*)dvb_network_create0(NULL, idc, conf); } -static const idclass_t * dvb_network_classes[] = { - &dvb_network_dvbt_class, - &dvb_network_dvbc_class, - &dvb_network_dvbs_class, - &dvb_network_atsc_t_class, - &dvb_network_atsc_c_class, - &dvb_network_cablecard_class, - &dvb_network_isdb_t_class, - &dvb_network_isdb_c_class, - &dvb_network_isdb_s_class, +static const idclass_t* dvb_network_classes[] = { + &dvb_network_dvbt_class, + &dvb_network_dvbc_class, + &dvb_network_dvbs_class, + &dvb_network_atsc_t_class, + &dvb_network_atsc_c_class, + &dvb_network_cablecard_class, + &dvb_network_isdb_t_class, + &dvb_network_isdb_c_class, + &dvb_network_isdb_s_class, #if 0 /* TODO: write DAB stream parser */ &dvb_network_dab_class, #endif }; -static const idclass_t * dvb_mux_classes[] = { - &dvb_mux_dvbt_class, - &dvb_mux_dvbc_class, - &dvb_mux_dvbs_class, - &dvb_mux_atsc_t_class, - &dvb_mux_atsc_c_class, - &dvb_mux_cablecard_class, - &dvb_mux_isdb_t_class, - &dvb_mux_isdb_c_class, - &dvb_mux_isdb_s_class, +static const idclass_t* dvb_mux_classes[] = { + &dvb_mux_dvbt_class, + &dvb_mux_dvbc_class, + &dvb_mux_dvbs_class, + &dvb_mux_atsc_t_class, + &dvb_mux_atsc_c_class, + &dvb_mux_cablecard_class, + &dvb_mux_isdb_t_class, + &dvb_mux_isdb_c_class, + &dvb_mux_isdb_s_class, #if 0 /* TODO: write DAB stream parser */ &dvb_mux_dab_class, #endif }; -void dvb_network_init ( void ) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - const char *s; - int i; +void dvb_network_init(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + const char* s; + int i; /* Load list of mux charset global overrides */ dvb_charset_init(); @@ -974,21 +925,23 @@ void dvb_network_init ( void ) /* Register class builders */ for (i = 0; i < ARRAY_SIZE(dvb_network_classes); i++) - mpegts_network_register_builder(dvb_network_classes[i], - dvb_network_builder); + mpegts_network_register_builder(dvb_network_classes[i], dvb_network_builder); /* Load settings */ if (!(c = hts_settings_load_r(1, "input/dvb/networks"))) return; HTSMSG_FOREACH(f, c) { - if (!(e = htsmsg_get_map_by_field(f))) continue; - if (!(e = htsmsg_get_map(e, "config"))) continue; - if (!(s = htsmsg_get_str(e, "class"))) continue; + if (!(e = htsmsg_get_map_by_field(f))) + continue; + if (!(e = htsmsg_get_map(e, "config"))) + continue; + if (!(s = htsmsg_get_str(e, "class"))) + continue; for (i = 0; i < ARRAY_SIZE(dvb_network_classes); i++) { if (strcmp(s, "dvb_network_atsc") == 0) s = "dvb_network_atsc_t"; - if(!strcmp(dvb_network_classes[i]->ic_class, s)) { + if (!strcmp(dvb_network_classes[i]->ic_class, s)) { dvb_network_create0(htsmsg_field_name(f), dvb_network_classes[i], e); break; } @@ -997,8 +950,7 @@ void dvb_network_init ( void ) htsmsg_destroy(c); } -void dvb_network_done ( void ) -{ +void dvb_network_done(void) { int i; tvh_mutex_lock(&global_lock); @@ -1017,8 +969,7 @@ void dvb_network_done ( void ) * Search * ***************************************************************************/ -const idclass_t *dvb_network_class_by_fe_type(dvb_fe_type_t type) -{ +const idclass_t* dvb_network_class_by_fe_type(dvb_fe_type_t type) { if (type == DVB_TYPE_T) return &dvb_network_dvbt_class; else if (type == DVB_TYPE_C) @@ -1045,8 +996,7 @@ const idclass_t *dvb_network_class_by_fe_type(dvb_fe_type_t type) return NULL; } -dvb_fe_type_t dvb_fe_type_by_network_class(const idclass_t *idc) -{ +dvb_fe_type_t dvb_fe_type_by_network_class(const idclass_t* idc) { if (idc == &dvb_network_dvbt_class) return DVB_TYPE_T; else if (idc == &dvb_network_dvbc_class) @@ -1073,9 +1023,8 @@ dvb_fe_type_t dvb_fe_type_by_network_class(const idclass_t *idc) return DVB_TYPE_NONE; } -idnode_set_t *dvb_network_list_by_fe_type(dvb_fe_type_t type) -{ - const idclass_t *idc = dvb_network_class_by_fe_type(type); +idnode_set_t* dvb_network_list_by_fe_type(dvb_fe_type_t type) { + const idclass_t* idc = dvb_network_class_by_fe_type(type); if (!idc) return NULL; @@ -1083,11 +1032,10 @@ idnode_set_t *dvb_network_list_by_fe_type(dvb_fe_type_t type) return idnode_find_all(idc, NULL); } -int dvb_network_get_orbital_pos(mpegts_network_t *mn) -{ - dvb_network_t *ln = (dvb_network_t *)mn; - mpegts_mux_t *mm; - dvb_mux_t *lm = NULL; +int dvb_network_get_orbital_pos(mpegts_network_t* mn) { + dvb_network_t* ln = (dvb_network_t*)mn; + mpegts_mux_t* mm; + dvb_mux_t* lm = NULL; if (!ln) return INT_MAX; @@ -1099,8 +1047,8 @@ int dvb_network_get_orbital_pos(mpegts_network_t *mn) } if (ln->mn_satpos != INT_MAX) return ln->mn_satpos; - LIST_FOREACH(mm, &ln->mn_muxes, mm_network_link) { - lm = (dvb_mux_t *)mm; + LIST_FOREACH (mm, &ln->mn_muxes, mm_network_link) { + lm = (dvb_mux_t*)mm; if (lm->lm_tuning.u.dmc_fe_qpsk.orbital_pos != INT_MAX) break; } diff --git a/src/input/mpegts/mpegts_network_scan.c b/src/input/mpegts/mpegts_network_scan.c index 5a6e2cfd9..f4d05249e 100644 --- a/src/input/mpegts/mpegts_network_scan.c +++ b/src/input/mpegts/mpegts_network_scan.c @@ -24,9 +24,7 @@ *****************************************************************************/ /* Notify */ -static void -mpegts_network_scan_notify ( mpegts_mux_t *mm ) -{ +static void mpegts_network_scan_notify(mpegts_mux_t* mm) { idnode_notify_changed(&mm->mm_id); idnode_notify_changed(&mm->mm_network->mn_id); } @@ -37,9 +35,7 @@ mpegts_network_scan_notify ( mpegts_mux_t *mm ) * 2) prefer muxes with the newer timestamp (scan interrupted?) * 3) do standard mux sorting */ -static int -mm_cmp ( mpegts_mux_t *a, mpegts_mux_t *b ) -{ +static int mm_cmp(mpegts_mux_t* a, mpegts_mux_t* b) { int r = b->mm_scan_weight - a->mm_scan_weight; if (r == 0) { int64_t l = b->mm_start_monoclock - a->mm_start_monoclock; @@ -56,9 +52,7 @@ mm_cmp ( mpegts_mux_t *a, mpegts_mux_t *b ) * 2) prefer muxes with the oldest timestamp * 3) do standard mux sorting */ -static int -mm_cmp_idle ( mpegts_mux_t *a, mpegts_mux_t *b ) -{ +static int mm_cmp_idle(mpegts_mux_t* a, mpegts_mux_t* b) { int r = b->mm_scan_weight - a->mm_scan_weight; if (r == 0) { int64_t l = a->mm_start_monoclock - b->mm_start_monoclock; @@ -69,10 +63,8 @@ mm_cmp_idle ( mpegts_mux_t *a, mpegts_mux_t *b ) return r; } -static void -mpegts_network_scan_queue_del0 ( mpegts_mux_t *mm ) -{ - mpegts_network_t *mn = mm->mm_network; +static void mpegts_network_scan_queue_del0(mpegts_mux_t* mm) { + mpegts_network_t* mn = mm->mm_network; if (mm->mm_scan_state == MM_SCAN_STATE_ACTIVE) { TAILQ_REMOVE(&mn->mn_scan_active, mm, mm_scan_link); } else if (mm->mm_scan_state == MM_SCAN_STATE_PEND) { @@ -82,23 +74,22 @@ mpegts_network_scan_queue_del0 ( mpegts_mux_t *mm ) } } -static int -mpegts_network_scan_do_mux ( mpegts_mux_queue_t *q, mpegts_mux_t *mm ) -{ +static int mpegts_network_scan_do_mux(mpegts_mux_queue_t* q, mpegts_mux_t* mm) { int r, state = mm->mm_scan_state; - assert(state == MM_SCAN_STATE_PEND || - state == MM_SCAN_STATE_IPEND || - state == MM_SCAN_STATE_ACTIVE); + assert( + state == MM_SCAN_STATE_PEND || state == MM_SCAN_STATE_IPEND || state == MM_SCAN_STATE_ACTIVE); /* Don't try to subscribe already tuned muxes */ - if (mm->mm_active) return 0; + if (mm->mm_active) + return 0; /* Attempt to tune */ - r = mpegts_mux_subscribe(mm, NULL, "scan", mm->mm_scan_weight, - mm->mm_scan_flags | - SUBSCRIPTION_ONESHOT | - SUBSCRIPTION_TABLES); + r = mpegts_mux_subscribe(mm, + NULL, + "scan", + mm->mm_scan_weight, + mm->mm_scan_flags | SUBSCRIPTION_ONESHOT | SUBSCRIPTION_TABLES); /* Started */ state = mm->mm_scan_state; @@ -106,8 +97,7 @@ mpegts_network_scan_do_mux ( mpegts_mux_queue_t *q, mpegts_mux_t *mm ) assert(state == MM_SCAN_STATE_ACTIVE); return 0; } - assert(state == MM_SCAN_STATE_PEND || - state == MM_SCAN_STATE_IPEND); + assert(state == MM_SCAN_STATE_PEND || state == MM_SCAN_STATE_IPEND); /* No free tuners - stop */ if (r == SM_CODE_NO_FREE_ADAPTER || r == SM_CODE_NO_ADAPTERS) @@ -131,11 +121,9 @@ mpegts_network_scan_do_mux ( mpegts_mux_queue_t *q, mpegts_mux_t *mm ) return 0; } -void -mpegts_network_scan_timer_cb ( void *p ) -{ - mpegts_network_t *mn = p; - mpegts_mux_t *mm, *nxt = NULL; +void mpegts_network_scan_timer_cb(void* p) { + mpegts_network_t* mn = p; + mpegts_mux_t * mm, *nxt = NULL; /* Process standard Q */ for (mm = TAILQ_FIRST(&mn->mn_scan_pend); mm != NULL; mm = nxt) { @@ -161,31 +149,21 @@ mpegts_network_scan_timer_cb ( void *p ) * Mux transition *****************************************************************************/ -static void -mpegts_network_scan_mux_add ( mpegts_network_t *mn, mpegts_mux_t *mm ) -{ - TAILQ_INSERT_SORTED_R(&mn->mn_scan_ipend, mpegts_mux_queue, mm, - mm_scan_link, mm_cmp); - mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, - mn, sec2mono(10)); +static void mpegts_network_scan_mux_add(mpegts_network_t* mn, mpegts_mux_t* mm) { + TAILQ_INSERT_SORTED_R(&mn->mn_scan_ipend, mpegts_mux_queue, mm, mm_scan_link, mm_cmp); + mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, sec2mono(10)); } -static void -mpegts_network_scan_idle_mux_add ( mpegts_network_t *mn, mpegts_mux_t *mm ) -{ +static void mpegts_network_scan_idle_mux_add(mpegts_network_t* mn, mpegts_mux_t* mm) { mm->mm_scan_weight = SUBSCRIPTION_PRIO_SCAN_IDLE; - TAILQ_INSERT_SORTED_R(&mn->mn_scan_ipend, mpegts_mux_queue, mm, - mm_scan_link, mm_cmp_idle); - mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, - mn, sec2mono(10)); + TAILQ_INSERT_SORTED_R(&mn->mn_scan_ipend, mpegts_mux_queue, mm, mm_scan_link, mm_cmp_idle); + mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, sec2mono(10)); } /* Finished */ static inline void -mpegts_network_scan_mux_done0 - ( mpegts_mux_t *mm, mpegts_mux_scan_result_t result, int weight ) -{ - mpegts_network_t *mn = mm->mm_network; +mpegts_network_scan_mux_done0(mpegts_mux_t* mm, mpegts_mux_scan_result_t result, int weight) { + mpegts_network_t* mn = mm->mm_network; mpegts_mux_scan_state_t state = mm->mm_scan_state; if (result == MM_SCAN_OK || result == MM_SCAN_PARTIAL) { @@ -229,31 +207,23 @@ mpegts_network_scan_mux_done0 } /* Failed - couldn't start */ -void -mpegts_network_scan_mux_fail ( mpegts_mux_t *mm ) -{ +void mpegts_network_scan_mux_fail(mpegts_mux_t* mm) { mpegts_network_scan_mux_done0(mm, MM_SCAN_FAIL, 0); } /* Completed succesfully */ -void -mpegts_network_scan_mux_done ( mpegts_mux_t *mm ) -{ +void mpegts_network_scan_mux_done(mpegts_mux_t* mm) { mm->mm_scan_flags = 0; mpegts_network_scan_mux_done0(mm, MM_SCAN_OK, 0); } /* Partially completed (not all tables were read) */ -void -mpegts_network_scan_mux_partial ( mpegts_mux_t *mm ) -{ +void mpegts_network_scan_mux_partial(mpegts_mux_t* mm) { mpegts_network_scan_mux_done0(mm, MM_SCAN_PARTIAL, 0); } /* Interrupted (re-add) */ -void -mpegts_network_scan_mux_cancel ( mpegts_mux_t *mm, int reinsert ) -{ +void mpegts_network_scan_mux_cancel(mpegts_mux_t* mm, int reinsert) { if (reinsert) { if (mm->mm_scan_state != MM_SCAN_STATE_ACTIVE) return; @@ -263,17 +233,13 @@ mpegts_network_scan_mux_cancel ( mpegts_mux_t *mm, int reinsert ) mm->mm_scan_flags = 0; } - mpegts_network_scan_mux_done0(mm, MM_SCAN_NONE, - reinsert ? mm->mm_scan_weight : 0); + mpegts_network_scan_mux_done0(mm, MM_SCAN_NONE, reinsert ? mm->mm_scan_weight : 0); } /* Mux has been started */ -void -mpegts_network_scan_mux_active ( mpegts_mux_t *mm ) -{ - mpegts_network_t *mn = mm->mm_network; - if (mm->mm_scan_state != MM_SCAN_STATE_PEND && - mm->mm_scan_state != MM_SCAN_STATE_IPEND) +void mpegts_network_scan_mux_active(mpegts_mux_t* mm) { + mpegts_network_t* mn = mm->mm_network; + if (mm->mm_scan_state != MM_SCAN_STATE_PEND && mm->mm_scan_state != MM_SCAN_STATE_IPEND) return; mpegts_network_scan_queue_del0(mm); mm->mm_scan_state = MM_SCAN_STATE_ACTIVE; @@ -282,10 +248,8 @@ mpegts_network_scan_mux_active ( mpegts_mux_t *mm ) } /* Mux has been reactivated */ -void -mpegts_network_scan_mux_reactivate ( mpegts_mux_t *mm ) -{ - mpegts_network_t *mn = mm->mm_network; +void mpegts_network_scan_mux_reactivate(mpegts_mux_t* mm) { + mpegts_network_t* mn = mm->mm_network; if (mm->mm_scan_state == MM_SCAN_STATE_ACTIVE) return; mpegts_network_scan_queue_del0(mm); @@ -298,10 +262,8 @@ mpegts_network_scan_mux_reactivate ( mpegts_mux_t *mm ) * Mux queue handling *****************************************************************************/ -void -mpegts_network_scan_queue_del ( mpegts_mux_t *mm ) -{ - mpegts_network_t *mn = mm->mm_network; +void mpegts_network_scan_queue_del(mpegts_mux_t* mm) { + mpegts_network_t* mn = mm->mm_network; tvhdebug(LS_MPEGTS, "removing mux %s from scan queue", mm->mm_nicename); mpegts_network_scan_queue_del0(mm); mm->mm_scan_state = MM_SCAN_STATE_IDLE; @@ -311,20 +273,19 @@ mpegts_network_scan_queue_del ( mpegts_mux_t *mm ) mpegts_network_scan_notify(mm); } -void -mpegts_network_scan_queue_add - ( mpegts_mux_t *mm, int weight, int flags, int delay ) -{ - int requeue = 0; - mpegts_network_t *mn = mm->mm_network; +void mpegts_network_scan_queue_add(mpegts_mux_t* mm, int weight, int flags, int delay) { + int requeue = 0; + mpegts_network_t* mn = mm->mm_network; - if (!mm->mm_is_enabled(mm)) return; + if (!mm->mm_is_enabled(mm)) + return; - if (weight <= 0) return; + if (weight <= 0) + return; if (weight > mm->mm_scan_weight) { mm->mm_scan_weight = weight; - requeue = 1; + requeue = 1; } /* Already active */ @@ -332,28 +293,28 @@ mpegts_network_scan_queue_add return; /* Remove entry (or ignore) */ - if (mm->mm_scan_state == MM_SCAN_STATE_PEND || - mm->mm_scan_state == MM_SCAN_STATE_IPEND) { + if (mm->mm_scan_state == MM_SCAN_STATE_PEND || mm->mm_scan_state == MM_SCAN_STATE_IPEND) { if (!requeue) return; mpegts_network_scan_queue_del0(mm); } - tvhdebug(LS_MPEGTS, "adding mux %s to scan queue weight %d flags %04X", - mm->mm_nicename, weight, flags); + tvhdebug(LS_MPEGTS, + "adding mux %s to scan queue weight %d flags %04X", + mm->mm_nicename, + weight, + flags); /* Add new entry */ mm->mm_scan_flags |= flags; if (mm->mm_scan_flags == 0) mm->mm_scan_flags = SUBSCRIPTION_IDLESCAN; if (weight == SUBSCRIPTION_PRIO_SCAN_IDLE) { - mm->mm_scan_state = MM_SCAN_STATE_IPEND; - TAILQ_INSERT_SORTED_R(&mn->mn_scan_ipend, mpegts_mux_queue, - mm, mm_scan_link, mm_cmp_idle); + mm->mm_scan_state = MM_SCAN_STATE_IPEND; + TAILQ_INSERT_SORTED_R(&mn->mn_scan_ipend, mpegts_mux_queue, mm, mm_scan_link, mm_cmp_idle); } else { - mm->mm_scan_state = MM_SCAN_STATE_PEND; - TAILQ_INSERT_SORTED_R(&mn->mn_scan_pend, mpegts_mux_queue, - mm, mm_scan_link, mm_cmp); + mm->mm_scan_state = MM_SCAN_STATE_PEND; + TAILQ_INSERT_SORTED_R(&mn->mn_scan_pend, mpegts_mux_queue, mm, mm_scan_link, mm_cmp); } mtimer_arm_rel(&mn->mn_scan_timer, mpegts_network_scan_timer_cb, mn, sec2mono(delay)); mpegts_network_scan_notify(mm); @@ -364,9 +325,7 @@ mpegts_network_scan_queue_add *****************************************************************************/ #if ENABLE_MPEGTS_DVB -static ssize_t -startswith( const char *str, const char *start ) -{ +static ssize_t startswith(const char* str, const char* start) { size_t len = strlen(start); if (!strncmp(str, start, len)) return len; @@ -374,16 +333,14 @@ startswith( const char *str, const char *start ) } #endif -void -mpegts_mux_bouquet_rescan ( const char *src, const char *extra ) -{ +void mpegts_mux_bouquet_rescan(const char* src, const char* extra) { #if ENABLE_MPEGTS_DVB - mpegts_network_t *mn; - mpegts_mux_t *mm; - ssize_t l; - const idclass_t *ic; - uint32_t freq; - int satpos; + mpegts_network_t* mn; + mpegts_mux_t* mm; + ssize_t l; + const idclass_t* ic; + uint32_t freq; + int satpos; #endif if (!src) @@ -398,11 +355,10 @@ mpegts_mux_bouquet_rescan ( const char *src, const char *extra ) src++; if (sscanf(src, ",%x,%x", &tsid, &nbid) != 2) return; - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) - if (idnode_is_instance(&mm->mm_id, &dvb_mux_dvbs_class) && - mm->mm_tsid == tsid && - ((dvb_mux_t *)mm)->lm_tuning.u.dmc_fe_qpsk.orbital_pos == satpos) + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) + if (idnode_is_instance(&mm->mm_id, &dvb_mux_dvbs_class) && mm->mm_tsid == tsid && + ((dvb_mux_t*)mm)->lm_tuning.u.dmc_fe_qpsk.orbital_pos == satpos) mpegts_mux_scan_state_set(mm, MM_SCAN_STATE_PEND); return; } @@ -418,11 +374,10 @@ mpegts_mux_bouquet_rescan ( const char *src, const char *extra ) if (sscanf(src, "%x,%x", &tsid, &nbid) != 2) return; ic = &dvb_mux_dvbc_class; -tsid_lookup: - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) - if (idnode_is_instance(&mm->mm_id, ic) && - mm->mm_tsid == tsid) + tsid_lookup: + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) + if (idnode_is_instance(&mm->mm_id, ic) && mm->mm_tsid == tsid) mpegts_mux_scan_state_set(mm, MM_SCAN_STATE_PEND); return; } @@ -435,17 +390,17 @@ tsid_lookup: return; freq = strtod(extra, NULL) * 1000; - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) if (idnode_is_instance(&mm->mm_id, &dvb_mux_dvbs_class) && - deltaU32(((dvb_mux_t *)mm)->lm_tuning.dmc_fe_freq, freq) < 2000 && - ((dvb_mux_t *)mm)->lm_tuning.u.dmc_fe_qpsk.orbital_pos == satpos) + deltaU32(((dvb_mux_t*)mm)->lm_tuning.dmc_fe_freq, freq) < 2000 && + ((dvb_mux_t*)mm)->lm_tuning.u.dmc_fe_qpsk.orbital_pos == satpos) mpegts_mux_scan_state_set(mm, MM_SCAN_STATE_PEND); return; } if ((l = startswith(src, "dvb-fastscan://")) > 0) { uint32_t pid, symbol, dvbs2; - char pol[2]; + char pol[2]; pol[1] = '\0'; src += l; @@ -465,40 +420,44 @@ tsid_lookup: return; // search for fastscan mux - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) if (idnode_is_instance(&mm->mm_id, &dvb_mux_dvbs_class) && - deltaU32(((dvb_mux_t *)mm)->lm_tuning.dmc_fe_freq, freq) < 2000 && - ((dvb_mux_t *)mm)->lm_tuning.u.dmc_fe_qpsk.polarisation == dvb_str2pol(pol) && - ((dvb_mux_t *)mm)->lm_tuning.u.dmc_fe_qpsk.orbital_pos == satpos) - { + deltaU32(((dvb_mux_t*)mm)->lm_tuning.dmc_fe_freq, freq) < 2000 && + ((dvb_mux_t*)mm)->lm_tuning.u.dmc_fe_qpsk.polarisation == dvb_str2pol(pol) && + ((dvb_mux_t*)mm)->lm_tuning.u.dmc_fe_qpsk.orbital_pos == satpos) { tvhinfo(LS_MPEGTS, "fastscan mux found '%s', set scan state 'PENDING'", mm->mm_nicename); mpegts_mux_scan_state_set(mm, MM_SCAN_STATE_PEND); return; } - tvhinfo(LS_MPEGTS, "fastscan mux not found, position:%i, frequency:%i, polarisation:%c", satpos, freq, pol[0]); + tvhinfo(LS_MPEGTS, + "fastscan mux not found, position:%i, frequency:%i, polarisation:%c", + satpos, + freq, + pol[0]); // fastscan mux not found, try to add it automatically - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) - if (mn->mn_satpos != INT_MAX && mn->mn_satpos == satpos) - { - dvb_mux_conf_t *mux; - mpegts_mux_t *mm = NULL; + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) + if (mn->mn_satpos != INT_MAX && mn->mn_satpos == satpos) { + dvb_mux_conf_t* mux; + mpegts_mux_t* mm = NULL; mux = malloc(sizeof(dvb_mux_conf_t)); dvb_mux_conf_init(mn, mux, dvbs2 ? DVB_SYS_DVBS2 : DVB_SYS_DVBS); - mux->dmc_fe_freq = freq; - mux->u.dmc_fe_qpsk.symbol_rate = symbol; + mux->dmc_fe_freq = freq; + mux->u.dmc_fe_qpsk.symbol_rate = symbol; mux->u.dmc_fe_qpsk.polarisation = dvb_str2pol(pol); - mux->u.dmc_fe_qpsk.orbital_pos = satpos; - mux->u.dmc_fe_qpsk.fec_inner = DVB_FEC_AUTO; - mux->dmc_fe_modulation = dvbs2 ? DVB_MOD_PSK_8 : DVB_MOD_QPSK; - mux->dmc_fe_rolloff = DVB_ROLLOFF_AUTO; + mux->u.dmc_fe_qpsk.orbital_pos = satpos; + mux->u.dmc_fe_qpsk.fec_inner = DVB_FEC_AUTO; + mux->dmc_fe_modulation = dvbs2 ? DVB_MOD_PSK_8 : DVB_MOD_QPSK; + mux->dmc_fe_rolloff = DVB_ROLLOFF_AUTO; mm = (mpegts_mux_t*)dvb_mux_create0((dvb_network_t*)mn, - MPEGTS_ONID_NONE, - MPEGTS_TSID_NONE, - mux, NULL, NULL); + MPEGTS_ONID_NONE, + MPEGTS_TSID_NONE, + mux, + NULL, + NULL); if (mm) { char buf[256]; mpegts_mux_post_create(mm); @@ -517,15 +476,9 @@ tsid_lookup: * Subsystem setup / tear down *****************************************************************************/ -void -mpegts_network_scan_init ( void ) -{ -} +void mpegts_network_scan_init(void) {} -void -mpegts_network_scan_done ( void ) -{ -} +void mpegts_network_scan_done(void) {} /****************************************************************************** * Editor Configuration diff --git a/src/input/mpegts/mpegts_network_scan.h b/src/input/mpegts/mpegts_network_scan.h index 5a8d9d46d..27421926d 100644 --- a/src/input/mpegts/mpegts_network_scan.h +++ b/src/input/mpegts/mpegts_network_scan.h @@ -28,30 +28,29 @@ /* * Timer callback (only to be used in network init) */ -void mpegts_network_scan_timer_cb ( void *p ); +void mpegts_network_scan_timer_cb(void* p); /* * Registration functions */ -void mpegts_network_scan_queue_add ( mpegts_mux_t *mm, int weight, - int flags, int delay ); -void mpegts_network_scan_queue_del ( mpegts_mux_t *mm ); +void mpegts_network_scan_queue_add(mpegts_mux_t* mm, int weight, int flags, int delay); +void mpegts_network_scan_queue_del(mpegts_mux_t* mm); /* * Events */ -void mpegts_network_scan_mux_fail ( mpegts_mux_t *mm ); -void mpegts_network_scan_mux_done ( mpegts_mux_t *mm ); -void mpegts_network_scan_mux_partial ( mpegts_mux_t *mm ); -void mpegts_network_scan_mux_cancel ( mpegts_mux_t *mm, int reinsert ); -void mpegts_network_scan_mux_active ( mpegts_mux_t *mm ); -void mpegts_network_scan_mux_reactivate ( mpegts_mux_t *mm ); +void mpegts_network_scan_mux_fail(mpegts_mux_t* mm); +void mpegts_network_scan_mux_done(mpegts_mux_t* mm); +void mpegts_network_scan_mux_partial(mpegts_mux_t* mm); +void mpegts_network_scan_mux_cancel(mpegts_mux_t* mm, int reinsert); +void mpegts_network_scan_mux_active(mpegts_mux_t* mm); +void mpegts_network_scan_mux_reactivate(mpegts_mux_t* mm); /* * Init / Teardown */ -void mpegts_network_scan_init ( void ); -void mpegts_network_scan_done ( void ); +void mpegts_network_scan_init(void); +void mpegts_network_scan_done(void); #endif /* __TVH_MPEGTS_NETWORK_SCAN_H__*/ diff --git a/src/input/mpegts/mpegts_pid.c b/src/input/mpegts/mpegts_pid.c index 04c9602ca..f26d69803 100644 --- a/src/input/mpegts/mpegts_pid.c +++ b/src/input/mpegts/mpegts_pid.c @@ -19,9 +19,7 @@ #include "tvheadend.h" #include "input.h" -static int -pid_cmp(uint16_t pid, uint16_t weight, mpegts_apid_t *p2) -{ +static int pid_cmp(uint16_t pid, uint16_t weight, mpegts_apid_t* p2) { if (pid < p2->pid) return 1; if (pid > p2->pid) @@ -33,11 +31,9 @@ pid_cmp(uint16_t pid, uint16_t weight, mpegts_apid_t *p2) return 0; } -static int -pid_wcmp(const void *_p1, const void *_p2) -{ - const mpegts_apid_t *p1 = _p1; - const mpegts_apid_t *p2 = _p2; +static int pid_wcmp(const void* _p1, const void* _p2) { + const mpegts_apid_t* p1 = _p1; + const mpegts_apid_t* p2 = _p2; if (p1->weight < p2->weight) return 1; if (p1->weight > p2->weight) @@ -50,37 +46,29 @@ pid_wcmp(const void *_p1, const void *_p2) return 0; } -int -mpegts_pid_init(mpegts_apids_t *pids) -{ +int mpegts_pid_init(mpegts_apids_t* pids) { assert(pids); memset(pids, 0, sizeof(*pids)); pids->sorted = 1; return 0; } -void -mpegts_pid_done(mpegts_apids_t *pids) -{ +void mpegts_pid_done(mpegts_apids_t* pids) { if (pids == NULL) return; free(pids->pids); - pids->pids = NULL; + pids->pids = NULL; pids->alloc = pids->count = 0; } -mpegts_apids_t * -mpegts_pid_alloc(void) -{ - mpegts_apids_t *r = calloc(1, sizeof(mpegts_apids_t)); +mpegts_apids_t* mpegts_pid_alloc(void) { + mpegts_apids_t* r = calloc(1, sizeof(mpegts_apids_t)); if (r) r->sorted = 1; return r; } -void -mpegts_pid_destroy(mpegts_apids_t **pids) -{ +void mpegts_pid_destroy(mpegts_apids_t** pids) { if (pids) { mpegts_pid_done(*pids); free(*pids); @@ -88,17 +76,13 @@ mpegts_pid_destroy(mpegts_apids_t **pids) } } -void -mpegts_pid_reset(mpegts_apids_t *pids) -{ +void mpegts_pid_reset(mpegts_apids_t* pids) { pids->alloc = pids->count = 0; } -int -mpegts_pid_add(mpegts_apids_t *pids, uint16_t pid, uint16_t weight) -{ - mpegts_apid_t *p; - int i; +int mpegts_pid_add(mpegts_apids_t* pids, uint16_t pid, uint16_t weight) { + mpegts_apid_t* p; + int i; if (mpegts_pid_wexists(pids, pid, weight)) return 0; @@ -109,27 +93,25 @@ mpegts_pid_add(mpegts_apids_t *pids, uint16_t pid, uint16_t weight) p = realloc(pids->pids, i * sizeof(*p)); if (p == NULL) return -1; - pids->pids = p; + pids->pids = p; pids->alloc = i; } p = pids->pids; if (pids->sorted) { for (i = pids->count++; i > 0 && pid_cmp(pid, weight, &p[i - 1]) > 0; i--) p[i] = p[i - 1]; - p[i].pid = pid; + p[i].pid = pid; p[i].weight = weight; } else { - p[pids->count].pid = pid; + p[pids->count].pid = pid; p[pids->count++].weight = weight; } return 0; } -int -mpegts_pid_add_group(mpegts_apids_t *pids, mpegts_apids_t *vals) -{ - int i, r; - mpegts_apid_t *p; +int mpegts_pid_add_group(mpegts_apids_t* pids, mpegts_apids_t* vals) { + int i, r; + mpegts_apid_t* p; for (i = 0; i < vals->count; i++) { p = &vals->pids[i]; @@ -140,15 +122,13 @@ mpegts_pid_add_group(mpegts_apids_t *pids, mpegts_apids_t *vals) return 0; } -int -mpegts_pid_find_windex(mpegts_apids_t *pids, uint16_t pid, uint16_t weight) -{ - mpegts_apid_t *p = pids->pids; - int first, last, i, cmp; +int mpegts_pid_find_windex(mpegts_apids_t* pids, uint16_t pid, uint16_t weight) { + mpegts_apid_t* p = pids->pids; + int first, last, i, cmp; if (pids->sorted) { first = 0; - last = pids->count - 1; + last = pids->count - 1; for (i = last / 2; first <= last; i = (first + last) / 2) { cmp = pid_cmp(pid, weight, &p[i]); if (cmp < 0) @@ -166,15 +146,13 @@ mpegts_pid_find_windex(mpegts_apids_t *pids, uint16_t pid, uint16_t weight) return -1; } -int -mpegts_pid_find_rindex(mpegts_apids_t *pids, uint16_t pid) -{ - mpegts_apid_t *p = pids->pids; - int i, first, last; +int mpegts_pid_find_rindex(mpegts_apids_t* pids, uint16_t pid) { + mpegts_apid_t* p = pids->pids; + int i, first, last; if (pids->sorted) { first = 0; - last = pids->count - 1; + last = pids->count - 1; for (i = last / 2; first <= last; i = (first + last) / 2) { if (pid > p[i].pid) first = i + 1; @@ -191,16 +169,13 @@ mpegts_pid_find_rindex(mpegts_apids_t *pids, uint16_t pid) return -1; } -int -mpegts_pid_del(mpegts_apids_t *pids, uint16_t pid, uint16_t weight) -{ +int mpegts_pid_del(mpegts_apids_t* pids, uint16_t pid, uint16_t weight) { int i; assert(pids); assert(pid >= 0 && pid <= 8191); if ((i = mpegts_pid_find_windex(pids, pid, weight)) >= 0) { - memmove(&pids->pids[i], &pids->pids[i+1], - (pids->count - i - 1) * sizeof(mpegts_apid_t)); + memmove(&pids->pids[i], &pids->pids[i + 1], (pids->count - i - 1) * sizeof(mpegts_apid_t)); pids->count--; return 0; } else { @@ -208,11 +183,9 @@ mpegts_pid_del(mpegts_apids_t *pids, uint16_t pid, uint16_t weight) } } -int -mpegts_pid_del_group(mpegts_apids_t *pids, mpegts_apids_t *vals) -{ - mpegts_apid_t *p; - int i, r; +int mpegts_pid_del_group(mpegts_apids_t* pids, mpegts_apids_t* vals) { + mpegts_apid_t* p; + int i, r; for (i = 0; i < vals->count; i++) { p = &vals->pids[i]; @@ -223,31 +196,27 @@ mpegts_pid_del_group(mpegts_apids_t *pids, mpegts_apids_t *vals) return 0; } -int -mpegts_pid_copy(mpegts_apids_t *dst, mpegts_apids_t *src) -{ - mpegts_apid_t *p; - int i; +int mpegts_pid_copy(mpegts_apids_t* dst, mpegts_apids_t* src) { + mpegts_apid_t* p; + int i; if (dst->alloc < src->alloc) { i = src->alloc; p = realloc(dst->pids, i * sizeof(*p)); if (p == NULL) return -1; - dst->pids = p; + dst->pids = p; dst->alloc = i; } - dst->count = src->count; - dst->all = src->all; + dst->count = src->count; + dst->all = src->all; dst->sorted = src->sorted; memcpy(dst->pids, src->pids, src->count * sizeof(mpegts_apid_t)); return 0; } -int -mpegts_pid_cmp(mpegts_apids_t *a, mpegts_apids_t *b) -{ - int i; +int mpegts_pid_cmp(mpegts_apids_t* a, mpegts_apids_t* b) { + int i; mpegts_apid_t *p1, *p2; if (a->count != b->count) @@ -261,20 +230,18 @@ mpegts_pid_cmp(mpegts_apids_t *a, mpegts_apids_t *b) return 0; } -static void -mpegts_pid_update_max_weight_by_index(mpegts_apids_t *a, int i, uint16_t weight) -{ - uint16_t *w = &a->pids[i].weight; +static void mpegts_pid_update_max_weight_by_index(mpegts_apids_t* a, int i, uint16_t weight) { + uint16_t* w = &a->pids[i].weight; if (*w < weight) *w = weight; } -int -mpegts_pid_compare(mpegts_apids_t *dst, mpegts_apids_t *src, - mpegts_apids_t *add, mpegts_apids_t *del) -{ - mpegts_apid_t *p; - int i, j; +int mpegts_pid_compare(mpegts_apids_t* dst, + mpegts_apids_t* src, + mpegts_apids_t* add, + mpegts_apids_t* del) { + mpegts_apid_t* p; + int i, j; assert(dst); assert(add); @@ -308,12 +275,12 @@ mpegts_pid_compare(mpegts_apids_t *dst, mpegts_apids_t *src, return add->count || del->count; } -int -mpegts_pid_compare_weight(mpegts_apids_t *dst, mpegts_apids_t *src, - mpegts_apids_t *add, mpegts_apids_t *del) -{ - mpegts_apid_t *p; - int i; +int mpegts_pid_compare_weight(mpegts_apids_t* dst, + mpegts_apids_t* src, + mpegts_apids_t* add, + mpegts_apids_t* del) { + mpegts_apid_t* p; + int i; assert(dst); assert(add); @@ -337,13 +304,10 @@ mpegts_pid_compare_weight(mpegts_apids_t *dst, mpegts_apids_t *src, return add->count || del->count; } -int -mpegts_pid_weighted - (mpegts_apids_t *dst, mpegts_apids_t *pids, int limit, int mweight) -{ - int i, j, overlimit = 0; +int mpegts_pid_weighted(mpegts_apids_t* dst, mpegts_apids_t* pids, int limit, int mweight) { + int i, j, overlimit = 0; mpegts_apids_t sorted; - mpegts_apid_t *p; + mpegts_apid_t* p; mpegts_pid_init(&sorted); mpegts_pid_copy(&sorted, pids); @@ -358,7 +322,7 @@ mpegts_pid_weighted else mpegts_pid_update_max_weight_by_index(dst, j, p->weight); } - for ( ; i < sorted.count; i++) { + for (; i < sorted.count; i++) { p = &sorted.pids[i]; if (p->weight < mweight) continue; @@ -371,12 +335,10 @@ mpegts_pid_weighted return overlimit; } -int -mpegts_pid_dump(mpegts_apids_t *pids, char *buf, int len, int wflag, int raw) -{ +int mpegts_pid_dump(mpegts_apids_t* pids, char* buf, int len, int wflag, int raw) { mpegts_apids_t spids; - mpegts_apid_t *p; - int i, l = 0; + mpegts_apid_t* p; + int i, l = 0; if (len < 1) return len; @@ -394,7 +356,7 @@ mpegts_pid_dump(mpegts_apids_t *pids, char *buf, int len, int wflag, int raw) } } else { for (i = 0; i < pids->count && l + 1 < len; i++) - tvh_strlcatf(buf, len, l, "%s%i", i > 0 ? "," : "", pids->pids[i].pid); + tvh_strlcatf(buf, len, l, "%s%i", i > 0 ? "," : "", pids->pids[i].pid); } if (pids == &spids) mpegts_pid_done(&spids); diff --git a/src/input/mpegts/mpegts_service.c b/src/input/mpegts/mpegts_service.c index 9114131b4..9c21f34a1 100644 --- a/src/input/mpegts/mpegts_service.c +++ b/src/input/mpegts/mpegts_service.c @@ -35,11 +35,9 @@ extern const idclass_t service_class; -static const void * -mpegts_service_class_get_mux ( void *ptr ) -{ - static char buf[512], *s = buf; - mpegts_service_t *ms = ptr; +static const void* mpegts_service_class_get_mux(void* ptr) { + static char buf[512], *s = buf; + mpegts_service_t* ms = ptr; if (ms->s_dvb_mux && ms->s_dvb_mux->mm_display_name) ms->s_dvb_mux->mm_display_name(ms->s_dvb_mux, buf, sizeof(buf)); else @@ -47,10 +45,8 @@ mpegts_service_class_get_mux ( void *ptr ) return &s; } -static const void * -mpegts_service_class_get_mux_uuid ( void *ptr ) -{ - mpegts_service_t *ms = ptr; +static const void* mpegts_service_class_get_mux_uuid(void* ptr) { + mpegts_service_t* ms = ptr; if (ms && ms->s_dvb_mux) idnode_uuid_as_str(&ms->s_dvb_mux->mm_id, prop_sbuf); else @@ -58,12 +54,10 @@ mpegts_service_class_get_mux_uuid ( void *ptr ) return &prop_sbuf_ptr; } -static const void * -mpegts_service_class_get_network ( void *ptr ) -{ - static char buf[512], *s = buf; - mpegts_service_t *ms = ptr; - mpegts_network_t *mn = ms->s_dvb_mux ? ms->s_dvb_mux->mm_network : NULL; +static const void* mpegts_service_class_get_network(void* ptr) { + static char buf[512], *s = buf; + mpegts_service_t* ms = ptr; + mpegts_network_t* mn = ms->s_dvb_mux ? ms->s_dvb_mux->mm_network : NULL; if (mn && mn->mn_display_name) mn->mn_display_name(mn, buf, sizeof(buf)); else @@ -71,198 +65,194 @@ mpegts_service_class_get_network ( void *ptr ) return &s; } -static htsmsg_t * -mpegts_service_pref_capid_lock_list ( void *o, const char *lang ) -{ +static htsmsg_t* mpegts_service_pref_capid_lock_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Off"), 0 }, - { N_("On"), 1 }, - { N_("Only preferred CA PID"), 2 }, + {N_("Off"), 0}, + {N_("On"), 1}, + {N_("Only preferred CA PID"), 2}, }; - return strtab2htsmsg(tab, 1, lang); + return strtab2htsmsg(tab, 1, lang); } CLASS_DOC(mpegts_service) -const idclass_t mpegts_service_class = -{ - .ic_super = &service_class, - .ic_class = "mpegts_service", - .ic_caption = N_("DVB Inputs - Services"), - .ic_doc = tvh_doc_mpegts_service_class, - .ic_order = "enabled,channel,svcname", - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "network", - .name = N_("Network"), - .desc = N_("The network the service is on."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = mpegts_service_class_get_network, - }, - { - .type = PT_STR, - .id = "multiplex", - .name = N_("Mux"), - .desc = N_("The mux the service is on."), - .opts = PO_RDONLY | PO_NOSAVE, - .get = mpegts_service_class_get_mux, - }, - { - .type = PT_STR, - .id = "multiplex_uuid", - .name = N_("Mux UUID"), - .desc = N_("The mux's universally unique identifier."), - .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_EXPERT, - .get = mpegts_service_class_get_mux_uuid, - }, - { - .type = PT_U16, - .id = "sid", - .name = N_("Service ID"), - .desc = N_("The service ID as set by the provider."), - .opts = PO_RDONLY | PO_ADVANCED, - .off = offsetof(mpegts_service_t, s_components.set_service_id), - }, - { - .type = PT_U16, - .id = "lcn", - .name = N_("Local channel number"), - .desc = N_("The service's channel number as set by the provider."), - .opts = PO_RDONLY | PO_ADVANCED, - .off = offsetof(mpegts_service_t, s_dvb_channel_num), - }, - { - .type = PT_U16, - .id = "lcn_minor", - .name = N_("Local channel minor"), - .desc = N_("The service's channel minor as set by the provider."), - .opts = PO_RDONLY | PO_EXPERT, - .off = offsetof(mpegts_service_t, s_dvb_channel_minor), - }, - { - .type = PT_U16, - .id = "lcn2", - .name = N_("OpenTV channel number"), - .desc = N_("The OpenTV channel number as set by the provider."), - .opts = PO_RDONLY | PO_EXPERT, - .off = offsetof(mpegts_service_t, s_dvb_opentv_chnum), - }, - { - .type = PT_U16, - .id = "srcid", - .name = N_("ATSC source ID"), - .desc = N_("The ATSC source ID as set by the provider."), - .opts = PO_RDONLY | PO_EXPERT, - .off = offsetof(mpegts_service_t, s_atsc_source_id), - }, - { - .type = PT_STR, - .id = "svcname", - .name = N_("Service name"), - .desc = N_("The service name as set by the provider."), - .opts = PO_RDONLY, - .off = offsetof(mpegts_service_t, s_dvb_svcname), - }, - { - .type = PT_STR, - .id = "provider", - .name = N_("Provider"), - .desc = N_("The provider's name."), - .opts = PO_RDONLY | PO_HIDDEN, - .off = offsetof(mpegts_service_t, s_dvb_provider), - }, - { - .type = PT_STR, - .id = "cridauth", - .name = N_("CRID authority"), - .desc = N_("Content reference identifier authority."), - .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, - .off = offsetof(mpegts_service_t, s_dvb_cridauth), - }, - { - .type = PT_U16, - .id = "dvb_servicetype", - .name = N_("Service type"), - .desc = N_("The service type flag as defined by the DVB " - "specifications (e.g. 0x02 = radio, 0x11 = MPEG2 " - "HD TV, 0x19 = H.264 HD TV)"), - .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, - .off = offsetof(mpegts_service_t, s_dvb_servicetype), - }, - { - .type = PT_BOOL, - .id = "dvb_ignore_eit", - .name = N_("Ignore EPG (EIT)"), - .desc = N_("Enable or disable ignoring of Event Information " - "Table (EIT) data for this service."), - .off = offsetof(mpegts_service_t, s_dvb_ignore_eit), - .opts = PO_EXPERT, - }, - { - .type = PT_STR, - .id = "charset", - .name = N_("Character set"), - .desc = N_("The character encoding for this service (e.g. UTF-8)."), - .off = offsetof(mpegts_service_t, s_dvb_charset), - .list = dvb_charset_enum, - .opts = PO_EXPERT | PO_DOC_NLIST, - }, - { - .type = PT_U16, - .id = "prefcapid", - .name = N_("Preferred CA PID"), - .desc = N_("The Preferred Conditional Access Packet " - "Identifier. Used for decrypting scrambled streams."), - .off = offsetof(mpegts_service_t, s_dvb_prefcapid), - .opts = PO_EXPERT, - }, - { - .type = PT_INT, - .id = "prefcapid_lock", - .name = N_("Lock preferred CA PID"), - .desc = N_("The locking mechanism selection for The Preferred " - "Conditional Access Packet Identifier. See Help " - "for more information."), - .off = offsetof(mpegts_service_t, s_dvb_prefcapid_lock), - .opts = PO_EXPERT | PO_DOC_NLIST, - .list = mpegts_service_pref_capid_lock_list, - }, - { - .type = PT_U16, - .id = "force_caid", - .name = N_("Force CA ID (e.g. 0x2600)"), - .desc = N_("Force usage of entered CA ID on this service."), - .off = offsetof(mpegts_service_t, s_dvb_forcecaid), - .opts = PO_EXPERT | PO_HEXA, - }, - { - .type = PT_INT, - .id = "pts_shift", - .name = N_("Shift PTS (ms)"), - .desc = N_("Add this value to PTS for the teletext subtitles. The time value is in milliseconds and may be negative."), - .off = offsetof(mpegts_service_t, s_pts_shift), - .opts = PO_EXPERT, - }, - { - .type = PT_TIME, - .id = "created", - .name = N_("Created"), - .desc = N_("When the service was first identified and recorded."), - .off = offsetof(mpegts_service_t, s_dvb_created), - .opts = PO_ADVANCED | PO_RDONLY, - }, - { - .type = PT_TIME, - .id = "last_seen", - .name = N_("Last seen"), - .desc = N_("When the service was last seen during a mux scan."), - .off = offsetof(mpegts_service_t, s_dvb_last_seen), - .opts = PO_ADVANCED | PO_RDONLY, - }, - {}, - } -}; +const idclass_t mpegts_service_class = {.ic_super = &service_class, + .ic_class = "mpegts_service", + .ic_caption = N_("DVB Inputs - Services"), + .ic_doc = tvh_doc_mpegts_service_class, + .ic_order = "enabled,channel,svcname", + .ic_properties = (const property_t[]){ + { + .type = PT_STR, + .id = "network", + .name = N_("Network"), + .desc = N_("The network the service is on."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = mpegts_service_class_get_network, + }, + { + .type = PT_STR, + .id = "multiplex", + .name = N_("Mux"), + .desc = N_("The mux the service is on."), + .opts = PO_RDONLY | PO_NOSAVE, + .get = mpegts_service_class_get_mux, + }, + { + .type = PT_STR, + .id = "multiplex_uuid", + .name = N_("Mux UUID"), + .desc = N_("The mux's universally unique identifier."), + .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN | PO_EXPERT, + .get = mpegts_service_class_get_mux_uuid, + }, + { + .type = PT_U16, + .id = "sid", + .name = N_("Service ID"), + .desc = N_("The service ID as set by the provider."), + .opts = PO_RDONLY | PO_ADVANCED, + .off = offsetof(mpegts_service_t, s_components.set_service_id), + }, + { + .type = PT_U16, + .id = "lcn", + .name = N_("Local channel number"), + .desc = N_("The service's channel number as set by the provider."), + .opts = PO_RDONLY | PO_ADVANCED, + .off = offsetof(mpegts_service_t, s_dvb_channel_num), + }, + { + .type = PT_U16, + .id = "lcn_minor", + .name = N_("Local channel minor"), + .desc = N_("The service's channel minor as set by the provider."), + .opts = PO_RDONLY | PO_EXPERT, + .off = offsetof(mpegts_service_t, s_dvb_channel_minor), + }, + { + .type = PT_U16, + .id = "lcn2", + .name = N_("OpenTV channel number"), + .desc = N_("The OpenTV channel number as set by the provider."), + .opts = PO_RDONLY | PO_EXPERT, + .off = offsetof(mpegts_service_t, s_dvb_opentv_chnum), + }, + { + .type = PT_U16, + .id = "srcid", + .name = N_("ATSC source ID"), + .desc = N_("The ATSC source ID as set by the provider."), + .opts = PO_RDONLY | PO_EXPERT, + .off = offsetof(mpegts_service_t, s_atsc_source_id), + }, + { + .type = PT_STR, + .id = "svcname", + .name = N_("Service name"), + .desc = N_("The service name as set by the provider."), + .opts = PO_RDONLY, + .off = offsetof(mpegts_service_t, s_dvb_svcname), + }, + { + .type = PT_STR, + .id = "provider", + .name = N_("Provider"), + .desc = N_("The provider's name."), + .opts = PO_RDONLY | PO_HIDDEN, + .off = offsetof(mpegts_service_t, s_dvb_provider), + }, + { + .type = PT_STR, + .id = "cridauth", + .name = N_("CRID authority"), + .desc = N_("Content reference identifier authority."), + .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, + .off = offsetof(mpegts_service_t, s_dvb_cridauth), + }, + { + .type = PT_U16, + .id = "dvb_servicetype", + .name = N_("Service type"), + .desc = N_("The service type flag as defined by the DVB " + "specifications (e.g. 0x02 = radio, 0x11 = MPEG2 " + "HD TV, 0x19 = H.264 HD TV)"), + .opts = PO_RDONLY | PO_HIDDEN | PO_EXPERT, + .off = offsetof(mpegts_service_t, s_dvb_servicetype), + }, + { + .type = PT_BOOL, + .id = "dvb_ignore_eit", + .name = N_("Ignore EPG (EIT)"), + .desc = N_("Enable or disable ignoring of Event Information " + "Table (EIT) data for this service."), + .off = offsetof(mpegts_service_t, s_dvb_ignore_eit), + .opts = PO_EXPERT, + }, + { + .type = PT_STR, + .id = "charset", + .name = N_("Character set"), + .desc = N_("The character encoding for this service (e.g. UTF-8)."), + .off = offsetof(mpegts_service_t, s_dvb_charset), + .list = dvb_charset_enum, + .opts = PO_EXPERT | PO_DOC_NLIST, + }, + { + .type = PT_U16, + .id = "prefcapid", + .name = N_("Preferred CA PID"), + .desc = N_("The Preferred Conditional Access Packet " + "Identifier. Used for decrypting scrambled streams."), + .off = offsetof(mpegts_service_t, s_dvb_prefcapid), + .opts = PO_EXPERT, + }, + { + .type = PT_INT, + .id = "prefcapid_lock", + .name = N_("Lock preferred CA PID"), + .desc = N_("The locking mechanism selection for The Preferred " + "Conditional Access Packet Identifier. See Help " + "for more information."), + .off = offsetof(mpegts_service_t, s_dvb_prefcapid_lock), + .opts = PO_EXPERT | PO_DOC_NLIST, + .list = mpegts_service_pref_capid_lock_list, + }, + { + .type = PT_U16, + .id = "force_caid", + .name = N_("Force CA ID (e.g. 0x2600)"), + .desc = N_("Force usage of entered CA ID on this service."), + .off = offsetof(mpegts_service_t, s_dvb_forcecaid), + .opts = PO_EXPERT | PO_HEXA, + }, + { + .type = PT_INT, + .id = "pts_shift", + .name = N_("Shift PTS (ms)"), + .desc = N_("Add this value to PTS for the teletext subtitles. The time value is in " + "milliseconds and may be negative."), + .off = offsetof(mpegts_service_t, s_pts_shift), + .opts = PO_EXPERT, + }, + { + .type = PT_TIME, + .id = "created", + .name = N_("Created"), + .desc = N_("When the service was first identified and recorded."), + .off = offsetof(mpegts_service_t, s_dvb_created), + .opts = PO_ADVANCED | PO_RDONLY, + }, + { + .type = PT_TIME, + .id = "last_seen", + .name = N_("Last seen"), + .desc = N_("When the service was last seen during a mux scan."), + .off = offsetof(mpegts_service_t, s_dvb_last_seen), + .opts = PO_ADVANCED | PO_RDONLY, + }, + {}, + }}; /* ************************************************************************** * Class methods @@ -271,51 +261,46 @@ const idclass_t mpegts_service_class = /* * Check the service is enabled */ -static int -mpegts_service_is_enabled(service_t *t, int flags) -{ - mpegts_service_t *s = (mpegts_service_t*)t; - mpegts_mux_t *mm = s->s_dvb_mux; - if (!s->s_verified) return 0; +static int mpegts_service_is_enabled(service_t* t, int flags) { + mpegts_service_t* s = (mpegts_service_t*)t; + mpegts_mux_t* mm = s->s_dvb_mux; + if (!s->s_verified) + return 0; return mm->mm_is_enabled(mm) ? s->s_enabled : 0; } -static int -mpegts_service_is_enabled_raw(service_t *t, int flags) -{ - mpegts_service_t *s = (mpegts_service_t*)t; - mpegts_mux_t *mm = s->s_dvb_mux; +static int mpegts_service_is_enabled_raw(service_t* t, int flags) { + mpegts_service_t* s = (mpegts_service_t*)t; + mpegts_mux_t* mm = s->s_dvb_mux; return mm->mm_is_enabled(mm) ? s->s_enabled : 0; } /* * Save */ -static htsmsg_t * -mpegts_service_config_save ( service_t *t, char *filename, size_t fsize ) -{ +static htsmsg_t* mpegts_service_config_save(service_t* t, char* filename, size_t fsize) { if (filename == NULL) { - htsmsg_t *e = htsmsg_create_map(); + htsmsg_t* e = htsmsg_create_map(); service_save(t, e); return e; } - idnode_changed(&((mpegts_service_t *)t)->s_dvb_mux->mm_id); + idnode_changed(&((mpegts_service_t*)t)->s_dvb_mux->mm_id); return NULL; } /* * Service instance list */ -static int -mpegts_service_enlist_raw - ( service_t *t, tvh_input_t *ti, struct service_instance_list *sil, - int flags, int weight ) -{ - int p, w, r, added = 0, errcnt = 0; - mpegts_service_t *s = (mpegts_service_t*)t; - mpegts_input_t *mi; - mpegts_mux_t *m = s->s_dvb_mux; - mpegts_mux_instance_t *mmi; +static int mpegts_service_enlist_raw(service_t* t, + tvh_input_t* ti, + struct service_instance_list* sil, + int flags, + int weight) { + int p, w, r, added = 0, errcnt = 0; + mpegts_service_t* s = (mpegts_service_t*)t; + mpegts_input_t* mi; + mpegts_mux_t* m = s->s_dvb_mux; + mpegts_mux_instance_t* mmi; assert(s->s_source_type == S_MPEG_TS); @@ -323,25 +308,35 @@ mpegts_service_enlist_raw m->mm_create_instances(m); /* Enlist available */ - LIST_FOREACH(mmi, &m->mm_instances, mmi_mux_link) { + LIST_FOREACH (mmi, &m->mm_instances, mmi_mux_link) { if (mmi->mmi_tune_failed) continue; mi = mmi->mmi_input; - if (ti && (tvh_input_t *)mi != ti) + if (ti && (tvh_input_t*)mi != ti) continue; r = mi->mi_is_enabled(mi, mmi->mmi_mux, flags, weight); if (r == MI_IS_ENABLED_NEVER) { - tvhtrace(LS_MPEGTS, "enlist: input %p not enabled for mux %p service %s weight %d flags %x", - mi, mmi->mmi_mux, s->s_nicename, weight, flags); + tvhtrace(LS_MPEGTS, + "enlist: input %p not enabled for mux %p service %s weight %d flags %x", + mi, + mmi->mmi_mux, + s->s_nicename, + weight, + flags); continue; } if (r == MI_IS_ENABLED_RETRY) { /* temporary error - retry later */ - tvhtrace(LS_MPEGTS, "enlist: input %p postponed for mux %p service %s weight %d flags %x", - mi, mmi->mmi_mux, s->s_nicename, weight, flags); + tvhtrace(LS_MPEGTS, + "enlist: input %p postponed for mux %p service %s weight %d flags %x", + mi, + mmi->mmi_mux, + s->s_nicename, + weight, + flags); errcnt++; continue; } @@ -353,8 +348,7 @@ mpegts_service_enlist_raw } else { w = mi->mi_get_weight(mi, mmi->mmi_mux, flags, weight); p = mi->mi_get_priority(mi, mmi->mmi_mux, flags); - if (w > 0 && mi->mi_free_weight && - weight >= mi->mi_free_weight && w < mi->mi_free_weight) + if (w > 0 && mi->mi_free_weight && weight >= mi->mi_free_weight && w < mi->mi_free_weight) w = 0; } @@ -368,11 +362,11 @@ mpegts_service_enlist_raw /* * Service instance list */ -static int -mpegts_service_enlist - ( service_t *t, tvh_input_t *ti, struct service_instance_list *sil, - int flags, int weight ) -{ +static int mpegts_service_enlist(service_t* t, + tvh_input_t* ti, + struct service_instance_list* sil, + int flags, + int weight) { const uint16_t pid = t->s_components.set_pmt_pid; /* invalid PMT */ @@ -385,21 +379,19 @@ mpegts_service_enlist /* * Start service */ -static int -mpegts_service_start(service_t *t, int instance, int weight, int flags) -{ - int r; - mpegts_service_t *s = (mpegts_service_t*)t; - mpegts_mux_t *m = s->s_dvb_mux; - mpegts_mux_instance_t *mmi; +static int mpegts_service_start(service_t* t, int instance, int weight, int flags) { + int r; + mpegts_service_t* s = (mpegts_service_t*)t; + mpegts_mux_t* m = s->s_dvb_mux; + mpegts_mux_instance_t* mmi; /* Validate */ - assert(s->s_status == SERVICE_IDLE); + assert(s->s_status == SERVICE_IDLE); assert(s->s_source_type == S_MPEG_TS); lock_assert(&global_lock); /* Find */ - LIST_FOREACH(mmi, &m->mm_instances, mmi_mux_link) + LIST_FOREACH (mmi, &m->mm_instances, mmi_mux_link) if (mmi->mmi_input->mi_instance == instance) break; assert(mmi != NULL); @@ -408,13 +400,13 @@ mpegts_service_start(service_t *t, int instance, int weight, int flags) /* Start Mux */ mmi->mmi_start_weight = weight; - r = mpegts_mux_instance_start(&mmi, t, weight); + r = mpegts_mux_instance_start(&mmi, t, weight); /* Start */ if (!r) { /* Open service */ - s->s_dvb_subscription_flags = flags; + s->s_dvb_subscription_flags = flags; s->s_dvb_subscription_weight = weight; mmi->mmi_input->mi_open_service(mmi->mmi_input, s, flags, 1, weight); } @@ -425,11 +417,9 @@ mpegts_service_start(service_t *t, int instance, int weight, int flags) /* * Stop service */ -static void -mpegts_service_stop(service_t *t) -{ - mpegts_service_t *s = (mpegts_service_t*)t; - mpegts_input_t *i = s->s_dvb_active_input; +static void mpegts_service_stop(service_t* t) { + mpegts_service_t* s = (mpegts_service_t*)t; + mpegts_input_t* i = s->s_dvb_active_input; /* Validate */ assert(s->s_source_type == S_MPEG_TS); @@ -446,11 +436,9 @@ mpegts_service_stop(service_t *t) /* * Refresh */ -static void -mpegts_service_refresh(service_t *t) -{ - mpegts_service_t *s = (mpegts_service_t*)t; - mpegts_input_t *i = s->s_dvb_active_input; +static void mpegts_service_refresh(service_t* t) { + mpegts_service_t* s = (mpegts_service_t*)t; + mpegts_input_t* i = s->s_dvb_active_input; /* Validate */ assert(s->s_source_type == S_MPEG_TS); @@ -464,12 +452,10 @@ mpegts_service_refresh(service_t *t) /* * Source info */ -static void -mpegts_service_setsourceinfo(service_t *t, source_info_t *si) -{ - char buf[256]; - mpegts_service_t *s = (mpegts_service_t*)t; - mpegts_mux_t *m = s->s_dvb_mux; +static void mpegts_service_setsourceinfo(service_t* t, source_info_t* si) { + char buf[256]; + mpegts_service_t* s = (mpegts_service_t*)t; + mpegts_mux_t* m = s->s_dvb_mux; /* Validate */ assert(s->s_source_type == S_MPEG_TS); @@ -481,7 +467,7 @@ mpegts_service_setsourceinfo(service_t *t, source_info_t *si) uuid_duplicate(&si->si_network_uuid, &m->mm_network->mn_id.in_uuid); uuid_duplicate(&si->si_mux_uuid, &m->mm_id.in_uuid); - if(m->mm_network->mn_network_name != NULL) + if (m->mm_network->mn_network_name != NULL) si->si_network = strdup(m->mm_network->mn_network_name); mpegts_network_get_type_str(m->mm_network, buf, sizeof(buf)); si->si_network_type = strdup(buf); @@ -489,21 +475,21 @@ mpegts_service_setsourceinfo(service_t *t, source_info_t *si) m->mm_display_name(m, buf, sizeof(buf)); si->si_mux = strdup(buf); - if(s->s_dvb_active_input) { - mpegts_input_t *mi = s->s_dvb_active_input; + if (s->s_dvb_active_input) { + mpegts_input_t* mi = s->s_dvb_active_input; uuid_duplicate(&si->si_adapter_uuid, &mi->ti_id.in_uuid); mi->mi_display_name(mi, buf, sizeof(buf)); si->si_adapter = strdup(buf); } - if(s->s_dvb_provider != NULL) + if (s->s_dvb_provider != NULL) si->si_provider = strdup(s->s_dvb_provider); - if(s->s_dvb_svcname != NULL) + if (s->s_dvb_svcname != NULL) si->si_service = strdup(s->s_dvb_svcname); #if ENABLE_MPEGTS_DVB - if(m->mm_network != NULL && m->mm_network->mn_satpos != INT_MAX) { + if (m->mm_network != NULL && m->mm_network->mn_satpos != INT_MAX) { dvb_sat_position_to_str(m->mm_network->mn_satpos, buf, sizeof(buf)); si->si_satpos = strdup(buf); } @@ -516,29 +502,25 @@ mpegts_service_setsourceinfo(service_t *t, source_info_t *si) /* * Grace period */ -static int -mpegts_service_grace_period(service_t *t) -{ - int r = 0; - mpegts_service_t *ms = (mpegts_service_t*)t; - mpegts_mux_t *mm = ms->s_dvb_mux; - mpegts_input_t *mi = ms->s_dvb_active_input; +static int mpegts_service_grace_period(service_t* t) { + int r = 0; + mpegts_service_t* ms = (mpegts_service_t*)t; + mpegts_mux_t* mm = ms->s_dvb_mux; + mpegts_input_t* mi = ms->s_dvb_active_input; assert(mi != NULL); if (mi && mi->mi_get_grace) r = mi->mi_get_grace(mi, mm); - - return r ?: 10; + + return r ?: 10; } /* * Channel number */ -int64_t -mpegts_service_channel_number ( service_t *s ) -{ - mpegts_service_t *ms = (mpegts_service_t*)s; - int64_t r = 0; +int64_t mpegts_service_channel_number(service_t* s) { + mpegts_service_t* ms = (mpegts_service_t*)s; + int64_t r = 0; if (!ms->s_dvb_mux->mm_network->mn_ignore_chnum) { r = ms->s_dvb_channel_num * CHANNEL_SPLIT + ms->s_dvb_channel_minor; @@ -550,42 +532,44 @@ mpegts_service_channel_number ( service_t *s ) return r; } -static const char * -mpegts_service_channel_name ( service_t *s ) -{ +static const char* mpegts_service_channel_name(service_t* s) { return ((mpegts_service_t*)s)->s_dvb_svcname; } -static const char * -mpegts_service_source ( service_t *s ) -{ +static const char* mpegts_service_source(service_t* s) { #if ENABLE_MPEGTS_DVB - mpegts_service_t *ms = (mpegts_service_t*)s; - const idclass_t *mux_idc = ms->s_dvb_mux->mm_id.in_class; - if (mux_idc == &dvb_mux_dvbs_class) return "DVB-S"; - if (mux_idc == &dvb_mux_dvbc_class) return "DVB-C"; - if (mux_idc == &dvb_mux_dvbt_class) return "DVB-T"; - if (mux_idc == &dvb_mux_atsc_t_class) return "ATSC-T"; - if (mux_idc == &dvb_mux_atsc_c_class) return "ATSC-C"; - if (mux_idc == &dvb_mux_isdb_t_class) return "ISDB-T"; - if (mux_idc == &dvb_mux_isdb_c_class) return "ISDB-C"; - if (mux_idc == &dvb_mux_isdb_s_class) return "ISDB-S"; - if (mux_idc == &dvb_mux_dtmb_class) return "DTMB"; - if (mux_idc == &dvb_mux_dab_class) return "DAB"; + mpegts_service_t* ms = (mpegts_service_t*)s; + const idclass_t* mux_idc = ms->s_dvb_mux->mm_id.in_class; + if (mux_idc == &dvb_mux_dvbs_class) + return "DVB-S"; + if (mux_idc == &dvb_mux_dvbc_class) + return "DVB-C"; + if (mux_idc == &dvb_mux_dvbt_class) + return "DVB-T"; + if (mux_idc == &dvb_mux_atsc_t_class) + return "ATSC-T"; + if (mux_idc == &dvb_mux_atsc_c_class) + return "ATSC-C"; + if (mux_idc == &dvb_mux_isdb_t_class) + return "ISDB-T"; + if (mux_idc == &dvb_mux_isdb_c_class) + return "ISDB-C"; + if (mux_idc == &dvb_mux_isdb_s_class) + return "ISDB-S"; + if (mux_idc == &dvb_mux_dtmb_class) + return "DTMB"; + if (mux_idc == &dvb_mux_dab_class) + return "DAB"; #endif return NULL; } -static const char * -mpegts_service_provider_name ( service_t *s ) -{ +static const char* mpegts_service_provider_name(service_t* s) { return ((mpegts_service_t*)s)->s_dvb_provider; } #if ENABLE_MPEGTS_DVB -static int -mpegts_picon_mux_isvalid(dvb_mux_t *mux, int orbital_position) -{ +static int mpegts_picon_mux_isvalid(dvb_mux_t* mux, int orbital_position) { switch (mux->mm_onid) { case 0: case 0x1111: @@ -595,25 +579,22 @@ mpegts_picon_mux_isvalid(dvb_mux_t *mux, int orbital_position) case 0x00B1: return mux->mm_tsid != 0x00B0; case 0x0002: - return abs(orbital_position-282) < 6; + return abs(orbital_position - 282) < 6; default: return mux->mm_tsid < 0xFF00; } } #endif -static const char * -mpegts_service_channel_icon ( service_t *s ) -{ +static const char* mpegts_service_channel_icon(service_t* s) { /* DVB? */ #if ENABLE_MPEGTS_DVB - mpegts_service_t *ms = (mpegts_service_t*)s; + mpegts_service_t* ms = (mpegts_service_t*)s; extern const idclass_t dvb_mux_class; - if (ms->s_dvb_mux && - idnode_is_instance(&ms->s_dvb_mux->mm_id, &dvb_mux_class)) { - int32_t hash = 0; - dvb_mux_t *mmd = (dvb_mux_t*)ms->s_dvb_mux; - int pos; + if (ms->s_dvb_mux && idnode_is_instance(&ms->s_dvb_mux->mm_id, &dvb_mux_class)) { + int32_t hash = 0; + dvb_mux_t* mmd = (dvb_mux_t*)ms->s_dvb_mux; + int pos; switch (mmd->lm_tuning.dmc_fe_type) { case DVB_TYPE_S: @@ -624,7 +605,8 @@ mpegts_service_channel_icon ( service_t *s ) hash = (pos >= 0 ? pos : 3600 + pos) << 16; if (!mpegts_picon_mux_isvalid(mmd, pos)) hash |= ((mmd->lm_tuning.dmc_fe_freq / 1000) & 0x7fff) | - (mmd->lm_tuning.u.dmc_fe_qpsk.orbital_pos == DVB_POLARISATION_HORIZONTAL ? 0x8000 : 0); + (mmd->lm_tuning.u.dmc_fe_qpsk.orbital_pos == DVB_POLARISATION_HORIZONTAL ? 0x8000 + : 0); break; case DVB_TYPE_C: case DVB_TYPE_ATSC_C: @@ -640,13 +622,14 @@ mpegts_service_channel_icon ( service_t *s ) return NULL; } - snprintf(prop_sbuf, PROP_SBUF_LEN, - "picon://1_0_%X_%X_%X_%X_%X_0_0_0.png", - config.picon_scheme == PICON_ISVCTYPE ? 1 : ms->s_dvb_servicetype, - service_id16(ms), - ms->s_dvb_mux->mm_tsid, - ms->s_dvb_mux->mm_onid, - hash); + snprintf(prop_sbuf, + PROP_SBUF_LEN, + "picon://1_0_%X_%X_%X_%X_%X_0_0_0.png", + config.picon_scheme == PICON_ISVCTYPE ? 1 : ms->s_dvb_servicetype, + service_id16(ms), + ms->s_dvb_mux->mm_tsid, + ms->s_dvb_mux->mm_onid, + hash); return prop_sbuf; } #endif @@ -655,83 +638,92 @@ mpegts_service_channel_icon ( service_t *s ) } #if ENABLE_MPEGTS_DVB -static int -mpegts_service_match_network(mpegts_network_t *mn, uint32_t hash, const idclass_t *idc) -{ +static int mpegts_service_match_network(mpegts_network_t* mn, uint32_t hash, const idclass_t* idc) { int pos, pos2; - if (idc != &dvb_mux_dvbs_class) return 1; + if (idc != &dvb_mux_dvbs_class) + return 1; pos = hash >> 16; - if (pos > 3600 || pos < 0) return 0; + if (pos > 3600 || pos < 0) + return 0; pos = pos <= 1800 ? pos : pos - 3600; - if ((pos2 = dvb_network_get_orbital_pos(mn)) == INT_MAX) return 0; + if ((pos2 = dvb_network_get_orbital_pos(mn)) == INT_MAX) + return 0; return deltaI32(pos, pos2) <= 20; } #endif #if ENABLE_MPEGTS_DVB -static int -mpegts_service_match_mux(dvb_mux_t *mm, uint32_t hash, const idclass_t *idc) -{ +static int mpegts_service_match_mux(dvb_mux_t* mm, uint32_t hash, const idclass_t* idc) { extern const idclass_t dvb_mux_dvbs_class; - dvb_mux_t *mmd; - int freq, pol; + dvb_mux_t* mmd; + int freq, pol; - if ((hash & 0xffff) == 0) return 1; - if (idc != &dvb_mux_dvbs_class) return 0; + if ((hash & 0xffff) == 0) + return 1; + if (idc != &dvb_mux_dvbs_class) + return 0; freq = (hash & 0x7fff) * 1000; - pol = (hash & 0x8000) ? DVB_POLARISATION_HORIZONTAL : DVB_POLARISATION_VERTICAL; - mmd = mm; + pol = (hash & 0x8000) ? DVB_POLARISATION_HORIZONTAL : DVB_POLARISATION_VERTICAL; + mmd = mm; return mmd->lm_tuning.u.dmc_fe_qpsk.orbital_pos == pol && - deltaU32(mmd->lm_tuning.dmc_fe_freq, freq) < 2000; + deltaU32(mmd->lm_tuning.dmc_fe_freq, freq) < 2000; } #endif -service_t * -mpegts_service_find_e2(uint32_t stype, uint32_t sid, uint32_t tsid, - uint32_t onid, uint32_t hash) -{ +service_t* +mpegts_service_find_e2(uint32_t stype, uint32_t sid, uint32_t tsid, uint32_t onid, uint32_t hash) { #if ENABLE_MPEGTS_DVB - mpegts_network_t *mn; - mpegts_mux_t *mm; - mpegts_service_t *s; - const idclass_t *idc; + mpegts_network_t* mn; + mpegts_mux_t* mm; + mpegts_service_t* s; + const idclass_t* idc; lock_assert(&global_lock); switch (hash & 0xFFFF0000) { - case 0xFFFF0000: idc = &dvb_mux_dvbc_class; break; - case 0xEEEE0000: idc = &dvb_mux_dvbt_class; break; - case 0xDDDD0000: idc = &dvb_mux_atsc_t_class; break; - default: idc = &dvb_mux_dvbs_class; break; + case 0xFFFF0000: + idc = &dvb_mux_dvbc_class; + break; + case 0xEEEE0000: + idc = &dvb_mux_dvbt_class; + break; + case 0xDDDD0000: + idc = &dvb_mux_atsc_t_class; + break; + default: + idc = &dvb_mux_dvbs_class; + break; } - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { - if (!idnode_is_instance(&mn->mn_id, &dvb_network_class)) continue; - if (dvb_network_mux_class(mn) != idc) continue; - if (!mpegts_service_match_network(mn, hash, idc)) continue; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { - if (!idnode_is_instance(&mm->mm_id, idc)) continue; - if (mm->mm_tsid != tsid || mm->mm_onid != onid) continue; - if (!mpegts_service_match_mux((dvb_mux_t *)mm, hash, idc)) continue; - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) { + if (!idnode_is_instance(&mn->mn_id, &dvb_network_class)) + continue; + if (dvb_network_mux_class(mn) != idc) + continue; + if (!mpegts_service_match_network(mn, hash, idc)) + continue; + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) { + if (!idnode_is_instance(&mm->mm_id, idc)) + continue; + if (mm->mm_tsid != tsid || mm->mm_onid != onid) + continue; + if (!mpegts_service_match_mux((dvb_mux_t*)mm, hash, idc)) + continue; + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) if (service_id16(s) == sid) - return (service_t *)s; + return (service_t*)s; } } #endif return NULL; } -static void -mpegts_service_mapped ( service_t *t ) -{ - epggrab_ota_queue_mux(((mpegts_service_t *)t)->s_dvb_mux); +static void mpegts_service_mapped(service_t* t) { + epggrab_ota_queue_mux(((mpegts_service_t*)t)->s_dvb_mux); } -void -mpegts_service_unref ( service_t *t ) -{ - mpegts_service_t *ms = (mpegts_service_t*)t; +void mpegts_service_unref(service_t* t) { + mpegts_service_t* ms = (mpegts_service_t*)t; free(ms->s_dvb_svcname); free(ms->s_dvb_provider); @@ -739,11 +731,9 @@ mpegts_service_unref ( service_t *t ) free(ms->s_dvb_charset); } -void -mpegts_service_delete ( service_t *t, int delconf ) -{ +void mpegts_service_delete(service_t* t, int delconf) { mpegts_service_t *ms = (mpegts_service_t*)t, *mms; - mpegts_mux_t *mm = t->s_type == STYPE_STD ? ms->s_dvb_mux : NULL; + mpegts_mux_t* mm = t->s_type == STYPE_STD ? ms->s_dvb_mux : NULL; if (mm) idnode_changed(&mm->mm_id); @@ -755,7 +745,7 @@ mpegts_service_delete ( service_t *t, int delconf ) /* Remove master/slave linking */ while (ms->s_masters.is_count > 0) { - mms = (mpegts_service_t *)ms->s_masters.is_array[0]; + mms = (mpegts_service_t*)ms->s_masters.is_array[0]; mms->s_unlink(mms, ms); } idnode_set_clear(&ms->s_masters); @@ -769,29 +759,26 @@ mpegts_service_delete ( service_t *t, int delconf ) // is done in service_destroy } -static int -mpegts_service_satip_source ( service_t *t ) -{ - mpegts_service_t *ms = (mpegts_service_t*)t; - mpegts_network_t *mn = ms->s_dvb_mux ? ms->s_dvb_mux->mm_network : NULL; +static int mpegts_service_satip_source(service_t* t) { + mpegts_service_t* ms = (mpegts_service_t*)t; + mpegts_network_t* mn = ms->s_dvb_mux ? ms->s_dvb_mux->mm_network : NULL; return mn ? mn->mn_satip_source : -1; } -static mpegts_apids_t * -mpegts_service_pid_list_ ( service_t *t, void *owner ) -{ - mpegts_service_t *ms = (mpegts_service_t*)t; - mpegts_apids_t *pids = NULL; - mpegts_input_t *mi = ms->s_dvb_active_input; - mpegts_mux_t *mm; - mpegts_pid_sub_t *mps; - mpegts_pid_t *mp; - - if (mi == NULL) return NULL; +static mpegts_apids_t* mpegts_service_pid_list_(service_t* t, void* owner) { + mpegts_service_t* ms = (mpegts_service_t*)t; + mpegts_apids_t* pids = NULL; + mpegts_input_t* mi = ms->s_dvb_active_input; + mpegts_mux_t* mm; + mpegts_pid_sub_t* mps; + mpegts_pid_t* mp; + + if (mi == NULL) + return NULL; tvh_mutex_lock(&mi->mi_output_lock); mm = ms->s_dvb_mux; - RB_FOREACH(mp, &mm->mm_pids, mp_link) { - RB_FOREACH(mps, &mp->mp_subs, mps_link) { + RB_FOREACH (mp, &mm->mm_pids, mp_link) { + RB_FOREACH (mps, &mp->mp_subs, mps_link) { if (owner == NULL || mps->mps_owner == owner) { if (pids == NULL) pids = mpegts_pid_alloc(); @@ -804,16 +791,12 @@ mpegts_service_pid_list_ ( service_t *t, void *owner ) return pids; } -static mpegts_apids_t * -mpegts_service_pid_list ( service_t *t ) -{ +static mpegts_apids_t* mpegts_service_pid_list(service_t* t) { return mpegts_service_pid_list_(t, t); } -static void -mpegts_service_memoryinfo ( service_t *t, int64_t *size ) -{ - mpegts_service_t *ms = (mpegts_service_t*)t; +static void mpegts_service_memoryinfo(service_t* t, int64_t* size) { + mpegts_service_t* ms = (mpegts_service_t*)t; *size += sizeof(*ms); *size += tvh_strlen(ms->s_nicename); *size += tvh_strlen(ms->s_dvb_svcname); @@ -822,12 +805,11 @@ mpegts_service_memoryinfo ( service_t *t, int64_t *size ) *size += tvh_strlen(ms->s_dvb_charset); } -static int -mpegts_service_unseen( service_t *t, const char *type, time_t before ) -{ - mpegts_service_t *ms = (mpegts_service_t*)t; - int pat = type && strcasecmp(type, "pat") == 0; - if (pat && ms->s_auto != SERVICE_AUTO_PAT_MISSING) return 0; +static int mpegts_service_unseen(service_t* t, const char* type, time_t before) { + mpegts_service_t* ms = (mpegts_service_t*)t; + int pat = type && strcasecmp(type, "pat") == 0; + if (pat && ms->s_auto != SERVICE_AUTO_PAT_MISSING) + return 0; return ms->s_dvb_last_seen < before; } @@ -838,24 +820,27 @@ mpegts_service_unseen( service_t *t, const char *type, time_t before ) /* * Create service */ -mpegts_service_t * -mpegts_service_create0 - ( mpegts_service_t *s, const idclass_t *class, const char *uuid, - mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, htsmsg_t *conf ) -{ - int r; - mpegts_network_t *mn = mm->mm_network; - time_t dispatch_clock = gclk(); +mpegts_service_t* mpegts_service_create0(mpegts_service_t* s, + const idclass_t* class, + const char* uuid, + mpegts_mux_t* mm, + uint16_t sid, + uint16_t pmt_pid, + htsmsg_t* conf) { + int r; + mpegts_network_t* mn = mm->mm_network; + time_t dispatch_clock = gclk(); /* defaults for older version */ s->s_dvb_created = dispatch_clock; if (!conf) { - if (sid) s->s_components.set_service_id = sid; - if (pmt_pid) s->s_components.set_pmt_pid = pmt_pid; + if (sid) + s->s_components.set_service_id = sid; + if (pmt_pid) + s->s_components.set_pmt_pid = pmt_pid; } - if (service_create0((service_t*)s, STYPE_STD, class, uuid, - S_MPEG_TS, conf) == NULL) + if (service_create0((service_t*)s, STYPE_STD, class, uuid, S_MPEG_TS, conf) == NULL) return NULL; /* Create */ @@ -864,11 +849,11 @@ mpegts_service_create0 if (s->s_dvb_last_seen > gclk()) /* sanity check */ s->s_dvb_last_seen = gclk(); } - s->s_dvb_mux = mm; + s->s_dvb_mux = mm; if ((r = dvb_servicetype_lookup(s->s_dvb_servicetype)) != -1) s->s_servicetype = r; LIST_INSERT_HEAD(&mm->mm_services, s, s_dvb_mux_link); - + s->s_delete = mpegts_service_delete; s->s_unref = mpegts_service_unref; s->s_is_enabled = mpegts_service_is_enabled; @@ -894,8 +879,11 @@ mpegts_service_create0 service_make_nicename((service_t*)s); tvh_mutex_unlock(&s->s_stream_mutex); - tvhdebug(LS_MPEGTS, "%s - add service %04X %s", - mm->mm_nicename, service_id16(s), s->s_dvb_svcname); + tvhdebug(LS_MPEGTS, + "%s - add service %04X %s", + mm->mm_nicename, + service_id16(s), + s->s_dvb_svcname); /* Bouquet */ mpegts_network_bouquet_trigger(mn, 1); @@ -906,7 +894,7 @@ mpegts_service_create0 /* Save the create time */ if (s->s_dvb_created == dispatch_clock) - service_request_save((service_t *)s); + service_request_save((service_t*)s); return s; } @@ -914,12 +902,9 @@ mpegts_service_create0 /* * Find service */ -mpegts_service_t * -mpegts_service_find - ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid, - int create, int *save ) -{ - mpegts_service_t *s; +mpegts_service_t* +mpegts_service_find(mpegts_mux_t* mm, uint16_t sid, uint16_t pmt_pid, int create, int* save) { + mpegts_service_t* s; /* Validate */ lock_assert(&global_lock); @@ -928,18 +913,20 @@ mpegts_service_find return NULL; /* Find existing service */ - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) { + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) { if (service_id16(s) == sid) { if (pmt_pid && pmt_pid != s->s_components.set_pmt_pid) { s->s_components.set_pmt_pid = pmt_pid; if (s->s_pmt_mon) mpegts_input_open_pmt_monitor(mm, s); - if (save) *save = 1; + if (save) + *save = 1; } if (create) { if ((save && *save) || s->s_dvb_last_seen + 3600 < gclk()) { s->s_dvb_last_seen = gclk(); - if (save) *save = 1; + if (save) + *save = 1; } } return s; @@ -948,9 +935,10 @@ mpegts_service_find /* Create */ if (create) { - s = mm->mm_network->mn_create_service(mm, sid, pmt_pid); + s = mm->mm_network->mn_create_service(mm, sid, pmt_pid); s->s_dvb_created = s->s_dvb_last_seen = gclk(); - if (save) *save = 1; + if (save) + *save = 1; } return s; @@ -959,18 +947,15 @@ mpegts_service_find /* * Find PID */ -mpegts_service_t * -mpegts_service_find_by_pid ( mpegts_mux_t *mm, int pid ) -{ - mpegts_service_t *s; +mpegts_service_t* mpegts_service_find_by_pid(mpegts_mux_t* mm, int pid) { + mpegts_service_t* s; lock_assert(&global_lock); /* Find existing service */ - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) { + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) { tvh_mutex_lock(&s->s_stream_mutex); - if (pid == s->s_components.set_pmt_pid || - pid == s->s_components.set_pcr_pid) + if (pid == s->s_components.set_pmt_pid || pid == s->s_components.set_pcr_pid) goto ok; if (elementary_stream_find(&s->s_components, pid)) goto ok; @@ -985,16 +970,15 @@ ok: /* * Auto-enable service */ -void -mpegts_service_autoenable( mpegts_service_t *s, const char *where ) -{ +void mpegts_service_autoenable(mpegts_service_t* s, const char* where) { if (!s->s_enabled && s->s_auto == SERVICE_AUTO_PAT_MISSING) { - tvhinfo(LS_MPEGTS, "enabling service %s [sid %04X/%d] (found in %s)", - s->s_nicename, - service_id16(s), - service_id16(s), - where); - service_set_enabled((service_t *)s, 1, SERVICE_AUTO_NORMAL); + tvhinfo(LS_MPEGTS, + "enabling service %s [sid %04X/%d] (found in %s)", + s->s_nicename, + service_id16(s), + service_id16(s), + where); + service_set_enabled((service_t*)s, 1, SERVICE_AUTO_NORMAL); } s->s_dvb_check_seen = gclk(); } @@ -1003,32 +987,25 @@ mpegts_service_autoenable( mpegts_service_t *s, const char *where ) * Raw MPEGTS Service */ -const idclass_t mpegts_service_raw_class = -{ - .ic_super = &service_raw_class, - .ic_class = "mpegts_raw_service", - .ic_caption = N_("MPEG-TS raw service"), - .ic_properties = NULL -}; - -static void -mpegts_service_raw_setsourceinfo(service_t *t, source_info_t *si) -{ +const idclass_t mpegts_service_raw_class = {.ic_super = &service_raw_class, + .ic_class = "mpegts_raw_service", + .ic_caption = N_("MPEG-TS raw service"), + .ic_properties = NULL}; + +static void mpegts_service_raw_setsourceinfo(service_t* t, source_info_t* si) { mpegts_service_setsourceinfo(t, si); free(si->si_service); si->si_service = strdup("Raw PID Subscription"); } -static int -mpegts_service_raw_update_pids(mpegts_service_t *t, mpegts_apids_t *pids) -{ - mpegts_input_t *mi = t->s_dvb_active_input; - mpegts_mux_t *mm = t->s_dvb_mux; +static int mpegts_service_raw_update_pids(mpegts_service_t* t, mpegts_apids_t* pids) { + mpegts_input_t* mi = t->s_dvb_active_input; + mpegts_mux_t* mm = t->s_dvb_mux; mpegts_apids_t *p, *x; - mpegts_apids_t add, del; - mpegts_apid_t *pi; - int i; + mpegts_apids_t add, del; + mpegts_apid_t* pi; + int i; lock_assert(&global_lock); if (pids) { @@ -1040,7 +1017,7 @@ mpegts_service_raw_update_pids(mpegts_service_t *t, mpegts_apids_t *pids) if (mi && mm) { tvh_mutex_lock(&mi->mi_output_lock); tvh_mutex_lock(&t->s_stream_mutex); - x = t->s_pids; + x = t->s_pids; t->s_pids = p; if (pids && !pids->all && x && x->all) { mpegts_input_close_pid(mi, mm, MPEGTS_FULLMUX_PID, MPS_RAW, t); @@ -1078,7 +1055,7 @@ mpegts_service_raw_update_pids(mpegts_service_t *t, mpegts_apids_t *pids) mpegts_mux_update_pids(mm); } else { tvh_mutex_lock(&t->s_stream_mutex); - x = t->s_pids; + x = t->s_pids; t->s_pids = p; tvh_mutex_unlock(&t->s_stream_mutex); } @@ -1089,15 +1066,12 @@ mpegts_service_raw_update_pids(mpegts_service_t *t, mpegts_apids_t *pids) return 0; } -void -mpegts_service_update_slave_pids - ( mpegts_service_t *s, mpegts_service_t *master, int del ) -{ - mpegts_service_t *s2; - mpegts_apids_t *pids; - elementary_stream_t *st; - int i; - const int is_ddci = dvbcam_is_ddci((service_t*)s); +void mpegts_service_update_slave_pids(mpegts_service_t* s, mpegts_service_t* master, int del) { + mpegts_service_t* s2; + mpegts_apids_t* pids; + elementary_stream_t* st; + int i; + const int is_ddci = dvbcam_is_ddci((service_t*)s); lock_assert(&s->s_stream_mutex); @@ -1110,14 +1084,15 @@ mpegts_service_update_slave_pids mpegts_pid_add(pids, s->s_components.set_pcr_pid, MPS_WEIGHT_PCR); /* Ensure that filtered PIDs are not send in ts_recv_raw */ - TAILQ_FOREACH(st, &s->s_components.set_filter, es_filter_link) - if ((is_ddci || s->s_scrambled_pass || st->es_type != SCT_CA) && - st->es_pid >= 0 && st->es_pid < 8192) + TAILQ_FOREACH (st, &s->s_components.set_filter, es_filter_link) + if ((is_ddci || s->s_scrambled_pass || st->es_type != SCT_CA) && st->es_pid >= 0 && + st->es_pid < 8192) mpegts_pid_add(pids, st->es_pid, mpegts_mps_weight(st)); for (i = 0; i < s->s_masters.is_count; i++) { - s2 = (mpegts_service_t *)s->s_masters.is_array[i]; - if (master && master != s2) continue; + s2 = (mpegts_service_t*)s->s_masters.is_array[i]; + if (master && master != s2) + continue; tvh_mutex_lock(&s2->s_stream_mutex); if (!del) mpegts_pid_add_group(s2->s_slaves_pids, pids); @@ -1129,9 +1104,7 @@ mpegts_service_update_slave_pids mpegts_pid_destroy(&pids); } -static int -mpegts_service_link ( mpegts_service_t *master, mpegts_service_t *slave ) -{ +static int mpegts_service_link(mpegts_service_t* master, mpegts_service_t* slave) { tvh_mutex_lock(&slave->s_stream_mutex); tvh_mutex_lock(&master->s_stream_mutex); assert(!idnode_set_exists(&slave->s_masters, &master->s_id)); @@ -1145,9 +1118,7 @@ mpegts_service_link ( mpegts_service_t *master, mpegts_service_t *slave ) return 0; } -static int -mpegts_service_unlink ( mpegts_service_t *master, mpegts_service_t *slave ) -{ +static int mpegts_service_unlink(mpegts_service_t* master, mpegts_service_t* slave) { tvh_mutex_lock(&slave->s_stream_mutex); mpegts_service_update_slave_pids(slave, master, 1); tvh_mutex_lock(&master->s_stream_mutex); @@ -1162,27 +1133,22 @@ mpegts_service_unlink ( mpegts_service_t *master, mpegts_service_t *slave ) return 0; } -static mpegts_apids_t * -mpegts_service_raw_pid_list ( service_t *t ) -{ +static mpegts_apids_t* mpegts_service_raw_pid_list(service_t* t) { return mpegts_service_pid_list_(t, NULL); } -mpegts_service_t * -mpegts_service_create_raw ( mpegts_mux_t *mm ) -{ - mpegts_service_t *s = calloc(1, sizeof(*s)); +mpegts_service_t* mpegts_service_create_raw(mpegts_mux_t* mm) { + mpegts_service_t* s = calloc(1, sizeof(*s)); - if (service_create0((service_t*)s, STYPE_RAW, - &mpegts_service_raw_class, NULL, - S_MPEG_TS, NULL) == NULL) { + if (service_create0((service_t*)s, STYPE_RAW, &mpegts_service_raw_class, NULL, S_MPEG_TS, NULL) == + NULL) { free(s); return NULL; } sbuf_init(&s->s_tsbuf); - s->s_dvb_mux = mm; + s->s_dvb_mux = mm; s->s_delete = mpegts_service_delete; s->s_is_enabled = mpegts_service_is_enabled_raw; diff --git a/src/input/mpegts/mpegts_table.c b/src/input/mpegts/mpegts_table.c index 3f7380db6..6cda1c8fe 100644 --- a/src/input/mpegts/mpegts_table.c +++ b/src/input/mpegts/mpegts_table.c @@ -21,11 +21,9 @@ #include -void -mpegts_table_consistency_check ( mpegts_mux_t *mm ) -{ - int i, c; - mpegts_table_t *mt; +void mpegts_table_consistency_check(mpegts_mux_t* mm) { + int i, c; + mpegts_table_t* mt; if (!tvhtrace_enabled()) return; @@ -35,7 +33,7 @@ mpegts_table_consistency_check ( mpegts_mux_t *mm ) lock_assert(&mm->mm_tables_lock); i = mm->mm_num_tables; - LIST_FOREACH(mt, &mm->mm_tables, mt_link) + LIST_FOREACH (mt, &mm->mm_tables, mt_link) c++; if (i != c) { @@ -44,10 +42,8 @@ mpegts_table_consistency_check ( mpegts_mux_t *mm ) } } -static void -mpegts_table_fastswitch ( mpegts_mux_t *mm, mpegts_table_t *mtm ) -{ - mpegts_table_t *mt; +static void mpegts_table_fastswitch(mpegts_mux_t* mm, mpegts_table_t* mtm) { + mpegts_table_t* mt; assert(mm == mtm->mt_mux); @@ -61,13 +57,19 @@ mpegts_table_fastswitch ( mpegts_mux_t *mm, mpegts_table_t *mtm ) return; } - LIST_FOREACH(mt, &mm->mm_tables, mt_link) { + LIST_FOREACH (mt, &mm->mm_tables, mt_link) { if (!(mt->mt_flags & MT_QUICKREQ) && !mt->mt_working) continue; if (!mt->mt_complete || mt->mt_working) { - tvhtrace(LS_MPEGTS, "table: mux %p no fastswitch %s %02X/%02X (%d) pid %04X (%d)", - mm, mt->mt_name, mt->mt_table, mt->mt_mask, mt->mt_table, - mt->mt_pid, mt->mt_pid); + tvhtrace(LS_MPEGTS, + "table: mux %p no fastswitch %s %02X/%02X (%d) pid %04X (%d)", + mm, + mt->mt_name, + mt->mt_table, + mt->mt_mask, + mt->mt_table, + mt->mt_pid, + mt->mt_pid); tvh_mutex_unlock(&mm->mm_tables_lock); return; } @@ -78,14 +80,11 @@ mpegts_table_fastswitch ( mpegts_mux_t *mm, mpegts_table_t *mtm ) mpegts_mux_scan_done(mm, mm->mm_nicename, 1); } -void -mpegts_table_dispatch - ( const uint8_t *sec, size_t r, void *aux ) -{ - int tid, len, crc_len, ret; - mpegts_table_t *mt = aux; +void mpegts_table_dispatch(const uint8_t* sec, size_t r, void* aux) { + int tid, len, crc_len, ret; + mpegts_table_t* mt = aux; - if(mt->mt_destroyed) + if (mt->mt_destroyed) return; tid = sec[0]; @@ -93,33 +92,37 @@ mpegts_table_dispatch /* Check table mask */ assert((tid & mt->mt_mask) == mt->mt_table); - len = ((sec[1] & 0x0f) << 8) | sec[2]; + len = ((sec[1] & 0x0f) << 8) | sec[2]; crc_len = (mt->mt_flags & MT_CRC) ? 4 : 0; /* Pass with tableid / len in data */ if (mt->mt_flags & MT_FULL) - ret = mt->mt_callback(mt, sec, len+3-crc_len, tid); + ret = mt->mt_callback(mt, sec, len + 3 - crc_len, tid); /* Pass w/out tableid/len in data */ else - ret = mt->mt_callback(mt, sec+3, len-crc_len, tid); - + ret = mt->mt_callback(mt, sec + 3, len - crc_len, tid); + /* Good */ - if(ret >= 0) + if (ret >= 0) mt->mt_count++; - if(!ret && mt->mt_flags & (MT_QUICKREQ|MT_FASTSWITCH)) + if (!ret && mt->mt_flags & (MT_QUICKREQ | MT_FASTSWITCH)) mpegts_table_fastswitch(mt->mt_mux, mt); } -void -mpegts_table_release_ ( mpegts_table_t *mt ) -{ +void mpegts_table_release_(mpegts_table_t* mt) { int mt_size = sizeof(*mt); - dvb_table_release((mpegts_psi_table_t *)mt); - tvhtrace(LS_MPEGTS, "table: mux %p free %s %02X/%02X (%d) pid %04X (%d)", - mt->mt_mux, mt->mt_name, mt->mt_table, mt->mt_mask, mt->mt_table, - mt->mt_pid, mt->mt_pid); + dvb_table_release((mpegts_psi_table_t*)mt); + tvhtrace(LS_MPEGTS, + "table: mux %p free %s %02X/%02X (%d) pid %04X (%d)", + mt->mt_mux, + mt->mt_name, + mt->mt_table, + mt->mt_mask, + mt->mt_table, + mt->mt_pid, + mt->mt_pid); if (mt->mt_bat && mt->mt_bat != mt) dvb_bat_destroy(mt); if (mt->mt_destroy) @@ -127,29 +130,33 @@ mpegts_table_release_ ( mpegts_table_t *mt ) free(mt->mt_name); tprofile_done(&mt->mt_profile); if (tvhtrace_enabled()) { - /* poison */ - #ifdef __STDC_LIB_EXT1__ +/* poison */ +#ifdef __STDC_LIB_EXT1__ memset_s(mt, sizeof(*mt), 0xa5, sizeof(*mt)); - #else - volatile unsigned char *p = (unsigned char*)mt; - while (mt_size--){ +#else + volatile unsigned char* p = (unsigned char*)mt; + while (mt_size--) { *p++ = 0xa5; } - #endif +#endif } free(mt); } -static void -mpegts_table_destroy_ ( mpegts_table_t *mt ) -{ - mpegts_mux_t *mm = mt->mt_mux; +static void mpegts_table_destroy_(mpegts_table_t* mt) { + mpegts_mux_t* mm = mt->mt_mux; lock_assert(&mm->mm_tables_lock); - tvhtrace(LS_MPEGTS, "table: mux %p destroy %s %02X/%02X (%d) pid %04X (%d)", - mm, mt->mt_name, mt->mt_table, mt->mt_mask, mt->mt_table, - mt->mt_pid, mt->mt_pid); + tvhtrace(LS_MPEGTS, + "table: mux %p destroy %s %02X/%02X (%d) pid %04X (%d)", + mm, + mt->mt_name, + mt->mt_table, + mt->mt_mask, + mt->mt_table, + mt->mt_pid, + mt->mt_pid); mpegts_table_consistency_check(mm); mt->mt_destroyed = 1; mt->mt_mux->mm_close_table(mt->mt_mux, mt); @@ -157,10 +164,8 @@ mpegts_table_destroy_ ( mpegts_table_t *mt ) mpegts_table_release(mt); } -void -mpegts_table_destroy ( mpegts_table_t *mt ) -{ - mpegts_mux_t *mm = mt->mt_mux; +void mpegts_table_destroy(mpegts_table_t* mt) { + mpegts_mux_t* mm = mt->mt_mux; tvh_mutex_lock(&mm->mm_tables_lock); if (!mt->mt_destroyed) @@ -171,28 +176,28 @@ mpegts_table_destroy ( mpegts_table_t *mt ) /** * Determine table type */ -int -mpegts_table_type ( mpegts_table_t *mt ) -{ +int mpegts_table_type(mpegts_table_t* mt) { int type = 0; - if (mt->mt_flags & MT_FAST) type |= MPS_FTABLE; - if (mt->mt_flags & MT_SLOW) type |= MPS_TABLE; - if (mt->mt_flags & MT_RECORD) type |= MPS_STREAM; - if ((type & (MPS_FTABLE | MPS_TABLE)) == 0) type |= MPS_TABLE; + if (mt->mt_flags & MT_FAST) + type |= MPS_FTABLE; + if (mt->mt_flags & MT_SLOW) + type |= MPS_TABLE; + if (mt->mt_flags & MT_RECORD) + type |= MPS_STREAM; + if ((type & (MPS_FTABLE | MPS_TABLE)) == 0) + type |= MPS_TABLE; return type; } /** * Find a table */ -mpegts_table_t *mpegts_table_find - ( mpegts_mux_t *mm, const char *name, void *opaque ) -{ - mpegts_table_t *mt; +mpegts_table_t* mpegts_table_find(mpegts_mux_t* mm, const char* name, void* opaque) { + mpegts_table_t* mt; tvh_mutex_lock(&mm->mm_tables_lock); mpegts_table_consistency_check(mm); - LIST_FOREACH(mt, &mm->mm_tables, mt_link) { + LIST_FOREACH (mt, &mm->mm_tables, mt_link) { if (mt->mt_opaque != opaque) continue; if (strcmp(mt->mt_name, name)) @@ -204,33 +209,36 @@ mpegts_table_t *mpegts_table_find return mt; } - /** * Add a new DVB table */ -mpegts_table_t * -mpegts_table_add - ( mpegts_mux_t *mm, int tableid, int mask, - mpegts_table_callback_t callback, void *opaque, - const char *name, int subsys, int flags, int pid, int weight ) -{ - mpegts_table_t *mt; - int subscribe = 1; - char buf[64]; +mpegts_table_t* mpegts_table_add(mpegts_mux_t* mm, + int tableid, + int mask, + mpegts_table_callback_t callback, + void* opaque, + const char* name, + int subsys, + int flags, + int pid, + int weight) { + mpegts_table_t* mt; + int subscribe = 1; + char buf[64]; /* Check for existing */ tvh_mutex_lock(&mm->mm_tables_lock); mpegts_table_consistency_check(mm); - LIST_FOREACH(mt, &mm->mm_tables, mt_link) { + LIST_FOREACH (mt, &mm->mm_tables, mt_link) { if (mt->mt_opaque != opaque) continue; if (mt->mt_pid < 0) { if (strcmp(mt->mt_name, name)) continue; - mt->mt_callback = callback; - mt->mt_pid = pid; - mt->mt_weight = weight; - mt->mt_table = tableid; + mt->mt_callback = callback; + mt->mt_pid = pid; + mt->mt_weight = weight; + mt->mt_table = tableid; mm->mm_open_table(mm, mt, 1); } else if (pid >= 0) { if (mt->mt_pid != pid) @@ -249,25 +257,32 @@ mpegts_table_add tvh_mutex_unlock(&mm->mm_tables_lock); return mt; } - tvhtrace(LS_MPEGTS, "table: mux %p add %s %02X/%02X (%d) pid %04X (%d)", - mm, name, tableid, mask, tableid, pid, pid); + tvhtrace(LS_MPEGTS, + "table: mux %p add %s %02X/%02X (%d) pid %04X (%d)", + mm, + name, + tableid, + mask, + tableid, + pid, + pid); /* Create */ - mt = calloc(1, sizeof(mpegts_table_t)); - mt->mt_arefcount = 1; - mt->mt_name = strdup(name); - mt->mt_subsys = subsys; - mt->mt_callback = callback; - mt->mt_opaque = opaque; - mt->mt_pid = pid; - mt->mt_weight = weight; - mt->mt_flags = flags & ~(MT_SKIPSUBS|MT_SCANSUBS); - mt->mt_table = tableid; - mt->mt_mask = mask; - mt->mt_mux = mm; - mt->mt_sect.ps_cc = -1; + mt = calloc(1, sizeof(mpegts_table_t)); + mt->mt_arefcount = 1; + mt->mt_name = strdup(name); + mt->mt_subsys = subsys; + mt->mt_callback = callback; + mt->mt_opaque = opaque; + mt->mt_pid = pid; + mt->mt_weight = weight; + mt->mt_flags = flags & ~(MT_SKIPSUBS | MT_SCANSUBS); + mt->mt_table = tableid; + mt->mt_mask = mask; + mt->mt_mux = mm; + mt->mt_sect.ps_cc = -1; mt->mt_sect.ps_table = tableid; - mt->mt_sect.ps_mask = mask; + mt->mt_sect.ps_mask = mask; snprintf(buf, sizeof(buf), "%s %p", mt->mt_name, mt); tprofile_init(&mt->mt_profile, buf); @@ -289,10 +304,8 @@ mpegts_table_add /** * */ -void -mpegts_table_flush_all ( mpegts_mux_t *mm ) -{ - mpegts_table_t *mt; +void mpegts_table_flush_all(mpegts_mux_t* mm) { + mpegts_table_t* mt; descrambler_flush_tables(mm); tvh_mutex_lock(&mm->mm_tables_lock); @@ -314,7 +327,6 @@ mpegts_table_flush_all ( mpegts_mux_t *mm ) tvh_mutex_unlock(&mm->mm_tables_lock); } - /****************************************************************************** * Editor Configuration * diff --git a/src/input/mpegts/mpegts_tsdebug.c b/src/input/mpegts/mpegts_tsdebug.c index c7d12c8cf..994cca44f 100644 --- a/src/input/mpegts/mpegts_tsdebug.c +++ b/src/input/mpegts/mpegts_tsdebug.c @@ -16,14 +16,15 @@ * along with this program. If not, see . */ - #include "input.h" -void -tsdebug_encode_keys - ( uint8_t *dst, uint16_t sid, uint16_t pid, - uint8_t keytype, uint8_t keylen, uint8_t *even, uint8_t *odd ) -{ +void tsdebug_encode_keys(uint8_t* dst, + uint16_t sid, + uint16_t pid, + uint8_t keytype, + uint8_t keylen, + uint8_t* even, + uint8_t* odd) { uint32_t pos = 0, crc; memset(dst, 0xff, 188); @@ -42,42 +43,40 @@ tsdebug_encode_keys memcpy(dst + pos, even, keylen); memcpy(dst + pos + keylen, odd, keylen); pos += 2 * keylen; - crc = tvh_crc32(dst, pos, 0x859aa5ba); + crc = tvh_crc32(dst, pos, 0x859aa5ba); dst[pos++] = (crc >> 24) & 0xff; dst[pos++] = (crc >> 16) & 0xff; dst[pos++] = (crc >> 8) & 0xff; dst[pos++] = crc & 0xff; } -void -tsdebug_check_tspkt( mpegts_mux_t *mm, uint8_t *pkt, int len ) -{ - void tsdebugcw_new_keys(service_t *t, int type, uint16_t pid, uint8_t *odd, uint8_t *even); +void tsdebug_check_tspkt(mpegts_mux_t* mm, uint8_t* pkt, int len) { + void tsdebugcw_new_keys(service_t * t, int type, uint16_t pid, uint8_t* odd, uint8_t* even); uint32_t pos, type, keylen, sid, crc; uint16_t pid; - mpegts_service_t *t; + mpegts_service_t* t; - for ( ; len > 0; pkt += 188, len -= 188) { + for (; len > 0; pkt += 188, len -= 188) { if (memcmp(pkt + 4, "TVHeadendDescramblerKeys", 24)) continue; - pos = 4 + 24; - type = pkt[pos + 0]; + pos = 4 + 24; + type = pkt[pos + 0]; keylen = pkt[pos + 1]; - sid = (pkt[pos + 2] << 8) | pkt[pos + 3]; - pid = (pkt[pos + 4] << 8) | pkt[pos + 5]; + sid = (pkt[pos + 2] << 8) | pkt[pos + 3]; + pid = (pkt[pos + 4] << 8) | pkt[pos + 5]; pos += 6 + 2 * keylen; if (pos > 184) return; - crc = (pkt[pos + 0] << 24) | (pkt[pos + 1] << 16) | - (pkt[pos + 2] << 8) | pkt[pos + 3]; + crc = (pkt[pos + 0] << 24) | (pkt[pos + 1] << 16) | (pkt[pos + 2] << 8) | pkt[pos + 3]; if (crc != tvh_crc32(pkt, pos, 0x859aa5ba)) return; - LIST_FOREACH(t, &mm->mm_services, s_dvb_mux_link) - if (service_id16(t) == sid) break; + LIST_FOREACH (t, &mm->mm_services, s_dvb_mux_link) + if (service_id16(t) == sid) + break; if (!t) return; pos = 4 + 24 + 4; tvhdebug(LS_DESCRAMBLER, "Keys from MPEG-TS source (PID 0x1FFF)!"); - tsdebugcw_new_keys((service_t *)t, type, pid, pkt + pos, pkt + pos + keylen); + tsdebugcw_new_keys((service_t*)t, type, pid, pkt + pos, pkt + pos + keylen); } } diff --git a/src/input/mpegts/satip/satip.c b/src/input/mpegts/satip/satip.c index 58e91d30b..ec26e4904 100644 --- a/src/input/mpegts/satip/satip.c +++ b/src/input/mpegts/satip/satip.c @@ -35,19 +35,17 @@ #include #endif -static void satip_discovery_timer_cb(void *aux); +static void satip_discovery_timer_cb(void* aux); /* * */ -static void -satip_device_dbus_notify( satip_device_t *sd, const char *sig_name ) -{ +static void satip_device_dbus_notify(satip_device_t* sd, const char* sig_name) { #if ENABLE_DBUS_1 char buf[256], ubuf[UUID_HEX_SIZE]; - htsmsg_t *msg = htsmsg_create_list(); + htsmsg_t* msg = htsmsg_create_list(); htsmsg_add_str(msg, NULL, sd->sd_info.addr); htsmsg_add_str(msg, NULL, sd->sd_info.location); htsmsg_add_str(msg, NULL, sd->sd_info.server); @@ -57,36 +55,34 @@ satip_device_dbus_notify( satip_device_t *sd, const char *sig_name ) #endif } -static void -satip_device_block( const char *addr, int block ) -{ +static void satip_device_block(const char* addr, int block) { extern const idclass_t satip_device_class; - tvh_hardware_t *th; - satip_device_t *sd; - satip_frontend_t *lfe; - int val = block < 0 ? 0 : block; + tvh_hardware_t* th; + satip_device_t* sd; + satip_frontend_t* lfe; + int val = block < 0 ? 0 : block; tvh_mutex_lock(&global_lock); - TVH_HARDWARE_FOREACH(th) { + TVH_HARDWARE_FOREACH (th) { if (!idnode_is_instance(&th->th_id, &satip_device_class)) continue; - sd = (satip_device_t *)th; + sd = (satip_device_t*)th; if (strcmp(sd->sd_info.addr, addr) == 0 && val != sd->sd_dbus_allow) { sd->sd_dbus_allow = val; if (block < 0) { - TAILQ_FOREACH(lfe, &sd->sd_frontends, sf_link) - mpegts_input_stop_all((mpegts_input_t *)lfe); + TAILQ_FOREACH (lfe, &sd->sd_frontends, sf_link) + mpegts_input_stop_all((mpegts_input_t*)lfe); } - tvhinfo(LS_SATIP, "address %s is %s", addr, - block < 0 ? "stopped" : (block > 0 ? "allowed" : "disabled")); + tvhinfo(LS_SATIP, + "address %s is %s", + addr, + block < 0 ? "stopped" : (block > 0 ? "allowed" : "disabled")); } } tvh_mutex_unlock(&global_lock); } -static char * -satip_device_addr( void *aux, const char *path, char *value ) -{ +static char* satip_device_addr(void* aux, const char* path, char* value) { if (strcmp(path, "/stop") == 0) { satip_device_block(value, -1); return strdup("ok"); @@ -103,9 +99,7 @@ satip_device_addr( void *aux, const char *path, char *value ) /* * */ -char * -satip_device_nicename( satip_device_t *sd, char *buf, int len ) -{ +char* satip_device_nicename(satip_device_t* sd, char* buf, int len) { if (sd->sd_info.rtsp_port != 554) snprintf(buf, len, "%s:%d", sd->sd_info.addr, sd->sd_info.rtsp_port); else @@ -117,13 +111,11 @@ satip_device_nicename( satip_device_t *sd, char *buf, int len ) * SAT-IP client */ -static htsmsg_t * -satip_device_class_save ( idnode_t *in, char *filename, size_t fsize ) -{ - satip_device_t *sd = (satip_device_t *)in; - satip_frontend_t *lfe; - htsmsg_t *m, *l; - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* satip_device_class_save(idnode_t* in, char* filename, size_t fsize) { + satip_device_t* sd = (satip_device_t*)in; + satip_frontend_t* lfe; + htsmsg_t * m, *l; + char ubuf[UUID_HEX_SIZE]; if (sd->sd_nosave) return NULL; @@ -133,439 +125,413 @@ satip_device_class_save ( idnode_t *in, char *filename, size_t fsize ) if (filename) { l = htsmsg_create_map(); - TAILQ_FOREACH(lfe, &sd->sd_frontends, sf_link) + TAILQ_FOREACH (lfe, &sd->sd_frontends, sf_link) satip_frontend_save(lfe, l); htsmsg_add_msg(m, "frontends", l); - snprintf(filename, fsize, "input/satip/adapters/%s", - idnode_uuid_as_str(&sd->th_id, ubuf)); + snprintf(filename, fsize, "input/satip/adapters/%s", idnode_uuid_as_str(&sd->th_id, ubuf)); } return m; } -static const void * -satip_device_class_active_get ( void * obj ) -{ - static int active; - satip_device_t *sd = (satip_device_t *)obj; - satip_frontend_t *lfe; +static const void* satip_device_class_active_get(void* obj) { + static int active; + satip_device_t* sd = (satip_device_t*)obj; + satip_frontend_t* lfe; active = 0; - TAILQ_FOREACH(lfe, &sd->sd_frontends, sf_link) - if (*(int *)mpegts_input_class_active_get(lfe)) { + TAILQ_FOREACH (lfe, &sd->sd_frontends, sf_link) + if (*(int*)mpegts_input_class_active_get(lfe)) { active = 1; break; } return &active; } -static idnode_set_t * -satip_device_class_get_childs ( idnode_t *in ) -{ - satip_device_t *sd = (satip_device_t *)in; - idnode_set_t *is = idnode_set_create(0); - satip_frontend_t *lfe; +static idnode_set_t* satip_device_class_get_childs(idnode_t* in) { + satip_device_t* sd = (satip_device_t*)in; + idnode_set_t* is = idnode_set_create(0); + satip_frontend_t* lfe; - TAILQ_FOREACH(lfe, &sd->sd_frontends, sf_link) + TAILQ_FOREACH (lfe, &sd->sd_frontends, sf_link) idnode_set_add(is, &lfe->ti_id, NULL, NULL); return is; } static void -satip_device_class_get_title - ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) -{ - satip_device_t *sd = (satip_device_t *)in; +satip_device_class_get_title(idnode_t* in, const char* lang, char* dst, size_t dstsize) { + satip_device_t* sd = (satip_device_t*)in; snprintf(dst, dstsize, "%s - %s", sd->sd_info.friendlyname, sd->sd_info.addr); } -static const char *satip_tunercfg_tab[] = { - "DVBS2-1", - "DVBS2-2", - "DVBS2-4", - "DVBS2-8", - "DVBC-1", - "DVBC-2", - "DVBC-4", - "DVBC-8", - "DVBC-16", - "DVBC-24", - "DVBC-32", - "DVBT-1", - "DVBT-2", - "DVBT-4", - "DVBT-8", - "DVBS2-1,DVBT-1", - "DVBS2-2,DVBT-2", - "DVBT-1,DVBS2-1", - "DVBT-2,DVBS2-2", - "DVBS2-1,DVBC-1", - "DVBS2-2,DVBC-2", - "DVBC-1,DVBS2-1", - "DVBC-2,DVBS2-2", - "DVBS2-4,DVBT-2", - "DVBS2-4,DVBC-2", - "DVBS2-4,DVBT-2,DVBC-2", - "DVBS2-8,DVBT-4,DVBC-4", - "ISDB-T", - NULL -}; - -static htsmsg_t * -satip_device_class_tunercfg_list ( void *o, const char *lang ) -{ - htsmsg_t *l = htsmsg_create_list(); - const char **p; +static const char* satip_tunercfg_tab[] = {"DVBS2-1", + "DVBS2-2", + "DVBS2-4", + "DVBS2-8", + "DVBC-1", + "DVBC-2", + "DVBC-4", + "DVBC-8", + "DVBC-16", + "DVBC-24", + "DVBC-32", + "DVBT-1", + "DVBT-2", + "DVBT-4", + "DVBT-8", + "DVBS2-1,DVBT-1", + "DVBS2-2,DVBT-2", + "DVBT-1,DVBS2-1", + "DVBT-2,DVBS2-2", + "DVBS2-1,DVBC-1", + "DVBS2-2,DVBC-2", + "DVBC-1,DVBS2-1", + "DVBC-2,DVBS2-2", + "DVBS2-4,DVBT-2", + "DVBS2-4,DVBC-2", + "DVBS2-4,DVBT-2,DVBC-2", + "DVBS2-8,DVBT-4,DVBC-4", + "ISDB-T", + NULL}; + +static htsmsg_t* satip_device_class_tunercfg_list(void* o, const char* lang) { + htsmsg_t* l = htsmsg_create_list(); + const char** p; htsmsg_add_str(l, NULL, "Auto"); for (p = satip_tunercfg_tab; *p; p++) htsmsg_add_str(l, NULL, *p); return l; } -static void -satip_device_class_tunercfg_notify ( void *o, const char *lang ) -{ - satip_device_t *sd = (satip_device_t *)o; +static void satip_device_class_tunercfg_notify(void* o, const char* lang) { + satip_device_t* sd = (satip_device_t*)o; if (!sd->sd_inload) satip_device_destroy_later(sd, 100); } -static htsmsg_t * -satip_device_class_default_rolloff_list ( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("Auto"), SATIP_DEFAULT_ROLLOFF_AUTO }, - { N_("0.35"), SATIP_DEFAULT_ROLLOFF_35 }, - { N_("0.25"), SATIP_DEFAULT_ROLLOFF_25 }, - { N_("0.20"), SATIP_DEFAULT_ROLLOFF_20 } - }; +static htsmsg_t* satip_device_class_default_rolloff_list(void* o, const char* lang) { + static const struct strtab tab[] = {{N_("Auto"), SATIP_DEFAULT_ROLLOFF_AUTO}, + {N_("0.35"), SATIP_DEFAULT_ROLLOFF_35}, + {N_("0.25"), SATIP_DEFAULT_ROLLOFF_25}, + {N_("0.20"), SATIP_DEFAULT_ROLLOFF_20}}; return strtab2htsmsg(tab, 1, lang); } CLASS_DOC(satip_client) -const idclass_t satip_device_class = -{ - .ic_class = "satip_client", - .ic_event = "satip_client", - .ic_caption = N_("SAT>IP Client"), - .ic_doc = tvh_doc_satip_client_class, - .ic_save = satip_device_class_save, - .ic_get_childs = satip_device_class_get_childs, - .ic_get_title = satip_device_class_get_title, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "active", - .name = N_("Active"), - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, - .get = satip_device_class_active_get, - }, - { - .type = PT_STR, - .id = "tunercfgu", - .name = N_("Tuner configuration"), - .desc = N_("Tuner configuration."), - .opts = PO_SORTKEY, - .off = offsetof(satip_device_t, sd_tunercfg), - .list = satip_device_class_tunercfg_list, - .notify = satip_device_class_tunercfg_notify, - .def.s = "Auto" - }, - { - .type = PT_BOOL, - .id = "tcp_mode", - .name = N_("RTP/AVP/TCP transport supported"), - .desc = N_("The server suports the Interlaved TCP transfer mode " - "(embedded data in the RTSP session). Selecting this " - "option enables this mode in all tuners by default."), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_tcp_mode), - }, - { - .type = PT_BOOL, - .id = "fast_switch", - .name = N_("Fast input switch"), - .desc = N_("Enable or disable fast input switching."), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_fast_switch), - }, - { - .type = PT_BOOL, - .id = "fullmux_ok", - .name = N_("Full mux RX mode supported"), - .desc = N_("Enable or disable full mux mode."), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_fullmux_ok), - }, - { - .type = PT_INT, - .id = "sigscale", - .name = N_("Signal scale (240 or 100)"), - .desc = N_("Not all SAT>IP servers use the same signal scaling. " - "Change this setting if the signal level displayed " - "within Tvheadend looks too low."), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_sig_scale), - }, - { - .type = PT_INT, - .id = "pids_max", - .name = N_("Maximum PIDs"), - .desc = N_("Set the maxiumum packet identifiers your SAT>IP " - "server supports."), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_pids_max), - }, - { - .type = PT_INT, - .id = "pids_len", - .name = N_("Maximum length of PIDs"), - .desc = N_("Maximum length in characters for the command " - "setting PIDs to the SAT>IP box."), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_pids_len), - }, - { - .type = PT_BOOL, - .id = "pids_deladd", - .name = N_("addpids/delpids supported"), - .desc = N_("Enable if the SAT>IP box supports the " - "addpids/delpids commands."), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_pids_deladd), - }, - { - .type = PT_BOOL, - .id = "fe", - .name = N_("FE supported"), - .desc = N_("Enable if the SAT>IP box supports the frontend " - "identifier. This allows the auto-tuner allocation, " - "but it might cause trouble for boxes with different " - "tuner reception connections like satellite inputs."), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_fe), - }, - { - .type = PT_BOOL, - .id = "piloton", - .name = N_("Force pilot for DVB-S2"), - .desc = N_("Enable if the SAT>IP box requests plts=on " - "parameter in the SETUP RTSP command for DVB-S2 " - "muxes."), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_pilot_on), - }, - { - .type = PT_INT, - .id = "default_rolloff", - .name = N_("Send rolloff settings for DVB-S2"), - .desc = N_("Enable if the SAT>IP box requires ro= " - "parameter in the SETUP RTSP command for DVB-S2 " - "muxes."), - .opts = PO_ADVANCED, - .list = satip_device_class_default_rolloff_list, - .off = offsetof(satip_device_t, sd_default_rolloff), - }, - { - .type = PT_BOOL, - .id = "pids21", - .name = N_("PIDs 21 in setup"), - .desc = N_("Enable if the SAT>IP box requires pids=21 " - "parameter in the SETUP RTSP command"), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_pids21), - }, - { - .type = PT_STR, - .id = "bindaddr", - .name = N_("Local bind IP address"), - .desc = N_("Bind to specific local IP address."), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_bindaddr), - }, - { - .type = PT_INT, - .id = "skip_ts", - .name = N_("Skip TS packets (0-200)"), - .desc = N_("Skip x number of transport packets."), - .opts = PO_EXPERT, - .off = offsetof(satip_device_t, sd_skip_ts), - }, - { - .type = PT_BOOL, - .id = "disableworkarounds", - .name = N_("Disable device/firmware-specific workarounds"), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_disable_workarounds), - }, - { - .type = PT_BOOL, - .id = "sigtunerno", - .name = N_("Check tuner-number in signal-status messages"), - .desc = N_("This is a workaround for some tuners that mess up " - "the numbers of tuners. Turn this off when you are not " - "seeing signal strength on all tuners but only on some."), - .opts = PO_ADVANCED, - .off = offsetof(satip_device_t, sd_sig_tunerno), - }, - { - .type = PT_STR, - .id = "addr", - .name = N_("IP address"), - .desc = N_("Force all network connections to this tuner to be " - "made over the specified IP address, similar to " - "the setting for the SAT>IP device itself. Setting " - "this overrides the device-specific setting."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.addr), - }, - { - .type = PT_INT, - .id = "rtsp", - .name = N_("RTSP port"), - .desc = N_("Current RTSP port."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.rtsp_port), - }, - { - .type = PT_STR, - .id = "device_uuid", - .name = N_("UUID"), - .desc = N_("The SAT>IP server's universally unique identifier."), - .opts = PO_RDONLY, - .off = offsetof(satip_device_t, sd_info.uuid), - }, - { - .type = PT_STR, - .id = "friendly", - .name = N_("Friendly name"), - .desc = N_("The SAT>IP server's name."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.friendlyname), - }, - { - .type = PT_STR, - .id = "serialnum", - .name = N_("Serial number"), - .desc = N_("The device's serial number."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.serialnum), - }, - { - .type = PT_STR, - .id = "tunercfg", - .name = N_("Tuner configuration"), - .desc = N_("Current tuner configuration."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.tunercfg), - }, - { - .type = PT_STR, - .id = "manufacturer", - .name = N_("Manufacturer"), - .desc = N_("The manufacturer of the SAT>IP server."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.manufacturer), - }, - { - .type = PT_STR, - .id = "manufurl", - .name = N_("Manufacturer URL"), - .desc = N_("Manufacturer's product information page for the device."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.manufacturerURL), - }, - { - .type = PT_STR, - .id = "modeldesc", - .name = N_("Model description"), - .desc = N_("Manufacturer's product description."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.modeldesc), - }, - { - .type = PT_STR, - .id = "modelname", - .name = N_("Model name"), - .desc = N_("Manufacturer's product name."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.modelname), - }, - { - .type = PT_STR, - .id = "modelnum", - .name = N_("Model number"), - .desc = N_("Manufacturer's model number."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.modelnum), - }, - { - .type = PT_STR, - .id = "bootid", - .name = N_("Boot ID"), - .desc = N_("The current boot ID."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.bootid), - }, - { - .type = PT_STR, - .id = "configid", - .name = N_("Configuration ID"), - .desc = N_("The current configuration ID."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.configid), - }, - { - .type = PT_STR, - .id = "deviceid", - .name = N_("Device ID"), - .desc = N_("The device ID."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.deviceid), - }, - { - .type = PT_STR, - .id = "presentation", - .name = N_("Presentation"), - .desc = N_("Presentation details."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.presentation), - }, - { - .type = PT_STR, - .id = "location", - .name = N_("Location"), - .desc = N_("Location details of the SAT>IP Server."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.location), - }, - { - .type = PT_STR, - .id = "server", - .name = N_("Server"), - .desc = N_("Server details."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.server), - }, - { - .type = PT_STR, - .id = "myaddr", - .name = N_("Local discovery IP address"), - .desc = N_("The SAT>IP's discovered IP address."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_device_t, sd_info.myaddr), - }, - {} - } -}; +const idclass_t satip_device_class = {.ic_class = "satip_client", + .ic_event = "satip_client", + .ic_caption = N_("SAT>IP Client"), + .ic_doc = tvh_doc_satip_client_class, + .ic_save = satip_device_class_save, + .ic_get_childs = satip_device_class_get_childs, + .ic_get_title = satip_device_class_get_title, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "active", + .name = N_("Active"), + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, + .get = satip_device_class_active_get, + }, + {.type = PT_STR, + .id = "tunercfgu", + .name = N_("Tuner configuration"), + .desc = N_("Tuner configuration."), + .opts = PO_SORTKEY, + .off = offsetof(satip_device_t, sd_tunercfg), + .list = satip_device_class_tunercfg_list, + .notify = satip_device_class_tunercfg_notify, + .def.s = "Auto"}, + { + .type = PT_BOOL, + .id = "tcp_mode", + .name = N_("RTP/AVP/TCP transport supported"), + .desc = N_("The server suports the Interlaved TCP transfer mode " + "(embedded data in the RTSP session). Selecting this " + "option enables this mode in all tuners by default."), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_tcp_mode), + }, + { + .type = PT_BOOL, + .id = "fast_switch", + .name = N_("Fast input switch"), + .desc = N_("Enable or disable fast input switching."), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_fast_switch), + }, + { + .type = PT_BOOL, + .id = "fullmux_ok", + .name = N_("Full mux RX mode supported"), + .desc = N_("Enable or disable full mux mode."), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_fullmux_ok), + }, + { + .type = PT_INT, + .id = "sigscale", + .name = N_("Signal scale (240 or 100)"), + .desc = N_("Not all SAT>IP servers use the same signal scaling. " + "Change this setting if the signal level displayed " + "within Tvheadend looks too low."), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_sig_scale), + }, + { + .type = PT_INT, + .id = "pids_max", + .name = N_("Maximum PIDs"), + .desc = N_("Set the maxiumum packet identifiers your SAT>IP " + "server supports."), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_pids_max), + }, + { + .type = PT_INT, + .id = "pids_len", + .name = N_("Maximum length of PIDs"), + .desc = N_("Maximum length in characters for the command " + "setting PIDs to the SAT>IP box."), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_pids_len), + }, + { + .type = PT_BOOL, + .id = "pids_deladd", + .name = N_("addpids/delpids supported"), + .desc = N_("Enable if the SAT>IP box supports the " + "addpids/delpids commands."), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_pids_deladd), + }, + { + .type = PT_BOOL, + .id = "fe", + .name = N_("FE supported"), + .desc = N_("Enable if the SAT>IP box supports the frontend " + "identifier. This allows the auto-tuner allocation, " + "but it might cause trouble for boxes with different " + "tuner reception connections like satellite inputs."), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_fe), + }, + { + .type = PT_BOOL, + .id = "piloton", + .name = N_("Force pilot for DVB-S2"), + .desc = N_("Enable if the SAT>IP box requests plts=on " + "parameter in the SETUP RTSP command for DVB-S2 " + "muxes."), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_pilot_on), + }, + { + .type = PT_INT, + .id = "default_rolloff", + .name = N_("Send rolloff settings for DVB-S2"), + .desc = N_("Enable if the SAT>IP box requires ro= " + "parameter in the SETUP RTSP command for DVB-S2 " + "muxes."), + .opts = PO_ADVANCED, + .list = satip_device_class_default_rolloff_list, + .off = offsetof(satip_device_t, sd_default_rolloff), + }, + { + .type = PT_BOOL, + .id = "pids21", + .name = N_("PIDs 21 in setup"), + .desc = N_("Enable if the SAT>IP box requires pids=21 " + "parameter in the SETUP RTSP command"), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_pids21), + }, + { + .type = PT_STR, + .id = "bindaddr", + .name = N_("Local bind IP address"), + .desc = N_("Bind to specific local IP address."), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_bindaddr), + }, + { + .type = PT_INT, + .id = "skip_ts", + .name = N_("Skip TS packets (0-200)"), + .desc = N_("Skip x number of transport packets."), + .opts = PO_EXPERT, + .off = offsetof(satip_device_t, sd_skip_ts), + }, + { + .type = PT_BOOL, + .id = "disableworkarounds", + .name = N_("Disable device/firmware-specific workarounds"), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_disable_workarounds), + }, + { + .type = PT_BOOL, + .id = "sigtunerno", + .name = N_("Check tuner-number in signal-status messages"), + .desc = N_("This is a workaround for some tuners that mess up " + "the numbers of tuners. Turn this off when you are not " + "seeing signal strength on all tuners but only on some."), + .opts = PO_ADVANCED, + .off = offsetof(satip_device_t, sd_sig_tunerno), + }, + { + .type = PT_STR, + .id = "addr", + .name = N_("IP address"), + .desc = N_("Force all network connections to this tuner to be " + "made over the specified IP address, similar to " + "the setting for the SAT>IP device itself. Setting " + "this overrides the device-specific setting."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.addr), + }, + { + .type = PT_INT, + .id = "rtsp", + .name = N_("RTSP port"), + .desc = N_("Current RTSP port."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.rtsp_port), + }, + { + .type = PT_STR, + .id = "device_uuid", + .name = N_("UUID"), + .desc = N_("The SAT>IP server's universally unique identifier."), + .opts = PO_RDONLY, + .off = offsetof(satip_device_t, sd_info.uuid), + }, + { + .type = PT_STR, + .id = "friendly", + .name = N_("Friendly name"), + .desc = N_("The SAT>IP server's name."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.friendlyname), + }, + { + .type = PT_STR, + .id = "serialnum", + .name = N_("Serial number"), + .desc = N_("The device's serial number."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.serialnum), + }, + { + .type = PT_STR, + .id = "tunercfg", + .name = N_("Tuner configuration"), + .desc = N_("Current tuner configuration."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.tunercfg), + }, + { + .type = PT_STR, + .id = "manufacturer", + .name = N_("Manufacturer"), + .desc = N_("The manufacturer of the SAT>IP server."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.manufacturer), + }, + { + .type = PT_STR, + .id = "manufurl", + .name = N_("Manufacturer URL"), + .desc = N_("Manufacturer's product information page for the device."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.manufacturerURL), + }, + { + .type = PT_STR, + .id = "modeldesc", + .name = N_("Model description"), + .desc = N_("Manufacturer's product description."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.modeldesc), + }, + { + .type = PT_STR, + .id = "modelname", + .name = N_("Model name"), + .desc = N_("Manufacturer's product name."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.modelname), + }, + { + .type = PT_STR, + .id = "modelnum", + .name = N_("Model number"), + .desc = N_("Manufacturer's model number."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.modelnum), + }, + { + .type = PT_STR, + .id = "bootid", + .name = N_("Boot ID"), + .desc = N_("The current boot ID."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.bootid), + }, + { + .type = PT_STR, + .id = "configid", + .name = N_("Configuration ID"), + .desc = N_("The current configuration ID."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.configid), + }, + { + .type = PT_STR, + .id = "deviceid", + .name = N_("Device ID"), + .desc = N_("The device ID."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.deviceid), + }, + { + .type = PT_STR, + .id = "presentation", + .name = N_("Presentation"), + .desc = N_("Presentation details."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.presentation), + }, + { + .type = PT_STR, + .id = "location", + .name = N_("Location"), + .desc = N_("Location details of the SAT>IP Server."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.location), + }, + { + .type = PT_STR, + .id = "server", + .name = N_("Server"), + .desc = N_("Server details."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.server), + }, + { + .type = PT_STR, + .id = "myaddr", + .name = N_("Local discovery IP address"), + .desc = N_("The SAT>IP's discovered IP address."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_device_t, sd_info.myaddr), + }, + {}}}; /* * Create entry */ -static void -satip_device_calc_bin_uuid( uint8_t *uuid, const char *satip_uuid ) -{ +static void satip_device_calc_bin_uuid(uint8_t* uuid, const char* satip_uuid) { SHA_CTX sha1; SHA1_Init(&sha1); @@ -573,20 +539,16 @@ satip_device_calc_bin_uuid( uint8_t *uuid, const char *satip_uuid ) SHA1_Final(uuid, &sha1); } -static void -satip_device_calc_uuid( char *uuid, const char *satip_uuid ) -{ +static void satip_device_calc_uuid(char* uuid, const char* satip_uuid) { uint8_t uuidbin[20]; - sha1_calc(uuidbin, (const uint8_t *)satip_uuid, strlen(satip_uuid), NULL, 0); + sha1_calc(uuidbin, (const uint8_t*)satip_uuid, strlen(satip_uuid), NULL, 0); bin2hex(uuid, UUID_HEX_SIZE, uuidbin, sizeof(uuidbin)); } -static void -satip_device_hack( satip_device_t *sd ) -{ - if(sd->sd_disable_workarounds) - return; +static void satip_device_hack(satip_device_t* sd) { + if (sd->sd_disable_workarounds) + return; #if 0 /* V1.24.0.156 cannot be distinguished from V1.13.0.105 :-( */ /* hopefully, all users have V1.16.0.120+ now */ @@ -604,48 +566,44 @@ satip_device_hack( satip_device_t *sd ) #endif if (strstr(sd->sd_info.location, ":8888/octonet.xml")) { /* OctopusNet requires pids in the SETUP RTSP command */ - } else if (strstr(sd->sd_info.manufacturer, "Triax") && - strstr(sd->sd_info.modelname, "TSS400")) { - sd->sd_fullmux_ok = 0; - sd->sd_pids_max = 64; - sd->sd_pids_len = 255; - sd->sd_pilot_on = 1; + } else if (strstr(sd->sd_info.manufacturer, "Triax") && strstr(sd->sd_info.modelname, "TSS400")) { + sd->sd_fullmux_ok = 0; + sd->sd_pids_max = 64; + sd->sd_pids_len = 255; + sd->sd_pilot_on = 1; sd->sd_default_rolloff = SATIP_DEFAULT_ROLLOFF_35; } else if (strstr(sd->sd_info.manufacturer, "KATHREIN") && - (strstr(sd->sd_info.modelname, "EXIP-4124") || - strstr(sd->sd_info.modelname, "EXIP-418") || - strstr(sd->sd_info.modelname, "EXIP-414"))) { - sd->sd_fullmux_ok = 0; - sd->sd_pids_max = 64; - sd->sd_pids_len = 255; - sd->sd_pilot_on = 1; + (strstr(sd->sd_info.modelname, "EXIP-4124") || strstr(sd->sd_info.modelname, "EXIP-418") || + strstr(sd->sd_info.modelname, "EXIP-414"))) { + sd->sd_fullmux_ok = 0; + sd->sd_pids_max = 64; + sd->sd_pids_len = 255; + sd->sd_pilot_on = 1; sd->sd_default_rolloff = SATIP_DEFAULT_ROLLOFF_35; - } else if (strcmp(sd->sd_info.modelname, "TVHeadend SAT>IP") == 0) { + } else if (strcmp(sd->sd_info.modelname, "TVHeadend SAT>IP") == 0) { sd->sd_pids_max = 128; sd->sd_pids_len = 2048; sd->sd_no_univ_lnb = 1; if (strcmp(sd->sd_info.modelnum ?: "", "1.0")) - sd->sd_can_weight = 1; + sd->sd_can_weight = 1; } else if (strstr(sd->sd_info.manufacturer, "AVM Berlin") && - strstr(sd->sd_info.modelname, "FRITZ!")) { + strstr(sd->sd_info.modelname, "FRITZ!")) { sd->sd_fullmux_ok = 0; sd->sd_pids_deladd = 0; sd->sd_pids21 = 1; } else if (strstr(sd->sd_info.modelname, "EyeTV Netstream 4C")) { - sd->sd_fe = 0; + sd->sd_fe = 0; } } -static satip_device_t * -satip_device_create( satip_device_info_t *info ) -{ - satip_device_t *sd = calloc(1, sizeof(satip_device_t)); - char uhex[UUID_HEX_SIZE]; - htsmsg_t *conf = NULL, *feconf = NULL; - char *argv[10], *tunercfg; - int i, j, n, m, fenum, v2, save = 0; - dvb_fe_type_t type; - char buf2[60]; +static satip_device_t* satip_device_create(satip_device_info_t* info) { + satip_device_t* sd = calloc(1, sizeof(satip_device_t)); + char uhex[UUID_HEX_SIZE]; + htsmsg_t * conf = NULL, *feconf = NULL; + char * argv[10], *tunercfg; + int i, j, n, m, fenum, v2, save = 0; + dvb_fe_type_t type; + char buf2[60]; sd->sd_inload = 1; @@ -664,8 +622,7 @@ satip_device_create( satip_device_info_t *info ) sd->sd_sig_tunerno = 1; sd->sd_dbus_allow = 1; - if (!tvh_hardware_create0((tvh_hardware_t*)sd, &satip_device_class, - uhex, conf)) { + if (!tvh_hardware_create0((tvh_hardware_t*)sd, &satip_device_class, uhex, conf)) { /* Note: sd is freed in above fcn */ return NULL; } @@ -681,7 +638,9 @@ satip_device_create( satip_device_info_t *info ) if (sd->sd_info.uuid) free(sd->sd_info.uuid); -#define ASSIGN(x) sd->sd_info.x = info->x; info->x = NULL +#define ASSIGN(x) \ + sd->sd_info.x = info->x; \ + info->x = NULL ASSIGN(myaddr); ASSIGN(addr); ASSIGN(uuid); @@ -701,7 +660,7 @@ satip_device_create( satip_device_info_t *info ) ASSIGN(tunercfg); #undef ASSIGN sd->sd_info.rtsp_port = info->rtsp_port; - sd->sd_info.srcs = info->srcs; + sd->sd_info.srcs = info->srcs; /* * device specific hacks @@ -721,47 +680,51 @@ satip_device_create( satip_device_info_t *info ) n = http_tokenize(tvh_strdupa(tunercfg), argv, 10, ','); for (i = m = 0, fenum = 1; i < n; i++) { type = DVB_TYPE_NONE; - v2 = 0; + v2 = 0; if (strncmp(argv[i], "DVBS2-", 6) == 0) { type = DVB_TYPE_S; - m = atoi(argv[i] + 6); - v2 = 1; + m = atoi(argv[i] + 6); + v2 = 1; } else if (strncmp(argv[i], "DVBS-", 5) == 0) { type = DVB_TYPE_S; - m = atoi(argv[i] + 5); + m = atoi(argv[i] + 5); } else if (strncmp(argv[i], "DVBT2-", 6) == 0) { type = DVB_TYPE_T; - m = atoi(argv[i] + 6); - v2 = 1; + m = atoi(argv[i] + 6); + v2 = 1; } else if (strncmp(argv[i], "DVBT-", 5) == 0) { type = DVB_TYPE_T; - m = atoi(argv[i] + 5); + m = atoi(argv[i] + 5); } else if (strncmp(argv[i], "DVBC2-", 6) == 0) { type = DVB_TYPE_C; - m = atoi(argv[i] + 6); - v2 = 1; + m = atoi(argv[i] + 6); + v2 = 1; } else if (strncmp(argv[i], "DVBC-", 5) == 0) { type = DVB_TYPE_C; - m = atoi(argv[i] + 5); + m = atoi(argv[i] + 5); } else if (strncmp(argv[i], "ATSC-", 5) == 0) { type = DVB_TYPE_ATSC_T; - m = atoi(argv[i] + 5); + m = atoi(argv[i] + 5); } else if (strncmp(argv[i], "ATSCT-", 6) == 0) { type = DVB_TYPE_ATSC_T; - m = atoi(argv[i] + 6); + m = atoi(argv[i] + 6); } else if (strncmp(argv[i], "ATSCC-", 6) == 0) { type = DVB_TYPE_ATSC_C; - m = atoi(argv[i] + 6); + m = atoi(argv[i] + 6); } else if (strncmp(argv[i], "ISDBT-", 6) == 0) { type = DVB_TYPE_ISDB_T; - m = atoi(argv[i] + 6); + m = atoi(argv[i] + 6); } if (type == DVB_TYPE_NONE) { - tvherror(LS_SATIP, "%s: bad tuner type [%s]", - satip_device_nicename(sd, buf2, sizeof(buf2)), argv[i]); + tvherror(LS_SATIP, + "%s: bad tuner type [%s]", + satip_device_nicename(sd, buf2, sizeof(buf2)), + argv[i]); } else if (m < 0 || m > 32) { - tvherror(LS_SATIP, "%s: bad tuner count [%s]", - satip_device_nicename(sd, buf2, sizeof(buf2)), argv[i]); + tvherror(LS_SATIP, + "%s: bad tuner count [%s]", + satip_device_nicename(sd, buf2, sizeof(buf2)), + argv[i]); } else { sd->sd_nosave = 1; for (j = 0; j < m; j++) @@ -783,38 +746,32 @@ satip_device_create( satip_device_info_t *info ) return sd; } -static satip_device_t * -satip_device_find( const char *satip_uuid ) -{ - tvh_hardware_t *th; - uint8_t binuuid[20]; +static satip_device_t* satip_device_find(const char* satip_uuid) { + tvh_hardware_t* th; + uint8_t binuuid[20]; satip_device_calc_bin_uuid(binuuid, satip_uuid); - TVH_HARDWARE_FOREACH(th) { + TVH_HARDWARE_FOREACH (th) { if (idnode_is_instance(&th->th_id, &satip_device_class) && memcmp(th->th_id.in_uuid.bin, binuuid, UUID_BIN_SIZE) == 0) - return (satip_device_t *)th; + return (satip_device_t*)th; } return NULL; } -static satip_device_t * -satip_device_find_by_descurl( const char *descurl ) -{ - tvh_hardware_t *th; +static satip_device_t* satip_device_find_by_descurl(const char* descurl) { + tvh_hardware_t* th; - TVH_HARDWARE_FOREACH(th) { + TVH_HARDWARE_FOREACH (th) { if (idnode_is_instance(&th->th_id, &satip_device_class) && - strcmp(((satip_device_t *)th)->sd_info.location, descurl) == 0) - return (satip_device_t *)th; + strcmp(((satip_device_t*)th)->sd_info.location, descurl) == 0) + return (satip_device_t*)th; } return NULL; } -void -satip_device_destroy( satip_device_t *sd ) -{ - satip_frontend_t *lfe; +void satip_device_destroy(satip_device_t* sd) { + satip_frontend_t* lfe; lock_assert(&global_lock); @@ -853,16 +810,12 @@ satip_device_destroy( satip_device_t *sd ) free(sd); } -static void -satip_device_destroy_cb( void *aux ) -{ - satip_device_destroy((satip_device_t *)aux); +static void satip_device_destroy_cb(void* aux) { + satip_device_destroy((satip_device_t*)aux); satip_device_discovery_start(); } -void -satip_device_destroy_later( satip_device_t *sd, int after ) -{ +void satip_device_destroy_later(satip_device_t* sd, int after) { mtimer_arm_rel(&sd->sd_destroy_timer, satip_device_destroy_cb, sd, ms2mono(after)); } @@ -872,33 +825,31 @@ satip_device_destroy_later( satip_device_t *sd, int after ) typedef struct satip_discovery { TAILQ_ENTRY(satip_discovery) disc_link; - char *myaddr; - char *location; - char *server; - char *uuid; - char *bootid; - char *configid; - char *deviceid; - url_t url; - http_client_t *http_client; - int64_t http_start; + char* myaddr; + char* location; + char* server; + char* uuid; + char* bootid; + char* configid; + char* deviceid; + url_t url; + http_client_t* http_client; + int64_t http_start; } satip_discovery_t; TAILQ_HEAD(satip_discovery_queue, satip_discovery); -static int satip_enabled; -static int satip_discoveries_count; +static int satip_enabled; +static int satip_discoveries_count; static struct satip_discovery_queue satip_discoveries; -static upnp_service_t *satip_discovery_service; -static mtimer_t satip_discovery_timer; -static mtimer_t satip_discovery_static_timer; -static mtimer_t satip_discovery_timerq; -static mtimer_t satip_discovery_msearch_timer; -static str_list_t *satip_static_clients; - -static void -satip_discovery_destroy(satip_discovery_t *d, int unlink) -{ +static upnp_service_t* satip_discovery_service; +static mtimer_t satip_discovery_timer; +static mtimer_t satip_discovery_static_timer; +static mtimer_t satip_discovery_timerq; +static mtimer_t satip_discovery_msearch_timer; +static str_list_t* satip_static_clients; + +static void satip_discovery_destroy(satip_discovery_t* d, int unlink) { if (d == NULL) return; if (unlink) { @@ -918,42 +869,38 @@ satip_discovery_destroy(satip_discovery_t *d, int unlink) free(d); } -static satip_discovery_t * -satip_discovery_find(satip_discovery_t *d) -{ - satip_discovery_t *sd; +static satip_discovery_t* satip_discovery_find(satip_discovery_t* d) { + satip_discovery_t* sd; - TAILQ_FOREACH(sd, &satip_discoveries, disc_link) + TAILQ_FOREACH (sd, &satip_discoveries, disc_link) if (strcmp(sd->uuid, d->uuid) == 0) return sd; return NULL; } -static void -satip_discovery_http_closed(http_client_t *hc, int errn) -{ - satip_discovery_t *d = hc->hc_aux; - char *s; - htsmsg_t *xml = NULL, *tags, *root, *device; - const char *friendlyname, *manufacturer, *manufacturerURL, *modeldesc; - const char *modelname, *modelnum, *serialnum; - const char *presentation, *tunercfg, *udn, *uuid; - const char *cs, *arg; +static void satip_discovery_http_closed(http_client_t* hc, int errn) { + satip_discovery_t* d = hc->hc_aux; + char* s; + htsmsg_t * xml = NULL, *tags, *root, *device; + const char * friendlyname, *manufacturer, *manufacturerURL, *modeldesc; + const char * modelname, *modelnum, *serialnum; + const char * presentation, *tunercfg, *udn, *uuid; + const char * cs, *arg; satip_device_info_t info; - char errbuf[100]; - char *argv[10]; - int i, n; + char errbuf[100]; + char* argv[10]; + int i, n; s = http_arg_get(&hc->hc_args, "Content-Type"); if (s) { n = http_tokenize(s, argv, ARRAY_SIZE(argv), ';'); if (n <= 0 || strcasecmp(s, "text/xml")) { errn = ENOENT; - s = NULL; + s = NULL; } } - if (errn != 0 || s == NULL || hc->hc_code != 200 || - hc->hc_data_size == 0 || hc->hc_data == NULL) { + if (errn != 0 || s == NULL || hc->hc_code != 200 || hc->hc_data_size == 0 || + hc->hc_data == NULL) { tvherror(LS_SATIP, "Cannot get %s: %s", d->location, strerror(errn)); return; } @@ -965,9 +912,9 @@ satip_discovery_http_closed(http_client_t *hc, int errn) if (d->myaddr == NULL || d->myaddr[0] == '\0') { struct sockaddr_storage ip; - socklen_t addrlen = sizeof(ip); - errbuf[0] = '\0'; - getsockname(hc->hc_fd, (struct sockaddr *)&ip, &addrlen); + socklen_t addrlen = sizeof(ip); + errbuf[0] = '\0'; + getsockname(hc->hc_fd, (struct sockaddr*)&ip, &addrlen); inet_ntop(ip.ss_family, IP_IN_ADDR(ip), errbuf, sizeof(errbuf)); free(d->myaddr); d->myaddr = strdup(errbuf); @@ -981,23 +928,23 @@ satip_discovery_http_closed(http_client_t *hc, int errn) if (strncmp(s, "", 7)) return; /* Parse */ - xml = htsmsg_xml_deserialize(hc->hc_data, errbuf, sizeof(errbuf)); + xml = htsmsg_xml_deserialize(hc->hc_data, errbuf, sizeof(errbuf)); hc->hc_data = NULL; if (!xml) { tvherror(LS_SATIP, "satip_discovery_desc htsmsg_xml_deserialize error %s", errbuf); goto finish; } - if ((tags = htsmsg_get_map(xml, "tags")) == NULL) + if ((tags = htsmsg_get_map(xml, "tags")) == NULL) goto finish; - if ((root = htsmsg_get_map(tags, "root")) == NULL) + if ((root = htsmsg_get_map(tags, "root")) == NULL) goto finish; - if ((device = htsmsg_get_map(root, "tags")) == NULL) + if ((device = htsmsg_get_map(root, "tags")) == NULL) goto finish; - if ((device = htsmsg_get_map(device, "device")) == NULL) + if ((device = htsmsg_get_map(device, "device")) == NULL) goto finish; - if ((device = htsmsg_get_map(device, "tags")) == NULL) + if ((device = htsmsg_get_map(device, "tags")) == NULL) goto finish; - if ((cs = htsmsg_xml_get_cdata_str(device, "deviceType")) == NULL) + if ((cs = htsmsg_xml_get_cdata_str(device, "deviceType")) == NULL) goto finish; if (strcmp(cs, "urn:ses-com:device:SatIPServer:1")) goto finish; @@ -1007,24 +954,24 @@ satip_discovery_http_closed(http_client_t *hc, int errn) manufacturer = ""; if ((manufacturerURL = htsmsg_xml_get_cdata_str(device, "manufacturerURL")) == NULL) manufacturerURL = ""; - if ((modeldesc = htsmsg_xml_get_cdata_str(device, "modelDescription")) == NULL) + if ((modeldesc = htsmsg_xml_get_cdata_str(device, "modelDescription")) == NULL) modeldesc = ""; - if ((modelname = htsmsg_xml_get_cdata_str(device, "modelName")) == NULL) + if ((modelname = htsmsg_xml_get_cdata_str(device, "modelName")) == NULL) goto finish; - if ((modelnum = htsmsg_xml_get_cdata_str(device, "modelNumber")) == NULL) + if ((modelnum = htsmsg_xml_get_cdata_str(device, "modelNumber")) == NULL) modelnum = ""; - if ((serialnum = htsmsg_xml_get_cdata_str(device, "serialNumber")) == NULL) + if ((serialnum = htsmsg_xml_get_cdata_str(device, "serialNumber")) == NULL) serialnum = ""; if ((presentation = htsmsg_xml_get_cdata_str(device, "presentationURL")) == NULL) presentation = ""; - if ((udn = htsmsg_xml_get_cdata_str(device, "UDN")) == NULL) + if ((udn = htsmsg_xml_get_cdata_str(device, "UDN")) == NULL) goto finish; - if ((tunercfg = htsmsg_xml_get_cdata_str(device, "urn:ses-com:satipX_SATIPCAP")) == NULL) + if ((tunercfg = htsmsg_xml_get_cdata_str(device, "urn:ses-com:satipX_SATIPCAP")) == NULL) tunercfg = ""; uuid = NULL; - n = http_tokenize((char *)udn, argv, ARRAY_SIZE(argv), ':'); - for (i = 0; i < n+1; i++) + n = http_tokenize((char*)udn, argv, ARRAY_SIZE(argv), ':'); + for (i = 0; i < n + 1; i++) if (argv[i] && strcmp(argv[i], "uuid") == 0) { uuid = argv[++i]; break; @@ -1033,7 +980,7 @@ satip_discovery_http_closed(http_client_t *hc, int errn) goto finish; info.rtsp_port = 554; - info.srcs = 4; + info.srcs = 4; arg = http_arg_get(&hc->hc_args, "X-SATIP-RTSP-Port"); if (arg) { @@ -1048,23 +995,23 @@ satip_discovery_http_closed(http_client_t *hc, int errn) info.srcs = i; } - info.myaddr = strdup(d->myaddr); - info.addr = strdup(d->url.host); - info.uuid = strdup(uuid); - info.bootid = strdup(d->bootid); - info.configid = strdup(d->configid); - info.deviceid = strdup(d->deviceid); - info.location = strdup(d->location); - info.server = strdup(d->server); - info.friendlyname = strdup(friendlyname); - info.manufacturer = strdup(manufacturer); + info.myaddr = strdup(d->myaddr); + info.addr = strdup(d->url.host); + info.uuid = strdup(uuid); + info.bootid = strdup(d->bootid); + info.configid = strdup(d->configid); + info.deviceid = strdup(d->deviceid); + info.location = strdup(d->location); + info.server = strdup(d->server); + info.friendlyname = strdup(friendlyname); + info.manufacturer = strdup(manufacturer); info.manufacturerURL = strdup(manufacturerURL); - info.modeldesc = strdup(modeldesc); - info.modelname = strdup(modelname); - info.modelnum = strdup(modelnum); - info.serialnum = strdup(serialnum); - info.presentation = strdup(presentation); - info.tunercfg = strdup(tunercfg); + info.modeldesc = strdup(modeldesc); + info.modelname = strdup(modelname); + info.modelnum = strdup(modelnum); + info.serialnum = strdup(serialnum); + info.presentation = strdup(presentation); + info.tunercfg = strdup(tunercfg); htsmsg_destroy(xml); xml = NULL; tvh_mutex_lock(&global_lock); @@ -1092,17 +1039,15 @@ finish: htsmsg_destroy(xml); } -static void -satip_discovery_timerq_cb(void *aux) -{ +static void satip_discovery_timerq_cb(void* aux) { satip_discovery_t *d, *next; - int r; + int r; lock_assert(&global_lock); next = TAILQ_FIRST(&satip_discoveries); while (next) { - d = next; + d = next; next = TAILQ_NEXT(d, disc_link); if (d->http_client) { if (mclk() - d->http_start > sec2mono(4)) @@ -1110,12 +1055,12 @@ satip_discovery_timerq_cb(void *aux) continue; } - d->http_client = http_client_connect(d, HTTP_VERSION_1_1, d->url.scheme, - d->url.host, d->url.port, NULL); + d->http_client = + http_client_connect(d, HTTP_VERSION_1_1, d->url.scheme, d->url.host, d->url.port, NULL); if (d->http_client == NULL) satip_discovery_destroy(d, 1); else { - d->http_start = mclk(); + d->http_start = mclk(); d->http_client->hc_conn_closed = satip_discovery_http_closed; http_client_register(d->http_client); r = http_client_simple(d->http_client, &d->url); @@ -1127,30 +1072,29 @@ satip_discovery_timerq_cb(void *aux) mtimer_arm_rel(&satip_discovery_timerq, satip_discovery_timerq_cb, NULL, sec2mono(5)); } -static void -satip_discovery_service_received - (uint8_t *data, size_t len, udp_connection_t *conn, - struct sockaddr_storage *storage) -{ - char *buf, *ptr, *saveptr; - char *argv[10]; - char *st = NULL; - char *location = NULL; - char *server = NULL; - char *uuid = NULL; - char *bootid = NULL; - char *configid = NULL; - char *deviceid = NULL; - char sockbuf[128]; - satip_discovery_t *d; - int n, i; +static void satip_discovery_service_received(uint8_t* data, + size_t len, + udp_connection_t* conn, + struct sockaddr_storage* storage) { + char * buf, *ptr, *saveptr; + char* argv[10]; + char* st = NULL; + char* location = NULL; + char* server = NULL; + char* uuid = NULL; + char* bootid = NULL; + char* configid = NULL; + char* deviceid = NULL; + char sockbuf[128]; + satip_discovery_t* d; + int n, i; if (len > 8191 || atomic_get(&satip_discoveries_count) > 100) return; - buf = alloca(len+1); + buf = alloca(len + 1); memcpy(buf, data, len); buf[len] = '\0'; - ptr = strtok_r(buf, "\r\n", &saveptr); + ptr = strtok_r(buf, "\r\n", &saveptr); /* Request decoder */ if (ptr) { if (http_tokenize(ptr, argv, 3, -1) != 3) @@ -1189,7 +1133,7 @@ satip_discovery_service_received deviceid = argv[1]; else if (strcasecmp(argv[0], "USN") == 0) { n = http_tokenize(argv[1], argv, ARRAY_SIZE(argv), ':'); - for (i = 0; i < n-1; i++) + for (i = 0; i < n - 1; i++) if (argv[i] && strcmp(argv[i], "uuid") == 0) { uuid = argv[++i]; break; @@ -1211,8 +1155,7 @@ satip_discovery_service_received /* Forward information to next layer */ d = calloc(1, sizeof(satip_discovery_t)); - if (inet_ntop(conn->ip.ss_family, IP_IN_ADDR(conn->ip), - sockbuf, sizeof(sockbuf)) == NULL) { + if (inet_ntop(conn->ip.ss_family, IP_IN_ADDR(conn->ip), sockbuf, sizeof(sockbuf)) == NULL) { satip_discovery_destroy(d, 0); return; } @@ -1228,7 +1171,7 @@ satip_discovery_service_received return; } - tvh_mutex_lock(&global_lock); + tvh_mutex_lock(&global_lock); i = 1; if (!satip_discovery_find(d) && !satip_device_find(d->uuid)) { TAILQ_INSERT_TAIL(&satip_discoveries, d, disc_link); @@ -1251,10 +1194,8 @@ add_uuid: tvh_mutex_unlock(&global_lock); } -static void -satip_discovery_static(const char *descurl) -{ - satip_discovery_t *d; +static void satip_discovery_static(const char* descurl) { + satip_discovery_t* d; lock_assert(&global_lock); @@ -1278,22 +1219,19 @@ satip_discovery_static(const char *descurl) satip_discovery_timerq_cb(NULL); } -static void -satip_discovery_service_destroy(upnp_service_t *us) -{ +static void satip_discovery_service_destroy(upnp_service_t* us) { satip_discovery_service = NULL; } -static void -satip_discovery_send_msearch(void *aux) -{ -#define MSG "\ +static void satip_discovery_send_msearch(void* aux) { +#define MSG \ + "\ M-SEARCH * HTTP/1.1\r\n\ HOST: 239.255.255.250:1900\r\n\ MAN: \"ssdp:discover\"\r\n\ MX: 2\r\n\ ST: urn:ses-com:device:SatIPServer:1\r\n" - int attempt = ((intptr_t)aux) % 10; + int attempt = ((intptr_t)aux) % 10; htsbuf_queue_t q; /* UDP is not reliable - send this message three times */ @@ -1303,77 +1241,70 @@ ST: urn:ses-com:device:SatIPServer:1\r\n" return; htsbuf_queue_init(&q, 0); - htsbuf_append(&q, MSG, sizeof(MSG)-1); + htsbuf_append(&q, MSG, sizeof(MSG) - 1); htsbuf_qprintf(&q, "USER-AGENT: unix/1.0 UPnP/1.1 tvheadend/%s\r\n", tvheadend_version); htsbuf_append(&q, "\r\n", 2); upnp_send(&q, NULL, 0, 0); htsbuf_queue_flush(&q); - mtimer_arm_rel(&satip_discovery_msearch_timer, satip_discovery_send_msearch, - (void *)(intptr_t)(attempt + 1), ms2mono(attempt * 11)); + mtimer_arm_rel(&satip_discovery_msearch_timer, + satip_discovery_send_msearch, + (void*)(intptr_t)(attempt + 1), + ms2mono(attempt * 11)); #undef MSG } -static void -satip_discovery_static_timer_cb(void *aux) -{ +static void satip_discovery_static_timer_cb(void* aux) { static int next_timeout = 10; - int i; + int i; if (!tvheadend_is_running()) return; for (i = 0; i < satip_static_clients->num; i++) satip_discovery_static(satip_static_clients->str[i]); - mtimer_arm_rel(&satip_discovery_static_timer, satip_discovery_static_timer_cb, - NULL, sec2mono(next_timeout)); + mtimer_arm_rel(&satip_discovery_static_timer, + satip_discovery_static_timer_cb, + NULL, + sec2mono(next_timeout)); if (next_timeout < 3600) next_timeout = next_timeout >= 30 ? 3600 : 30; } -static void -satip_discovery_timer_cb(void *aux) -{ +static void satip_discovery_timer_cb(void* aux) { static int next_timeout = 10; if (!tvheadend_is_running()) return; if (!atomic_get(&upnp_running)) { - mtimer_arm_rel(&satip_discovery_timer, satip_discovery_timer_cb, - NULL, sec2mono(1)); + mtimer_arm_rel(&satip_discovery_timer, satip_discovery_timer_cb, NULL, sec2mono(1)); return; } if (satip_discovery_service == NULL) { - satip_discovery_service = upnp_service_create(upnp_service); + satip_discovery_service = upnp_service_create(upnp_service); if (satip_discovery_service) { satip_discovery_service->us_received = satip_discovery_service_received; satip_discovery_service->us_destroy = satip_discovery_service_destroy; } } if (satip_discovery_service) - satip_discovery_send_msearch((void *)1); - mtimer_arm_rel(&satip_discovery_timer, satip_discovery_timer_cb, - NULL, sec2mono(next_timeout)); + satip_discovery_send_msearch((void*)1); + mtimer_arm_rel(&satip_discovery_timer, satip_discovery_timer_cb, NULL, sec2mono(next_timeout)); if (next_timeout < 3600) next_timeout = next_timeout >= 30 ? 3600 : 30; } -void -satip_device_discovery_start( void ) -{ +void satip_device_discovery_start(void) { if (!satip_enabled) return; - mtimer_arm_rel(&satip_discovery_timer, satip_discovery_timer_cb, - NULL, sec2mono(1)); - mtimer_arm_rel(&satip_discovery_static_timer, satip_discovery_static_timer_cb, - NULL, sec2mono(1)); + mtimer_arm_rel(&satip_discovery_timer, satip_discovery_timer_cb, NULL, sec2mono(1)); + mtimer_arm_rel(&satip_discovery_static_timer, satip_discovery_static_timer_cb, NULL, sec2mono(1)); } /* * Initialization */ -void satip_init ( int nosatip, str_list_t *clients ) -{ +void satip_init(int nosatip, str_list_t* clients) { idclass_register(&satip_device_class); idclass_register(&satip_frontend_class); @@ -1395,16 +1326,15 @@ void satip_init ( int nosatip, str_list_t *clients ) } } -void satip_done ( void ) -{ - tvh_hardware_t *th, *n; +void satip_done(void) { + tvh_hardware_t * th, *n; satip_discovery_t *d, *nd; tvh_mutex_lock(&global_lock); for (th = LIST_FIRST(&tvh_hardware); th != NULL; th = n) { n = LIST_NEXT(th, th_link); if (idnode_is_instance(&th->th_id, &satip_device_class)) { - satip_device_destroy((satip_device_t *)th); + satip_device_destroy((satip_device_t*)th); } } for (d = TAILQ_FIRST(&satip_discoveries); d != NULL; d = nd) { diff --git a/src/input/mpegts/satip/satip.h b/src/input/mpegts/satip/satip.h index ee403d035..83c861ac0 100644 --- a/src/input/mpegts/satip/satip.h +++ b/src/input/mpegts/satip/satip.h @@ -20,9 +20,9 @@ #ifndef __TVH_SATIP_H__ #define __TVH_SATIP_H__ -void satip_device_discovery_start( void ); +void satip_device_discovery_start(void); -void satip_init( int nosatip, str_list_t *clients ); -void satip_done( void ); +void satip_init(int nosatip, str_list_t* clients); +void satip_done(void); #endif /* __TVH_SATIP_H__ */ diff --git a/src/input/mpegts/satip/satip_frontend.c b/src/input/mpegts/satip/satip_frontend.c index 1c414da68..a85dcb3d6 100644 --- a/src/input/mpegts/satip/satip_frontend.c +++ b/src/input/mpegts/satip/satip_frontend.c @@ -29,62 +29,49 @@ #include #endif - -typedef enum rtp_transport_mode -{ - RTP_SERVER_DEFAULT, // Use server configuretion - RTP_UDP, // Use regular RTP/AVP_UDP - RTP_INTERLEAVED, // Use Interleaved RTP/AVP/TCP +typedef enum rtp_transport_mode { + RTP_SERVER_DEFAULT, // Use server configuretion + RTP_UDP, // Use regular RTP/AVP_UDP + RTP_INTERLEAVED, // Use Interleaved RTP/AVP/TCP } rtp_transport_mode_t; - /* * */ -static int -udp_rtp_packet_cmp( const void *_a, const void *_b ) -{ +static int udp_rtp_packet_cmp(const void* _a, const void* _b) { const struct satip_udppkt *a = _a, *b = _b; - int seq1 = a->up_data_seq, seq2 = b->up_data_seq; - if (seq1 < 0x4000 && seq2 > 0xc000) return 1; - if (seq2 < 0x4000 && seq1 > 0xc000) return -1; + int seq1 = a->up_data_seq, seq2 = b->up_data_seq; + if (seq1 < 0x4000 && seq2 > 0xc000) + return 1; + if (seq2 < 0x4000 && seq1 > 0xc000) + return -1; return seq1 - seq2; } -static void -udp_rtp_packet_free( satip_frontend_t *lfe, struct satip_udppkt *up ) -{ +static void udp_rtp_packet_free(satip_frontend_t* lfe, struct satip_udppkt* up) { free(up->up_data); free(up); } -static void -udp_rtp_packet_remove( satip_frontend_t *lfe, struct satip_udppkt *up ) -{ +static void udp_rtp_packet_remove(satip_frontend_t* lfe, struct satip_udppkt* up) { TAILQ_REMOVE(&lfe->sf_udp_packets, up, up_link); lfe->sf_udp_packets_count--; } -static void -udp_rtp_packet_destroy( satip_frontend_t *lfe, struct satip_udppkt *up ) -{ +static void udp_rtp_packet_destroy(satip_frontend_t* lfe, struct satip_udppkt* up) { udp_rtp_packet_remove(lfe, up); udp_rtp_packet_free(lfe, up); } -static void -udp_rtp_packet_destroy_all( satip_frontend_t *lfe ) -{ - struct satip_udppkt *up; +static void udp_rtp_packet_destroy_all(satip_frontend_t* lfe) { + struct satip_udppkt* up; while ((up = TAILQ_FIRST(&lfe->sf_udp_packets)) != NULL) udp_rtp_packet_destroy(lfe, up); } -static void -udp_rtp_packet_append( satip_frontend_t *lfe, uint8_t *p, int len, uint16_t seq ) -{ - struct satip_udppkt *up = malloc(sizeof(*up)); +static void udp_rtp_packet_append(satip_frontend_t* lfe, uint8_t* p, int len, uint16_t seq) { + struct satip_udppkt* up = malloc(sizeof(*up)); if (len > 0) { up->up_data = malloc(len); memcpy(up->up_data, p, len); @@ -100,49 +87,42 @@ udp_rtp_packet_append( satip_frontend_t *lfe, uint8_t *p, int len, uint16_t seq /* * */ -static int -satip_frontend_rtsp_flags( satip_frontend_t *lfe ) -{ +static int satip_frontend_rtsp_flags(satip_frontend_t* lfe) { int rtsp_flags = lfe->sf_device->sd_tcp_mode ? SATIP_SETUP_TCP : 0; if (lfe->sf_transport_mode != RTP_SERVER_DEFAULT) rtsp_flags = lfe->sf_transport_mode == RTP_INTERLEAVED ? SATIP_SETUP_TCP : 0; return rtsp_flags; } -static satip_frontend_t * -satip_frontend_find_by_number( satip_device_t *sd, int num ) -{ - satip_frontend_t *lfe; +static satip_frontend_t* satip_frontend_find_by_number(satip_device_t* sd, int num) { + satip_frontend_t* lfe; - TAILQ_FOREACH(lfe, &sd->sd_frontends, sf_link) + TAILQ_FOREACH (lfe, &sd->sd_frontends, sf_link) if (lfe->sf_number == num) return lfe; return NULL; } -static char * -satip_frontend_bindaddr( satip_frontend_t *lfe ) -{ - char *bindaddr = lfe->sf_tuner_bindaddr; +static char* satip_frontend_bindaddr(satip_frontend_t* lfe) { + char* bindaddr = lfe->sf_tuner_bindaddr; if (bindaddr == NULL || bindaddr[0] == '\0') bindaddr = lfe->sf_device->sd_bindaddr; return bindaddr; } -static void -satip_frontend_signal_cb( void *aux ) -{ - satip_frontend_t *lfe = aux; - mpegts_mux_instance_t *mmi = LIST_FIRST(&lfe->mi_mux_active); +static void satip_frontend_signal_cb(void* aux) { + satip_frontend_t* lfe = aux; + mpegts_mux_instance_t* mmi = LIST_FIRST(&lfe->mi_mux_active); streaming_message_t sm; signal_status_t sigstat; - service_t *svc; + service_t* svc; if (mmi == NULL) return; if (!lfe->sf_tables) { - psi_tables_install(mmi->mmi_input, mmi->mmi_mux, - ((dvb_mux_t *)mmi->mmi_mux)->lm_tuning.dmc_fe_delsys); + psi_tables_install(mmi->mmi_input, + mmi->mmi_mux, + ((dvb_mux_t*)mmi->mmi_mux)->lm_tuning.dmc_fe_delsys); lfe->sf_tables = 1; } tvh_mutex_lock(&mmi->tii_stats_mutex); @@ -161,41 +141,33 @@ satip_frontend_signal_cb( void *aux ) memset(&sm, 0, sizeof(sm)); sm.sm_type = SMT_SIGNAL_STATUS; sm.sm_data = &sigstat; - LIST_FOREACH(svc, &mmi->mmi_mux->mm_transports, s_active_link) { + LIST_FOREACH (svc, &mmi->mmi_mux->mm_transports, s_active_link) { tvh_mutex_lock(&svc->s_stream_mutex); streaming_service_deliver(svc, streaming_msg_clone(&sm)); tvh_mutex_unlock(&svc->s_stream_mutex); } - mtimer_arm_rel(&lfe->sf_monitor_timer, satip_frontend_signal_cb, - lfe, ms2mono(250)); + mtimer_arm_rel(&lfe->sf_monitor_timer, satip_frontend_signal_cb, lfe, ms2mono(250)); } /* ************************************************************************** * Class definition * *************************************************************************/ -static void -satip_frontend_class_changed ( idnode_t *in ) -{ - satip_device_t *la = ((satip_frontend_t*)in)->sf_device; +static void satip_frontend_class_changed(idnode_t* in) { + satip_device_t* la = ((satip_frontend_t*)in)->sf_device; satip_device_changed(la); } -static int -satip_frontend_set_new_type - ( satip_frontend_t *lfe, const char *type ) -{ +static int satip_frontend_set_new_type(satip_frontend_t* lfe, const char* type) { free(lfe->sf_type_override); lfe->sf_type_override = strdup(type); satip_device_destroy_later(lfe->sf_device, 100); return 1; } -static int -satip_frontend_class_override_set( void *obj, const void * p ) -{ - satip_frontend_t *lfe = obj; - const char *s = p; +static int satip_frontend_class_override_set(void* obj, const void* p) { + satip_frontend_t* lfe = obj; + const char* s = p; if (lfe->sf_type_override == NULL) { if (strlen(p) > 0) @@ -205,206 +177,184 @@ satip_frontend_class_override_set( void *obj, const void * p ) return 0; } -static htsmsg_t * -satip_frontend_class_override_enum( void * p, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_list(); +static htsmsg_t* satip_frontend_class_override_enum(void* p, const char* lang) { + htsmsg_t* m = htsmsg_create_list(); htsmsg_add_str(m, NULL, "DVB-T"); htsmsg_add_str(m, NULL, "DVB-C"); return m; } -static htsmsg_t * -satip_frontend_transport_mode_list ( void *o, const char *lang ) -{ +static htsmsg_t* satip_frontend_transport_mode_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Default server config"), RTP_SERVER_DEFAULT }, - { N_("RTP over UDP"), RTP_UDP }, - { N_("TCP Interleaved"), RTP_INTERLEAVED }, + {N_("Default server config"), RTP_SERVER_DEFAULT}, + {N_("RTP over UDP"), RTP_UDP}, + {N_("TCP Interleaved"), RTP_INTERLEAVED}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -satip_frontend_specinv_list ( void *o, const char *lang ) -{ +static htsmsg_t* satip_frontend_specinv_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Do not use"), 0 }, - { N_("Off"), 1 }, - { N_("On"), 2 }, + {N_("Do not use"), 0}, + {N_("Off"), 1}, + {N_("On"), 2}, }; return strtab2htsmsg(tab, 1, lang); } CLASS_DOC(satip_frontend) -const idclass_t satip_frontend_class = -{ - .ic_super = &mpegts_input_class, - .ic_class = "satip_frontend", - .ic_doc = tvh_doc_satip_frontend_class, - .ic_caption = N_("TV Adapters - SAT>IP DVB Frontend"), - .ic_changed = satip_frontend_class_changed, - .ic_properties = (const property_t[]) { - { - .type = PT_INT, - .id = "fe_number", - .name = N_("Frontend number"), - .desc = N_("SAT->IP frontend number."), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(satip_frontend_t, sf_number), - }, - { - .type = PT_INT, - .id = "transport_mode", - .name = N_("Transport mode"), - .desc = N_("Select the transport used for this tuner."), - .list = satip_frontend_transport_mode_list, - .off = offsetof(satip_frontend_t, sf_transport_mode), - .opts = PO_ADVANCED, - }, - { - .type = PT_INT, - .id = "udp_rtp_port", - .name = N_("UDP RTP port number (2 ports)"), - .desc = N_("Force the local UDP Port number here. The number " - "should be even (RTP port). The next odd number " - "(+1) will be used as the RTCP port."), - .off = offsetof(satip_frontend_t, sf_udp_rtp_port), - .opts = PO_ADVANCED, - }, - { - .type = PT_INT, - .id = "tdelay", - .name = N_("Next tune delay in ms (0-2000)"), - .desc = N_("The minimum delay before tuning in milliseconds " - "after tuner stop. If the time between the " - "previous and next start is greater than this " - "value then the delay is not applied."), - .opts = PO_ADVANCED, - .off = offsetof(satip_frontend_t, sf_tdelay), - }, - { - .type = PT_BOOL, - .id = "play2", - .name = N_("Send full PLAY cmd"), - .desc = N_("Send the full RTSP PLAY command after full RTSP " - "SETUP command. Some devices firmware require this " - "to get an MPEG-TS stream."), - .opts = PO_ADVANCED, - .off = offsetof(satip_frontend_t, sf_play2), - }, - { - .type = PT_INT, - .id = "grace_period", - .name = N_("Grace period"), - .desc = N_("Force the grace period for which SAT>IP client waits " - "for the data from server. After this grace period, " - "the tuner is handled as dead. The default value is " - "5 seconds (for DVB-S/S2: 10 seconds)."), - .opts = PO_ADVANCED, - .off = offsetof(satip_frontend_t, sf_grace_period), - }, - { - .type = PT_BOOL, - .id = "teardown_delay", - .name = N_("Force teardown delay"), - .desc = N_("Force the delay between RTSP TEARDOWN and RTSP " - "SETUP command (value from 'Next tune delay in ms' " - "is used). Some devices are not able to handle " - "quick continuous tuning."), - .opts = PO_ADVANCED, - .off = offsetof(satip_frontend_t, sf_teardown_delay), - }, - { - .type = PT_INT, - .id = "pass_weight", - .name = N_("Pass subscription weight"), - .desc = N_("Pass subscription weight to the SAT>IP server " - "(Tvheadend specific extension)."), - .opts = PO_ADVANCED, - .off = offsetof(satip_frontend_t, sf_pass_weight), - }, - { - .type = PT_INT, - .id = "specinv", - .name = N_("Pass specinv"), - .desc = N_("Pass Spectrum inversion to the SAT>IP server."), - .opts = PO_ADVANCED, - .off = offsetof(satip_frontend_t, sf_specinv), - .list = satip_frontend_specinv_list, - }, - { - .type = PT_STR, - .id = "tunerbindaddr", - .name = N_("Tuner bind IP address"), - .desc = N_("Force all network connections to this tuner to be " - "made over the specified IP address, similar to " - "the setting for the SAT>IP device itself. " - "Setting this overrides the device-specific " - "setting."), - .opts = PO_ADVANCED, - .off = offsetof(satip_frontend_t, sf_tuner_bindaddr), - }, - {} - } -}; - -static htsmsg_t * -satip_frontend_dvbt_delsys_list ( void *o, const char *lang ) -{ +const idclass_t satip_frontend_class = {.ic_super = &mpegts_input_class, + .ic_class = "satip_frontend", + .ic_doc = tvh_doc_satip_frontend_class, + .ic_caption = N_("TV Adapters - SAT>IP DVB Frontend"), + .ic_changed = satip_frontend_class_changed, + .ic_properties = (const property_t[]){{ + .type = PT_INT, + .id = "fe_number", + .name = N_("Frontend number"), + .desc = N_("SAT->IP frontend number."), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(satip_frontend_t, sf_number), + }, + { + .type = PT_INT, + .id = "transport_mode", + .name = N_("Transport mode"), + .desc = N_("Select the transport used for this tuner."), + .list = satip_frontend_transport_mode_list, + .off = offsetof(satip_frontend_t, sf_transport_mode), + .opts = PO_ADVANCED, + }, + { + .type = PT_INT, + .id = "udp_rtp_port", + .name = N_("UDP RTP port number (2 ports)"), + .desc = N_("Force the local UDP Port number here. The number " + "should be even (RTP port). The next odd number " + "(+1) will be used as the RTCP port."), + .off = offsetof(satip_frontend_t, sf_udp_rtp_port), + .opts = PO_ADVANCED, + }, + { + .type = PT_INT, + .id = "tdelay", + .name = N_("Next tune delay in ms (0-2000)"), + .desc = N_("The minimum delay before tuning in milliseconds " + "after tuner stop. If the time between the " + "previous and next start is greater than this " + "value then the delay is not applied."), + .opts = PO_ADVANCED, + .off = offsetof(satip_frontend_t, sf_tdelay), + }, + { + .type = PT_BOOL, + .id = "play2", + .name = N_("Send full PLAY cmd"), + .desc = N_("Send the full RTSP PLAY command after full RTSP " + "SETUP command. Some devices firmware require this " + "to get an MPEG-TS stream."), + .opts = PO_ADVANCED, + .off = offsetof(satip_frontend_t, sf_play2), + }, + { + .type = PT_INT, + .id = "grace_period", + .name = N_("Grace period"), + .desc = N_("Force the grace period for which SAT>IP client waits " + "for the data from server. After this grace period, " + "the tuner is handled as dead. The default value is " + "5 seconds (for DVB-S/S2: 10 seconds)."), + .opts = PO_ADVANCED, + .off = offsetof(satip_frontend_t, sf_grace_period), + }, + { + .type = PT_BOOL, + .id = "teardown_delay", + .name = N_("Force teardown delay"), + .desc = N_("Force the delay between RTSP TEARDOWN and RTSP " + "SETUP command (value from 'Next tune delay in ms' " + "is used). Some devices are not able to handle " + "quick continuous tuning."), + .opts = PO_ADVANCED, + .off = offsetof(satip_frontend_t, sf_teardown_delay), + }, + { + .type = PT_INT, + .id = "pass_weight", + .name = N_("Pass subscription weight"), + .desc = N_("Pass subscription weight to the SAT>IP server " + "(Tvheadend specific extension)."), + .opts = PO_ADVANCED, + .off = offsetof(satip_frontend_t, sf_pass_weight), + }, + { + .type = PT_INT, + .id = "specinv", + .name = N_("Pass specinv"), + .desc = N_("Pass Spectrum inversion to the SAT>IP server."), + .opts = PO_ADVANCED, + .off = offsetof(satip_frontend_t, sf_specinv), + .list = satip_frontend_specinv_list, + }, + { + .type = PT_STR, + .id = "tunerbindaddr", + .name = N_("Tuner bind IP address"), + .desc = N_("Force all network connections to this tuner to be " + "made over the specified IP address, similar to " + "the setting for the SAT>IP device itself. " + "Setting this overrides the device-specific " + "setting."), + .opts = PO_ADVANCED, + .off = offsetof(satip_frontend_t, sf_tuner_bindaddr), + }, + {}}}; + +static htsmsg_t* satip_frontend_dvbt_delsys_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("All"), DVB_SYS_NONE }, - { N_("DVB-T"), DVB_SYS_DVBT }, - { N_("DVB-T2"), DVB_SYS_DVBT2 }, + {N_("All"), DVB_SYS_NONE}, + {N_("DVB-T"), DVB_SYS_DVBT}, + {N_("DVB-T2"), DVB_SYS_DVBT2}, }; return strtab2htsmsg(tab, 1, lang); } -const idclass_t satip_frontend_dvbt_class = -{ - .ic_super = &satip_frontend_class, - .ic_class = "satip_frontend_dvbt", - .ic_caption = N_("TV Adapters - SAT>IP DVB-T Frontend"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "fe_override", - .name = N_("Network type"), - .desc = N_("Override the frontend type."), - .set = satip_frontend_class_override_set, - .list = satip_frontend_class_override_enum, - .off = offsetof(satip_frontend_t, sf_type_override), - }, - { - .type = PT_INT, - .id = "delsys", - .name = N_("Delivery system"), - .desc = N_("Limit delivery system."), - .opts = PO_EXPERT, - .list = satip_frontend_dvbt_delsys_list, - .off = offsetof(satip_frontend_t, sf_delsys), - }, - {} - } -}; - -static idnode_set_t * -satip_frontend_dvbs_class_get_childs ( idnode_t *self ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)self; - idnode_set_t *is = idnode_set_create(0); - satip_satconf_t *sfc; - TAILQ_FOREACH(sfc, &lfe->sf_satconf, sfc_link) +const idclass_t satip_frontend_dvbt_class = {.ic_super = &satip_frontend_class, + .ic_class = "satip_frontend_dvbt", + .ic_caption = N_("TV Adapters - SAT>IP DVB-T Frontend"), + .ic_properties = (const property_t[]){{ + .type = PT_STR, + .id = "fe_override", + .name = N_("Network type"), + .desc = N_("Override the frontend type."), + .set = satip_frontend_class_override_set, + .list = satip_frontend_class_override_enum, + .off = offsetof(satip_frontend_t, sf_type_override), + }, + { + .type = PT_INT, + .id = "delsys", + .name = N_("Delivery system"), + .desc = N_("Limit delivery system."), + .opts = PO_EXPERT, + .list = satip_frontend_dvbt_delsys_list, + .off = offsetof(satip_frontend_t, sf_delsys), + }, + {}}}; + +static idnode_set_t* satip_frontend_dvbs_class_get_childs(idnode_t* self) { + satip_frontend_t* lfe = (satip_frontend_t*)self; + idnode_set_t* is = idnode_set_create(0); + satip_satconf_t* sfc; + TAILQ_FOREACH (sfc, &lfe->sf_satconf, sfc_link) idnode_set_add(is, &sfc->sfc_id, NULL, NULL); return is; } -static int -satip_frontend_dvbs_class_positions_set ( void *self, const void *val ) -{ - satip_frontend_t *lfe = self; - int n = *(int *)val; +static int satip_frontend_dvbs_class_positions_set(void* self, const void* val) { + satip_frontend_t* lfe = self; + int n = *(int*)val; if (n < 0 || n > 32) return 0; @@ -416,15 +366,13 @@ satip_frontend_dvbs_class_positions_set ( void *self, const void *val ) return 0; } -static int -satip_frontend_dvbs_class_master_set ( void *self, const void *val ) -{ - satip_frontend_t *lfe = self; - satip_frontend_t *lfe2 = NULL; - int num = *(int *)val, pos = 0; +static int satip_frontend_dvbs_class_master_set(void* self, const void* val) { + satip_frontend_t* lfe = self; + satip_frontend_t* lfe2 = NULL; + int num = *(int*)val, pos = 0; if (num) { - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) + TAILQ_FOREACH (lfe2, &lfe->sf_device->sd_frontends, sf_link) if (lfe2 != lfe && lfe2->sf_type == lfe->sf_type) if (++pos == num) { num = lfe2->sf_number; @@ -443,257 +391,214 @@ satip_frontend_dvbs_class_master_set ( void *self, const void *val ) return 0; } -static htsmsg_t * -satip_frontend_dvbs_class_master_enum( void * self, const char *lang ) -{ +static htsmsg_t* satip_frontend_dvbs_class_master_enum(void* self, const char* lang) { satip_frontend_t *lfe = self, *lfe2; - htsmsg_t *m = htsmsg_create_list(); + htsmsg_t* m = htsmsg_create_list(); htsmsg_add_str(m, NULL, N_("This tuner")); if (lfe == NULL) return m; - satip_device_t *sd = lfe->sf_device; - TAILQ_FOREACH(lfe2, &sd->sd_frontends, sf_link) + satip_device_t* sd = lfe->sf_device; + TAILQ_FOREACH (lfe2, &sd->sd_frontends, sf_link) if (lfe2 != lfe && lfe2->sf_type == lfe->sf_type) htsmsg_add_str(m, NULL, lfe2->mi_name); return m; } -static htsmsg_t * -satip_frontend_dvbs_delsys_list ( void *o, const char *lang ) -{ +static htsmsg_t* satip_frontend_dvbs_delsys_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("All"), DVB_SYS_NONE }, - { N_("DVB-S"), DVB_SYS_DVBS }, - { N_("DVB-S2"), DVB_SYS_DVBS2 }, + {N_("All"), DVB_SYS_NONE}, + {N_("DVB-S"), DVB_SYS_DVBS}, + {N_("DVB-S2"), DVB_SYS_DVBS2}, }; return strtab2htsmsg(tab, 1, lang); } -const idclass_t satip_frontend_dvbs_class = -{ - .ic_super = &satip_frontend_class, - .ic_class = "satip_frontend_dvbs", - .ic_caption = N_("TV Adapters - SAT>IP DVB-S Frontend"), - .ic_get_childs = satip_frontend_dvbs_class_get_childs, - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "positions", - .name = N_("Satellite positions"), - .desc = N_("Select the number of satellite positions " - "supported by the SAT>IP hardware and your " - "coaxial cable wiring."), - .set = satip_frontend_dvbs_class_positions_set, - .opts = PO_NOSAVE, - .off = offsetof(satip_frontend_t, sf_positions), - .def.i = 4 - }, - { - .type = PT_INT, - .id = "fe_master", - .name = N_("Master tuner"), - .desc = N_("Select the master tuner." - "The signal from the standard universal LNB can be " - "split using a simple coaxial splitter " - "(no multiswitch) to several outputs. In this " - "case, the position, the polarization and low-high " - "band settings must be equal." - "if you set other tuner as master, then this tuner " - "will act like a slave one and Tvheadend will " - "assure that this tuner will not use incompatible " - "parameters (position, polarization, lo-hi)."), - .set = satip_frontend_dvbs_class_master_set, - .list = satip_frontend_dvbs_class_master_enum, - .off = offsetof(satip_frontend_t, sf_master), - }, - { - .type = PT_INT, - .id = "delsys", - .name = N_("Delivery system"), - .desc = N_("Limit delivery system."), - .opts = PO_EXPERT, - .list = satip_frontend_dvbs_delsys_list, - .off = offsetof(satip_frontend_t, sf_delsys), - }, - { - .id = "networks", - .type = PT_NONE, - }, - {} - } -}; - -const idclass_t satip_frontend_dvbs_slave_class = -{ - .ic_super = &satip_frontend_class, - .ic_class = "satip_frontend_dvbs_slave", - .ic_caption = N_("TV Adapters - SAT>IP DVB-S Slave Frontend"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "fe_master", - .name = N_("Master tuner"), - .desc = N_("Select the master tuner." - "The signal from the standard universal LNB can be " - "split using a simple coaxial splitter " - "(no multiswitch) to several outputs. In this " - "case, the position, the polarization and low-high " - "band settings must be equal." - "if you set other tuner as master, then this tuner " - "will act like a slave one and Tvheadend will " - "assure that this tuner will not use incompatible " - "parameters (position, polarization, lo-hi)."), - .set = satip_frontend_dvbs_class_master_set, - .list = satip_frontend_dvbs_class_master_enum, - .off = offsetof(satip_frontend_t, sf_master), - }, - { - .id = "networks", - .type = PT_NONE, - }, - {} - } -}; - -static htsmsg_t * -satip_frontend_dvbc_delsys_list ( void *o, const char *lang ) -{ +const idclass_t satip_frontend_dvbs_class = {.ic_super = &satip_frontend_class, + .ic_class = "satip_frontend_dvbs", + .ic_caption = N_("TV Adapters - SAT>IP DVB-S Frontend"), + .ic_get_childs = satip_frontend_dvbs_class_get_childs, + .ic_properties = + (const property_t[]){{.type = PT_INT, + .id = "positions", + .name = N_("Satellite positions"), + .desc = N_("Select the number of satellite positions " + "supported by the SAT>IP hardware and your " + "coaxial cable wiring."), + .set = satip_frontend_dvbs_class_positions_set, + .opts = PO_NOSAVE, + .off = offsetof(satip_frontend_t, sf_positions), + .def.i = 4}, + { + .type = PT_INT, + .id = "fe_master", + .name = N_("Master tuner"), + .desc = N_("Select the master tuner." + "The signal from the standard universal LNB can be " + "split using a simple coaxial splitter " + "(no multiswitch) to several outputs. In this " + "case, the position, the polarization and low-high " + "band settings must be equal." + "if you set other tuner as master, then this tuner " + "will act like a slave one and Tvheadend will " + "assure that this tuner will not use incompatible " + "parameters (position, polarization, lo-hi)."), + .set = satip_frontend_dvbs_class_master_set, + .list = satip_frontend_dvbs_class_master_enum, + .off = offsetof(satip_frontend_t, sf_master), + }, + { + .type = PT_INT, + .id = "delsys", + .name = N_("Delivery system"), + .desc = N_("Limit delivery system."), + .opts = PO_EXPERT, + .list = satip_frontend_dvbs_delsys_list, + .off = offsetof(satip_frontend_t, sf_delsys), + }, + { + .id = "networks", + .type = PT_NONE, + }, + {}}}; + +const idclass_t satip_frontend_dvbs_slave_class = {.ic_super = &satip_frontend_class, + .ic_class = "satip_frontend_dvbs_slave", + .ic_caption = N_("TV Adapters - SAT>IP DVB-S Slave Frontend"), + .ic_properties = + (const property_t[]){{ + .type = PT_INT, + .id = "fe_master", + .name = N_("Master tuner"), + .desc = N_("Select the master tuner." + "The signal from the standard universal LNB can be " + "split using a simple coaxial splitter " + "(no multiswitch) to several outputs. In this " + "case, the position, the polarization and low-high " + "band settings must be equal." + "if you set other tuner as master, then this tuner " + "will act like a slave one and Tvheadend will " + "assure that this tuner will not use incompatible " + "parameters (position, polarization, lo-hi)."), + .set = satip_frontend_dvbs_class_master_set, + .list = satip_frontend_dvbs_class_master_enum, + .off = offsetof(satip_frontend_t, sf_master), + }, + { + .id = "networks", + .type = PT_NONE, + }, + {}}}; + +static htsmsg_t* satip_frontend_dvbc_delsys_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("All"), DVB_SYS_NONE }, - { N_("DVB-C"), DVB_SYS_DVBC_ANNEX_A }, - { N_("DVB-C2"), DVB_SYS_DVBC_ANNEX_C }, + {N_("All"), DVB_SYS_NONE}, + {N_("DVB-C"), DVB_SYS_DVBC_ANNEX_A}, + {N_("DVB-C2"), DVB_SYS_DVBC_ANNEX_C}, }; return strtab2htsmsg(tab, 1, lang); } -const idclass_t satip_frontend_dvbc_class = -{ - .ic_super = &satip_frontend_class, - .ic_class = "satip_frontend_dvbc", - .ic_caption = N_("TV Adapters - SAT>IP DVB-C Frontend"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "fe_override", - .name = N_("Network type"), - .desc = N_("Override the frontend type."), - .set = satip_frontend_class_override_set, - .list = satip_frontend_class_override_enum, - .off = offsetof(satip_frontend_t, sf_type_override), - }, - { - .type = PT_INT, - .id = "delsys", - .name = N_("Delivery system"), - .desc = N_("Limit delivery system."), - .opts = PO_EXPERT, - .list = satip_frontend_dvbc_delsys_list, - .off = offsetof(satip_frontend_t, sf_delsys), - }, - {} - } -}; - -const idclass_t satip_frontend_atsc_t_class = -{ - .ic_super = &satip_frontend_class, - .ic_class = "satip_frontend_atsc_t", - .ic_caption = N_("SAT>IP ATSC-T Frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t satip_frontend_atsc_c_class = -{ - .ic_super = &satip_frontend_class, - .ic_class = "satip_frontend_atsc_c", - .ic_caption = N_("TV Adapters - SAT>IP ATSC-C Frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t satip_frontend_isdb_t_class = -{ - .ic_super = &satip_frontend_class, - .ic_class = "satip_frontend_isdb_t", - .ic_caption = N_("SAT>IP ISDB-T Frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; +const idclass_t satip_frontend_dvbc_class = {.ic_super = &satip_frontend_class, + .ic_class = "satip_frontend_dvbc", + .ic_caption = N_("TV Adapters - SAT>IP DVB-C Frontend"), + .ic_properties = (const property_t[]){{ + .type = PT_STR, + .id = "fe_override", + .name = N_("Network type"), + .desc = N_("Override the frontend type."), + .set = satip_frontend_class_override_set, + .list = satip_frontend_class_override_enum, + .off = offsetof(satip_frontend_t, sf_type_override), + }, + { + .type = PT_INT, + .id = "delsys", + .name = N_("Delivery system"), + .desc = N_("Limit delivery system."), + .opts = PO_EXPERT, + .list = satip_frontend_dvbc_delsys_list, + .off = offsetof(satip_frontend_t, sf_delsys), + }, + {}}}; + +const idclass_t satip_frontend_atsc_t_class = {.ic_super = &satip_frontend_class, + .ic_class = "satip_frontend_atsc_t", + .ic_caption = N_("SAT>IP ATSC-T Frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t satip_frontend_atsc_c_class = {.ic_super = &satip_frontend_class, + .ic_class = "satip_frontend_atsc_c", + .ic_caption = N_("TV Adapters - SAT>IP ATSC-C Frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t satip_frontend_isdb_t_class = {.ic_super = &satip_frontend_class, + .ic_class = "satip_frontend_isdb_t", + .ic_caption = N_("SAT>IP ISDB-T Frontend"), + .ic_properties = (const property_t[]){{}}}; /* ************************************************************************** * Class methods * *************************************************************************/ -static void -satip_frontend_display_name ( mpegts_input_t *mi, char *buf, size_t len ) -{ - satip_frontend_t *lfe = (satip_frontend_t *)mi; - char nname[60]; - int rtsp_flags = satip_frontend_rtsp_flags(lfe); - snprintf(buf, len, "%s #%d (%s@%s)", - mi->mi_name ?: "", lfe->sf_number, - satip_device_nicename(lfe->sf_device, nname, sizeof(nname)), - rtsp_flags & SATIP_SETUP_TCP ? "TCP" : "UDP"); +static void satip_frontend_display_name(mpegts_input_t* mi, char* buf, size_t len) { + satip_frontend_t* lfe = (satip_frontend_t*)mi; + char nname[60]; + int rtsp_flags = satip_frontend_rtsp_flags(lfe); + snprintf(buf, + len, + "%s #%d (%s@%s)", + mi->mi_name ?: "", + lfe->sf_number, + satip_device_nicename(lfe->sf_device, nname, sizeof(nname)), + rtsp_flags & SATIP_SETUP_TCP ? "TCP" : "UDP"); } -static int -satip_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) -{ +static int satip_frontend_get_weight(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight) { return mpegts_input_get_weight(mi, mm, flags, weight); } -static int -satip_frontend_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)mi; - int r = mpegts_input_get_priority(mi, mm, flags); +static int satip_frontend_get_priority(mpegts_input_t* mi, mpegts_mux_t* mm, int flags) { + satip_frontend_t* lfe = (satip_frontend_t*)mi; + int r = mpegts_input_get_priority(mi, mm, flags); if (lfe->sf_positions) r += satip_satconf_get_priority(lfe, mm); return r; } -static int -satip_frontend_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)mi; - int r = lfe->sf_grace_period > 0 ? MINMAX(lfe->sf_grace_period, 1, 60) : 5; +static int satip_frontend_get_grace(mpegts_input_t* mi, mpegts_mux_t* mm) { + satip_frontend_t* lfe = (satip_frontend_t*)mi; + int r = lfe->sf_grace_period > 0 ? MINMAX(lfe->sf_grace_period, 1, 60) : 5; if (lfe->sf_positions || lfe->sf_master) r = MINMAX(satip_satconf_get_grace(lfe, mm) ?: 10, r, 60); return r; } -static int -satip_frontend_get_max_weight ( satip_frontend_t *lfe, mpegts_mux_t *mm, int flags ) -{ - satip_frontend_t *lfe2; - int w = 0, w2; - - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { - if (!lfe2->sf_running) continue; - if (lfe2->sf_type != DVB_TYPE_S) continue; - if (lfe2 != lfe) continue; - if (lfe->sf_master != lfe2->sf_number && - lfe2->sf_master != lfe->sf_number) continue; - w2 = lfe2->mi_get_weight((mpegts_input_t *)lfe2, mm, flags, 0); +static int satip_frontend_get_max_weight(satip_frontend_t* lfe, mpegts_mux_t* mm, int flags) { + satip_frontend_t* lfe2; + int w = 0, w2; + + TAILQ_FOREACH (lfe2, &lfe->sf_device->sd_frontends, sf_link) { + if (!lfe2->sf_running) + continue; + if (lfe2->sf_type != DVB_TYPE_S) + continue; + if (lfe2 != lfe) + continue; + if (lfe->sf_master != lfe2->sf_number && lfe2->sf_master != lfe->sf_number) + continue; + w2 = lfe2->mi_get_weight((mpegts_input_t*)lfe2, mm, flags, 0); if (w2 > w) w = w2; } return w; } -int -satip_frontend_match_satcfg - ( satip_frontend_t *lfe2, mpegts_mux_t *mm2, int flags, int weight ) -{ - satip_frontend_t *lfe_master; - satip_satconf_t *sfc; - mpegts_mux_t *mm1 = NULL; - dvb_mux_conf_t *mc1, *mc2; - int weight2, high1, high2; +int satip_frontend_match_satcfg(satip_frontend_t* lfe2, mpegts_mux_t* mm2, int flags, int weight) { + satip_frontend_t* lfe_master; + satip_satconf_t* sfc; + mpegts_mux_t* mm1 = NULL; + dvb_mux_conf_t * mc1, *mc2; + int weight2, high1, high2; if (!lfe2->sf_running) return 0; @@ -712,8 +617,8 @@ satip_frontend_match_satcfg sfc = satip_satconf_get_position(lfe2, mm2, NULL, 0, 0, -1); if (!sfc || lfe_master->sf_position != sfc->sfc_position) return 0; - mc1 = &((dvb_mux_t *)mm1)->lm_tuning; - mc2 = &((dvb_mux_t *)mm2)->lm_tuning; + mc1 = &((dvb_mux_t*)mm1)->lm_tuning; + mc2 = &((dvb_mux_t*)mm2)->lm_tuning; if (mc1->dmc_fe_type != DVB_TYPE_S || mc2->dmc_fe_type != DVB_TYPE_S) return 0; if (mc1->u.dmc_fe_qpsk.polarisation != mc2->u.dmc_fe_qpsk.polarisation) @@ -725,14 +630,11 @@ satip_frontend_match_satcfg return 1; } -static int -satip_frontend_is_enabled - ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)mi; - satip_frontend_t *lfe2; - satip_satconf_t *sfc; - int r; +static int satip_frontend_is_enabled(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight) { + satip_frontend_t* lfe = (satip_frontend_t*)mi; + satip_frontend_t* lfe2; + satip_satconf_t* sfc; + int r; lock_assert(&global_lock); @@ -747,41 +649,42 @@ satip_frontend_is_enabled return MI_IS_ENABLED_OK; /* delivery system specific check */ lfe2 = lfe->sf_master ? satip_frontend_find_by_number(lfe->sf_device, lfe->sf_master) : lfe; - if (lfe2 == NULL) lfe2 = lfe; + if (lfe2 == NULL) + lfe2 = lfe; if (lfe2->sf_delsys != DVB_SYS_NONE) { - dvb_mux_conf_t *dmc = &((dvb_mux_t *)mm)->lm_tuning; + dvb_mux_conf_t* dmc = &((dvb_mux_t*)mm)->lm_tuning; if (dmc->dmc_fe_delsys != lfe2->sf_delsys) return MI_IS_ENABLED_NEVER; } /* check if the position is enabled */ sfc = satip_satconf_get_position(lfe, mm, NULL, 1, flags, weight); - if (!sfc) return MI_IS_ENABLED_NEVER; + if (!sfc) + return MI_IS_ENABLED_NEVER; /* check if any "blocking" tuner is running */ - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { - if (lfe2 == lfe) continue; - if (lfe2->sf_type != DVB_TYPE_S) continue; + TAILQ_FOREACH (lfe2, &lfe->sf_device->sd_frontends, sf_link) { + if (lfe2 == lfe) + continue; + if (lfe2->sf_type != DVB_TYPE_S) + continue; if (lfe->sf_master == lfe2->sf_number) { if (!lfe2->sf_running) return MI_IS_ENABLED_RETRY; /* master must be running */ - return satip_frontend_match_satcfg(lfe2, mm, flags, weight) ? - MI_IS_ENABLED_OK : MI_IS_ENABLED_RETRY; + return satip_frontend_match_satcfg(lfe2, mm, flags, weight) ? MI_IS_ENABLED_OK + : MI_IS_ENABLED_RETRY; } if (lfe2->sf_master == lfe->sf_number) { if (lfe2->sf_running) - return satip_frontend_match_satcfg(lfe2, mm, flags, weight) ? - MI_IS_ENABLED_OK : MI_IS_ENABLED_RETRY; + return satip_frontend_match_satcfg(lfe2, mm, flags, weight) ? MI_IS_ENABLED_OK + : MI_IS_ENABLED_RETRY; } } return MI_IS_ENABLED_OK; } -static void -satip_frontend_stop_mux - ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)mi; - satip_tune_req_t *tr; - char buf1[256]; +static void satip_frontend_stop_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { + satip_frontend_t* lfe = (satip_frontend_t*)mi; + satip_tune_req_t* tr; + char buf1[256]; mi->mi_display_name(mi, buf1, sizeof(buf1)); tvhdebug(LS_SATIP, "%s - stopping %s", buf1, mmi->mmi_mux->mm_nicename); @@ -799,26 +702,21 @@ satip_frontend_stop_mux free(tr); } lfe->sf_running = 0; - lfe->sf_req = NULL; + lfe->sf_req = NULL; tvh_mutex_unlock(&lfe->sf_dvr_lock); } -static int -satip_frontend_warm_mux - ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)mi; - satip_satconf_t *sfc; - int r; +static int satip_frontend_warm_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { + satip_frontend_t* lfe = (satip_frontend_t*)mi; + satip_satconf_t* sfc; + int r; r = mpegts_input_warm_mux(mi, mmi); if (r) return r; if (lfe->sf_positions > 0) { - sfc = satip_satconf_get_position(lfe, mmi->mmi_mux, - &lfe->sf_netposhash, - 2, 0, -1); + sfc = satip_satconf_get_position(lfe, mmi->mmi_mux, &lfe->sf_netposhash, 2, 0, -1); if (sfc) { lfe->sf_position = sfc->sfc_position; lfe->sf_netgroup = sfc->sfc_network_group; @@ -831,31 +729,29 @@ satip_frontend_warm_mux return 0; } -static int -satip_frontend_start_mux - ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weight ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)mi; - dvb_mux_t *lm = (dvb_mux_t *)mmi->mmi_mux; - satip_tune_req_t *tr; - char buf1[256]; +static int satip_frontend_start_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi, int weight) { + satip_frontend_t* lfe = (satip_frontend_t*)mi; + dvb_mux_t* lm = (dvb_mux_t*)mmi->mmi_mux; + satip_tune_req_t* tr; + char buf1[256]; lfe->mi_display_name((mpegts_input_t*)lfe, buf1, sizeof(buf1)); tvhdebug(LS_SATIP, "%s - starting %s", buf1, lm->mm_nicename); if (!lfe->sf_device->sd_no_univ_lnb && (lm->lm_tuning.dmc_fe_delsys == DVB_SYS_DVBS || - lm->lm_tuning.dmc_fe_delsys == DVB_SYS_DVBS2)) { + lm->lm_tuning.dmc_fe_delsys == DVB_SYS_DVBS2)) { /* Note: assume universal LNB */ - if (lm->lm_tuning.dmc_fe_freq < 10700000 || - lm->lm_tuning.dmc_fe_freq > 12750000) { - tvhwarn(LS_SATIP, "DVB-S/S2 frequency %d out of range universal LNB", lm->lm_tuning.dmc_fe_freq); + if (lm->lm_tuning.dmc_fe_freq < 10700000 || lm->lm_tuning.dmc_fe_freq > 12750000) { + tvhwarn(LS_SATIP, + "DVB-S/S2 frequency %d out of range universal LNB", + lm->lm_tuning.dmc_fe_freq); return SM_CODE_TUNING_FAILED; } } - tr = calloc(1, sizeof(*tr)); - tr->sf_mmi = mmi; + tr = calloc(1, sizeof(*tr)); + tr->sf_mmi = mmi; mpegts_pid_init(&tr->sf_pids); mpegts_pid_init(&tr->sf_pids_tuned); @@ -867,59 +763,55 @@ satip_frontend_start_mux tr->sf_netgroup = lfe->sf_netgroup; tvh_mutex_lock(&lfe->sf_dvr_lock); - lfe->sf_req = tr; - lfe->sf_running = 1; - lfe->sf_tables = 0; - lfe->sf_atsc_c = lm->lm_tuning.dmc_fe_modulation != DVB_MOD_VSB_8; + lfe->sf_req = tr; + lfe->sf_running = 1; + lfe->sf_tables = 0; + lfe->sf_atsc_c = lm->lm_tuning.dmc_fe_modulation != DVB_MOD_VSB_8; tvh_mutex_unlock(&lfe->sf_dvr_lock); tvh_mutex_lock(&mmi->tii_stats_mutex); - lfe->sf_status = SIGNAL_NONE; + lfe->sf_status = SIGNAL_NONE; mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_UNKNOWN; - mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN; + mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_UNKNOWN; tvh_mutex_unlock(&mmi->tii_stats_mutex); /* notify thread that we are ready */ tvh_write(lfe->sf_dvr_pipe.wr, "s", 1); - mtimer_arm_rel(&lfe->sf_monitor_timer, satip_frontend_signal_cb, - lfe, ms2mono(50)); + mtimer_arm_rel(&lfe->sf_monitor_timer, satip_frontend_signal_cb, lfe, ms2mono(50)); return 0; } -static void -satip_frontend_update_pids - ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)mi; - satip_tune_req_t *tr; - mpegts_pid_t *mp; - mpegts_pid_sub_t *mps; +static void satip_frontend_update_pids(mpegts_input_t* mi, mpegts_mux_t* mm) { + satip_frontend_t* lfe = (satip_frontend_t*)mi; + satip_tune_req_t* tr; + mpegts_pid_t* mp; + mpegts_pid_sub_t* mps; tvh_mutex_lock(&lfe->sf_dvr_lock); if ((tr = lfe->sf_req) != NULL) { mpegts_pid_done(&tr->sf_pids); - RB_FOREACH(mp, &mm->mm_pids, mp_link) { + RB_FOREACH (mp, &mm->mm_pids, mp_link) { if (mp->mp_pid == MPEGTS_FULLMUX_PID) { if (lfe->sf_device->sd_fullmux_ok) { if (!tr->sf_pids.all) tr->sf_pids.all = 1; } else { - mpegts_service_t *s; - elementary_stream_t *st; - int w = 0; - RB_FOREACH(mps, &mp->mp_subs, mps_link) + mpegts_service_t* s; + elementary_stream_t* st; + int w = 0; + RB_FOREACH (mps, &mp->mp_subs, mps_link) w = MAX(w, mps->mps_weight); - LIST_FOREACH(s, &mm->mm_services, s_dvb_mux_link) { + LIST_FOREACH (s, &mm->mm_services, s_dvb_mux_link) { mpegts_pid_add(&tr->sf_pids, s->s_components.set_pmt_pid, w); mpegts_pid_add(&tr->sf_pids, s->s_components.set_pcr_pid, w); - TAILQ_FOREACH(st, &s->s_components.set_all, es_link) + TAILQ_FOREACH (st, &s->s_components.set_all, es_link) if (st->es_pid < MPEGTS_FULLMUX_PID) mpegts_pid_add(&tr->sf_pids, st->es_pid, w); } } } else if (mp->mp_pid < MPEGTS_FULLMUX_PID) { - RB_FOREACH(mps, &mp->mp_subs, mps_link) + RB_FOREACH (mps, &mp->mp_subs, mps_link) mpegts_pid_add(&tr->sf_pids, mp->mp_pid, mps->mps_weight); } } @@ -932,13 +824,14 @@ satip_frontend_update_pids tvh_write(lfe->sf_dvr_pipe.wr, "c", 1); } -static void -satip_frontend_open_service - ( mpegts_input_t *mi, mpegts_service_t *s, int flags, int init, int weight ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)mi; - satip_tune_req_t *tr; - int w; +static void satip_frontend_open_service(mpegts_input_t* mi, + mpegts_service_t* s, + int flags, + int init, + int weight) { + satip_frontend_t* lfe = (satip_frontend_t*)mi; + satip_tune_req_t* tr; + int w; mpegts_input_open_service(mi, s, flags, init, weight); @@ -948,7 +841,7 @@ satip_frontend_open_service tvh_mutex_lock(&lfe->sf_dvr_lock); if ((tr = lfe->sf_req) != NULL && tr->sf_mmi != NULL) { tvh_mutex_lock(&mi->mi_output_lock); - w = mpegts_mux_instance_weight(tr->sf_mmi); + w = mpegts_mux_instance_weight(tr->sf_mmi); tr->sf_weight = MAX(w, weight); tvh_mutex_unlock(&mi->mi_output_lock); } @@ -957,10 +850,8 @@ satip_frontend_open_service tvh_write(lfe->sf_dvr_pipe.wr, "c", 1); } -static idnode_set_t * -satip_frontend_network_list ( mpegts_input_t *mi ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)mi; +static idnode_set_t* satip_frontend_network_list(mpegts_input_t* mi) { + satip_frontend_t* lfe = (satip_frontend_t*)mi; return dvb_network_list_by_fe_type(lfe->sf_type); } @@ -969,17 +860,17 @@ satip_frontend_network_list ( mpegts_input_t *mi ) * Data processing * *************************************************************************/ -static void -satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name, - mpegts_mux_instance_t *mmi, - uint8_t *rtcp, size_t len ) -{ - const satip_device_t *device = lfe->sf_device; - signal_state_t status; - uint16_t l, sl; - char *s; - char *argv[4]; - int n; +static void satip_frontend_decode_rtcp(satip_frontend_t* lfe, + const char* name, + mpegts_mux_instance_t* mmi, + uint8_t* rtcp, + size_t len) { + const satip_device_t* device = lfe->sf_device; + signal_state_t status; + uint16_t l, sl; + char* s; + char* argv[4]; + int n; /* * DVB-S/S2: @@ -1010,7 +901,7 @@ satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name, * * lock: * lock Set to one of the following values: - * "0" the frontend is not locked + * "0" the frontend is not locked * "1" the frontend is locked * * quality: @@ -1022,49 +913,43 @@ satip_frontend_decode_rtcp( satip_frontend_t *lfe, const char *name, */ tvh_mutex_lock(&mmi->tii_stats_mutex); while (len >= 12) { - if ((rtcp[0] & 0xc0) != 0x80) /* protocol version: v2 */ + if ((rtcp[0] & 0xc0) != 0x80) /* protocol version: v2 */ goto fail; - l = (((rtcp[2] << 8) | rtcp[3]) + 1) * 4; /* length of payload */ - if (rtcp[1] == 204 && l > 20 && /* packet type */ - rtcp[8] == 'S' && rtcp[9] == 'E' && - rtcp[10] == 'S' && rtcp[11] == '1') { + l = (((rtcp[2] << 8) | rtcp[3]) + 1) * 4; /* length of payload */ + if (rtcp[1] == 204 && l > 20 && /* packet type */ + rtcp[8] == 'S' && rtcp[9] == 'E' && rtcp[10] == 'S' && rtcp[11] == '1') { /* workaround for broken minisatip */ if (l > len && l - 4 != len) goto fail; sl = (rtcp[14] << 8) | rtcp[15]; if (sl > 0 && l - 16 >= sl) { rtcp[sl + 16] = '\0'; - s = (char *)rtcp + 16; + s = (char*)rtcp + 16; tvhtrace(LS_SATIP, "Status string: '%s'", s); status = SIGNAL_NONE; if (strncmp(s, "ver=1.2;src=1;tuner=", 20) == 0) { /* broken FritzBox 6490/6590 */ n = http_tokenize(s + 20, argv, ARRAY_SIZE(argv), ','); goto __ver12; - } else if (strncmp(s, "ver=0.9;tuner=", 14) == 0 || - strncmp(s, "ver=1.2;tuner=", 14) == 0) { + } else if (strncmp(s, "ver=0.9;tuner=", 14) == 0 || strncmp(s, "ver=1.2;tuner=", 14) == 0) { n = http_tokenize(s + 14, argv, ARRAY_SIZE(argv), ','); -__ver12: + __ver12: if (n < 4) goto fail; if (atoi(argv[0]) != lfe->sf_number && device->sd_sig_tunerno) goto fail; - mmi->tii_stats.signal = - atoi(argv[1]) * 0xffff / device->sd_sig_scale; - mmi->tii_stats.signal_scale = - SIGNAL_STATUS_SCALE_RELATIVE; + mmi->tii_stats.signal = atoi(argv[1]) * 0xffff / device->sd_sig_scale; + mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE; if (atoi(argv[2]) > 0) status = SIGNAL_GOOD; - mmi->tii_stats.snr = atoi(argv[3]) * 0xffff / 15; - mmi->tii_stats.snr_scale = - SIGNAL_STATUS_SCALE_RELATIVE; - if (status == SIGNAL_GOOD && - mmi->tii_stats.signal == 0 && mmi->tii_stats.snr == 0) { + mmi->tii_stats.snr = atoi(argv[3]) * 0xffff / 15; + mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE; + if (status == SIGNAL_GOOD && mmi->tii_stats.signal == 0 && mmi->tii_stats.snr == 0) { /* some values that we're tuned */ mmi->tii_stats.signal = 50 * 0xffff / 100; - mmi->tii_stats.snr = 12 * 0xffff / 15; + mmi->tii_stats.snr = 12 * 0xffff / 15; } - goto ok; + goto ok; } else if (strncmp(s, "ver=1.0;", 8) == 0) { if ((s = strstr(s + 8, ";tuner=")) == NULL) goto fail; @@ -1074,31 +959,25 @@ __ver12: goto fail; if (atoi(argv[0]) != lfe->sf_number && device->sd_sig_tunerno) goto fail; - mmi->tii_stats.signal = - atoi(argv[1]) * 0xffff / device->sd_sig_scale; - mmi->tii_stats.signal_scale = - SIGNAL_STATUS_SCALE_RELATIVE; + mmi->tii_stats.signal = atoi(argv[1]) * 0xffff / device->sd_sig_scale; + mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE; if (atoi(argv[2]) > 0) status = SIGNAL_GOOD; - mmi->tii_stats.snr = atoi(argv[3]) * 0xffff / 15; - mmi->tii_stats.snr_scale = - SIGNAL_STATUS_SCALE_RELATIVE; - goto ok; + mmi->tii_stats.snr = atoi(argv[3]) * 0xffff / 15; + mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE; + goto ok; } else if (strncmp(s, "ver=1.1;tuner=", 14) == 0) { n = http_tokenize(s + 14, argv, 4, ','); if (n < 4) goto fail; if (atoi(argv[0]) != lfe->sf_number && device->sd_sig_tunerno) goto fail; - mmi->tii_stats.signal = - atoi(argv[1]) * 0xffff / device->sd_sig_scale; - mmi->tii_stats.signal_scale = - SIGNAL_STATUS_SCALE_RELATIVE; + mmi->tii_stats.signal = atoi(argv[1]) * 0xffff / device->sd_sig_scale; + mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE; if (atoi(argv[2]) > 0) status = SIGNAL_GOOD; - mmi->tii_stats.snr = atoi(argv[3]) * 0xffff / 15; - mmi->tii_stats.snr_scale = - SIGNAL_STATUS_SCALE_RELATIVE; + mmi->tii_stats.snr = atoi(argv[3]) * 0xffff / 15; + mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE; goto ok; } } @@ -1110,25 +989,23 @@ __ver12: ok: if (mmi->tii_stats.snr < 2 && status == SIGNAL_GOOD) - status = SIGNAL_BAD; + status = SIGNAL_BAD; else if (mmi->tii_stats.snr < 4 && status == SIGNAL_GOOD) - status = SIGNAL_FAINT; - lfe->sf_status = status; + status = SIGNAL_FAINT; + lfe->sf_status = status; fail: tvh_mutex_unlock(&mmi->tii_stats_mutex); } static int -satip_frontend_pid_changed( http_client_t *rtsp, - satip_frontend_t *lfe, const char *name ) -{ - satip_tune_req_t *tr; - satip_device_t *sd = lfe->sf_device; - char *setup = NULL, *add = NULL, *del = NULL; - int i, j, r, pid, overlimit; - int max_pids_len = sd->sd_pids_len; - int max_pids_count = sd->sd_pids_max; - mpegts_apids_t wpid, padd, pdel; +satip_frontend_pid_changed(http_client_t* rtsp, satip_frontend_t* lfe, const char* name) { + satip_tune_req_t* tr; + satip_device_t* sd = lfe->sf_device; + char * setup = NULL, *add = NULL, *del = NULL; + int i, j, r, pid, overlimit; + int max_pids_len = sd->sd_pids_len; + int max_pids_count = sd->sd_pids_max; + mpegts_apids_t wpid, padd, pdel; tvh_mutex_lock(&lfe->sf_dvr_lock); @@ -1141,29 +1018,26 @@ satip_frontend_pid_changed( http_client_t *rtsp, if (tr->sf_pids.all) { -all: + all: i = tr->sf_pids_tuned.all; mpegts_pid_done(&tr->sf_pids_tuned); tr->sf_pids_tuned.all = 1; tvh_mutex_unlock(&lfe->sf_dvr_lock); if (i) goto skip; - setup = (char *)"all"; + setup = (char*)"all"; - } else if (!sd->sd_pids_deladd || - tr->sf_pids_tuned.all || - tr->sf_pids.count == 0) { + } else if (!sd->sd_pids_deladd || tr->sf_pids_tuned.all || tr->sf_pids.count == 0) { - overlimit = mpegts_pid_weighted(&wpid, &tr->sf_pids, - max_pids_count, MPS_WEIGHT_ALLLIMIT); + overlimit = mpegts_pid_weighted(&wpid, &tr->sf_pids, max_pids_count, MPS_WEIGHT_ALLLIMIT); if (overlimit > 0 && sd->sd_fullmux_ok) { mpegts_pid_done(&wpid); goto all; } - j = MIN(wpid.count, max_pids_count); - setup = alloca(1 + j * 5); + j = MIN(wpid.count, max_pids_count); + setup = alloca(1 + j * 5); setup[0] = '\0'; for (i = 0; i < j; i++) sprintf(setup + strlen(setup), ",%i", wpid.pids[i].pid); @@ -1177,8 +1051,7 @@ all: } else { - overlimit = mpegts_pid_weighted(&wpid, &tr->sf_pids, - max_pids_count, MPS_WEIGHT_ALLLIMIT); + overlimit = mpegts_pid_weighted(&wpid, &tr->sf_pids, max_pids_count, MPS_WEIGHT_ALLLIMIT); if (overlimit > 0 && sd->sd_fullmux_ok) { mpegts_pid_done(&wpid); @@ -1187,8 +1060,8 @@ all: mpegts_pid_compare(&wpid, &tr->sf_pids_tuned, &padd, &pdel); - add = alloca(1 + padd.count * 5); - del = alloca(1 + pdel.count * 5); + add = alloca(1 + padd.count * 5); + del = alloca(1 + pdel.count * 5); add[0] = del[0] = '\0'; for (i = 0; i < pdel.count; i++) { @@ -1217,8 +1090,8 @@ all: } tr->sf_weight_tuned = tr->sf_weight; - r = satip_rtsp_play(rtsp, setup, add, del, max_pids_len, tr->sf_weight); - r = r == 0 ? 1 : r; + r = satip_rtsp_play(rtsp, setup, add, del, max_pids_len, tr->sf_weight); + r = r == 0 ? 1 : r; if (r < 0) tvherror(LS_SATIP, "%s - failed to modify pids: %s", name, strerror(-r)); @@ -1227,17 +1100,15 @@ all: skip: if (tr->sf_weight_tuned != tr->sf_weight) { tr->sf_weight_tuned = tr->sf_weight; - r = satip_rtsp_play(rtsp, NULL, NULL, NULL, 0, tr->sf_weight); + r = satip_rtsp_play(rtsp, NULL, NULL, NULL, 0, tr->sf_weight); } return 0; } -static int -satip_frontend_other_is_waiting( satip_frontend_t *lfe ) -{ - satip_device_t *sd = lfe->sf_device; - satip_frontend_t *lfe2; - int r, i, cont, hash1, hash2, limit0, limit, group, *hashes, count; +static int satip_frontend_other_is_waiting(satip_frontend_t* lfe) { + satip_device_t* sd = lfe->sf_device; + satip_frontend_t* lfe2; + int r, i, cont, hash1, hash2, limit0, limit, group, *hashes, count; if (lfe->sf_type != DVB_TYPE_S) return 0; @@ -1257,25 +1128,29 @@ satip_frontend_other_is_waiting( satip_frontend_t *lfe ) r = count = 0; tvh_mutex_lock(&sd->sd_tune_mutex); - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) count++; + TAILQ_FOREACH (lfe2, &lfe->sf_device->sd_frontends, sf_link) + count++; hashes = alloca(sizeof(int) * count); memset(hashes, 0, sizeof(int) * count); - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { - if (lfe2 == lfe) continue; + TAILQ_FOREACH (lfe2, &lfe->sf_device->sd_frontends, sf_link) { + if (lfe2 == lfe) + continue; tvh_mutex_lock(&lfe2->sf_dvr_lock); cont = 0; if (limit0 > 0) { cont = group > 0 && lfe2->sf_req_thread && group != lfe2->sf_req_thread->sf_netgroup; } else { cont = (lfe->sf_master && lfe2->sf_number != lfe->sf_master) || - (lfe2->sf_master && lfe->sf_number != lfe2->sf_master); + (lfe2->sf_master && lfe->sf_number != lfe2->sf_master); } hash2 = lfe2->sf_req_thread ? lfe2->sf_req_thread->sf_netposhash : 0; tvh_mutex_unlock(&lfe2->sf_dvr_lock); - if (cont || hash2 == 0) continue; + if (cont || hash2 == 0) + continue; if (hash2 != hash1) { for (i = 0; i < count; i++) { - if (hashes[i] == hash2) break; + if (hashes[i] == hash2) + break; if (hashes[i] == 0) { hashes[i] = hash2; r++; @@ -1288,12 +1163,9 @@ satip_frontend_other_is_waiting( satip_frontend_t *lfe ) return r > limit; } -static void -satip_frontend_wake_other_waiting - ( satip_frontend_t *lfe, satip_tune_req_t *tr ) -{ - satip_frontend_t *lfe2; - int hash1, hash2; +static void satip_frontend_wake_other_waiting(satip_frontend_t* lfe, satip_tune_req_t* tr) { + satip_frontend_t* lfe2; + int hash1, hash2; if (tr == NULL) return; @@ -1303,7 +1175,7 @@ satip_frontend_wake_other_waiting hash1 = tr->sf_netposhash; - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { + TAILQ_FOREACH (lfe2, &lfe->sf_device->sd_frontends, sf_link) { if (lfe2 == lfe) continue; if ((lfe->sf_master && lfe2->sf_number != lfe->sf_master) || @@ -1321,10 +1193,7 @@ end: atomic_dec(&lfe->sf_device->sd_wake_ref, 1); } -static void -satip_frontend_request_cleanup - ( satip_frontend_t *lfe, satip_tune_req_t *tr ) -{ +static void satip_frontend_request_cleanup(satip_frontend_t* lfe, satip_tune_req_t* tr) { if (tr && tr != lfe->sf_req) { mpegts_pid_done(&tr->sf_pids); mpegts_pid_done(&tr->sf_pids_tuned); @@ -1334,28 +1203,27 @@ satip_frontend_request_cleanup lfe->sf_req_thread = NULL; } -static void -satip_frontend_extra_shutdown - ( satip_frontend_t *lfe, uint8_t *session, long stream_id ) -{ - http_client_t *rtsp; - tvhpoll_t *efd; +static void satip_frontend_extra_shutdown(satip_frontend_t* lfe, uint8_t* session, long stream_id) { + http_client_t* rtsp; + tvhpoll_t* efd; tvhpoll_event_t ev; - int r, nfds; - char b[32]; + int r, nfds; + char b[32]; if (session[0] == '\0' || stream_id <= 0) return; - efd = tvhpoll_create(1); - rtsp = http_client_connect(lfe, RTSP_VERSION_1_0, "rstp", - lfe->sf_device->sd_info.addr, - lfe->sf_device->sd_info.rtsp_port, - satip_frontend_bindaddr(lfe)); + efd = tvhpoll_create(1); + rtsp = http_client_connect(lfe, + RTSP_VERSION_1_0, + "rstp", + lfe->sf_device->sd_info.addr, + lfe->sf_device->sd_info.rtsp_port, + satip_frontend_bindaddr(lfe)); if (rtsp == NULL) goto done; - rtsp->hc_rtsp_session = strdup((char *)session); + rtsp->hc_rtsp_session = strdup((char*)session); tvhpoll_add1(efd, rtsp->hc_fd, TVHPOLL_IN, rtsp); rtsp->hc_efd = efd; @@ -1378,7 +1246,7 @@ satip_frontend_extra_shutdown continue; break; } - if(ev.events & (TVHPOLL_ERR | TVHPOLL_HUP)) + if (ev.events & (TVHPOLL_ERR | TVHPOLL_HUP)) break; } } @@ -1390,26 +1258,26 @@ done: tvhpoll_destroy(efd); } -static void -satip_frontend_shutdown - ( satip_frontend_t *lfe, const char *name, http_client_t *rtsp, - satip_tune_req_t *tr, tvhpoll_t *efd ) -{ - char b[32]; +static void satip_frontend_shutdown(satip_frontend_t* lfe, + const char* name, + http_client_t* rtsp, + satip_tune_req_t* tr, + tvhpoll_t* efd) { + char b[32]; tvhpoll_event_t ev; - int r, nfds; + int r, nfds; if (rtsp->hc_rtsp_stream_id < 0) goto wake; snprintf(b, sizeof(b), "/stream=%li", rtsp->hc_rtsp_stream_id); tvhtrace(LS_SATIP, "%s - shutdown for %s/%s", name, b, rtsp->hc_rtsp_session ?: ""); - r = rtsp_teardown(rtsp, (char *)b, NULL); + r = rtsp_teardown(rtsp, (char*)b, NULL); if (r < 0) { tvhtrace(LS_SATIP, "%s - bad teardown", b); } else { while (1) { - r = http_client_run(rtsp); + r = http_client_run(rtsp); if (r != HTTP_CON_RECEIVING && r != HTTP_CON_SENDING) break; nfds = tvhpoll_wait(efd, &ev, 1, 400); @@ -1420,7 +1288,7 @@ satip_frontend_shutdown continue; break; } - if(ev.events & (TVHPOLL_ERR | TVHPOLL_HUP)) + if (ev.events & (TVHPOLL_ERR | TVHPOLL_HUP)) break; } } @@ -1433,16 +1301,14 @@ wake: tvh_mutex_unlock(&lfe->sf_dvr_lock); } -static void -satip_frontend_tuning_error ( satip_frontend_t *lfe, satip_tune_req_t *tr ) -{ - mpegts_mux_t *mm; - mpegts_mux_instance_t *mmi; - char uuid[UUID_HEX_SIZE]; +static void satip_frontend_tuning_error(satip_frontend_t* lfe, satip_tune_req_t* tr) { + mpegts_mux_t* mm; + mpegts_mux_instance_t* mmi; + char uuid[UUID_HEX_SIZE]; tvh_mutex_lock(&lfe->sf_dvr_lock); - if (lfe->sf_running && lfe->sf_req == tr && - (mmi = tr->sf_mmi) != NULL && (mm = mmi->mmi_mux) != NULL) { + if (lfe->sf_running && lfe->sf_req == tr && (mmi = tr->sf_mmi) != NULL && + (mm = mmi->mmi_mux) != NULL) { idnode_uuid_as_str(&mm->mm_id, uuid); tvh_mutex_unlock(&lfe->sf_dvr_lock); mpegts_mux_tuning_error(uuid, mmi); @@ -1451,24 +1317,24 @@ satip_frontend_tuning_error ( satip_frontend_t *lfe, satip_tune_req_t *tr ) tvh_mutex_unlock(&lfe->sf_dvr_lock); } -static void -satip_frontend_close_rtsp - ( satip_frontend_t *lfe, const char *name, tvhpoll_t *efd, - http_client_t *rtsp, satip_tune_req_t *tr ) -{ +static void satip_frontend_close_rtsp(satip_frontend_t* lfe, + const char* name, + tvhpoll_t* efd, + http_client_t* rtsp, + satip_tune_req_t* tr) { tvhpoll_rem1(efd, lfe->sf_dvr_pipe.rd); satip_frontend_shutdown(lfe, name, rtsp, tr, efd); tvhpoll_add1(efd, lfe->sf_dvr_pipe.rd, TVHPOLL_IN, NULL); http_client_close(rtsp); } -static int -satip_frontend_rtp_decode - ( satip_frontend_t *lfe, uint32_t *_seq, uint32_t *_unc, - uint8_t *p, int c ) -{ - int pos, len, seq = *_seq, nseq; - struct satip_udppkt *up; +static int satip_frontend_rtp_decode(satip_frontend_t* lfe, + uint32_t* _seq, + uint32_t* _unc, + uint8_t* p, + int c) { + int pos, len, seq = *_seq, nseq; + struct satip_udppkt* up; /* Strip RTP header */ if (c < 12) @@ -1481,7 +1347,7 @@ satip_frontend_rtp_decode if (p[0] & 0x10) { if (c < pos + 4) return 0; - pos += (((p[pos+2] << 8) | p[pos+3]) + 1) * 4; + pos += (((p[pos + 2] << 8) | p[pos + 3]) + 1) * 4; } len = c - pos; if (c < pos || (len % 188) != 0) @@ -1493,9 +1359,13 @@ satip_frontend_rtp_decode else if (((seq + 1) & 0xffff) != nseq) { if (lfe->sf_udp_packets_count > 5) { up = TAILQ_FIRST(&lfe->sf_udp_packets); - tvhtrace(LS_SATIP, "RTP discontinuity, reset sequence to %d from %d", up->up_data_seq, (seq + 1) & 0xffff); + tvhtrace(LS_SATIP, + "RTP discontinuity, reset sequence to %d from %d", + up->up_data_seq, + (seq + 1) & 0xffff); *_seq = (up->up_data_seq - 1) & 0xffff; - *_unc += (up->up_data_len / 188) * (uint32_t)((uint16_t)up->up_data_seq-(uint16_t)(seq+1)); + *_unc += + (up->up_data_len / 188) * (uint32_t)((uint16_t)up->up_data_seq - (uint16_t)(seq + 1)); } tvhtrace(LS_SATIP, "RTP discontinuity (%i != %i), queueing packet", seq + 1, nseq); udp_rtp_packet_append(lfe, p, c, nseq); @@ -1515,7 +1385,7 @@ satip_frontend_rtp_decode lfe->sf_skip_ts -= len; } } else { -wrdata: + wrdata: sbuf_append(&lfe->sf_sbuf, p + pos, len); } next: @@ -1529,13 +1399,11 @@ next: return len; } -static int -satip_frontend_rtp_data_received( http_client_t *hc, void *buf, size_t len ) -{ - uint32_t unc; - uint8_t *b = buf; - satip_frontend_t *lfe = hc->hc_aux; - mpegts_mux_instance_t *mmi; +static int satip_frontend_rtp_data_received(http_client_t* hc, void* buf, size_t len) { + uint32_t unc; + uint8_t* b = buf; + satip_frontend_t* lfe = hc->hc_aux; + mpegts_mux_instance_t* mmi; if (len < 4) return -EINVAL; @@ -1548,8 +1416,7 @@ satip_frontend_rtp_data_received( http_client_t *hc, void *buf, size_t len ) if (satip_frontend_rtp_decode(lfe, &lfe->sf_seq, &unc, b + 4, len - 4) == 0) return 0; - if (lfe->sf_sbuf.sb_ptr > 64 * 1024 || - lfe->sf_last_data_tstamp + sec2mono(1) <= mclk()) { + if (lfe->sf_sbuf.sb_ptr > 64 * 1024 || lfe->sf_last_data_tstamp + sec2mono(1) <= mclk()) { tvh_mutex_lock(&lfe->sf_dvr_lock); if (lfe->sf_req == lfe->sf_req_thread) { mmi = lfe->sf_req->sf_mmi; @@ -1568,48 +1435,44 @@ satip_frontend_rtp_data_received( http_client_t *hc, void *buf, size_t len ) tvh_mutex_lock(&lfe->sf_dvr_lock); if (lfe->sf_req == lfe->sf_req_thread) - satip_frontend_decode_rtcp(lfe, lfe->sf_display_name, - lfe->sf_req->sf_mmi, b, len); + satip_frontend_decode_rtcp(lfe, lfe->sf_display_name, lfe->sf_req->sf_mmi, b, len); tvh_mutex_unlock(&lfe->sf_dvr_lock); - } return 0; } -static void * -satip_frontend_input_thread ( void *aux ) -{ +static void* satip_frontend_input_thread(void* aux) { #define RTP_PKTS 64 -#define UDP_PKT_SIZE 1472 /* this is maximum UDP payload (standard ethernet) */ -#define RTP_PKT_SIZE (UDP_PKT_SIZE - 12) /* minus RTP minimal RTP header */ +#define UDP_PKT_SIZE 1472 /* this is maximum UDP payload (standard ethernet) */ +#define RTP_PKT_SIZE (UDP_PKT_SIZE - 12) /* minus RTP minimal RTP header */ #define HTTP_CMD_NONE 9874 - satip_frontend_t *lfe = aux, *lfe_master; - satip_tune_req_t *tr = NULL; - mpegts_mux_instance_t *mmi; - http_client_t *rtsp = NULL; - udp_connection_t *rtp = NULL, *rtcp = NULL; - dvb_mux_t *lm; - char buf[256]; - struct iovec *iovec; - uint8_t b[2048], session[32]; - sbuf_t *sb; - int nfds, i, r, tc, rtp_port, start = 0, poll_reg = 0; - size_t c; - tvhpoll_event_t ev[3]; - tvhpoll_t *efd; - int changing, ms, fatal, running, play2, exit_flag; - int rtsp_flags, position, reply; - uint32_t seq, unc; - udp_multirecv_t um; - uint64_t u64, u64_2, fatal_timeout; - long stream_id; + satip_frontend_t * lfe = aux, *lfe_master; + satip_tune_req_t* tr = NULL; + mpegts_mux_instance_t* mmi; + http_client_t* rtsp = NULL; + udp_connection_t * rtp = NULL, *rtcp = NULL; + dvb_mux_t* lm; + char buf[256]; + struct iovec* iovec; + uint8_t b[2048], session[32]; + sbuf_t* sb; + int nfds, i, r, tc, rtp_port, start = 0, poll_reg = 0; + size_t c; + tvhpoll_event_t ev[3]; + tvhpoll_t* efd; + int changing, ms, fatal, running, play2, exit_flag; + int rtsp_flags, position, reply; + uint32_t seq, unc; + udp_multirecv_t um; + uint64_t u64, u64_2, fatal_timeout; + long stream_id; /* If set - the thread will be cancelled */ exit_flag = 0; /* Remember session for extra shutdown (workaround for IDL4K firmware bug) */ session[0] = '\0'; - stream_id = 0; + stream_id = 0; /* Setup poll */ efd = tvhpoll_create(4); @@ -1638,7 +1501,7 @@ new_tune: if (rtsp && !lfe->sf_device->sd_fast_switch) { satip_frontend_close_rtsp(lfe, buf, efd, rtsp, tr); rtsp = NULL; - tr = NULL; + tr = NULL; } if (rtsp) @@ -1651,22 +1514,33 @@ new_tune: u64_2 = getfastmonoclock(); - if (!satip_frontend_other_is_waiting(lfe)) start |= 2; else start &= ~2; + if (!satip_frontend_other_is_waiting(lfe)) + start |= 2; + else + start &= ~2; while (start != 3) { nfds = tvhpoll_wait(efd, ev, 1, rtsp ? 55 : -1); - if (!satip_frontend_other_is_waiting(lfe)) start |= 2; else start &= ~2; + if (!satip_frontend_other_is_waiting(lfe)) + start |= 2; + else + start &= ~2; - if (!tvheadend_is_running()) { exit_flag = 1; goto done; } - if (rtsp && (getfastmonoclock() - u64_2 > 50000 || /* 50ms */ - (start & 2) == 0)) { + if (!tvheadend_is_running()) { + exit_flag = 1; + goto done; + } + if (rtsp && + (getfastmonoclock() - u64_2 > 50000 || /* 50ms */ + (start & 2) == 0)) { satip_frontend_close_rtsp(lfe, buf, efd, rtsp, tr); rtsp = NULL; - tr = NULL; + tr = NULL; } - if (nfds <= 0) continue; + if (nfds <= 0) + continue; if (ev[0].ptr == NULL) { c = read(lfe->sf_dvr_pipe.rd, b, 1); @@ -1689,18 +1563,17 @@ new_tune: rtsp = NULL; } else { switch (rtsp->hc_cmd) { - case RTSP_CMD_OPTIONS: - rtsp_options_decode(rtsp); - break; - case RTSP_CMD_SETUP: - rtsp_setup_decode(rtsp, 1); - break; - default: - break; + case RTSP_CMD_OPTIONS: + rtsp_options_decode(rtsp); + break; + case RTSP_CMD_SETUP: + rtsp_setup_decode(rtsp, 1); + break; + default: + break; } } } - } start = 0; @@ -1726,20 +1599,29 @@ new_tune: rtsp_flags = satip_frontend_rtsp_flags(lfe); if ((rtsp_flags & SATIP_SETUP_TCP) == 0) { - if (udp_bind_double(&rtp, &rtcp, - LS_SATIP, "rtp", "rtcp", - satip_frontend_bindaddr(lfe), lfe->sf_udp_rtp_port, - NULL, SATIP_BUF_SIZE, 16384, 4*1024, 4*1024) < 0) { + if (udp_bind_double(&rtp, + &rtcp, + LS_SATIP, + "rtp", + "rtcp", + satip_frontend_bindaddr(lfe), + lfe->sf_udp_rtp_port, + NULL, + SATIP_BUF_SIZE, + 16384, + 4 * 1024, + 4 * 1024) < 0) { satip_frontend_tuning_error(lfe, tr); goto done; } rtp_port = ntohs(IP_PORT(rtp->ip)); - tvhtrace(LS_SATIP, "%s - local RTP port %i RTCP port %i", - lfe->mi_name, - ntohs(IP_PORT(rtp->ip)), - ntohs(IP_PORT(rtcp->ip))); + tvhtrace(LS_SATIP, + "%s - local RTP port %i RTCP port %i", + lfe->mi_name, + ntohs(IP_PORT(rtp->ip)), + ntohs(IP_PORT(rtcp->ip))); if (rtp == NULL || rtcp == NULL) { satip_frontend_tuning_error(lfe, tr); @@ -1754,7 +1636,7 @@ new_tune: goto done; } - lfe->sf_curmux = lm = (dvb_mux_t *)mmi->mmi_mux; + lfe->sf_curmux = lm = (dvb_mux_t*)mmi->mmi_mux; lfe_master = lfe; if (lfe->sf_master) @@ -1764,7 +1646,7 @@ new_tune: if (!rtsp) { tvh_mutex_lock(&lfe->sf_device->sd_tune_mutex); u64 = lfe_master->sf_last_tune; - i = lfe_master->sf_tdelay; + i = lfe_master->sf_tdelay; tvh_mutex_unlock(&lfe->sf_device->sd_tune_mutex); if (i < 0) i = 0; @@ -1779,24 +1661,32 @@ new_tune: if (u64_2 >= (uint64_t)i) break; r = (uint64_t)i - u64_2; - + if (tc) - tvhtrace(LS_SATIP, "%s - last tune diff = %llu (delay = %d)", - buf, (unsigned long long)u64_2, r); + tvhtrace(LS_SATIP, + "%s - last tune diff = %llu (delay = %d)", + buf, + (unsigned long long)u64_2, + r); - tc = 1; + tc = 1; nfds = tvhpoll_wait(efd, ev, 1, r); - if (!tvheadend_is_running()) { exit_flag = 1; goto done; } - if (nfds < 0) continue; - if (nfds == 0) break; + if (!tvheadend_is_running()) { + exit_flag = 1; + goto done; + } + if (nfds < 0) + continue; + if (nfds == 0) + break; if (ev[0].ptr == NULL) { c = read(lfe->sf_dvr_pipe.rd, b, 1); if (c == 1) { if (b[0] == 'c') { - tc = 0; - ms = 20; + tc = 0; + ms = 20; changing = 1; continue; } else if (b[0] == 'e') { @@ -1816,13 +1706,12 @@ new_tune: if (ev[0].ptr == rtsp) { tc = 0; - r = http_client_run(rtsp); + r = http_client_run(rtsp); if (r < 0) { http_client_close(rtsp); rtsp = NULL; } } - } tvh_mutex_lock(&lfe->sf_device->sd_tune_mutex); @@ -1831,10 +1720,12 @@ new_tune: i = 0; if (!rtsp) { - rtsp = http_client_connect(lfe, RTSP_VERSION_1_0, "rstp", - lfe->sf_device->sd_info.addr, - lfe->sf_device->sd_info.rtsp_port, - satip_frontend_bindaddr(lfe)); + rtsp = http_client_connect(lfe, + RTSP_VERSION_1_0, + "rstp", + lfe->sf_device->sd_info.addr, + lfe->sf_device->sd_info.rtsp_port, + satip_frontend_bindaddr(lfe)); if (rtsp == NULL) { satip_frontend_tuning_error(lfe, tr); goto done; @@ -1855,23 +1746,23 @@ new_tune: tvhpoll_event(&ev[nfds++], rtsp->hc_fd, TVHPOLL_IN, rtsp); tvhpoll_add(efd, ev, nfds); rtsp->hc_efd = efd; - poll_reg = 1; + poll_reg = 1; position = lfe_master->sf_position; if (lfe->sf_device->sd_pilot_on) rtsp_flags |= SATIP_SETUP_PILOT_ON; switch (lfe->sf_device->sd_default_rolloff) { - case SATIP_DEFAULT_ROLLOFF_20: - rtsp_flags |= SATIP_SETUP_ROLLOFF_25; - break; - case SATIP_DEFAULT_ROLLOFF_25: - rtsp_flags |= SATIP_SETUP_ROLLOFF_25; - break; - case SATIP_DEFAULT_ROLLOFF_35: - rtsp_flags |= SATIP_SETUP_ROLLOFF_35; - break; - default: - break; + case SATIP_DEFAULT_ROLLOFF_20: + rtsp_flags |= SATIP_SETUP_ROLLOFF_25; + break; + case SATIP_DEFAULT_ROLLOFF_25: + rtsp_flags |= SATIP_SETUP_ROLLOFF_25; + break; + case SATIP_DEFAULT_ROLLOFF_35: + rtsp_flags |= SATIP_SETUP_ROLLOFF_35; + break; + default: + break; } if (lfe->sf_device->sd_pids21) rtsp_flags |= SATIP_SETUP_PIDS21; @@ -1886,11 +1777,13 @@ new_tune: tvh_mutex_lock(&lfe->sf_dvr_lock); if (lfe->sf_req == lfe->sf_req_thread) { lfe->sf_req->sf_weight_tuned = lfe->sf_req->sf_weight; - r = satip_rtsp_setup(rtsp, - position, lfe->sf_number, - rtp_port, &lm->lm_tuning, - rtsp_flags, - lfe->sf_req->sf_weight); + r = satip_rtsp_setup(rtsp, + position, + lfe->sf_number, + rtp_port, + &lm->lm_tuning, + rtsp_flags, + lfe->sf_req->sf_weight); } tvh_mutex_unlock(&lfe->sf_dvr_lock); if (r < 0) { @@ -1907,9 +1800,9 @@ new_tune: sbuf_init_fixed(sb, RTP_PKTS * RTP_PKT_SIZE); udp_rtp_packet_destroy_all(lfe); lfe->sf_skip_ts = MINMAX(lfe->sf_device->sd_skip_ts, 0, 200) * 188; - + lfe->sf_last_activity_tstamp = mclk(); - fatal_timeout = sec2mono(5 + MINMAX(lfe->sf_grace_period, 0, 60)); + fatal_timeout = sec2mono(5 + MINMAX(lfe->sf_grace_period, 0, 60)); while ((reply || running) && !fatal) { @@ -1917,7 +1810,7 @@ new_tune: if (!tvheadend_is_running() || exit_flag) { exit_flag = 1; - running = 0; + running = 0; if (reply++ > 5) break; } @@ -1926,15 +1819,17 @@ new_tune: c = read(lfe->sf_dvr_pipe.rd, b, 1); if (c == 1) { if (b[0] == 'c') { - ms = 20; + ms = 20; changing = 1; continue; } else if (b[0] == 'e') { tvhtrace(LS_SATIP, "%s - input thread received shutdown", buf); - exit_flag = 1; running = 0; + exit_flag = 1; + running = 0; continue; } else if (b[0] == 's') { - start = 1; running = 0; + start = 1; + running = 0; continue; } else if (b[0] == 'o') { continue; @@ -1946,7 +1841,7 @@ new_tune: } if (changing && rtsp->hc_cmd == HTTP_CMD_NONE) { - ms = 500; + ms = 500; changing = 0; if (satip_frontend_pid_changed(rtsp, lfe, buf) > 0) reply = 1; @@ -1960,7 +1855,8 @@ new_tune: continue; } - if (nfds < 1) continue; + if (nfds < 1) + continue; if (ev[0].ptr == rtsp) { r = http_client_run(rtsp); @@ -1969,13 +1865,18 @@ new_tune: tvhwarn(LS_SATIP, "%s - RTSP 404 ERROR (retrying)", buf); satip_frontend_extra_shutdown(lfe, session, stream_id); session[0] = '\0'; - start = 1; + start = 1; http_client_close(rtsp); rtsp = NULL; break; } - tvherror(LS_SATIP, "%s - RTSP error %d (%s) [%i-%i]", - buf, r, strerror(-r), rtsp->hc_cmd, rtsp->hc_code); + tvherror(LS_SATIP, + "%s - RTSP error %d (%s) [%i-%i]", + buf, + r, + strerror(-r), + rtsp->hc_cmd, + rtsp->hc_code); satip_frontend_tuning_error(lfe, tr); fatal = 1; } else if (r == HTTP_CON_DONE) { @@ -1983,84 +1884,104 @@ new_tune: goto done; reply = 0; switch (rtsp->hc_cmd) { - case RTSP_CMD_OPTIONS: - r = rtsp_options_decode(rtsp); - if (!running) - break; - if (r < 0) { - tvherror(LS_SATIP, "%s - RTSP OPTIONS error %d (%s) [%i-%i]", - buf, r, strerror(-r), rtsp->hc_cmd, rtsp->hc_code); - satip_frontend_tuning_error(lfe, tr); - fatal = 1; - } - break; - case RTSP_CMD_SETUP: - r = rtsp_setup_decode(rtsp, 1); - if (!running) + case RTSP_CMD_OPTIONS: + r = rtsp_options_decode(rtsp); + if (!running) + break; + if (r < 0) { + tvherror(LS_SATIP, + "%s - RTSP OPTIONS error %d (%s) [%i-%i]", + buf, + r, + strerror(-r), + rtsp->hc_cmd, + rtsp->hc_code); + satip_frontend_tuning_error(lfe, tr); + fatal = 1; + } break; - if (r < 0 || ((rtsp_flags & SATIP_SETUP_TCP) == 0 && - (rtsp->hc_rtp_port != rtp_port || - rtsp->hc_rtcp_port != rtp_port + 1)) || - ((rtsp_flags & SATIP_SETUP_TCP) != 0 && - (rtsp->hc_rtp_tcp < 0 || rtsp->hc_rtcp_tcp < 0))) { - tvherror(LS_SATIP, "%s - RTSP SETUP error %d (%s) [%i-%i]", - buf, r, strerror(-r), rtsp->hc_cmd, rtsp->hc_code); - satip_frontend_tuning_error(lfe, tr); - fatal = 1; - continue; - } else { - strlcpy((char *)session, rtsp->hc_rtsp_session ?: "", sizeof(session)); - stream_id = rtsp->hc_rtsp_stream_id; - tvhdebug(LS_SATIP, "%s #%i - new session %s stream id %li", - rtsp->hc_host, lfe->sf_number, - rtsp->hc_rtsp_session, rtsp->hc_rtsp_stream_id); - if (lfe->sf_play2) { - r = -12345678; - tvh_mutex_lock(&lfe->sf_dvr_lock); - if (lfe->sf_req == lfe->sf_req_thread) { - lfe->sf_req->sf_weight_tuned = lfe->sf_req->sf_weight; - r = satip_rtsp_setup(rtsp, position, lfe->sf_number, - rtp_port, &lm->lm_tuning, - rtsp_flags | SATIP_SETUP_PLAY, - lfe->sf_req->sf_weight); - } - tvh_mutex_unlock(&lfe->sf_dvr_lock); - if (r < 0) { - tvherror(LS_SATIP, "%s - failed to tune2 (%i)", buf, r); - satip_frontend_tuning_error(lfe, tr); - fatal = 1; - } - reply = 1; + case RTSP_CMD_SETUP: + r = rtsp_setup_decode(rtsp, 1); + if (!running) + break; + if (r < 0 || + ((rtsp_flags & SATIP_SETUP_TCP) == 0 && + (rtsp->hc_rtp_port != rtp_port || rtsp->hc_rtcp_port != rtp_port + 1)) || + ((rtsp_flags & SATIP_SETUP_TCP) != 0 && + (rtsp->hc_rtp_tcp < 0 || rtsp->hc_rtcp_tcp < 0))) { + tvherror(LS_SATIP, + "%s - RTSP SETUP error %d (%s) [%i-%i]", + buf, + r, + strerror(-r), + rtsp->hc_cmd, + rtsp->hc_code); + satip_frontend_tuning_error(lfe, tr); + fatal = 1; continue; } else { - if (satip_frontend_pid_changed(rtsp, lfe, buf) > 0) { + strlcpy((char*)session, rtsp->hc_rtsp_session ?: "", sizeof(session)); + stream_id = rtsp->hc_rtsp_stream_id; + tvhdebug(LS_SATIP, + "%s #%i - new session %s stream id %li", + rtsp->hc_host, + lfe->sf_number, + rtsp->hc_rtsp_session, + rtsp->hc_rtsp_stream_id); + if (lfe->sf_play2) { + r = -12345678; + tvh_mutex_lock(&lfe->sf_dvr_lock); + if (lfe->sf_req == lfe->sf_req_thread) { + lfe->sf_req->sf_weight_tuned = lfe->sf_req->sf_weight; + r = satip_rtsp_setup(rtsp, + position, + lfe->sf_number, + rtp_port, + &lm->lm_tuning, + rtsp_flags | SATIP_SETUP_PLAY, + lfe->sf_req->sf_weight); + } + tvh_mutex_unlock(&lfe->sf_dvr_lock); + if (r < 0) { + tvherror(LS_SATIP, "%s - failed to tune2 (%i)", buf, r); + satip_frontend_tuning_error(lfe, tr); + fatal = 1; + } reply = 1; continue; + } else { + if (satip_frontend_pid_changed(rtsp, lfe, buf) > 0) { + reply = 1; + continue; + } } } - } - break; - case RTSP_CMD_PLAY: - if (!running) break; - satip_frontend_wake_other_waiting(lfe, tr); - if (rtsp->hc_code == 200 && play2) { - play2 = 0; - if (satip_frontend_pid_changed(rtsp, lfe, buf) > 0) { - reply = 1; - continue; + case RTSP_CMD_PLAY: + if (!running) + break; + satip_frontend_wake_other_waiting(lfe, tr); + if (rtsp->hc_code == 200 && play2) { + play2 = 0; + if (satip_frontend_pid_changed(rtsp, lfe, buf) > 0) { + reply = 1; + continue; + } } - } - /* fall thru */ - default: - if (rtsp->hc_code >= 400) { - tvherror(LS_SATIP, "%s - RTSP cmd error %d (%s) [%i-%i]", - buf, r, r > 0 ? http_client_con2str(r) : strerror(-r), - rtsp->hc_cmd, rtsp->hc_code); - satip_frontend_tuning_error(lfe, tr); - fatal = 1; - } - break; + /* fall thru */ + default: + if (rtsp->hc_code >= 400) { + tvherror(LS_SATIP, + "%s - RTSP cmd error %d (%s) [%i-%i]", + buf, + r, + r > 0 ? http_client_con2str(r) : strerror(-r), + rtsp->hc_cmd, + rtsp->hc_code); + satip_frontend_tuning_error(lfe, tr); + fatal = 1; + } + break; } rtsp->hc_cmd = HTTP_CMD_NONE; } @@ -2088,9 +2009,9 @@ new_tune: } continue; } - + if (ev[0].ptr != rtp) - continue; + continue; tc = udp_multirecv_read(&um, rtp->fd, RTP_PKTS, &iovec); @@ -2101,8 +2022,7 @@ new_tune: tvhwarn(LS_SATIP, "%s - recvmsg() EOVERFLOW", buf); continue; } - tvherror(LS_SATIP, "%s - multirecv error %d (%s)", - buf, errno, strerror(errno)); + tvherror(LS_SATIP, "%s - multirecv error %d (%s)", buf, errno, strerror(errno)); break; } else { lfe->sf_last_activity_tstamp = mclk(); @@ -2176,7 +2096,7 @@ done: tvhpoll_destroy(efd); lfe->sf_display_name = NULL; - lfe->sf_curmux = NULL; + lfe->sf_curmux = NULL; return NULL; #undef PKTS @@ -2186,55 +2106,47 @@ done: * Creation/Config * *************************************************************************/ -static int -satip_frontend_default_positions ( satip_frontend_t *lfe ) -{ - satip_device_t *sd = lfe->sf_device; +static int satip_frontend_default_positions(satip_frontend_t* lfe) { + satip_device_t* sd = lfe->sf_device; if (!strcmp(sd->sd_info.modelname, "IPLNB")) return 1; return sd->sd_info.srcs; } -static mpegts_network_t * -satip_frontend_wizard_network ( satip_frontend_t *lfe ) -{ - satip_satconf_t *sfc; +static mpegts_network_t* satip_frontend_wizard_network(satip_frontend_t* lfe) { + satip_satconf_t* sfc; sfc = TAILQ_FIRST(&lfe->sf_satconf); if (sfc && sfc->sfc_networks) if (sfc->sfc_networks->is_count > 0) - return (mpegts_network_t *)sfc->sfc_networks->is_array[0]; + return (mpegts_network_t*)sfc->sfc_networks->is_array[0]; return NULL; } -static htsmsg_t * -satip_frontend_wizard_get( tvh_input_t *ti, const char *lang ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)ti; - mpegts_network_t *mn; - const idclass_t *idc = NULL; +static htsmsg_t* satip_frontend_wizard_get(tvh_input_t* ti, const char* lang) { + satip_frontend_t* lfe = (satip_frontend_t*)ti; + mpegts_network_t* mn; + const idclass_t* idc = NULL; mn = satip_frontend_wizard_network(lfe); if (lfe->sf_master == 0 && (mn == NULL || (mn && mn->mn_wizard))) idc = dvb_network_class_by_fe_type(lfe->sf_type); - return mpegts_network_wizard_get((mpegts_input_t *)lfe, idc, mn, lang); + return mpegts_network_wizard_get((mpegts_input_t*)lfe, idc, mn, lang); } -static void -satip_frontend_wizard_set( tvh_input_t *ti, htsmsg_t *conf, const char *lang ) -{ - satip_frontend_t *lfe = (satip_frontend_t*)ti; - const char *ntype = htsmsg_get_str(conf, "mpegts_network_type"); - mpegts_network_t *mn; - htsmsg_t *nlist; +static void satip_frontend_wizard_set(tvh_input_t* ti, htsmsg_t* conf, const char* lang) { + satip_frontend_t* lfe = (satip_frontend_t*)ti; + const char* ntype = htsmsg_get_str(conf, "mpegts_network_type"); + mpegts_network_t* mn; + htsmsg_t* nlist; mpegts_network_wizard_create(ntype, &nlist, lang); mn = satip_frontend_wizard_network(lfe); if (nlist && lfe->sf_master == 0 && (mn == NULL || mn->mn_wizard)) { - htsmsg_t *conf = htsmsg_create_map(); - htsmsg_t *list = htsmsg_create_list(); - htsmsg_t *pos = htsmsg_create_map(); + htsmsg_t* conf = htsmsg_create_map(); + htsmsg_t* list = htsmsg_create_list(); + htsmsg_t* pos = htsmsg_create_map(); htsmsg_add_bool(pos, "enabled", 1); htsmsg_add_msg(pos, "networks", nlist); htsmsg_add_msg(list, NULL, pos); @@ -2242,44 +2154,40 @@ satip_frontend_wizard_set( tvh_input_t *ti, htsmsg_t *conf, const char *lang ) satip_satconf_create(lfe, conf, satip_frontend_default_positions(lfe)); htsmsg_destroy(conf); if (satip_frontend_wizard_network(lfe)) - mpegts_input_set_enabled((mpegts_input_t *)lfe, 1); + mpegts_input_set_enabled((mpegts_input_t*)lfe, 1); satip_device_changed(lfe->sf_device); } else { htsmsg_destroy(nlist); } } -static void -satip_frontend_hacks( satip_frontend_t *lfe ) -{ - satip_device_t *sd = lfe->sf_device; +static void satip_frontend_hacks(satip_frontend_t* lfe) { + satip_device_t* sd = lfe->sf_device; - lfe->sf_tdelay = 50; /* should not hurt anything */ + lfe->sf_tdelay = 50; /* should not hurt anything */ lfe->sf_pass_weight = 1; if (strstr(sd->sd_info.location, ":8888/octonet.xml")) { if (lfe->sf_type == DVB_TYPE_S) lfe->sf_play2 = 1; - lfe->sf_tdelay = 250; + lfe->sf_tdelay = 250; lfe->sf_teardown_delay = 1; } else if (strstr(sd->sd_info.manufacturer, "AVM Berlin") && - strstr(sd->sd_info.modelname, "FRITZ!")) { + strstr(sd->sd_info.modelname, "FRITZ!")) { lfe->sf_play2 = 1; } else if (strstr(sd->sd_info.modelname, "EyeTV Netstream 4C")) { - lfe->sf_specinv = 1; + lfe->sf_specinv = 1; lfe->sf_pass_weight = 0; } } -satip_frontend_t * -satip_frontend_create - ( htsmsg_t *conf, satip_device_t *sd, dvb_fe_type_t type, int v2, int num ) -{ - const idclass_t *idc; - const char *uuid = NULL, *override = NULL; - char id[16], lname[256]; - satip_frontend_t *lfe; - uint32_t master = 0; - int i; +satip_frontend_t* +satip_frontend_create(htsmsg_t* conf, satip_device_t* sd, dvb_fe_type_t type, int v2, int num) { + const idclass_t* idc; + const char * uuid = NULL, *override = NULL; + char id[16], lname[256]; + satip_frontend_t* lfe; + uint32_t master = 0; + int i; /* Override type */ snprintf(id, sizeof(id), "override #%d", num); @@ -2310,8 +2218,7 @@ satip_frontend_create /* Class */ if (type == DVB_TYPE_S) - idc = master ? &satip_frontend_dvbs_slave_class : - &satip_frontend_dvbs_class; + idc = master ? &satip_frontend_dvbs_slave_class : &satip_frontend_dvbs_class; else if (type == DVB_TYPE_T) idc = &satip_frontend_dvbt_class; else if (type == DVB_TYPE_C) @@ -2330,25 +2237,25 @@ satip_frontend_create // Note: there is a bit of a chicken/egg issue below, without the // correct "fe_type" we cannot set the network (which is done // in mpegts_input_create()). So we must set early. - lfe = calloc(1, sizeof(satip_frontend_t)); - lfe->sf_device = sd; - lfe->sf_number = num; - lfe->sf_type = type; - lfe->sf_type_v2 = v2; - lfe->sf_master = master; + lfe = calloc(1, sizeof(satip_frontend_t)); + lfe->sf_device = sd; + lfe->sf_number = num; + lfe->sf_type = type; + lfe->sf_type_v2 = v2; + lfe->sf_master = master; lfe->sf_type_override = override ? strdup(override) : NULL; - lfe->sf_pass_weight = 1; + lfe->sf_pass_weight = 1; satip_frontend_hacks(lfe); TAILQ_INIT(&lfe->sf_satconf); tvh_mutex_init(&lfe->sf_dvr_lock, NULL); lfe = (satip_frontend_t*)mpegts_input_create0((mpegts_input_t*)lfe, idc, uuid, conf); - if (!lfe) return NULL; + if (!lfe) + return NULL; /* Defaults */ - lfe->sf_position = -1; - lfe->sf_netlimit = 1; - lfe->sf_netgroup = 0; - + lfe->sf_position = -1; + lfe->sf_netlimit = 1; + lfe->sf_netgroup = 0; /* Callbacks */ lfe->mi_get_weight = satip_frontend_get_weight; @@ -2357,25 +2264,24 @@ satip_frontend_create /* Default name */ if (!lfe->mi_name || - (strncmp(lfe->mi_name, "SAT>IP ", 7) == 0 && - strstr(lfe->mi_name, " Tuner"))) { + (strncmp(lfe->mi_name, "SAT>IP ", 7) == 0 && strstr(lfe->mi_name, " Tuner"))) { snprintf(lname, sizeof(lname), "SAT>IP %s Tuner", dvb_type2str(type)); free(lfe->mi_name); lfe->mi_name = strdup(lname); } /* Input callbacks */ - lfe->ti_wizard_get = satip_frontend_wizard_get; - lfe->ti_wizard_set = satip_frontend_wizard_set; - lfe->mi_display_name = satip_frontend_display_name; - lfe->mi_is_enabled = satip_frontend_is_enabled; - lfe->mi_warm_mux = satip_frontend_warm_mux; - lfe->mi_start_mux = satip_frontend_start_mux; - lfe->mi_stop_mux = satip_frontend_stop_mux; - lfe->mi_network_list = satip_frontend_network_list; - lfe->mi_update_pids = satip_frontend_update_pids; - lfe->mi_open_service = satip_frontend_open_service; - lfe->mi_empty_status = mpegts_input_empty_status; + lfe->ti_wizard_get = satip_frontend_wizard_get; + lfe->ti_wizard_set = satip_frontend_wizard_set; + lfe->mi_display_name = satip_frontend_display_name; + lfe->mi_is_enabled = satip_frontend_is_enabled; + lfe->mi_warm_mux = satip_frontend_warm_mux; + lfe->mi_start_mux = satip_frontend_start_mux; + lfe->mi_stop_mux = satip_frontend_stop_mux; + lfe->mi_network_list = satip_frontend_network_list; + lfe->mi_update_pids = satip_frontend_update_pids; + lfe->mi_open_service = satip_frontend_open_service; + lfe->mi_empty_status = mpegts_input_empty_status; /* Adapter link */ lfe->sf_device = sd; @@ -2387,9 +2293,9 @@ satip_frontend_create /* Slave networks update */ if (master) { - satip_frontend_t *lfe2 = satip_frontend_find_by_number(sd, master); + satip_frontend_t* lfe2 = satip_frontend_find_by_number(sd, master); if (lfe2) { - htsmsg_t *l = (htsmsg_t *)mpegts_input_class_network_get(lfe2); + htsmsg_t* l = (htsmsg_t*)mpegts_input_class_network_get(lfe2); if (l) { mpegts_input_class_network_set(lfe, l); htsmsg_destroy(l); @@ -2398,17 +2304,14 @@ satip_frontend_create } tvh_pipe(O_NONBLOCK, &lfe->sf_dvr_pipe); - tvh_thread_create(&lfe->sf_dvr_thread, NULL, - satip_frontend_input_thread, lfe, "satip-front"); + tvh_thread_create(&lfe->sf_dvr_thread, NULL, satip_frontend_input_thread, lfe, "satip-front"); return lfe; } -void -satip_frontend_save ( satip_frontend_t *lfe, htsmsg_t *fe ) -{ - char id[16]; - htsmsg_t *m = htsmsg_create_map(); +void satip_frontend_save(satip_frontend_t* lfe, htsmsg_t* fe) { + char id[16]; + htsmsg_t* m = htsmsg_create_map(); /* Save frontend */ mpegts_input_save((mpegts_input_t*)lfe, m); @@ -2434,14 +2337,12 @@ satip_frontend_save ( satip_frontend_t *lfe, htsmsg_t *fe ) } } -void -satip_frontend_delete ( satip_frontend_t *lfe ) -{ +void satip_frontend_delete(satip_frontend_t* lfe) { char buf1[256]; lock_assert(&global_lock); - lfe->mi_display_name((mpegts_input_t *)lfe, buf1, sizeof(buf1)); + lfe->mi_display_name((mpegts_input_t*)lfe, buf1, sizeof(buf1)); /* Ensure we're stopped */ mpegts_input_stop_all((mpegts_input_t*)lfe); diff --git a/src/input/mpegts/satip/satip_private.h b/src/input/mpegts/satip/satip_private.h index af123ca86..edd192ffa 100644 --- a/src/input/mpegts/satip/satip_private.h +++ b/src/input/mpegts/satip/satip_private.h @@ -27,12 +27,12 @@ #include "http.h" #include "satip.h" -#define SATIP_BUF_SIZE (4000*188) +#define SATIP_BUF_SIZE (4000 * 188) -#define SATIP_DEFAULT_ROLLOFF_AUTO 0 -#define SATIP_DEFAULT_ROLLOFF_35 1 -#define SATIP_DEFAULT_ROLLOFF_25 2 -#define SATIP_DEFAULT_ROLLOFF_20 3 +#define SATIP_DEFAULT_ROLLOFF_AUTO 0 +#define SATIP_DEFAULT_ROLLOFF_35 1 +#define SATIP_DEFAULT_ROLLOFF_25 2 +#define SATIP_DEFAULT_ROLLOFF_20 3 typedef struct satip_device_info satip_device_info_t; typedef struct satip_device satip_device_t; @@ -40,185 +40,181 @@ typedef struct satip_tune_req satip_tune_req_t; typedef struct satip_frontend satip_frontend_t; typedef struct satip_satconf satip_satconf_t; -struct satip_device_info -{ - char *myaddr; /* IP address of this host received data from the SAT>IP device */ - char *addr; /* IP address */ - char *uuid; - char *bootid; - char *configid; - char *deviceid; - char *location; /*< URL of the XML file */ - char *server; - char *friendlyname; - char *manufacturer; - char *manufacturerURL; - char *modeldesc; - char *modelname; - char *modelnum; - char *serialnum; - char *presentation; - char *tunercfg; /*< XML urn:ses-com:satipX_SATIPCAP contents */ - int rtsp_port; - int srcs; +struct satip_device_info { + char* myaddr; /* IP address of this host received data from the SAT>IP device */ + char* addr; /* IP address */ + char* uuid; + char* bootid; + char* configid; + char* deviceid; + char* location; /*< URL of the XML file */ + char* server; + char* friendlyname; + char* manufacturer; + char* manufacturerURL; + char* modeldesc; + char* modelname; + char* modelnum; + char* serialnum; + char* presentation; + char* tunercfg; /*< XML urn:ses-com:satipX_SATIPCAP contents */ + int rtsp_port; + int srcs; }; -struct satip_device -{ +struct satip_device { tvh_hardware_t; - mtimer_t sd_destroy_timer; - int sd_inload; - int sd_nosave; + mtimer_t sd_destroy_timer; + int sd_inload; + int sd_nosave; /* * Adapter info */ - satip_device_info_t sd_info; + satip_device_info_t sd_info; /* * Frontends */ - TAILQ_HEAD(,satip_frontend) sd_frontends; + TAILQ_HEAD(, satip_frontend) sd_frontends; /* * RTSP */ - char *sd_bindaddr; - int sd_tcp_mode; - int sd_fast_switch; - int sd_fullmux_ok; - int sd_pids_max; - int sd_pids_len; - int sd_pids_deladd; - int sd_fe; - int sd_sig_scale; - int sd_sig_tunerno; - char *sd_tunercfg; - int sd_pids21; - int sd_pilot_on; - int sd_default_rolloff; - int sd_no_univ_lnb; - int sd_can_weight; - int sd_dbus_allow; - int sd_skip_ts; - int sd_disable_workarounds; - int sd_wake_ref; - tvh_mutex_t sd_tune_mutex; - TAILQ_HEAD(,satip_frontend)sd_serialize_queue; + char* sd_bindaddr; + int sd_tcp_mode; + int sd_fast_switch; + int sd_fullmux_ok; + int sd_pids_max; + int sd_pids_len; + int sd_pids_deladd; + int sd_fe; + int sd_sig_scale; + int sd_sig_tunerno; + char* sd_tunercfg; + int sd_pids21; + int sd_pilot_on; + int sd_default_rolloff; + int sd_no_univ_lnb; + int sd_can_weight; + int sd_dbus_allow; + int sd_skip_ts; + int sd_disable_workarounds; + int sd_wake_ref; + tvh_mutex_t sd_tune_mutex; + TAILQ_HEAD(, satip_frontend) sd_serialize_queue; }; struct satip_tune_req { - mpegts_mux_instance_t *sf_mmi; + mpegts_mux_instance_t* sf_mmi; - mpegts_apids_t sf_pids; - mpegts_apids_t sf_pids_tuned; + mpegts_apids_t sf_pids; + mpegts_apids_t sf_pids_tuned; - int sf_weight; - int sf_weight_tuned; + int sf_weight; + int sf_weight_tuned; - int sf_netlimit; - int sf_netgroup; - int sf_netposhash; + int sf_netlimit; + int sf_netgroup; + int sf_netposhash; }; struct satip_udppkt { - TAILQ_ENTRY(satip_udppkt) up_link; - uint8_t *up_data; - uint16_t up_data_len; - uint16_t up_data_seq; + TAILQ_ENTRY(satip_udppkt) up_link; + uint8_t* up_data; + uint16_t up_data_len; + uint16_t up_data_seq; }; -struct satip_frontend -{ +struct satip_frontend { mpegts_input_t; /* * Device */ - satip_device_t *sf_device; + satip_device_t* sf_device; TAILQ_ENTRY(satip_frontend) sf_link; /* * Frontend info */ - int sf_number; - dvb_fe_type_t sf_type; - int sf_type_v2; - char *sf_type_override; - int sf_master; - int sf_udp_rtp_port; - int sf_transport_mode; - int sf_play2; - int sf_tdelay; - int sf_grace_period; - int sf_teardown_delay; - int sf_pass_weight; - int sf_specinv; - int sf_delsys; - char *sf_tuner_bindaddr; + int sf_number; + dvb_fe_type_t sf_type; + int sf_type_v2; + char* sf_type_override; + int sf_master; + int sf_udp_rtp_port; + int sf_transport_mode; + int sf_play2; + int sf_tdelay; + int sf_grace_period; + int sf_teardown_delay; + int sf_pass_weight; + int sf_specinv; + int sf_delsys; + char* sf_tuner_bindaddr; /* * Reception */ - pthread_t sf_dvr_thread; - th_pipe_t sf_dvr_pipe; - tvh_mutex_t sf_dvr_lock; - int sf_thread; - int sf_running; - int sf_tables; - int sf_atsc_c; - int sf_position; - signal_state_t sf_status; - mtimer_t sf_monitor_timer; - uint64_t sf_last_tune; - satip_tune_req_t *sf_req; - satip_tune_req_t *sf_req_thread; - sbuf_t sf_sbuf; - int sf_skip_ts; - const char * sf_display_name; - uint32_t sf_seq; - dvb_mux_t *sf_curmux; - int64_t sf_last_data_tstamp; - int64_t sf_last_activity_tstamp; - int sf_netlimit; - int sf_netgroup; - int sf_netposhash; - TAILQ_HEAD(,satip_udppkt) sf_udp_packets; - int sf_udp_packets_count; - + pthread_t sf_dvr_thread; + th_pipe_t sf_dvr_pipe; + tvh_mutex_t sf_dvr_lock; + int sf_thread; + int sf_running; + int sf_tables; + int sf_atsc_c; + int sf_position; + signal_state_t sf_status; + mtimer_t sf_monitor_timer; + uint64_t sf_last_tune; + satip_tune_req_t* sf_req; + satip_tune_req_t* sf_req_thread; + sbuf_t sf_sbuf; + int sf_skip_ts; + const char* sf_display_name; + uint32_t sf_seq; + dvb_mux_t* sf_curmux; + int64_t sf_last_data_tstamp; + int64_t sf_last_activity_tstamp; + int sf_netlimit; + int sf_netgroup; + int sf_netposhash; + TAILQ_HEAD(, satip_udppkt) sf_udp_packets; + int sf_udp_packets_count; + /* * Configuration */ - int sf_positions; - TAILQ_HEAD(,satip_satconf) sf_satconf; + int sf_positions; + TAILQ_HEAD(, satip_satconf) sf_satconf; }; -struct satip_satconf -{ +struct satip_satconf { - idnode_t sfc_id; + idnode_t sfc_id; /* * Parent */ - satip_frontend_t *sfc_lfe; - TAILQ_ENTRY(satip_satconf) sfc_link; + satip_frontend_t* sfc_lfe; + TAILQ_ENTRY(satip_satconf) sfc_link; /* * Config */ - int sfc_enabled; - int sfc_position; - int sfc_priority; - int sfc_grace; - char *sfc_name; - int sfc_network_limit; - int sfc_network_group; + int sfc_enabled; + int sfc_position; + int sfc_priority; + int sfc_grace; + char* sfc_name; + int sfc_network_limit; + int sfc_network_group; /* * Assigned networks to this SAT configuration */ - idnode_set_t *sfc_networks; + idnode_set_t* sfc_networks; }; /* @@ -238,78 +234,80 @@ extern const idclass_t satip_satconf_class; /* * Methods */ - -void satip_device_init ( void ); -void satip_device_done ( void ); +void satip_device_init(void); + +void satip_device_done(void); -static inline void satip_device_changed ( satip_device_t *sd ) - { idnode_changed(&sd->th_id); } +static inline void satip_device_changed(satip_device_t* sd) { + idnode_changed(&sd->th_id); +} -void satip_device_destroy ( satip_device_t *sd ); +void satip_device_destroy(satip_device_t* sd); -void satip_device_destroy_later( satip_device_t *sd, int after_ms ); +void satip_device_destroy_later(satip_device_t* sd, int after_ms); -char *satip_device_nicename ( satip_device_t *sd, char *buf, int len ); +char* satip_device_nicename(satip_device_t* sd, char* buf, int len); -int satip_frontend_match_satcfg - ( satip_frontend_t *lfe2, mpegts_mux_t *mm2, int flags, int weight ); +int satip_frontend_match_satcfg(satip_frontend_t* lfe2, mpegts_mux_t* mm2, int flags, int weight); -satip_frontend_t * -satip_frontend_create - ( htsmsg_t *conf, satip_device_t *sd, dvb_fe_type_t type, int v2, int num ); +satip_frontend_t* +satip_frontend_create(htsmsg_t* conf, satip_device_t* sd, dvb_fe_type_t type, int v2, int num); -void satip_frontend_save ( satip_frontend_t *lfe, htsmsg_t *m ); +void satip_frontend_save(satip_frontend_t* lfe, htsmsg_t* m); -void satip_frontend_delete ( satip_frontend_t *lfe ); +void satip_frontend_delete(satip_frontend_t* lfe); /* * SAT>IP Satconf configuration */ -void satip_satconf_save ( satip_frontend_t *lfe, htsmsg_t *m ); +void satip_satconf_save(satip_frontend_t* lfe, htsmsg_t* m); -void satip_satconf_destroy ( satip_frontend_t *lfe ); +void satip_satconf_destroy(satip_frontend_t* lfe); -void satip_satconf_create - ( satip_frontend_t *lfe, htsmsg_t *conf, int def_positions ); +void satip_satconf_create(satip_frontend_t* lfe, htsmsg_t* conf, int def_positions); -void satip_satconf_updated_positions - ( satip_frontend_t *lfe ); +void satip_satconf_updated_positions(satip_frontend_t* lfe); -int satip_satconf_get_priority - ( satip_frontend_t *lfe, mpegts_mux_t *mm ); +int satip_satconf_get_priority(satip_frontend_t* lfe, mpegts_mux_t* mm); -int satip_satconf_get_grace - ( satip_frontend_t *lfe, mpegts_mux_t *mm ); +int satip_satconf_get_grace(satip_frontend_t* lfe, mpegts_mux_t* mm); -satip_satconf_t *satip_satconf_get_position - ( satip_frontend_t *lfe, mpegts_mux_t *mm, int *hash, - int check, int flags, int weight ); +satip_satconf_t* satip_satconf_get_position(satip_frontend_t* lfe, + mpegts_mux_t* mm, + int* hash, + int check, + int flags, + int weight); /* * RTSP part */ -#define SATIP_SETUP_TCP (1<<0) -#define SATIP_SETUP_PLAY (1<<1) -#define SATIP_SETUP_PILOT_ON (1<<2) -#define SATIP_SETUP_ROLLOFF_20 (1<<3) -#define SATIP_SETUP_ROLLOFF_25 (1<<4) -#define SATIP_SETUP_ROLLOFF_35 (1<<5) -#define SATIP_SETUP_PIDS21 (1<<6) -#define SATIP_SETUP_FE (1<<7) -#define SATIP_SETUP_SPECINV0 (1<<8) -#define SATIP_SETUP_SPECINV1 (1<<9) - -int -satip_rtsp_setup( http_client_t *hc, - int src, int fe, int udp_port, - const dvb_mux_conf_t *dmc, - int flags, int weight ); - -int -satip_rtsp_play( http_client_t *hc, const char *pids, - const char *addpids, const char *delpids, - int max_pids_len, int weight ); +#define SATIP_SETUP_TCP (1 << 0) +#define SATIP_SETUP_PLAY (1 << 1) +#define SATIP_SETUP_PILOT_ON (1 << 2) +#define SATIP_SETUP_ROLLOFF_20 (1 << 3) +#define SATIP_SETUP_ROLLOFF_25 (1 << 4) +#define SATIP_SETUP_ROLLOFF_35 (1 << 5) +#define SATIP_SETUP_PIDS21 (1 << 6) +#define SATIP_SETUP_FE (1 << 7) +#define SATIP_SETUP_SPECINV0 (1 << 8) +#define SATIP_SETUP_SPECINV1 (1 << 9) + +int satip_rtsp_setup(http_client_t* hc, + int src, + int fe, + int udp_port, + const dvb_mux_conf_t* dmc, + int flags, + int weight); + +int satip_rtsp_play(http_client_t* hc, + const char* pids, + const char* addpids, + const char* delpids, + int max_pids_len, + int weight); #endif /* __TVH_SATIP_PRIVATE_H__ */ diff --git a/src/input/mpegts/satip/satip_rtsp.c b/src/input/mpegts/satip/satip_rtsp.c index f6a376bd1..5271d4a5d 100644 --- a/src/input/mpegts/satip/satip_rtsp.c +++ b/src/input/mpegts/satip/satip_rtsp.c @@ -30,18 +30,16 @@ typedef struct tvh2satip { int t; ///< TVH internal value - const char *s; ///< SATIP API value + const char* s; ///< SATIP API value } tvh2satip_t; #define TABLE_EOD -1 -static const char * -satip_rtsp_setup_find(const char *prefix, tvh2satip_t *tbl, - int src, const char *defval) -{ +static const char* +satip_rtsp_setup_find(const char* prefix, tvh2satip_t* tbl, int src, const char* defval) { while (tbl->t >= 0) { if (tbl->t == src) - return tbl->s; + return tbl->s; tbl++; } tvhtrace(LS_SATIP, "%s - cannot translate %d", prefix, src); @@ -51,12 +49,10 @@ satip_rtsp_setup_find(const char *prefix, tvh2satip_t *tbl, #define ADD(s, d, def) \ strcat(buf, "&" #d "="), strcat(buf, satip_rtsp_setup_find(#d, d, dmc->s, def)) -static void -satip_rtsp_add_val(const char *name, char *buf, uint32_t val) -{ +static void satip_rtsp_add_val(const char* name, char* buf, uint32_t val) { sprintf(buf + strlen(buf), "&%s=%i", name, val / 1000); if (val % 1000) { - char *sec = buf + strlen(buf); + char* sec = buf + strlen(buf); sprintf(sec, ".%03u", val % 1000); if (sec[3] == '0') { sec[3] = '\0'; @@ -66,104 +62,86 @@ satip_rtsp_add_val(const char *name, char *buf, uint32_t val) } } -static void -satip_rtsp_add_ival(const char *name, char *buf, uint32_t val) -{ +static void satip_rtsp_add_ival(const char* name, char* buf, uint32_t val) { sprintf(buf + strlen(buf), "&%s=%i", name, val); } -int -satip_rtsp_setup( http_client_t *hc, int src, int fe, - int udp_port, const dvb_mux_conf_t *dmc, int flags, - int weight ) -{ - static tvh2satip_t msys[] = { - { .t = DVB_SYS_DVBT, "dvbt" }, - { .t = DVB_SYS_DVBT2, "dvbt2" }, - { .t = DVB_SYS_DVBS, "dvbs" }, - { .t = DVB_SYS_DVBS2, "dvbs2" }, - { .t = DVB_SYS_DVBC_ANNEX_A, "dvbc" }, - { .t = DVB_SYS_DVBC_ANNEX_C, "dvbc2" }, - { .t = DVB_SYS_ATSC, "atsc" }, - { .t = DVB_SYS_ISDBT, "isdbt" }, - { .t = DVB_SYS_DVBC_ANNEX_B, "dvbcb" }, - { .t = TABLE_EOD } - }; - static tvh2satip_t pol[] = { - { .t = DVB_POLARISATION_HORIZONTAL, "h" }, - { .t = DVB_POLARISATION_VERTICAL, "v" }, - { .t = DVB_POLARISATION_CIRCULAR_LEFT, "l" }, - { .t = DVB_POLARISATION_CIRCULAR_RIGHT, "r" }, - { .t = TABLE_EOD } - }; - static tvh2satip_t ro[] = { - { .t = DVB_ROLLOFF_AUTO, "0.35" }, - { .t = DVB_ROLLOFF_20, "0.20" }, - { .t = DVB_ROLLOFF_25, "0.25" }, - { .t = DVB_ROLLOFF_35, "0.35" }, - { .t = TABLE_EOD } - }; - static tvh2satip_t mtype[] = { - { .t = DVB_MOD_AUTO, "auto" }, - { .t = DVB_MOD_QAM_16, "16qam" }, - { .t = DVB_MOD_QAM_32, "32qam" }, - { .t = DVB_MOD_QAM_64, "64qam" }, - { .t = DVB_MOD_QAM_128, "128qam"}, - { .t = DVB_MOD_QAM_256, "256qam"}, - { .t = DVB_MOD_QPSK, "qpsk" }, - { .t = DVB_MOD_PSK_8, "8psk" }, - { .t = TABLE_EOD } - }; - static tvh2satip_t plts[] = { - { .t = DVB_PILOT_AUTO, "auto" }, - { .t = DVB_PILOT_ON, "on" }, - { .t = DVB_PILOT_OFF, "off" }, - { .t = TABLE_EOD } - }; - static tvh2satip_t fec[] = { - { .t = DVB_FEC_AUTO, "auto" }, - { .t = DVB_FEC_1_2, "12" }, - { .t = DVB_FEC_2_3, "23" }, - { .t = DVB_FEC_3_4, "34" }, - { .t = DVB_FEC_3_5, "35" }, - { .t = DVB_FEC_4_5, "45" }, - { .t = DVB_FEC_5_6, "56" }, - { .t = DVB_FEC_7_8, "78" }, - { .t = DVB_FEC_8_9, "89" }, - { .t = DVB_FEC_9_10, "910" }, - { .t = TABLE_EOD } - }; - static tvh2satip_t plsm[] = { - { .t = DVB_PLS_ROOT, "root" }, - { .t = DVB_PLS_GOLD, "gold" }, - { .t = DVB_PLS_COMBO, "combo" }, - { .t = TABLE_EOD } - }; - static tvh2satip_t tmode[] = { - { .t = DVB_TRANSMISSION_MODE_AUTO, "auto" }, - { .t = DVB_TRANSMISSION_MODE_1K, "1k" }, - { .t = DVB_TRANSMISSION_MODE_2K, "2k" }, - { .t = DVB_TRANSMISSION_MODE_4K, "4k" }, - { .t = DVB_TRANSMISSION_MODE_8K, "8k" }, - { .t = DVB_TRANSMISSION_MODE_16K, "16k" }, - { .t = DVB_TRANSMISSION_MODE_32K, "32k" }, - { .t = TABLE_EOD } - }; - static tvh2satip_t gi[] = { - { .t = DVB_GUARD_INTERVAL_AUTO, "auto" }, - { .t = DVB_GUARD_INTERVAL_1_4, "14" }, - { .t = DVB_GUARD_INTERVAL_1_8, "18" }, - { .t = DVB_GUARD_INTERVAL_1_16, "116" }, - { .t = DVB_GUARD_INTERVAL_1_32, "132" }, - { .t = DVB_GUARD_INTERVAL_1_128, "1128" }, - { .t = DVB_GUARD_INTERVAL_19_128, "19128" }, - { .t = DVB_GUARD_INTERVAL_19_256, "19256" }, - { .t = TABLE_EOD } - }; +int satip_rtsp_setup(http_client_t* hc, + int src, + int fe, + int udp_port, + const dvb_mux_conf_t* dmc, + int flags, + int weight) { + static tvh2satip_t msys[] = {{.t = DVB_SYS_DVBT, "dvbt"}, + {.t = DVB_SYS_DVBT2, "dvbt2"}, + {.t = DVB_SYS_DVBS, "dvbs"}, + {.t = DVB_SYS_DVBS2, "dvbs2"}, + {.t = DVB_SYS_DVBC_ANNEX_A, "dvbc"}, + {.t = DVB_SYS_DVBC_ANNEX_C, "dvbc2"}, + {.t = DVB_SYS_ATSC, "atsc"}, + {.t = DVB_SYS_ISDBT, "isdbt"}, + {.t = DVB_SYS_DVBC_ANNEX_B, "dvbcb"}, + {.t = TABLE_EOD}}; + static tvh2satip_t pol[] = {{.t = DVB_POLARISATION_HORIZONTAL, "h"}, + {.t = DVB_POLARISATION_VERTICAL, "v"}, + {.t = DVB_POLARISATION_CIRCULAR_LEFT, "l"}, + {.t = DVB_POLARISATION_CIRCULAR_RIGHT, "r"}, + {.t = TABLE_EOD}}; + static tvh2satip_t ro[] = {{.t = DVB_ROLLOFF_AUTO, "0.35"}, + {.t = DVB_ROLLOFF_20, "0.20"}, + {.t = DVB_ROLLOFF_25, "0.25"}, + {.t = DVB_ROLLOFF_35, "0.35"}, + {.t = TABLE_EOD}}; + static tvh2satip_t mtype[] = {{.t = DVB_MOD_AUTO, "auto"}, + {.t = DVB_MOD_QAM_16, "16qam"}, + {.t = DVB_MOD_QAM_32, "32qam"}, + {.t = DVB_MOD_QAM_64, "64qam"}, + {.t = DVB_MOD_QAM_128, "128qam"}, + {.t = DVB_MOD_QAM_256, "256qam"}, + {.t = DVB_MOD_QPSK, "qpsk"}, + {.t = DVB_MOD_PSK_8, "8psk"}, + {.t = TABLE_EOD}}; + static tvh2satip_t plts[] = {{.t = DVB_PILOT_AUTO, "auto"}, + {.t = DVB_PILOT_ON, "on"}, + {.t = DVB_PILOT_OFF, "off"}, + {.t = TABLE_EOD}}; + static tvh2satip_t fec[] = {{.t = DVB_FEC_AUTO, "auto"}, + {.t = DVB_FEC_1_2, "12"}, + {.t = DVB_FEC_2_3, "23"}, + {.t = DVB_FEC_3_4, "34"}, + {.t = DVB_FEC_3_5, "35"}, + {.t = DVB_FEC_4_5, "45"}, + {.t = DVB_FEC_5_6, "56"}, + {.t = DVB_FEC_7_8, "78"}, + {.t = DVB_FEC_8_9, "89"}, + {.t = DVB_FEC_9_10, "910"}, + {.t = TABLE_EOD}}; + static tvh2satip_t plsm[] = {{.t = DVB_PLS_ROOT, "root"}, + {.t = DVB_PLS_GOLD, "gold"}, + {.t = DVB_PLS_COMBO, "combo"}, + {.t = TABLE_EOD}}; + static tvh2satip_t tmode[] = {{.t = DVB_TRANSMISSION_MODE_AUTO, "auto"}, + {.t = DVB_TRANSMISSION_MODE_1K, "1k"}, + {.t = DVB_TRANSMISSION_MODE_2K, "2k"}, + {.t = DVB_TRANSMISSION_MODE_4K, "4k"}, + {.t = DVB_TRANSMISSION_MODE_8K, "8k"}, + {.t = DVB_TRANSMISSION_MODE_16K, "16k"}, + {.t = DVB_TRANSMISSION_MODE_32K, "32k"}, + {.t = TABLE_EOD}}; + static tvh2satip_t gi[] = {{.t = DVB_GUARD_INTERVAL_AUTO, "auto"}, + {.t = DVB_GUARD_INTERVAL_1_4, "14"}, + {.t = DVB_GUARD_INTERVAL_1_8, "18"}, + {.t = DVB_GUARD_INTERVAL_1_16, "116"}, + {.t = DVB_GUARD_INTERVAL_1_32, "132"}, + {.t = DVB_GUARD_INTERVAL_1_128, "1128"}, + {.t = DVB_GUARD_INTERVAL_19_128, "19128"}, + {.t = DVB_GUARD_INTERVAL_19_256, "19256"}, + {.t = TABLE_EOD}}; - char buf[512]; - char *stream = NULL; - char _stream[32]; + char buf[512]; + char* stream = NULL; + char _stream[32]; if (src > 0) sprintf(buf, "src=%i&", src); @@ -173,23 +151,21 @@ satip_rtsp_setup( http_client_t *hc, int src, int fe, if (flags & SATIP_SETUP_FE) sprintf(buf + strlen(buf), "fe=%i", fe); - if (dmc->dmc_fe_delsys == DVB_SYS_DVBS || - dmc->dmc_fe_delsys == DVB_SYS_DVBS2) { + if (dmc->dmc_fe_delsys == DVB_SYS_DVBS || dmc->dmc_fe_delsys == DVB_SYS_DVBS2) { satip_rtsp_add_val("freq", buf, dmc->dmc_fe_freq); satip_rtsp_add_val("sr", buf, dmc->u.dmc_fe_qpsk.symbol_rate); ADD(dmc_fe_delsys, msys, "dvbs"); - if (dmc->dmc_fe_modulation != DVB_MOD_NONE && - dmc->dmc_fe_modulation != DVB_MOD_AUTO && + if (dmc->dmc_fe_modulation != DVB_MOD_NONE && dmc->dmc_fe_modulation != DVB_MOD_AUTO && dmc->dmc_fe_modulation != DVB_MOD_QAM_AUTO) ADD(dmc_fe_modulation, mtype, "qpsk"); ADD(u.dmc_fe_qpsk.polarisation, pol, "h"); if (dmc->u.dmc_fe_qpsk.fec_inner != DVB_FEC_NONE && dmc->u.dmc_fe_qpsk.fec_inner != DVB_FEC_AUTO) ADD(u.dmc_fe_qpsk.fec_inner, fec, "auto"); - if (dmc->dmc_fe_rolloff != DVB_ROLLOFF_NONE && - dmc->dmc_fe_rolloff != DVB_ROLLOFF_AUTO) { + if (dmc->dmc_fe_rolloff != DVB_ROLLOFF_NONE && dmc->dmc_fe_rolloff != DVB_ROLLOFF_AUTO) { ADD(dmc_fe_rolloff, ro, "0.35"); - } if (dmc->dmc_fe_delsys == DVB_SYS_DVBS2) { + } + if (dmc->dmc_fe_delsys == DVB_SYS_DVBS2) { if (flags & SATIP_SETUP_ROLLOFF_20) { satip_rtsp_add_val("ro", buf, 200); } else if (flags & SATIP_SETUP_ROLLOFF_25) { @@ -198,11 +174,9 @@ satip_rtsp_setup( http_client_t *hc, int src, int fe, satip_rtsp_add_val("ro", buf, 350); } } - if (dmc->dmc_fe_pilot != DVB_PILOT_NONE && - dmc->dmc_fe_pilot != DVB_PILOT_AUTO) { + if (dmc->dmc_fe_pilot != DVB_PILOT_NONE && dmc->dmc_fe_pilot != DVB_PILOT_AUTO) { ADD(dmc_fe_pilot, plts, "auto"); - } else if ((flags & SATIP_SETUP_PILOT_ON) != 0 && - dmc->dmc_fe_delsys == DVB_SYS_DVBS2) { + } else if ((flags & SATIP_SETUP_PILOT_ON) != 0 && dmc->dmc_fe_delsys == DVB_SYS_DVBS2) { strcat(buf, "&plts=on"); } if (dmc->dmc_fe_stream_id != DVB_NO_STREAM_ID_FILTER) { @@ -211,22 +185,20 @@ satip_rtsp_setup( http_client_t *hc, int src, int fe, satip_rtsp_add_ival("plsc", buf, dmc->dmc_fe_pls_code); } } else if (dmc->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_A || - dmc->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_C) { + dmc->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_C) { satip_rtsp_add_val("freq", buf, dmc->dmc_fe_freq / 1000); satip_rtsp_add_val("sr", buf, dmc->u.dmc_fe_qam.symbol_rate); ADD(dmc_fe_delsys, msys, "dvbc"); - if (dmc->dmc_fe_modulation != DVB_MOD_AUTO && - dmc->dmc_fe_modulation != DVB_MOD_NONE && + if (dmc->dmc_fe_modulation != DVB_MOD_AUTO && dmc->dmc_fe_modulation != DVB_MOD_NONE && dmc->dmc_fe_modulation != DVB_MOD_QAM_AUTO) ADD(dmc_fe_modulation, mtype, "64qam"); if (dmc->dmc_fe_stream_id != DVB_NO_STREAM_ID_FILTER) { satip_rtsp_add_ival("ds", buf, dmc->dmc_fe_data_slice & 0xff); satip_rtsp_add_ival("plp", buf, dmc->dmc_fe_stream_id & 0xff); } - if (dmc->u.dmc_fe_qam.fec_inner != DVB_FEC_NONE && - dmc->u.dmc_fe_qam.fec_inner != DVB_FEC_AUTO) + if (dmc->u.dmc_fe_qam.fec_inner != DVB_FEC_NONE && dmc->u.dmc_fe_qam.fec_inner != DVB_FEC_AUTO) /* note: OctopusNet device does not handle 'fec=auto' */ - ADD(u.dmc_fe_qam.fec_inner, fec, "auto"); + ADD(u.dmc_fe_qam.fec_inner, fec, "auto"); // for sat>ip compliance if (flags & SATIP_SETUP_SPECINV0) @@ -238,20 +210,17 @@ satip_rtsp_setup( http_client_t *hc, int src, int fe, satip_rtsp_add_val("freq", buf, dmc->dmc_fe_freq / 1000); ADD(dmc_fe_delsys, msys, "dvbcb"); - if (dmc->dmc_fe_modulation != DVB_MOD_AUTO && - dmc->dmc_fe_modulation != DVB_MOD_NONE && + if (dmc->dmc_fe_modulation != DVB_MOD_AUTO && dmc->dmc_fe_modulation != DVB_MOD_NONE && dmc->dmc_fe_modulation != DVB_MOD_QAM_AUTO) ADD(dmc_fe_modulation, mtype, "256qam"); - } else if (dmc->dmc_fe_delsys == DVB_SYS_DVBT || - dmc->dmc_fe_delsys == DVB_SYS_DVBT2) { + } else if (dmc->dmc_fe_delsys == DVB_SYS_DVBT || dmc->dmc_fe_delsys == DVB_SYS_DVBT2) { satip_rtsp_add_val("freq", buf, dmc->dmc_fe_freq / 1000); if (dmc->u.dmc_fe_ofdm.bandwidth != DVB_BANDWIDTH_AUTO && dmc->u.dmc_fe_ofdm.bandwidth != DVB_BANDWIDTH_NONE) satip_rtsp_add_val("bw", buf, dmc->u.dmc_fe_ofdm.bandwidth); ADD(dmc_fe_delsys, msys, "dvbt"); - if (dmc->dmc_fe_modulation != DVB_MOD_AUTO && - dmc->dmc_fe_modulation != DVB_MOD_NONE && + if (dmc->dmc_fe_modulation != DVB_MOD_AUTO && dmc->dmc_fe_modulation != DVB_MOD_NONE && dmc->dmc_fe_modulation != DVB_MOD_QAM_AUTO) ADD(dmc_fe_modulation, mtype, "64qam"); if (dmc->u.dmc_fe_ofdm.transmission_mode != DVB_TRANSMISSION_MODE_AUTO && @@ -266,16 +235,13 @@ satip_rtsp_setup( http_client_t *hc, int src, int fe, } else if (dmc->dmc_fe_delsys == DVB_SYS_ATSC) { satip_rtsp_add_val("freq", buf, dmc->dmc_fe_freq / 1000); ADD(dmc_fe_delsys, msys, "atsc"); - if (dmc->dmc_fe_modulation != DVB_MOD_AUTO && - dmc->dmc_fe_modulation != DVB_MOD_NONE && + if (dmc->dmc_fe_modulation != DVB_MOD_AUTO && dmc->dmc_fe_modulation != DVB_MOD_NONE && dmc->dmc_fe_modulation != DVB_MOD_QAM_AUTO) - ADD(dmc_fe_modulation, mtype, - dmc->dmc_fe_delsys == DVB_SYS_ATSC ? "8vsb" : "64qam"); + ADD(dmc_fe_modulation, mtype, dmc->dmc_fe_delsys == DVB_SYS_ATSC ? "8vsb" : "64qam"); } else if (dmc->dmc_fe_delsys == DVB_SYS_ISDBT) { satip_rtsp_add_val("freq", buf, dmc->dmc_fe_freq / 1000); ADD(dmc_fe_delsys, msys, "isdbt"); - if (dmc->dmc_fe_modulation != DVB_MOD_AUTO && - dmc->dmc_fe_modulation != DVB_MOD_NONE && + if (dmc->dmc_fe_modulation != DVB_MOD_AUTO && dmc->dmc_fe_modulation != DVB_MOD_NONE && dmc->dmc_fe_modulation != DVB_MOD_QAM_AUTO) ADD(dmc_fe_modulation, mtype, "64qam"); } @@ -286,8 +252,7 @@ satip_rtsp_setup( http_client_t *hc, int src, int fe, strcat(buf, ",21"); tvhtrace(LS_SATIP, "%04X: SETUP params - %s", hc->hc_id, buf); if (hc->hc_rtsp_stream_id >= 0) - snprintf(stream = _stream, sizeof(_stream), "/stream=%li", - hc->hc_rtsp_stream_id); + snprintf(stream = _stream, sizeof(_stream), "/stream=%li", hc->hc_rtsp_stream_id); if (flags & SATIP_SETUP_PLAY) return rtsp_play(hc, stream, buf); if (flags & SATIP_SETUP_TCP) @@ -296,11 +261,9 @@ satip_rtsp_setup( http_client_t *hc, int src, int fe, } static int -satip_rtsp_pids_split( http_client_t *hc, const char **pids, int size, - const char *s, int maxlen ) -{ - char *ptr; - int idx = 0; +satip_rtsp_pids_split(http_client_t* hc, const char** pids, int size, const char* s, int maxlen) { + char* ptr; + int idx = 0; if (s == NULL) return 0; @@ -309,13 +272,14 @@ satip_rtsp_pids_split( http_client_t *hc, const char **pids, int size, while (idx < size) { if (strlen(s) <= maxlen) goto _out; - ptr = (char *)s + maxlen - 1; - while (ptr != s && *ptr != ',') ptr--; + ptr = (char*)s + maxlen - 1; + while (ptr != s && *ptr != ',') + ptr--; if (ptr == s) abort(); pids[idx++] = s; - *ptr = '\0'; - s = ptr + 1; + *ptr = '\0'; + s = ptr + 1; } _out: if (*s == '\0') @@ -327,38 +291,36 @@ _out: return idx; } -static int -satip_rtsp_play0( http_client_t *hc, int index, const char *stream, const char *query ) -{ +static int satip_rtsp_play0(http_client_t* hc, int index, const char* stream, const char* query) { tvhtrace(LS_SATIP, "%04X: PLAY params[%d] - %s", hc->hc_id, index, query); return rtsp_play(hc, stream, query); } -int -satip_rtsp_play( http_client_t *hc, const char *pids, - const char *addpids, const char *delpids, - int max_pids_len, int weight ) -{ - char *stream = NULL; - char _stream[32], _w[16]; +int satip_rtsp_play(http_client_t* hc, + const char* pids, + const char* addpids, + const char* delpids, + int max_pids_len, + int weight) { + char* stream = NULL; + char _stream[32], _w[16]; const char *p[8], *add[8], *del[8]; - int pcnt, addcnt, delcnt; - int i, r = 0, index = 0; - char buf[max_pids_len + 32]; + int pcnt, addcnt, delcnt; + int i, r = 0, index = 0; + char buf[max_pids_len + 32]; if (max_pids_len < 32) max_pids_len = 32; - pcnt = satip_rtsp_pids_split(hc, p, ARRAY_SIZE(p), pids, max_pids_len); - addcnt = satip_rtsp_pids_split(hc, add, ARRAY_SIZE(add), addpids, max_pids_len); - delcnt = satip_rtsp_pids_split(hc, del, ARRAY_SIZE(del), delpids, max_pids_len); + pcnt = satip_rtsp_pids_split(hc, p, ARRAY_SIZE(p), pids, max_pids_len); + addcnt = satip_rtsp_pids_split(hc, add, ARRAY_SIZE(add), addpids, max_pids_len); + delcnt = satip_rtsp_pids_split(hc, del, ARRAY_SIZE(del), delpids, max_pids_len); if (pcnt == 0 && addcnt == 0 && delcnt == 0 && weight <= 0) return -EINVAL; if (hc->hc_rtsp_stream_id >= 0) - snprintf(stream = _stream, sizeof(_stream), "/stream=%li", - hc->hc_rtsp_stream_id); + snprintf(stream = _stream, sizeof(_stream), "/stream=%li", hc->hc_rtsp_stream_id); if (weight) snprintf(_w, sizeof(_w), "&tvhweight=%d", weight); @@ -385,8 +347,7 @@ satip_rtsp_play( http_client_t *hc, const char *pids, if (r < 0) return r; } - if (i == delcnt - 1 && addcnt > 0 && - strlen(del[i]) + strlen(add[0]) <= max_pids_len) { + if (i == delcnt - 1 && addcnt > 0 && strlen(del[i]) + strlen(add[0]) <= max_pids_len) { snprintf(buf, sizeof(buf), "delpids=%s&addpids=%s%s", del[i], add[0], _w); r = satip_rtsp_play0(hc, index++, stream, buf); if (r < 0) @@ -401,7 +362,7 @@ satip_rtsp_play( http_client_t *hc, const char *pids, } i = 0; } - for ( ; i < addcnt; i++) { + for (; i < addcnt; i++) { snprintf(buf, sizeof(buf), "addpids=%s%s", add[i], _w); r = satip_rtsp_play0(hc, index++, stream, buf); if (r < 0) diff --git a/src/input/mpegts/satip/satip_satconf.c b/src/input/mpegts/satip/satip_satconf.c index 8560ef9b9..f04e3ef37 100644 --- a/src/input/mpegts/satip/satip_satconf.c +++ b/src/input/mpegts/satip/satip_satconf.c @@ -25,27 +25,22 @@ * Frontend callbacks * *************************************************************************/ -static const void * -satip_satconf_class_active_get ( void *obj ) -{ - static int active; - satip_satconf_t *sfc = obj; - active = 0; - if (*(int *)mpegts_input_class_active_get(sfc->sfc_lfe)) +static const void* satip_satconf_class_active_get(void* obj) { + static int active; + satip_satconf_t* sfc = obj; + active = 0; + if (*(int*)mpegts_input_class_active_get(sfc->sfc_lfe)) active = sfc->sfc_enabled; return &active; } -static satip_satconf_t * -satip_satconf_find_ele( satip_frontend_t *lfe, mpegts_mux_t *mux ) -{ - satip_satconf_t *sfc; - satip_frontend_t *lfe2; +static satip_satconf_t* satip_satconf_find_ele(satip_frontend_t* lfe, mpegts_mux_t* mux) { + satip_satconf_t* sfc; + satip_frontend_t* lfe2; if (lfe->sf_master) { - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) - if (lfe2->sf_number != lfe->sf_number && - lfe2->sf_number == lfe->sf_master && + TAILQ_FOREACH (lfe2, &lfe->sf_device->sd_frontends, sf_link) + if (lfe2->sf_number != lfe->sf_number && lfe2->sf_number == lfe->sf_master && lfe2->sf_master == 0) { lfe = lfe2; goto found; @@ -53,49 +48,34 @@ satip_satconf_find_ele( satip_frontend_t *lfe, mpegts_mux_t *mux ) return 0; } found: - TAILQ_FOREACH(sfc, &lfe->sf_satconf, sfc_link) { + TAILQ_FOREACH (sfc, &lfe->sf_satconf, sfc_link) { if (idnode_set_exists(sfc->sfc_networks, &mux->mm_network->mn_id)) return sfc; } return NULL; } -int -satip_satconf_get_priority - ( satip_frontend_t *lfe, mpegts_mux_t *mm ) -{ - satip_satconf_t *sfc = satip_satconf_find_ele(lfe, mm); +int satip_satconf_get_priority(satip_frontend_t* lfe, mpegts_mux_t* mm) { + satip_satconf_t* sfc = satip_satconf_find_ele(lfe, mm); return sfc ? sfc->sfc_priority : 0; } -int -satip_satconf_get_grace - ( satip_frontend_t *lfe, mpegts_mux_t *mm ) -{ - satip_satconf_t *sfc = satip_satconf_find_ele(lfe, mm); +int satip_satconf_get_grace(satip_frontend_t* lfe, mpegts_mux_t* mm) { + satip_satconf_t* sfc = satip_satconf_find_ele(lfe, mm); return sfc ? sfc->sfc_grace : 0; } -static int -satip_satconf_master_or_slave - ( satip_frontend_t *lfe1, satip_frontend_t *lfe2 ) -{ - return lfe1->sf_number == lfe2->sf_master || - lfe2->sf_number == lfe1->sf_master; +static int satip_satconf_master_or_slave(satip_frontend_t* lfe1, satip_frontend_t* lfe2) { + return lfe1->sf_number == lfe2->sf_master || lfe2->sf_number == lfe1->sf_master; } -static int -satip_satconf_in_network_group - ( satip_frontend_t *lfe, int network_group, idnode_t *mn ) -{ - satip_satconf_t *sfc; +static int satip_satconf_in_network_group(satip_frontend_t* lfe, int network_group, idnode_t* mn) { + satip_satconf_t* sfc; - TAILQ_FOREACH(sfc, &lfe->sf_satconf, sfc_link) { + TAILQ_FOREACH (sfc, &lfe->sf_satconf, sfc_link) { if (sfc->sfc_position != lfe->sf_position) continue; - if (network_group > 0 && - sfc->sfc_network_group > 0 && - sfc->sfc_network_group == network_group) + if (network_group > 0 && sfc->sfc_network_group > 0 && sfc->sfc_network_group == network_group) break; else if (idnode_set_exists(sfc->sfc_networks, mn)) break; @@ -103,29 +83,27 @@ satip_satconf_in_network_group return sfc != NULL; } -static int -satip_satconf_hash ( mpegts_mux_t *mm, int position ) -{ - dvb_mux_conf_t *mc = &((dvb_mux_t *)mm)->lm_tuning; +static int satip_satconf_hash(mpegts_mux_t* mm, int position) { + dvb_mux_conf_t* mc = &((dvb_mux_t*)mm)->lm_tuning; assert(position <= 0x7fff); - return 1 | (mc->dmc_fe_freq > 11700000 ? 2 : 0) | - ((int)mc->u.dmc_fe_qpsk.polarisation << 8) | - ((position & 0xffff) << 16); + return 1 | (mc->dmc_fe_freq > 11700000 ? 2 : 0) | ((int)mc->u.dmc_fe_qpsk.polarisation << 8) | + ((position & 0xffff) << 16); } -static int -satip_satconf_check_limits - ( satip_frontend_t *lfe, satip_satconf_t *sfc, mpegts_mux_t *mm, - int flags, int weight, int manage ) -{ +static int satip_satconf_check_limits(satip_frontend_t* lfe, + satip_satconf_t* sfc, + mpegts_mux_t* mm, + int flags, + int weight, + int manage) { satip_frontend_t *lfe2, *lowest_lfe; - mpegts_mux_t *mm2; - mpegts_input_t *mi2; - idnode_t *mn = &mm->mm_network->mn_id; - int count, size, lowest, w2, r, i, limit, *hashes; + mpegts_mux_t* mm2; + mpegts_input_t* mi2; + idnode_t* mn = &mm->mm_network->mn_id; + int count, size, lowest, w2, r, i, limit, *hashes; size = 0; - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) + TAILQ_FOREACH (lfe2, &lfe->sf_device->sd_frontends, sf_link) size++; hashes = alloca(size * sizeof(int)); @@ -133,14 +111,14 @@ satip_satconf_check_limits retry: memset(hashes, 0, size * sizeof(int)); - lowest = INT_MAX; + lowest = INT_MAX; lowest_lfe = NULL; /* add wanted mux to hashes */ hashes[0] = satip_satconf_hash(mm, sfc->sfc_position); - count = 1; + count = 1; - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) { + TAILQ_FOREACH (lfe2, &lfe->sf_device->sd_frontends, sf_link) { if (lfe == lfe2 || !lfe2->sf_running || lfe2->sf_type != DVB_TYPE_S) continue; if (sfc->sfc_network_limit) { @@ -152,7 +130,7 @@ retry: } if (!manage && weight <= 0) continue; - mi2 = (mpegts_input_t *)lfe2; + mi2 = (mpegts_input_t*)lfe2; mm2 = lfe2->sf_req->sf_mmi->mmi_mux; w2 = -1; if (weight > 0 || manage) @@ -160,7 +138,7 @@ retry: if (!manage && w2 < weight) continue; if (manage && w2 < lowest) { - lowest = w2; + lowest = w2; lowest_lfe = lfe2; } r = satip_satconf_hash(mm2, lfe2->sf_position); @@ -185,12 +163,13 @@ retry: return 0; } -satip_satconf_t * -satip_satconf_get_position - ( satip_frontend_t *lfe, mpegts_mux_t *mm, int *hash, - int check, int flags, int weight ) -{ - satip_satconf_t *sfc; +satip_satconf_t* satip_satconf_get_position(satip_frontend_t* lfe, + mpegts_mux_t* mm, + int* hash, + int check, + int flags, + int weight) { + satip_satconf_t* sfc; sfc = satip_satconf_find_ele(lfe, mm); if (sfc && sfc->sfc_enabled) { if (hash) @@ -217,43 +196,41 @@ satip_satconf_get_position * Class definition * *************************************************************************/ -static void -satip_satconf_sanity_check( satip_frontend_t *lfe ) -{ - satip_satconf_t *sfc; +static void satip_satconf_sanity_check(satip_frontend_t* lfe) { + satip_satconf_t* sfc; - TAILQ_FOREACH(sfc, &lfe->sf_satconf, sfc_link) { + TAILQ_FOREACH (sfc, &lfe->sf_satconf, sfc_link) { if (sfc->sfc_network_limit) { if (lfe->sf_master) { - tvherror(LS_SATIP, "%s: unable to combine master/slave with network limiter, " - "disabling master", lfe->mi_name); + tvherror(LS_SATIP, + "%s: unable to combine master/slave with network limiter, " + "disabling master", + lfe->mi_name); lfe->sf_master = 0; } } } } -static const void * -satip_satconf_class_network_get( void *o ) -{ - satip_satconf_t *sfc = o; +static const void* satip_satconf_class_network_get(void* o) { + satip_satconf_t* sfc = o; return idnode_set_as_htsmsg(sfc->sfc_networks); } -static int -satip_satconf_class_network_set( void *o, const void *p ) -{ - satip_satconf_t *sfc = o; - const htsmsg_t *msg = p; - mpegts_network_t *mn; - idnode_set_t *n = idnode_set_create(0); - htsmsg_field_t *f; - const char *str; - int i, save; +static int satip_satconf_class_network_set(void* o, const void* p) { + satip_satconf_t* sfc = o; + const htsmsg_t* msg = p; + mpegts_network_t* mn; + idnode_set_t* n = idnode_set_create(0); + htsmsg_field_t* f; + const char* str; + int i, save; HTSMSG_FOREACH(f, msg) { - if (!(str = htsmsg_field_get_str(f))) continue; - if (!(mn = mpegts_network_find(str))) continue; + if (!(str = htsmsg_field_get_str(f))) + continue; + if (!(mn = mpegts_network_find(str))) + continue; idnode_set_add(n, &mn->mn_id, NULL, NULL); } @@ -270,18 +247,17 @@ satip_satconf_class_network_set( void *o, const void *p ) idnode_set_free(sfc->sfc_networks); sfc->sfc_networks = n; /* update the input (frontend) network list */ - htsmsg_t *l = htsmsg_create_list(); + htsmsg_t* l = htsmsg_create_list(); satip_frontend_t *lfe = sfc->sfc_lfe, *lfe2; - satip_satconf_t *sfc2; - TAILQ_FOREACH(sfc2, &lfe->sf_satconf, sfc_link) { + satip_satconf_t* sfc2; + TAILQ_FOREACH (sfc2, &lfe->sf_satconf, sfc_link) { for (i = 0; i < sfc2->sfc_networks->is_count; i++) htsmsg_add_uuid(l, NULL, &sfc2->sfc_networks->is_array[i]->in_uuid); } mpegts_input_class_network_set(lfe, l); /* update the slave tuners, too */ - TAILQ_FOREACH(lfe2, &lfe->sf_device->sd_frontends, sf_link) - if (lfe2->sf_number != lfe->sf_number && - lfe2->sf_master == lfe->sf_number) + TAILQ_FOREACH (lfe2, &lfe->sf_device->sd_frontends, sf_link) + if (lfe2->sf_number != lfe->sf_number && lfe2->sf_master == lfe->sf_number) mpegts_input_class_network_set(lfe2, l); htsmsg_destroy(l); } else { @@ -290,153 +266,134 @@ satip_satconf_class_network_set( void *o, const void *p ) return save; } -static htsmsg_t * -satip_satconf_class_network_enum( void *o, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_t *p = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "idnode/load"); +static htsmsg_t* satip_satconf_class_network_enum(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_t* p = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "idnode/load"); htsmsg_add_str(m, "event", "mpegts_network"); - htsmsg_add_u32(p, "enum", 1); + htsmsg_add_u32(p, "enum", 1); htsmsg_add_str(p, "class", dvb_network_dvbs_class.ic_class); htsmsg_add_msg(m, "params", p); return m; } -static char * -satip_satconf_class_network_rend( void *o, const char *lang ) -{ - satip_satconf_t *sfc = o; - htsmsg_t *l = idnode_set_as_htsmsg(sfc->sfc_networks); - char *str = htsmsg_list_2_csv(l, ',', 1); +static char* satip_satconf_class_network_rend(void* o, const char* lang) { + satip_satconf_t* sfc = o; + htsmsg_t* l = idnode_set_as_htsmsg(sfc->sfc_networks); + char* str = htsmsg_list_2_csv(l, ',', 1); htsmsg_destroy(l); return str; } -static void -satip_satconf_class_get_title - ( idnode_t *o, const char *lang, char *dst, size_t size ) -{ - snprintf(dst, size, "%s", ((satip_satconf_t *)o)->sfc_name); +static void satip_satconf_class_get_title(idnode_t* o, const char* lang, char* dst, size_t size) { + snprintf(dst, size, "%s", ((satip_satconf_t*)o)->sfc_name); } -static void -satip_satconf_class_changed ( idnode_t *in ) -{ - satip_satconf_t *sfc = (satip_satconf_t*)in; +static void satip_satconf_class_changed(idnode_t* in) { + satip_satconf_t* sfc = (satip_satconf_t*)in; satip_satconf_sanity_check(sfc->sfc_lfe); satip_device_changed(sfc->sfc_lfe->sf_device); } CLASS_DOC(satip_satconf) -const idclass_t satip_satconf_class = -{ - .ic_class = "satip_satconf", - .ic_caption = N_("SAT>IP Satellite Configuration"), - .ic_event = "satip_satconf", - .ic_doc = tvh_doc_satip_satconf_class, - .ic_get_title = satip_satconf_class_get_title, - .ic_changed = satip_satconf_class_changed, - .ic_properties = (const property_t[]) { - { - .type = PT_BOOL, - .id = "active", - .name = N_("Active"), - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, - .get = satip_satconf_class_active_get, - }, - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable or disable this configuration."), - .off = offsetof(satip_satconf_t, sfc_enabled), - }, - { - .type = PT_STR, - .id = "displayname", - .name = N_("Name"), - .desc = N_("Set the display name."), - .off = offsetof(satip_satconf_t, sfc_name), - .notify = idnode_notify_title_changed_lang, - }, - { - .type = PT_INT, - .id = "priority", - .name = N_("Priority"), - .desc = N_("Set the priority of this configuration."), - .off = offsetof(satip_satconf_t, sfc_priority), - .opts = PO_ADVANCED, - }, - { - .type = PT_INT, - .id = "timeout", - .name = N_("Timeout (seconds)"), - .desc = N_("Number of seconds to wait before timing out."), - .off = offsetof(satip_satconf_t, sfc_grace), - .opts = PO_ADVANCED, - .def.i = 10 - }, - { - .type = PT_INT, - .id = "position", - .name = N_("Position"), - .desc = N_("Position of the input."), - .off = offsetof(satip_satconf_t, sfc_position), - .def.i = 1, - .opts = PO_RDONLY | PO_ADVANCED, - }, - { - .type = PT_INT, - .id = "network_limit", - .name = N_("Network limit per group"), - .desc = N_("Concurrent input limit per network group " - "for satellite SAT>IP tuners."), - .opts = PO_EXPERT, - .off = offsetof(satip_satconf_t, sfc_network_limit), - }, - { - .type = PT_INT, - .id = "network_group", - .name = N_("Network group"), - .desc = N_("Define network group to limit network usage (value 1-1000). " - "All SAT>IP positions in the same group must have " - "identical network limit, otherwise the limiting " - "will not work correctly."), - .opts = PO_EXPERT, - .off = offsetof(satip_satconf_t, sfc_network_group), - }, - { - .type = PT_STR, - .id = "networks", - .name = N_("Networks"), - .desc = N_("The networks using this configuration."), - .islist = 1, - .set = satip_satconf_class_network_set, - .get = satip_satconf_class_network_get, - .list = satip_satconf_class_network_enum, - .rend = satip_satconf_class_network_rend, - }, - {} - } -}; +const idclass_t satip_satconf_class = {.ic_class = "satip_satconf", + .ic_caption = N_("SAT>IP Satellite Configuration"), + .ic_event = "satip_satconf", + .ic_doc = tvh_doc_satip_satconf_class, + .ic_get_title = satip_satconf_class_get_title, + .ic_changed = satip_satconf_class_changed, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "active", + .name = N_("Active"), + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, + .get = satip_satconf_class_active_get, + }, + { + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable or disable this configuration."), + .off = offsetof(satip_satconf_t, sfc_enabled), + }, + { + .type = PT_STR, + .id = "displayname", + .name = N_("Name"), + .desc = N_("Set the display name."), + .off = offsetof(satip_satconf_t, sfc_name), + .notify = idnode_notify_title_changed_lang, + }, + { + .type = PT_INT, + .id = "priority", + .name = N_("Priority"), + .desc = N_("Set the priority of this configuration."), + .off = offsetof(satip_satconf_t, sfc_priority), + .opts = PO_ADVANCED, + }, + {.type = PT_INT, + .id = "timeout", + .name = N_("Timeout (seconds)"), + .desc = N_("Number of seconds to wait before timing out."), + .off = offsetof(satip_satconf_t, sfc_grace), + .opts = PO_ADVANCED, + .def.i = 10}, + { + .type = PT_INT, + .id = "position", + .name = N_("Position"), + .desc = N_("Position of the input."), + .off = offsetof(satip_satconf_t, sfc_position), + .def.i = 1, + .opts = PO_RDONLY | PO_ADVANCED, + }, + { + .type = PT_INT, + .id = "network_limit", + .name = N_("Network limit per group"), + .desc = N_("Concurrent input limit per network group " + "for satellite SAT>IP tuners."), + .opts = PO_EXPERT, + .off = offsetof(satip_satconf_t, sfc_network_limit), + }, + { + .type = PT_INT, + .id = "network_group", + .name = N_("Network group"), + .desc = N_("Define network group to limit network usage (value 1-1000). " + "All SAT>IP positions in the same group must have " + "identical network limit, otherwise the limiting " + "will not work correctly."), + .opts = PO_EXPERT, + .off = offsetof(satip_satconf_t, sfc_network_group), + }, + { + .type = PT_STR, + .id = "networks", + .name = N_("Networks"), + .desc = N_("The networks using this configuration."), + .islist = 1, + .set = satip_satconf_class_network_set, + .get = satip_satconf_class_network_get, + .list = satip_satconf_class_network_enum, + .rend = satip_satconf_class_network_rend, + }, + {}}}; /* ************************************************************************** * Creation/Config * *************************************************************************/ -static satip_satconf_t * -satip_satconf_create0 - ( satip_frontend_t *lfe, htsmsg_t *conf, int position ) -{ - static const char *tbl[] = {" (AA)", " (AB)", " (BA)", " (BB)"}; - const char *uuid = NULL; - satip_satconf_t *sfc = calloc(1, sizeof(*sfc)); - char buf[32]; - const char *s; +static satip_satconf_t* satip_satconf_create0(satip_frontend_t* lfe, htsmsg_t* conf, int position) { + static const char* tbl[] = {" (AA)", " (AB)", " (BA)", " (BB)"}; + const char* uuid = NULL; + satip_satconf_t* sfc = calloc(1, sizeof(*sfc)); + char buf[32]; + const char* s; /* defaults */ sfc->sfc_priority = 1; @@ -464,34 +421,29 @@ satip_satconf_create0 return sfc; } -void -satip_satconf_create - ( satip_frontend_t *lfe, htsmsg_t *conf, int def_positions ) -{ - htsmsg_t *l, *e; - htsmsg_field_t *f; - int pos = 0; +void satip_satconf_create(satip_frontend_t* lfe, htsmsg_t* conf, int def_positions) { + htsmsg_t * l, *e; + htsmsg_field_t* f; + int pos = 0; if (conf && (l = htsmsg_get_list(conf, "satconf"))) { satip_satconf_destroy(lfe); HTSMSG_FOREACH(f, l) { - if (!(e = htsmsg_field_get_map(f))) continue; + if (!(e = htsmsg_field_get_map(f))) + continue; if (satip_satconf_create0(lfe, e, pos++)) lfe->sf_positions++; } } if (lfe->sf_positions == 0) - for ( ; lfe->sf_positions < def_positions; lfe->sf_positions++) + for (; lfe->sf_positions < def_positions; lfe->sf_positions++) satip_satconf_create0(lfe, NULL, lfe->sf_positions); satip_satconf_sanity_check(lfe); } -static void -satip_satconf_destroy0 - ( satip_satconf_t *sfc ) -{ - satip_frontend_t *lfe = sfc->sfc_lfe; +static void satip_satconf_destroy0(satip_satconf_t* sfc) { + satip_frontend_t* lfe = sfc->sfc_lfe; TAILQ_REMOVE(&lfe->sf_satconf, sfc, sfc_link); idnode_save_check(&sfc->sfc_id, 1); idnode_unlink(&sfc->sfc_id); @@ -500,12 +452,9 @@ satip_satconf_destroy0 free(sfc); } -void -satip_satconf_updated_positions - ( satip_frontend_t *lfe ) -{ +void satip_satconf_updated_positions(satip_frontend_t* lfe) { satip_satconf_t *sfc, *sfc_old; - int i; + int i; sfc = TAILQ_FIRST(&lfe->sf_satconf); for (i = 0; i < lfe->sf_positions; i++) { @@ -513,32 +462,28 @@ satip_satconf_updated_positions satip_satconf_create0(lfe, NULL, i); sfc = sfc ? TAILQ_NEXT(sfc, sfc_link) : NULL; } - while (sfc) { + while (sfc) { sfc_old = sfc; - sfc = TAILQ_NEXT(sfc, sfc_link); + sfc = TAILQ_NEXT(sfc, sfc_link); satip_satconf_destroy0(sfc_old); } satip_satconf_sanity_check(lfe); } -void -satip_satconf_destroy ( satip_frontend_t *lfe ) -{ - satip_satconf_t *sfc; +void satip_satconf_destroy(satip_frontend_t* lfe) { + satip_satconf_t* sfc; while ((sfc = TAILQ_FIRST(&lfe->sf_satconf)) != NULL) satip_satconf_destroy0(sfc); lfe->sf_positions = 0; } -void -satip_satconf_save ( satip_frontend_t *lfe, htsmsg_t *m ) -{ - satip_satconf_t *sfc; - htsmsg_t *l, *e; +void satip_satconf_save(satip_frontend_t* lfe, htsmsg_t* m) { + satip_satconf_t* sfc; + htsmsg_t * l, *e; l = htsmsg_create_list(); - TAILQ_FOREACH(sfc, &lfe->sf_satconf, sfc_link) { + TAILQ_FOREACH (sfc, &lfe->sf_satconf, sfc_link) { e = htsmsg_create_map(); idnode_save(&sfc->sfc_id, e); htsmsg_add_msg(l, NULL, e); @@ -546,7 +491,6 @@ satip_satconf_save ( satip_frontend_t *lfe, htsmsg_t *m ) htsmsg_add_msg(m, "satconf", l); } - /****************************************************************************** * Editor Configuration * diff --git a/src/input/mpegts/scanfile.c b/src/input/mpegts/scanfile.c index 8a16c44ff..3b6ecf2c3 100644 --- a/src/input/mpegts/scanfile.c +++ b/src/input/mpegts/scanfile.c @@ -35,90 +35,85 @@ #include #include -#define SCANFILE_LIMIT (64*1024*1024) - -static const char *scanfile_region_types[][2] = { - { "dvb-s", "dvbs" }, - { "dvb-t", "dvbt" }, - { "dvb-c", "dvbc" }, - { "atsc-t", NULL }, - { "atsc-c", NULL }, - { "isdb-t", NULL } -}; +#define SCANFILE_LIMIT (64 * 1024 * 1024) -#define REGIONS ARRAY_SIZE(scanfile_region_types) +static const char* scanfile_region_types[][2] = {{"dvb-s", "dvbs"}, + {"dvb-t", "dvbt"}, + {"dvb-c", "dvbc"}, + {"atsc-t", NULL}, + {"atsc-c", NULL}, + {"isdb-t", NULL}}; -static scanfile_region_list_t *scanfile_regions; -static scanfile_region_list_t *scanfile_regions_load; -static int64_t scanfile_total_load; -static memoryinfo_t scanfile_memoryinfo = { .my_name = "Scan files" }; +#define REGIONS ARRAY_SIZE(scanfile_region_types) -static void scanfile_done_muxes( scanfile_network_t *net ); +static scanfile_region_list_t* scanfile_regions; +static scanfile_region_list_t* scanfile_regions_load; +static int64_t scanfile_total_load; +static memoryinfo_t scanfile_memoryinfo = {.my_name = "Scan files"}; +static void scanfile_done_muxes(scanfile_network_t* net); /* ************************************************************************** * Country codes * *************************************************************************/ static const struct { - const char *code; - const char *name; + const char* code; + const char* name; } tldlist[] = { - {"auto", "--Generic--"}, - {"ad", "Andorra"}, - {"ar", "Argentina"}, - {"at", "Austria"}, - {"au", "Australia"}, - {"ax", "Aland Islands"}, - {"be", "Belgium"}, - {"bg", "Bulgaria"}, - {"br", "Brazil"}, - {"ca", "Canada"}, - {"ch", "Switzerland"}, - {"cz", "Czech Republic"}, - {"de", "Germany"}, - {"dk", "Denmark"}, - {"ee", "Estonia"}, - {"es", "Spain"}, - {"fi", "Finland"}, - {"fr", "France"}, - {"gr", "Greece"}, - {"hk", "Hong Kong"}, - {"hr", "Croatia"}, - {"hu", "Hungary"}, - {"ie", "Ireland"}, - {"il", "Israel"}, - {"ir", "Iran"}, - {"is", "Iceland"}, - {"it", "Italy"}, - {"lt", "Lithuania"}, - {"lu", "Luxembourg"}, - {"lv", "Latvia"}, - {"nl", "Netherlands"}, - {"no", "Norway"}, - {"nz", "New Zealand"}, - {"pl", "Poland"}, - {"pt", "Portugal"}, - {"ro", "Romania"}, - {"ru", "Russia"}, - {"se", "Sweden"}, - {"si", "Slovenia"}, - {"sk", "Slovakia"}, - {"tw", "Taiwan"}, - {"ua", "Ukraine"}, - {"ug", "Uganda"}, - {"uk", "United Kingdom"}, - {"us", "United States"}, - {"vn", "Vietnam"}, - {"za", "South Africa"}, + {"auto", "--Generic--"}, + {"ad", "Andorra"}, + {"ar", "Argentina"}, + {"at", "Austria"}, + {"au", "Australia"}, + {"ax", "Aland Islands"}, + {"be", "Belgium"}, + {"bg", "Bulgaria"}, + {"br", "Brazil"}, + {"ca", "Canada"}, + {"ch", "Switzerland"}, + {"cz", "Czech Republic"}, + {"de", "Germany"}, + {"dk", "Denmark"}, + {"ee", "Estonia"}, + {"es", "Spain"}, + {"fi", "Finland"}, + {"fr", "France"}, + {"gr", "Greece"}, + {"hk", "Hong Kong"}, + {"hr", "Croatia"}, + {"hu", "Hungary"}, + {"ie", "Ireland"}, + {"il", "Israel"}, + {"ir", "Iran"}, + {"is", "Iceland"}, + {"it", "Italy"}, + {"lt", "Lithuania"}, + {"lu", "Luxembourg"}, + {"lv", "Latvia"}, + {"nl", "Netherlands"}, + {"no", "Norway"}, + {"nz", "New Zealand"}, + {"pl", "Poland"}, + {"pt", "Portugal"}, + {"ro", "Romania"}, + {"ru", "Russia"}, + {"se", "Sweden"}, + {"si", "Slovenia"}, + {"sk", "Slovakia"}, + {"tw", "Taiwan"}, + {"ua", "Ukraine"}, + {"ug", "Uganda"}, + {"uk", "United Kingdom"}, + {"us", "United States"}, + {"vn", "Vietnam"}, + {"za", "South Africa"}, }; -static const char * -tldcode2longname(const char *tld) -{ +static const char* tldcode2longname(const char* tld) { int i; - for(i = 0; i < sizeof(tldlist) / sizeof(tldlist[0]); i++) - if(!strcmp(tld, tldlist[i].code)) + for (i = 0; i < sizeof(tldlist) / sizeof(tldlist[0]); i++) + if (!strcmp(tld, tldlist[i].code)) return tldlist[i].name; return tld; } @@ -127,65 +122,97 @@ tldcode2longname(const char *tld) * Type specific parsers * *************************************************************************/ -static int -scanfile_load_atsc ( dvb_mux_conf_t *mux, const char *line ) -{ +static int scanfile_load_atsc(dvb_mux_conf_t* mux, const char* line) { char qam[20]; - int r; + int r; dvb_mux_conf_init(NULL, mux, DVB_SYS_ATSC); r = sscanf(line, "%u %s", &mux->dmc_fe_freq, qam); - if (r != 2) return 1; - if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) return 1; + if (r != 2) + return 1; + if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) + return 1; return 0; } -static int -scanfile_load_dvbt ( dvb_mux_conf_t *mux, const char *line ) -{ +static int scanfile_load_dvbt(dvb_mux_conf_t* mux, const char* line) { char bw[20], fec[20], fec2[20], qam[20], mode[20], guard[20], hier[20]; - int r; + int r; if (*line == '2') { unsigned int system_id; dvb_mux_conf_init(NULL, mux, DVB_SYS_DVBT2); - r = sscanf(line+1, "%u %s", &mux->dmc_fe_stream_id, bw); + r = sscanf(line + 1, "%u %s", &mux->dmc_fe_stream_id, bw); if (r == 2 && mux->dmc_fe_stream_id < 1000 && strstr(bw, "MHz") == 0) { - r = sscanf(line+1, "%u %u %u %10s %10s %10s %10s %10s %10s %10s", - &mux->dmc_fe_stream_id, &system_id, &mux->dmc_fe_freq, bw, fec, fec2, qam, - mode, guard, hier); - if(r != 10) return 1; + r = sscanf(line + 1, + "%u %u %u %10s %10s %10s %10s %10s %10s %10s", + &mux->dmc_fe_stream_id, + &system_id, + &mux->dmc_fe_freq, + bw, + fec, + fec2, + qam, + mode, + guard, + hier); + if (r != 10) + return 1; } else { - r = sscanf(line+1, "%u %10s %10s %10s %10s %10s %10s %10s %u", - &mux->dmc_fe_freq, bw, fec, fec2, qam, - mode, guard, hier, &mux->dmc_fe_stream_id); - if(r == 8) mux->dmc_fe_stream_id = DVB_NO_STREAM_ID_FILTER; else - if(r != 9) return 1; + r = sscanf(line + 1, + "%u %10s %10s %10s %10s %10s %10s %10s %u", + &mux->dmc_fe_freq, + bw, + fec, + fec2, + qam, + mode, + guard, + hier, + &mux->dmc_fe_stream_id); + if (r == 8) + mux->dmc_fe_stream_id = DVB_NO_STREAM_ID_FILTER; + else if (r != 9) + return 1; } } else { dvb_mux_conf_init(NULL, mux, DVB_SYS_DVBT); - r = sscanf(line, "%u %10s %10s %10s %10s %10s %10s %10s", - &mux->dmc_fe_freq, bw, fec, fec2, qam, mode, guard, hier); - if(r != 8) return 1; + r = sscanf(line, + "%u %10s %10s %10s %10s %10s %10s %10s", + &mux->dmc_fe_freq, + bw, + fec, + fec2, + qam, + mode, + guard, + hier); + if (r != 8) + return 1; } - if ((mux->u.dmc_fe_ofdm.bandwidth = dvb_str2bw(bw)) == -1) return 1; - if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) return 1; - if ((mux->u.dmc_fe_ofdm.code_rate_HP = dvb_str2fec(fec)) == -1) return 1; - if ((mux->u.dmc_fe_ofdm.code_rate_LP = dvb_str2fec(fec2)) == -1) return 1; - if ((mux->u.dmc_fe_ofdm.transmission_mode = dvb_str2mode(mode)) == -1) return 1; - if ((mux->u.dmc_fe_ofdm.guard_interval = dvb_str2guard(guard)) == -1) return 1; - if ((mux->u.dmc_fe_ofdm.hierarchy_information = dvb_str2hier(hier)) == -1) return 1; + if ((mux->u.dmc_fe_ofdm.bandwidth = dvb_str2bw(bw)) == -1) + return 1; + if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) + return 1; + if ((mux->u.dmc_fe_ofdm.code_rate_HP = dvb_str2fec(fec)) == -1) + return 1; + if ((mux->u.dmc_fe_ofdm.code_rate_LP = dvb_str2fec(fec2)) == -1) + return 1; + if ((mux->u.dmc_fe_ofdm.transmission_mode = dvb_str2mode(mode)) == -1) + return 1; + if ((mux->u.dmc_fe_ofdm.guard_interval = dvb_str2guard(guard)) == -1) + return 1; + if ((mux->u.dmc_fe_ofdm.hierarchy_information = dvb_str2hier(hier)) == -1) + return 1; return 0; } -static int -scanfile_load_dvbs ( dvb_mux_conf_t *mux, const char *line ) -{ +static int scanfile_load_dvbs(dvb_mux_conf_t* mux, const char* line) { char pol[20], fec[20], qam[20], rolloff[20]; - int r, v2 = 0; + int r, v2 = 0; if (*line == '2') { v2 = 2; @@ -194,19 +221,35 @@ scanfile_load_dvbs ( dvb_mux_conf_t *mux, const char *line ) dvb_mux_conf_init(NULL, mux, v2 ? DVB_SYS_DVBS2 : DVB_SYS_DVBS); - r = sscanf(line, "%u %s %u %s %s %s %d %d %d", - &mux->dmc_fe_freq, pol, &mux->u.dmc_fe_qpsk.symbol_rate, - fec, rolloff, qam, &mux->dmc_fe_stream_id, &mux->dmc_fe_pls_code, (int*)&mux->dmc_fe_pls_mode); - if (r < (4+v2)) return 1; + r = sscanf(line, + "%u %s %u %s %s %s %d %d %d", + &mux->dmc_fe_freq, + pol, + &mux->u.dmc_fe_qpsk.symbol_rate, + fec, + rolloff, + qam, + &mux->dmc_fe_stream_id, + &mux->dmc_fe_pls_code, + (int*)&mux->dmc_fe_pls_mode); + if (r < (4 + v2)) + return 1; - if ((mux->u.dmc_fe_qpsk.polarisation = dvb_str2pol(pol)) == -1) return 1; - if ((mux->u.dmc_fe_qpsk.fec_inner = dvb_str2fec(fec)) == -1) return 1; + if ((mux->u.dmc_fe_qpsk.polarisation = dvb_str2pol(pol)) == -1) + return 1; + if ((mux->u.dmc_fe_qpsk.fec_inner = dvb_str2fec(fec)) == -1) + return 1; if (v2) { - if ((mux->dmc_fe_rolloff = dvb_str2rolloff(rolloff)) == -1) return 1; - if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) return 1; - if (r < (4+v2+1)) mux->dmc_fe_stream_id = DVB_NO_STREAM_ID_FILTER; - if (r < (4+v2+2)) mux->dmc_fe_pls_code = 1; - if (r < (4+v2+3)) mux->dmc_fe_pls_mode = 0; + if ((mux->dmc_fe_rolloff = dvb_str2rolloff(rolloff)) == -1) + return 1; + if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) + return 1; + if (r < (4 + v2 + 1)) + mux->dmc_fe_stream_id = DVB_NO_STREAM_ID_FILTER; + if (r < (4 + v2 + 2)) + mux->dmc_fe_pls_code = 1; + if (r < (4 + v2 + 3)) + mux->dmc_fe_pls_mode = 0; } else { mux->dmc_fe_rolloff = DVB_ROLLOFF_35; mux->dmc_fe_modulation = DVB_MOD_QPSK; @@ -215,24 +258,23 @@ scanfile_load_dvbs ( dvb_mux_conf_t *mux, const char *line ) return 0; } -static int -scanfile_load_dvbc ( dvb_mux_conf_t *mux, const char *line ) -{ +static int scanfile_load_dvbc(dvb_mux_conf_t* mux, const char* line) { char fec[20], qam[20]; - int r; + int r; - r = sscanf(line, "%u %u %s %s", - &mux->dmc_fe_freq, &mux->u.dmc_fe_qam.symbol_rate, fec, qam); - if(r != 4) return 1; + r = sscanf(line, "%u %u %s %s", &mux->dmc_fe_freq, &mux->u.dmc_fe_qam.symbol_rate, fec, qam); + if (r != 4) + return 1; dvb_mux_conf_init(NULL, mux, DVB_SYS_DVBC_ANNEX_A); - if ((mux->u.dmc_fe_qam.fec_inner = dvb_str2fec(fec)) == -1) return 1; - if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) return 1; + if ((mux->u.dmc_fe_qam.fec_inner = dvb_str2fec(fec)) == -1) + return 1; + if ((mux->dmc_fe_modulation = dvb_str2qam(qam)) == -1) + return 1; return 0; } - /* ************************************************************************** * File processing * *************************************************************************/ @@ -240,9 +282,7 @@ scanfile_load_dvbc ( dvb_mux_conf_t *mux, const char *line ) /* * Sorting */ -static int -scanfile_network_dvbs_pos(char *n, int *rpos) -{ +static int scanfile_network_dvbs_pos(char* n, int* rpos) { int len = strlen(n), pos = len - 1, frac = 0; if (len > 0 && toupper(n[pos]) != 'W' && toupper(n[pos]) != 'E') @@ -266,23 +306,17 @@ scanfile_network_dvbs_pos(char *n, int *rpos) n[pos] = '\0'; *rpos *= 10; *rpos += frac; - if (toupper(n[len-1]) == 'W') + if (toupper(n[len - 1]) == 'W') *rpos = -*rpos; return 1; } -static int -scanfile_network_cmp - ( scanfile_network_t *a, scanfile_network_t *b ) -{ +static int scanfile_network_cmp(scanfile_network_t* a, scanfile_network_t* b) { if (a->sfn_satpos == b->sfn_satpos) return strcmp(a->sfn_name, b->sfn_name); return b->sfn_satpos - a->sfn_satpos; } -static int -scanfile_region_cmp - ( scanfile_region_t *a, scanfile_region_t *b ) -{ +static int scanfile_region_cmp(scanfile_region_t* a, scanfile_region_t* b) { return strcmp(a->sfr_name, b->sfr_name); } @@ -291,22 +325,22 @@ scanfile_region_cmp * * TODO: not sure why I didn't use RB here! */ -static scanfile_region_t * -scanfile_region_create - ( const char *type, const char *id, const char *desc ) -{ - scanfile_region_t *reg; - scanfile_region_list_t *list = NULL; - int i; +static scanfile_region_t* +scanfile_region_create(const char* type, const char* id, const char* desc) { + scanfile_region_t* reg; + scanfile_region_list_t* list = NULL; + int i; for (i = 0; i < REGIONS; i++) if (strcmp(scanfile_regions_load[i].srl_type, type) == 0) { list = &scanfile_regions_load[i]; break; } - if (!list) return NULL; + if (!list) + return NULL; - LIST_FOREACH(reg, &list->srl_regions, sfr_link) { - if (!strcmp(reg->sfr_id, id)) break; + LIST_FOREACH (reg, &list->srl_regions, sfr_link) { + if (!strcmp(reg->sfr_id, id)) + break; } if (!reg) { @@ -317,23 +351,22 @@ scanfile_region_create reg->sfr_name = strdup(desc); LIST_INSERT_SORTED(&list->srl_regions, reg, sfr_link, scanfile_region_cmp); } - + return reg; } /* * */ -static int -scanfile_create_network - ( scanfile_network_t **_net, const char *type, - const char *path, const char *name, - dvb_fe_delivery_system_t delsys ) -{ - scanfile_region_t *reg = NULL; - scanfile_network_t *net; - char *buf, *buf2, *buf3, *str; - int opos; +static int scanfile_create_network(scanfile_network_t** _net, + const char* type, + const char* path, + const char* name, + dvb_fe_delivery_system_t delsys) { + scanfile_region_t* reg = NULL; + scanfile_network_t* net; + char * buf, *buf2, *buf3, *str; + int opos; /* Region */ buf = malloc(strlen(name) + 1); @@ -362,34 +395,45 @@ scanfile_create_network /* Network */ str = buf; while (*str) { - if (!isprint(*str)) *str = '_'; + if (!isprint(*str)) + *str = '_'; str++; } *str = '\0'; opos = INT_MAX; if (!strcmp(type, "dvb-s") && scanfile_network_dvbs_pos(buf, &opos)) { - int sizeneeded = snprintf(NULL, 0, "%c%3i.%i%c:%s", opos < 0 ? '<' : '>', - abs(opos) / 10, abs(opos) % 10, - opos < 0 ? 'W' :'E', buf); + int sizeneeded = snprintf(NULL, + 0, + "%c%3i.%i%c:%s", + opos < 0 ? '<' : '>', + abs(opos) / 10, + abs(opos) % 10, + opos < 0 ? 'W' : 'E', + buf); buf3 = malloc(sizeneeded + 1); - snprintf(buf3, sizeneeded, "%c%3i.%i%c:%s", opos < 0 ? '<' : '>', - abs(opos) / 10, abs(opos) % 10, - opos < 0 ? 'W' :'E', buf); + snprintf(buf3, + sizeneeded, + "%c%3i.%i%c:%s", + opos < 0 ? '<' : '>', + abs(opos) / 10, + abs(opos) % 10, + opos < 0 ? 'W' : 'E', + buf); free(buf); buf = buf3; } int sizeneeded = snprintf(NULL, 0, "%s_%s", type, buf); - buf2 = malloc(sizeneeded + 1); + buf2 = malloc(sizeneeded + 1); snprintf(buf2, sizeneeded, "%s_%s", type, buf); net = calloc(1, sizeof(scanfile_network_t)); - memoryinfo_alloc(&scanfile_memoryinfo, sizeof(*net) + strlen(buf2) + 1 + strlen(buf) + 1 + - strlen(path) + 1 + strlen(type) + 1); - net->sfn_id = strdup(buf2); - net->sfn_name = strdup(buf); - net->sfn_path = strdup(path); - net->sfn_type = strdup(type); + memoryinfo_alloc(&scanfile_memoryinfo, + sizeof(*net) + strlen(buf2) + 1 + strlen(buf) + 1 + strlen(path) + 1 + strlen(type) + 1); + net->sfn_id = strdup(buf2); + net->sfn_name = strdup(buf); + net->sfn_path = strdup(path); + net->sfn_type = strdup(type); net->sfn_satpos = opos; LIST_INSERT_SORTED(®->sfr_networks, net, sfn_link, scanfile_network_cmp); @@ -403,26 +447,27 @@ scanfile_create_network /* * Process mux entry */ -static int -scanfile_load_one - ( scanfile_network_t **net, const char *type, const char *path, - const char *name, const char *line, int test ) -{ - int r = 1; - dvb_mux_conf_t *mux = malloc(sizeof(dvb_mux_conf_t)); - +static int scanfile_load_one(scanfile_network_t** net, + const char* type, + const char* path, + const char* name, + const char* line, + int test) { + int r = 1; + dvb_mux_conf_t* mux = malloc(sizeof(dvb_mux_conf_t)); + switch (line[0]) { case 'A': - r = scanfile_load_atsc(mux, line+1); + r = scanfile_load_atsc(mux, line + 1); break; case 'T': - r = scanfile_load_dvbt(mux, line+1); + r = scanfile_load_dvbt(mux, line + 1); break; case 'S': - r = scanfile_load_dvbs(mux, line+1); + r = scanfile_load_dvbs(mux, line + 1); break; case 'C': - r = scanfile_load_dvbc(mux, line+1); + r = scanfile_load_dvbc(mux, line + 1); break; } @@ -430,8 +475,7 @@ scanfile_load_one if (r) { free(mux); } else { - if (*net == NULL && - scanfile_create_network(net, type, path, name, mux->dmc_fe_delsys)) { + if (*net == NULL && scanfile_create_network(net, type, path, name, mux->dmc_fe_delsys)) { free(mux); return -1; } @@ -449,10 +493,8 @@ scanfile_load_one /* * Process mux dvbv5 entry */ -static char * -str_trim(char *s) -{ - char *t; +static char* str_trim(char* s) { + char* t; while (*s && *s <= ' ') s++; if (*s) { @@ -466,28 +508,31 @@ str_trim(char *s) return s; } -#define mux_fail0(r, text) do { \ - tvhtrace(LS_SCANFILE, text); \ - ((r) = -1); \ -} while (0) -#define mux_fail(r, text, val) do { \ - tvhtrace(LS_SCANFILE, text, val); \ - ((r) = -1); \ -} while (0) -#define mux_ok(r) ((r) = ((r) > 0) ? 0 : (r)) - -static int -scanfile_load_dvbv5 - ( scanfile_network_t **net, const char *type, - const char *path, const char *name, - char *line, fb_file *fp, int test ) -{ - int res = 1, r = 1, i; - char buf[256]; - char *s, *t; - const char *x; - dvb_mux_conf_t *mux; - htsmsg_t *l; +#define mux_fail0(r, text) \ + do { \ + tvhtrace(LS_SCANFILE, text); \ + ((r) = -1); \ + } while (0) +#define mux_fail(r, text, val) \ + do { \ + tvhtrace(LS_SCANFILE, text, val); \ + ((r) = -1); \ + } while (0) +#define mux_ok(r) ((r) = ((r) > 0) ? 0 : (r)) + +static int scanfile_load_dvbv5(scanfile_network_t** net, + const char* type, + const char* path, + const char* name, + char* line, + fb_file* fp, + int test) { + int res = 1, r = 1, i; + char buf[256]; + char * s, *t; + const char* x; + dvb_mux_conf_t* mux; + htsmsg_t* l; /* validity check for [text] */ s = str_trim(line); @@ -499,8 +544,9 @@ scanfile_load_dvbv5 /* Process file */ while (!fb_eof(fp)) { /* Get line */ - buf[sizeof(buf)-1] = '\0'; - if (!fb_gets(fp, buf, sizeof(buf) - 1)) break; + buf[sizeof(buf) - 1] = '\0'; + if (!fb_gets(fp, buf, sizeof(buf) - 1)) + break; s = str_trim(buf); if (*s == '#' || *s == '\0') continue; @@ -511,14 +557,14 @@ scanfile_load_dvbv5 if ((t = strchr(s, '=')) == NULL) continue; *t = '\0'; - s = str_trim(s); - t = str_trim(t + 1); + s = str_trim(s); + t = str_trim(t + 1); htsmsg_add_str(l, s, t); } - mux = calloc(1, sizeof(dvb_mux_conf_t)); - mux->dmc_fe_delsys = -1; + mux = calloc(1, sizeof(dvb_mux_conf_t)); + mux->dmc_fe_delsys = -1; mux->dmc_fe_inversion = DVB_INVERSION_AUTO; x = htsmsg_get_str(l, "DELIVERY_SYSTEM"); @@ -532,14 +578,13 @@ scanfile_load_dvbv5 dvb_mux_conf_init(NULL, mux, mux->dmc_fe_delsys); - if (mux->dmc_fe_delsys == DVB_SYS_DVBT || - mux->dmc_fe_delsys == DVB_SYS_DVBT2) { + if (mux->dmc_fe_delsys == DVB_SYS_DVBT || mux->dmc_fe_delsys == DVB_SYS_DVBT2) { - mux->u.dmc_fe_ofdm.bandwidth = DVB_BANDWIDTH_AUTO; - mux->u.dmc_fe_ofdm.code_rate_HP = DVB_FEC_AUTO; - mux->u.dmc_fe_ofdm.code_rate_LP = DVB_FEC_NONE; - mux->dmc_fe_modulation = DVB_MOD_QAM_64; - mux->u.dmc_fe_ofdm.transmission_mode = DVB_TRANSMISSION_MODE_8K; + mux->u.dmc_fe_ofdm.bandwidth = DVB_BANDWIDTH_AUTO; + mux->u.dmc_fe_ofdm.code_rate_HP = DVB_FEC_AUTO; + mux->u.dmc_fe_ofdm.code_rate_LP = DVB_FEC_NONE; + mux->dmc_fe_modulation = DVB_MOD_QAM_64; + mux->u.dmc_fe_ofdm.transmission_mode = DVB_TRANSMISSION_MODE_8K; mux->u.dmc_fe_ofdm.hierarchy_information = DVB_HIERARCHY_NONE; if ((x = htsmsg_get_str(l, "BANDWIDTH_HZ"))) { @@ -577,13 +622,11 @@ scanfile_load_dvbv5 if (htsmsg_get_s32(l, "STREAM_ID", &mux->dmc_fe_stream_id)) mux->dmc_fe_stream_id = DVB_NO_STREAM_ID_FILTER; - } else if (mux->dmc_fe_delsys == DVB_SYS_DVBS || - mux->dmc_fe_delsys == DVB_SYS_DVBS2) { + } else if (mux->dmc_fe_delsys == DVB_SYS_DVBS || mux->dmc_fe_delsys == DVB_SYS_DVBS2) { - mux->dmc_fe_modulation = - mux->dmc_fe_delsys == DVB_SYS_DVBS2 ? DVB_MOD_PSK_8 : DVB_MOD_QPSK; + mux->dmc_fe_modulation = mux->dmc_fe_delsys == DVB_SYS_DVBS2 ? DVB_MOD_PSK_8 : DVB_MOD_QPSK; mux->u.dmc_fe_qpsk.fec_inner = DVB_FEC_AUTO; - mux->dmc_fe_rolloff = DVB_ROLLOFF_35; + mux->dmc_fe_rolloff = DVB_ROLLOFF_35; if ((x = htsmsg_get_str(l, "MODULATION"))) if ((mux->dmc_fe_modulation = dvb_str2qam(x)) == -1) @@ -602,13 +645,12 @@ scanfile_load_dvbv5 mux_fail(r, "wrong pilot '%s'", x); if (htsmsg_get_s32(l, "STREAM_ID", &r)) { mux->dmc_fe_stream_id = DVB_NO_STREAM_ID_FILTER; - mux->dmc_fe_pls_mode = 0; - mux->dmc_fe_pls_code = 1; - } - else { - mux->dmc_fe_stream_id = r&0xff; - mux->dmc_fe_pls_mode = (r>>26)&0x3; - mux->dmc_fe_pls_code = (r>>8)&0x3FFFF; + mux->dmc_fe_pls_mode = 0; + mux->dmc_fe_pls_code = 1; + } else { + mux->dmc_fe_stream_id = r & 0xff; + mux->dmc_fe_pls_mode = (r >> 26) & 0x3; + mux->dmc_fe_pls_code = (r >> 8) & 0x3FFFF; } if (htsmsg_get_u32(l, "PLS_CODE", &mux->dmc_fe_pls_code) == 0) @@ -617,7 +659,8 @@ scanfile_load_dvbv5 if ((x = htsmsg_get_str(l, "POLARIZATION"))) { char pol[2]; - pol[0] = x[0]; pol[1] = '\0'; + pol[0] = x[0]; + pol[1] = '\0'; if ((mux->u.dmc_fe_qpsk.polarisation = dvb_str2pol(pol)) == -1) mux_fail(r, "wrong polarisation '%s'", x); } else { @@ -627,10 +670,9 @@ scanfile_load_dvbv5 mux_fail0(r, "dvb-s: undefined symbol rate"); } else if (mux->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_A || - mux->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_B || - mux->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_C) { + mux->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_B || mux->dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_C) { - mux->dmc_fe_modulation = DVB_MOD_QAM_128; + mux->dmc_fe_modulation = DVB_MOD_QAM_128; mux->u.dmc_fe_qam.fec_inner = DVB_FEC_NONE; if ((x = htsmsg_get_str(l, "MODULATION"))) @@ -669,7 +711,7 @@ scanfile_load_dvbv5 if ((mux->u.dmc_fe_ofdm.bandwidth = dvb_str2bw(x)) == -1) mux_fail(r, "wrong bandwidth '%s'", x); } - + if ((x = htsmsg_get_str(l, "INVERSION"))) if ((mux->dmc_fe_inversion = dvb_str2inver(x)) == -1) mux_fail(r, "wrong inversion '%s'", x); @@ -678,7 +720,7 @@ scanfile_load_dvbv5 mux_fail(r, "wrong guard interval '%s'", x); for (i = 0; i < 3; i++) { - mux->u.dmc_fe_isdbt.layers[i].fec = DVB_FEC_AUTO; + mux->u.dmc_fe_isdbt.layers[i].fec = DVB_FEC_AUTO; mux->u.dmc_fe_isdbt.layers[i].modulation = DVB_MOD_AUTO; } @@ -702,18 +744,23 @@ scanfile_load_dvbv5 if ((mux->u.dmc_fe_isdbt.layers[2].modulation = dvb_str2qam(x)) == -1) mux_fail(r, "wrong modulation '%s'", x); - mux->u.dmc_fe_isdbt.layers[0].segment_count = htsmsg_get_u32_or_default(l, "ISDBT_LAYERA_SEGMENT_COUNT", 0); - mux->u.dmc_fe_isdbt.layers[1].segment_count = htsmsg_get_u32_or_default(l, "ISDBT_LAYERB_SEGMENT_COUNT", 0); - mux->u.dmc_fe_isdbt.layers[2].segment_count = htsmsg_get_u32_or_default(l, "ISDBT_LAYERC_SEGMENT_COUNT", 0); + mux->u.dmc_fe_isdbt.layers[0].segment_count = + htsmsg_get_u32_or_default(l, "ISDBT_LAYERA_SEGMENT_COUNT", 0); + mux->u.dmc_fe_isdbt.layers[1].segment_count = + htsmsg_get_u32_or_default(l, "ISDBT_LAYERB_SEGMENT_COUNT", 0); + mux->u.dmc_fe_isdbt.layers[2].segment_count = + htsmsg_get_u32_or_default(l, "ISDBT_LAYERC_SEGMENT_COUNT", 0); - mux->u.dmc_fe_isdbt.layers[0].time_interleaving = htsmsg_get_u32_or_default(l, "ISDBT_LAYERA_TIME_INTERLEAVING", 0); - mux->u.dmc_fe_isdbt.layers[1].time_interleaving = htsmsg_get_u32_or_default(l, "ISDBT_LAYERB_TIME_INTERLEAVING", 0); - mux->u.dmc_fe_isdbt.layers[2].time_interleaving = htsmsg_get_u32_or_default(l, "ISDBT_LAYERC_TIME_INTERLEAVING", 0); + mux->u.dmc_fe_isdbt.layers[0].time_interleaving = + htsmsg_get_u32_or_default(l, "ISDBT_LAYERA_TIME_INTERLEAVING", 0); + mux->u.dmc_fe_isdbt.layers[1].time_interleaving = + htsmsg_get_u32_or_default(l, "ISDBT_LAYERB_TIME_INTERLEAVING", 0); + mux->u.dmc_fe_isdbt.layers[2].time_interleaving = + htsmsg_get_u32_or_default(l, "ISDBT_LAYERC_TIME_INTERLEAVING", 0); } else { mux_fail(r, "wrong delivery system '%s'", x); - } if (!htsmsg_get_u32(l, "FREQUENCY", &mux->dmc_fe_freq)) @@ -744,21 +791,23 @@ scanfile_load_dvbv5 /* * Process a file */ -static scanfile_network_t * -scanfile_load_file - ( scanfile_network_t *net, const char *type, const char *path, - fb_file *fp, const char *name, int test ) -{ +static scanfile_network_t* scanfile_load_file(scanfile_network_t* net, + const char* type, + const char* path, + fb_file* fp, + const char* name, + int test) { char *str, buf[256]; - int load = 0; + int load = 0; - tvhtrace(LS_SCANFILE, "load file %s (processed bytes %"PRId64")", - name, scanfile_total_load); + tvhtrace(LS_SCANFILE, "load file %s (processed bytes %" PRId64 ")", name, scanfile_total_load); - if (!fp) return NULL; + if (!fp) + return NULL; scanfile_total_load += fb_size(fp); - if (scanfile_total_load > SCANFILE_LIMIT) goto end; + if (scanfile_total_load > SCANFILE_LIMIT) + goto end; /* Process file */ load = 1; @@ -766,8 +815,9 @@ scanfile_load_file /* Get line */ if (load) { - buf[sizeof(buf)-1] = '\0'; - if (!fb_gets(fp, buf, sizeof(buf) - 1)) break; + buf[sizeof(buf) - 1] = '\0'; + if (!fb_gets(fp, buf, sizeof(buf) - 1)) + break; str = buf + strlen(buf) - 1; if (buf[0]) *(str--) = '\0'; @@ -801,31 +851,32 @@ end: * * Note: should we follow symlinks? */ -static void -scanfile_load_dir - ( const char *path, const char *type, int lvl, int test ) -{ - char p[PATH_MAX]; - fb_dir *dir; - fb_dirent *de; - fb_file *fp; - scanfile_network_t *net; +static void scanfile_load_dir(const char* path, const char* type, int lvl, int test) { + char p[PATH_MAX]; + fb_dir* dir; + fb_dirent* de; + fb_file* fp; + scanfile_network_t* net; tvhtrace(LS_SCANFILE, "load dir %s", path); - if (lvl >= 3) return; - if (!(dir = fb_opendir(path))) return; + if (lvl >= 3) + return; + if (!(dir = fb_opendir(path))) + return; lvl++; - + while ((de = fb_readdir(dir))) { - if (*de->name == '.') continue; + if (*de->name == '.') + continue; if (de->type == FB_DIR) { snprintf(p, sizeof(p), "%s/%s", path, de->name); - scanfile_load_dir(p, de->name, lvl+1, test); + scanfile_load_dir(p, de->name, lvl + 1, test); } else if (type) { snprintf(p, sizeof(p), "%s/%s", path, de->name); - if (scanfile_total_load > SCANFILE_LIMIT) continue; - fp = fb_open2(dir, de->name, 1, 0); + if (scanfile_total_load > SCANFILE_LIMIT) + continue; + fp = fb_open2(dir, de->name, 1, 0); net = scanfile_load_file(NULL, type, p, fp, de->name, test); scanfile_done_muxes(net); } @@ -837,16 +888,14 @@ scanfile_load_dir /* * */ -static int -scanfile_stats(const char *what, scanfile_region_list_t *list) -{ - scanfile_region_t *reg; - scanfile_network_t *sfn; - int regions = 0, networks =0; - - LIST_FOREACH(reg, &list->srl_regions, sfr_link) { +static int scanfile_stats(const char* what, scanfile_region_list_t* list) { + scanfile_region_t* reg; + scanfile_network_t* sfn; + int regions = 0, networks = 0; + + LIST_FOREACH (reg, &list->srl_regions, sfr_link) { regions++; - LIST_FOREACH(sfn, ®->sfr_networks, sfn_link) + LIST_FOREACH (sfn, ®->sfr_networks, sfn_link) networks++; } if (regions) { @@ -859,11 +908,10 @@ scanfile_stats(const char *what, scanfile_region_list_t *list) /* * Destroy the muxes */ -static void -scanfile_done_muxes( scanfile_network_t *net ) -{ - dvb_mux_conf_t *mux; - if (!net) return; +static void scanfile_done_muxes(scanfile_network_t* net) { + dvb_mux_conf_t* mux; + if (!net) + return; while ((mux = LIST_FIRST(&net->sfn_muxes)) != NULL) { memoryinfo_free(&scanfile_memoryinfo, sizeof(*mux)); LIST_REMOVE(mux, dmc_link); @@ -871,37 +919,34 @@ scanfile_done_muxes( scanfile_network_t *net ) } } - /* * Destroy the region */ -static void -scanfile_done_region( scanfile_region_list_t *list ) -{ - scanfile_region_t *reg; - scanfile_network_t *net; +static void scanfile_done_region(scanfile_region_list_t* list) { + scanfile_region_t* reg; + scanfile_network_t* net; while ((reg = LIST_FIRST(&list->srl_regions)) != NULL) { LIST_REMOVE(reg, sfr_link); while ((net = LIST_FIRST(®->sfr_networks)) != NULL) { LIST_REMOVE(net, sfn_link); scanfile_done_muxes(net); - memoryinfo_free(&scanfile_memoryinfo, sizeof(*net) + - (net->sfn_id ? strlen(net->sfn_id) + 1 : 0) + - (net->sfn_name ? strlen(net->sfn_name) + 1 : 0) + - (net->sfn_path ? strlen(net->sfn_path) + 1 : 0) + - (net->sfn_type ? strlen(net->sfn_type) + 1 : 0)); - free((void *)net->sfn_id); - free((void *)net->sfn_name); - free((void *)net->sfn_path); - free((void *)net->sfn_type); + memoryinfo_free(&scanfile_memoryinfo, + sizeof(*net) + (net->sfn_id ? strlen(net->sfn_id) + 1 : 0) + + (net->sfn_name ? strlen(net->sfn_name) + 1 : 0) + + (net->sfn_path ? strlen(net->sfn_path) + 1 : 0) + + (net->sfn_type ? strlen(net->sfn_type) + 1 : 0)); + free((void*)net->sfn_id); + free((void*)net->sfn_name); + free((void*)net->sfn_path); + free((void*)net->sfn_type); free(net); } - memoryinfo_free(&scanfile_memoryinfo, sizeof(*reg) + - (reg->sfr_id ? strlen(reg->sfr_id) + 1 : 0) + - (reg->sfr_name ? strlen(reg->sfr_name) + 1 : 0)); - free((void *)reg->sfr_id); - free((void *)reg->sfr_name); + memoryinfo_free(&scanfile_memoryinfo, + sizeof(*reg) + (reg->sfr_id ? strlen(reg->sfr_id) + 1 : 0) + + (reg->sfr_name ? strlen(reg->sfr_name) + 1 : 0)); + free((void*)reg->sfr_id); + free((void*)reg->sfr_name); free(reg); } } @@ -909,13 +954,11 @@ scanfile_done_region( scanfile_region_list_t *list ) /* * Initialise the mux list */ -void -scanfile_init ( const char *muxconf_path, int lock ) -{ - static int initialized = 0; - const char *path = muxconf_path; - char buf[32], *p; - int r = 0, i; +void scanfile_init(const char* muxconf_path, int lock) { + static int initialized = 0; + const char* path = muxconf_path; + char buf[32], *p; + int r = 0, i; if (!path || !*path) #if ENABLE_DVBSCAN path = "data/dvb-scan"; @@ -934,27 +977,30 @@ scanfile_init ( const char *muxconf_path, int lock ) tvh_mutex_unlock(&global_lock); } - scanfile_total_load = 0; + scanfile_total_load = 0; scanfile_regions_load = calloc(REGIONS, sizeof(scanfile_region_list_t)); memoryinfo_alloc(&scanfile_memoryinfo, REGIONS * sizeof(scanfile_region_list_t)); for (i = 0; i < REGIONS; i++) { - scanfile_regions_load[i].srl_type = scanfile_region_types[i][0]; + scanfile_regions_load[i].srl_type = scanfile_region_types[i][0]; scanfile_regions_load[i].srl_alt_type = scanfile_region_types[i][1]; } scanfile_load_dir(path, NULL, 0, 1); for (i = 0; i < REGIONS; i++) { - snprintf(buf, sizeof(buf)-1, "%s", scanfile_regions_load[i].srl_type); - buf[sizeof(buf)-1] = '\0'; - for (p = buf; *p; p++) *p = toupper(*p); + snprintf(buf, sizeof(buf) - 1, "%s", scanfile_regions_load[i].srl_type); + buf[sizeof(buf) - 1] = '\0'; + for (p = buf; *p; p++) + *p = toupper(*p); r += scanfile_stats(buf, &scanfile_regions_load[i]); } if (!r) { - tvhwarn(LS_SCANFILE, "no predefined muxes found, check path '%s%s'", - path[0] == '/' ? path : TVHEADEND_DATADIR "/", - path[0] == '/' ? "" : path); - tvhwarn(LS_SCANFILE, "expected tree structure - http://git.linuxtv.org/cgit.cgi/dtv-scan-tables.git/tree/"); + tvhwarn(LS_SCANFILE, + "no predefined muxes found, check path '%s%s'", + path[0] == '/' ? path : TVHEADEND_DATADIR "/", + path[0] == '/' ? "" : path); + tvhwarn(LS_SCANFILE, + "expected tree structure - http://git.linuxtv.org/cgit.cgi/dtv-scan-tables.git/tree/"); for (i = 0; i < REGIONS; i++) scanfile_done_region(&scanfile_regions_load[i]); memoryinfo_free(&scanfile_memoryinfo, REGIONS * sizeof(scanfile_region_list_t)); @@ -964,7 +1010,7 @@ scanfile_init ( const char *muxconf_path, int lock ) if (lock) tvh_mutex_lock(&global_lock); scanfile_done(); - scanfile_regions = scanfile_regions_load; + scanfile_regions = scanfile_regions_load; scanfile_regions_load = NULL; if (lock) tvh_mutex_unlock(&global_lock); @@ -974,13 +1020,11 @@ scanfile_init ( const char *muxconf_path, int lock ) /* * Destroy the mux list */ -void -scanfile_done ( void ) -{ - scanfile_region_list_t *l; - int i; +void scanfile_done(void) { + scanfile_region_list_t* l; + int i; - l = scanfile_regions; + l = scanfile_regions; scanfile_regions = NULL; if (l) { for (i = 0; i < REGIONS; i++) @@ -993,12 +1037,10 @@ scanfile_done ( void ) /* * Find region list by type */ -scanfile_region_list_t * -scanfile_find_region_list ( const char *type ) -{ - scanfile_region_list_t *list = NULL; - scanfile_region_list_t *ptr = scanfile_regions; - int i; +scanfile_region_list_t* scanfile_find_region_list(const char* type) { + scanfile_region_list_t* list = NULL; + scanfile_region_list_t* ptr = scanfile_regions; + int i; if (ptr == NULL) return NULL; for (i = 0; i < REGIONS; i++, ptr++) { @@ -1014,14 +1056,12 @@ scanfile_find_region_list ( const char *type ) /* * Find scanfile and load muxes */ -scanfile_network_t * -scanfile_find ( const char *id ) -{ - char *tok, *s = NULL, *tmp; - scanfile_region_t *r = NULL; - scanfile_network_t *n = NULL; - scanfile_region_list_t *l; - fb_file *fp; +scanfile_network_t* scanfile_find(const char* id) { + char * tok, *s = NULL, *tmp; + scanfile_region_t* r = NULL; + scanfile_network_t* n = NULL; + scanfile_region_list_t* l; + fb_file* fp; tmp = strdup(id); /* Type */ @@ -1034,22 +1074,23 @@ scanfile_find ( const char *id ) /* Region */ if (!(tok = strtok_r(NULL, "/", &s))) goto fail; - LIST_FOREACH(r, &l->srl_regions, sfr_link) + LIST_FOREACH (r, &l->srl_regions, sfr_link) if (!strcmp(r->sfr_id, tok)) break; - if (!r) goto fail; + if (!r) + goto fail; /* Network */ if (!(tok = strtok_r(NULL, "/", &s))) goto fail; - LIST_FOREACH(n, &r->sfr_networks, sfn_link) + LIST_FOREACH (n, &r->sfr_networks, sfn_link) if (!strcmp(n->sfn_id, tok)) break; free(tmp); if (n) { - fp = fb_open(n->sfn_path, 1, 0); + fp = fb_open(n->sfn_path, 1, 0); tmp = strrchr(n->sfn_path, '/'); scanfile_load_file(n, n->sfn_type, n->sfn_path, fp, tmp ?: n->sfn_path, 0); } @@ -1064,8 +1105,6 @@ fail: /* * Remove muxes from scanfile */ -void -scanfile_clean( scanfile_network_t *sfn ) -{ +void scanfile_clean(scanfile_network_t* sfn) { scanfile_done_muxes(sfn); } diff --git a/src/input/mpegts/scanfile.h b/src/input/mpegts/scanfile.h index ffdcaaa1e..4092eeae3 100644 --- a/src/input/mpegts/scanfile.h +++ b/src/input/mpegts/scanfile.h @@ -20,33 +20,33 @@ #define __DVB_SCANFILES_H__ typedef struct scanfile_network { - const char *sfn_id; - const char *sfn_name; - const char *sfn_path; - const char *sfn_type; - int sfn_satpos; + const char* sfn_id; + const char* sfn_name; + const char* sfn_path; + const char* sfn_type; + int sfn_satpos; LIST_ENTRY(scanfile_network) sfn_link; - LIST_HEAD(,dvb_mux_conf) sfn_muxes; + LIST_HEAD(, dvb_mux_conf) sfn_muxes; } scanfile_network_t; typedef struct scanfile_region { - const char *sfr_id; - const char *sfr_name; - LIST_ENTRY(scanfile_region) sfr_link; - LIST_HEAD(,scanfile_network) sfr_networks; + const char* sfr_id; + const char* sfr_name; + LIST_ENTRY(scanfile_region) sfr_link; + LIST_HEAD(, scanfile_network) sfr_networks; } scanfile_region_t; typedef struct scanfile_region_list { - LIST_HEAD(,scanfile_region) srl_regions; - const char *srl_type; - const char *srl_alt_type; + LIST_HEAD(, scanfile_region) srl_regions; + const char* srl_type; + const char* srl_alt_type; } scanfile_region_list_t; -void scanfile_init ( const char *muxconf_path, int lock ); -void scanfile_done ( void ); +void scanfile_init(const char* muxconf_path, int lock); +void scanfile_done(void); + +scanfile_region_list_t* scanfile_find_region_list(const char* type); +scanfile_network_t* scanfile_find(const char* id); +void scanfile_clean(scanfile_network_t* sfn); -scanfile_region_list_t *scanfile_find_region_list ( const char *type ); -scanfile_network_t *scanfile_find ( const char *id ); -void scanfile_clean( scanfile_network_t *sfn ); - #endif /* __DVB_SCANFILES_H__ */ diff --git a/src/input/mpegts/tsdemux.c b/src/input/mpegts/tsdemux.c index c33b185a8..8c887f33a 100644 --- a/src/input/mpegts/tsdemux.c +++ b/src/input/mpegts/tsdemux.c @@ -25,19 +25,16 @@ #define TS_REMUX_BUFSIZE (188 * 100) -static void ts_remux(mpegts_service_t *t, const uint8_t *tsb, int len, int errors); -static void ts_skip(mpegts_service_t *t, const uint8_t *tsb, int len); +static void ts_remux(mpegts_service_t* t, const uint8_t* tsb, int len, int errors); +static void ts_skip(mpegts_service_t* t, const uint8_t* tsb, int len); /** * Continue processing of transport stream packets */ -void -ts_recv_packet0 - (mpegts_service_t *t, elementary_stream_t *st, const uint8_t *tsb, int len) -{ - mpegts_service_t *m; - int len2, off, cc, pid, error, errors = 0; - const uint8_t *tsb2; +void ts_recv_packet0(mpegts_service_t* t, elementary_stream_t* st, const uint8_t* tsb, int len) { + mpegts_service_t* m; + int len2, off, cc, pid, error, errors = 0; + const uint8_t* tsb2; service_set_streaming_status_flags((service_t*)t, TSS_MUX_PACKETS); @@ -46,19 +43,20 @@ ts_recv_packet0 for (tsb2 = tsb, len2 = len; len2 > 0; tsb2 += 188, len2 -= 188) { - error = (tsb2[1] >> 7) & 1; /* 0x80 */ + error = (tsb2[1] >> 7) & 1; /* 0x80 */ errors += error; /* Check CC */ if (tsb2[3] & 0x10) { cc = tsb2[3] & 0xf; - if(st->es_cc != -1 && cc != st->es_cc) { + if (st->es_cc != -1 && cc != st->es_cc) { /* Let the hardware to stabilize and don't flood the log */ - if (t->s_start_time + sec2mono(1) < mclk() && - tvhlog_limit(&st->es_cc_log, 10)) - tvhwarn(LS_TS, "%s Continuity counter error (total %zi)", - st->es_nicename, st->es_cc_log.count); + if (t->s_start_time + sec2mono(1) < mclk() && tvhlog_limit(&st->es_cc_log, 10)) + tvhwarn(LS_TS, + "%s Continuity counter error (total %zi)", + st->es_nicename, + st->es_cc_log.count); if (!error) errors++; error |= 2; @@ -74,13 +72,13 @@ ts_recv_packet0 return; skip_cc: - if(streaming_pad_probe_type(&t->s_streaming_pad, SMT_MPEGTS)) + if (streaming_pad_probe_type(&t->s_streaming_pad, SMT_MPEGTS)) ts_remux(t, tsb, len, errors); - for(off = 0; off < t->s_masters.is_count; off++) { - m = (mpegts_service_t *)t->s_masters.is_array[off]; + for (off = 0; off < t->s_masters.is_count; off++) { + m = (mpegts_service_t*)t->s_masters.is_array[off]; tvh_mutex_lock(&m->s_stream_mutex); - if(streaming_pad_probe_type(&m->s_streaming_pad, SMT_MPEGTS)) { + if (streaming_pad_probe_type(&m->s_streaming_pad, SMT_MPEGTS)) { pid = (tsb[1] & 0x1f) << 8 | tsb[2]; if (mpegts_pid_rexists(m->s_slaves_pids, pid)) ts_remux(m, tsb, len, errors); @@ -96,12 +94,10 @@ skip_cc: * Continue processing of skipped packets */ static void -ts_recv_skipped0 - (mpegts_service_t *t, elementary_stream_t *st, const uint8_t *tsb, int len) -{ - mpegts_service_t *m; - int len2, off, cc, pid; - const uint8_t *tsb2; +ts_recv_skipped0(mpegts_service_t* t, elementary_stream_t* st, const uint8_t* tsb, int len) { + mpegts_service_t* m; + int len2, off, cc, pid; + const uint8_t* tsb2; if (!st) goto skip_cc; @@ -110,28 +106,28 @@ ts_recv_skipped0 /* Check CC */ - if(tsb2[3] & 0x10) { + if (tsb2[3] & 0x10) { cc = tsb2[3] & 0xf; - if(st->es_cc != -1 && cc != st->es_cc) { + if (st->es_cc != -1 && cc != st->es_cc) { /* Let the hardware to stabilize and don't flood the log */ - if (t->s_start_time + sec2mono(1) < mclk() && - tvhlog_limit(&st->es_cc_log, 10)) - tvhwarn(LS_TS, "%s Continuity counter error (total %zi)", - st->es_nicename, st->es_cc_log.count); + if (t->s_start_time + sec2mono(1) < mclk() && tvhlog_limit(&st->es_cc_log, 10)) + tvhwarn(LS_TS, + "%s Continuity counter error (total %zi)", + st->es_nicename, + st->es_cc_log.count); } st->es_cc = (cc + 1) & 0xf; } - } skip_cc: - if(streaming_pad_probe_type(&t->s_streaming_pad, SMT_MPEGTS)) + if (streaming_pad_probe_type(&t->s_streaming_pad, SMT_MPEGTS)) ts_skip(t, tsb, len); - for(off = 0; off < t->s_masters.is_count; off++) { - m = (mpegts_service_t *)t->s_masters.is_array[off]; + for (off = 0; off < t->s_masters.is_count; off++) { + m = (mpegts_service_t*)t->s_masters.is_array[off]; tvh_mutex_lock(&m->s_stream_mutex); - if(streaming_pad_probe_type(&m->s_streaming_pad, SMT_MPEGTS)) { + if (streaming_pad_probe_type(&m->s_streaming_pad, SMT_MPEGTS)) { pid = (tsb[1] & 0x1f) << 8 | tsb[2]; if (mpegts_pid_rexists(t->s_slaves_pids, pid)) ts_skip(m, tsb, len); @@ -143,15 +139,16 @@ skip_cc: /** * Process service stream packets, optionally descramble */ -int -ts_recv_packet1 - (mpegts_service_t *t, uint64_t tspos, uint16_t pid, - const uint8_t *tsb, int len, int table) -{ - elementary_stream_t *st; - uint_fast8_t scrambled, error = 0; - int r; - +int ts_recv_packet1(mpegts_service_t* t, + uint64_t tspos, + uint16_t pid, + const uint8_t* tsb, + int len, + int table) { + elementary_stream_t* st; + uint_fast8_t scrambled, error = 0; + int r; + /* Error */ if (tsb[1] & 0x80) error = 1; @@ -164,48 +161,50 @@ ts_recv_packet1 tvh_mutex_lock(&t->s_stream_mutex); /* Service inactive - ignore */ - if(t->s_status != SERVICE_RUNNING) { + if (t->s_status != SERVICE_RUNNING) { tvh_mutex_unlock(&t->s_stream_mutex); return 0; } service_set_streaming_status_flags((service_t*)t, TSS_INPUT_HARDWARE); - if(error) { + if (error) { /* Transport Error Indicator */ if (tvhlog_limit(&t->s_tei_log, 10)) - tvhwarn(LS_TS, "%s Transport error indicator (total %zi)", - service_nicename((service_t*)t), t->s_tei_log.count); + tvhwarn(LS_TS, + "%s Transport error indicator (total %zi)", + service_nicename((service_t*)t), + t->s_tei_log.count); } st = elementary_stream_find(&t->s_components, pid); - if((st == NULL) && (pid != t->s_components.set_pcr_pid) && !table) { + if ((st == NULL) && (pid != t->s_components.set_pcr_pid) && !table) { tvh_mutex_unlock(&t->s_stream_mutex); return 0; } - if(!error) + if (!error) service_set_streaming_status_flags((service_t*)t, TSS_INPUT_SERVICE); scrambled = t->s_scrambled_seen; - if(!t->s_scrambled_pass && ((tsb[3] & 0xc0) || scrambled)) { + if (!t->s_scrambled_pass && ((tsb[3] & 0xc0) || scrambled)) { /** * Lock for descrambling, but only if packet was not in error */ - if(!scrambled && !error) + if (!scrambled && !error) t->s_scrambled_seen |= service_is_encrypted((service_t*)t); /* scrambled stream */ - r = descrambler_descramble((service_t *)t, st, tsb, len); - if(r > 0) { + r = descrambler_descramble((service_t*)t, st, tsb, len); + if (r > 0) { tvh_mutex_unlock(&t->s_stream_mutex); return 1; } - if(!error && service_is_encrypted((service_t*)t)) { - if(r == 0) { + if (!error && service_is_encrypted((service_t*)t)) { + if (r == 0) { service_set_streaming_status_flags((service_t*)t, TSS_NO_DESCRAMBLER); } else { service_set_streaming_status_flags((service_t*)t, TSS_NO_ACCESS); @@ -219,20 +218,17 @@ ts_recv_packet1 return 1; } - /* * Process transport stream packets, simple version */ -void -ts_recv_packet2(mpegts_service_t *t, const uint8_t *tsb, int len) -{ - elementary_stream_t *st; - int pid, len2; +void ts_recv_packet2(mpegts_service_t* t, const uint8_t* tsb, int len) { + elementary_stream_t* st; + int pid, len2; - for ( ; len > 0; tsb += len2, len -= len2 ) { + for (; len > 0; tsb += len2, len -= len2) { len2 = mpegts_word_count(tsb, len, 0xFF9FFFD0); - pid = (tsb[1] & 0x1f) << 8 | tsb[2]; - st = elementary_stream_find(&t->s_components, pid); + pid = (tsb[1] & 0x1f) << 8 | tsb[2]; + st = elementary_stream_find(&t->s_components, pid); ts_recv_packet0(t, st, tsb, len2); } } @@ -240,16 +236,14 @@ ts_recv_packet2(mpegts_service_t *t, const uint8_t *tsb, int len) /* * Process transport stream packets, simple version */ -void -ts_skip_packet2(mpegts_service_t *t, const uint8_t *tsb, int len) -{ - elementary_stream_t *st; - int pid, len2; +void ts_skip_packet2(mpegts_service_t* t, const uint8_t* tsb, int len) { + elementary_stream_t* st; + int pid, len2; - for ( ; len > 0; tsb += len2, len -= len2 ) { + for (; len > 0; tsb += len2, len -= len2) { len2 = mpegts_word_count(tsb, len, 0xFF9FFFD0); - pid = (tsb[1] & 0x1f) << 8 | tsb[2]; - if((st = elementary_stream_find(&t->s_components, pid)) != NULL) + pid = (tsb[1] & 0x1f) << 8 | tsb[2]; + if ((st = elementary_stream_find(&t->s_components, pid)) != NULL) ts_recv_skipped0(t, st, tsb, len2); } } @@ -257,9 +251,7 @@ ts_skip_packet2(mpegts_service_t *t, const uint8_t *tsb, int len) /* * */ -void -ts_recv_raw(mpegts_service_t *t, uint64_t tspos, const uint8_t *tsb, int len) -{ +void ts_recv_raw(mpegts_service_t* t, uint64_t tspos, const uint8_t* tsb, int len) { int pid, parent = 0; tvh_mutex_lock(&t->s_stream_mutex); @@ -268,7 +260,7 @@ ts_recv_raw(mpegts_service_t *t, uint64_t tspos, const uint8_t *tsb, int len) /* If PID is owned by a slave service, let parent service to * deliver this PID (decrambling) */ - pid = (tsb[1] & 0x1f) << 8 | tsb[2]; + pid = (tsb[1] & 0x1f) << 8 | tsb[2]; parent = mpegts_pid_rexists(t->s_slaves_pids, pid); service_set_streaming_status_flags((service_t*)t, TSS_PACKETS); t->s_streaming_live |= TSS_LIVE; @@ -288,37 +280,33 @@ ts_recv_raw(mpegts_service_t *t, uint64_t tspos, const uint8_t *tsb, int len) /** * */ -static void -ts_flush(mpegts_service_t *t, sbuf_t *sb) -{ +static void ts_flush(mpegts_service_t* t, sbuf_t* sb) { streaming_message_t sm; - pktbuf_t *pb; + pktbuf_t* pb; t->s_tsbuf_last = mclk(); - pb = pktbuf_alloc(sb->sb_data, sb->sb_ptr); + pb = pktbuf_alloc(sb->sb_data, sb->sb_ptr); pb->pb_err = sb->sb_err; memset(&sm, 0, sizeof(sm)); sm.sm_type = SMT_MPEGTS; sm.sm_data = pb; - streaming_service_deliver((service_t *)t, streaming_msg_clone(&sm)); + streaming_service_deliver((service_t*)t, streaming_msg_clone(&sm)); pktbuf_ref_dec(pb); - service_set_streaming_status_flags((service_t *)t, TSS_PACKETS); + service_set_streaming_status_flags((service_t*)t, TSS_PACKETS); t->s_streaming_live |= TSS_LIVE; - sbuf_reset(sb, 2*TS_REMUX_BUFSIZE); + sbuf_reset(sb, 2 * TS_REMUX_BUFSIZE); } /** * */ -static void -ts_remux(mpegts_service_t *t, const uint8_t *src, int len, int errors) -{ - sbuf_t *sb = &t->s_tsbuf; +static void ts_remux(mpegts_service_t* t, const uint8_t* src, int len, int errors) { + sbuf_t* sb = &t->s_tsbuf; if (sb->sb_data == NULL) sbuf_init_fixed(sb, TS_REMUX_BUFSIZE); @@ -326,7 +314,7 @@ ts_remux(mpegts_service_t *t, const uint8_t *src, int len, int errors) sbuf_append(sb, src, len); sb->sb_err += errors; - if(monocmpfastsec(mclk(), t->s_tsbuf_last) && sb->sb_ptr < TS_REMUX_BUFSIZE) + if (monocmpfastsec(mclk(), t->s_tsbuf_last) && sb->sb_ptr < TS_REMUX_BUFSIZE) return; ts_flush(t, sb); @@ -335,10 +323,8 @@ ts_remux(mpegts_service_t *t, const uint8_t *src, int len, int errors) /** * */ -static void -ts_skip(mpegts_service_t *t, const uint8_t *src, int len) -{ - sbuf_t *sb = &t->s_tsbuf; +static void ts_skip(mpegts_service_t* t, const uint8_t* src, int len) { + sbuf_t* sb = &t->s_tsbuf; if (len < 188) return; @@ -348,25 +334,22 @@ ts_skip(mpegts_service_t *t, const uint8_t *src, int len) sb->sb_err += len / 188; - if(monocmpfastsec(mclk(), t->s_tsbuf_last) && - sb->sb_err < (TS_REMUX_BUFSIZE / 188)) + if (monocmpfastsec(mclk(), t->s_tsbuf_last) && sb->sb_err < (TS_REMUX_BUFSIZE / 188)) return; ts_flush(t, sb); - service_send_streaming_status((service_t *)t); + service_send_streaming_status((service_t*)t); } /* * Attempt to re-sync a ts stream (3 valid sync's in a row) */ -int -ts_resync ( const uint8_t *tsb, int *len, int *idx ) -{ +int ts_resync(const uint8_t* tsb, int* len, int* idx) { int err = 1; while (err && (*len > 376)) { - (*idx)++; (*len)--; - err = (tsb[*idx] != 0x47) || (tsb[*idx+188] != 0x47) || - (tsb[*idx+376] != 0x47); + (*idx)++; + (*len)--; + err = (tsb[*idx] != 0x47) || (tsb[*idx + 188] != 0x47) || (tsb[*idx + 376] != 0x47); } return err; } diff --git a/src/input/mpegts/tsdemux.h b/src/input/mpegts/tsdemux.h index e62bb070f..f618b46e5 100644 --- a/src/input/mpegts/tsdemux.h +++ b/src/input/mpegts/tsdemux.h @@ -19,20 +19,24 @@ #ifndef TSDEMUX_H #define TSDEMUX_H -int ts_resync ( const uint8_t *tsb, int *len, int *idx ); +int ts_resync(const uint8_t* tsb, int* len, int* idx); -void ts_recv_packet0 - (struct mpegts_service *t, elementary_stream_t *st, const uint8_t *tsb, int len); +void ts_recv_packet0(struct mpegts_service* t, + elementary_stream_t* st, + const uint8_t* tsb, + int len); -int ts_recv_packet1 - (struct mpegts_service *t, uint64_t tspos, uint16_t pid, - const uint8_t *tsb, int len, int table); +int ts_recv_packet1(struct mpegts_service* t, + uint64_t tspos, + uint16_t pid, + const uint8_t* tsb, + int len, + int table); -void ts_recv_packet2(struct mpegts_service *t, const uint8_t *tsb, int len); +void ts_recv_packet2(struct mpegts_service* t, const uint8_t* tsb, int len); -void ts_skip_packet2(struct mpegts_service *t, const uint8_t *tsb, int len); +void ts_skip_packet2(struct mpegts_service* t, const uint8_t* tsb, int len); -void ts_recv_raw - (struct mpegts_service *t, uint64_t tspos, const uint8_t *tsb, int len); +void ts_recv_raw(struct mpegts_service* t, uint64_t tspos, const uint8_t* tsb, int len); #endif /* TSDEMUX_H */ diff --git a/src/input/mpegts/tsfile.h b/src/input/mpegts/tsfile.h index 87ed5ec4d..845fe6a47 100644 --- a/src/input/mpegts/tsfile.h +++ b/src/input/mpegts/tsfile.h @@ -26,13 +26,13 @@ struct mpegts_mux; struct mpegts_network; /* Initialise system (with N tuners) */ -void tsfile_init ( int tuners ); +void tsfile_init(int tuners); /* Shutdown */ -void tsfile_done ( void ); +void tsfile_done(void); /* Add a new file (multiplex) */ -void tsfile_add_file ( const char *path ); +void tsfile_add_file(const char* path); #endif /* __TVH_TSFILE_H__ */ diff --git a/src/input/mpegts/tsfile/tsfile.c b/src/input/mpegts/tsfile/tsfile.c index 407e06197..aa4502a34 100644 --- a/src/input/mpegts/tsfile/tsfile.c +++ b/src/input/mpegts/tsfile/tsfile.c @@ -26,47 +26,40 @@ /* * Globals */ -tvh_mutex_t tsfile_lock; -mpegts_network_t *tsfile_network; -tsfile_input_list_t tsfile_inputs; +tvh_mutex_t tsfile_lock; +mpegts_network_t* tsfile_network; +tsfile_input_list_t tsfile_inputs; extern const idclass_t mpegts_service_class; extern const idclass_t mpegts_network_class; -static htsmsg_t * -tsfile_service_config_save ( service_t *s, char *filename, size_t fsize ) -{ +static htsmsg_t* tsfile_service_config_save(service_t* s, char* filename, size_t fsize) { return NULL; } -static void -tsfile_service_delete ( service_t *s, int delconf ) -{ +static void tsfile_service_delete(service_t* s, int delconf) { mpegts_service_delete(s, 0); } /* * Network definition */ -static mpegts_service_t * -tsfile_network_create_service - ( mpegts_mux_t *mm, uint16_t sid, uint16_t pmt_pid ) -{ +static mpegts_service_t* +tsfile_network_create_service(mpegts_mux_t* mm, uint16_t sid, uint16_t pmt_pid) { tvh_mutex_lock(&tsfile_lock); - mpegts_service_t *s = mpegts_service_create1(NULL, mm, sid, pmt_pid, NULL); + mpegts_service_t* s = mpegts_service_create1(NULL, mm, sid, pmt_pid, NULL); // TODO: HACK: REMOVE ME if (s) { s->s_config_save = tsfile_service_config_save; - s->s_delete = tsfile_service_delete; + s->s_delete = tsfile_service_delete; tvh_mutex_unlock(&tsfile_lock); - channel_t *c = channel_create(NULL, NULL, NULL); + channel_t* c = channel_create(NULL, NULL, NULL); if (c) { c->ch_dont_save = 1; service_mapper_link((service_t*)s, c, NULL); } - } - else + } else tvh_mutex_unlock(&tsfile_lock); return s; @@ -75,18 +68,16 @@ tsfile_network_create_service /* * Initialise */ -void tsfile_init ( int tuners ) -{ - int i; - tsfile_input_t *mi; +void tsfile_init(int tuners) { + int i; + tsfile_input_t* mi; /* Mutex - used for minor efficiency in service processing */ tvh_mutex_init(&tsfile_lock, NULL); /* Shared network */ tsfile_network = calloc(1, sizeof(*tsfile_network)); - mpegts_network_create0(tsfile_network, &mpegts_network_class, NULL, - "TSfile Network", NULL); + mpegts_network_create0(tsfile_network, &mpegts_network_class, NULL, "TSfile Network", NULL); tsfile_network->mn_create_service = tsfile_network_create_service; /* IPTV like setup */ @@ -95,7 +86,7 @@ void tsfile_init ( int tuners ) mpegts_input_add_network((mpegts_input_t*)mi, tsfile_network); } else { for (i = 0; i < tuners; i++) { - mi = tsfile_input_create(i+1); + mi = tsfile_input_create(i + 1); mpegts_input_add_network((mpegts_input_t*)mi, tsfile_network); } } @@ -104,10 +95,8 @@ void tsfile_init ( int tuners ) /* * Shutdown */ -void -tsfile_done ( void ) -{ - tsfile_input_t *mi; +void tsfile_done(void) { + tsfile_input_t* mi; tvh_mutex_lock(&global_lock); while ((mi = LIST_FIRST(&tsfile_inputs))) { LIST_REMOVE(mi, tsi_link); @@ -122,11 +111,10 @@ tsfile_done ( void ) /* * Add multiplex */ -void tsfile_add_file ( const char *path ) -{ - tsfile_input_t *mi; - mpegts_mux_t *mm; - char *uuid = NULL, *tok; +void tsfile_add_file(const char* path) { + tsfile_input_t* mi; + mpegts_mux_t* mm; + char * uuid = NULL, *tok; char tmp[strlen(path) + 1]; strcpy(tmp, path); @@ -139,14 +127,14 @@ void tsfile_add_file ( const char *path ) } tvhtrace(LS_TSFILE, "add file %s (uuid:%s)", path, uuid); - + /* Create logical instance */ - mm = tsfile_mux_create(uuid, tsfile_network); + mm = tsfile_mux_create(uuid, tsfile_network); mm->mm_tsid_accept_zero_value = 1; mpegts_mux_post_create(mm); - + /* Create physical instance (for each tuner) */ - LIST_FOREACH(mi, &tsfile_inputs, tsi_link) + LIST_FOREACH (mi, &tsfile_inputs, tsi_link) tsfile_mux_instance_create(path, (mpegts_input_t*)mi, mm); } diff --git a/src/input/mpegts/tsfile/tsfile_input.c b/src/input/mpegts/tsfile/tsfile_input.c index 3615fef92..3ebd71b22 100644 --- a/src/input/mpegts/tsfile/tsfile_input.c +++ b/src/input/mpegts/tsfile/tsfile_input.c @@ -33,23 +33,20 @@ extern const idclass_t mpegts_input_class; - -static void * -tsfile_input_thread ( void *aux ) -{ - int fd = -1, nfds; - size_t len, rem; - ssize_t c; - tvhpoll_t *efd; - tvhpoll_event_t ev; - struct stat st; - sbuf_t buf; - mpegts_pcr_t pcr; - int64_t pcr_last = PTS_UNSET; - int64_t pcr_last_mono = 0; - tsfile_input_t *mi = aux; - mpegts_mux_instance_t *mmi; - tsfile_mux_instance_t *tmi; +static void* tsfile_input_thread(void* aux) { + int fd = -1, nfds; + size_t len, rem; + ssize_t c; + tvhpoll_t* efd; + tvhpoll_event_t ev; + struct stat st; + sbuf_t buf; + mpegts_pcr_t pcr; + int64_t pcr_last = PTS_UNSET; + int64_t pcr_last_mono = 0; + tsfile_input_t* mi = aux; + mpegts_mux_instance_t* mmi; + tsfile_mux_instance_t* tmi; /* Open file */ tvh_mutex_lock(&global_lock); @@ -58,14 +55,14 @@ tsfile_input_thread ( void *aux ) tmi = (tsfile_mux_instance_t*)mmi; fd = tvh_open(tmi->mmi_tsfile_path, O_RDONLY | O_NONBLOCK, 0); if (fd == -1) - tvherror(LS_TSFILE, "open(%s) failed %d (%s)", - tmi->mmi_tsfile_path, errno, strerror(errno)); + tvherror(LS_TSFILE, "open(%s) failed %d (%s)", tmi->mmi_tsfile_path, errno, strerror(errno)); else tvhtrace(LS_TSFILE, "adapter %d opened %s", mi->mi_instance, tmi->mmi_tsfile_path); } tvh_mutex_unlock(&global_lock); - if (fd == -1) return NULL; - + if (fd == -1) + return NULL; + /* Polling */ efd = tvhpoll_create(2); tvhpoll_add1(efd, mi->ti_thread_pipe.rd, TVHPOLL_IN, NULL); @@ -75,44 +72,46 @@ tsfile_input_thread ( void *aux ) /* Get file length */ if (fstat(fd, &st)) { - tvherror(LS_TSFILE, "stat() failed %d (%s)", - errno, strerror(errno)); + tvherror(LS_TSFILE, "stat() failed %d (%s)", errno, strerror(errno)); goto exit; } /* Check for extra (incomplete) packet at end */ rem = st.st_size % 188; len = 0; - tvhtrace(LS_TSFILE, "adapter %d file size %jd rem %zu", - mi->mi_instance, (intmax_t)st.st_size, rem); + tvhtrace(LS_TSFILE, + "adapter %d file size %jd rem %zu", + mi->mi_instance, + (intmax_t)st.st_size, + rem); pcr_last_mono = getfastmonoclock(); - + /* Process input */ while (1) { - + /* Find PCR PID */ - if (tmi->mmi_tsfile_pcr_pid == MPEGTS_PID_NONE) { - mpegts_service_t *s; + if (tmi->mmi_tsfile_pcr_pid == MPEGTS_PID_NONE) { + mpegts_service_t* s; tvh_mutex_lock(&tsfile_lock); - LIST_FOREACH(s, &tmi->mmi_mux->mm_services, s_dvb_mux_link) { + LIST_FOREACH (s, &tmi->mmi_mux->mm_services, s_dvb_mux_link) { if (s->s_components.set_pcr_pid) tmi->mmi_tsfile_pcr_pid = s->s_components.set_pcr_pid; } tvh_mutex_unlock(&tsfile_lock); } - + /* Check for terminate */ nfds = tvhpoll_wait(efd, &ev, 1, 0); - if (nfds == 1) break; - + if (nfds == 1) + break; + /* Read */ c = sbuf_read(&buf, fd); if (c < 0) { if (ERRNO_AGAIN(errno)) continue; - tvherror(LS_TSFILE, "read() error %d (%s)", - errno, strerror(errno)); + tvherror(LS_TSFILE, "read() error %d (%s)", errno, strerror(errno)); break; } len += c; @@ -166,11 +165,9 @@ exit: return NULL; } -static void -tsfile_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ - int err; - tsfile_input_t *ti = (tsfile_input_t*)mi; +static void tsfile_input_stop_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { + int err; + tsfile_input_t* ti = (tsfile_input_t*)mi; /* Stop thread */ if (ti->ti_thread_pipe.rd != -1) { @@ -186,13 +183,11 @@ tsfile_input_stop_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) LIST_REMOVE(mmi, mmi_active_link); } -static int -tsfile_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *t, int weight ) -{ - struct stat st; - mpegts_mux_t *mm = t->mmi_mux; - tsfile_mux_instance_t *mmi = (tsfile_mux_instance_t*)t; - tsfile_input_t *ti = (tsfile_input_t*)mi; +static int tsfile_input_start_mux(mpegts_input_t* mi, mpegts_mux_instance_t* t, int weight) { + struct stat st; + mpegts_mux_t* mm = t->mmi_mux; + tsfile_mux_instance_t* mmi = (tsfile_mux_instance_t*)t; + tsfile_input_t* ti = (tsfile_input_t*)mi; tvhtrace(LS_TSFILE, "adapter %d starting mmi %p", mi->mi_instance, mmi); /* Already tuned */ @@ -205,8 +200,7 @@ tsfile_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *t, int weigh /* Check file is accessible */ if (lstat(mmi->mmi_tsfile_path, &st)) { - tvherror(LS_TSFILE, "mmi %p could not stat '%s' (%i)", - mmi, mmi->mmi_tsfile_path, errno); + tvherror(LS_TSFILE, "mmi %p could not stat '%s' (%i)", mmi, mmi->mmi_tsfile_path, errno); mmi->mmi_tune_failed = 1; return SM_CODE_TUNING_FAILED; } @@ -231,20 +225,16 @@ tsfile_input_start_mux ( mpegts_input_t *mi, mpegts_mux_instance_t *t, int weigh return 0; } -tsfile_input_t * -tsfile_input_create ( int idx ) -{ - tsfile_input_t *mi; +tsfile_input_t* tsfile_input_create(int idx) { + tsfile_input_t* mi; /* Create object */ mi = (tsfile_input_t*) - mpegts_input_create0(calloc(1, sizeof(tsfile_input_t)), - &mpegts_input_class, - NULL, NULL); - mi->mi_instance = idx; - mi->mi_enabled = 1; - mi->mi_start_mux = tsfile_input_start_mux; - mi->mi_stop_mux = tsfile_input_stop_mux; + mpegts_input_create0(calloc(1, sizeof(tsfile_input_t)), &mpegts_input_class, NULL, NULL); + mi->mi_instance = idx; + mi->mi_enabled = 1; + mi->mi_start_mux = tsfile_input_start_mux; + mi->mi_stop_mux = tsfile_input_stop_mux; LIST_INSERT_HEAD(&tsfile_inputs, mi, tsi_link); if (!mi->mi_name) mi->mi_name = strdup("TSFile"); diff --git a/src/input/mpegts/tsfile/tsfile_mux.c b/src/input/mpegts/tsfile/tsfile_mux.c index 4cfb40816..6434d7f1c 100644 --- a/src/input/mpegts/tsfile/tsfile_mux.c +++ b/src/input/mpegts/tsfile/tsfile_mux.c @@ -22,22 +22,17 @@ extern const idclass_t mpegts_mux_class; extern const idclass_t mpegts_mux_instance_class; -static void -tsfile_mux_instance_delete( tvh_input_instance_t *tii ) -{ - tsfile_mux_instance_t *mmi = (tsfile_mux_instance_t *)tii; +static void tsfile_mux_instance_delete(tvh_input_instance_t* tii) { + tsfile_mux_instance_t* mmi = (tsfile_mux_instance_t*)tii; free(mmi->mmi_tsfile_path); mpegts_mux_instance_delete(tii); } -tsfile_mux_instance_t * -tsfile_mux_instance_create - ( const char *path, mpegts_input_t *mi, mpegts_mux_t *mm ) -{ +tsfile_mux_instance_t* +tsfile_mux_instance_create(const char* path, mpegts_input_t* mi, mpegts_mux_t* mm) { #define tsfile_mux_instance_class mpegts_mux_instance_class - tsfile_mux_instance_t *mmi = - mpegts_mux_instance_create(tsfile_mux_instance, NULL, mi, mm); + tsfile_mux_instance_t* mmi = mpegts_mux_instance_create(tsfile_mux_instance, NULL, mi, mm); #undef tsfile_mux_instance_class mmi->mmi_tsfile_path = strdup(path); mmi->mmi_tsfile_pcr_pid = MPEGTS_PID_NONE; @@ -46,24 +41,18 @@ tsfile_mux_instance_create return mmi; } -static htsmsg_t * -iptv_mux_config_save ( mpegts_mux_t *m, char *filename, size_t fsize ) -{ +static htsmsg_t* iptv_mux_config_save(mpegts_mux_t* m, char* filename, size_t fsize) { return NULL; } -mpegts_mux_t * -tsfile_mux_create ( const char *uuid, mpegts_network_t *mn ) -{ - mpegts_mux_t *mm - = mpegts_mux_create1(uuid, mn, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, NULL); +mpegts_mux_t* tsfile_mux_create(const char* uuid, mpegts_network_t* mn) { + mpegts_mux_t* mm = mpegts_mux_create1(uuid, mn, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, NULL); mm->mm_config_save = iptv_mux_config_save; - mm->mm_epg = MM_EPG_DISABLE; + mm->mm_epg = MM_EPG_DISABLE; tvhtrace(LS_TSFILE, "mm created %p", mm); return mm; } - /****************************************************************************** * Editor Configuration * diff --git a/src/input/mpegts/tsfile/tsfile_private.h b/src/input/mpegts/tsfile/tsfile_private.h index cbf903a6b..d6a1c2b13 100644 --- a/src/input/mpegts/tsfile/tsfile_private.h +++ b/src/input/mpegts/tsfile/tsfile_private.h @@ -27,58 +27,53 @@ */ typedef struct tsfile_input tsfile_input_t; typedef struct tsfile_mux_instance tsfile_mux_instance_t; -typedef LIST_HEAD(,tsfile_input) tsfile_input_list_t; +typedef LIST_HEAD(, tsfile_input) tsfile_input_list_t; /* * Globals */ -extern mpegts_network_t *tsfile_network; +extern mpegts_network_t* tsfile_network; extern tsfile_input_list_t tsfile_inputs; -extern tvh_mutex_t tsfile_lock; - +extern tvh_mutex_t tsfile_lock; /* * Mux instance */ -struct tsfile_mux_instance -{ +struct tsfile_mux_instance { mpegts_mux_instance_t; ///< Parent obj /* * Timing */ - /* * File input */ - - char *mmi_tsfile_path; ///< Source file path - uint16_t mmi_tsfile_pcr_pid; ///< Timing control + + char* mmi_tsfile_path; ///< Source file path + uint16_t mmi_tsfile_pcr_pid; ///< Timing control }; /* * TS file input */ -struct tsfile_input -{ +struct tsfile_input { mpegts_input_t; LIST_ENTRY(tsfile_input) tsi_link; - th_pipe_t ti_thread_pipe; - pthread_t ti_thread_id; + th_pipe_t ti_thread_pipe; + pthread_t ti_thread_id; }; /* * Prototypes */ -tsfile_input_t *tsfile_input_create ( int idx ); +tsfile_input_t* tsfile_input_create(int idx); -tsfile_mux_instance_t *tsfile_mux_instance_create - ( const char *path, mpegts_input_t *mi, mpegts_mux_t *mm ); +tsfile_mux_instance_t* +tsfile_mux_instance_create(const char* path, mpegts_input_t* mi, mpegts_mux_t* mm); -mpegts_mux_t * -tsfile_mux_create ( const char *uuid, mpegts_network_t *mn ); +mpegts_mux_t* tsfile_mux_create(const char* uuid, mpegts_network_t* mn); #endif /* __TVH_TSFILE_PRIVATE_H__ */ diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun.c index f8914d61b..81e9405be 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun.c @@ -32,45 +32,41 @@ #include "config.h" -#if defined(HDHOMERUN_TAG_DEVICE_AUTH_BIN) \ - || defined(HDHOMERUN_TAG_DEVICE_AUTH_BIN_DEPRECATED) -#define hdhomerun_discover_find_devices_custom \ - hdhomerun_discover_find_devices_custom_v2 +#if defined(HDHOMERUN_TAG_DEVICE_AUTH_BIN) || defined(HDHOMERUN_TAG_DEVICE_AUTH_BIN_DEPRECATED) +#define hdhomerun_discover_find_devices_custom hdhomerun_discover_find_devices_custom_v2 #endif -static htsmsg_t * -tvhdhomerun_device_class_save ( idnode_t *in, char *filename, size_t fsize ) -{ - tvhdhomerun_device_t *hd = (tvhdhomerun_device_t *)in; - tvhdhomerun_frontend_t *lfe; - htsmsg_t *m, *l; - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* tvhdhomerun_device_class_save(idnode_t* in, char* filename, size_t fsize) { + tvhdhomerun_device_t* hd = (tvhdhomerun_device_t*)in; + tvhdhomerun_frontend_t* lfe; + htsmsg_t * m, *l; + char ubuf[UUID_HEX_SIZE]; m = htsmsg_create_map(); idnode_save(&hd->th_id, m); if (filename) { l = htsmsg_create_map(); - TAILQ_FOREACH(lfe, &hd->hd_frontends, hf_link) + TAILQ_FOREACH (lfe, &hd->hd_frontends, hf_link) tvhdhomerun_frontend_save(lfe, l); htsmsg_add_msg(m, "frontends", l); - snprintf(filename, fsize, "input/tvhdhomerun/adapters/%s", - idnode_uuid_as_str(&hd->th_id, ubuf)); + snprintf(filename, + fsize, + "input/tvhdhomerun/adapters/%s", + idnode_uuid_as_str(&hd->th_id, ubuf)); } htsmsg_add_str(m, "fe_override", hd->hd_override_type); return m; } -static idnode_set_t * -tvhdhomerun_device_class_get_childs ( idnode_t *in ) -{ - tvhdhomerun_device_t *hd = (tvhdhomerun_device_t *)in; - idnode_set_t *is = idnode_set_create(0); - tvhdhomerun_frontend_t *lfe; +static idnode_set_t* tvhdhomerun_device_class_get_childs(idnode_t* in) { + tvhdhomerun_device_t* hd = (tvhdhomerun_device_t*)in; + idnode_set_t* is = idnode_set_create(0); + tvhdhomerun_frontend_t* lfe; - TAILQ_FOREACH(lfe, &hd->hd_frontends, hf_link) + TAILQ_FOREACH (lfe, &hd->hd_frontends, hf_link) idnode_set_add(is, &lfe->ti_id, NULL, NULL); return is; } @@ -81,43 +77,36 @@ typedef struct tvhdhomerun_discovery { TAILQ_HEAD(tvhdhomerun_discovery_queue, tvhdhomerun_discovery); -static int tvhdhomerun_discoveries_count; +static int tvhdhomerun_discoveries_count; static struct tvhdhomerun_discovery_queue tvhdhomerun_discoveries; -static pthread_t tvhdhomerun_discovery_tid; +static pthread_t tvhdhomerun_discovery_tid; static tvh_mutex_t tvhdhomerun_discovery_lock; -static tvh_cond_t tvhdhomerun_discovery_cond; +static tvh_cond_t tvhdhomerun_discovery_cond; static void -tvhdhomerun_device_class_get_title - ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) -{ - tvhdhomerun_device_t *hd = (tvhdhomerun_device_t *)in; - char ip[64]; +tvhdhomerun_device_class_get_title(idnode_t* in, const char* lang, char* dst, size_t dstsize) { + tvhdhomerun_device_t* hd = (tvhdhomerun_device_t*)in; + char ip[64]; tcp_get_str_from_ip(&hd->hd_info.ip_address, ip, sizeof(ip)); - snprintf(dst, dstsize, - "%s - %s", hd->hd_info.friendlyname, ip); + snprintf(dst, dstsize, "%s - %s", hd->hd_info.friendlyname, ip); } -static const void * -tvhdhomerun_device_class_active_get ( void * obj ) -{ - static int active; - tvhdhomerun_device_t *hd = (tvhdhomerun_device_t *)obj; - tvhdhomerun_frontend_t *lfe; +static const void* tvhdhomerun_device_class_active_get(void* obj) { + static int active; + tvhdhomerun_device_t* hd = (tvhdhomerun_device_t*)obj; + tvhdhomerun_frontend_t* lfe; active = 0; - TAILQ_FOREACH(lfe, &hd->hd_frontends, hf_link) - if (*(int *)mpegts_input_class_active_get(lfe)) { + TAILQ_FOREACH (lfe, &hd->hd_frontends, hf_link) + if (*(int*)mpegts_input_class_active_get(lfe)) { active = 1; break; } return &active; } -static htsmsg_t * -tvhdhomerun_device_class_override_enum( void * p, const char *lang ) -{ - htsmsg_t *m = htsmsg_create_list(); +static htsmsg_t* tvhdhomerun_device_class_override_enum(void* p, const char* lang) { + htsmsg_t* m = htsmsg_create_list(); htsmsg_add_str(m, NULL, "DVB-T"); htsmsg_add_str(m, NULL, "DVB-C"); htsmsg_add_str(m, NULL, "ATSC-T"); @@ -127,13 +116,11 @@ tvhdhomerun_device_class_override_enum( void * p, const char *lang ) return m; } -static int -tvhdhomerun_device_class_override_set( void *obj, const void * p ) -{ - tvhdhomerun_device_t *hd = obj; - const char *s = p; - if ( s != NULL && strlen(s) > 0 ) { - if ( hd->hd_override_type != NULL && strcmp(hd->hd_override_type,s) != 0 ) { +static int tvhdhomerun_device_class_override_set(void* obj, const void* p) { + tvhdhomerun_device_t* hd = obj; + const char* s = p; + if (s != NULL && strlen(s) > 0) { + if (hd->hd_override_type != NULL && strcmp(hd->hd_override_type, s) != 0) { free(hd->hd_override_type); hd->hd_override_type = strdup(p); tvhinfo(LS_TVHDHOMERUN, "Setting override_type : %s", hd->hd_override_type); @@ -143,33 +130,30 @@ tvhdhomerun_device_class_override_set( void *obj, const void * p ) return 0; } -static void -tvhdhomerun_device_class_override_notify( void * obj, const char *lang ) -{ - tvhdhomerun_device_t *hd = obj; - tvhdhomerun_frontend_t *hfe; - dvb_fe_type_t type = dvb_str2type(hd->hd_override_type); +static void tvhdhomerun_device_class_override_notify(void* obj, const char* lang) { + tvhdhomerun_device_t* hd = obj; + tvhdhomerun_frontend_t* hfe; + dvb_fe_type_t type = dvb_str2type(hd->hd_override_type); struct hdhomerun_discover_device_t discover_info; - unsigned int tuner; - htsmsg_t *conf; + unsigned int tuner; + htsmsg_t* conf; conf = hts_settings_load("input/tvhdhomerun/adapters/%s", hd->hd_info.uuid); if (conf) { - htsmsg_t *subconf = htsmsg_get_map(conf, "frontends"); + htsmsg_t* subconf = htsmsg_get_map(conf, "frontends"); htsmsg_destroy(conf); conf = subconf; } lock_assert(&global_lock); - while ((hfe = TAILQ_FIRST(&hd->hd_frontends)) != NULL) - { + while ((hfe = TAILQ_FIRST(&hd->hd_frontends)) != NULL) { if (hfe->hf_type == type) break; discover_info.device_id = hdhomerun_device_get_device_id(hfe->hf_hdhomerun_tuner); - discover_info.ip_addr = hdhomerun_device_get_device_ip(hfe->hf_hdhomerun_tuner); - tuner = hfe->hf_tunerNumber; + discover_info.ip_addr = hdhomerun_device_get_device_ip(hfe->hf_hdhomerun_tuner); + tuner = hfe->hf_tunerNumber; tvhdhomerun_frontend_delete(hfe); @@ -177,82 +161,72 @@ tvhdhomerun_device_class_override_notify( void * obj, const char *lang ) } } -static const void * -tvhdhomerun_device_class_get_ip_address ( void *obj ) -{ - tvhdhomerun_device_t *hd = obj; +static const void* tvhdhomerun_device_class_get_ip_address(void* obj) { + tvhdhomerun_device_t* hd = obj; tcp_get_str_from_ip(&hd->hd_info.ip_address, prop_sbuf, PROP_SBUF_LEN); return &prop_sbuf_ptr; } -const idclass_t tvhdhomerun_device_class = -{ - .ic_class = "tvhdhomerun_client", - .ic_caption = N_("tvhdhomerun client"), - .ic_save = tvhdhomerun_device_class_save, - .ic_get_childs = tvhdhomerun_device_class_get_childs, - .ic_get_title = tvhdhomerun_device_class_get_title, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "active", - .name = N_("Active"), - .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, - .get = tvhdhomerun_device_class_active_get, - }, - { - .type = PT_STR, - .id = "networkType", - .name = N_("Network"), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(tvhdhomerun_device_t, hd_override_type), - }, - { - .type = PT_STR, - .id = "ip_address", - .name = N_("IP address"), - .opts = PO_RDONLY | PO_NOSAVE, - .get = tvhdhomerun_device_class_get_ip_address, - }, - { - .type = PT_STR, - .id = "uuid", - .name = N_("UUID"), - .opts = PO_RDONLY, - .off = offsetof(tvhdhomerun_device_t, hd_info.uuid), - }, - { - .type = PT_STR, - .id = "friendly", - .name = N_("Friendly name"), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(tvhdhomerun_device_t, hd_info.friendlyname), - }, - { - .type = PT_STR, - .id = "deviceModel", - .name = N_("Device model"), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(tvhdhomerun_device_t, hd_info.deviceModel), - }, - { - .type = PT_STR, - .id = "fe_override", - .name = N_("Network type"), - .opts = PO_ADVANCED, - .set = tvhdhomerun_device_class_override_set, - .notify = tvhdhomerun_device_class_override_notify, - .list = tvhdhomerun_device_class_override_enum, - .off = offsetof(tvhdhomerun_device_t, hd_type), - }, - {} - } -}; - - -static void -tvhdhomerun_discovery_destroy(tvhdhomerun_discovery_t *d, int unlink) -{ +const idclass_t tvhdhomerun_device_class = {.ic_class = "tvhdhomerun_client", + .ic_caption = N_("tvhdhomerun client"), + .ic_save = tvhdhomerun_device_class_save, + .ic_get_childs = tvhdhomerun_device_class_get_childs, + .ic_get_title = tvhdhomerun_device_class_get_title, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "active", + .name = N_("Active"), + .opts = PO_RDONLY | PO_NOSAVE | PO_NOUI, + .get = tvhdhomerun_device_class_active_get, + }, + { + .type = PT_STR, + .id = "networkType", + .name = N_("Network"), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(tvhdhomerun_device_t, hd_override_type), + }, + { + .type = PT_STR, + .id = "ip_address", + .name = N_("IP address"), + .opts = PO_RDONLY | PO_NOSAVE, + .get = tvhdhomerun_device_class_get_ip_address, + }, + { + .type = PT_STR, + .id = "uuid", + .name = N_("UUID"), + .opts = PO_RDONLY, + .off = offsetof(tvhdhomerun_device_t, hd_info.uuid), + }, + { + .type = PT_STR, + .id = "friendly", + .name = N_("Friendly name"), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(tvhdhomerun_device_t, hd_info.friendlyname), + }, + { + .type = PT_STR, + .id = "deviceModel", + .name = N_("Device model"), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(tvhdhomerun_device_t, hd_info.deviceModel), + }, + { + .type = PT_STR, + .id = "fe_override", + .name = N_("Network type"), + .opts = PO_ADVANCED, + .set = tvhdhomerun_device_class_override_set, + .notify = tvhdhomerun_device_class_override_notify, + .list = tvhdhomerun_device_class_override_enum, + .off = offsetof(tvhdhomerun_device_t, hd_type), + }, + {}}}; + +static void tvhdhomerun_discovery_destroy(tvhdhomerun_discovery_t* d, int unlink) { if (d == NULL) return; if (unlink) { @@ -262,9 +236,7 @@ tvhdhomerun_discovery_destroy(tvhdhomerun_discovery_t *d, int unlink) free(d); } -static void -tvhdhomerun_device_calc_bin_uuid( uint8_t *uuid, const uint32_t device_id ) -{ +static void tvhdhomerun_device_calc_bin_uuid(uint8_t* uuid, const uint32_t device_id) { SHA_CTX sha1; SHA1_Init(&sha1); @@ -272,48 +244,43 @@ tvhdhomerun_device_calc_bin_uuid( uint8_t *uuid, const uint32_t device_id ) SHA1_Final(uuid, &sha1); } -static void -tvhdhomerun_device_calc_uuid( char *uhex, const uint32_t device_id ) -{ +static void tvhdhomerun_device_calc_uuid(char* uhex, const uint32_t device_id) { uint8_t uuidbin[20]; tvhdhomerun_device_calc_bin_uuid(uuidbin, device_id); bin2hex(uhex, UUID_HEX_SIZE, uuidbin, sizeof(uuidbin)); } -static tvhdhomerun_device_t * -tvhdhomerun_device_find( uint32_t device_id ) -{ - tvh_hardware_t *th; - uint8_t binuuid[20]; +static tvhdhomerun_device_t* tvhdhomerun_device_find(uint32_t device_id) { + tvh_hardware_t* th; + uint8_t binuuid[20]; tvhdhomerun_device_calc_bin_uuid(binuuid, device_id); - TVH_HARDWARE_FOREACH(th) { + TVH_HARDWARE_FOREACH (th) { if (idnode_is_instance(&th->th_id, &tvhdhomerun_device_class) && memcmp(th->th_id.in_uuid.bin, binuuid, UUID_BIN_SIZE) == 0) - return (tvhdhomerun_device_t *)th; + return (tvhdhomerun_device_t*)th; } return NULL; } - #define MAX_HDHOMERUN_DEVICES 8 -static void tvhdhomerun_device_create(struct hdhomerun_discover_device_t *dInfo) { +static void tvhdhomerun_device_create(struct hdhomerun_discover_device_t* dInfo) { - tvhdhomerun_device_t *hd = calloc(1, sizeof(tvhdhomerun_device_t)); - htsmsg_t *conf = NULL, *feconf = NULL; - char uhex[UUID_HEX_SIZE]; - int j, save = 0; - struct hdhomerun_device_t *hdhomerun_tuner; - dvb_fe_type_t type = DVB_TYPE_C; + tvhdhomerun_device_t* hd = calloc(1, sizeof(tvhdhomerun_device_t)); + htsmsg_t * conf = NULL, *feconf = NULL; + char uhex[UUID_HEX_SIZE]; + int j, save = 0; + struct hdhomerun_device_t* hdhomerun_tuner; + dvb_fe_type_t type = DVB_TYPE_C; tvhdhomerun_device_calc_uuid(uhex, dInfo->device_id); hdhomerun_tuner = hdhomerun_device_create(dInfo->device_id, dInfo->ip_addr, 0, NULL); { - const char *deviceModel = hdhomerun_device_get_model_str(hdhomerun_tuner); - if(deviceModel != NULL) { + const char* deviceModel = hdhomerun_device_get_model_str(hdhomerun_tuner); + if (deviceModel != NULL) { hd->hd_info.deviceModel = strdup(deviceModel); } hdhomerun_device_destroy(hdhomerun_tuner); @@ -321,16 +288,15 @@ static void tvhdhomerun_device_create(struct hdhomerun_discover_device_t *dInfo) conf = hts_settings_load("input/tvhdhomerun/adapters/%s", uhex); - if ( conf != NULL ) { - const char *override_type = htsmsg_get_str(conf, "fe_override"); - if ( override_type != NULL) { - if ( !strcmp(override_type, "ATSC" ) ) + if (conf != NULL) { + const char* override_type = htsmsg_get_str(conf, "fe_override"); + if (override_type != NULL) { + if (!strcmp(override_type, "ATSC")) override_type = "ATSC-T"; type = dvb_str2type(override_type); - if ( ! ( type == DVB_TYPE_C || type == DVB_TYPE_T || - type == DVB_TYPE_ATSC_T || type == DVB_TYPE_ATSC_C || - type == DVB_TYPE_ISDB_T || type == DVB_TYPE_ISDB_C || - type == DVB_TYPE_CABLECARD ) ) { + if (!(type == DVB_TYPE_C || type == DVB_TYPE_T || type == DVB_TYPE_ATSC_T || + type == DVB_TYPE_ATSC_C || type == DVB_TYPE_ISDB_T || type == DVB_TYPE_ISDB_C || + type == DVB_TYPE_CABLECARD)) { type = DVB_TYPE_C; } } @@ -354,8 +320,7 @@ static void tvhdhomerun_device_create(struct hdhomerun_discover_device_t *dInfo) hd->hd_pids_max = 32; hd->hd_pids_deladd = 1; - if (!tvh_hardware_create0((tvh_hardware_t*)hd, &tvhdhomerun_device_class, - uhex, conf)) + if (!tvh_hardware_create0((tvh_hardware_t*)hd, &tvhdhomerun_device_class, uhex, conf)) return; TAILQ_INIT(&hd->hd_frontends); @@ -365,37 +330,38 @@ static void tvhdhomerun_device_create(struct hdhomerun_discover_device_t *dInfo) free(hd->hd_info.uuid); char fName[128]; - snprintf(fName, 128, "HDHomeRun(%08X)",dInfo->device_id); + snprintf(fName, 128, "HDHomeRun(%08X)", dInfo->device_id); memset(&hd->hd_info.ip_address, 0, sizeof(hd->hd_info.ip_address)); - hd->hd_info.ip_address.ss_family = AF_INET; - ((struct sockaddr_in *)&hd->hd_info.ip_address)->sin_addr.s_addr = htonl(dInfo->ip_addr); - hd->hd_info.uuid = strdup(uhex); - hd->hd_info.friendlyname = strdup(fName); + hd->hd_info.ip_address.ss_family = AF_INET; + ((struct sockaddr_in*)&hd->hd_info.ip_address)->sin_addr.s_addr = htonl(dInfo->ip_addr); + hd->hd_info.uuid = strdup(uhex); + hd->hd_info.friendlyname = strdup(fName); if (conf) feconf = htsmsg_get_map(conf, "frontends"); save = !conf || !feconf; for (j = 0; j < dInfo->tuner_count; ++j) { - if (tvhdhomerun_frontend_create(hd, dInfo, feconf, type, j)) { - tvhinfo(LS_TVHDHOMERUN, "Created frontend %08X tuner %d", dInfo->device_id, j); - } else { - tvherror(LS_TVHDHOMERUN, "Unable to create frontend-device. ( %08x-%d )", dInfo->device_id,j); - } + if (tvhdhomerun_frontend_create(hd, dInfo, feconf, type, j)) { + tvhinfo(LS_TVHDHOMERUN, "Created frontend %08X tuner %d", dInfo->device_id, j); + } else { + tvherror(LS_TVHDHOMERUN, + "Unable to create frontend-device. ( %08x-%d )", + dInfo->device_id, + j); + } } - if (save) tvhdhomerun_device_changed(hd); htsmsg_destroy(conf); } -static uint32_t -tvhdhomerun_ip( void ) -{ - if (*config.hdhomerun_ip == 0) return 0; +static uint32_t tvhdhomerun_ip(void) { + if (*config.hdhomerun_ip == 0) + return 0; uint32_t ip = 0; if (inet_pton(AF_INET, config.hdhomerun_ip, &ip)) @@ -406,39 +372,38 @@ tvhdhomerun_ip( void ) return ip; } -static void * -tvhdhomerun_device_discovery_thread( void *aux ) -{ +static void* tvhdhomerun_device_discovery_thread(void* aux) { struct hdhomerun_discover_device_t result_list[MAX_HDHOMERUN_DEVICES]; - int numDevices, brk; + int numDevices, brk; while (tvheadend_is_running()) { - numDevices = - hdhomerun_discover_find_devices_custom(tvhdhomerun_ip(), - HDHOMERUN_DEVICE_TYPE_TUNER, - HDHOMERUN_DEVICE_ID_WILDCARD, - result_list, - MAX_HDHOMERUN_DEVICES); + numDevices = hdhomerun_discover_find_devices_custom(tvhdhomerun_ip(), + HDHOMERUN_DEVICE_TYPE_TUNER, + HDHOMERUN_DEVICE_ID_WILDCARD, + result_list, + MAX_HDHOMERUN_DEVICES); if (numDevices > 0) { - while (numDevices > 0 ) { + while (numDevices > 0) { numDevices--; struct hdhomerun_discover_device_t* cDev = &result_list[numDevices]; - if ( cDev->device_type == HDHOMERUN_DEVICE_TYPE_TUNER ) { + if (cDev->device_type == HDHOMERUN_DEVICE_TYPE_TUNER) { tvh_mutex_lock(&global_lock); - tvhdhomerun_device_t *existing = tvhdhomerun_device_find(cDev->device_id); - if ( tvheadend_is_running() ) { - if ( !existing ) { - tvhinfo(LS_TVHDHOMERUN,"Found HDHomerun device %08x with %d tuners", - cDev->device_id, cDev->tuner_count); + tvhdhomerun_device_t* existing = tvhdhomerun_device_find(cDev->device_id); + if (tvheadend_is_running()) { + if (!existing) { + tvhinfo(LS_TVHDHOMERUN, + "Found HDHomerun device %08x with %d tuners", + cDev->device_id, + cDev->tuner_count); tvhdhomerun_device_create(cDev); - } else if ( ((struct sockaddr_in *)&existing->hd_info.ip_address)->sin_addr.s_addr != - htonl(cDev->ip_addr) ) { + } else if (((struct sockaddr_in*)&existing->hd_info.ip_address)->sin_addr.s_addr != + htonl(cDev->ip_addr)) { struct sockaddr_storage detected_dev_addr; memset(&detected_dev_addr, 0, sizeof(detected_dev_addr)); - detected_dev_addr.ss_family = AF_INET; - ((struct sockaddr_in *)&detected_dev_addr)->sin_addr.s_addr = htonl(cDev->ip_addr); + detected_dev_addr.ss_family = AF_INET; + ((struct sockaddr_in*)&detected_dev_addr)->sin_addr.s_addr = htonl(cDev->ip_addr); char existing_ip[64]; tcp_get_str_from_ip(&existing->hd_info.ip_address, existing_ip, sizeof(existing_ip)); @@ -446,8 +411,11 @@ tvhdhomerun_device_discovery_thread( void *aux ) char detected_ip[64]; tcp_get_str_from_ip(&detected_dev_addr, detected_ip, sizeof(detected_ip)); - tvhinfo(LS_TVHDHOMERUN,"HDHomerun device %08x switched IPs from %s to %s, updating", - cDev->device_id, existing_ip, detected_ip); + tvhinfo(LS_TVHDHOMERUN, + "HDHomerun device %08x switched IPs from %s to %s, updating", + cDev->device_id, + existing_ip, + detected_ip); tvhdhomerun_device_destroy(existing); tvhdhomerun_device_create(cDev); } @@ -461,8 +429,8 @@ tvhdhomerun_device_discovery_thread( void *aux ) brk = 0; if (tvheadend_is_running()) { brk = tvh_cond_timedwait(&tvhdhomerun_discovery_cond, - &tvhdhomerun_discovery_lock, - mclk() + sec2mono(15)); + &tvhdhomerun_discovery_lock, + mclk() + sec2mono(15)); brk = !ERRNO_AGAIN(brk) && brk != ETIMEDOUT; } tvh_mutex_unlock(&tvhdhomerun_discovery_lock); @@ -473,10 +441,9 @@ tvhdhomerun_device_discovery_thread( void *aux ) return NULL; } -void tvhdhomerun_init ( void ) -{ +void tvhdhomerun_init(void) { hdhomerun_debug_obj = hdhomerun_debug_create(); - const char *s = getenv("TVHEADEND_HDHOMERUN_DEBUG"); + const char* s = getenv("TVHEADEND_HDHOMERUN_DEBUG"); if (s != NULL && *s) { hdhomerun_debug_set_filename(hdhomerun_debug_obj, s); @@ -492,14 +459,15 @@ void tvhdhomerun_init ( void ) TAILQ_INIT(&tvhdhomerun_discoveries); tvh_mutex_init(&tvhdhomerun_discovery_lock, NULL); tvh_cond_init(&tvhdhomerun_discovery_cond, 1); - tvh_thread_create(&tvhdhomerun_discovery_tid, NULL, - tvhdhomerun_device_discovery_thread, - NULL, "hdhm-disc"); + tvh_thread_create(&tvhdhomerun_discovery_tid, + NULL, + tvhdhomerun_device_discovery_thread, + NULL, + "hdhm-disc"); } -void tvhdhomerun_done ( void ) -{ - tvh_hardware_t *th, *n; +void tvhdhomerun_done(void) { + tvh_hardware_t * th, *n; tvhdhomerun_discovery_t *d, *nd; tvh_mutex_lock(&tvhdhomerun_discovery_lock); @@ -511,7 +479,7 @@ void tvhdhomerun_done ( void ) for (th = LIST_FIRST(&tvh_hardware); th != NULL; th = n) { n = LIST_NEXT(th, th_link); if (idnode_is_instance(&th->th_id, &tvhdhomerun_device_class)) { - tvhdhomerun_device_destroy((tvhdhomerun_device_t *)th); + tvhdhomerun_device_destroy((tvhdhomerun_device_t*)th); } } for (d = TAILQ_FIRST(&tvhdhomerun_discoveries); d != NULL; d = nd) { @@ -522,10 +490,8 @@ void tvhdhomerun_done ( void ) hdhomerun_debug_destroy(hdhomerun_debug_obj); } -void -tvhdhomerun_device_destroy( tvhdhomerun_device_t *hd ) -{ - tvhdhomerun_frontend_t *lfe; +void tvhdhomerun_device_destroy(tvhdhomerun_device_t* hd) { + tvhdhomerun_frontend_t* lfe; lock_assert(&global_lock); diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun.h b/src/input/mpegts/tvhdhomerun/tvhdhomerun.h index be2652410..068f05d1a 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun.h +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun.h @@ -28,7 +28,7 @@ extern const idclass_t tvhdhomerun_frontend_atsc_c_class; extern const idclass_t tvhdhomerun_frontend_cablecard_class; extern const idclass_t tvhdhomerun_frontend_isdbt_class; -void tvhdhomerun_init( void ); -void tvhdhomerun_done( void ); +void tvhdhomerun_init(void); +void tvhdhomerun_done(void); #endif /* __TVH_SATIP_H__ */ diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c index 3f8f82081..58eb216d9 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun_frontend.c @@ -30,47 +30,38 @@ #include "config.h" static int -tvhdhomerun_frontend_get_weight ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) -{ +tvhdhomerun_frontend_get_weight(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight) { return mpegts_input_get_weight(mi, mm, flags, weight); } -static int -tvhdhomerun_frontend_get_priority ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags ) -{ +static int tvhdhomerun_frontend_get_priority(mpegts_input_t* mi, mpegts_mux_t* mm, int flags) { return mpegts_input_get_priority(mi, mm, flags); } -static int -tvhdhomerun_frontend_get_grace ( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ +static int tvhdhomerun_frontend_get_grace(mpegts_input_t* mi, mpegts_mux_t* mm) { return 15; } static int -tvhdhomerun_frontend_is_enabled - ( mpegts_input_t *mi, mpegts_mux_t *mm, int flags, int weight ) -{ +tvhdhomerun_frontend_is_enabled(mpegts_input_t* mi, mpegts_mux_t* mm, int flags, int weight) { return mpegts_input_is_enabled(mi, mm, flags, weight); } -static void * -tvhdhomerun_frontend_input_thread ( void *aux ) -{ - tvhdhomerun_frontend_t *hfe = aux; - mpegts_mux_instance_t *mmi; - sbuf_t sb; - char buf[256]; - char target[64]; - uint32_t local_ip; - int sockfd, nfds; - int sock_opt = 1; - int r; - int rx_size = 1024 * 1024; - struct sockaddr_in sock_addr; - socklen_t sockaddr_len = sizeof(sock_addr); - tvhpoll_event_t ev[2]; - tvhpoll_t *efd; +static void* tvhdhomerun_frontend_input_thread(void* aux) { + tvhdhomerun_frontend_t* hfe = aux; + mpegts_mux_instance_t* mmi; + sbuf_t sb; + char buf[256]; + char target[64]; + uint32_t local_ip; + int sockfd, nfds; + int sock_opt = 1; + int r; + int rx_size = 1024 * 1024; + struct sockaddr_in sock_addr; + socklen_t sockaddr_len = sizeof(sock_addr); + tvhpoll_event_t ev[2]; + tvhpoll_t* efd; tvhdebug(LS_TVHDHOMERUN, "starting input thread"); @@ -80,7 +71,8 @@ tvhdhomerun_frontend_input_thread ( void *aux ) mmi = LIST_FIRST(&hfe->mi_mux_active); tvh_cond_signal(&hfe->hf_input_thread_cond, 0); tvh_mutex_unlock(&hfe->hf_input_thread_mutex); - if (mmi == NULL) return NULL; + if (mmi == NULL) + return NULL; tvhdebug(LS_TVHDHOMERUN, "opening client socket"); @@ -102,68 +94,70 @@ tvhdhomerun_frontend_input_thread ( void *aux ) /* first setup a local socket for the device to stream to */ sockfd = tvh_socket(AF_INET, SOCK_DGRAM, 0); - if(sockfd == -1) { + if (sockfd == -1) { tvherror(LS_TVHDHOMERUN, "failed to open socket (%d)", errno); return NULL; } - if(fcntl(sockfd, F_SETFL, O_NONBLOCK) != 0) { + if (fcntl(sockfd, F_SETFL, O_NONBLOCK) != 0) { close(sockfd); tvherror(LS_TVHDHOMERUN, "failed to set socket nonblocking (%d)", errno); return NULL; } /* enable broadcast */ - if(setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (char *) &sock_opt, sizeof(sock_opt)) < 0) { + if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, (char*)&sock_opt, sizeof(sock_opt)) < 0) { close(sockfd); tvherror(LS_TVHDHOMERUN, "failed to enable broadcast on socket (%d)", errno); return NULL; } - if(setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &sock_opt, sizeof(sock_opt)) < 0) { + if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char*)&sock_opt, sizeof(sock_opt)) < 0) { close(sockfd); tvherror(LS_TVHDHOMERUN, "failed to set address reuse on socket (%d)", errno); return NULL; } /* important: we need large rx buffers to accomodate the large amount of traffic */ - if(setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char *) &rx_size, sizeof(rx_size)) < 0) { + if (setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (char*)&rx_size, sizeof(rx_size)) < 0) { tvhwarn(LS_TVHDHOMERUN, "failed set socket rx buffer size, expect CC errors (%d)", errno); } memset(&sock_addr, 0, sizeof(sock_addr)); - sock_addr.sin_family = AF_INET; + sock_addr.sin_family = AF_INET; sock_addr.sin_addr.s_addr = htonl(INADDR_ANY); - sock_addr.sin_port = config.local_port==0?0:htons(config.local_port + hfe->hf_tunerNumber); - if(bind(sockfd, (struct sockaddr *) &sock_addr, sizeof(sock_addr)) != 0) { + sock_addr.sin_port = config.local_port == 0 ? 0 : htons(config.local_port + hfe->hf_tunerNumber); + if (bind(sockfd, (struct sockaddr*)&sock_addr, sizeof(sock_addr)) != 0) { tvherror(LS_TVHDHOMERUN, "failed bind socket: %d", errno); close(sockfd); return NULL; } memset(&sock_addr, 0, sizeof(sock_addr)); - if(getsockname(sockfd, (struct sockaddr *) &sock_addr, &sockaddr_len) != 0) { + if (getsockname(sockfd, (struct sockaddr*)&sock_addr, &sockaddr_len) != 0) { tvherror(LS_TVHDHOMERUN, "failed to getsockname: %d", errno); close(sockfd); return NULL; } /* pretend we are smart and set video_socket; doubt that this is required though */ - //hfe->hf_hdhomerun_tuner->vs = sockfd; + // hfe->hf_hdhomerun_tuner->vs = sockfd; /* and tell the device to stream to the local port */ memset(target, 0, sizeof(target)); - snprintf(target, sizeof(target), "udp://%u.%u.%u.%u:%u", - (unsigned int)(local_ip >> 24) & 0xFF, - (unsigned int)(local_ip >> 16) & 0xFF, - (unsigned int)(local_ip >> 8) & 0xFF, - (unsigned int)(local_ip >> 0) & 0xFF, - ntohs(sock_addr.sin_port)); + snprintf(target, + sizeof(target), + "udp://%u.%u.%u.%u:%u", + (unsigned int)(local_ip >> 24) & 0xFF, + (unsigned int)(local_ip >> 16) & 0xFF, + (unsigned int)(local_ip >> 8) & 0xFF, + (unsigned int)(local_ip >> 0) & 0xFF, + ntohs(sock_addr.sin_port)); tvhdebug(LS_TVHDHOMERUN, "setting target to: %s", target); tvh_mutex_lock(&hfe->hf_hdhomerun_device_mutex); r = hdhomerun_device_set_tuner_target(hfe->hf_hdhomerun_tuner, target); tvh_mutex_unlock(&hfe->hf_hdhomerun_device_mutex); - if(r < 1) { + if (r < 1) { tvherror(LS_TVHDHOMERUN, "failed to set target: %d", r); close(sockfd); return NULL; @@ -171,41 +165,41 @@ tvhdhomerun_frontend_input_thread ( void *aux ) /* the poll set includes the sockfd and the pipe for IPC */ efd = tvhpoll_create(2); - tvhpoll_event(ev+0, sockfd, TVHPOLL_IN, hfe); - tvhpoll_event(ev+1, hfe->hf_input_thread_pipe.rd, TVHPOLL_IN, - &hfe->hf_input_thread_pipe); + tvhpoll_event(ev + 0, sockfd, TVHPOLL_IN, hfe); + tvhpoll_event(ev + 1, hfe->hf_input_thread_pipe.rd, TVHPOLL_IN, &hfe->hf_input_thread_pipe); r = tvhpoll_add(efd, ev, 2); - if(r < 0) + if (r < 0) tvherror(LS_TVHDHOMERUN, "failed to setup poll"); sbuf_init_fixed(&sb, (20000000 / 8)); /* TODO: flush buffer? */ - while(tvheadend_is_running()) { + while (tvheadend_is_running()) { nfds = tvhpoll_wait(efd, ev, 1, -1); - if (nfds < 1) continue; - if (ev[0].ptr != hfe) break; + if (nfds < 1) + continue; + if (ev[0].ptr != hfe) + break; - if((r = sbuf_read(&sb, sockfd)) < 0) { + if ((r = sbuf_read(&sb, sockfd)) < 0) { /* whoopsy */ - if(ERRNO_AGAIN(errno)) + if (ERRNO_AGAIN(errno)) continue; - if(errno == EOVERFLOW) { + if (errno == EOVERFLOW) { tvhwarn(LS_TVHDHOMERUN, "%s - read() EOVERFLOW", buf); continue; } - tvherror(LS_TVHDHOMERUN, "%s - read() error %d (%s)", - buf, errno, strerror(errno)); + tvherror(LS_TVHDHOMERUN, "%s - read() error %d (%s)", buf, errno, strerror(errno)); break; } - //if(r != (7*188)) - //continue; /* dude; this is not a valid packet */ + // if(r != (7*188)) + // continue; /* dude; this is not a valid packet */ - //tvhdebug(LS_TVHDHOMERUN, "got r=%d (thats %d)", r, (r == 7*188)); + // tvhdebug(LS_TVHDHOMERUN, "got r=%d (thats %d)", r, (r == 7*188)); mpegts_input_recv_packets(mmi, &sb, 0, NULL); } @@ -221,35 +215,34 @@ tvhdhomerun_frontend_input_thread ( void *aux ) return NULL; } -static void -tvhdhomerun_frontend_monitor_cb( void *aux ) -{ - tvhdhomerun_frontend_t *hfe = aux; - mpegts_mux_instance_t *mmi = LIST_FIRST(&hfe->mi_mux_active); - mpegts_mux_t *mm; - streaming_message_t sm; - signal_status_t sigstat; - service_t *svc; - int res, e; +static void tvhdhomerun_frontend_monitor_cb(void* aux) { + tvhdhomerun_frontend_t* hfe = aux; + mpegts_mux_instance_t* mmi = LIST_FIRST(&hfe->mi_mux_active); + mpegts_mux_t* mm; + streaming_message_t sm; + signal_status_t sigstat; + service_t* svc; + int res, e; struct hdhomerun_tuner_status_t tuner_status; - char *tuner_status_str; + char* tuner_status_str; /* Stop timer */ - if (!mmi || !hfe->hf_ready) return; + if (!mmi || !hfe->hf_ready) + return; /* re-arm */ - mtimer_arm_rel(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, - hfe, sec2mono(1)); + mtimer_arm_rel(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, sec2mono(1)); /* Get current status */ tvh_mutex_lock(&hfe->hf_hdhomerun_device_mutex); - res = hdhomerun_device_get_tuner_status(hfe->hf_hdhomerun_tuner, &tuner_status_str, &tuner_status); + res = + hdhomerun_device_get_tuner_status(hfe->hf_hdhomerun_tuner, &tuner_status_str, &tuner_status); tvh_mutex_unlock(&hfe->hf_hdhomerun_device_mutex); - if(res < 1) + if (res < 1) tvhwarn(LS_TVHDHOMERUN, "tuner_status (%d)", res); - if(tuner_status.signal_present) + if (tuner_status.signal_present) hfe->hf_status = SIGNAL_GOOD; else hfe->hf_status = SIGNAL_NONE; @@ -258,19 +251,20 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) mm = mmi->mmi_mux; /* wait for a signal_present */ - if(!hfe->hf_locked) { - if(tuner_status.signal_present) { + if (!hfe->hf_locked) { + if (tuner_status.signal_present) { tvhdebug(LS_TVHDHOMERUN, "locked"); hfe->hf_locked = 1; /* Get CableCARD variables */ if (hfe->hf_type == DVB_TYPE_CABLECARD) { - dvb_mux_t *lm = (dvb_mux_t *)mm; + dvb_mux_t* lm = (dvb_mux_t*)mm; struct hdhomerun_tuner_vstatus_t tuner_vstatus; - char *tuner_vstatus_str; + char* tuner_vstatus_str; tvh_mutex_lock(&hfe->hf_hdhomerun_device_mutex); res = hdhomerun_device_get_tuner_vstatus(hfe->hf_hdhomerun_tuner, - &tuner_vstatus_str, &tuner_vstatus); + &tuner_vstatus_str, + &tuner_vstatus); tvh_mutex_unlock(&hfe->hf_hdhomerun_device_mutex); if (res < 1) tvhwarn(LS_TVHDHOMERUN, "tuner_vstatus (%d)", res); @@ -281,7 +275,11 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) /* start input thread */ tvh_pipe(O_NONBLOCK, &hfe->hf_input_thread_pipe); tvh_mutex_lock(&hfe->hf_input_thread_mutex); - tvh_thread_create(&hfe->hf_input_thread, NULL, tvhdhomerun_frontend_input_thread, hfe, "hdhm-front"); + tvh_thread_create(&hfe->hf_input_thread, + NULL, + tvhdhomerun_frontend_input_thread, + hfe, + "hdhm-front"); do { e = tvh_cond_wait(&hfe->hf_input_thread_cond, &hfe->hf_input_thread_mutex); if (e == ETIMEDOUT) @@ -290,8 +288,7 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) tvh_mutex_unlock(&hfe->hf_input_thread_mutex); /* install table handlers */ - psi_tables_install(mmi->mmi_input, mm, - ((dvb_mux_t *)mm)->lm_tuning.dmc_fe_delsys); + psi_tables_install(mmi->mmi_input, mm, ((dvb_mux_t*)mm)->lm_tuning.dmc_fe_delsys); } else { // quick re-arm the timer to wait for signal lock mtimer_arm_rel(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, ms2mono(50)); @@ -300,56 +297,63 @@ tvhdhomerun_frontend_monitor_cb( void *aux ) tvh_mutex_lock(&mmi->tii_stats_mutex); - if(tuner_status.signal_present) { + if (tuner_status.signal_present) { /* TODO: totaly stupid conversion from 0-100 scale to 0-655.35 */ - mmi->tii_stats.snr = tuner_status.signal_to_noise_quality * 655.35; + mmi->tii_stats.snr = tuner_status.signal_to_noise_quality * 655.35; mmi->tii_stats.signal = tuner_status.signal_strength * 655.35; } else { mmi->tii_stats.snr = 0; } - sigstat.status_text = signal2str(hfe->hf_status); - sigstat.snr = mmi->tii_stats.snr; - sigstat.snr_scale = mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE; - sigstat.signal = mmi->tii_stats.signal; + sigstat.status_text = signal2str(hfe->hf_status); + sigstat.snr = mmi->tii_stats.snr; + sigstat.snr_scale = mmi->tii_stats.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE; + sigstat.signal = mmi->tii_stats.signal; sigstat.signal_scale = mmi->tii_stats.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE; - sigstat.ber = mmi->tii_stats.ber; - sigstat.unc = atomic_get(&mmi->tii_stats.unc); + sigstat.ber = mmi->tii_stats.ber; + sigstat.unc = atomic_get(&mmi->tii_stats.unc); memset(&sm, 0, sizeof(sm)); sm.sm_type = SMT_SIGNAL_STATUS; sm.sm_data = &sigstat; tvh_mutex_unlock(&mmi->tii_stats_mutex); - LIST_FOREACH(svc, &mmi->mmi_mux->mm_transports, s_active_link) { + LIST_FOREACH (svc, &mmi->mmi_mux->mm_transports, s_active_link) { tvh_mutex_lock(&svc->s_stream_mutex); streaming_service_deliver(svc, streaming_msg_clone(&sm)); tvh_mutex_unlock(&svc->s_stream_mutex); } } -static int tvhdhomerun_frontend_tune(tvhdhomerun_frontend_t *hfe, mpegts_mux_instance_t *mmi) -{ - hfe->hf_status = SIGNAL_NONE; - dvb_mux_t *lm = (dvb_mux_t*)mmi->mmi_mux; - dvb_mux_conf_t *dmc = &lm->lm_tuning; - char channel_buf[64]; - uint32_t symbol_rate = 0; - uint8_t bandwidth = 0; - int res; - char *perror; +static int tvhdhomerun_frontend_tune(tvhdhomerun_frontend_t* hfe, mpegts_mux_instance_t* mmi) { + hfe->hf_status = SIGNAL_NONE; + dvb_mux_t* lm = (dvb_mux_t*)mmi->mmi_mux; + dvb_mux_conf_t* dmc = &lm->lm_tuning; + char channel_buf[64]; + uint32_t symbol_rate = 0; + uint8_t bandwidth = 0; + int res; + char* perror; /* resolve the modulation type */ switch (dmc->dmc_fe_type) { case DVB_TYPE_C: /* the symbol rate */ symbol_rate = dmc->u.dmc_fe_qam.symbol_rate / 1000; - switch(dmc->dmc_fe_modulation) { + switch (dmc->dmc_fe_modulation) { case DVB_MOD_QAM_64: - snprintf(channel_buf, sizeof(channel_buf), "a8qam64-%d:%u", symbol_rate, dmc->dmc_fe_freq); + snprintf(channel_buf, + sizeof(channel_buf), + "a8qam64-%d:%u", + symbol_rate, + dmc->dmc_fe_freq); break; case DVB_MOD_QAM_256: - snprintf(channel_buf, sizeof(channel_buf), "a8qam256-%d:%u", symbol_rate, dmc->dmc_fe_freq); + snprintf(channel_buf, + sizeof(channel_buf), + "a8qam256-%d:%u", + symbol_rate, + dmc->dmc_fe_freq); break; default: snprintf(channel_buf, sizeof(channel_buf), "auto:%u", dmc->dmc_fe_freq); @@ -360,37 +364,41 @@ static int tvhdhomerun_frontend_tune(tvhdhomerun_frontend_t *hfe, mpegts_mux_ins bandwidth = dmc->u.dmc_fe_ofdm.bandwidth / 1000UL; switch (dmc->dmc_fe_modulation) { case DVB_MOD_AUTO: - if (dmc->u.dmc_fe_ofdm.bandwidth == DVB_BANDWIDTH_AUTO) { - snprintf(channel_buf, sizeof(channel_buf), "auto:%u", dmc->dmc_fe_freq); - } else { - snprintf(channel_buf, sizeof(channel_buf), "auto%dt:%u", bandwidth, dmc->dmc_fe_freq); - } - break; + if (dmc->u.dmc_fe_ofdm.bandwidth == DVB_BANDWIDTH_AUTO) { + snprintf(channel_buf, sizeof(channel_buf), "auto:%u", dmc->dmc_fe_freq); + } else { + snprintf(channel_buf, sizeof(channel_buf), "auto%dt:%u", bandwidth, dmc->dmc_fe_freq); + } + break; case DVB_MOD_QAM_256: - if (dmc->dmc_fe_delsys == DVB_SYS_DVBT2) { - snprintf(channel_buf, sizeof(channel_buf), "tt%dqam256:%u", bandwidth, dmc->dmc_fe_freq); - } else { - snprintf(channel_buf, sizeof(channel_buf), "t%dqam256:%u", bandwidth, dmc->dmc_fe_freq); - } - break; + if (dmc->dmc_fe_delsys == DVB_SYS_DVBT2) { + snprintf(channel_buf, + sizeof(channel_buf), + "tt%dqam256:%u", + bandwidth, + dmc->dmc_fe_freq); + } else { + snprintf(channel_buf, sizeof(channel_buf), "t%dqam256:%u", bandwidth, dmc->dmc_fe_freq); + } + break; case DVB_MOD_QAM_64: - if (dmc->dmc_fe_delsys == DVB_SYS_DVBT2) { - snprintf(channel_buf, sizeof(channel_buf), "tt%dqam64:%u", bandwidth, dmc->dmc_fe_freq); - } else { - snprintf(channel_buf, sizeof(channel_buf), "t%dqam64:%u", bandwidth, dmc->dmc_fe_freq); - } - break; + if (dmc->dmc_fe_delsys == DVB_SYS_DVBT2) { + snprintf(channel_buf, sizeof(channel_buf), "tt%dqam64:%u", bandwidth, dmc->dmc_fe_freq); + } else { + snprintf(channel_buf, sizeof(channel_buf), "t%dqam64:%u", bandwidth, dmc->dmc_fe_freq); + } + break; default: - /* probably won't work but never mind */ - snprintf(channel_buf, sizeof(channel_buf), "auto:%u", dmc->dmc_fe_freq); - break; + /* probably won't work but never mind */ + snprintf(channel_buf, sizeof(channel_buf), "auto:%u", dmc->dmc_fe_freq); + break; } break; case DVB_TYPE_CABLECARD: snprintf(channel_buf, sizeof(channel_buf), "%u", dmc->u.dmc_fe_cablecard.vchannel); break; case DVB_TYPE_ATSC_T: - switch(dmc->dmc_fe_modulation) { + switch (dmc->dmc_fe_modulation) { case DVB_MOD_VSB_8: snprintf(channel_buf, sizeof(channel_buf), "auto6t:%u", dmc->dmc_fe_freq); break; @@ -408,7 +416,7 @@ static int tvhdhomerun_frontend_tune(tvhdhomerun_frontend_t *hfe, mpegts_mux_ins tvh_mutex_lock(&hfe->hf_hdhomerun_device_mutex); res = hdhomerun_device_tuner_lockkey_request(hfe->hf_hdhomerun_tuner, &perror); - if(res < 1) { + if (res < 1) { tvh_mutex_unlock(&hfe->hf_hdhomerun_device_mutex); tvherror(LS_TVHDHOMERUN, "failed to acquire lockkey: %s", perror); return SM_CODE_TUNING_FAILED; @@ -418,7 +426,7 @@ static int tvhdhomerun_frontend_tune(tvhdhomerun_frontend_t *hfe, mpegts_mux_ins else res = hdhomerun_device_set_tuner_channel(hfe->hf_hdhomerun_tuner, channel_buf); tvh_mutex_unlock(&hfe->hf_hdhomerun_device_mutex); - if(res < 1) { + if (res < 1) { tvherror(LS_TVHDHOMERUN, "failed to tune to %s", channel_buf); return SM_CODE_TUNING_FAILED; } @@ -433,12 +441,10 @@ static int tvhdhomerun_frontend_tune(tvhdhomerun_frontend_t *hfe, mpegts_mux_ins } static int -tvhdhomerun_frontend_start_mux - ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi, int weight ) -{ - tvhdhomerun_frontend_t *hfe = (tvhdhomerun_frontend_t*)mi; - int res, r; - char buf1[256], buf2[256]; +tvhdhomerun_frontend_start_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi, int weight) { + tvhdhomerun_frontend_t* hfe = (tvhdhomerun_frontend_t*)mi; + int res, r; + char buf1[256], buf2[256]; mi->mi_display_name(mi, buf1, sizeof(buf1)); mpegts_mux_nice_name(mmi->mmi_mux, buf2, sizeof(buf2)); @@ -452,26 +458,23 @@ tvhdhomerun_frontend_start_mux tvh_mutex_lock(&hfe->hf_hdhomerun_device_mutex); r = hdhomerun_device_set_tuner_filter(hfe->hf_hdhomerun_tuner, "0x0000"); tvh_mutex_unlock(&hfe->hf_hdhomerun_device_mutex); - if(r < 1) + if (r < 1) tvherror(LS_TVHDHOMERUN, "failed to reset pfilter: %d", r); } return res; } -static void -tvhdhomerun_frontend_stop_mux - ( mpegts_input_t *mi, mpegts_mux_instance_t *mmi ) -{ - tvhdhomerun_frontend_t *hfe = (tvhdhomerun_frontend_t*)mi; - char buf1[256], buf2[256]; +static void tvhdhomerun_frontend_stop_mux(mpegts_input_t* mi, mpegts_mux_instance_t* mmi) { + tvhdhomerun_frontend_t* hfe = (tvhdhomerun_frontend_t*)mi; + char buf1[256], buf2[256]; mi->mi_display_name(mi, buf1, sizeof(buf1)); mpegts_mux_nice_name(mmi->mmi_mux, buf2, sizeof(buf2)); tvhdebug(LS_TVHDHOMERUN, "%s - stopping %s", buf1, buf2); /* join input thread */ - if(hfe->hf_input_thread_pipe.wr > 0) { + if (hfe->hf_input_thread_pipe.wr > 0) { tvh_write(hfe->hf_input_thread_pipe.wr, "", 1); // wake input thread tvhtrace(LS_TVHDHOMERUN, "%s - waiting for input thread", buf1); pthread_join(hfe->hf_input_thread, NULL); @@ -483,50 +486,65 @@ tvhdhomerun_frontend_stop_mux hfe->hf_locked = 0; hfe->hf_status = 0; - hfe->hf_ready = 0; + hfe->hf_ready = 0; mtimer_arm_rel(&hfe->hf_monitor_timer, tvhdhomerun_frontend_monitor_cb, hfe, sec2mono(2)); } -static void tvhdhomerun_frontend_update_pids_appendPidRange(int a, int b, int *firstDelimiter, char **pBuffer, const char **endBuffer ) - /* A helper function that writes a range of pids to the 'buffer'. This function is called more than once from tvhdhomerun_frontend_update_pids. */ +static void tvhdhomerun_frontend_update_pids_appendPidRange(int a, + int b, + int* firstDelimiter, + char** pBuffer, + const char** endBuffer) +/* A helper function that writes a range of pids to the 'buffer'. This function is called more than + once from tvhdhomerun_frontend_update_pids. */ { - if(*firstDelimiter) /* Don't bother printing a space before the first range of pids. */ - *firstDelimiter = 0; /* Set this to false the first time. */ + if (*firstDelimiter) /* Don't bother printing a space before the first range of pids. */ + *firstDelimiter = 0; /* Set this to false the first time. */ else { - if(*pBuffer < *endBuffer) /* Check if 'buffer' is full. */ - *pBuffer += snprintf(*pBuffer, *endBuffer-*pBuffer, " "); /* After the first range, separate pid ranges by a space. */ - } - if(*pBuffer < *endBuffer) { /* Check if 'buffer' is full. */ - if(a == b) - *pBuffer += snprintf(*pBuffer, *endBuffer-*pBuffer, "0x%04x", a); /* First and last pid in a range are the same, then that one pid is appended. */ + if (*pBuffer < *endBuffer) /* Check if 'buffer' is full. */ + *pBuffer += snprintf(*pBuffer, + *endBuffer - *pBuffer, + " "); /* After the first range, separate pid ranges by a space. */ + } + if (*pBuffer < *endBuffer) { /* Check if 'buffer' is full. */ + if (a == b) + *pBuffer += snprintf(*pBuffer, + *endBuffer - *pBuffer, + "0x%04x", + a); /* First and last pid in a range are the same, then that one pid is appended. */ else - *pBuffer += snprintf(*pBuffer, *endBuffer-*pBuffer, "0x%04x-0x%04x", a, b); /* Append a range of pids to 'buffer'. */ + *pBuffer += snprintf(*pBuffer, + *endBuffer - *pBuffer, + "0x%04x-0x%04x", + a, + b); /* Append a range of pids to 'buffer'. */ } } -static void tvhdhomerun_frontend_update_pids( mpegts_input_t *mi, mpegts_mux_t *mm ) -{ - tvhdhomerun_frontend_t *hfe = (tvhdhomerun_frontend_t*)mi; - mpegts_apids_t pids, wpids; - mpegts_pid_t *mp; - mpegts_pid_sub_t *mps; - int i; - int res; - - /* The length of the buffer for list of hdhomerun formatted list of pids. MUST BE GREATER THAN 14! */ +static void tvhdhomerun_frontend_update_pids(mpegts_input_t* mi, mpegts_mux_t* mm) { + tvhdhomerun_frontend_t* hfe = (tvhdhomerun_frontend_t*)mi; + mpegts_apids_t pids, wpids; + mpegts_pid_t* mp; + mpegts_pid_sub_t* mps; + int i; + int res; + + /* The length of the buffer for list of hdhomerun formatted list of pids. MUST BE GREATER THAN 14! + */ const unsigned int bufferSize = 1024; - /* Temporary storage for preparing the list of pid ranges to send to the hdhomerun device by the set filter command. - * (hdhomerun's filter format example: "0x0000-0x0001 0x0030-0x0031 0x0034-0x0036 0x00a0-0x00a1 0x00a4-0x00a5 0x1ffb") */ + /* Temporary storage for preparing the list of pid ranges to send to the hdhomerun device by the + * set filter command. (hdhomerun's filter format example: "0x0000-0x0001 0x0030-0x0031 + * 0x0034-0x0036 0x00a0-0x00a1 0x00a4-0x00a5 0x1ffb") */ char buffer[bufferSize]; mpegts_pid_init(&pids); - RB_FOREACH(mp, &mm->mm_pids, mp_link) { + RB_FOREACH (mp, &mm->mm_pids, mp_link) { if (mp->mp_pid == MPEGTS_FULLMUX_PID) pids.all = 1; else if (mp->mp_pid < MPEGTS_FULLMUX_PID) { - RB_FOREACH(mps, &mp->mp_subs, mps_link) + RB_FOREACH (mps, &mp->mp_subs, mps_link) mpegts_pid_add(&pids, mp->mp_pid, mps->mps_weight); } } @@ -537,53 +555,73 @@ static void tvhdhomerun_frontend_update_pids( mpegts_input_t *mi, mpegts_mux_t * buffer[0] = '\0'; /* Initialize buffer to handle the case where no pids are requested. */ - /* Check if the turn-on-all-pids flag is set. If so, ask the hdhomerun to send all pids ("0x0000-0x1fff"). */ - if(wpids.all) { - tvhdebug(LS_TVHDHOMERUN, "setting PID filter full mux"); - snprintf(buffer, bufferSize, "0x0000-0x1fff"); + /* Check if the turn-on-all-pids flag is set. If so, ask the hdhomerun to send all pids + * ("0x0000-0x1fff"). */ + if (wpids.all) { + tvhdebug(LS_TVHDHOMERUN, "setting PID filter full mux"); + snprintf(buffer, bufferSize, "0x0000-0x1fff"); } - /* Otherwise, if we have any pids, proceed to find consecutive runs of pids to group them into a list of ranges. */ + /* Otherwise, if we have any pids, proceed to find consecutive runs of pids to group them into a + list of ranges. */ else { - if(wpids.count > 0) { + if (wpids.count > 0) { /* 'begin' is the first pid in a consecutive run of pids. * 'prev' is the previous pid while walking the list of pids and * 'curr' is the current pid. */ int begin, prev, curr; - const char *endBuffer = buffer + bufferSize; /* Have the address after the end of buffer on hand to help avoid writing past the buffer. */ - char *pBuffer = buffer; /* Move this pointer through the buffer as we write formatted pids. */ - int firstDelimiter = -1; /* Set this to 'true' so that we can skip writing the first delimiter/space. */ + const char* endBuffer = buffer + bufferSize; /* Have the address after the end of buffer on + hand to help avoid writing past the buffer. */ + char* pBuffer = buffer; /* Move this pointer through the buffer as we write formatted pids. */ + int firstDelimiter = + -1; /* Set this to 'true' so that we can skip writing the first delimiter/space. */ - /* Walk the list of pids and keep track of runs of consecutive pids. Setup the state for the first pid. */ + /* Walk the list of pids and keep track of runs of consecutive pids. Setup the state for the + * first pid. */ for (i = 1, prev = begin = wpids.pids[0].pid; i < wpids.count; i++) { curr = wpids.pids[i].pid; /* make sure the pid maps to a max of 0x1FFF, API will reject the call otherwise */ - if(curr > 0x1FFF) { + if (curr > 0x1FFF) { tvherror(LS_TVHDHOMERUN, "pid %d is too large, masking to API maximum of 0x1FFF", curr); curr = (curr & 0x1FFF); } /* Check to see if there is a break in a run of consecutive pids. */ - if(prev + 1 != curr) { - /* If the current pid is NOT +1 more than the previous pid, then this is the end of a range of pids. - * Write out this range of consecutive pids. */ - tvhdhomerun_frontend_update_pids_appendPidRange(begin, prev, &firstDelimiter, &pBuffer, &endBuffer); - - /* Also, this is the start of a new range of pids. Set 'begin' to the beginning of the next range. */ + if (prev + 1 != curr) { + /* If the current pid is NOT +1 more than the previous pid, then this is the end of a + * range of pids. Write out this range of consecutive pids. */ + tvhdhomerun_frontend_update_pids_appendPidRange(begin, + prev, + &firstDelimiter, + &pBuffer, + &endBuffer); + + /* Also, this is the start of a new range of pids. Set 'begin' to the beginning of the + * next range. */ begin = curr; } - prev = curr; /* At bottom of the loop, current pid is now the previous pid. */ - if(pBuffer >= endBuffer) /* We have reached the end of the 'buffer', no need to continue walking through the list. */ + prev = curr; /* At bottom of the loop, current pid is now the previous pid. */ + if (pBuffer >= endBuffer) /* We have reached the end of the 'buffer', no need to continue + walking through the list. */ break; } - /* We are at the end of the list of pids, write the final range of consecutive pids to the 'buffer'. */ - tvhdhomerun_frontend_update_pids_appendPidRange(begin, prev, &firstDelimiter, &pBuffer, &endBuffer); - - if(pBuffer >= endBuffer) { /* We could not fit the list of ranges of pids into the 'buffer' and have an incomplete/mangled 'buffer' - * so as a backup, we will request all pids except NULL packets (0x1fff). */ - tvhdebug(LS_TVHDHOMERUN, "pfilter list is too big for buffer[%d] = \"%s\"(truncated)", bufferSize, buffer); + /* We are at the end of the list of pids, write the final range of consecutive pids to the + * 'buffer'. */ + tvhdhomerun_frontend_update_pids_appendPidRange(begin, + prev, + &firstDelimiter, + &pBuffer, + &endBuffer); + + if (pBuffer >= endBuffer) { /* We could not fit the list of ranges of pids into the 'buffer' + * and have an incomplete/mangled 'buffer' so as a backup, we will + * request all pids except NULL packets (0x1fff). */ + tvhdebug(LS_TVHDHOMERUN, + "pfilter list is too big for buffer[%d] = \"%s\"(truncated)", + bufferSize, + buffer); snprintf(buffer, bufferSize, "0x0000-0x1ffe"); } } @@ -594,33 +632,27 @@ static void tvhdhomerun_frontend_update_pids( mpegts_input_t *mi, mpegts_mux_t * /* Send the specially formatted list of pid ranges to the hdhomerun device. */ res = hdhomerun_device_set_tuner_filter(hfe->hf_hdhomerun_tuner, buffer); tvh_mutex_unlock(&hfe->hf_hdhomerun_device_mutex); - if(res < 1) + if (res < 1) tvherror(LS_TVHDHOMERUN, "failed to set_tuner_filter: %d", res); mpegts_pid_done(&wpids); mpegts_pid_done(&pids); } -static idnode_set_t * -tvhdhomerun_frontend_network_list ( mpegts_input_t *mi ) -{ - tvhdhomerun_frontend_t *hfe = (tvhdhomerun_frontend_t*)mi; +static idnode_set_t* tvhdhomerun_frontend_network_list(mpegts_input_t* mi) { + tvhdhomerun_frontend_t* hfe = (tvhdhomerun_frontend_t*)mi; return dvb_network_list_by_fe_type(hfe->hf_type); } -static void -tvhdhomerun_frontend_class_changed ( idnode_t *in ) -{ - tvhdhomerun_device_t *la = ((tvhdhomerun_frontend_t*)in)->hf_device; +static void tvhdhomerun_frontend_class_changed(idnode_t* in) { + tvhdhomerun_device_t* la = ((tvhdhomerun_frontend_t*)in)->hf_device; tvhdhomerun_device_changed(la); } -void -tvhdhomerun_frontend_save ( tvhdhomerun_frontend_t *hfe, htsmsg_t *fe ) -{ - char id[16], ubuf[UUID_HEX_SIZE]; - htsmsg_t *m = htsmsg_create_map(); +void tvhdhomerun_frontend_save(tvhdhomerun_frontend_t* hfe, htsmsg_t* fe) { + char id[16], ubuf[UUID_HEX_SIZE]; + htsmsg_t* m = htsmsg_create_map(); /* Save frontend */ mpegts_input_save((mpegts_input_t*)hfe, m); @@ -632,129 +664,86 @@ tvhdhomerun_frontend_save ( tvhdhomerun_frontend_t *hfe, htsmsg_t *fe ) htsmsg_add_msg(fe, id, m); } - -const idclass_t tvhdhomerun_frontend_class = -{ - .ic_super = &mpegts_input_class, - .ic_class = "tvhdhomerun_frontend", - .ic_caption = N_("HDHomeRun DVB frontend"), - .ic_changed = tvhdhomerun_frontend_class_changed, - .ic_properties = (const property_t[]) { - { - .type = PT_INT, - .id = "fe_number", - .name = N_("Frontend number"), - .opts = PO_RDONLY | PO_NOSAVE, - .off = offsetof(tvhdhomerun_frontend_t, hf_tunerNumber), - }, - {} - } -}; - -const idclass_t tvhdhomerun_frontend_dvbt_class = -{ - .ic_super = &tvhdhomerun_frontend_class, - .ic_class = "tvhdhomerun_frontend_dvbt", - .ic_caption = N_("HDHomeRun DVB-T frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t tvhdhomerun_frontend_dvbc_class = -{ - .ic_super = &tvhdhomerun_frontend_class, - .ic_class = "tvhdhomerun_frontend_dvbc", - .ic_caption = N_("HDHomeRun DVB-C frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t tvhdhomerun_frontend_atsc_t_class = -{ - .ic_super = &tvhdhomerun_frontend_class, - .ic_class = "tvhdhomerun_frontend_atsc_t", - .ic_caption = N_("HDHomeRun ATSC-T frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t tvhdhomerun_frontend_atsc_c_class = -{ - .ic_super = &tvhdhomerun_frontend_class, - .ic_class = "tvhdhomerun_frontend_atsc_c", - .ic_caption = N_("HDHomeRun ATSC-C frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t tvhdhomerun_frontend_cablecard_class = -{ - .ic_super = &tvhdhomerun_frontend_class, - .ic_class = "tvhdhomerun_frontend_cablecard", - .ic_caption = N_("HDHomeRun CableCARD frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -const idclass_t tvhdhomerun_frontend_isdbt_class = -{ - .ic_super = &tvhdhomerun_frontend_class, - .ic_class = "tvhdhomerun_frontend_isdbt", - .ic_caption = N_("HDHomeRun ISDB-T frontend"), - .ic_properties = (const property_t[]){ - {} - } -}; - -static mpegts_network_t * -tvhdhomerun_frontend_wizard_network ( tvhdhomerun_frontend_t *hfe ) -{ - return (mpegts_network_t *)LIST_FIRST(&hfe->mi_networks); +const idclass_t tvhdhomerun_frontend_class = {.ic_super = &mpegts_input_class, + .ic_class = "tvhdhomerun_frontend", + .ic_caption = N_("HDHomeRun DVB frontend"), + .ic_changed = tvhdhomerun_frontend_class_changed, + .ic_properties = + (const property_t[]){{ + .type = PT_INT, + .id = "fe_number", + .name = N_("Frontend number"), + .opts = PO_RDONLY | PO_NOSAVE, + .off = offsetof(tvhdhomerun_frontend_t, hf_tunerNumber), + }, + {}}}; + +const idclass_t tvhdhomerun_frontend_dvbt_class = {.ic_super = &tvhdhomerun_frontend_class, + .ic_class = "tvhdhomerun_frontend_dvbt", + .ic_caption = N_("HDHomeRun DVB-T frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t tvhdhomerun_frontend_dvbc_class = {.ic_super = &tvhdhomerun_frontend_class, + .ic_class = "tvhdhomerun_frontend_dvbc", + .ic_caption = N_("HDHomeRun DVB-C frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t tvhdhomerun_frontend_atsc_t_class = {.ic_super = &tvhdhomerun_frontend_class, + .ic_class = "tvhdhomerun_frontend_atsc_t", + .ic_caption = N_("HDHomeRun ATSC-T frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t tvhdhomerun_frontend_atsc_c_class = {.ic_super = &tvhdhomerun_frontend_class, + .ic_class = "tvhdhomerun_frontend_atsc_c", + .ic_caption = N_("HDHomeRun ATSC-C frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t tvhdhomerun_frontend_cablecard_class = {.ic_super = &tvhdhomerun_frontend_class, + .ic_class = "tvhdhomerun_frontend_cablecard", + .ic_caption = N_("HDHomeRun CableCARD frontend"), + .ic_properties = (const property_t[]){{}}}; + +const idclass_t tvhdhomerun_frontend_isdbt_class = {.ic_super = &tvhdhomerun_frontend_class, + .ic_class = "tvhdhomerun_frontend_isdbt", + .ic_caption = N_("HDHomeRun ISDB-T frontend"), + .ic_properties = (const property_t[]){{}}}; + +static mpegts_network_t* tvhdhomerun_frontend_wizard_network(tvhdhomerun_frontend_t* hfe) { + return (mpegts_network_t*)LIST_FIRST(&hfe->mi_networks); } -static htsmsg_t * -tvhdhomerun_frontend_wizard_get( tvh_input_t *ti, const char *lang ) -{ - tvhdhomerun_frontend_t *hfe = (tvhdhomerun_frontend_t*)ti; - mpegts_network_t *mn; - const idclass_t *idc = NULL; +static htsmsg_t* tvhdhomerun_frontend_wizard_get(tvh_input_t* ti, const char* lang) { + tvhdhomerun_frontend_t* hfe = (tvhdhomerun_frontend_t*)ti; + mpegts_network_t* mn; + const idclass_t* idc = NULL; mn = tvhdhomerun_frontend_wizard_network(hfe); if (mn == NULL || (mn && mn->mn_wizard)) idc = dvb_network_class_by_fe_type(hfe->hf_type); - return mpegts_network_wizard_get((mpegts_input_t *)hfe, idc, mn, lang); + return mpegts_network_wizard_get((mpegts_input_t*)hfe, idc, mn, lang); } -static void -tvhdhomerun_frontend_wizard_set( tvh_input_t *ti, htsmsg_t *conf, const char *lang ) -{ - tvhdhomerun_frontend_t *hfe = (tvhdhomerun_frontend_t*)ti; - const char *ntype = htsmsg_get_str(conf, "mpegts_network_type"); - mpegts_network_t *mn; - htsmsg_t *nlist; +static void tvhdhomerun_frontend_wizard_set(tvh_input_t* ti, htsmsg_t* conf, const char* lang) { + tvhdhomerun_frontend_t* hfe = (tvhdhomerun_frontend_t*)ti; + const char* ntype = htsmsg_get_str(conf, "mpegts_network_type"); + mpegts_network_t* mn; + htsmsg_t* nlist; mn = tvhdhomerun_frontend_wizard_network(hfe); mpegts_network_wizard_create(ntype, &nlist, lang); if (ntype && (mn == NULL || mn->mn_wizard)) { htsmsg_add_str(nlist, NULL, ntype); - mpegts_input_set_networks((mpegts_input_t *)hfe, nlist); + mpegts_input_set_networks((mpegts_input_t*)hfe, nlist); htsmsg_destroy(nlist); if (tvhdhomerun_frontend_wizard_network(hfe)) - mpegts_input_set_enabled((mpegts_input_t *)hfe, 1); + mpegts_input_set_enabled((mpegts_input_t*)hfe, 1); tvhdhomerun_device_changed(hfe->hf_device); } else { htsmsg_destroy(nlist); } } -void -tvhdhomerun_frontend_delete ( tvhdhomerun_frontend_t *hfe ) -{ +void tvhdhomerun_frontend_delete(tvhdhomerun_frontend_t* hfe) { lock_assert(&global_lock); /* Ensure we're stopped */ @@ -775,13 +764,15 @@ tvhdhomerun_frontend_delete ( tvhdhomerun_frontend_t *hfe ) mpegts_input_delete((mpegts_input_t*)hfe, 0); } -tvhdhomerun_frontend_t * -tvhdhomerun_frontend_create(tvhdhomerun_device_t *hd, struct hdhomerun_discover_device_t *discover_info, htsmsg_t *conf, dvb_fe_type_t type, unsigned int frontend_number ) -{ - const idclass_t *idc; - const char *uuid = NULL; - char id[16]; - tvhdhomerun_frontend_t *hfe; +tvhdhomerun_frontend_t* tvhdhomerun_frontend_create(tvhdhomerun_device_t* hd, + struct hdhomerun_discover_device_t* discover_info, + htsmsg_t* conf, + dvb_fe_type_t type, + unsigned int frontend_number) { + const idclass_t* idc; + const char* uuid = NULL; + char id[16]; + tvhdhomerun_frontend_t* hfe; /* Internal config ID */ snprintf(id, sizeof(id), "%s #%u", dvb_type2str(type), frontend_number); @@ -808,24 +799,28 @@ tvhdhomerun_frontend_create(tvhdhomerun_device_t *hd, struct hdhomerun_discover_ return NULL; } - hfe = calloc(1, sizeof(tvhdhomerun_frontend_t)); - hfe->hf_device = hd; - hfe->hf_type = type; + hfe = calloc(1, sizeof(tvhdhomerun_frontend_t)); + hfe->hf_device = hd; + hfe->hf_type = type; - hfe->hf_hdhomerun_tuner = hdhomerun_device_create(discover_info->device_id, discover_info->ip_addr, frontend_number, hdhomerun_debug_obj); + hfe->hf_hdhomerun_tuner = hdhomerun_device_create(discover_info->device_id, + discover_info->ip_addr, + frontend_number, + hdhomerun_debug_obj); - hfe->hf_input_thread_running = 0; + hfe->hf_input_thread_running = 0; hfe->hf_input_thread_terminating = 0; hfe->hf_tunerNumber = frontend_number; hfe = (tvhdhomerun_frontend_t*)mpegts_input_create0((mpegts_input_t*)hfe, idc, uuid, conf); - if (!hfe) return NULL; + if (!hfe) + return NULL; /* Set some initial CableCARD settings */ if (type == DVB_TYPE_CABLECARD) { - hfe->mi_ota_epg = 0; - hfe->mi_idlescan = 0; + hfe->mi_ota_epg = 0; + hfe->mi_idlescan = 0; hfe->mi_remove_scrambled_bits = 1; } @@ -836,27 +831,30 @@ tvhdhomerun_frontend_create(tvhdhomerun_device_t *hd, struct hdhomerun_discover_ /* Default name */ if (!hfe->mi_name || - (strncmp(hfe->mi_name, "HDHomeRun ", 7) == 0 && - strstr(hfe->mi_name, " Tuner ") && - strstr(hfe->mi_name, " #"))) { + (strncmp(hfe->mi_name, "HDHomeRun ", 7) == 0 && strstr(hfe->mi_name, " Tuner ") && + strstr(hfe->mi_name, " #"))) { char lname[256]; char ip[64]; tcp_get_str_from_ip(&hd->hd_info.ip_address, ip, sizeof(ip)); - snprintf(lname, sizeof(lname), "HDHomeRun %s Tuner #%i (%s)", - dvb_type2str(type), hfe->hf_tunerNumber, ip); + snprintf(lname, + sizeof(lname), + "HDHomeRun %s Tuner #%i (%s)", + dvb_type2str(type), + hfe->hf_tunerNumber, + ip); free(hfe->mi_name); hfe->mi_name = strdup(lname); } /* Input callbacks */ - hfe->ti_wizard_get = tvhdhomerun_frontend_wizard_get; - hfe->ti_wizard_set = tvhdhomerun_frontend_wizard_set; - hfe->mi_is_enabled = tvhdhomerun_frontend_is_enabled; - hfe->mi_start_mux = tvhdhomerun_frontend_start_mux; - hfe->mi_stop_mux = tvhdhomerun_frontend_stop_mux; - hfe->mi_network_list = tvhdhomerun_frontend_network_list; - hfe->mi_update_pids = tvhdhomerun_frontend_update_pids; - hfe->mi_empty_status = mpegts_input_empty_status; + hfe->ti_wizard_get = tvhdhomerun_frontend_wizard_get; + hfe->ti_wizard_set = tvhdhomerun_frontend_wizard_set; + hfe->mi_is_enabled = tvhdhomerun_frontend_is_enabled; + hfe->mi_start_mux = tvhdhomerun_frontend_start_mux; + hfe->mi_stop_mux = tvhdhomerun_frontend_stop_mux; + hfe->mi_network_list = tvhdhomerun_frontend_network_list; + hfe->mi_update_pids = tvhdhomerun_frontend_update_pids; + hfe->mi_empty_status = mpegts_input_empty_status; /* Adapter link */ hfe->hf_device = hd; diff --git a/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h b/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h index eaf14f81d..28758a9f6 100644 --- a/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h +++ b/src/input/mpegts/tvhdhomerun/tvhdhomerun_private.h @@ -28,113 +28,111 @@ typedef struct tvhdhomerun_device_info tvhdhomerun_device_info_t; typedef struct tvhdhomerun_device tvhdhomerun_device_t; typedef struct tvhdhomerun_frontend tvhdhomerun_frontend_t; - static struct hdhomerun_debug_t* hdhomerun_debug_obj = 0; -struct tvhdhomerun_device_info -{ - struct sockaddr_storage ip_address; /* IP address */ - char *friendlyname; - char *deviceModel; - char *uuid; +struct tvhdhomerun_device_info { + struct sockaddr_storage ip_address; /* IP address */ + char* friendlyname; + char* deviceModel; + char* uuid; }; -struct tvhdhomerun_device -{ +struct tvhdhomerun_device { tvh_hardware_t; - mtimer_t hd_destroy_timer; + mtimer_t hd_destroy_timer; /* * Adapter info */ - tvhdhomerun_device_info_t hd_info; + tvhdhomerun_device_info_t hd_info; /* * Frontends */ - TAILQ_HEAD(,tvhdhomerun_frontend) hd_frontends; + TAILQ_HEAD(, tvhdhomerun_frontend) hd_frontends; /* Flags... */ - int hd_fullmux_ok; - - int hd_pids_max; - int hd_pids_len; - int hd_pids_deladd; + int hd_fullmux_ok; - dvb_fe_type_t hd_type; - char *hd_override_type; + int hd_pids_max; + int hd_pids_len; + int hd_pids_deladd; + dvb_fe_type_t hd_type; + char* hd_override_type; }; #define HDHOMERUN_MAX_PIDS 32 -struct tvhdhomerun_frontend -{ +struct tvhdhomerun_frontend { mpegts_input_t; /* * Device */ - tvhdhomerun_device_t *hf_device; + tvhdhomerun_device_t* hf_device; - TAILQ_ENTRY(tvhdhomerun_frontend) hf_link; + TAILQ_ENTRY(tvhdhomerun_frontend) hf_link; /* * Frontend info */ - int hf_tunerNumber; - dvb_fe_type_t hf_type; + int hf_tunerNumber; + dvb_fe_type_t hf_type; // libhdhomerun objects. - struct hdhomerun_device_t *hf_hdhomerun_tuner; + struct hdhomerun_device_t* hf_hdhomerun_tuner; // Tuning information - int hf_locked; - int hf_ready; - int hf_status; + int hf_locked; + int hf_ready; + int hf_status; // input thread.. - pthread_t hf_input_thread; - tvh_mutex_t hf_input_thread_mutex; /* used in condition signaling */ - tvh_cond_t hf_input_thread_cond; /* used in condition signaling */ - th_pipe_t hf_input_thread_pipe; /* IPC with input thread */ - uint8_t hf_input_thread_running; // Indicates if input_thread is running. - uint8_t hf_input_thread_terminating; // Used for terminating the input_thread. + pthread_t hf_input_thread; + tvh_mutex_t hf_input_thread_mutex; /* used in condition signaling */ + tvh_cond_t hf_input_thread_cond; /* used in condition signaling */ + th_pipe_t hf_input_thread_pipe; /* IPC with input thread */ + uint8_t hf_input_thread_running; // Indicates if input_thread is running. + uint8_t hf_input_thread_terminating; // Used for terminating the input_thread. // Global lock for the libhdhomerun library since it seems to have some threading-issues. - tvh_mutex_t hf_hdhomerun_device_mutex; + tvh_mutex_t hf_hdhomerun_device_mutex; /* * Reception */ - char hf_pid_filter_buf[1024]; - - mtimer_t hf_monitor_timer; + char hf_pid_filter_buf[1024]; - mpegts_mux_instance_t *hf_mmi; + mtimer_t hf_monitor_timer; + mpegts_mux_instance_t* hf_mmi; }; /* * Methods */ -void tvhdhomerun_device_init ( void ); -void tvhdhomerun_device_done ( void ); -void tvhdhomerun_device_destroy ( tvhdhomerun_device_t *sd ); -void tvhdhomerun_device_destroy_later( tvhdhomerun_device_t *sd, int after_ms ); +void tvhdhomerun_device_init(void); +void tvhdhomerun_device_done(void); +void tvhdhomerun_device_destroy(tvhdhomerun_device_t* sd); +void tvhdhomerun_device_destroy_later(tvhdhomerun_device_t* sd, int after_ms); -tvhdhomerun_frontend_t * -tvhdhomerun_frontend_create( tvhdhomerun_device_t *hd, struct hdhomerun_discover_device_t *discover_info, htsmsg_t *conf, dvb_fe_type_t type, unsigned int frontend_number ); +tvhdhomerun_frontend_t* tvhdhomerun_frontend_create(tvhdhomerun_device_t* hd, + struct hdhomerun_discover_device_t* discover_info, + htsmsg_t* conf, + dvb_fe_type_t type, + unsigned int frontend_number); -void tvhdhomerun_frontend_delete ( tvhdhomerun_frontend_t *lfe ); +void tvhdhomerun_frontend_delete(tvhdhomerun_frontend_t* lfe); -static inline void tvhdhomerun_device_changed ( tvhdhomerun_device_t *sd ) - { idnode_changed(&sd->th_id); } +static inline void tvhdhomerun_device_changed(tvhdhomerun_device_t* sd) { + idnode_changed(&sd->th_id); +} -void tvhdhomerun_frontend_save ( tvhdhomerun_frontend_t *lfe, htsmsg_t *m ); +void tvhdhomerun_frontend_save(tvhdhomerun_frontend_t* lfe, htsmsg_t* m); #endif diff --git a/src/intlconv.c b/src/intlconv.c index 617341f55..651820e47 100644 --- a/src/intlconv.c +++ b/src/intlconv.c @@ -8,35 +8,29 @@ typedef struct intlconv_cache { RB_ENTRY(intlconv_cache) ic_link; - char *ic_charset_id; + char* ic_charset_id; iconv_t ic_handle; } intlconv_cache_t; -static RB_HEAD(,intlconv_cache) intlconv_all; -static intlconv_cache_t *intlconv_last_ic; -tvh_mutex_t intlconv_lock; +static RB_HEAD(, intlconv_cache) intlconv_all; +static intlconv_cache_t* intlconv_last_ic; +tvh_mutex_t intlconv_lock; -static RB_HEAD(,intlconv_cache) intlconv_src_all; -static intlconv_cache_t *intlconv_last_src_ic; -tvh_mutex_t intlconv_lock_src; +static RB_HEAD(, intlconv_cache) intlconv_src_all; +static intlconv_cache_t* intlconv_last_src_ic; +tvh_mutex_t intlconv_lock_src; static inline size_t -tvh_iconv(iconv_t cd, char **inbuf, size_t *inbytesleft, - char **outbuf, size_t *outbytesleft) -{ +tvh_iconv(iconv_t cd, char** inbuf, size_t* inbytesleft, char** outbuf, size_t* outbytesleft) { return iconv(cd, inbuf, inbytesleft, outbuf, outbytesleft); } -static void -intlconv_test( void ) -{ +static void intlconv_test(void) { /* The string is "Yellow Horse" in Czech for the curiosity */ - const char *charset = intlconv_charset_id("ASCII", 1, 1); - char *s = intlconv_utf8safestr(charset, "ŽluÅ¥oučkýKůň", 128); + const char* charset = intlconv_charset_id("ASCII", 1, 1); + char* s = intlconv_utf8safestr(charset, "ŽluÅ¥oučkýKůň", 128); if (s == NULL || - (strcmp(s, "ZlutouckyKun") && - strcmp(s, "Zlutouck'yKun") && - strcmp(s, "?lu?ou?k?K??"))) { + (strcmp(s, "ZlutouckyKun") && strcmp(s, "Zlutouck'yKun") && strcmp(s, "?lu?ou?k?K??"))) { tvherror(LS_MAIN, "iconv() routine is not working properly (%s), aborting!", s); tvh_safe_usleep(2000000); abort(); @@ -44,18 +38,14 @@ intlconv_test( void ) free(s); } -void -intlconv_init( void ) -{ +void intlconv_init(void) { tvh_mutex_init(&intlconv_lock, NULL); tvh_mutex_init(&intlconv_lock_src, NULL); intlconv_test(); } -void -intlconv_done( void ) -{ - intlconv_cache_t *ic; +void intlconv_done(void) { + intlconv_cache_t* ic; tvh_mutex_lock(&intlconv_lock); intlconv_last_ic = NULL; @@ -75,36 +65,26 @@ intlconv_done( void ) tvh_mutex_unlock(&intlconv_lock); } -const char * -intlconv_filesystem_charset( void ) -{ - char *s = getenv("LANG"); +const char* intlconv_filesystem_charset(void) { + char* s = getenv("LANG"); if (s && strstr(s, ".utf8")) return NULL; /* be safe here */ return "ASCII"; } -static int -intlconv_cmp ( intlconv_cache_t *a, intlconv_cache_t *b ) -{ +static int intlconv_cmp(intlconv_cache_t* a, intlconv_cache_t* b) { return strcmp(a->ic_charset_id, b->ic_charset_id); } -char * -intlconv_charset_id( const char *charset, - int transil, - int ignore_bad_chars ) -{ +char* intlconv_charset_id(const char* charset, int transil, int ignore_bad_chars) { static __thread char buf[128]; - const char *delim; + const char* delim; - if (charset == NULL || charset[0] == '\0' || - strcasecmp(charset, "UTF8") == 0 || + if (charset == NULL || charset[0] == '\0' || strcasecmp(charset, "UTF8") == 0 || strcasecmp(charset, "UTF-8") == 0) return NULL; - delim = index(charset, '/') ? - (charset[strlen(charset)-1] != '/' ? "/" : "") : "//"; + delim = index(charset, '/') ? (charset[strlen(charset) - 1] != '/' ? "/" : "") : "//"; if (transil && ignore_bad_chars) snprintf(buf, sizeof(buf), "%s%sTRANSLIT//IGNORE", charset, delim); else if (transil) @@ -117,23 +97,19 @@ intlconv_charset_id( const char *charset, } ssize_t -intlconv_utf8( char *dst, size_t dst_size, - const char *dst_charset_id, - const char *src_utf8 ) -{ +intlconv_utf8(char* dst, size_t dst_size, const char* dst_charset_id, const char* src_utf8) { intlconv_cache_t templ, *ic; - char **inbuf, **outbuf; - size_t inbuf_left, outbuf_left; - ssize_t res; + char ** inbuf, **outbuf; + size_t inbuf_left, outbuf_left; + ssize_t res; if (dst_charset_id == NULL) { strlcpy(dst, src_utf8, dst_size); return strlen(dst); } - templ.ic_charset_id = (char *)dst_charset_id; + templ.ic_charset_id = (char*)dst_charset_id; tvh_mutex_lock(&intlconv_lock); - if (intlconv_last_ic && - strcmp(intlconv_last_ic->ic_charset_id, dst_charset_id) == 0) { + if (intlconv_last_ic && strcmp(intlconv_last_ic->ic_charset_id, dst_charset_id) == 0) { ic = intlconv_last_ic; goto found; } @@ -163,11 +139,11 @@ intlconv_utf8( char *dst, size_t dst_size, intlconv_last_ic = ic; found: tvh_mutex_unlock(&intlconv_lock); - inbuf = (char **)&src_utf8; + inbuf = (char**)&src_utf8; inbuf_left = strlen(src_utf8); outbuf = &dst; outbuf_left = dst_size; - res = tvh_iconv(ic->ic_handle, inbuf, &inbuf_left, outbuf, &outbuf_left); + res = tvh_iconv(ic->ic_handle, inbuf, &inbuf_left, outbuf, &outbuf_left); if (res == -1) res = -errno; if (res >= 0) @@ -175,26 +151,22 @@ found: return res; } -char * -intlconv_utf8safestr( const char *dst_charset_id, - const char *src_utf8, - size_t max_size ) -{ - char *str, *res; +char* intlconv_utf8safestr(const char* dst_charset_id, const char* src_utf8, size_t max_size) { + char * str, *res; ssize_t r; - size_t i; + size_t i; if (max_size == 0 || *src_utf8 == '\0') return strdup(""); str = alloca(max_size); - r = intlconv_utf8(str, max_size, dst_charset_id, src_utf8); + r = intlconv_utf8(str, max_size, dst_charset_id, src_utf8); if (r <= 0) return NULL; if (r >= max_size) r--; str[r++] = '\0'; - res = strdup(str); + res = strdup(str); if (res != NULL) { /* don't terminate string */ for (i = 0; i < r - 1; i++) @@ -204,24 +176,23 @@ intlconv_utf8safestr( const char *dst_charset_id, return res; } -ssize_t -intlconv_to_utf8( char *dst, size_t dst_size, - const char *src_charset_id, - const char *src, size_t src_size ) -{ +ssize_t intlconv_to_utf8(char* dst, + size_t dst_size, + const char* src_charset_id, + const char* src, + size_t src_size) { intlconv_cache_t templ, *ic; - char **inbuf, **outbuf; - size_t inbuf_left, outbuf_left; - ssize_t res; + char ** inbuf, **outbuf; + size_t inbuf_left, outbuf_left; + ssize_t res; if (src_charset_id == NULL) { strlcpy(dst, src, dst_size); return strlen(dst); } - templ.ic_charset_id = (char *)src_charset_id; + templ.ic_charset_id = (char*)src_charset_id; tvh_mutex_lock(&intlconv_lock_src); - if (intlconv_last_src_ic && - strcmp(intlconv_last_src_ic->ic_charset_id, src_charset_id) == 0) { + if (intlconv_last_src_ic && strcmp(intlconv_last_src_ic->ic_charset_id, src_charset_id) == 0) { ic = intlconv_last_src_ic; goto found; } @@ -251,11 +222,11 @@ intlconv_to_utf8( char *dst, size_t dst_size, intlconv_last_src_ic = ic; found: tvh_mutex_unlock(&intlconv_lock_src); - inbuf = (char **)&src; + inbuf = (char**)&src; inbuf_left = src_size; outbuf = &dst; outbuf_left = dst_size; - res = tvh_iconv(ic->ic_handle, inbuf, &inbuf_left, outbuf, &outbuf_left); + res = tvh_iconv(ic->ic_handle, inbuf, &inbuf_left, outbuf, &outbuf_left); if (res == -1) res = -errno; if (res >= 0) @@ -263,19 +234,15 @@ found: return res; } -char * -intlconv_to_utf8safestr( const char *src_charset_id, - const char *src_str, - size_t max_size ) -{ - char *str; +char* intlconv_to_utf8safestr(const char* src_charset_id, const char* src_str, size_t max_size) { + char* str; ssize_t r; if (max_size == 0 || *src_str == '\0') return strdup(""); str = alloca(max_size); - r = intlconv_to_utf8(str, max_size, src_charset_id, src_str, strlen(src_str)); + r = intlconv_to_utf8(str, max_size, src_charset_id, src_str, strlen(src_str)); if (r <= 0) return NULL; if (r >= max_size) @@ -288,1180 +255,1178 @@ intlconv_to_utf8safestr( const char *src_charset_id, * */ -const char *intlconv_charsets[] = { - "437", - "500", - "500V1", - "850", - "851", - "852", - "855", - "856", - "857", - "860", - "861", - "862", - "863", - "864", - "865", - "866", - "866NAV", - "869", - "874", - "904", - "1026", - "1046", - "1047", - "8859_1", - "8859_2", - "8859_3", - "8859_4", - "8859_5", - "8859_6", - "8859_7", - "8859_8", - "8859_9", - "10646-1:1993", - "10646-1:1993/UCS4", - "ANSI_X3.4-1968", - "ANSI_X3.4-1986", - "ANSI_X3.4", - "ANSI_X3.110-1983", - "ANSI_X3.110", - "ARABIC", - "ARABIC7", - "ARMSCII-8", - "ASCII", - "ASMO-708", - "ASMO_449", - "BALTIC", - "BIG-5", - "BIG-FIVE", - "BIG5-HKSCS", - "BIG5", - "BIG5HKSCS", - "BIGFIVE", - "BRF", - "BS_4730", - "CA", - "CN-BIG5", - "CN-GB", - "CN", - "CP-AR", - "CP-GR", - "CP-HU", - "CP037", - "CP038", - "CP273", - "CP274", - "CP275", - "CP278", - "CP280", - "CP281", - "CP282", - "CP284", - "CP285", - "CP290", - "CP297", - "CP367", - "CP420", - "CP423", - "CP424", - "CP437", - "CP500", - "CP737", - "CP770", - "CP771", - "CP772", - "CP773", - "CP774", - "CP775", - "CP803", - "CP813", - "CP819", - "CP850", - "CP851", - "CP852", - "CP855", - "CP856", - "CP857", - "CP860", - "CP861", - "CP862", - "CP863", - "CP864", - "CP865", - "CP866", - "CP866NAV", - "CP868", - "CP869", - "CP870", - "CP871", - "CP874", - "CP875", - "CP880", - "CP891", - "CP901", - "CP902", - "CP903", - "CP904", - "CP905", - "CP912", - "CP915", - "CP916", - "CP918", - "CP920", - "CP921", - "CP922", - "CP930", - "CP932", - "CP933", - "CP935", - "CP936", - "CP937", - "CP939", - "CP949", - "CP950", - "CP1004", - "CP1008", - "CP1025", - "CP1026", - "CP1046", - "CP1047", - "CP1070", - "CP1079", - "CP1081", - "CP1084", - "CP1089", - "CP1097", - "CP1112", - "CP1122", - "CP1123", - "CP1124", - "CP1125", - "CP1129", - "CP1130", - "CP1132", - "CP1133", - "CP1137", - "CP1140", - "CP1141", - "CP1142", - "CP1143", - "CP1144", - "CP1145", - "CP1146", - "CP1147", - "CP1148", - "CP1149", - "CP1153", - "CP1154", - "CP1155", - "CP1156", - "CP1157", - "CP1158", - "CP1160", - "CP1161", - "CP1162", - "CP1163", - "CP1164", - "CP1166", - "CP1167", - "CP1250", - "CP1251", - "CP1252", - "CP1253", - "CP1254", - "CP1255", - "CP1256", - "CP1257", - "CP1258", - "CP1282", - "CP1361", - "CP1364", - "CP1371", - "CP1388", - "CP1390", - "CP1399", - "CP4517", - "CP4899", - "CP4909", - "CP4971", - "CP5347", - "CP9030", - "CP9066", - "CP9448", - "CP10007", - "CP12712", - "CP16804", - "CPIBM861", - "CSA7-1", - "CSA7-2", - "CSASCII", - "CSA_T500-1983", - "CSA_T500", - "CSA_Z243.4-1985-1", - "CSA_Z243.4-1985-2", - "CSA_Z243.419851", - "CSA_Z243.419852", - "CSDECMCS", - "CSEBCDICATDE", - "CSEBCDICATDEA", - "CSEBCDICCAFR", - "CSEBCDICDKNO", - "CSEBCDICDKNOA", - "CSEBCDICES", - "CSEBCDICESA", - "CSEBCDICESS", - "CSEBCDICFISE", - "CSEBCDICFISEA", - "CSEBCDICFR", - "CSEBCDICIT", - "CSEBCDICPT", - "CSEBCDICUK", - "CSEBCDICUS", - "CSEUCKR", - "CSEUCPKDFMTJAPANESE", - "CSGB2312", - "CSHPROMAN8", - "CSIBM037", - "CSIBM038", - "CSIBM273", - "CSIBM274", - "CSIBM275", - "CSIBM277", - "CSIBM278", - "CSIBM280", - "CSIBM281", - "CSIBM284", - "CSIBM285", - "CSIBM290", - "CSIBM297", - "CSIBM420", - "CSIBM423", - "CSIBM424", - "CSIBM500", - "CSIBM803", - "CSIBM851", - "CSIBM855", - "CSIBM856", - "CSIBM857", - "CSIBM860", - "CSIBM863", - "CSIBM864", - "CSIBM865", - "CSIBM866", - "CSIBM868", - "CSIBM869", - "CSIBM870", - "CSIBM871", - "CSIBM880", - "CSIBM891", - "CSIBM901", - "CSIBM902", - "CSIBM903", - "CSIBM904", - "CSIBM905", - "CSIBM918", - "CSIBM921", - "CSIBM922", - "CSIBM930", - "CSIBM932", - "CSIBM933", - "CSIBM935", - "CSIBM937", - "CSIBM939", - "CSIBM943", - "CSIBM1008", - "CSIBM1025", - "CSIBM1026", - "CSIBM1097", - "CSIBM1112", - "CSIBM1122", - "CSIBM1123", - "CSIBM1124", - "CSIBM1129", - "CSIBM1130", - "CSIBM1132", - "CSIBM1133", - "CSIBM1137", - "CSIBM1140", - "CSIBM1141", - "CSIBM1142", - "CSIBM1143", - "CSIBM1144", - "CSIBM1145", - "CSIBM1146", - "CSIBM1147", - "CSIBM1148", - "CSIBM1149", - "CSIBM1153", - "CSIBM1154", - "CSIBM1155", - "CSIBM1156", - "CSIBM1157", - "CSIBM1158", - "CSIBM1160", - "CSIBM1161", - "CSIBM1163", - "CSIBM1164", - "CSIBM1166", - "CSIBM1167", - "CSIBM1364", - "CSIBM1371", - "CSIBM1388", - "CSIBM1390", - "CSIBM1399", - "CSIBM4517", - "CSIBM4899", - "CSIBM4909", - "CSIBM4971", - "CSIBM5347", - "CSIBM9030", - "CSIBM9066", - "CSIBM9448", - "CSIBM12712", - "CSIBM16804", - "CSIBM11621162", - "CSISO4UNITEDKINGDOM", - "CSISO10SWEDISH", - "CSISO11SWEDISHFORNAMES", - "CSISO14JISC6220RO", - "CSISO15ITALIAN", - "CSISO16PORTUGESE", - "CSISO17SPANISH", - "CSISO18GREEK7OLD", - "CSISO19LATINGREEK", - "CSISO21GERMAN", - "CSISO25FRENCH", - "CSISO27LATINGREEK1", - "CSISO49INIS", - "CSISO50INIS8", - "CSISO51INISCYRILLIC", - "CSISO58GB1988", - "CSISO60DANISHNORWEGIAN", - "CSISO60NORWEGIAN1", - "CSISO61NORWEGIAN2", - "CSISO69FRENCH", - "CSISO84PORTUGUESE2", - "CSISO85SPANISH2", - "CSISO86HUNGARIAN", - "CSISO88GREEK7", - "CSISO89ASMO449", - "CSISO90", - "CSISO92JISC62991984B", - "CSISO99NAPLPS", - "CSISO103T618BIT", - "CSISO111ECMACYRILLIC", - "CSISO121CANADIAN1", - "CSISO122CANADIAN2", - "CSISO139CSN369103", - "CSISO141JUSIB1002", - "CSISO143IECP271", - "CSISO150", - "CSISO150GREEKCCITT", - "CSISO151CUBA", - "CSISO153GOST1976874", - "CSISO646DANISH", - "CSISO2022CN", - "CSISO2022JP", - "CSISO2022JP2", - "CSISO2022KR", - "CSISO2033", - "CSISO5427CYRILLIC", - "CSISO5427CYRILLIC1981", - "CSISO5428GREEK", - "CSISO10367BOX", - "CSISOLATIN1", - "CSISOLATIN2", - "CSISOLATIN3", - "CSISOLATIN4", - "CSISOLATIN5", - "CSISOLATIN6", - "CSISOLATINARABIC", - "CSISOLATINCYRILLIC", - "CSISOLATINGREEK", - "CSISOLATINHEBREW", - "CSKOI8R", - "CSKSC5636", - "CSMACINTOSH", - "CSNATSDANO", - "CSNATSSEFI", - "CSN_369103", - "CSPC8CODEPAGE437", - "CSPC775BALTIC", - "CSPC850MULTILINGUAL", - "CSPC862LATINHEBREW", - "CSPCP852", - "CSSHIFTJIS", - "CSUCS4", - "CSUNICODE", - "CSWINDOWS31J", - "CUBA", - "CWI-2", - "CWI", - "CYRILLIC", - "DE", - "DEC-MCS", - "DEC", - "DECMCS", - "DIN_66003", - "DK", - "DS2089", - "DS_2089", - "E13B", - "EBCDIC-AT-DE-A", - "EBCDIC-AT-DE", - "EBCDIC-BE", - "EBCDIC-BR", - "EBCDIC-CA-FR", - "EBCDIC-CP-AR1", - "EBCDIC-CP-AR2", - "EBCDIC-CP-BE", - "EBCDIC-CP-CA", - "EBCDIC-CP-CH", - "EBCDIC-CP-DK", - "EBCDIC-CP-ES", - "EBCDIC-CP-FI", - "EBCDIC-CP-FR", - "EBCDIC-CP-GB", - "EBCDIC-CP-GR", - "EBCDIC-CP-HE", - "EBCDIC-CP-IS", - "EBCDIC-CP-IT", - "EBCDIC-CP-NL", - "EBCDIC-CP-NO", - "EBCDIC-CP-ROECE", - "EBCDIC-CP-SE", - "EBCDIC-CP-TR", - "EBCDIC-CP-US", - "EBCDIC-CP-WT", - "EBCDIC-CP-YU", - "EBCDIC-CYRILLIC", - "EBCDIC-DK-NO-A", - "EBCDIC-DK-NO", - "EBCDIC-ES-A", - "EBCDIC-ES-S", - "EBCDIC-ES", - "EBCDIC-FI-SE-A", - "EBCDIC-FI-SE", - "EBCDIC-FR", - "EBCDIC-GREEK", - "EBCDIC-INT", - "EBCDIC-INT1", - "EBCDIC-IS-FRISS", - "EBCDIC-IT", - "EBCDIC-JP-E", - "EBCDIC-JP-KANA", - "EBCDIC-PT", - "EBCDIC-UK", - "EBCDIC-US", - "EBCDICATDE", - "EBCDICATDEA", - "EBCDICCAFR", - "EBCDICDKNO", - "EBCDICDKNOA", - "EBCDICES", - "EBCDICESA", - "EBCDICESS", - "EBCDICFISE", - "EBCDICFISEA", - "EBCDICFR", - "EBCDICISFRISS", - "EBCDICIT", - "EBCDICPT", - "EBCDICUK", - "EBCDICUS", - "ECMA-114", - "ECMA-118", - "ECMA-128", - "ECMA-CYRILLIC", - "ECMACYRILLIC", - "ELOT_928", - "ES", - "ES2", - "EUC-CN", - "EUC-JISX0213", - "EUC-JP-MS", - "EUC-JP", - "EUC-KR", - "EUC-TW", - "EUCCN", - "EUCJP-MS", - "EUCJP-OPEN", - "EUCJP-WIN", - "EUCJP", - "EUCKR", - "EUCTW", - "FI", - "FR", - "GB", - "GB2312", - "GB13000", - "GB18030", - "GBK", - "GB_1988-80", - "GB_198880", - "GEORGIAN-ACADEMY", - "GEORGIAN-PS", - "GOST_19768-74", - "GOST_19768", - "GOST_1976874", - "GREEK-CCITT", - "GREEK", - "GREEK7-OLD", - "GREEK7", - "GREEK7OLD", - "GREEK8", - "GREEKCCITT", - "HEBREW", - "HP-GREEK8", - "HP-ROMAN8", - "HP-ROMAN9", - "HP-THAI8", - "HP-TURKISH8", - "HPGREEK8", - "HPROMAN8", - "HPROMAN9", - "HPTHAI8", - "HPTURKISH8", - "HU", - "IBM-803", - "IBM-856", - "IBM-901", - "IBM-902", - "IBM-921", - "IBM-922", - "IBM-930", - "IBM-932", - "IBM-933", - "IBM-935", - "IBM-937", - "IBM-939", - "IBM-943", - "IBM-1008", - "IBM-1025", - "IBM-1046", - "IBM-1047", - "IBM-1097", - "IBM-1112", - "IBM-1122", - "IBM-1123", - "IBM-1124", - "IBM-1129", - "IBM-1130", - "IBM-1132", - "IBM-1133", - "IBM-1137", - "IBM-1140", - "IBM-1141", - "IBM-1142", - "IBM-1143", - "IBM-1144", - "IBM-1145", - "IBM-1146", - "IBM-1147", - "IBM-1148", - "IBM-1149", - "IBM-1153", - "IBM-1154", - "IBM-1155", - "IBM-1156", - "IBM-1157", - "IBM-1158", - "IBM-1160", - "IBM-1161", - "IBM-1162", - "IBM-1163", - "IBM-1164", - "IBM-1166", - "IBM-1167", - "IBM-1364", - "IBM-1371", - "IBM-1388", - "IBM-1390", - "IBM-1399", - "IBM-4517", - "IBM-4899", - "IBM-4909", - "IBM-4971", - "IBM-5347", - "IBM-9030", - "IBM-9066", - "IBM-9448", - "IBM-12712", - "IBM-16804", - "IBM037", - "IBM038", - "IBM256", - "IBM273", - "IBM274", - "IBM275", - "IBM277", - "IBM278", - "IBM280", - "IBM281", - "IBM284", - "IBM285", - "IBM290", - "IBM297", - "IBM367", - "IBM420", - "IBM423", - "IBM424", - "IBM437", - "IBM500", - "IBM775", - "IBM803", - "IBM813", - "IBM819", - "IBM848", - "IBM850", - "IBM851", - "IBM852", - "IBM855", - "IBM856", - "IBM857", - "IBM860", - "IBM861", - "IBM862", - "IBM863", - "IBM864", - "IBM865", - "IBM866", - "IBM866NAV", - "IBM868", - "IBM869", - "IBM870", - "IBM871", - "IBM874", - "IBM875", - "IBM880", - "IBM891", - "IBM901", - "IBM902", - "IBM903", - "IBM904", - "IBM905", - "IBM912", - "IBM915", - "IBM916", - "IBM918", - "IBM920", - "IBM921", - "IBM922", - "IBM930", - "IBM932", - "IBM933", - "IBM935", - "IBM937", - "IBM939", - "IBM943", - "IBM1004", - "IBM1008", - "IBM1025", - "IBM1026", - "IBM1046", - "IBM1047", - "IBM1089", - "IBM1097", - "IBM1112", - "IBM1122", - "IBM1123", - "IBM1124", - "IBM1129", - "IBM1130", - "IBM1132", - "IBM1133", - "IBM1137", - "IBM1140", - "IBM1141", - "IBM1142", - "IBM1143", - "IBM1144", - "IBM1145", - "IBM1146", - "IBM1147", - "IBM1148", - "IBM1149", - "IBM1153", - "IBM1154", - "IBM1155", - "IBM1156", - "IBM1157", - "IBM1158", - "IBM1160", - "IBM1161", - "IBM1162", - "IBM1163", - "IBM1164", - "IBM1166", - "IBM1167", - "IBM1364", - "IBM1371", - "IBM1388", - "IBM1390", - "IBM1399", - "IBM4517", - "IBM4899", - "IBM4909", - "IBM4971", - "IBM5347", - "IBM9030", - "IBM9066", - "IBM9448", - "IBM12712", - "IBM16804", - "IEC_P27-1", - "IEC_P271", - "INIS-8", - "INIS-CYRILLIC", - "INIS", - "INIS8", - "INISCYRILLIC", - "ISIRI-3342", - "ISIRI3342", - "ISO-2022-CN-EXT", - "ISO-2022-CN", - "ISO-2022-JP-2", - "ISO-2022-JP-3", - "ISO-2022-JP", - "ISO-2022-KR", - "ISO-8859-1", - "ISO-8859-2", - "ISO-8859-3", - "ISO-8859-4", - "ISO-8859-5", - "ISO-8859-6", - "ISO-8859-7", - "ISO-8859-8", - "ISO-8859-9", - "ISO-8859-9E", - "ISO-8859-10", - "ISO-8859-11", - "ISO-8859-13", - "ISO-8859-14", - "ISO-8859-15", - "ISO-8859-16", - "ISO-10646-UCS-2", - "ISO-10646", - "ISO-10646/UCS2", - "ISO-10646/UCS4", - "ISO-10646/UTF-8", - "ISO-10646/UTF8", - "ISO-CELTIC", - "ISO-IR-4", - "ISO-IR-6", - "ISO-IR-8-1", - "ISO-IR-9-1", - "ISO-IR-10", - "ISO-IR-11", - "ISO-IR-14", - "ISO-IR-15", - "ISO-IR-16", - "ISO-IR-17", - "ISO-IR-18", - "ISO-IR-19", - "ISO-IR-21", - "ISO-IR-25", - "ISO-IR-27", - "ISO-IR-37", - "ISO-IR-49", - "ISO-IR-50", - "ISO-IR-51", - "ISO-IR-54", - "ISO-IR-55", - "ISO-IR-57", - "ISO-IR-60", - "ISO-IR-61", - "ISO-IR-69", - "ISO-IR-84", - "ISO-IR-85", - "ISO-IR-86", - "ISO-IR-88", - "ISO-IR-89", - "ISO-IR-90", - "ISO-IR-92", - "ISO-IR-98", - "ISO-IR-99", - "ISO-IR-100", - "ISO-IR-101", - "ISO-IR-103", - "ISO-IR-109", - "ISO-IR-110", - "ISO-IR-111", - "ISO-IR-121", - "ISO-IR-122", - "ISO-IR-126", - "ISO-IR-127", - "ISO-IR-138", - "ISO-IR-139", - "ISO-IR-141", - "ISO-IR-143", - "ISO-IR-144", - "ISO-IR-148", - "ISO-IR-150", - "ISO-IR-151", - "ISO-IR-153", - "ISO-IR-155", - "ISO-IR-156", - "ISO-IR-157", - "ISO-IR-166", - "ISO-IR-179", - "ISO-IR-193", - "ISO-IR-197", - "ISO-IR-199", - "ISO-IR-203", - "ISO-IR-209", - "ISO-IR-226", - "ISO/TR_11548-1", - "ISO646-CA", - "ISO646-CA2", - "ISO646-CN", - "ISO646-CU", - "ISO646-DE", - "ISO646-DK", - "ISO646-ES", - "ISO646-ES2", - "ISO646-FI", - "ISO646-FR", - "ISO646-FR1", - "ISO646-GB", - "ISO646-HU", - "ISO646-IT", - "ISO646-JP-OCR-B", - "ISO646-JP", - "ISO646-KR", - "ISO646-NO", - "ISO646-NO2", - "ISO646-PT", - "ISO646-PT2", - "ISO646-SE", - "ISO646-SE2", - "ISO646-US", - "ISO646-YU", - "ISO2022CN", - "ISO2022CNEXT", - "ISO2022JP", - "ISO2022JP2", - "ISO2022KR", - "ISO6937", - "ISO8859-1", - "ISO8859-2", - "ISO8859-3", - "ISO8859-4", - "ISO8859-5", - "ISO8859-6", - "ISO8859-7", - "ISO8859-8", - "ISO8859-9", - "ISO8859-9E", - "ISO8859-10", - "ISO8859-11", - "ISO8859-13", - "ISO8859-14", - "ISO8859-15", - "ISO8859-16", - "ISO11548-1", - "ISO88591", - "ISO88592", - "ISO88593", - "ISO88594", - "ISO88595", - "ISO88596", - "ISO88597", - "ISO88598", - "ISO88599", - "ISO88599E", - "ISO885910", - "ISO885911", - "ISO885913", - "ISO885914", - "ISO885915", - "ISO885916", - "ISO_646.IRV:1991", - "ISO_2033-1983", - "ISO_2033", - "ISO_5427-EXT", - "ISO_5427", - "ISO_5427:1981", - "ISO_5427EXT", - "ISO_5428", - "ISO_5428:1980", - "ISO_6937-2", - "ISO_6937-2:1983", - "ISO_6937", - "ISO_6937:1992", - "ISO_8859-1", - "ISO_8859-1:1987", - "ISO_8859-2", - "ISO_8859-2:1987", - "ISO_8859-3", - "ISO_8859-3:1988", - "ISO_8859-4", - "ISO_8859-4:1988", - "ISO_8859-5", - "ISO_8859-5:1988", - "ISO_8859-6", - "ISO_8859-6:1987", - "ISO_8859-7", - "ISO_8859-7:1987", - "ISO_8859-7:2003", - "ISO_8859-8", - "ISO_8859-8:1988", - "ISO_8859-9", - "ISO_8859-9:1989", - "ISO_8859-9E", - "ISO_8859-10", - "ISO_8859-10:1992", - "ISO_8859-14", - "ISO_8859-14:1998", - "ISO_8859-15", - "ISO_8859-15:1998", - "ISO_8859-16", - "ISO_8859-16:2001", - "ISO_9036", - "ISO_10367-BOX", - "ISO_10367BOX", - "ISO_11548-1", - "ISO_69372", - "IT", - "JIS_C6220-1969-RO", - "JIS_C6229-1984-B", - "JIS_C62201969RO", - "JIS_C62291984B", - "JOHAB", - "JP-OCR-B", - "JP", - "JS", - "JUS_I.B1.002", - "KOI-7", - "KOI-8", - "KOI8-R", - "KOI8-RU", - "KOI8-T", - "KOI8-U", - "KOI8", - "KOI8R", - "KOI8U", - "KSC5636", - "L1", - "L2", - "L3", - "L4", - "L5", - "L6", - "L7", - "L8", - "L10", - "LATIN-9", - "LATIN-GREEK-1", - "LATIN-GREEK", - "LATIN1", - "LATIN2", - "LATIN3", - "LATIN4", - "LATIN5", - "LATIN6", - "LATIN7", - "LATIN8", - "LATIN9", - "LATIN10", - "LATINGREEK", - "LATINGREEK1", - "MAC-CENTRALEUROPE", - "MAC-CYRILLIC", - "MAC-IS", - "MAC-SAMI", - "MAC-UK", - "MAC", - "MACCYRILLIC", - "MACINTOSH", - "MACIS", - "MACUK", - "MACUKRAINIAN", - "MIK", - "MS-ANSI", - "MS-ARAB", - "MS-CYRL", - "MS-EE", - "MS-GREEK", - "MS-HEBR", - "MS-MAC-CYRILLIC", - "MS-TURK", - "MS932", - "MS936", - "MSCP949", - "MSCP1361", - "MSMACCYRILLIC", - "MSZ_7795.3", - "MS_KANJI", - "NAPLPS", - "NATS-DANO", - "NATS-SEFI", - "NATSDANO", - "NATSSEFI", - "NC_NC0010", - "NC_NC00-10", - "NC_NC00-10:81", - "NF_Z_62-010", - "NF_Z_62-010_(1973)", - "NF_Z_62-010_1973", - "NF_Z_62010", - "NF_Z_62010_1973", - "NO", - "NO2", - "NS_4551-1", - "NS_4551-2", - "NS_45511", - "NS_45512", - "OS2LATIN1", - "OSF00010001", - "OSF00010002", - "OSF00010003", - "OSF00010004", - "OSF00010005", - "OSF00010006", - "OSF00010007", - "OSF00010008", - "OSF00010009", - "OSF0001000A", - "OSF00010020", - "OSF00010100", - "OSF00010101", - "OSF00010102", - "OSF00010104", - "OSF00010105", - "OSF00010106", - "OSF00030010", - "OSF0004000A", - "OSF0005000A", - "OSF05010001", - "OSF100201A4", - "OSF100201A8", - "OSF100201B5", - "OSF100201F4", - "OSF100203B5", - "OSF1002011C", - "OSF1002011D", - "OSF1002035D", - "OSF1002035E", - "OSF1002035F", - "OSF1002036B", - "OSF1002037B", - "OSF10010001", - "OSF10010004", - "OSF10010006", - "OSF10020025", - "OSF10020111", - "OSF10020115", - "OSF10020116", - "OSF10020118", - "OSF10020122", - "OSF10020129", - "OSF10020352", - "OSF10020354", - "OSF10020357", - "OSF10020359", - "OSF10020360", - "OSF10020364", - "OSF10020365", - "OSF10020366", - "OSF10020367", - "OSF10020370", - "OSF10020387", - "OSF10020388", - "OSF10020396", - "OSF10020402", - "OSF10020417", - "PT", - "PT2", - "PT154", - "R8", - "R9", - "RK1048", - "ROMAN8", - "ROMAN9", - "RUSCII", - "SE", - "SE2", - "SEN_850200_B", - "SEN_850200_C", - "SHIFT-JIS", - "SHIFT_JIS", - "SHIFT_JISX0213", - "SJIS-OPEN", - "SJIS-WIN", - "SJIS", - "SS636127", - "STRK1048-2002", - "ST_SEV_358-88", - "T.61-8BIT", - "T.61", - "T.618BIT", - "TCVN-5712", - "TCVN", - "TCVN5712-1", - "TCVN5712-1:1993", - "THAI8", - "TIS-620", - "TIS620-0", - "TIS620.2529-1", - "TIS620.2533-0", - "TIS620", - "TS-5881", - "TSCII", - "TURKISH8", - "UCS-2", - "UCS-2BE", - "UCS-2LE", - "UCS-4", - "UCS-4BE", - "UCS-4LE", - "UCS2", - "UCS4", - "UHC", - "UJIS", - "UK", - "UNICODE", - "UNICODEBIG", - "UNICODELITTLE", - "US-ASCII", - "US", - "UTF-7", - "UTF-8", - "UTF-16", - "UTF-16BE", - "UTF-16LE", - "UTF-32", - "UTF-32BE", - "UTF-32LE", - "UTF7", - "UTF8", - "UTF16", - "UTF16BE", - "UTF16LE", - "UTF32", - "UTF32BE", - "UTF32LE", - "VISCII", - "WCHAR_T", - "WIN-SAMI-2", - "WINBALTRIM", - "WINDOWS-31J", - "WINDOWS-874", - "WINDOWS-936", - "WINDOWS-1250", - "WINDOWS-1251", - "WINDOWS-1252", - "WINDOWS-1253", - "WINDOWS-1254", - "WINDOWS-1255", - "WINDOWS-1256", - "WINDOWS-1257", - "WINDOWS-1258", - "WINSAMI2", - "WS2", - "YU", - NULL -}; +const char* intlconv_charsets[] = {"437", + "500", + "500V1", + "850", + "851", + "852", + "855", + "856", + "857", + "860", + "861", + "862", + "863", + "864", + "865", + "866", + "866NAV", + "869", + "874", + "904", + "1026", + "1046", + "1047", + "8859_1", + "8859_2", + "8859_3", + "8859_4", + "8859_5", + "8859_6", + "8859_7", + "8859_8", + "8859_9", + "10646-1:1993", + "10646-1:1993/UCS4", + "ANSI_X3.4-1968", + "ANSI_X3.4-1986", + "ANSI_X3.4", + "ANSI_X3.110-1983", + "ANSI_X3.110", + "ARABIC", + "ARABIC7", + "ARMSCII-8", + "ASCII", + "ASMO-708", + "ASMO_449", + "BALTIC", + "BIG-5", + "BIG-FIVE", + "BIG5-HKSCS", + "BIG5", + "BIG5HKSCS", + "BIGFIVE", + "BRF", + "BS_4730", + "CA", + "CN-BIG5", + "CN-GB", + "CN", + "CP-AR", + "CP-GR", + "CP-HU", + "CP037", + "CP038", + "CP273", + "CP274", + "CP275", + "CP278", + "CP280", + "CP281", + "CP282", + "CP284", + "CP285", + "CP290", + "CP297", + "CP367", + "CP420", + "CP423", + "CP424", + "CP437", + "CP500", + "CP737", + "CP770", + "CP771", + "CP772", + "CP773", + "CP774", + "CP775", + "CP803", + "CP813", + "CP819", + "CP850", + "CP851", + "CP852", + "CP855", + "CP856", + "CP857", + "CP860", + "CP861", + "CP862", + "CP863", + "CP864", + "CP865", + "CP866", + "CP866NAV", + "CP868", + "CP869", + "CP870", + "CP871", + "CP874", + "CP875", + "CP880", + "CP891", + "CP901", + "CP902", + "CP903", + "CP904", + "CP905", + "CP912", + "CP915", + "CP916", + "CP918", + "CP920", + "CP921", + "CP922", + "CP930", + "CP932", + "CP933", + "CP935", + "CP936", + "CP937", + "CP939", + "CP949", + "CP950", + "CP1004", + "CP1008", + "CP1025", + "CP1026", + "CP1046", + "CP1047", + "CP1070", + "CP1079", + "CP1081", + "CP1084", + "CP1089", + "CP1097", + "CP1112", + "CP1122", + "CP1123", + "CP1124", + "CP1125", + "CP1129", + "CP1130", + "CP1132", + "CP1133", + "CP1137", + "CP1140", + "CP1141", + "CP1142", + "CP1143", + "CP1144", + "CP1145", + "CP1146", + "CP1147", + "CP1148", + "CP1149", + "CP1153", + "CP1154", + "CP1155", + "CP1156", + "CP1157", + "CP1158", + "CP1160", + "CP1161", + "CP1162", + "CP1163", + "CP1164", + "CP1166", + "CP1167", + "CP1250", + "CP1251", + "CP1252", + "CP1253", + "CP1254", + "CP1255", + "CP1256", + "CP1257", + "CP1258", + "CP1282", + "CP1361", + "CP1364", + "CP1371", + "CP1388", + "CP1390", + "CP1399", + "CP4517", + "CP4899", + "CP4909", + "CP4971", + "CP5347", + "CP9030", + "CP9066", + "CP9448", + "CP10007", + "CP12712", + "CP16804", + "CPIBM861", + "CSA7-1", + "CSA7-2", + "CSASCII", + "CSA_T500-1983", + "CSA_T500", + "CSA_Z243.4-1985-1", + "CSA_Z243.4-1985-2", + "CSA_Z243.419851", + "CSA_Z243.419852", + "CSDECMCS", + "CSEBCDICATDE", + "CSEBCDICATDEA", + "CSEBCDICCAFR", + "CSEBCDICDKNO", + "CSEBCDICDKNOA", + "CSEBCDICES", + "CSEBCDICESA", + "CSEBCDICESS", + "CSEBCDICFISE", + "CSEBCDICFISEA", + "CSEBCDICFR", + "CSEBCDICIT", + "CSEBCDICPT", + "CSEBCDICUK", + "CSEBCDICUS", + "CSEUCKR", + "CSEUCPKDFMTJAPANESE", + "CSGB2312", + "CSHPROMAN8", + "CSIBM037", + "CSIBM038", + "CSIBM273", + "CSIBM274", + "CSIBM275", + "CSIBM277", + "CSIBM278", + "CSIBM280", + "CSIBM281", + "CSIBM284", + "CSIBM285", + "CSIBM290", + "CSIBM297", + "CSIBM420", + "CSIBM423", + "CSIBM424", + "CSIBM500", + "CSIBM803", + "CSIBM851", + "CSIBM855", + "CSIBM856", + "CSIBM857", + "CSIBM860", + "CSIBM863", + "CSIBM864", + "CSIBM865", + "CSIBM866", + "CSIBM868", + "CSIBM869", + "CSIBM870", + "CSIBM871", + "CSIBM880", + "CSIBM891", + "CSIBM901", + "CSIBM902", + "CSIBM903", + "CSIBM904", + "CSIBM905", + "CSIBM918", + "CSIBM921", + "CSIBM922", + "CSIBM930", + "CSIBM932", + "CSIBM933", + "CSIBM935", + "CSIBM937", + "CSIBM939", + "CSIBM943", + "CSIBM1008", + "CSIBM1025", + "CSIBM1026", + "CSIBM1097", + "CSIBM1112", + "CSIBM1122", + "CSIBM1123", + "CSIBM1124", + "CSIBM1129", + "CSIBM1130", + "CSIBM1132", + "CSIBM1133", + "CSIBM1137", + "CSIBM1140", + "CSIBM1141", + "CSIBM1142", + "CSIBM1143", + "CSIBM1144", + "CSIBM1145", + "CSIBM1146", + "CSIBM1147", + "CSIBM1148", + "CSIBM1149", + "CSIBM1153", + "CSIBM1154", + "CSIBM1155", + "CSIBM1156", + "CSIBM1157", + "CSIBM1158", + "CSIBM1160", + "CSIBM1161", + "CSIBM1163", + "CSIBM1164", + "CSIBM1166", + "CSIBM1167", + "CSIBM1364", + "CSIBM1371", + "CSIBM1388", + "CSIBM1390", + "CSIBM1399", + "CSIBM4517", + "CSIBM4899", + "CSIBM4909", + "CSIBM4971", + "CSIBM5347", + "CSIBM9030", + "CSIBM9066", + "CSIBM9448", + "CSIBM12712", + "CSIBM16804", + "CSIBM11621162", + "CSISO4UNITEDKINGDOM", + "CSISO10SWEDISH", + "CSISO11SWEDISHFORNAMES", + "CSISO14JISC6220RO", + "CSISO15ITALIAN", + "CSISO16PORTUGESE", + "CSISO17SPANISH", + "CSISO18GREEK7OLD", + "CSISO19LATINGREEK", + "CSISO21GERMAN", + "CSISO25FRENCH", + "CSISO27LATINGREEK1", + "CSISO49INIS", + "CSISO50INIS8", + "CSISO51INISCYRILLIC", + "CSISO58GB1988", + "CSISO60DANISHNORWEGIAN", + "CSISO60NORWEGIAN1", + "CSISO61NORWEGIAN2", + "CSISO69FRENCH", + "CSISO84PORTUGUESE2", + "CSISO85SPANISH2", + "CSISO86HUNGARIAN", + "CSISO88GREEK7", + "CSISO89ASMO449", + "CSISO90", + "CSISO92JISC62991984B", + "CSISO99NAPLPS", + "CSISO103T618BIT", + "CSISO111ECMACYRILLIC", + "CSISO121CANADIAN1", + "CSISO122CANADIAN2", + "CSISO139CSN369103", + "CSISO141JUSIB1002", + "CSISO143IECP271", + "CSISO150", + "CSISO150GREEKCCITT", + "CSISO151CUBA", + "CSISO153GOST1976874", + "CSISO646DANISH", + "CSISO2022CN", + "CSISO2022JP", + "CSISO2022JP2", + "CSISO2022KR", + "CSISO2033", + "CSISO5427CYRILLIC", + "CSISO5427CYRILLIC1981", + "CSISO5428GREEK", + "CSISO10367BOX", + "CSISOLATIN1", + "CSISOLATIN2", + "CSISOLATIN3", + "CSISOLATIN4", + "CSISOLATIN5", + "CSISOLATIN6", + "CSISOLATINARABIC", + "CSISOLATINCYRILLIC", + "CSISOLATINGREEK", + "CSISOLATINHEBREW", + "CSKOI8R", + "CSKSC5636", + "CSMACINTOSH", + "CSNATSDANO", + "CSNATSSEFI", + "CSN_369103", + "CSPC8CODEPAGE437", + "CSPC775BALTIC", + "CSPC850MULTILINGUAL", + "CSPC862LATINHEBREW", + "CSPCP852", + "CSSHIFTJIS", + "CSUCS4", + "CSUNICODE", + "CSWINDOWS31J", + "CUBA", + "CWI-2", + "CWI", + "CYRILLIC", + "DE", + "DEC-MCS", + "DEC", + "DECMCS", + "DIN_66003", + "DK", + "DS2089", + "DS_2089", + "E13B", + "EBCDIC-AT-DE-A", + "EBCDIC-AT-DE", + "EBCDIC-BE", + "EBCDIC-BR", + "EBCDIC-CA-FR", + "EBCDIC-CP-AR1", + "EBCDIC-CP-AR2", + "EBCDIC-CP-BE", + "EBCDIC-CP-CA", + "EBCDIC-CP-CH", + "EBCDIC-CP-DK", + "EBCDIC-CP-ES", + "EBCDIC-CP-FI", + "EBCDIC-CP-FR", + "EBCDIC-CP-GB", + "EBCDIC-CP-GR", + "EBCDIC-CP-HE", + "EBCDIC-CP-IS", + "EBCDIC-CP-IT", + "EBCDIC-CP-NL", + "EBCDIC-CP-NO", + "EBCDIC-CP-ROECE", + "EBCDIC-CP-SE", + "EBCDIC-CP-TR", + "EBCDIC-CP-US", + "EBCDIC-CP-WT", + "EBCDIC-CP-YU", + "EBCDIC-CYRILLIC", + "EBCDIC-DK-NO-A", + "EBCDIC-DK-NO", + "EBCDIC-ES-A", + "EBCDIC-ES-S", + "EBCDIC-ES", + "EBCDIC-FI-SE-A", + "EBCDIC-FI-SE", + "EBCDIC-FR", + "EBCDIC-GREEK", + "EBCDIC-INT", + "EBCDIC-INT1", + "EBCDIC-IS-FRISS", + "EBCDIC-IT", + "EBCDIC-JP-E", + "EBCDIC-JP-KANA", + "EBCDIC-PT", + "EBCDIC-UK", + "EBCDIC-US", + "EBCDICATDE", + "EBCDICATDEA", + "EBCDICCAFR", + "EBCDICDKNO", + "EBCDICDKNOA", + "EBCDICES", + "EBCDICESA", + "EBCDICESS", + "EBCDICFISE", + "EBCDICFISEA", + "EBCDICFR", + "EBCDICISFRISS", + "EBCDICIT", + "EBCDICPT", + "EBCDICUK", + "EBCDICUS", + "ECMA-114", + "ECMA-118", + "ECMA-128", + "ECMA-CYRILLIC", + "ECMACYRILLIC", + "ELOT_928", + "ES", + "ES2", + "EUC-CN", + "EUC-JISX0213", + "EUC-JP-MS", + "EUC-JP", + "EUC-KR", + "EUC-TW", + "EUCCN", + "EUCJP-MS", + "EUCJP-OPEN", + "EUCJP-WIN", + "EUCJP", + "EUCKR", + "EUCTW", + "FI", + "FR", + "GB", + "GB2312", + "GB13000", + "GB18030", + "GBK", + "GB_1988-80", + "GB_198880", + "GEORGIAN-ACADEMY", + "GEORGIAN-PS", + "GOST_19768-74", + "GOST_19768", + "GOST_1976874", + "GREEK-CCITT", + "GREEK", + "GREEK7-OLD", + "GREEK7", + "GREEK7OLD", + "GREEK8", + "GREEKCCITT", + "HEBREW", + "HP-GREEK8", + "HP-ROMAN8", + "HP-ROMAN9", + "HP-THAI8", + "HP-TURKISH8", + "HPGREEK8", + "HPROMAN8", + "HPROMAN9", + "HPTHAI8", + "HPTURKISH8", + "HU", + "IBM-803", + "IBM-856", + "IBM-901", + "IBM-902", + "IBM-921", + "IBM-922", + "IBM-930", + "IBM-932", + "IBM-933", + "IBM-935", + "IBM-937", + "IBM-939", + "IBM-943", + "IBM-1008", + "IBM-1025", + "IBM-1046", + "IBM-1047", + "IBM-1097", + "IBM-1112", + "IBM-1122", + "IBM-1123", + "IBM-1124", + "IBM-1129", + "IBM-1130", + "IBM-1132", + "IBM-1133", + "IBM-1137", + "IBM-1140", + "IBM-1141", + "IBM-1142", + "IBM-1143", + "IBM-1144", + "IBM-1145", + "IBM-1146", + "IBM-1147", + "IBM-1148", + "IBM-1149", + "IBM-1153", + "IBM-1154", + "IBM-1155", + "IBM-1156", + "IBM-1157", + "IBM-1158", + "IBM-1160", + "IBM-1161", + "IBM-1162", + "IBM-1163", + "IBM-1164", + "IBM-1166", + "IBM-1167", + "IBM-1364", + "IBM-1371", + "IBM-1388", + "IBM-1390", + "IBM-1399", + "IBM-4517", + "IBM-4899", + "IBM-4909", + "IBM-4971", + "IBM-5347", + "IBM-9030", + "IBM-9066", + "IBM-9448", + "IBM-12712", + "IBM-16804", + "IBM037", + "IBM038", + "IBM256", + "IBM273", + "IBM274", + "IBM275", + "IBM277", + "IBM278", + "IBM280", + "IBM281", + "IBM284", + "IBM285", + "IBM290", + "IBM297", + "IBM367", + "IBM420", + "IBM423", + "IBM424", + "IBM437", + "IBM500", + "IBM775", + "IBM803", + "IBM813", + "IBM819", + "IBM848", + "IBM850", + "IBM851", + "IBM852", + "IBM855", + "IBM856", + "IBM857", + "IBM860", + "IBM861", + "IBM862", + "IBM863", + "IBM864", + "IBM865", + "IBM866", + "IBM866NAV", + "IBM868", + "IBM869", + "IBM870", + "IBM871", + "IBM874", + "IBM875", + "IBM880", + "IBM891", + "IBM901", + "IBM902", + "IBM903", + "IBM904", + "IBM905", + "IBM912", + "IBM915", + "IBM916", + "IBM918", + "IBM920", + "IBM921", + "IBM922", + "IBM930", + "IBM932", + "IBM933", + "IBM935", + "IBM937", + "IBM939", + "IBM943", + "IBM1004", + "IBM1008", + "IBM1025", + "IBM1026", + "IBM1046", + "IBM1047", + "IBM1089", + "IBM1097", + "IBM1112", + "IBM1122", + "IBM1123", + "IBM1124", + "IBM1129", + "IBM1130", + "IBM1132", + "IBM1133", + "IBM1137", + "IBM1140", + "IBM1141", + "IBM1142", + "IBM1143", + "IBM1144", + "IBM1145", + "IBM1146", + "IBM1147", + "IBM1148", + "IBM1149", + "IBM1153", + "IBM1154", + "IBM1155", + "IBM1156", + "IBM1157", + "IBM1158", + "IBM1160", + "IBM1161", + "IBM1162", + "IBM1163", + "IBM1164", + "IBM1166", + "IBM1167", + "IBM1364", + "IBM1371", + "IBM1388", + "IBM1390", + "IBM1399", + "IBM4517", + "IBM4899", + "IBM4909", + "IBM4971", + "IBM5347", + "IBM9030", + "IBM9066", + "IBM9448", + "IBM12712", + "IBM16804", + "IEC_P27-1", + "IEC_P271", + "INIS-8", + "INIS-CYRILLIC", + "INIS", + "INIS8", + "INISCYRILLIC", + "ISIRI-3342", + "ISIRI3342", + "ISO-2022-CN-EXT", + "ISO-2022-CN", + "ISO-2022-JP-2", + "ISO-2022-JP-3", + "ISO-2022-JP", + "ISO-2022-KR", + "ISO-8859-1", + "ISO-8859-2", + "ISO-8859-3", + "ISO-8859-4", + "ISO-8859-5", + "ISO-8859-6", + "ISO-8859-7", + "ISO-8859-8", + "ISO-8859-9", + "ISO-8859-9E", + "ISO-8859-10", + "ISO-8859-11", + "ISO-8859-13", + "ISO-8859-14", + "ISO-8859-15", + "ISO-8859-16", + "ISO-10646-UCS-2", + "ISO-10646", + "ISO-10646/UCS2", + "ISO-10646/UCS4", + "ISO-10646/UTF-8", + "ISO-10646/UTF8", + "ISO-CELTIC", + "ISO-IR-4", + "ISO-IR-6", + "ISO-IR-8-1", + "ISO-IR-9-1", + "ISO-IR-10", + "ISO-IR-11", + "ISO-IR-14", + "ISO-IR-15", + "ISO-IR-16", + "ISO-IR-17", + "ISO-IR-18", + "ISO-IR-19", + "ISO-IR-21", + "ISO-IR-25", + "ISO-IR-27", + "ISO-IR-37", + "ISO-IR-49", + "ISO-IR-50", + "ISO-IR-51", + "ISO-IR-54", + "ISO-IR-55", + "ISO-IR-57", + "ISO-IR-60", + "ISO-IR-61", + "ISO-IR-69", + "ISO-IR-84", + "ISO-IR-85", + "ISO-IR-86", + "ISO-IR-88", + "ISO-IR-89", + "ISO-IR-90", + "ISO-IR-92", + "ISO-IR-98", + "ISO-IR-99", + "ISO-IR-100", + "ISO-IR-101", + "ISO-IR-103", + "ISO-IR-109", + "ISO-IR-110", + "ISO-IR-111", + "ISO-IR-121", + "ISO-IR-122", + "ISO-IR-126", + "ISO-IR-127", + "ISO-IR-138", + "ISO-IR-139", + "ISO-IR-141", + "ISO-IR-143", + "ISO-IR-144", + "ISO-IR-148", + "ISO-IR-150", + "ISO-IR-151", + "ISO-IR-153", + "ISO-IR-155", + "ISO-IR-156", + "ISO-IR-157", + "ISO-IR-166", + "ISO-IR-179", + "ISO-IR-193", + "ISO-IR-197", + "ISO-IR-199", + "ISO-IR-203", + "ISO-IR-209", + "ISO-IR-226", + "ISO/TR_11548-1", + "ISO646-CA", + "ISO646-CA2", + "ISO646-CN", + "ISO646-CU", + "ISO646-DE", + "ISO646-DK", + "ISO646-ES", + "ISO646-ES2", + "ISO646-FI", + "ISO646-FR", + "ISO646-FR1", + "ISO646-GB", + "ISO646-HU", + "ISO646-IT", + "ISO646-JP-OCR-B", + "ISO646-JP", + "ISO646-KR", + "ISO646-NO", + "ISO646-NO2", + "ISO646-PT", + "ISO646-PT2", + "ISO646-SE", + "ISO646-SE2", + "ISO646-US", + "ISO646-YU", + "ISO2022CN", + "ISO2022CNEXT", + "ISO2022JP", + "ISO2022JP2", + "ISO2022KR", + "ISO6937", + "ISO8859-1", + "ISO8859-2", + "ISO8859-3", + "ISO8859-4", + "ISO8859-5", + "ISO8859-6", + "ISO8859-7", + "ISO8859-8", + "ISO8859-9", + "ISO8859-9E", + "ISO8859-10", + "ISO8859-11", + "ISO8859-13", + "ISO8859-14", + "ISO8859-15", + "ISO8859-16", + "ISO11548-1", + "ISO88591", + "ISO88592", + "ISO88593", + "ISO88594", + "ISO88595", + "ISO88596", + "ISO88597", + "ISO88598", + "ISO88599", + "ISO88599E", + "ISO885910", + "ISO885911", + "ISO885913", + "ISO885914", + "ISO885915", + "ISO885916", + "ISO_646.IRV:1991", + "ISO_2033-1983", + "ISO_2033", + "ISO_5427-EXT", + "ISO_5427", + "ISO_5427:1981", + "ISO_5427EXT", + "ISO_5428", + "ISO_5428:1980", + "ISO_6937-2", + "ISO_6937-2:1983", + "ISO_6937", + "ISO_6937:1992", + "ISO_8859-1", + "ISO_8859-1:1987", + "ISO_8859-2", + "ISO_8859-2:1987", + "ISO_8859-3", + "ISO_8859-3:1988", + "ISO_8859-4", + "ISO_8859-4:1988", + "ISO_8859-5", + "ISO_8859-5:1988", + "ISO_8859-6", + "ISO_8859-6:1987", + "ISO_8859-7", + "ISO_8859-7:1987", + "ISO_8859-7:2003", + "ISO_8859-8", + "ISO_8859-8:1988", + "ISO_8859-9", + "ISO_8859-9:1989", + "ISO_8859-9E", + "ISO_8859-10", + "ISO_8859-10:1992", + "ISO_8859-14", + "ISO_8859-14:1998", + "ISO_8859-15", + "ISO_8859-15:1998", + "ISO_8859-16", + "ISO_8859-16:2001", + "ISO_9036", + "ISO_10367-BOX", + "ISO_10367BOX", + "ISO_11548-1", + "ISO_69372", + "IT", + "JIS_C6220-1969-RO", + "JIS_C6229-1984-B", + "JIS_C62201969RO", + "JIS_C62291984B", + "JOHAB", + "JP-OCR-B", + "JP", + "JS", + "JUS_I.B1.002", + "KOI-7", + "KOI-8", + "KOI8-R", + "KOI8-RU", + "KOI8-T", + "KOI8-U", + "KOI8", + "KOI8R", + "KOI8U", + "KSC5636", + "L1", + "L2", + "L3", + "L4", + "L5", + "L6", + "L7", + "L8", + "L10", + "LATIN-9", + "LATIN-GREEK-1", + "LATIN-GREEK", + "LATIN1", + "LATIN2", + "LATIN3", + "LATIN4", + "LATIN5", + "LATIN6", + "LATIN7", + "LATIN8", + "LATIN9", + "LATIN10", + "LATINGREEK", + "LATINGREEK1", + "MAC-CENTRALEUROPE", + "MAC-CYRILLIC", + "MAC-IS", + "MAC-SAMI", + "MAC-UK", + "MAC", + "MACCYRILLIC", + "MACINTOSH", + "MACIS", + "MACUK", + "MACUKRAINIAN", + "MIK", + "MS-ANSI", + "MS-ARAB", + "MS-CYRL", + "MS-EE", + "MS-GREEK", + "MS-HEBR", + "MS-MAC-CYRILLIC", + "MS-TURK", + "MS932", + "MS936", + "MSCP949", + "MSCP1361", + "MSMACCYRILLIC", + "MSZ_7795.3", + "MS_KANJI", + "NAPLPS", + "NATS-DANO", + "NATS-SEFI", + "NATSDANO", + "NATSSEFI", + "NC_NC0010", + "NC_NC00-10", + "NC_NC00-10:81", + "NF_Z_62-010", + "NF_Z_62-010_(1973)", + "NF_Z_62-010_1973", + "NF_Z_62010", + "NF_Z_62010_1973", + "NO", + "NO2", + "NS_4551-1", + "NS_4551-2", + "NS_45511", + "NS_45512", + "OS2LATIN1", + "OSF00010001", + "OSF00010002", + "OSF00010003", + "OSF00010004", + "OSF00010005", + "OSF00010006", + "OSF00010007", + "OSF00010008", + "OSF00010009", + "OSF0001000A", + "OSF00010020", + "OSF00010100", + "OSF00010101", + "OSF00010102", + "OSF00010104", + "OSF00010105", + "OSF00010106", + "OSF00030010", + "OSF0004000A", + "OSF0005000A", + "OSF05010001", + "OSF100201A4", + "OSF100201A8", + "OSF100201B5", + "OSF100201F4", + "OSF100203B5", + "OSF1002011C", + "OSF1002011D", + "OSF1002035D", + "OSF1002035E", + "OSF1002035F", + "OSF1002036B", + "OSF1002037B", + "OSF10010001", + "OSF10010004", + "OSF10010006", + "OSF10020025", + "OSF10020111", + "OSF10020115", + "OSF10020116", + "OSF10020118", + "OSF10020122", + "OSF10020129", + "OSF10020352", + "OSF10020354", + "OSF10020357", + "OSF10020359", + "OSF10020360", + "OSF10020364", + "OSF10020365", + "OSF10020366", + "OSF10020367", + "OSF10020370", + "OSF10020387", + "OSF10020388", + "OSF10020396", + "OSF10020402", + "OSF10020417", + "PT", + "PT2", + "PT154", + "R8", + "R9", + "RK1048", + "ROMAN8", + "ROMAN9", + "RUSCII", + "SE", + "SE2", + "SEN_850200_B", + "SEN_850200_C", + "SHIFT-JIS", + "SHIFT_JIS", + "SHIFT_JISX0213", + "SJIS-OPEN", + "SJIS-WIN", + "SJIS", + "SS636127", + "STRK1048-2002", + "ST_SEV_358-88", + "T.61-8BIT", + "T.61", + "T.618BIT", + "TCVN-5712", + "TCVN", + "TCVN5712-1", + "TCVN5712-1:1993", + "THAI8", + "TIS-620", + "TIS620-0", + "TIS620.2529-1", + "TIS620.2533-0", + "TIS620", + "TS-5881", + "TSCII", + "TURKISH8", + "UCS-2", + "UCS-2BE", + "UCS-2LE", + "UCS-4", + "UCS-4BE", + "UCS-4LE", + "UCS2", + "UCS4", + "UHC", + "UJIS", + "UK", + "UNICODE", + "UNICODEBIG", + "UNICODELITTLE", + "US-ASCII", + "US", + "UTF-7", + "UTF-8", + "UTF-16", + "UTF-16BE", + "UTF-16LE", + "UTF-32", + "UTF-32BE", + "UTF-32LE", + "UTF7", + "UTF8", + "UTF16", + "UTF16BE", + "UTF16LE", + "UTF32", + "UTF32BE", + "UTF32LE", + "VISCII", + "WCHAR_T", + "WIN-SAMI-2", + "WINBALTRIM", + "WINDOWS-31J", + "WINDOWS-874", + "WINDOWS-936", + "WINDOWS-1250", + "WINDOWS-1251", + "WINDOWS-1252", + "WINDOWS-1253", + "WINDOWS-1254", + "WINDOWS-1255", + "WINDOWS-1256", + "WINDOWS-1257", + "WINDOWS-1258", + "WINSAMI2", + "WS2", + "YU", + NULL}; diff --git a/src/intlconv.h b/src/intlconv.h index f28781eb0..4b8bad960 100644 --- a/src/intlconv.h +++ b/src/intlconv.h @@ -19,33 +19,21 @@ #ifndef INTLCONV_H_ #define INTLCONV_H_ -extern const char *intlconv_charsets[]; +extern const char* intlconv_charsets[]; -void intlconv_init( void ); -void intlconv_done( void ); -const char * -intlconv_filesystem_charset( void ); -char * -intlconv_charset_id( const char *charset, - int transil, - int ignore_bad_chars ); -ssize_t -intlconv_utf8( char *dst, size_t dst_size, - const char *dst_charset_id, - const char *src_utf8 ); -char * -intlconv_utf8safestr( const char *dst_charset_id, - const char *src_utf8, - size_t max_size ); +void intlconv_init(void); +void intlconv_done(void); +const char* intlconv_filesystem_charset(void); +char* intlconv_charset_id(const char* charset, int transil, int ignore_bad_chars); +ssize_t intlconv_utf8(char* dst, size_t dst_size, const char* dst_charset_id, const char* src_utf8); +char* intlconv_utf8safestr(const char* dst_charset_id, const char* src_utf8, size_t max_size); -ssize_t -intlconv_to_utf8( char *dst, size_t dst_size, - const char *src_charset_id, - const char *src, size_t src_size ); +ssize_t intlconv_to_utf8(char* dst, + size_t dst_size, + const char* src_charset_id, + const char* src, + size_t src_size); -char * -intlconv_to_utf8safestr( const char *src_charset_id, - const char *src_str, - size_t max_size ); +char* intlconv_to_utf8safestr(const char* src_charset_id, const char* src_str, size_t max_size); #endif /* INTLCONV_H_ */ diff --git a/src/lang_codes.c b/src/lang_codes.c index 8677f514c..7574a4cb9 100644 --- a/src/lang_codes.c +++ b/src/lang_codes.c @@ -26,533 +26,531 @@ * Code list * *************************************************************************/ -const lang_code_t lang_codes[] = { - { "und", NULL, NULL , "Undetermined" }, - { "aar", "aa", NULL , "Afar" }, - { "abk", "ab", NULL , "Abkhazian" }, - { "ace", NULL, NULL , "Achinese" }, - { "ach", NULL, NULL , "Acoli" }, - { "ada", NULL, NULL , "Adangme" }, - { "ady", NULL, NULL , "Adyghe; Adygei" }, - { "afa", NULL, NULL , "Afro-Asiatic languages" }, - { "afh", NULL, NULL , "Afrihili" }, - { "afr", "af", NULL , "Afrikaans" }, - { "ain", NULL, NULL , "Ainu" }, - { "aka", "ak", NULL , "Akan" }, - { "akk", NULL, NULL , "Akkadian" }, - { "alb", "sq", "sqi", "Albanian" }, - { "ale", NULL, NULL , "Aleut" }, - { "alg", NULL, NULL , "Algonquian languages" }, - { "alt", NULL, NULL , "Southern Altai" }, - { "amh", "am", NULL , "Amharic" }, - { "anp", NULL, NULL , "Angika" }, - { "apa", NULL, NULL , "Apache languages" }, - { "ara", "ar", NULL , "Arabic" }, - { "arc", NULL, NULL , "Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)" }, - { "arg", "an", NULL , "Aragonese" }, - { "arm", "hy", "hye", "Armenian" }, - { "arn", NULL, NULL , "Mapudungun; Mapuche" }, - { "arp", NULL, NULL , "Arapaho" }, - { "art", NULL, NULL , "Artificial languages" }, - { "arw", NULL, NULL , "Arawak" }, - { "asm", "as", NULL , "Assamese" }, - { "ast", NULL, NULL , "Asturian; Bable; Leonese; Asturleonese" }, - { "ath", NULL, NULL , "Athapascan languages" }, - { "aus", NULL, NULL , "Australian languages" }, - { "ava", "av", NULL , "Avaric" }, - { "ave", "ae", NULL , "Avestan" }, - { "awa", NULL, NULL , "Awadhi" }, - { "aym", "ay", NULL , "Aymara" }, - { "aze", "az", NULL , "Azerbaijani" }, - { "bad", NULL, NULL , "Banda languages" }, - { "bai", NULL, NULL , "Bamileke languages" }, - { "bak", "ba", NULL , "Bashkir" }, - { "bal", NULL, NULL , "Baluchi" }, - { "bam", "bm", NULL , "Bambara" }, - { "ban", NULL, NULL , "Balinese" }, - { "baq", "eu", "eus", "Basque" }, - { "bas", NULL, NULL , "Basa" }, - { "bat", NULL, NULL , "Baltic languages" }, - { "bej", NULL, NULL , "Beja; Bedawiyet" }, - { "bel", "be", NULL , "Belarusian" }, - { "bem", NULL, NULL , "Bemba" }, - { "ben", "bn", NULL , "Bengali" }, - { "ber", NULL, NULL , "Berber languages" }, - { "bho", NULL, NULL , "Bhojpuri" }, - { "bih", "bh", NULL , "Bihari languages" }, - { "bik", NULL, NULL , "Bikol" }, - { "bin", NULL, NULL , "Bini; Edo" }, - { "bis", "bi", NULL , "Bislama" }, - { "bla", NULL, NULL , "Siksika" }, - { "bnt", NULL, NULL , "Bantu languages" }, - { "bos", "bs", NULL , "Bosnian" }, - { "bra", NULL, NULL , "Braj" }, - { "bre", "br", NULL , "Breton" }, - { "btk", NULL, NULL , "Batak languages" }, - { "bua", NULL, NULL , "Buriat" }, - { "bug", NULL, NULL , "Buginese" }, - { "bul", "bg", NULL , "Bulgarian" }, - { "bur", "my", "mya", "Burmese" }, - { "byn", NULL, NULL , "Blin; Bilin" }, - { "cad", NULL, NULL , "Caddo" }, - { "cai", NULL, NULL , "Central American Indian languages" }, - { "car", NULL, NULL , "Galibi Carib" }, - { "cat", "ca", NULL , "Catalan; Valencian" }, - { "cau", NULL, NULL , "Caucasian languages" }, - { "ceb", NULL, NULL , "Cebuano" }, - { "cel", NULL, NULL , "Celtic languages" }, - { "cha", "ch", NULL , "Chamorro" }, - { "chb", NULL, NULL , "Chibcha" }, - { "che", "ce", NULL , "Chechen" }, - { "chg", NULL, NULL , "Chagatai" }, - { "chi", "zh", "zho", "Chinese", "CN" }, - { "chk", NULL, NULL , "Chuukese" }, - { "chm", NULL, NULL , "Mari" }, - { "chn", NULL, NULL , "Chinook jargon" }, - { "cho", NULL, NULL , "Choctaw" }, - { "chp", NULL, NULL , "Chipewyan; Dene Suline" }, - { "chr", NULL, NULL , "Cherokee" }, - { "chu", "cu", NULL , "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic" }, - { "chv", "cv", NULL , "Chuvash" }, - { "chy", NULL, NULL , "Cheyenne" }, - { "cmc", NULL, NULL , "Chamic languages" }, - { "cop", NULL, NULL , "Coptic" }, - { "cor", "kw", NULL , "Cornish" }, - { "cos", "co", NULL , "Corsican" }, - { "cre", "cr", NULL , "Cree" }, - { "crh", NULL, NULL , "Crimean Tatar; Crimean Turkish" }, - { "crp", NULL, NULL , "Creoles and pidgins" }, - { "csb", NULL, NULL , "Kashubian" }, - { "cus", NULL, NULL , "Cushitic languages" }, - { "cze", "cs", "ces", "Czech" }, - { "dak", NULL, NULL , "Dakota" }, - { "dan", "da", NULL , "Danish" }, - { "dar", NULL, NULL , "Dargwa" }, - { "day", NULL, NULL , "Land Dayak languages" }, - { "del", NULL, NULL , "Delaware" }, - { "den", NULL, NULL , "Slave (Athapascan)" }, - { "dgr", NULL, NULL , "Dogrib" }, - { "din", NULL, NULL , "Dinka" }, - { "div", "dv", NULL , "Divehi; Dhivehi; Maldivian" }, - { "doi", NULL, NULL , "Dogri" }, - { "dra", NULL, NULL , "Dravidian languages" }, - { "dsb", NULL, NULL , "Lower Sorbian" }, - { "dua", NULL, NULL , "Duala" }, - { "dut", "nl", "nld", "Dutch; Flemish" }, - { "dyu", NULL, NULL , "Dyula" }, - { "dzo", "dz", NULL , "Dzongkha" }, - { "efi", NULL, NULL , "Efik" }, - { "egy", NULL, NULL , "Egyptian (Ancient)" }, - { "eka", NULL, NULL , "Ekajuk" }, - { "elx", NULL, NULL , "Elamite" }, - { "eng", "en", NULL , "English", "US|GB" }, - { "epo", "eo", NULL , "Esperanto" }, - { "est", "et", NULL , "Estonian" }, - { "ewe", "ee", NULL , "Ewe" }, - { "ewo", NULL, NULL , "Ewondo" }, - { "fan", NULL, NULL , "Fang" }, - { "fao", "fo", NULL , "Faroese" }, - { "fat", NULL, NULL , "Fanti" }, - { "fij", "fj", NULL , "Fijian" }, - { "fil", NULL, NULL , "Filipino; Pilipino" }, - { "fin", "fi", NULL , "Finnish" }, - { "fiu", NULL, NULL , "Finno-Ugrian languages" }, - { "fon", NULL, NULL , "Fon" }, - { "fre", "fr", "fra", "French" }, - { "frr", NULL, NULL , "Northern Frisian" }, - { "frs", NULL, NULL , "Eastern Frisian" }, - { "fry", "fy", NULL , "Western Frisian" }, - { "ful", "ff", NULL , "Fulah" }, - { "fur", NULL, NULL , "Friulian" }, - { "gaa", NULL, NULL , "Ga" }, - { "gay", NULL, NULL , "Gayo" }, - { "gba", NULL, NULL , "Gbaya" }, - { "gem", NULL, NULL , "Germanic languages" }, - { "geo", "ka", "kat", "Georgian" }, - { "ger", "de", "deu", "German" }, - { "gez", NULL, NULL , "Geez" }, - { "gil", NULL, NULL , "Gilbertese" }, - { "gla", "gd", NULL , "Gaelic; Scottish Gaelic" }, - { "gle", "ga", NULL , "Irish" }, - { "glg", "gl", NULL , "Galician" }, - { "glv", "gv", NULL , "Manx" }, - { "gon", NULL, NULL , "Gondi" }, - { "gor", NULL, NULL , "Gorontalo" }, - { "got", NULL, NULL , "Gothic" }, - { "grb", NULL, NULL , "Grebo" }, - { "gre", "el", NULL , "Greek" }, - { "grn", "gn", NULL , "Guarani" }, - { "gsw", NULL, NULL , "Swiss German; Alemannic; Alsatian" }, - { "guj", "gu", NULL , "Gujarati" }, - { "gwi", NULL, NULL , "Gwich'in" }, - { "hai", NULL, NULL , "Haida" }, - { "hat", "ht", NULL , "Haitian; Haitian Creole" }, - { "hau", "ha", NULL , "Hausa" }, - { "haw", NULL, NULL , "Hawaiian" }, - { "heb", "he", NULL , "Hebrew" }, - { "her", "hz", NULL , "Herero" }, - { "hil", NULL, NULL , "Hiligaynon" }, - { "him", NULL, NULL , "Himachali languages; Western Pahari languages" }, - { "hin", "hi", NULL , "Hindi" }, - { "hit", NULL, NULL , "Hittite" }, - { "hmn", NULL, NULL , "Hmong; Mong" }, - { "hmo", "ho", NULL , "Hiri Motu" }, - { "hrv", "hr", NULL , "Croatian" }, - { "hsb", NULL, NULL , "Upper Sorbian" }, - { "hun", "hu", NULL , "Hungarian" }, - { "hup", NULL, NULL , "Hupa" }, - { "iba", NULL, NULL , "Iban" }, - { "ibo", "ig", NULL , "Igbo" }, - { "ice", "is", "isl", "Icelandic" }, - { "ido", "io", NULL , "Ido" }, - { "iii", "ii", NULL , "Sichuan Yi; Nuosu" }, - { "ijo", NULL, NULL , "Ijo languages" }, - { "iku", "iu", NULL , "Inuktitut" }, - { "ile", "ie", NULL , "Interlingue; Occidental" }, - { "ilo", NULL, NULL , "Iloko" }, - { "ina", "ia", NULL , "Interlingua (International Auxiliary Language Association)" }, - { "inc", NULL, NULL , "Indic languages" }, - { "ind", "id", NULL , "Indonesian" }, - { "ine", NULL, NULL , "Indo-European languages" }, - { "inh", NULL, NULL , "Ingush" }, - { "ipk", "ik", NULL , "Inupiaq" }, - { "ira", NULL, NULL , "Iranian languages" }, - { "iro", NULL, NULL , "Iroquoian languages" }, - { "ita", "it", NULL , "Italian" }, - { "jav", "jv", NULL , "Javanese" }, - { "jbo", NULL, NULL , "Lojban" }, - { "jpn", "ja", NULL , "Japanese" }, - { "jpr", NULL, NULL , "Judeo-Persian" }, - { "jrb", NULL, NULL , "Judeo-Arabic" }, - { "kaa", NULL, NULL , "Kara-Kalpak" }, - { "kab", NULL, NULL , "Kabyle" }, - { "kac", NULL, NULL , "Kachin; Jingpho" }, - { "kal", "kl", NULL , "Kalaallisut; Greenlandic" }, - { "kam", NULL, NULL , "Kamba" }, - { "kan", "kn", NULL , "Kannada" }, - { "kar", NULL, NULL , "Karen languages" }, - { "kas", "ks", NULL , "Kashmiri" }, - { "kau", "kr", NULL , "Kanuri" }, - { "kaw", NULL, NULL , "Kawi" }, - { "kaz", "kk", NULL , "Kazakh" }, - { "kbd", NULL, NULL , "Kabardian" }, - { "kha", NULL, NULL , "Khasi" }, - { "khi", NULL, NULL , "Khoisan languages" }, - { "khm", "km", NULL , "Central Khmer" }, - { "kho", NULL, NULL , "Khotanese; Sakan" }, - { "kik", "ki", NULL , "Kikuyu; Gikuyu" }, - { "kin", "rw", NULL , "Kinyarwanda" }, - { "kir", "ky", NULL , "Kirghiz; Kyrgyz" }, - { "kmb", NULL, NULL , "Kimbundu" }, - { "kok", NULL, NULL , "Konkani" }, - { "kom", "kv", NULL , "Komi" }, - { "kon", "kg", NULL , "Kongo" }, - { "kor", "ko", NULL , "Korean" }, - { "kos", NULL, NULL , "Kosraean" }, - { "kpe", NULL, NULL , "Kpelle" }, - { "krc", NULL, NULL , "Karachay-Balkar" }, - { "krl", NULL, NULL , "Karelian" }, - { "kro", NULL, NULL , "Kru languages" }, - { "kru", NULL, NULL , "Kurukh" }, - { "kua", "kj", NULL , "Kuanyama; Kwanyama" }, - { "kum", NULL, NULL , "Kumyk" }, - { "kur", "ku", NULL , "Kurdish" }, - { "kut", NULL, NULL , "Kutenai" }, - { "lad", NULL, NULL , "Ladino" }, - { "lah", NULL, NULL , "Lahnda" }, - { "lam", NULL, NULL , "Lamba" }, - { "lao", "lo", NULL , "Lao" }, - { "lat", "la", NULL , "Latin" }, - { "lav", "lv", NULL , "Latvian" }, - { "lez", NULL, NULL , "Lezghian" }, - { "lim", "li", NULL , "Limburgan; Limburger; Limburgish" }, - { "lin", "ln", NULL , "Lingala" }, - { "lit", "lt", NULL , "Lithuanian" }, - { "lol", NULL, NULL , "Mongo" }, - { "loz", NULL, NULL , "Lozi" }, - { "ltz", "lb", NULL , "Luxembourgish; Letzeburgesch" }, - { "lua", NULL, NULL , "Luba-Lulua" }, - { "lub", "lu", NULL , "Luba-Katanga" }, - { "lug", "lg", NULL , "Ganda" }, - { "lui", NULL, NULL , "Luiseno" }, - { "lun", NULL, NULL , "Lunda" }, - { "luo", NULL, NULL , "Luo (Kenya and Tanzania)" }, - { "lus", NULL, NULL , "Lushai" }, - { "mac", "mk", "mkd", "Macedonian" }, - { "mad", NULL, NULL , "Madurese" }, - { "mag", NULL, NULL , "Magahi" }, - { "mah", "mh", NULL , "Marshallese" }, - { "mai", NULL, NULL , "Maithili" }, - { "mak", NULL, NULL , "Makasar" }, - { "mal", "ml", NULL , "Malayalam" }, - { "man", NULL, NULL , "Mandingo" }, - { "mao", "mi", "mri", "Maori" }, - { "map", NULL, NULL , "Austronesian languages" }, - { "mar", "mr", NULL , "Marathi" }, - { "mas", NULL, NULL , "Masai" }, - { "may", "ms", "msa", "Malay" }, - { "mdf", NULL, NULL , "Moksha" }, - { "mdr", NULL, NULL , "Mandar" }, - { "men", NULL, NULL , "Mende" }, - { "mic", NULL, NULL , "Mi'kmaq; Micmac" }, - { "min", NULL, NULL , "Minangkabau" }, - { "mis", NULL, NULL , "Uncoded languages" }, - { "mkh", NULL, NULL , "Mon-Khmer languages" }, - { "mlg", "mg", NULL , "Malagasy" }, - { "mlt", "mt", NULL , "Maltese" }, - { "mnc", NULL, NULL , "Manchu" }, - { "mni", NULL, NULL , "Manipuri" }, - { "mno", NULL, NULL , "Manobo languages" }, - { "moh", NULL, NULL , "Mohawk" }, - { "mon", "mn", NULL , "Mongolian" }, - { "mos", NULL, NULL , "Mossi" }, - { "mul", NULL, NULL , "Multiple languages" }, - { "mun", NULL, NULL , "Munda languages" }, - { "mus", NULL, NULL , "Creek" }, - { "mwl", NULL, NULL , "Mirandese" }, - { "mwr", NULL, NULL , "Marwari" }, - { "myn", NULL, NULL , "Mayan languages" }, - { "myv", NULL, NULL , "Erzya" }, - { "nah", NULL, NULL , "Nahuatl languages" }, - { "nai", NULL, NULL , "North American Indian languages" }, - { "nap", NULL, NULL , "Neapolitan" }, - { "nar", NULL, NULL , "Narration: (audio described)"}, - // Note: above is not part of the ISO spec, but is used in DVB - { "nau", "na", NULL , "Nauru" }, - { "nav", "nv", NULL , "Navajo; Navaho" }, - { "ndo", "ng", NULL , "Ndonga" }, - { "nep", "ne", NULL , "Nepali" }, - { "new", NULL, NULL , "Nepal Bhasa; Newari" }, - { "nia", NULL, NULL , "Nias" }, - { "nic", NULL, NULL , "Niger-Kordofanian languages" }, - { "niu", NULL, NULL , "Niuean" }, - { "nog", NULL, NULL , "Nogai" }, - { "nor", "no", NULL , "Norwegian" }, - { "nqo", NULL, NULL , "N'Ko" }, - { "nso", NULL, NULL , "Pedi; Sepedi; Northern Sotho" }, - { "nub", NULL, NULL , "Nubian languages" }, - { "nwc", NULL, NULL , "Classical Newari; Old Newari; Classical Nepal Bhasa" }, - { "nya", "ny", NULL , "Chichewa; Chewa; Nyanja" }, - { "nym", NULL, NULL , "Nyamwezi" }, - { "nyn", NULL, NULL , "Nyankole" }, - { "nyo", NULL, NULL , "Nyoro" }, - { "nzi", NULL, NULL , "Nzima" }, - { "oci", "oc", NULL , "Occitan (post 1500)" }, - { "oji", "oj", NULL , "Ojibwa" }, - { "ori", "or", NULL , "Oriya" }, - { "orm", "om", NULL , "Oromo" }, - { "osa", NULL, NULL , "Osage" }, - { "oss", "os", NULL , "Ossetian; Ossetic" }, - { "oto", NULL, NULL , "Otomian languages" }, - { "paa", NULL, NULL , "Papuan languages" }, - { "pag", NULL, NULL , "Pangasinan" }, - { "pal", NULL, NULL , "Pahlavi" }, - { "pam", NULL, NULL , "Pampanga; Kapampangan" }, - { "pan", "pa", NULL , "Panjabi; Punjabi" }, - { "pap", NULL, NULL , "Papiamento" }, - { "pau", NULL, NULL , "Palauan" }, - { "per", "fa", "fas", "Persian" }, - { "phi", NULL, NULL , "Philippine languages" }, - { "phn", NULL, NULL , "Phoenician" }, - { "pli", "pi", NULL , "Pali" }, - { "pol", "pl", NULL , "Polish" }, - { "pon", NULL, NULL , "Pohnpeian" }, - { "por", "pt", NULL , "Portuguese" }, - { "pra", NULL, NULL , "Prakrit languages" }, - { "pus", "ps", NULL , "Pushto; Pashto" }, - { "qaa", NULL, NULL , "Reserved" }, - // Note: above is actually range from qaa to qtz - { "que", "qu", NULL , "Quechua" }, - { "raj", NULL, NULL , "Rajasthani" }, - { "rap", NULL, NULL , "Rapanui" }, - { "rar", NULL, NULL , "Rarotongan; Cook Islands Maori" }, - { "roa", NULL, NULL , "Romance languages" }, - { "roh", "rm", NULL , "Romansh" }, - { "rom", NULL, NULL , "Romany" }, - { "rum", "ro", "ron", "Romanian; Moldavian; Moldovan" }, - { "run", "rn", NULL , "Rundi" }, - { "rup", NULL, NULL , "Aromanian; Arumanian; Macedo-Romanian" }, - { "rus", "ru", NULL , "Russian" }, - { "sad", NULL, NULL , "Sandawe" }, - { "sag", "sg", NULL , "Sango" }, - { "sah", NULL, NULL , "Yakut" }, - { "sai", NULL, NULL , "South American Indian languages" }, - { "sal", NULL, NULL , "Salishan languages" }, - { "sam", NULL, NULL , "Samaritan Aramaic" }, - { "san", "sa", NULL , "Sanskrit" }, - { "sas", NULL, NULL , "Sasak" }, - { "sat", NULL, NULL , "Santali" }, - { "scn", NULL, NULL , "Sicilian" }, - { "sco", NULL, NULL , "Scots" }, - { "sel", NULL, NULL , "Selkup" }, - { "sem", NULL, NULL , "Semitic languages" }, - { "sgn", NULL, NULL , "Sign Languages" }, - { "shn", NULL, NULL , "Shan" }, - { "sid", NULL, NULL , "Sidamo" }, - { "sin", "si", NULL , "Sinhala; Sinhalese" }, - { "sio", NULL, NULL , "Siouan languages" }, - { "sit", NULL, NULL , "Sino-Tibetan languages" }, - { "sla", NULL, NULL , "Slavic languages" }, - { "slo", "sk", "slk", "Slovak" }, - { "slv", "sl", NULL , "Slovenian" }, - { "sma", NULL, NULL , "Southern Sami" }, - { "sme", "se", NULL , "Northern Sami" }, - { "smi", NULL, NULL , "Sami languages" }, - { "smj", NULL, NULL , "Lule Sami" }, - { "smn", NULL, NULL , "Inari Sami" }, - { "smo", "sm", NULL , "Samoan" }, - { "sms", NULL, NULL , "Skolt Sami" }, - { "sna", "sn", NULL , "Shona" }, - { "snd", "sd", NULL , "Sindhi" }, - { "snk", NULL, NULL , "Soninke" }, - { "sog", NULL, NULL , "Sogdian" }, - { "som", "so", NULL , "Somali" }, - { "son", NULL, NULL , "Songhai languages" }, - { "spa", "es", NULL , "Spanish" }, - { "srd", "sc", NULL , "Sardinian" }, - { "srn", NULL, NULL , "Sranan Tongo" }, - { "srp", "sr", NULL , "Serbian" }, - { "srr", NULL, NULL , "Serer" }, - { "ssa", NULL, NULL , "Nilo-Saharan languages" }, - { "ssw", "ss", NULL , "Swati" }, - { "suk", NULL, NULL , "Sukuma" }, - { "sun", "su", NULL , "Sundanese" }, - { "sus", NULL, NULL , "Susu" }, - { "sux", NULL, NULL , "Sumerian" }, - { "swa", "sw", NULL , "Swahili" }, - { "swe", "sv", NULL , "Swedish" }, - { "syc", NULL, NULL , "Classical Syriac" }, - { "syn", NULL, NULL , "Narration: (sync audio described)"}, - { "syr", NULL, NULL , "Syriac" }, - { "tah", "ty", NULL , "Tahitian" }, - { "tai", NULL, NULL , "Tai languages" }, - { "tam", "ta", NULL , "Tamil" }, - { "tat", "tt", NULL , "Tatar" }, - { "tel", "te", NULL , "Telugu" }, - { "tem", NULL, NULL , "Timne" }, - { "ter", NULL, NULL , "Tereno" }, - { "tet", NULL, NULL , "Tetum" }, - { "tgk", "tg", NULL , "Tajik" }, - { "tgl", "tl", NULL , "Tagalog" }, - { "tha", "th", NULL , "Thai" }, - { "tib", "bo", "bod", "Tibetan" }, - { "tig", NULL, NULL , "Tigre" }, - { "tir", "ti", NULL , "Tigrinya" }, - { "tiv", NULL, NULL , "Tiv" }, - { "tkl", NULL, NULL , "Tokelau" }, - { "tlh", NULL, NULL , "Klingon; tlhIngan-Hol" }, - { "tli", NULL, NULL , "Tlingit" }, - { "tmh", NULL, NULL , "Tamashek" }, - { "tog", NULL, NULL , "Tonga (Nyasa)" }, - { "ton", "to", NULL , "Tonga (Tonga Islands)" }, - { "tpi", NULL, NULL , "Tok Pisin" }, - { "tsi", NULL, NULL , "Tsimshian" }, - { "tsn", "tn", NULL , "Tswana" }, - { "tso", "ts", NULL , "Tsonga" }, - { "tuk", "tk", NULL , "Turkmen" }, - { "tum", NULL, NULL , "Tumbuka" }, - { "tup", NULL, NULL , "Tupi languages" }, - { "tur", "tr", NULL , "Turkish" }, - { "tut", NULL, NULL , "Altaic languages" }, - { "tvl", NULL, NULL , "Tuvalu" }, - { "twi", "tw", NULL , "Twi" }, - { "tyv", NULL, NULL , "Tuvinian" }, - { "udm", NULL, NULL , "Udmurt" }, - { "uga", NULL, NULL , "Ugaritic" }, - { "uig", "ug", NULL , "Uighur; Uyghur" }, - { "ukr", "uk", NULL , "Ukrainian" }, - { "umb", NULL, NULL , "Umbundu" }, - { "urd", "ur", NULL , "Urdu" }, - { "uzb", "uz", NULL , "Uzbek" }, - { "v.o", NULL, NULL , "Voice Original" }, - { "vai", NULL, NULL , "Vai" }, - { "ven", "ve", NULL , "Venda" }, - { "vie", "vi", NULL , "Vietnamese" }, - { "vol", "vo", NULL , "Volapük" }, - { "vot", NULL, NULL , "Votic" }, - { "wak", NULL, NULL , "Wakashan languages" }, - { "wal", NULL, NULL , "Wolaitta; Wolaytta" }, - { "war", NULL, NULL , "Waray" }, - { "was", NULL, NULL , "Washo" }, - { "wel", "cy", "cym", "Welsh" }, - { "wen", NULL, NULL , "Sorbian languages" }, - { "wln", "wa", NULL , "Walloon" }, - { "wol", "wo", NULL , "Wolof" }, - { "xal", NULL, NULL , "Kalmyk; Oirat" }, - { "xho", "xh", NULL , "Xhosa" }, - { "yao", NULL, NULL , "Yao" }, - { "yap", NULL, NULL , "Yapese" }, - { "yid", "yi", NULL , "Yiddish" }, - { "yor", "yo", NULL , "Yoruba" }, - { "ypk", NULL, NULL , "Yupik languages" }, - { "zap", NULL, NULL , "Zapotec" }, - { "zbl", NULL, NULL , "Blissymbols; Blissymbolics; Bliss" }, - { "zen", NULL, NULL , "Zenaga" }, - { "zha", "za", NULL , "Zhuang; Chuang" }, - { "znd", NULL, NULL , "Zande languages" }, - { "zul", "zu", NULL , "Zulu" }, - { "zun", NULL, NULL , "Zuni" }, - { "zza", NULL, NULL , "Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki" }, - { NULL, NULL, NULL, NULL } -}; +const lang_code_t lang_codes[] = {{"und", NULL, NULL, "Undetermined"}, + {"aar", "aa", NULL, "Afar"}, + {"abk", "ab", NULL, "Abkhazian"}, + {"ace", NULL, NULL, "Achinese"}, + {"ach", NULL, NULL, "Acoli"}, + {"ada", NULL, NULL, "Adangme"}, + {"ady", NULL, NULL, "Adyghe; Adygei"}, + {"afa", NULL, NULL, "Afro-Asiatic languages"}, + {"afh", NULL, NULL, "Afrihili"}, + {"afr", "af", NULL, "Afrikaans"}, + {"ain", NULL, NULL, "Ainu"}, + {"aka", "ak", NULL, "Akan"}, + {"akk", NULL, NULL, "Akkadian"}, + {"alb", "sq", "sqi", "Albanian"}, + {"ale", NULL, NULL, "Aleut"}, + {"alg", NULL, NULL, "Algonquian languages"}, + {"alt", NULL, NULL, "Southern Altai"}, + {"amh", "am", NULL, "Amharic"}, + {"anp", NULL, NULL, "Angika"}, + {"apa", NULL, NULL, "Apache languages"}, + {"ara", "ar", NULL, "Arabic"}, + {"arc", NULL, NULL, "Official Aramaic (700-300 BCE); Imperial Aramaic (700-300 BCE)"}, + {"arg", "an", NULL, "Aragonese"}, + {"arm", "hy", "hye", "Armenian"}, + {"arn", NULL, NULL, "Mapudungun; Mapuche"}, + {"arp", NULL, NULL, "Arapaho"}, + {"art", NULL, NULL, "Artificial languages"}, + {"arw", NULL, NULL, "Arawak"}, + {"asm", "as", NULL, "Assamese"}, + {"ast", NULL, NULL, "Asturian; Bable; Leonese; Asturleonese"}, + {"ath", NULL, NULL, "Athapascan languages"}, + {"aus", NULL, NULL, "Australian languages"}, + {"ava", "av", NULL, "Avaric"}, + {"ave", "ae", NULL, "Avestan"}, + {"awa", NULL, NULL, "Awadhi"}, + {"aym", "ay", NULL, "Aymara"}, + {"aze", "az", NULL, "Azerbaijani"}, + {"bad", NULL, NULL, "Banda languages"}, + {"bai", NULL, NULL, "Bamileke languages"}, + {"bak", "ba", NULL, "Bashkir"}, + {"bal", NULL, NULL, "Baluchi"}, + {"bam", "bm", NULL, "Bambara"}, + {"ban", NULL, NULL, "Balinese"}, + {"baq", "eu", "eus", "Basque"}, + {"bas", NULL, NULL, "Basa"}, + {"bat", NULL, NULL, "Baltic languages"}, + {"bej", NULL, NULL, "Beja; Bedawiyet"}, + {"bel", "be", NULL, "Belarusian"}, + {"bem", NULL, NULL, "Bemba"}, + {"ben", "bn", NULL, "Bengali"}, + {"ber", NULL, NULL, "Berber languages"}, + {"bho", NULL, NULL, "Bhojpuri"}, + {"bih", "bh", NULL, "Bihari languages"}, + {"bik", NULL, NULL, "Bikol"}, + {"bin", NULL, NULL, "Bini; Edo"}, + {"bis", "bi", NULL, "Bislama"}, + {"bla", NULL, NULL, "Siksika"}, + {"bnt", NULL, NULL, "Bantu languages"}, + {"bos", "bs", NULL, "Bosnian"}, + {"bra", NULL, NULL, "Braj"}, + {"bre", "br", NULL, "Breton"}, + {"btk", NULL, NULL, "Batak languages"}, + {"bua", NULL, NULL, "Buriat"}, + {"bug", NULL, NULL, "Buginese"}, + {"bul", "bg", NULL, "Bulgarian"}, + {"bur", "my", "mya", "Burmese"}, + {"byn", NULL, NULL, "Blin; Bilin"}, + {"cad", NULL, NULL, "Caddo"}, + {"cai", NULL, NULL, "Central American Indian languages"}, + {"car", NULL, NULL, "Galibi Carib"}, + {"cat", "ca", NULL, "Catalan; Valencian"}, + {"cau", NULL, NULL, "Caucasian languages"}, + {"ceb", NULL, NULL, "Cebuano"}, + {"cel", NULL, NULL, "Celtic languages"}, + {"cha", "ch", NULL, "Chamorro"}, + {"chb", NULL, NULL, "Chibcha"}, + {"che", "ce", NULL, "Chechen"}, + {"chg", NULL, NULL, "Chagatai"}, + {"chi", "zh", "zho", "Chinese", "CN"}, + {"chk", NULL, NULL, "Chuukese"}, + {"chm", NULL, NULL, "Mari"}, + {"chn", NULL, NULL, "Chinook jargon"}, + {"cho", NULL, NULL, "Choctaw"}, + {"chp", NULL, NULL, "Chipewyan; Dene Suline"}, + {"chr", NULL, NULL, "Cherokee"}, + {"chu", + "cu", + NULL, + "Church Slavic; Old Slavonic; Church Slavonic; Old Bulgarian; Old Church Slavonic"}, + {"chv", "cv", NULL, "Chuvash"}, + {"chy", NULL, NULL, "Cheyenne"}, + {"cmc", NULL, NULL, "Chamic languages"}, + {"cop", NULL, NULL, "Coptic"}, + {"cor", "kw", NULL, "Cornish"}, + {"cos", "co", NULL, "Corsican"}, + {"cre", "cr", NULL, "Cree"}, + {"crh", NULL, NULL, "Crimean Tatar; Crimean Turkish"}, + {"crp", NULL, NULL, "Creoles and pidgins"}, + {"csb", NULL, NULL, "Kashubian"}, + {"cus", NULL, NULL, "Cushitic languages"}, + {"cze", "cs", "ces", "Czech"}, + {"dak", NULL, NULL, "Dakota"}, + {"dan", "da", NULL, "Danish"}, + {"dar", NULL, NULL, "Dargwa"}, + {"day", NULL, NULL, "Land Dayak languages"}, + {"del", NULL, NULL, "Delaware"}, + {"den", NULL, NULL, "Slave (Athapascan)"}, + {"dgr", NULL, NULL, "Dogrib"}, + {"din", NULL, NULL, "Dinka"}, + {"div", "dv", NULL, "Divehi; Dhivehi; Maldivian"}, + {"doi", NULL, NULL, "Dogri"}, + {"dra", NULL, NULL, "Dravidian languages"}, + {"dsb", NULL, NULL, "Lower Sorbian"}, + {"dua", NULL, NULL, "Duala"}, + {"dut", "nl", "nld", "Dutch; Flemish"}, + {"dyu", NULL, NULL, "Dyula"}, + {"dzo", "dz", NULL, "Dzongkha"}, + {"efi", NULL, NULL, "Efik"}, + {"egy", NULL, NULL, "Egyptian (Ancient)"}, + {"eka", NULL, NULL, "Ekajuk"}, + {"elx", NULL, NULL, "Elamite"}, + {"eng", "en", NULL, "English", "US|GB"}, + {"epo", "eo", NULL, "Esperanto"}, + {"est", "et", NULL, "Estonian"}, + {"ewe", "ee", NULL, "Ewe"}, + {"ewo", NULL, NULL, "Ewondo"}, + {"fan", NULL, NULL, "Fang"}, + {"fao", "fo", NULL, "Faroese"}, + {"fat", NULL, NULL, "Fanti"}, + {"fij", "fj", NULL, "Fijian"}, + {"fil", NULL, NULL, "Filipino; Pilipino"}, + {"fin", "fi", NULL, "Finnish"}, + {"fiu", NULL, NULL, "Finno-Ugrian languages"}, + {"fon", NULL, NULL, "Fon"}, + {"fre", "fr", "fra", "French"}, + {"frr", NULL, NULL, "Northern Frisian"}, + {"frs", NULL, NULL, "Eastern Frisian"}, + {"fry", "fy", NULL, "Western Frisian"}, + {"ful", "ff", NULL, "Fulah"}, + {"fur", NULL, NULL, "Friulian"}, + {"gaa", NULL, NULL, "Ga"}, + {"gay", NULL, NULL, "Gayo"}, + {"gba", NULL, NULL, "Gbaya"}, + {"gem", NULL, NULL, "Germanic languages"}, + {"geo", "ka", "kat", "Georgian"}, + {"ger", "de", "deu", "German"}, + {"gez", NULL, NULL, "Geez"}, + {"gil", NULL, NULL, "Gilbertese"}, + {"gla", "gd", NULL, "Gaelic; Scottish Gaelic"}, + {"gle", "ga", NULL, "Irish"}, + {"glg", "gl", NULL, "Galician"}, + {"glv", "gv", NULL, "Manx"}, + {"gon", NULL, NULL, "Gondi"}, + {"gor", NULL, NULL, "Gorontalo"}, + {"got", NULL, NULL, "Gothic"}, + {"grb", NULL, NULL, "Grebo"}, + {"gre", "el", NULL, "Greek"}, + {"grn", "gn", NULL, "Guarani"}, + {"gsw", NULL, NULL, "Swiss German; Alemannic; Alsatian"}, + {"guj", "gu", NULL, "Gujarati"}, + {"gwi", NULL, NULL, "Gwich'in"}, + {"hai", NULL, NULL, "Haida"}, + {"hat", "ht", NULL, "Haitian; Haitian Creole"}, + {"hau", "ha", NULL, "Hausa"}, + {"haw", NULL, NULL, "Hawaiian"}, + {"heb", "he", NULL, "Hebrew"}, + {"her", "hz", NULL, "Herero"}, + {"hil", NULL, NULL, "Hiligaynon"}, + {"him", NULL, NULL, "Himachali languages; Western Pahari languages"}, + {"hin", "hi", NULL, "Hindi"}, + {"hit", NULL, NULL, "Hittite"}, + {"hmn", NULL, NULL, "Hmong; Mong"}, + {"hmo", "ho", NULL, "Hiri Motu"}, + {"hrv", "hr", NULL, "Croatian"}, + {"hsb", NULL, NULL, "Upper Sorbian"}, + {"hun", "hu", NULL, "Hungarian"}, + {"hup", NULL, NULL, "Hupa"}, + {"iba", NULL, NULL, "Iban"}, + {"ibo", "ig", NULL, "Igbo"}, + {"ice", "is", "isl", "Icelandic"}, + {"ido", "io", NULL, "Ido"}, + {"iii", "ii", NULL, "Sichuan Yi; Nuosu"}, + {"ijo", NULL, NULL, "Ijo languages"}, + {"iku", "iu", NULL, "Inuktitut"}, + {"ile", "ie", NULL, "Interlingue; Occidental"}, + {"ilo", NULL, NULL, "Iloko"}, + {"ina", "ia", NULL, "Interlingua (International Auxiliary Language Association)"}, + {"inc", NULL, NULL, "Indic languages"}, + {"ind", "id", NULL, "Indonesian"}, + {"ine", NULL, NULL, "Indo-European languages"}, + {"inh", NULL, NULL, "Ingush"}, + {"ipk", "ik", NULL, "Inupiaq"}, + {"ira", NULL, NULL, "Iranian languages"}, + {"iro", NULL, NULL, "Iroquoian languages"}, + {"ita", "it", NULL, "Italian"}, + {"jav", "jv", NULL, "Javanese"}, + {"jbo", NULL, NULL, "Lojban"}, + {"jpn", "ja", NULL, "Japanese"}, + {"jpr", NULL, NULL, "Judeo-Persian"}, + {"jrb", NULL, NULL, "Judeo-Arabic"}, + {"kaa", NULL, NULL, "Kara-Kalpak"}, + {"kab", NULL, NULL, "Kabyle"}, + {"kac", NULL, NULL, "Kachin; Jingpho"}, + {"kal", "kl", NULL, "Kalaallisut; Greenlandic"}, + {"kam", NULL, NULL, "Kamba"}, + {"kan", "kn", NULL, "Kannada"}, + {"kar", NULL, NULL, "Karen languages"}, + {"kas", "ks", NULL, "Kashmiri"}, + {"kau", "kr", NULL, "Kanuri"}, + {"kaw", NULL, NULL, "Kawi"}, + {"kaz", "kk", NULL, "Kazakh"}, + {"kbd", NULL, NULL, "Kabardian"}, + {"kha", NULL, NULL, "Khasi"}, + {"khi", NULL, NULL, "Khoisan languages"}, + {"khm", "km", NULL, "Central Khmer"}, + {"kho", NULL, NULL, "Khotanese; Sakan"}, + {"kik", "ki", NULL, "Kikuyu; Gikuyu"}, + {"kin", "rw", NULL, "Kinyarwanda"}, + {"kir", "ky", NULL, "Kirghiz; Kyrgyz"}, + {"kmb", NULL, NULL, "Kimbundu"}, + {"kok", NULL, NULL, "Konkani"}, + {"kom", "kv", NULL, "Komi"}, + {"kon", "kg", NULL, "Kongo"}, + {"kor", "ko", NULL, "Korean"}, + {"kos", NULL, NULL, "Kosraean"}, + {"kpe", NULL, NULL, "Kpelle"}, + {"krc", NULL, NULL, "Karachay-Balkar"}, + {"krl", NULL, NULL, "Karelian"}, + {"kro", NULL, NULL, "Kru languages"}, + {"kru", NULL, NULL, "Kurukh"}, + {"kua", "kj", NULL, "Kuanyama; Kwanyama"}, + {"kum", NULL, NULL, "Kumyk"}, + {"kur", "ku", NULL, "Kurdish"}, + {"kut", NULL, NULL, "Kutenai"}, + {"lad", NULL, NULL, "Ladino"}, + {"lah", NULL, NULL, "Lahnda"}, + {"lam", NULL, NULL, "Lamba"}, + {"lao", "lo", NULL, "Lao"}, + {"lat", "la", NULL, "Latin"}, + {"lav", "lv", NULL, "Latvian"}, + {"lez", NULL, NULL, "Lezghian"}, + {"lim", "li", NULL, "Limburgan; Limburger; Limburgish"}, + {"lin", "ln", NULL, "Lingala"}, + {"lit", "lt", NULL, "Lithuanian"}, + {"lol", NULL, NULL, "Mongo"}, + {"loz", NULL, NULL, "Lozi"}, + {"ltz", "lb", NULL, "Luxembourgish; Letzeburgesch"}, + {"lua", NULL, NULL, "Luba-Lulua"}, + {"lub", "lu", NULL, "Luba-Katanga"}, + {"lug", "lg", NULL, "Ganda"}, + {"lui", NULL, NULL, "Luiseno"}, + {"lun", NULL, NULL, "Lunda"}, + {"luo", NULL, NULL, "Luo (Kenya and Tanzania)"}, + {"lus", NULL, NULL, "Lushai"}, + {"mac", "mk", "mkd", "Macedonian"}, + {"mad", NULL, NULL, "Madurese"}, + {"mag", NULL, NULL, "Magahi"}, + {"mah", "mh", NULL, "Marshallese"}, + {"mai", NULL, NULL, "Maithili"}, + {"mak", NULL, NULL, "Makasar"}, + {"mal", "ml", NULL, "Malayalam"}, + {"man", NULL, NULL, "Mandingo"}, + {"mao", "mi", "mri", "Maori"}, + {"map", NULL, NULL, "Austronesian languages"}, + {"mar", "mr", NULL, "Marathi"}, + {"mas", NULL, NULL, "Masai"}, + {"may", "ms", "msa", "Malay"}, + {"mdf", NULL, NULL, "Moksha"}, + {"mdr", NULL, NULL, "Mandar"}, + {"men", NULL, NULL, "Mende"}, + {"mic", NULL, NULL, "Mi'kmaq; Micmac"}, + {"min", NULL, NULL, "Minangkabau"}, + {"mis", NULL, NULL, "Uncoded languages"}, + {"mkh", NULL, NULL, "Mon-Khmer languages"}, + {"mlg", "mg", NULL, "Malagasy"}, + {"mlt", "mt", NULL, "Maltese"}, + {"mnc", NULL, NULL, "Manchu"}, + {"mni", NULL, NULL, "Manipuri"}, + {"mno", NULL, NULL, "Manobo languages"}, + {"moh", NULL, NULL, "Mohawk"}, + {"mon", "mn", NULL, "Mongolian"}, + {"mos", NULL, NULL, "Mossi"}, + {"mul", NULL, NULL, "Multiple languages"}, + {"mun", NULL, NULL, "Munda languages"}, + {"mus", NULL, NULL, "Creek"}, + {"mwl", NULL, NULL, "Mirandese"}, + {"mwr", NULL, NULL, "Marwari"}, + {"myn", NULL, NULL, "Mayan languages"}, + {"myv", NULL, NULL, "Erzya"}, + {"nah", NULL, NULL, "Nahuatl languages"}, + {"nai", NULL, NULL, "North American Indian languages"}, + {"nap", NULL, NULL, "Neapolitan"}, + {"nar", NULL, NULL, "Narration: (audio described)"}, + // Note: above is not part of the ISO spec, but is used in DVB + {"nau", "na", NULL, "Nauru"}, + {"nav", "nv", NULL, "Navajo; Navaho"}, + {"ndo", "ng", NULL, "Ndonga"}, + {"nep", "ne", NULL, "Nepali"}, + {"new", NULL, NULL, "Nepal Bhasa; Newari"}, + {"nia", NULL, NULL, "Nias"}, + {"nic", NULL, NULL, "Niger-Kordofanian languages"}, + {"niu", NULL, NULL, "Niuean"}, + {"nog", NULL, NULL, "Nogai"}, + {"nor", "no", NULL, "Norwegian"}, + {"nqo", NULL, NULL, "N'Ko"}, + {"nso", NULL, NULL, "Pedi; Sepedi; Northern Sotho"}, + {"nub", NULL, NULL, "Nubian languages"}, + {"nwc", NULL, NULL, "Classical Newari; Old Newari; Classical Nepal Bhasa"}, + {"nya", "ny", NULL, "Chichewa; Chewa; Nyanja"}, + {"nym", NULL, NULL, "Nyamwezi"}, + {"nyn", NULL, NULL, "Nyankole"}, + {"nyo", NULL, NULL, "Nyoro"}, + {"nzi", NULL, NULL, "Nzima"}, + {"oci", "oc", NULL, "Occitan (post 1500)"}, + {"oji", "oj", NULL, "Ojibwa"}, + {"ori", "or", NULL, "Oriya"}, + {"orm", "om", NULL, "Oromo"}, + {"osa", NULL, NULL, "Osage"}, + {"oss", "os", NULL, "Ossetian; Ossetic"}, + {"oto", NULL, NULL, "Otomian languages"}, + {"paa", NULL, NULL, "Papuan languages"}, + {"pag", NULL, NULL, "Pangasinan"}, + {"pal", NULL, NULL, "Pahlavi"}, + {"pam", NULL, NULL, "Pampanga; Kapampangan"}, + {"pan", "pa", NULL, "Panjabi; Punjabi"}, + {"pap", NULL, NULL, "Papiamento"}, + {"pau", NULL, NULL, "Palauan"}, + {"per", "fa", "fas", "Persian"}, + {"phi", NULL, NULL, "Philippine languages"}, + {"phn", NULL, NULL, "Phoenician"}, + {"pli", "pi", NULL, "Pali"}, + {"pol", "pl", NULL, "Polish"}, + {"pon", NULL, NULL, "Pohnpeian"}, + {"por", "pt", NULL, "Portuguese"}, + {"pra", NULL, NULL, "Prakrit languages"}, + {"pus", "ps", NULL, "Pushto; Pashto"}, + {"qaa", NULL, NULL, "Reserved"}, + // Note: above is actually range from qaa to qtz + {"que", "qu", NULL, "Quechua"}, + {"raj", NULL, NULL, "Rajasthani"}, + {"rap", NULL, NULL, "Rapanui"}, + {"rar", NULL, NULL, "Rarotongan; Cook Islands Maori"}, + {"roa", NULL, NULL, "Romance languages"}, + {"roh", "rm", NULL, "Romansh"}, + {"rom", NULL, NULL, "Romany"}, + {"rum", "ro", "ron", "Romanian; Moldavian; Moldovan"}, + {"run", "rn", NULL, "Rundi"}, + {"rup", NULL, NULL, "Aromanian; Arumanian; Macedo-Romanian"}, + {"rus", "ru", NULL, "Russian"}, + {"sad", NULL, NULL, "Sandawe"}, + {"sag", "sg", NULL, "Sango"}, + {"sah", NULL, NULL, "Yakut"}, + {"sai", NULL, NULL, "South American Indian languages"}, + {"sal", NULL, NULL, "Salishan languages"}, + {"sam", NULL, NULL, "Samaritan Aramaic"}, + {"san", "sa", NULL, "Sanskrit"}, + {"sas", NULL, NULL, "Sasak"}, + {"sat", NULL, NULL, "Santali"}, + {"scn", NULL, NULL, "Sicilian"}, + {"sco", NULL, NULL, "Scots"}, + {"sel", NULL, NULL, "Selkup"}, + {"sem", NULL, NULL, "Semitic languages"}, + {"sgn", NULL, NULL, "Sign Languages"}, + {"shn", NULL, NULL, "Shan"}, + {"sid", NULL, NULL, "Sidamo"}, + {"sin", "si", NULL, "Sinhala; Sinhalese"}, + {"sio", NULL, NULL, "Siouan languages"}, + {"sit", NULL, NULL, "Sino-Tibetan languages"}, + {"sla", NULL, NULL, "Slavic languages"}, + {"slo", "sk", "slk", "Slovak"}, + {"slv", "sl", NULL, "Slovenian"}, + {"sma", NULL, NULL, "Southern Sami"}, + {"sme", "se", NULL, "Northern Sami"}, + {"smi", NULL, NULL, "Sami languages"}, + {"smj", NULL, NULL, "Lule Sami"}, + {"smn", NULL, NULL, "Inari Sami"}, + {"smo", "sm", NULL, "Samoan"}, + {"sms", NULL, NULL, "Skolt Sami"}, + {"sna", "sn", NULL, "Shona"}, + {"snd", "sd", NULL, "Sindhi"}, + {"snk", NULL, NULL, "Soninke"}, + {"sog", NULL, NULL, "Sogdian"}, + {"som", "so", NULL, "Somali"}, + {"son", NULL, NULL, "Songhai languages"}, + {"spa", "es", NULL, "Spanish"}, + {"srd", "sc", NULL, "Sardinian"}, + {"srn", NULL, NULL, "Sranan Tongo"}, + {"srp", "sr", NULL, "Serbian"}, + {"srr", NULL, NULL, "Serer"}, + {"ssa", NULL, NULL, "Nilo-Saharan languages"}, + {"ssw", "ss", NULL, "Swati"}, + {"suk", NULL, NULL, "Sukuma"}, + {"sun", "su", NULL, "Sundanese"}, + {"sus", NULL, NULL, "Susu"}, + {"sux", NULL, NULL, "Sumerian"}, + {"swa", "sw", NULL, "Swahili"}, + {"swe", "sv", NULL, "Swedish"}, + {"syc", NULL, NULL, "Classical Syriac"}, + {"syn", NULL, NULL, "Narration: (sync audio described)"}, + {"syr", NULL, NULL, "Syriac"}, + {"tah", "ty", NULL, "Tahitian"}, + {"tai", NULL, NULL, "Tai languages"}, + {"tam", "ta", NULL, "Tamil"}, + {"tat", "tt", NULL, "Tatar"}, + {"tel", "te", NULL, "Telugu"}, + {"tem", NULL, NULL, "Timne"}, + {"ter", NULL, NULL, "Tereno"}, + {"tet", NULL, NULL, "Tetum"}, + {"tgk", "tg", NULL, "Tajik"}, + {"tgl", "tl", NULL, "Tagalog"}, + {"tha", "th", NULL, "Thai"}, + {"tib", "bo", "bod", "Tibetan"}, + {"tig", NULL, NULL, "Tigre"}, + {"tir", "ti", NULL, "Tigrinya"}, + {"tiv", NULL, NULL, "Tiv"}, + {"tkl", NULL, NULL, "Tokelau"}, + {"tlh", NULL, NULL, "Klingon; tlhIngan-Hol"}, + {"tli", NULL, NULL, "Tlingit"}, + {"tmh", NULL, NULL, "Tamashek"}, + {"tog", NULL, NULL, "Tonga (Nyasa)"}, + {"ton", "to", NULL, "Tonga (Tonga Islands)"}, + {"tpi", NULL, NULL, "Tok Pisin"}, + {"tsi", NULL, NULL, "Tsimshian"}, + {"tsn", "tn", NULL, "Tswana"}, + {"tso", "ts", NULL, "Tsonga"}, + {"tuk", "tk", NULL, "Turkmen"}, + {"tum", NULL, NULL, "Tumbuka"}, + {"tup", NULL, NULL, "Tupi languages"}, + {"tur", "tr", NULL, "Turkish"}, + {"tut", NULL, NULL, "Altaic languages"}, + {"tvl", NULL, NULL, "Tuvalu"}, + {"twi", "tw", NULL, "Twi"}, + {"tyv", NULL, NULL, "Tuvinian"}, + {"udm", NULL, NULL, "Udmurt"}, + {"uga", NULL, NULL, "Ugaritic"}, + {"uig", "ug", NULL, "Uighur; Uyghur"}, + {"ukr", "uk", NULL, "Ukrainian"}, + {"umb", NULL, NULL, "Umbundu"}, + {"urd", "ur", NULL, "Urdu"}, + {"uzb", "uz", NULL, "Uzbek"}, + {"v.o", NULL, NULL, "Voice Original"}, + {"vai", NULL, NULL, "Vai"}, + {"ven", "ve", NULL, "Venda"}, + {"vie", "vi", NULL, "Vietnamese"}, + {"vol", "vo", NULL, "Volapük"}, + {"vot", NULL, NULL, "Votic"}, + {"wak", NULL, NULL, "Wakashan languages"}, + {"wal", NULL, NULL, "Wolaitta; Wolaytta"}, + {"war", NULL, NULL, "Waray"}, + {"was", NULL, NULL, "Washo"}, + {"wel", "cy", "cym", "Welsh"}, + {"wen", NULL, NULL, "Sorbian languages"}, + {"wln", "wa", NULL, "Walloon"}, + {"wol", "wo", NULL, "Wolof"}, + {"xal", NULL, NULL, "Kalmyk; Oirat"}, + {"xho", "xh", NULL, "Xhosa"}, + {"yao", NULL, NULL, "Yao"}, + {"yap", NULL, NULL, "Yapese"}, + {"yid", "yi", NULL, "Yiddish"}, + {"yor", "yo", NULL, "Yoruba"}, + {"ypk", NULL, NULL, "Yupik languages"}, + {"zap", NULL, NULL, "Zapotec"}, + {"zbl", NULL, NULL, "Blissymbols; Blissymbolics; Bliss"}, + {"zen", NULL, NULL, "Zenaga"}, + {"zha", "za", NULL, "Zhuang; Chuang"}, + {"znd", NULL, NULL, "Zande languages"}, + {"zul", "zu", NULL, "Zulu"}, + {"zun", NULL, NULL, "Zuni"}, + {"zza", NULL, NULL, "Zaza; Dimili; Dimli; Kirdki; Kirmanjki; Zazaki"}, + {NULL, NULL, NULL, NULL}}; lang_code_lookup_t* lang_codes_code2b = NULL; -lang_code_lookup_t* lang_codes_code1 = NULL; +lang_code_lookup_t* lang_codes_code1 = NULL; lang_code_lookup_t* lang_codes_code2t = NULL; tvh_mutex_t lang_code_split_mutex = TVH_THREAD_MUTEX_INITIALIZER; -RB_HEAD(,lang_code_list) lang_code_split_tree = { NULL, NULL, NULL, 0 }; +RB_HEAD(, lang_code_list) lang_code_split_tree = {NULL, NULL, NULL, 0}; /* ************************************************************************** * Functions * *************************************************************************/ /* Compare language codes */ -static int _lang_code2b_cmp ( void *a, void *b ) -{ +static int _lang_code2b_cmp(void* a, void* b) { return strcmp(((lang_code_lookup_element_t*)a)->lang_code->code2b, - ((lang_code_lookup_element_t*)b)->lang_code->code2b); + ((lang_code_lookup_element_t*)b)->lang_code->code2b); } -static int _lang_code1_cmp ( void *a, void *b ) -{ +static int _lang_code1_cmp(void* a, void* b) { return strcmp(((lang_code_lookup_element_t*)a)->lang_code->code1, - ((lang_code_lookup_element_t*)b)->lang_code->code1); + ((lang_code_lookup_element_t*)b)->lang_code->code1); } -static int _lang_code2t_cmp ( void *a, void *b ) -{ +static int _lang_code2t_cmp(void* a, void* b) { return strcmp(((lang_code_lookup_element_t*)a)->lang_code->code2t, - ((lang_code_lookup_element_t*)b)->lang_code->code2t); + ((lang_code_lookup_element_t*)b)->lang_code->code2t); } -static int _lang_code_lookup_add - ( lang_code_lookup_t* lookup_table, const lang_code_t *code, - int (*func)(void*, void*) ) -{ - lang_code_lookup_element_t *element; - element = (lang_code_lookup_element_t *)calloc(1, sizeof(lang_code_lookup_element_t)); +static int _lang_code_lookup_add(lang_code_lookup_t* lookup_table, + const lang_code_t* code, + int (*func)(void*, void*)) { + lang_code_lookup_element_t* element; + element = (lang_code_lookup_element_t*)calloc(1, sizeof(lang_code_lookup_element_t)); element->lang_code = code; RB_INSERT_SORTED(lookup_table, element, link, func); return 0; } -static const lang_code_t *_lang_code_get ( const char *code, size_t len ) -{ - int i; +static const lang_code_t* _lang_code_get(const char* code, size_t len) { + int i; char tmp[4]; - + if (lang_codes_code2b == NULL) { - const lang_code_t *c = lang_codes; + const lang_code_t* c = lang_codes; - lang_codes_code2b = (lang_code_lookup_t *)calloc(1, sizeof(lang_code_lookup_t)); - lang_codes_code1 = (lang_code_lookup_t *)calloc(1, sizeof(lang_code_lookup_t)); - lang_codes_code2t = (lang_code_lookup_t *)calloc(1, sizeof(lang_code_lookup_t)); + lang_codes_code2b = (lang_code_lookup_t*)calloc(1, sizeof(lang_code_lookup_t)); + lang_codes_code1 = (lang_code_lookup_t*)calloc(1, sizeof(lang_code_lookup_t)); + lang_codes_code2t = (lang_code_lookup_t*)calloc(1, sizeof(lang_code_lookup_t)); while (c->code2b) { _lang_code_lookup_add(lang_codes_code2b, c, _lang_code2b_cmp); - if (c->code1) _lang_code_lookup_add(lang_codes_code1, c, _lang_code1_cmp); - if (c->code2t) _lang_code_lookup_add(lang_codes_code2t, c, _lang_code2t_cmp); + if (c->code1) + _lang_code_lookup_add(lang_codes_code1, c, _lang_code1_cmp); + if (c->code2t) + _lang_code_lookup_add(lang_codes_code2t, c, _lang_code2t_cmp); c++; } } @@ -562,7 +560,8 @@ static const lang_code_t *_lang_code_get ( const char *code, size_t len ) /* Extract the code (lowercase) */ i = 0; while (i < 3 && *code && len) { - if (*code == ';' || *code == ',' || *code == '-') break; + if (*code == ';' || *code == ',' || *code == '-') + break; if (*code != ' ') tmp[i++] = *code | 0x20; // |0x20 = lower case code++; @@ -581,74 +580,75 @@ static const lang_code_t *_lang_code_get ( const char *code, size_t len ) /* Search */ if (i) { lang_code_lookup_element_t sample, *element; - lang_code_t lang_code; - lang_code.code1 = tmp; + lang_code_t lang_code; + lang_code.code1 = tmp; lang_code.code2b = tmp; lang_code.code2t = tmp; sample.lang_code = &lang_code; - element = RB_FIND(lang_codes_code2b, &sample, link, _lang_code2b_cmp); - if (element != NULL) return element->lang_code; + element = RB_FIND(lang_codes_code2b, &sample, link, _lang_code2b_cmp); + if (element != NULL) + return element->lang_code; element = RB_FIND(lang_codes_code1, &sample, link, _lang_code1_cmp); - if (element != NULL) return element->lang_code; + if (element != NULL) + return element->lang_code; element = RB_FIND(lang_codes_code2t, &sample, link, _lang_code2t_cmp); - if (element != NULL) return element->lang_code; + if (element != NULL) + return element->lang_code; } } return &lang_codes[0]; } -const char *lang_code_get ( const char *code ) -{ +const char* lang_code_get(const char* code) { return lang_code_get3(code)->code2b; } -const char *lang_code_get2 ( const char *code, size_t len ) -{ +const char* lang_code_get2(const char* code, size_t len) { return _lang_code_get(code, len)->code2b; } -const lang_code_t *lang_code_get3 ( const char *code ) -{ +const lang_code_t* lang_code_get3(const char* code) { return _lang_code_get(code, strlen(code ?: "")); } -static int _split_cmp(const void *_a, const void *_b) -{ - const lang_code_list_t *a = _a; - const lang_code_list_t *b = _b; +static int _split_cmp(const void* _a, const void* _b) { + const lang_code_list_t* a = _a; + const lang_code_list_t* b = _b; return strcmp(a->langs, b->langs); } -const lang_code_list_t *lang_code_split ( const char *codes ) -{ - int n; - const char *c, *p; - lang_code_list_t *ret, skel; - const lang_code_t *co; +const lang_code_list_t* lang_code_split(const char* codes) { + int n; + const char * c, *p; + lang_code_list_t * ret, skel; + const lang_code_t* co; /* Defaults */ - if (!codes) codes = config_get_language(); + if (!codes) + codes = config_get_language(); /* No config */ - if (!codes) return NULL; + if (!codes) + return NULL; tvh_mutex_lock(&lang_code_split_mutex); - skel.langs = (char *)codes; - ret = RB_FIND(&lang_code_split_tree, &skel, link, _split_cmp); + skel.langs = (char*)codes; + ret = RB_FIND(&lang_code_split_tree, &skel, link, _split_cmp); if (ret) goto unlock; for (n = 1, p = codes; *p; p++) - if (*p == ',') n++; + if (*p == ',') + n++; - ret = calloc(1, sizeof(lang_code_list_t) + n * sizeof(lang_code_t *)); + ret = calloc(1, sizeof(lang_code_list_t) + n * sizeof(lang_code_t*)); if (ret) { /* Create list */ for (n = 0, p = c = codes; *c; c++) if (*c == ',') { co = lang_code_get3(p); - if(co) + if (co) ret->codes[n++] = co; p = c + 1; } @@ -658,7 +658,7 @@ const lang_code_list_t *lang_code_split ( const char *codes ) ret->codes[n++] = co; } ret->codeslen = n; - ret->langs = strdup(codes); + ret->langs = strdup(codes); RB_INSERT_SORTED(&lang_code_split_tree, ret, link, _split_cmp); } @@ -667,9 +667,8 @@ unlock: return ret; } -static void lang_code_free( lang_code_lookup_t *l ) -{ - lang_code_lookup_element_t *element; +static void lang_code_free(lang_code_lookup_t* l) { + lang_code_lookup_element_t* element; if (l == NULL) return; while ((element = RB_FIRST(l)) != NULL) { @@ -679,10 +678,9 @@ static void lang_code_free( lang_code_lookup_t *l ) free(l); } -const char *lang_code_preferred( void ) -{ - const char *codes = config_get_language(), *ret = "und"; - const lang_code_t *co; +const char* lang_code_preferred(void) { + const char * codes = config_get_language(), *ret = "und"; + const lang_code_t* co; if (codes) { co = lang_code_get3(codes); @@ -693,10 +691,9 @@ const char *lang_code_preferred( void ) return ret; } -char *lang_code_user( const char *ucode ) -{ +char* lang_code_user(const char* ucode) { const char *codes = config_get_language(), *s; - char *ret; + char* ret; if (!codes) return ucode ? strdup(ucode) : NULL; @@ -719,13 +716,12 @@ char *lang_code_user( const char *ucode ) return ret; } -void lang_code_done( void ) -{ - lang_code_list_t *lcs; +void lang_code_done(void) { + lang_code_list_t* lcs; tvh_mutex_lock(&lang_code_split_mutex); while ((lcs = RB_FIRST(&lang_code_split_tree)) != NULL) { RB_REMOVE(&lang_code_split_tree, lcs, link); - free((char *)lcs->langs); + free((char*)lcs->langs); free(lcs); } tvh_mutex_unlock(&lang_code_split_mutex); diff --git a/src/lang_codes.h b/src/lang_codes.h index 2fcc5f158..9e89b04b2 100644 --- a/src/lang_codes.h +++ b/src/lang_codes.h @@ -21,44 +21,42 @@ #include "redblack.h" -typedef struct lang_code -{ - const char *code2b; ///< ISO 639-2 B - const char *code1; ///< ISO 639-1 - const char *code2t; ///< ISO 639-2 T - const char *desc; ///< Description - const char *locale; ///< Locale variants (like US|GB or DE|BE) +typedef struct lang_code { + const char* code2b; ///< ISO 639-2 B + const char* code1; ///< ISO 639-1 + const char* code2t; ///< ISO 639-2 T + const char* desc; ///< Description + const char* locale; ///< Locale variants (like US|GB or DE|BE) } lang_code_t; extern const lang_code_t lang_codes[]; -typedef struct lang_code_list -{ +typedef struct lang_code_list { RB_ENTRY(lang_code_list) link; - const char *langs; - int codeslen; - const lang_code_t *codes[0]; + const char* langs; + int codeslen; + const lang_code_t* codes[0]; } lang_code_list_t; /* Convert code to preferred internal code */ -const char *lang_code_get ( const char *code ); -const char *lang_code_get2 ( const char *code, size_t len ); -const lang_code_t *lang_code_get3 ( const char *code ); +const char* lang_code_get(const char* code); +const char* lang_code_get2(const char* code, size_t len); +const lang_code_t* lang_code_get3(const char* code); -const char *lang_code_preferred( void ); -char *lang_code_user( const char *ucode ); +const char* lang_code_preferred(void); +char* lang_code_user(const char* ucode); /* Split list of codes as per HTTP Language-Accept spec */ -const lang_code_list_t *lang_code_split ( const char *codes ); +const lang_code_list_t* lang_code_split(const char* codes); /* Efficient code lookup */ typedef struct lang_code_lookup_element { RB_ENTRY(lang_code_lookup_element) link; - const lang_code_t *lang_code; + const lang_code_t* lang_code; } lang_code_lookup_element_t; typedef RB_HEAD(lang_code_lookup, lang_code_lookup_element) lang_code_lookup_t; -void lang_code_done( void ); +void lang_code_done(void); #endif /* __TVH_LANG_CODES_H__ */ diff --git a/src/lang_str.c b/src/lang_str.c index c0cfbe016..a32e0c9c7 100644 --- a/src/lang_str.c +++ b/src/lang_str.c @@ -29,14 +29,12 @@ #define LANG_STR_UPDATE 1 #define LANG_STR_APPEND 2 - /* ************************************************************************ * Support * ***********************************************************************/ /* Compare language codes */ -static int _lang_cmp ( void *a, void *b ) -{ +static int _lang_cmp(void* a, void* b) { return strcmp(((lang_str_ele_t*)a)->lang, ((lang_str_ele_t*)b)->lang); } @@ -45,23 +43,20 @@ static int _lang_cmp ( void *a, void *b ) * ***********************************************************************/ /* Create new instance */ -lang_str_t *lang_str_create ( void ) -{ +lang_str_t* lang_str_create(void) { return calloc(1, sizeof(lang_str_t)); } -lang_str_t *lang_str_create2 ( const char *s, const char *lang ) -{ - lang_str_t *ls = lang_str_create(); +lang_str_t* lang_str_create2(const char* s, const char* lang) { + lang_str_t* ls = lang_str_create(); if (ls) lang_str_add(ls, s, lang); return ls; } /* Destroy (free memory) */ -void lang_str_destroy ( lang_str_t *ls ) -{ - lang_str_ele_t *e; +void lang_str_destroy(lang_str_t* ls) { + lang_str_ele_t* e; if (ls == NULL) return; while ((e = RB_FIRST(ls))) { @@ -72,28 +67,26 @@ void lang_str_destroy ( lang_str_t *ls ) } /* Copy the lang_str instance */ -lang_str_t *lang_str_copy ( const lang_str_t *ls ) -{ - lang_str_t *ret; - lang_str_ele_t *e; +lang_str_t* lang_str_copy(const lang_str_t* ls) { + lang_str_t* ret; + lang_str_ele_t* e; if (ls == NULL) return NULL; ret = lang_str_create(); - RB_FOREACH(e, ls, link) + RB_FOREACH (e, ls, link) lang_str_add(ret, e->str, e->lang); return ret; } /* Get language element, don't return first */ -lang_str_ele_t *lang_str_get2_only - ( const lang_str_t *ls, const char *lang ) -{ - int i; - const lang_code_list_t *langs; - lang_str_ele_t skel, *e = NULL; - - if (!ls) return NULL; - +lang_str_ele_t* lang_str_get2_only(const lang_str_t* ls, const char* lang) { + int i; + const lang_code_list_t* langs; + lang_str_ele_t skel, *e = NULL; + + if (!ls) + return NULL; + /* Check config/requested langs */ if ((langs = lang_code_split(lang)) != NULL) { for (i = 0; i < langs->codeslen; i++) { @@ -108,34 +101,34 @@ lang_str_ele_t *lang_str_get2_only } /* Get language element */ -lang_str_ele_t *lang_str_get2 - ( const lang_str_t *ls, const char *lang ) -{ - lang_str_ele_t *e = lang_str_get2_only(ls, lang); +lang_str_ele_t* lang_str_get2(const lang_str_t* ls, const char* lang) { + lang_str_ele_t* e = lang_str_get2_only(ls, lang); /* Use first available */ - if (!e && ls) e = RB_FIRST(ls); + if (!e && ls) + e = RB_FIRST(ls); /* Return */ return e; } /* Internal insertion routine */ -static int _lang_str_add - ( lang_str_t *ls, const char *str, const char *lang, int cmd ) -{ - int save = 0; +static int _lang_str_add(lang_str_t* ls, const char* str, const char* lang, int cmd) { + int save = 0; lang_str_ele_t *e, *ae; - if (!ls || !str) return 0; + if (!ls || !str) + return 0; /* Get proper code */ - if (!lang) lang = lang_code_preferred(); - if (!(lang = lang_code_get(lang))) return 0; + if (!lang) + lang = lang_code_preferred(); + if (!(lang = lang_code_get(lang))) + return 0; /* Use 'dummy' ele pointer for _lang_cmp */ - ae = (lang_str_ele_t *)(lang - offsetof(lang_str_ele_t, lang)); - e = RB_FIND(ls, ae, link, _lang_cmp); + ae = (lang_str_ele_t*)(lang - offsetof(lang_str_ele_t, lang)); + e = RB_FIND(ls, ae, link, _lang_cmp); /* Create */ if (!e) { @@ -145,7 +138,7 @@ static int _lang_str_add RB_INSERT_SORTED(ls, e, link, _lang_cmp); save = 1; - /* Append */ + /* Append */ } else if (cmd == LANG_STR_APPEND) { RB_REMOVE(ls, e, link); ae = realloc(e, sizeof(*e) + strlen(e->str) + strlen(str) + 1); @@ -157,7 +150,7 @@ static int _lang_str_add } RB_INSERT_SORTED(ls, ae, link, _lang_cmp); - /* Update */ + /* Update */ } else if (cmd == LANG_STR_UPDATE && strcmp(str, e->str)) { if (strlen(e->str) >= strlen(str)) { strcpy(e->str, str); @@ -174,40 +167,36 @@ static int _lang_str_add RB_INSERT_SORTED(ls, ae, link, _lang_cmp); } } - + return save; } /* Add new string (or replace existing one) */ -int lang_str_add - ( lang_str_t *ls, const char *str, const char *lang ) -{ +int lang_str_add(lang_str_t* ls, const char* str, const char* lang) { return _lang_str_add(ls, str, lang, LANG_STR_UPDATE); } /* Append to existing string (or add new one) */ -int lang_str_append - ( lang_str_t *ls, const char *str, const char *lang ) -{ +int lang_str_append(lang_str_t* ls, const char* str, const char* lang) { return _lang_str_add(ls, str, lang, LANG_STR_APPEND); } /* Set new string with update check */ -int lang_str_set - ( lang_str_t **dst, const char *str, const char *lang ) -{ - lang_str_ele_t *e; - int found; - if (*dst == NULL) goto change1; - if (!lang) lang = lang_code_preferred(); - if (!(lang = lang_code_get(lang))) return 0; +int lang_str_set(lang_str_t** dst, const char* str, const char* lang) { + lang_str_ele_t* e; + int found; + if (*dst == NULL) + goto change1; + if (!lang) + lang = lang_code_preferred(); + if (!(lang = lang_code_get(lang))) + return 0; if (*dst) { found = 0; - RB_FOREACH(e, *dst, link) { + RB_FOREACH (e, *dst, link) { if (found) goto change; - found = strcmp(e->lang, lang) == 0 && - strcmp(e->str, str) == 0; + found = strcmp(e->lang, lang) == 0 && strcmp(e->str, str) == 0; if (!found) goto change; } @@ -223,21 +212,17 @@ change1: } /* Set new string with update check */ -int lang_str_set_multi - ( lang_str_t **dst, const lang_str_t *src ) -{ - int changed = 0; - lang_str_ele_t *e; - RB_FOREACH(e, src, link) { +int lang_str_set_multi(lang_str_t** dst, const lang_str_t* src) { + int changed = 0; + lang_str_ele_t* e; + RB_FOREACH (e, src, link) { changed |= lang_str_set(dst, e->str, e->lang); } return changed; } /* Set new strings with update check */ -int lang_str_set2 - ( lang_str_t **dst, const lang_str_t *src ) -{ +int lang_str_set2(lang_str_t** dst, const lang_str_t* src) { if (*dst) { if (!lang_str_compare(*dst, src)) return 0; @@ -248,29 +233,27 @@ int lang_str_set2 } /* Serialize map */ -htsmsg_t *lang_str_serialize_map ( lang_str_t *ls ) -{ - lang_str_ele_t *e; - if (!ls) return NULL; - htsmsg_t *a = htsmsg_create_map(); - RB_FOREACH(e, ls, link) { +htsmsg_t* lang_str_serialize_map(lang_str_t* ls) { + lang_str_ele_t* e; + if (!ls) + return NULL; + htsmsg_t* a = htsmsg_create_map(); + RB_FOREACH (e, ls, link) { htsmsg_add_str(a, e->lang, e->str); } return a; } /* Serialize */ -void lang_str_serialize ( lang_str_t *ls, htsmsg_t *m, const char *f ) -{ - if (!ls) return; +void lang_str_serialize(lang_str_t* ls, htsmsg_t* m, const char* f) { + if (!ls) + return; htsmsg_add_msg(m, f, lang_str_serialize_map(ls)); } /* Serialize one string element directly */ -void lang_str_serialize_one - ( htsmsg_t *m, const char *f, const char *str, const char *lang ) -{ - lang_str_t *l = lang_str_create(); +void lang_str_serialize_one(htsmsg_t* m, const char* f, const char* str, const char* lang) { + lang_str_t* l = lang_str_create(); if (l) { lang_str_add(l, str, lang); lang_str_serialize(l, m, f); @@ -279,11 +262,10 @@ void lang_str_serialize_one } /* De-serialize map */ -lang_str_t *lang_str_deserialize_map ( htsmsg_t *map ) -{ - lang_str_t *ret = lang_str_create(); - htsmsg_field_t *f; - const char *str; +lang_str_t* lang_str_deserialize_map(htsmsg_t* map) { + lang_str_t* ret = lang_str_create(); + htsmsg_field_t* f; + const char* str; if (ret) { HTSMSG_FOREACH(f, map) { @@ -296,15 +278,14 @@ lang_str_t *lang_str_deserialize_map ( htsmsg_t *map ) } /* De-serialize */ -lang_str_t *lang_str_deserialize ( htsmsg_t *m, const char *n ) -{ - htsmsg_t *a; - const char *str; - +lang_str_t* lang_str_deserialize(htsmsg_t* m, const char* n) { + htsmsg_t* a; + const char* str; + if ((a = htsmsg_get_map(m, n))) { return lang_str_deserialize_map(a); } else if ((str = htsmsg_get_str(m, n))) { - lang_str_t *ret = lang_str_create(); + lang_str_t* ret = lang_str_create(); lang_str_add(ret, str, NULL); return ret; } @@ -312,11 +293,10 @@ lang_str_t *lang_str_deserialize ( htsmsg_t *m, const char *n ) } /* Compare */ -int lang_str_compare( const lang_str_t *ls1, const lang_str_t *ls2 ) -{ - lang_str_ele_t *e; - const char *s1, *s2; - int r; +int lang_str_compare(const lang_str_t* ls1, const lang_str_t* ls2) { + lang_str_ele_t* e; + const char * s1, *s2; + int r; if (ls1 == NULL && ls2) return -1; @@ -325,7 +305,7 @@ int lang_str_compare( const lang_str_t *ls1, const lang_str_t *ls2 ) if (ls1 == ls2) return 0; /* Note: may be optimized to not check languages twice */ - RB_FOREACH(e, ls1, link) { + RB_FOREACH (e, ls1, link) { s1 = lang_str_get(ls1, e->lang); s2 = lang_str_get(ls2, e->lang); if (s1 == NULL && s2 != NULL) @@ -335,9 +315,10 @@ int lang_str_compare( const lang_str_t *ls1, const lang_str_t *ls2 ) if (s1 == NULL || s2 == NULL) continue; r = strcmp(s1, s2); - if (r) return r; + if (r) + return r; } - RB_FOREACH(e, ls2, link) { + RB_FOREACH (e, ls2, link) { s1 = lang_str_get(ls1, e->lang); s2 = lang_str_get(ls2, e->lang); if (s1 == NULL && s2 != NULL) @@ -347,18 +328,19 @@ int lang_str_compare( const lang_str_t *ls1, const lang_str_t *ls2 ) if (s1 == NULL || s2 == NULL) continue; r = strcmp(s1, s2); - if (r) return r; + if (r) + return r; } return 0; } -size_t lang_str_size(const lang_str_t *ls) -{ - lang_str_ele_t *e; - size_t size; - if (!ls) return 0; +size_t lang_str_size(const lang_str_t* ls) { + lang_str_ele_t* e; + size_t size; + if (!ls) + return 0; size = sizeof(*ls); - RB_FOREACH(e, ls, link) { + RB_FOREACH (e, ls, link) { size += sizeof(*e); size += tvh_strlen(e->str); } diff --git a/src/lang_str.h b/src/lang_str.h index 3bf1a3285..97568e60f 100644 --- a/src/lang_str.h +++ b/src/lang_str.h @@ -23,8 +23,7 @@ #include "tvh_string.h" #include "htsmsg.h" -typedef struct lang_str_ele -{ +typedef struct lang_str_ele { RB_ENTRY(lang_str_ele) link; char lang[4]; char str[0]; @@ -33,58 +32,46 @@ typedef struct lang_str_ele typedef RB_HEAD(lang_str, lang_str_ele) lang_str_t; /* Create/Destroy */ -void lang_str_destroy ( lang_str_t *ls ); -lang_str_t *lang_str_create ( void ); -lang_str_t *lang_str_create2 ( const char *str, const char *lang ); -lang_str_t *lang_str_copy ( const lang_str_t *ls ); +void lang_str_destroy(lang_str_t* ls); +lang_str_t* lang_str_create(void); +lang_str_t* lang_str_create2(const char* str, const char* lang); +lang_str_t* lang_str_copy(const lang_str_t* ls); /* Get elements */ -lang_str_ele_t *lang_str_get2_only ( const lang_str_t *ls, const char *lang ); -static inline const char *lang_str_get_only(const lang_str_t *ls, const char *lang) - { - lang_str_ele_t *e = lang_str_get2_only(ls, lang); - return e ? e->str : NULL; - } -lang_str_ele_t *lang_str_get2 ( const lang_str_t *ls, const char *lang ); -static inline const char *lang_str_get(const lang_str_t *ls, const char *lang) - { - lang_str_ele_t *e = lang_str_get2(ls, lang); - return e ? e->str : NULL; - } - +lang_str_ele_t* lang_str_get2_only(const lang_str_t* ls, const char* lang); +static inline const char* lang_str_get_only(const lang_str_t* ls, const char* lang) { + lang_str_ele_t* e = lang_str_get2_only(ls, lang); + return e ? e->str : NULL; +} +lang_str_ele_t* lang_str_get2(const lang_str_t* ls, const char* lang); +static inline const char* lang_str_get(const lang_str_t* ls, const char* lang) { + lang_str_ele_t* e = lang_str_get2(ls, lang); + return e ? e->str : NULL; +} /* Add/Update elements */ -int lang_str_add - ( lang_str_t *ls, const char *str, const char *lang ); -int lang_str_append - ( lang_str_t *ls, const char *str, const char *lang ); -int lang_str_set - ( lang_str_t **dst, const char *str, const char *lang ); -int lang_str_set_multi - ( lang_str_t **dst, const lang_str_t *src ); -int lang_str_set2 - ( lang_str_t **dst, const lang_str_t *src ); +int lang_str_add(lang_str_t* ls, const char* str, const char* lang); +int lang_str_append(lang_str_t* ls, const char* str, const char* lang); +int lang_str_set(lang_str_t** dst, const char* str, const char* lang); +int lang_str_set_multi(lang_str_t** dst, const lang_str_t* src); +int lang_str_set2(lang_str_t** dst, const lang_str_t* src); /* Serialize/Deserialize */ -htsmsg_t *lang_str_serialize_map - ( lang_str_t *ls ); -void lang_str_serialize - ( lang_str_t *ls, htsmsg_t *msg, const char *f ); -void lang_str_serialize_one - ( htsmsg_t *msg, const char *f, const char *str, const char *lang ); -lang_str_t *lang_str_deserialize_map - ( htsmsg_t *map ); -lang_str_t *lang_str_deserialize - ( htsmsg_t *m, const char *f ); +htsmsg_t* lang_str_serialize_map(lang_str_t* ls); +void lang_str_serialize(lang_str_t* ls, htsmsg_t* msg, const char* f); +void lang_str_serialize_one(htsmsg_t* msg, const char* f, const char* str, const char* lang); +lang_str_t* lang_str_deserialize_map(htsmsg_t* map); +lang_str_t* lang_str_deserialize(htsmsg_t* m, const char* f); /* Compare */ -int lang_str_compare ( const lang_str_t *ls1, const lang_str_t *ls2 ); +int lang_str_compare(const lang_str_t* ls1, const lang_str_t* ls2); /* Is string empty? */ -static inline int lang_str_empty(lang_str_t* str) - { return strempty(lang_str_get(str, NULL)); } +static inline int lang_str_empty(lang_str_t* str) { + return strempty(lang_str_get(str, NULL)); +} /* Size in bytes */ -size_t lang_str_size ( const lang_str_t *ls ); +size_t lang_str_size(const lang_str_t* ls); #endif /* __TVH_LANG_STR_H__ */ diff --git a/src/libav.c b/src/libav.c index c633d05c9..f953d72ed 100644 --- a/src/libav.c +++ b/src/libav.c @@ -7,23 +7,20 @@ /** * */ -static void -libav_log_callback(void *ptr, int level, const char *fmt, va_list vl) -{ - int severity = LOG_TVH_NOTIFY, l1, l2; - const char *class_name; - char *fmt1; +static void libav_log_callback(void* ptr, int level, const char* fmt, va_list vl) { + int severity = LOG_TVH_NOTIFY, l1, l2; + const char* class_name; + char* fmt1; - if (level != AV_LOG_QUIET && - ((level <= AV_LOG_INFO) || (tvhlog_options & TVHLOG_OPT_LIBAV))) { + if (level != AV_LOG_QUIET && ((level <= AV_LOG_INFO) || (tvhlog_options & TVHLOG_OPT_LIBAV))) { - class_name = ptr && *(void **)ptr ? av_default_item_name(ptr) : ""; + class_name = ptr && *(void**)ptr ? av_default_item_name(ptr) : ""; if (fmt == NULL) return; - l1 = strlen(fmt); - l2 = strlen(class_name); + l1 = strlen(fmt); + l2 = strlen(class_name); fmt1 = alloca(l1 + l2 + 3); strcpy(fmt1, class_name); @@ -32,14 +29,14 @@ libav_log_callback(void *ptr, int level, const char *fmt, va_list vl) strcat(fmt1, fmt); /* remove trailing newline */ - if (fmt[l1-1] == '\n') + if (fmt[l1 - 1] == '\n') fmt1[l1 + l2 + 1] = '\0'; if (strcmp(class_name, "AVFormatContext") == 0) { if (strcmp(fmt, "Negative cts, previous timestamps might be wrong.\n") == 0) { level = AV_LOG_TRACE; } else if (strcmp(fmt, "Invalid timestamps stream=%d, pts=%s, dts=%s, size=%d\n") == 0 && - strstr(fmt, ", pts=-") == 0) { + strstr(fmt, ", pts=-") == 0) { level = AV_LOG_TRACE; } } else if (strcmp(class_name, "AVCodecContext") == 0) { @@ -48,33 +45,33 @@ libav_log_callback(void *ptr, int level, const char *fmt, va_list vl) } } - switch(level) { - case AV_LOG_TRACE: + switch (level) { + case AV_LOG_TRACE: #if ENABLE_TRACE - severity |= LOG_TRACE; - break; + severity |= LOG_TRACE; + break; #endif - case AV_LOG_DEBUG: - case AV_LOG_VERBOSE: - severity |= LOG_DEBUG; - break; - case AV_LOG_INFO: - severity |= LOG_INFO; - break; - case AV_LOG_WARNING: - severity |= LOG_WARNING; - break; - case AV_LOG_ERROR: - severity |= LOG_ERR; - break; - case AV_LOG_FATAL: - severity |= LOG_CRIT; - break; - case AV_LOG_PANIC: - severity |= LOG_EMERG; - break; - default: - break; + case AV_LOG_DEBUG: + case AV_LOG_VERBOSE: + severity |= LOG_DEBUG; + break; + case AV_LOG_INFO: + severity |= LOG_INFO; + break; + case AV_LOG_WARNING: + severity |= LOG_WARNING; + break; + case AV_LOG_ERROR: + severity |= LOG_ERR; + break; + case AV_LOG_FATAL: + severity |= LOG_CRIT; + break; + case AV_LOG_PANIC: + severity |= LOG_EMERG; + break; + default: + break; } va_list ap; va_copy(ap, vl); @@ -86,174 +83,167 @@ libav_log_callback(void *ptr, int level, const char *fmt, va_list vl) /** * Translate a component type to a libavcodec id */ -enum AVCodecID -streaming_component_type2codec_id(streaming_component_type_t type) -{ +enum AVCodecID streaming_component_type2codec_id(streaming_component_type_t type) { enum AVCodecID codec_id = AV_CODEC_ID_NONE; - switch(type) { - case SCT_H264: - codec_id = AV_CODEC_ID_H264; - break; - case SCT_MPEG2VIDEO: - codec_id = AV_CODEC_ID_MPEG2VIDEO; - break; - case SCT_VP8: - codec_id = AV_CODEC_ID_VP8; - break; - case SCT_VP9: - codec_id = AV_CODEC_ID_VP9; - break; - case SCT_HEVC: - codec_id = AV_CODEC_ID_HEVC; - break; - case SCT_THEORA: - codec_id = AV_CODEC_ID_THEORA; - break; - case SCT_AC3: - codec_id = AV_CODEC_ID_AC3; - break; - case SCT_EAC3: - codec_id = AV_CODEC_ID_EAC3; - break; - // Enable once supported, see https://trac.ffmpeg.org/ticket/8349 - // case SCT_AC4: - // codec_id = AV_CODEC_ID_AC4; - // break; - case SCT_MP4A: - case SCT_AAC: - codec_id = AV_CODEC_ID_AAC; - break; - case SCT_MPEG2AUDIO: - codec_id = AV_CODEC_ID_MP2; - break; - case SCT_VORBIS: - codec_id = AV_CODEC_ID_VORBIS; - break; - case SCT_OPUS: - codec_id = AV_CODEC_ID_OPUS; - break; - case SCT_DVBSUB: - codec_id = AV_CODEC_ID_DVB_SUBTITLE; - break; - case SCT_TEXTSUB: - codec_id = AV_CODEC_ID_TEXT; - break; - case SCT_TELETEXT: - codec_id = AV_CODEC_ID_DVB_TELETEXT; - break; - default: - break; + switch (type) { + case SCT_H264: + codec_id = AV_CODEC_ID_H264; + break; + case SCT_MPEG2VIDEO: + codec_id = AV_CODEC_ID_MPEG2VIDEO; + break; + case SCT_VP8: + codec_id = AV_CODEC_ID_VP8; + break; + case SCT_VP9: + codec_id = AV_CODEC_ID_VP9; + break; + case SCT_HEVC: + codec_id = AV_CODEC_ID_HEVC; + break; + case SCT_THEORA: + codec_id = AV_CODEC_ID_THEORA; + break; + case SCT_AC3: + codec_id = AV_CODEC_ID_AC3; + break; + case SCT_EAC3: + codec_id = AV_CODEC_ID_EAC3; + break; + // Enable once supported, see https://trac.ffmpeg.org/ticket/8349 + // case SCT_AC4: + // codec_id = AV_CODEC_ID_AC4; + // break; + case SCT_MP4A: + case SCT_AAC: + codec_id = AV_CODEC_ID_AAC; + break; + case SCT_MPEG2AUDIO: + codec_id = AV_CODEC_ID_MP2; + break; + case SCT_VORBIS: + codec_id = AV_CODEC_ID_VORBIS; + break; + case SCT_OPUS: + codec_id = AV_CODEC_ID_OPUS; + break; + case SCT_DVBSUB: + codec_id = AV_CODEC_ID_DVB_SUBTITLE; + break; + case SCT_TEXTSUB: + codec_id = AV_CODEC_ID_TEXT; + break; + case SCT_TELETEXT: + codec_id = AV_CODEC_ID_DVB_TELETEXT; + break; + default: + break; } return codec_id; } - /** * Translate a libavcodec id to a component type */ -streaming_component_type_t -codec_id2streaming_component_type(enum AVCodecID id) -{ +streaming_component_type_t codec_id2streaming_component_type(enum AVCodecID id) { streaming_component_type_t type = SCT_UNKNOWN; - switch(id) { - case AV_CODEC_ID_H264: - type = SCT_H264; - break; - case AV_CODEC_ID_MPEG2VIDEO: - type = SCT_MPEG2VIDEO; - break; - case AV_CODEC_ID_VP8: - type = SCT_VP8; - break; - case AV_CODEC_ID_VP9: - type = SCT_VP9; - break; - case AV_CODEC_ID_HEVC: - type = SCT_HEVC; - break; - case AV_CODEC_ID_THEORA: - type = SCT_THEORA; - break; - case AV_CODEC_ID_AC3: - type = SCT_AC3; - break; - case AV_CODEC_ID_EAC3: - type = SCT_EAC3; - break; - // Enable once supported, see https://trac.ffmpeg.org/ticket/8349 - // case AV_CODEC_ID_AC4: - // type = SCT_AC4; - // break; - case AV_CODEC_ID_AAC: - type = SCT_AAC; - break; - case AV_CODEC_ID_MP2: - type = SCT_MPEG2AUDIO; - break; - case AV_CODEC_ID_VORBIS: - type = SCT_VORBIS; - break; - case AV_CODEC_ID_OPUS: - type = SCT_OPUS; - break; - case AV_CODEC_ID_DVB_SUBTITLE: - type = SCT_DVBSUB; - break; - case AV_CODEC_ID_TEXT: - type = SCT_TEXTSUB; - break; - case AV_CODEC_ID_DVB_TELETEXT: - type = SCT_TELETEXT; - break; - case AV_CODEC_ID_FLAC: - type = SCT_FLAC; - break; - case AV_CODEC_ID_NONE: - type = SCT_NONE; - break; - default: - break; + switch (id) { + case AV_CODEC_ID_H264: + type = SCT_H264; + break; + case AV_CODEC_ID_MPEG2VIDEO: + type = SCT_MPEG2VIDEO; + break; + case AV_CODEC_ID_VP8: + type = SCT_VP8; + break; + case AV_CODEC_ID_VP9: + type = SCT_VP9; + break; + case AV_CODEC_ID_HEVC: + type = SCT_HEVC; + break; + case AV_CODEC_ID_THEORA: + type = SCT_THEORA; + break; + case AV_CODEC_ID_AC3: + type = SCT_AC3; + break; + case AV_CODEC_ID_EAC3: + type = SCT_EAC3; + break; + // Enable once supported, see https://trac.ffmpeg.org/ticket/8349 + // case AV_CODEC_ID_AC4: + // type = SCT_AC4; + // break; + case AV_CODEC_ID_AAC: + type = SCT_AAC; + break; + case AV_CODEC_ID_MP2: + type = SCT_MPEG2AUDIO; + break; + case AV_CODEC_ID_VORBIS: + type = SCT_VORBIS; + break; + case AV_CODEC_ID_OPUS: + type = SCT_OPUS; + break; + case AV_CODEC_ID_DVB_SUBTITLE: + type = SCT_DVBSUB; + break; + case AV_CODEC_ID_TEXT: + type = SCT_TEXTSUB; + break; + case AV_CODEC_ID_DVB_TELETEXT: + type = SCT_TELETEXT; + break; + case AV_CODEC_ID_FLAC: + type = SCT_FLAC; + break; + case AV_CODEC_ID_NONE: + type = SCT_NONE; + break; + default: + break; } return type; } - /** * */ #if ENABLE_VAAPI #ifdef VA_FOURCC_I010 -static void libav_va_log(int severity, const char *msg) -{ - char *s; - int l; +static void libav_va_log(int severity, const char* msg) { + char* s; + int l; if (msg == NULL || *msg == '\0') return; s = tvh_strdupa(msg); l = strlen(s); - if (s[l-1] == '\n') - s[l-1] = '\0'; + if (s[l - 1] == '\n') + s[l - 1] = '\0'; tvhlog(severity, LS_VAAPI, "%s", s); } #if VA_CHECK_VERSION(1, 0, 0) -static void libav_va_error_callback(void *context, const char *msg) +static void libav_va_error_callback(void* context, const char* msg) #else -static void libav_va_error_callback(const char *msg) +static void libav_va_error_callback(const char* msg) #endif { libav_va_log(LOG_ERR, msg); } #if VA_CHECK_VERSION(1, 0, 0) -static void libav_va_info_callback(void *context, const char *msg) +static void libav_va_info_callback(void* context, const char* msg) #else -static void libav_va_info_callback(const char *msg) +static void libav_va_info_callback(const char* msg) #endif { libav_va_log(LOG_INFO, msg); @@ -264,9 +254,7 @@ static void libav_va_info_callback(const char *msg) /** * */ -static void -libav_vaapi_init(void) -{ +static void libav_vaapi_init(void) { #if ENABLE_VAAPI #ifdef VA_FOURCC_I010 #if !VA_CHECK_VERSION(1, 0, 0) @@ -280,9 +268,7 @@ libav_vaapi_init(void) /** * */ -void -libav_vaapi_init_context(void *context) -{ +void libav_vaapi_init_context(void* context) { #if ENABLE_VAAPI #ifdef VA_FOURCC_I010 #if VA_CHECK_VERSION(1, 0, 0) @@ -296,9 +282,7 @@ libav_vaapi_init_context(void *context) /** * */ -void -libav_set_loglevel(void) -{ +void libav_set_loglevel(void) { int level = (tvhlog_options & TVHLOG_OPT_LIBAV) ? AV_LOG_DEBUG : AV_LOG_INFO; av_log_set_level(level); } @@ -306,9 +290,7 @@ libav_set_loglevel(void) /** * */ -void -libav_init(void) -{ +void libav_init(void) { libav_vaapi_init(); libav_set_loglevel(); av_log_set_callback(libav_log_callback); @@ -319,9 +301,7 @@ libav_init(void) /** * */ -void -libav_done(void) -{ +void libav_done(void) { transcode_done(); avformat_network_deinit(); } \ No newline at end of file diff --git a/src/libav.h b/src/libav.h index c73b61089..b6b55750a 100644 --- a/src/libav.h +++ b/src/libav.h @@ -37,8 +37,9 @@ http://git.videolan.org/?p=ffmpeg.git;a=commitdiff;h=104e10fb426f903ba9157fdbfe3 This list must be updated every time we use a new AV_CODEC_ID */ -#if LIBAVCODEC_VERSION_MAJOR < 54 || (LIBAVCODEC_VERSION_MAJOR == 54 && LIBAVCODEC_VERSION_MINOR < 25) -#define AVCodecID CodecID +#if LIBAVCODEC_VERSION_MAJOR < 54 || \ + (LIBAVCODEC_VERSION_MAJOR == 54 && LIBAVCODEC_VERSION_MINOR < 25) +#define AVCodecID CodecID #define AV_CODEC_ID_AAC CODEC_ID_AAC #define AV_CODEC_ID_AC3 CODEC_ID_AC3 #define AV_CODEC_ID_DVB CODEC_ID_DVB @@ -54,19 +55,19 @@ This list must be updated every time we use a new AV_CODEC_ID #define AV_CODEC_ID_DVB_TELETEXT CODEC_ID_DVB_TELETEXT #endif -enum AVCodecID streaming_component_type2codec_id(streaming_component_type_t type); +enum AVCodecID streaming_component_type2codec_id(streaming_component_type_t type); streaming_component_type_t codec_id2streaming_component_type(enum AVCodecID id); -void libav_set_loglevel(void); -void libav_vaapi_init_context(void *context); -void libav_init(void); -void libav_done(void); +void libav_set_loglevel(void); +void libav_vaapi_init_context(void* context); +void libav_init(void); +void libav_done(void); #else -static inline void libav_set_loglevel(void) { }; -static inline void libav_vaapi_init_context(void *context) { }; -static inline void libav_init(void) { }; -static inline void libav_done(void) { }; +static inline void libav_set_loglevel(void) {}; +static inline void libav_vaapi_init_context(void* context) {}; +static inline void libav_init(void) {}; +static inline void libav_done(void) {}; #endif diff --git a/src/lock.c b/src/lock.c index ffa9d6ebe..cee3347ef 100644 --- a/src/lock.c +++ b/src/lock.c @@ -25,105 +25,101 @@ #include "tvheadend.h" #include "lock.h" -static -int state_lock_(const char *lfile, int lock, int timeout, int _fd) -{ - int fd = -1, err = 0; - struct flock lck; - struct stat st; - char lcktxt[13]; +static int state_lock_(const char* lfile, int lock, int timeout, int _fd) { + int fd = -1, err = 0; + struct flock lck; + struct stat st; + char lcktxt[13]; - lck.l_type = lock ? F_WRLCK : F_UNLCK; - lck.l_whence = SEEK_SET; - lck.l_start = 0; - lck.l_len = 11; - lck.l_pid = 0; - if (lock) { - snprintf(lcktxt, sizeof(lcktxt), "%10li\n", (long)getpid()); - } else { - snprintf(lcktxt, sizeof(lcktxt), "%10s\n", ""); - fd = _fd; - } - while (fd < 0 && timeout-- > 0) { - fd = open(lfile, O_RDWR); - if (!lock && fd < 0) { - err = -EIO; - goto out; - } - if (fd < 0) { - fd = open(lfile, O_RDWR|O_CREAT|O_EXCL, 0644); - if (fd < 0) { - if (errno == EBUSY || errno == EAGAIN) { - sleep(1); - timeout--; - } else { - err = -errno; - goto out; - } - } - } - } - if (fd < 0 && timeout <= 0) { - err = -EBUSY; - goto out; + lck.l_type = lock ? F_WRLCK : F_UNLCK; + lck.l_whence = SEEK_SET; + lck.l_start = 0; + lck.l_len = 11; + lck.l_pid = 0; + if (lock) { + snprintf(lcktxt, sizeof(lcktxt), "%10li\n", (long)getpid()); + } else { + snprintf(lcktxt, sizeof(lcktxt), "%10s\n", ""); + fd = _fd; + } + while (fd < 0 && timeout-- > 0) { + fd = open(lfile, O_RDWR); + if (!lock && fd < 0) { + err = -EIO; + goto out; } - if (fstat(fd, &st) < 0) { - err = -errno; - goto out; - } - if (st.st_size != 11 || !lock) { - if (write(fd, lcktxt, 11) != 11) { - err = -EIO; - goto out; - } - if (lock && lseek(fd, 0, SEEK_SET)) { - err = -errno; - goto out; - } - } - while (timeout > 0) { - if (fcntl(fd, F_SETLK, &lck) < 0) { - sleep(1); - timeout--; + if (fd < 0) { + fd = open(lfile, O_RDWR | O_CREAT | O_EXCL, 0644); + if (fd < 0) { + if (errno == EBUSY || errno == EAGAIN) { + sleep(1); + timeout--; } else { - break; + err = -errno; + goto out; } + } } - if (timeout <= 0) { - err = -EBUSY; - goto out; + } + if (fd < 0 && timeout <= 0) { + err = -EBUSY; + goto out; + } + if (fstat(fd, &st) < 0) { + err = -errno; + goto out; + } + if (st.st_size != 11 || !lock) { + if (write(fd, lcktxt, 11) != 11) { + err = -EIO; + goto out; } - if (lock) { - if (write(fd, lcktxt, 11) != 11) { - err = -EIO; - goto out; - } - return fd; + if (lock && lseek(fd, 0, SEEK_SET)) { + err = -errno; + goto out; + } + } + while (timeout > 0) { + if (fcntl(fd, F_SETLK, &lck) < 0) { + sleep(1); + timeout--; + } else { + break; + } + } + if (timeout <= 0) { + err = -EBUSY; + goto out; + } + if (lock) { + if (write(fd, lcktxt, 11) != 11) { + err = -EIO; + goto out; } - err = 0; + return fd; + } + err = 0; out: - if (fd >= 0) - close(fd); - return err; + if (fd >= 0) + close(fd); + return err; } -int file_lock(const char *lfile, int timeout) -{ - int err; +int file_lock(const char* lfile, int timeout) { + int err; - err = state_lock_(lfile, 1, timeout, -1); - if (err < 0) - tvherror(LS_LOCK, "file %s lock error: %s", lfile, strerror(-err)); - return err; + err = state_lock_(lfile, 1, timeout, -1); + if (err < 0) + tvherror(LS_LOCK, "file %s lock error: %s", lfile, strerror(-err)); + return err; } -int file_unlock(const char *lfile, int _fd) -{ - int err; +int file_unlock(const char* lfile, int _fd) { + int err; - err = state_lock_(lfile, 0, 10, _fd); - if (err < 0) - tvherror(LS_LOCK, "file %s unlock error: %s", lfile, strerror(-err)); - return err; + err = state_lock_(lfile, 0, 10, _fd); + if (err < 0) + tvherror(LS_LOCK, "file %s unlock error: %s", lfile, strerror(-err)); + return err; } diff --git a/src/lock.h b/src/lock.h index 2f5690393..198498861 100644 --- a/src/lock.h +++ b/src/lock.h @@ -19,7 +19,7 @@ #ifndef TVH_LOCK_H #define TVH_LOCK_H -int file_lock(const char *lfile, int timeout); -int file_unlock(const char *lfile, int _fd); +int file_lock(const char* lfile, int timeout); +int file_unlock(const char* lfile, int _fd); #endif /* TVH_LOCK_H */ diff --git a/src/main.c b/src/main.c index 3b43c9534..a08774ee0 100644 --- a/src/main.c +++ b/src/main.c @@ -96,26 +96,24 @@ pthread_t main_tid; -int64_t __mdispatch_clock; -time_t __gdispatch_clock; +int64_t __mdispatch_clock; +time_t __gdispatch_clock; /* Command line option struct */ typedef struct { const char sopt; - const char *lopt; - const char *desc; + const char* lopt; + const char* desc; enum { OPT_STR, OPT_INT, OPT_BOOL, OPT_STR_LIST, - } type; - void *param; + } type; + void* param; } cmdline_opt_t; -static cmdline_opt_t* cmdline_opt_find - ( cmdline_opt_t *opts, int num, const char *arg ) -{ +static cmdline_opt_t* cmdline_opt_find(cmdline_opt_t* opts, int num, const char* arg) { int i; int isshort = 0; @@ -131,7 +129,8 @@ static cmdline_opt_t* cmdline_opt_find return NULL; for (i = 0; i < num; i++) { - if (!opts[i].lopt) continue; + if (!opts[i].lopt) + continue; if (isshort && opts[i].sopt == *arg) return &opts[i]; if (!isshort && !strcmp(opts[i].lopt, arg)) @@ -150,33 +149,32 @@ int tvheadend_webui_port; int tvheadend_webui_debug; int tvheadend_htsp_port; int tvheadend_htsp_port_extra; -const char *tvheadend_cwd0; -const char *tvheadend_cwd; -const char *tvheadend_webroot; +const char* tvheadend_cwd0; +const char* tvheadend_cwd; +const char* tvheadend_webroot; const tvh_caps_t tvheadend_capabilities[] = { #if ENABLE_CWC || ENABLE_CAPMT || ENABLE_CONSTCW || ENABLE_CCCAM - { "caclient", NULL }, + {"caclient", NULL}, #endif #if ENABLE_LINUXDVB || ENABLE_SATIP_CLIENT || ENABLE_HDHOMERUN_CLIENT - { "tvadapters", NULL }, + {"tvadapters", NULL}, #endif #if ENABLE_SATIP_CLIENT - { "satip_client", NULL }, + {"satip_client", NULL}, #endif #if ENABLE_SATIP_SERVER - { "satip_server", NULL }, + {"satip_server", NULL}, #endif #if ENABLE_TIMESHIFT - { "timeshift", (uint32_t *)×hift_conf.enabled }, + {"timeshift", (uint32_t*)×hift_conf.enabled}, #endif #if ENABLE_TRACE - { "trace", NULL }, + {"trace", NULL}, #endif #if ENABLE_LIBAV - { "libav", NULL }, + {"libav", NULL}, #endif - { NULL, NULL } -}; + {NULL, NULL}}; tvh_mutex_t global_lock; tvh_mutex_t mtimer_lock; @@ -190,29 +188,25 @@ tvh_mutex_t atomic_lock; */ static LIST_HEAD(, mtimer) mtimers; static tvh_cond_t mtimer_cond; -static mtimer_t *mtimer_running; -static int64_t mtimer_periodic; -static pthread_t mtimer_tid; -static pthread_t mtimer_tick_tid; +static mtimer_t* mtimer_running; +static int64_t mtimer_periodic; +static pthread_t mtimer_tid; +static pthread_t mtimer_tick_tid; static tprofile_t mtimer_profile; static LIST_HEAD(, gtimer) gtimers; -static gtimer_t *gtimer_running; +static gtimer_t* gtimer_running; static tvh_cond_t gtimer_cond; static tprofile_t gtimer_profile; static TAILQ_HEAD(, tasklet) tasklets; -static tvh_cond_t tasklet_cond; -static pthread_t tasklet_tid; -static memoryinfo_t tasklet_memoryinfo = { .my_name = "Tasklet" }; +static tvh_cond_t tasklet_cond; +static pthread_t tasklet_tid; +static memoryinfo_t tasklet_memoryinfo = {.my_name = "Tasklet"}; -static void -handle_sigpipe(int x) -{ +static void handle_sigpipe(int x) { return; } -static void -handle_sigill(int x) -{ +static void handle_sigill(int x) { /* Note that on some platforms, the SSL library tries */ /* to determine the CPU capabilities with possible */ /* unknown instructions */ @@ -220,9 +214,7 @@ handle_sigill(int x) tvh_signal(SIGILL, handle_sigill); } -void -doexit(int x) -{ +void doexit(int x) { if (pthread_self() != main_tid) tvh_thread_kill(main_tid, SIGTERM); tvh_cond_signal(>imer_cond, 0); @@ -231,18 +223,18 @@ doexit(int x) tvh_signal(x, doexit); } -static int -get_user_groups (const struct passwd *pw, gid_t* glist, size_t gmax) -{ +static int get_user_groups(const struct passwd* pw, gid_t* glist, size_t gmax) { int num = 0; #if !ENABLE_ANDROID - struct group *gr; - char **mem; + struct group* gr; + char** mem; glist[num++] = pw->pw_gid; - for ( gr = getgrent(); (gr != NULL) && (num < gmax); gr = getgrent() ) { - if (gr->gr_gid == pw->pw_gid) continue; + for (gr = getgrent(); (gr != NULL) && (num < gmax); gr = getgrent()) { + if (gr->gr_gid == pw->pw_gid) + continue; for (mem = gr->gr_mem; *mem; mem++) { - if(!strcmp(*mem, pw->pw_name)) glist[num++] = gr->gr_gid; + if (!strcmp(*mem, pw->pw_name)) + glist[num++] = gr->gr_gid; } } #endif @@ -255,15 +247,12 @@ get_user_groups (const struct passwd *pw, gid_t* glist, size_t gmax) #define safecmp(a, b) ((a) > (b) ? 1 : ((a) < (b) ? -1 : 0)) -static int -mtimercmp(mtimer_t *a, mtimer_t *b) -{ +static int mtimercmp(mtimer_t* a, mtimer_t* b) { return safecmp(a->mti_expire, b->mti_expire); } #if ENABLE_TRACE -static void mtimer_magic_check(mtimer_t *mti) -{ +static void mtimer_magic_check(mtimer_t* mti) { if (mti->mti_magic1 != MTIMER_MAGIC1) { tvhdbg(LS_MAIN, "mtimer magic check failed for %p", mti); tvherror(LS_MAIN, "mtimer magic check failed for %p", mti); @@ -271,18 +260,16 @@ static void mtimer_magic_check(mtimer_t *mti) } } #else -static inline void mtimer_magic_check(mtimer_t *mti) -{ -} +static inline void mtimer_magic_check(mtimer_t* mti) {} #endif /** * this routine can be called inside any locks */ -void -GTIMER_FCN(mtimer_arm_abs) - (GTIMER_TRACEID_ mtimer_t *mti, mti_callback_t *callback, void *opaque, int64_t when) -{ +void GTIMER_FCN(mtimer_arm_abs)(GTIMER_TRACEID_ mtimer_t* mti, + mti_callback_t* callback, + void* opaque, + int64_t when) { tvh_mutex_lock(&mtimer_lock); if (mti->mti_callback != NULL) { @@ -291,13 +278,13 @@ GTIMER_FCN(mtimer_arm_abs) } #if ENABLE_TRACE - mti->mti_magic1 = MTIMER_MAGIC1; + mti->mti_magic1 = MTIMER_MAGIC1; #endif mti->mti_callback = callback; mti->mti_opaque = opaque; mti->mti_expire = when; #if ENABLE_GTIMER_CHECK - mti->mti_id = id; + mti->mti_id = id; #endif LIST_INSERT_SORTED(&mtimers, mti, mti_link, mtimercmp); @@ -311,10 +298,10 @@ GTIMER_FCN(mtimer_arm_abs) /** * */ -void -GTIMER_FCN(mtimer_arm_rel) - (GTIMER_TRACEID_ mtimer_t *gti, mti_callback_t *callback, void *opaque, int64_t delta) -{ +void GTIMER_FCN(mtimer_arm_rel)(GTIMER_TRACEID_ mtimer_t* gti, + mti_callback_t* callback, + void* opaque, + int64_t delta) { #if ENABLE_GTIMER_CHECK GTIMER_FCN(mtimer_arm_abs)(id, gti, callback, opaque, mclk() + delta); #else @@ -325,9 +312,7 @@ GTIMER_FCN(mtimer_arm_rel) /** * the global_lock must be held */ -void -mtimer_disarm(mtimer_t *mti) -{ +void mtimer_disarm(mtimer_t* mti) { lock_assert(&global_lock); tvh_mutex_lock(&mtimer_lock); if (mtimer_running == mti) @@ -343,15 +328,12 @@ mtimer_disarm(mtimer_t *mti) /** * */ -static int -gtimercmp(gtimer_t *a, gtimer_t *b) -{ +static int gtimercmp(gtimer_t* a, gtimer_t* b) { return safecmp(a->gti_expire, b->gti_expire); } #if ENABLE_TRACE -static void gtimer_magic_check(gtimer_t *gti) -{ +static void gtimer_magic_check(gtimer_t* gti) { if (gti->gti_magic1 != GTIMER_MAGIC1) { tvhdbg(LS_MAIN, "gtimer magic check failed for %p", gti); tvherror(LS_MAIN, "gtimer magic check failed for %p", gti); @@ -359,18 +341,16 @@ static void gtimer_magic_check(gtimer_t *gti) } } #else -static inline void gtimer_magic_check(gtimer_t *gti) -{ -} +static inline void gtimer_magic_check(gtimer_t* gti) {} #endif /** * this routine can be called inside any locks */ -void -GTIMER_FCN(gtimer_arm_absn) - (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t when) -{ +void GTIMER_FCN(gtimer_arm_absn)(GTIMER_TRACEID_ gtimer_t* gti, + gti_callback_t* callback, + void* opaque, + time_t when) { tvh_mutex_lock(>imer_lock); if (gti->gti_callback != NULL) { @@ -379,13 +359,13 @@ GTIMER_FCN(gtimer_arm_absn) } #if ENABLE_TRACE - gti->gti_magic1 = GTIMER_MAGIC1; + gti->gti_magic1 = GTIMER_MAGIC1; #endif gti->gti_callback = callback; gti->gti_opaque = opaque; gti->gti_expire = when; #if ENABLE_GTIMER_CHECK - gti->gti_id = id; + gti->gti_id = id; #endif LIST_INSERT_SORTED(>imers, gti, gti_link, gtimercmp); @@ -399,10 +379,10 @@ GTIMER_FCN(gtimer_arm_absn) /** * */ -void -GTIMER_FCN(gtimer_arm_rel) - (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t delta) -{ +void GTIMER_FCN(gtimer_arm_rel)(GTIMER_TRACEID_ gtimer_t* gti, + gti_callback_t* callback, + void* opaque, + time_t delta) { #if ENABLE_GTIMER_CHECK GTIMER_FCN(gtimer_arm_absn)(id, gti, callback, opaque, gclk() + delta); #else @@ -413,9 +393,7 @@ GTIMER_FCN(gtimer_arm_rel) /** * the global_lock must be held */ -void -gtimer_disarm(gtimer_t *gti) -{ +void gtimer_disarm(gtimer_t* gti) { lock_assert(&global_lock); tvh_mutex_lock(>imer_lock); if (gti == gtimer_running) @@ -431,10 +409,8 @@ gtimer_disarm(gtimer_t *gti) /** * */ -tasklet_t * -tasklet_arm_alloc(tsk_callback_t *callback, void *opaque) -{ - tasklet_t *tsk = calloc(1, sizeof(*tsk)); +tasklet_t* tasklet_arm_alloc(tsk_callback_t* callback, void* opaque) { + tasklet_t* tsk = calloc(1, sizeof(*tsk)); if (tsk) { memoryinfo_alloc(&tasklet_memoryinfo, sizeof(*tsk)); tsk->tsk_free = free; @@ -446,9 +422,7 @@ tasklet_arm_alloc(tsk_callback_t *callback, void *opaque) /** * */ -void -tasklet_arm(tasklet_t *tsk, tsk_callback_t *callback, void *opaque) -{ +void tasklet_arm(tasklet_t* tsk, tsk_callback_t* callback, void* opaque) { tvh_mutex_lock(&tasklet_lock); if (tsk->tsk_callback != NULL) @@ -468,25 +442,22 @@ tasklet_arm(tasklet_t *tsk, tsk_callback_t *callback, void *opaque) /** * */ -void -tasklet_disarm(tasklet_t *tsk) -{ +void tasklet_disarm(tasklet_t* tsk) { tvh_mutex_lock(&tasklet_lock); - if(tsk->tsk_callback) { + if (tsk->tsk_callback) { TAILQ_REMOVE(&tasklets, tsk, tsk_link); tsk->tsk_callback(tsk->tsk_opaque, 1); tsk->tsk_callback = NULL; - if (tsk->tsk_free) tsk->tsk_free(tsk); + if (tsk->tsk_free) + tsk->tsk_free(tsk); } tvh_mutex_unlock(&tasklet_lock); } -static void -tasklet_flush() -{ - tasklet_t *tsk; +static void tasklet_flush() { + tasklet_t* tsk; tvh_mutex_lock(&tasklet_lock); @@ -506,12 +477,10 @@ tasklet_flush() /** * */ -static void * -tasklet_thread ( void *aux ) -{ - tasklet_t *tsk; - tsk_callback_t *tsk_cb; - void *opaque; +static void* tasklet_thread(void* aux) { + tasklet_t* tsk; + tsk_callback_t* tsk_cb; + void* opaque; tvh_thread_renice(20); @@ -524,8 +493,8 @@ tasklet_thread ( void *aux ) } /* the callback might re-initialize tasklet, save everything */ TAILQ_REMOVE(&tasklets, tsk, tsk_link); - tsk_cb = tsk->tsk_callback; - opaque = tsk->tsk_opaque; + tsk_cb = tsk->tsk_callback; + opaque = tsk->tsk_opaque; tsk->tsk_callback = NULL; if (tsk->tsk_free) { memoryinfo_free(&tasklet_memoryinfo, sizeof(*tsk)); @@ -546,9 +515,7 @@ tasklet_thread ( void *aux ) /** * Show version info */ -static void -show_version(const char *argv0) -{ +static void show_version(const char* argv0) { printf("%s: version %s\n", argv0, tvheadend_version); exit(0); } @@ -556,11 +523,8 @@ show_version(const char *argv0) /** * */ -static void -show_usage - (const char *argv0, cmdline_opt_t *opts, int num, const char *err, ...) -{ - int i; +static void show_usage(const char* argv0, cmdline_opt_t* opts, int num, const char* err, ...) { + int i; char buf[256]; printf(_("Usage: %s [OPTIONS]\n"), argv0); for (i = 0; i < num; i++) { @@ -569,9 +533,9 @@ show_usage if (!opts[i].lopt) { printf("\n%s\n\n", tvh_gettext(opts[i].desc)); - /* Option */ + /* Option */ } else { - char sopt[4]; + char sopt[4]; char *desc, *tok; if (opts[i].sopt) snprintf(sopt, sizeof(sopt), "-%c,", opts[i].sopt); @@ -593,20 +557,18 @@ show_usage } } printf("%s", - _("\n" - "For more information please visit the Tvheadend website:\n" - "https://tvheadend.org\n")); + _("\n" + "For more information please visit the Tvheadend website:\n" + "https://tvheadend.org\n")); exit(0); } /** * Show subsystems info */ -static void -show_subsystems(const char *argv0) -{ - int i; - tvhlog_subsys_t *ts = tvhlog_subsystems; +static void show_subsystems(const char* argv0) { + int i; + tvhlog_subsys_t* ts = tvhlog_subsystems; printf("Subsystems:\n\n"); for (i = 1, ts++; i < LS_LAST; i++, ts++) { printf(" %-15s %s\n", ts->name, _(ts->desc)); @@ -617,9 +579,7 @@ show_subsystems(const char *argv0) /** * */ -static inline time_t -gdispatch_clock_update(void) -{ +static inline time_t gdispatch_clock_update(void) { time_t now = time(NULL); atomic_set_time_t(&__gdispatch_clock, now); return now; @@ -628,16 +588,14 @@ gdispatch_clock_update(void) /** * */ -static int64_t -mdispatch_clock_update(void) -{ +static int64_t mdispatch_clock_update(void) { int64_t mono = getmonoclock(); if (mono > atomic_get_s64(&mtimer_periodic)) { atomic_set_s64(&mtimer_periodic, mono + MONOCLOCK_RESOLUTION); gdispatch_clock_update(); /* gclk() update */ - tprofile_log_stats(); /* Log timings */ - comet_flush(); /* Flush idle comet mailboxes */ + tprofile_log_stats(); /* Log timings */ + comet_flush(); /* Flush idle comet mailboxes */ } atomic_set_s64(&__mdispatch_clock, mono); @@ -647,9 +605,7 @@ mdispatch_clock_update(void) /** * */ -static void * -mtimer_tick_thread(void *aux) -{ +static void* mtimer_tick_thread(void* aux) { while (tvheadend_is_running()) { /* update clocks each 10x in one second */ atomic_set_s64(&__mdispatch_clock, getmonoclock()); @@ -661,13 +617,11 @@ mtimer_tick_thread(void *aux) /** * */ -static void * -mtimer_thread(void *aux) -{ - mtimer_t *mti; - mti_callback_t *cb; - int64_t now, next; - const char *id; +static void* mtimer_thread(void* aux) { + mtimer_t* mti; + mti_callback_t* cb; + int64_t now, next; + const char* id; tvh_mutex_lock(&mtimer_lock); while (tvheadend_is_running() && atomic_get(&tvheadend_mainloop) == 0) @@ -676,7 +630,7 @@ mtimer_thread(void *aux) while (tvheadend_is_running()) { /* Global monoclock timers */ - now = mdispatch_clock_update(); + now = mdispatch_clock_update(); next = now + sec2mono(3600); while (1) { @@ -727,17 +681,15 @@ mtimer_thread(void *aux) /** * */ -static void -mainloop(void) -{ - gtimer_t *gti; - gti_callback_t *cb; - time_t now; +static void mainloop(void) { + gtimer_t* gti; + gti_callback_t* cb; + time_t now; struct timespec ts; - const char *id; + const char* id; while (tvheadend_is_running()) { - now = gdispatch_clock_update(); + now = gdispatch_clock_update(); ts.tv_sec = now + 3600; ts.tv_nsec = 0; @@ -759,7 +711,7 @@ mainloop(void) cb = gti->gti_callback; LIST_REMOVE(gti, gti_link); gti->gti_callback = NULL; - gtimer_running = gti; + gtimer_running = gti; tvh_mutex_unlock(>imer_lock); tvh_mutex_lock(&global_lock); @@ -778,32 +730,29 @@ mainloop(void) } } - /** * */ -int -main(int argc, char **argv) -{ - int i; +int main(int argc, char** argv) { + int i; sigset_t set; #if ENABLE_MPEGTS uint32_t adapter_mask = 0; #endif - int log_level = LOG_INFO; - int log_options = TVHLOG_OPT_MILLIS | TVHLOG_OPT_STDERR | TVHLOG_OPT_SYSLOG; + int log_level = LOG_INFO; + int log_options = TVHLOG_OPT_MILLIS | TVHLOG_OPT_STDERR | TVHLOG_OPT_SYSLOG; const char *log_debug = NULL, *log_trace = NULL; - gid_t gid = -1; - uid_t uid = -1; - char buf[512]; - FILE *pidfile = NULL; + gid_t gid = -1; + uid_t uid = -1; + char buf[512]; + FILE* pidfile = NULL; static struct { - void *thread_id; + void* thread_id; struct timeval tv; - uint8_t ru[32]; + uint8_t ru[32]; } randseed; struct rlimit rl; - extern int dvb_bouquets_parse; + extern int dvb_bouquets_parse; main_tid = pthread_self(); @@ -824,159 +773,141 @@ main(int argc, char **argv) tvheadend_webroot = NULL; tvheadend_htsp_port = 9982; tvheadend_htsp_port_extra = 0; - __mdispatch_clock = getmonoclock(); - __gdispatch_clock = time(NULL); + __mdispatch_clock = getmonoclock(); + __gdispatch_clock = time(NULL); /* Command line options */ - int opt_help = 0, - opt_version = 0, - opt_fork = 0, - opt_firstrun = 0, - opt_stderr = 0, - opt_nostderr = 0, - opt_syslog = 0, - opt_nosyslog = 0, - opt_uidebug = 0, - opt_abort = 0, - opt_noacl = 0, - opt_fileline = 0, - opt_threadid = 0, - opt_libav = 0, - opt_ipv6 = 0, - opt_nosatipcli = 0, - opt_satip_rtsp = 0, + int opt_help = 0, opt_version = 0, opt_fork = 0, opt_firstrun = 0, opt_stderr = 0, + opt_nostderr = 0, opt_syslog = 0, opt_nosyslog = 0, opt_uidebug = 0, opt_abort = 0, + opt_noacl = 0, opt_fileline = 0, opt_threadid = 0, opt_libav = 0, opt_ipv6 = 0, + opt_nosatipcli = 0, opt_satip_rtsp = 0, #if ENABLE_TSFILE - opt_tsfile_tuner = 0, + opt_tsfile_tuner = 0, #endif - opt_dump = 0, - opt_xspf = 0, - opt_dbus = 0, - opt_dbus_session = 0, - opt_nobackup = 0, - opt_nobat = 0, - opt_subsystems = 0, - opt_tprofile = 0, - opt_thread_debug = 0; - const char *opt_config = NULL, - *opt_user = NULL, - *opt_group = NULL, - *opt_logpath = NULL, - *opt_log_debug = NULL, - *opt_log_trace = NULL, - *opt_pidpath = "/run/tvheadend.pid", + opt_dump = 0, opt_xspf = 0, opt_dbus = 0, opt_dbus_session = 0, opt_nobackup = 0, + opt_nobat = 0, opt_subsystems = 0, opt_tprofile = 0, opt_thread_debug = 0; + const char *opt_config = NULL, *opt_user = NULL, *opt_group = NULL, *opt_logpath = NULL, + *opt_log_debug = NULL, *opt_log_trace = NULL, *opt_pidpath = "/run/tvheadend.pid", #if ENABLE_LINUXDVB *opt_dvb_adapters = NULL, #endif - *opt_bindaddr = NULL, - *opt_subscribe = NULL, - *opt_user_agent = NULL, + *opt_bindaddr = NULL, *opt_subscribe = NULL, *opt_user_agent = NULL, *opt_satip_bindaddr = NULL; - static char *__opt_satip_xml[10]; - str_list_t opt_satip_xml = { .max = 10, .num = 0, .str = __opt_satip_xml }; - static char *__opt_satip_tsfile[10]; - str_list_t opt_tsfile = { .max = 10, .num = 0, .str = __opt_satip_tsfile }; + static char* __opt_satip_xml[10]; + str_list_t opt_satip_xml = {.max = 10, .num = 0, .str = __opt_satip_xml}; + static char* __opt_satip_tsfile[10]; + str_list_t opt_tsfile = {.max = 10, .num = 0, .str = __opt_satip_tsfile}; cmdline_opt_t cmdline_opts[] = { - { 0, NULL, N_("Generic options"), OPT_BOOL, NULL }, - { 'h', "help", N_("Show this page"), OPT_BOOL, &opt_help }, - { 'v', "version", N_("Show version information"),OPT_BOOL, &opt_version }, - - { 0, NULL, N_("Service configuration"), OPT_BOOL, NULL }, - { 'c', "config", N_("Alternate configuration path"), OPT_STR, &opt_config }, - { 'B', "nobackup", N_("Don't backup configuration tree at upgrade"), OPT_BOOL, &opt_nobackup }, - { 'f', "fork", N_("Fork and run as daemon"), OPT_BOOL, &opt_fork }, - { 'u', "user", N_("Run as user"), OPT_STR, &opt_user }, - { 'g', "group", N_("Run as group"), OPT_STR, &opt_group }, - { 'p', "pid", N_("Alternate PID path"), OPT_STR, &opt_pidpath }, - { 'C', "firstrun", N_("If no user account exists then create one with\n" - "no username and no password. Use with care as\n" - "it will allow world-wide administrative access\n" - "to your Tvheadend installation until you create or edit\n" - "the access control from within the Tvheadend web interface."), - OPT_BOOL, &opt_firstrun }, + {0, NULL, N_("Generic options"), OPT_BOOL, NULL}, + {'h', "help", N_("Show this page"), OPT_BOOL, &opt_help}, + {'v', "version", N_("Show version information"), OPT_BOOL, &opt_version}, + + {0, NULL, N_("Service configuration"), OPT_BOOL, NULL}, + {'c', "config", N_("Alternate configuration path"), OPT_STR, &opt_config}, + {'B', "nobackup", N_("Don't backup configuration tree at upgrade"), OPT_BOOL, &opt_nobackup}, + {'f', "fork", N_("Fork and run as daemon"), OPT_BOOL, &opt_fork}, + {'u', "user", N_("Run as user"), OPT_STR, &opt_user}, + {'g', "group", N_("Run as group"), OPT_STR, &opt_group}, + {'p', "pid", N_("Alternate PID path"), OPT_STR, &opt_pidpath}, + {'C', + "firstrun", + N_("If no user account exists then create one with\n" + "no username and no password. Use with care as\n" + "it will allow world-wide administrative access\n" + "to your Tvheadend installation until you create or edit\n" + "the access control from within the Tvheadend web interface."), + OPT_BOOL, + &opt_firstrun}, #if ENABLE_DBUS_1 - { 'U', "dbus", N_("Enable DBus"), - OPT_BOOL, &opt_dbus }, - { 'e', "dbus_session", N_("DBus - use the session message bus instead of the system one"), - OPT_BOOL, &opt_dbus_session }, + {'U', "dbus", N_("Enable DBus"), OPT_BOOL, &opt_dbus}, + {'e', + "dbus_session", + N_("DBus - use the session message bus instead of the system one"), + OPT_BOOL, + &opt_dbus_session}, #endif #if ENABLE_LINUXDVB - { 'a', "adapters", N_("Only use specified DVB adapters (comma-separated, -1 = none)"), - OPT_STR, &opt_dvb_adapters }, + {'a', + "adapters", + N_("Only use specified DVB adapters (comma-separated, -1 = none)"), + OPT_STR, + &opt_dvb_adapters}, #endif #if ENABLE_SATIP_SERVER - { 0, "satip_bindaddr", N_("Specify bind address for SAT>IP server"), - OPT_STR, &opt_satip_bindaddr }, - { 0, "satip_rtsp", N_("SAT>IP RTSP port number for server\n" - "(default: -1 = disable, 0 = webconfig, standard port is 554)"), - OPT_INT, &opt_satip_rtsp }, + {0, + "satip_bindaddr", + N_("Specify bind address for SAT>IP server"), + OPT_STR, + &opt_satip_bindaddr}, + {0, + "satip_rtsp", + N_("SAT>IP RTSP port number for server\n" + "(default: -1 = disable, 0 = webconfig, standard port is 554)"), + OPT_INT, + &opt_satip_rtsp}, #endif #if ENABLE_SATIP_CLIENT - { 0, "nosatip", N_("Disable SAT>IP client (deprecated flag, use nosatipcli)"), - OPT_BOOL, &opt_nosatipcli }, - { 0, "nosatipcli", N_("Disable SAT>IP client"), - OPT_BOOL, &opt_nosatipcli }, - { 0, "satip_xml", N_("URL with the SAT>IP server XML location"), - OPT_STR_LIST, &opt_satip_xml }, + {0, + "nosatip", + N_("Disable SAT>IP client (deprecated flag, use nosatipcli)"), + OPT_BOOL, + &opt_nosatipcli}, + {0, "nosatipcli", N_("Disable SAT>IP client"), OPT_BOOL, &opt_nosatipcli}, + {0, "satip_xml", N_("URL with the SAT>IP server XML location"), OPT_STR_LIST, &opt_satip_xml}, #endif - { 0, NULL, N_("Server connectivity"), OPT_BOOL, NULL }, - { '6', "ipv6", N_("Listen on IPv6"), OPT_BOOL, &opt_ipv6 }, - { 'b', "bindaddr", N_("Specify bind address"), OPT_STR, &opt_bindaddr}, - { 0, "http_port", N_("Specify alternative http port"), - OPT_INT, &tvheadend_webui_port }, - { 0, "http_root", N_("Specify alternative http webroot"), - OPT_STR, &tvheadend_webroot }, - { 0, "htsp_port", N_("Specify alternative htsp port"), - OPT_INT, &tvheadend_htsp_port }, - { 0, "htsp_port2", N_("Specify extra htsp port"), - OPT_INT, &tvheadend_htsp_port_extra }, - { 0, "useragent", N_("Specify User-Agent header for the http client"), - OPT_STR, &opt_user_agent }, - { 0, "xspf", N_("Use XSPF playlist instead of M3U"), - OPT_BOOL, &opt_xspf }, - - { 0, NULL, N_("Debug options"), OPT_BOOL, NULL }, - { 'd', "stderr", N_("Enable debug on stderr"), OPT_BOOL, &opt_stderr }, - { 'n', "nostderr", N_("Disable debug on stderr"), OPT_BOOL, &opt_nostderr }, - { 's', "syslog", N_("Enable debug to syslog"), OPT_BOOL, &opt_syslog }, - { 'S', "nosyslog", N_("Disable syslog (all messages)"), OPT_BOOL, &opt_nosyslog }, - { 'l', "logfile", N_("Enable debug to file"), OPT_STR, &opt_logpath }, - { 0, "debug", N_("Enable debug subsystems"), OPT_STR, &opt_log_debug }, + {0, NULL, N_("Server connectivity"), OPT_BOOL, NULL}, + {'6', "ipv6", N_("Listen on IPv6"), OPT_BOOL, &opt_ipv6}, + {'b', "bindaddr", N_("Specify bind address"), OPT_STR, &opt_bindaddr}, + {0, "http_port", N_("Specify alternative http port"), OPT_INT, &tvheadend_webui_port}, + {0, "http_root", N_("Specify alternative http webroot"), OPT_STR, &tvheadend_webroot}, + {0, "htsp_port", N_("Specify alternative htsp port"), OPT_INT, &tvheadend_htsp_port}, + {0, "htsp_port2", N_("Specify extra htsp port"), OPT_INT, &tvheadend_htsp_port_extra}, + {0, + "useragent", + N_("Specify User-Agent header for the http client"), + OPT_STR, + &opt_user_agent}, + {0, "xspf", N_("Use XSPF playlist instead of M3U"), OPT_BOOL, &opt_xspf}, + + {0, NULL, N_("Debug options"), OPT_BOOL, NULL}, + {'d', "stderr", N_("Enable debug on stderr"), OPT_BOOL, &opt_stderr}, + {'n', "nostderr", N_("Disable debug on stderr"), OPT_BOOL, &opt_nostderr}, + {'s', "syslog", N_("Enable debug to syslog"), OPT_BOOL, &opt_syslog}, + {'S', "nosyslog", N_("Disable syslog (all messages)"), OPT_BOOL, &opt_nosyslog}, + {'l', "logfile", N_("Enable debug to file"), OPT_STR, &opt_logpath}, + {0, "debug", N_("Enable debug subsystems"), OPT_STR, &opt_log_debug}, #if ENABLE_TRACE - { 0, "trace", N_("Enable trace subsystems"), OPT_STR, &opt_log_trace }, + {0, "trace", N_("Enable trace subsystems"), OPT_STR, &opt_log_trace}, #endif - { 0, "subsystems",N_("List subsystems"), OPT_BOOL, &opt_subsystems }, - { 0, "fileline", N_("Add file and line numbers to debug"), OPT_BOOL, &opt_fileline }, - { 0, "threadid", N_("Add the thread ID to debug"), OPT_BOOL, &opt_threadid }, + {0, "subsystems", N_("List subsystems"), OPT_BOOL, &opt_subsystems}, + {0, "fileline", N_("Add file and line numbers to debug"), OPT_BOOL, &opt_fileline}, + {0, "threadid", N_("Add the thread ID to debug"), OPT_BOOL, &opt_threadid}, #if ENABLE_LIBAV - { 0, "libav", N_("More verbose libav log"), OPT_BOOL, &opt_libav }, + {0, "libav", N_("More verbose libav log"), OPT_BOOL, &opt_libav}, #endif - { 0, "uidebug", N_("Enable web UI debug (non-minified JS)"), OPT_BOOL, &opt_uidebug }, - { 'A', "abort", N_("Immediately abort"), OPT_BOOL, &opt_abort }, - { 'D', "dump", N_("Enable coredumps for daemon"), OPT_BOOL, &opt_dump }, - { 0, "noacl", N_("Disable all access control checks"), - OPT_BOOL, &opt_noacl }, - { 0, "nobat", N_("Disable DVB bouquets"), - OPT_BOOL, &opt_nobat }, - { 'j', "join", N_("Subscribe to a service permanently"), - OPT_STR, &opt_subscribe }, - + {0, "uidebug", N_("Enable web UI debug (non-minified JS)"), OPT_BOOL, &opt_uidebug}, + {'A', "abort", N_("Immediately abort"), OPT_BOOL, &opt_abort}, + {'D', "dump", N_("Enable coredumps for daemon"), OPT_BOOL, &opt_dump}, + {0, "noacl", N_("Disable all access control checks"), OPT_BOOL, &opt_noacl}, + {0, "nobat", N_("Disable DVB bouquets"), OPT_BOOL, &opt_nobat}, + {'j', "join", N_("Subscribe to a service permanently"), OPT_STR, &opt_subscribe}, #if ENABLE_TSFILE || ENABLE_TSDEBUG - { 0, NULL, N_("Testing options"), OPT_BOOL, NULL }, - { 0, "tsfile_tuners", N_("Number of tsfile tuners"), OPT_INT, &opt_tsfile_tuner }, - { 0, "tsfile", N_("tsfile input (mux file)"), OPT_STR_LIST, &opt_tsfile }, + {0, NULL, N_("Testing options"), OPT_BOOL, NULL}, + {0, "tsfile_tuners", N_("Number of tsfile tuners"), OPT_INT, &opt_tsfile_tuner}, + {0, "tsfile", N_("tsfile input (mux file)"), OPT_STR_LIST, &opt_tsfile}, #endif - { 0, "tprofile", N_("Gather timing statistics for the code"), OPT_BOOL, &opt_tprofile }, + {0, "tprofile", N_("Gather timing statistics for the code"), OPT_BOOL, &opt_tprofile}, #if ENABLE_TRACE - { 0, "thrdebug", N_("Thread debugging"), OPT_INT, &opt_thread_debug }, + {0, "thrdebug", N_("Thread debugging"), OPT_INT, &opt_thread_debug}, #endif }; /* Get current directory */ tvheadend_cwd0 = dirname(tvh_strdupa(argv[0])); - tvheadend_cwd = dirname(tvh_strdupa(tvheadend_cwd0)); + tvheadend_cwd = dirname(tvh_strdupa(tvheadend_cwd0)); /* Set locale */ setlocale(LC_ALL, ""); @@ -990,11 +921,13 @@ main(int argc, char **argv) for (i = 1; i < argc; i++) { /* Find option */ - cmdline_opt_t *opt - = cmdline_opt_find(cmdline_opts, ARRAY_SIZE(cmdline_opts), argv[i]); + cmdline_opt_t* opt = cmdline_opt_find(cmdline_opts, ARRAY_SIZE(cmdline_opts), argv[i]); if (!opt) { - show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), - _("invalid option specified [%s]"), argv[i]); + show_usage(argv[0], + cmdline_opts, + ARRAY_SIZE(cmdline_opts), + _("invalid option specified [%s]"), + argv[i]); continue; } @@ -1002,16 +935,18 @@ main(int argc, char **argv) if (opt->type == OPT_BOOL) *((int*)opt->param) = 1; else if (++i == argc) - show_usage(argv[0], cmdline_opts, ARRAY_SIZE(cmdline_opts), - _("option %s requires a value"), opt->lopt); + show_usage(argv[0], + cmdline_opts, + ARRAY_SIZE(cmdline_opts), + _("option %s requires a value"), + opt->lopt); else if (opt->type == OPT_INT) *((int*)opt->param) = atoi(argv[i]); else if (opt->type == OPT_STR_LIST) { - str_list_t *strl = opt->param; + str_list_t* strl = opt->param; if (strl->num < strl->max) strl->str[strl->num++] = argv[i]; - } - else + } else *((char**)opt->param) = argv[i]; /* Stop processing */ @@ -1031,11 +966,11 @@ main(int argc, char **argv) adapter_mask = ~0; } else { char *p, *e; - char *r = NULL; - char *dvb_adapters = strdup(opt_dvb_adapters); - adapter_mask = 0x0; - i = 0; - p = strtok_r(dvb_adapters, ",", &r); + char* r = NULL; + char* dvb_adapters = strdup(opt_dvb_adapters); + adapter_mask = 0x0; + i = 0; + p = strtok_r(dvb_adapters, ",", &r); while (p) { int a = strtol(p, &e, 10); if (*e != 0 || a > 31) { @@ -1058,16 +993,16 @@ main(int argc, char **argv) } #endif if (tvheadend_webroot) { - char *tmp; + char* tmp; if (*tvheadend_webroot == '/') tmp = strdup(tvheadend_webroot); else { - tmp = malloc(strlen(tvheadend_webroot)+2); + tmp = malloc(strlen(tvheadend_webroot) + 2); *tmp = '/'; - strcpy(tmp+1, tvheadend_webroot); + strcpy(tmp + 1, tvheadend_webroot); } - if (tmp[strlen(tmp)-1] == '/') - tmp[strlen(tmp)-1] = '\0'; + if (tmp[strlen(tmp) - 1] == '/') + tmp[strlen(tmp) - 1] = '\0'; if (tmp[0]) tvheadend_webroot = tmp; else @@ -1080,19 +1015,19 @@ main(int argc, char **argv) log_options |= TVHLOG_OPT_DECORATE; if (opt_stderr || opt_syslog || opt_logpath) { if (!opt_log_trace && !opt_log_debug) - log_debug = "all"; - log_level = LOG_DEBUG; + log_debug = "all"; + log_level = LOG_DEBUG; if (opt_stderr) - log_options |= TVHLOG_OPT_DBG_STDERR; + log_options |= TVHLOG_OPT_DBG_STDERR; if (opt_syslog) - log_options |= TVHLOG_OPT_DBG_SYSLOG; + log_options |= TVHLOG_OPT_DBG_SYSLOG; if (opt_logpath) - log_options |= TVHLOG_OPT_DBG_FILE; + log_options |= TVHLOG_OPT_DBG_FILE; } if (opt_nostderr) - log_options &= ~(TVHLOG_OPT_DECORATE|TVHLOG_OPT_STDERR|TVHLOG_OPT_DBG_STDERR); + log_options &= ~(TVHLOG_OPT_DECORATE | TVHLOG_OPT_STDERR | TVHLOG_OPT_DBG_STDERR); if (opt_nosyslog) - log_options &= ~(TVHLOG_OPT_SYSLOG|TVHLOG_OPT_DBG_SYSLOG); + log_options &= ~(TVHLOG_OPT_SYSLOG | TVHLOG_OPT_DBG_SYSLOG); if (opt_fileline) log_options |= TVHLOG_OPT_FILELINE; if (opt_threadid) @@ -1100,11 +1035,11 @@ main(int argc, char **argv) if (opt_libav) log_options |= TVHLOG_OPT_LIBAV; if (opt_log_trace) { - log_level = LOG_TRACE; - log_trace = opt_log_trace; + log_level = LOG_TRACE; + log_trace = opt_log_trace; } if (opt_log_debug) - log_debug = opt_log_debug; + log_debug = opt_log_debug; tvh_thread_init(opt_thread_debug); @@ -1117,15 +1052,16 @@ main(int argc, char **argv) tvh_signal(SIGILL, handle_sigill); // see handler.. if (opt_fork && !opt_user && !opt_config) - tvhwarn(LS_START, "Forking without --user or --config may use unexpected configuration location"); + tvhwarn(LS_START, + "Forking without --user or --config may use unexpected configuration location"); /* Set privileges */ - if((opt_fork && getuid() == 0) || opt_group || opt_user) { - const char *homedir; - struct group *grp = getgrnam(opt_group ?: "video"); - struct passwd *pw = getpwnam(opt_user ?: "daemon"); + if ((opt_fork && getuid() == 0) || opt_group || opt_user) { + const char* homedir; + struct group* grp = getgrnam(opt_group ?: "video"); + struct passwd* pw = getpwnam(opt_user ?: "daemon"); - if(grp != NULL) { + if (grp != NULL) { gid = grp->gr_gid; } else { gid = 1; @@ -1134,16 +1070,14 @@ main(int argc, char **argv) if (pw != NULL) { if (getuid() != pw->pw_uid) { gid_t glist[16]; - int gnum; + int gnum; gnum = get_user_groups(pw, glist, ARRAY_SIZE(glist)); if (gnum > 0 && setgroups(gnum, glist)) { char buf[256] = ""; - int i; + int i; for (i = 0; i < gnum; i++) - snprintf(buf + strlen(buf), sizeof(buf) - 1 - strlen(buf), - ",%d", glist[i]); - tvhlog(LOG_ALERT, LS_START, - "setgroups(%s) failed, do you have permission?", buf+1); + snprintf(buf + strlen(buf), sizeof(buf) - 1 - strlen(buf), ",%d", glist[i]); + tvhlog(LOG_ALERT, LS_START, "setgroups(%s) failed, do you have permission?", buf + 1); return 1; } } @@ -1162,30 +1096,28 @@ main(int argc, char **argv) idnode_boot(); config_boot(opt_config, gid, uid, opt_user_agent); tcp_server_preinit(opt_ipv6); - http_server_init(opt_bindaddr); // bind to ports only - htsp_init(opt_bindaddr); // bind to ports only + http_server_init(opt_bindaddr); // bind to ports only + htsp_init(opt_bindaddr); // bind to ports only satip_server_init(opt_satip_bindaddr, opt_satip_rtsp); // bind to ports only if (opt_fork) pidfile = tvh_fopen(opt_pidpath, "w+"); if (gid != -1 && (getgid() != gid) && setgid(gid)) { - tvhlog(LOG_ALERT, LS_START, - "setgid(%d) failed, do you have permission?", gid); + tvhlog(LOG_ALERT, LS_START, "setgid(%d) failed, do you have permission?", gid); return 1; } if (uid != -1 && (getuid() != uid) && setuid(uid)) { - tvhlog(LOG_ALERT, LS_START, - "setuid(%d) failed, do you have permission?", uid); + tvhlog(LOG_ALERT, LS_START, "setuid(%d) failed, do you have permission?", uid); return 1; } /* Daemonise */ - if(opt_fork) { - if(daemon(0, 0)) { + if (opt_fork) { + if (daemon(0, 0)) { exit(2); } - if(pidfile != NULL) { + if (pidfile != NULL) { fprintf(pidfile, "%d\n", getpid()); fclose(pidfile); } @@ -1205,9 +1137,9 @@ main(int argc, char **argv) } memset(&rl, 0, sizeof(rl)); - if (getrlimit(RLIMIT_STACK, &rl) || rl.rlim_cur < 2*1024*1024) { - rlim_t rl2 = rl.rlim_cur; - rl.rlim_cur = 2*1024*1024; + if (getrlimit(RLIMIT_STACK, &rl) || rl.rlim_cur < 2 * 1024 * 1024) { + rlim_t rl2 = rl.rlim_cur; + rl.rlim_cur = 2 * 1024 * 1024; if (setrlimit(RLIMIT_STACK, &rl)) { tvhlog(LOG_ALERT, LS_START, "too small stack size - %ld", (long)rl2); return 1; @@ -1249,7 +1181,7 @@ main(int argc, char **argv) #endif /* Rand seed */ - randseed.thread_id = (void *)main_tid; + randseed.thread_id = (void*)main_tid; gettimeofday(&randseed.tv, NULL); uuid_random(randseed.ru, sizeof(randseed.ru)); RAND_seed(&randseed, sizeof(randseed)); @@ -1304,8 +1236,13 @@ main(int argc, char **argv) tvhftrace(LS_MAIN, descrambler_init); tvhftrace(LS_MAIN, dvb_init); #if ENABLE_MPEGTS - tvhftrace(LS_MAIN, mpegts_init, adapter_mask, opt_nosatipcli, &opt_satip_xml, - &opt_tsfile, opt_tsfile_tuner); + tvhftrace(LS_MAIN, + mpegts_init, + adapter_mask, + opt_nosatipcli, + &opt_satip_xml, + &opt_tsfile, + opt_tsfile_tuner); #endif tvhftrace(LS_MAIN, channel_init); tvhftrace(LS_MAIN, bouquet_service_resolve); @@ -1329,7 +1266,7 @@ main(int argc, char **argv) tvhftrace(LS_MAIN, satip_server_register); tvhftrace(LS_MAIN, htsp_register); - if(opt_subscribe != NULL) + if (opt_subscribe != NULL) subscription_dummy_join(opt_subscribe, 1); tvhftrace(LS_MAIN, avahi_init); @@ -1355,13 +1292,18 @@ main(int argc, char **argv) pthread_sigmask(SIG_UNBLOCK, &set, NULL); - tvhlog(LOG_NOTICE, LS_START, "HTS Tvheadend version %s started, " - "running as PID:%d UID:%d GID:%d, CWD:%s CNF:%s", - tvheadend_version, - getpid(), getuid(), getgid(), getcwd(buf, sizeof(buf)), - hts_settings_get_root()); - - if(opt_abort) + tvhlog(LOG_NOTICE, + LS_START, + "HTS Tvheadend version %s started, " + "running as PID:%d UID:%d GID:%d, CWD:%s CNF:%s", + tvheadend_version, + getpid(), + getuid(), + getgid(), + getcwd(buf, sizeof(buf)), + hts_settings_get_root()); + + if (opt_abort) abort(); tvh_mutex_lock(&mtimer_lock); @@ -1451,11 +1393,11 @@ main(int argc, char **argv) tvh_thread_done(); - if(opt_fork) + if (opt_fork) unlink(opt_pidpath); #if OPENSSL_VERSION_NUMBER < 0x10100000L - /* OpenSSL - welcome to the "cleanup" hell */ + /* OpenSSL - welcome to the "cleanup" hell */ #ifndef OPENSSL_NO_ENGINE ENGINE_cleanup(); #endif @@ -1476,10 +1418,11 @@ main(int argc, char **argv) #if ENABLE_DBUS_1 extern void dbus_shutdown(void); - if (opt_dbus) dbus_shutdown(); + if (opt_dbus) + dbus_shutdown(); #endif tvh_gettext_done(); - free((char *)tvheadend_webroot); + free((char*)tvheadend_webroot); tvhftrace(LS_MAIN, watchdog_done); return 0; @@ -1488,35 +1431,28 @@ main(int argc, char **argv) /** * */ -void -tvh_str_set(char **strp, const char *src) -{ +void tvh_str_set(char** strp, const char* src) { free(*strp); *strp = src ? strdup(src) : NULL; } - /** * */ -int -tvh_str_update(char **strp, const char *src) -{ - if(src == NULL) +int tvh_str_update(char** strp, const char* src) { + if (src == NULL) return 0; free(*strp); *strp = strdup(src); return 1; } - /** * */ -htsmsg_t *tvheadend_capabilities_list(int check) -{ - const tvh_caps_t *tc = tvheadend_capabilities; - htsmsg_t *r = htsmsg_create_list(); +htsmsg_t* tvheadend_capabilities_list(int check) { + const tvh_caps_t* tc = tvheadend_capabilities; + htsmsg_t* r = htsmsg_create_list(); while (tc->name) { if (!check || !tc->enabled || *tc->enabled) htsmsg_add_str(r, NULL, tc->name); @@ -1530,7 +1466,6 @@ htsmsg_t *tvheadend_capabilities_list(int check) /** * */ -void time_t_out_of_range_notify(int64_t val) -{ - tvherror(LS_MAIN, "time value out of range (%"PRId64") of time_t", val); +void time_t_out_of_range_notify(int64_t val) { + tvherror(LS_MAIN, "time value out of range (%" PRId64 ") of time_t", val); } diff --git a/src/memoryinfo.c b/src/memoryinfo.c index 8039164a5..4229cca47 100644 --- a/src/memoryinfo.c +++ b/src/memoryinfo.c @@ -23,63 +23,56 @@ struct memoryinfo_list memoryinfo_entries; -static void -service_class_get_title - ( idnode_t *self, const char *lang, char *dst, size_t dstsize ) -{ - snprintf(dst, dstsize, "%s", ((memoryinfo_t *)self)->my_name); +static void service_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + snprintf(dst, dstsize, "%s", ((memoryinfo_t*)self)->my_name); } CLASS_DOC(memoryinfo) -const idclass_t memoryinfo_class = { - .ic_class = "memoryinfo", - .ic_caption = N_("Memory Information"), - .ic_event = "memoryinfo", - .ic_doc = tvh_doc_memoryinfo_class, - .ic_perm_def = ACCESS_ADMIN, - .ic_get_title = service_class_get_title, - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "name", - .name = N_("Name"), - .desc = N_("Name of object."), - .off = offsetof(memoryinfo_t, my_name), - .opts = PO_RDONLY | PO_NOSAVE, - }, - { - .type = PT_S64_ATOMIC, - .id = "size", - .name = N_("Size"), - .desc = N_("Current object size."), - .off = offsetof(memoryinfo_t, my_size), - .opts = PO_RDONLY | PO_NOSAVE, - }, - { - .type = PT_S64_ATOMIC, - .id = "peak_size", - .name = N_("Peak size"), - .desc = N_("Largest size the object has reached."), - .off = offsetof(memoryinfo_t, my_peak_size), - .opts = PO_RDONLY | PO_NOSAVE, - }, - { - .type = PT_S64_ATOMIC, - .id = "count", - .name = N_("Count of objects"), - .desc = N_("Current number of objects."), - .off = offsetof(memoryinfo_t, my_count), - .opts = PO_RDONLY | PO_NOSAVE, - }, - { - .type = PT_S64_ATOMIC, - .id = "peak_count", - .name = N_("Peak count of objects"), - .desc = N_("Highest count of objects."), - .off = offsetof(memoryinfo_t, my_peak_count), - .opts = PO_RDONLY | PO_NOSAVE, - }, - {} - } -}; +const idclass_t memoryinfo_class = {.ic_class = "memoryinfo", + .ic_caption = N_("Memory Information"), + .ic_event = "memoryinfo", + .ic_doc = tvh_doc_memoryinfo_class, + .ic_perm_def = ACCESS_ADMIN, + .ic_get_title = service_class_get_title, + .ic_properties = (const property_t[]){{ + .type = PT_STR, + .id = "name", + .name = N_("Name"), + .desc = N_("Name of object."), + .off = offsetof(memoryinfo_t, my_name), + .opts = PO_RDONLY | PO_NOSAVE, + }, + { + .type = PT_S64_ATOMIC, + .id = "size", + .name = N_("Size"), + .desc = N_("Current object size."), + .off = offsetof(memoryinfo_t, my_size), + .opts = PO_RDONLY | PO_NOSAVE, + }, + { + .type = PT_S64_ATOMIC, + .id = "peak_size", + .name = N_("Peak size"), + .desc = N_("Largest size the object has reached."), + .off = offsetof(memoryinfo_t, my_peak_size), + .opts = PO_RDONLY | PO_NOSAVE, + }, + { + .type = PT_S64_ATOMIC, + .id = "count", + .name = N_("Count of objects"), + .desc = N_("Current number of objects."), + .off = offsetof(memoryinfo_t, my_count), + .opts = PO_RDONLY | PO_NOSAVE, + }, + { + .type = PT_S64_ATOMIC, + .id = "peak_count", + .name = N_("Peak count of objects"), + .desc = N_("Highest count of objects."), + .off = offsetof(memoryinfo_t, my_peak_count), + .opts = PO_RDONLY | PO_NOSAVE, + }, + {}}}; diff --git a/src/memoryinfo.h b/src/memoryinfo.h index d59c8a6a1..166f52bb9 100644 --- a/src/memoryinfo.h +++ b/src/memoryinfo.h @@ -23,62 +23,55 @@ struct memoryinfo; -typedef void (*memoryinfo_cb_t)(struct memoryinfo *my); +typedef void (*memoryinfo_cb_t)(struct memoryinfo* my); typedef struct memoryinfo { - idnode_t my_idnode; + idnode_t my_idnode; LIST_ENTRY(memoryinfo) my_link; - const char *my_name; - void *my_opaque; - memoryinfo_cb_t my_update; - int64_t my_size; - int64_t my_peak_size; - int64_t my_count; - int64_t my_peak_count; + const char* my_name; + void* my_opaque; + memoryinfo_cb_t my_update; + int64_t my_size; + int64_t my_peak_size; + int64_t my_count; + int64_t my_peak_count; } memoryinfo_t; LIST_HEAD(memoryinfo_list, memoryinfo); extern struct memoryinfo_list memoryinfo_entries; -extern const idclass_t memoryinfo_class; +extern const idclass_t memoryinfo_class; -static inline void memoryinfo_register(memoryinfo_t *my) -{ +static inline void memoryinfo_register(memoryinfo_t* my) { LIST_INSERT_HEAD(&memoryinfo_entries, my, my_link); idnode_insert(&my->my_idnode, NULL, &memoryinfo_class, 0); } -static inline void memoryinfo_unregister(memoryinfo_t *my) -{ +static inline void memoryinfo_unregister(memoryinfo_t* my) { LIST_REMOVE(my, my_link); idnode_unlink(&my->my_idnode); } -static inline void memoryinfo_update(memoryinfo_t *my, int64_t size, int64_t count) -{ +static inline void memoryinfo_update(memoryinfo_t* my, int64_t size, int64_t count) { atomic_set_s64_peak(&my->my_size, size, &my->my_peak_size); atomic_set_s64_peak(&my->my_count, count, &my->my_peak_count); } -static inline void memoryinfo_alloc(memoryinfo_t *my, int64_t size) -{ +static inline void memoryinfo_alloc(memoryinfo_t* my, int64_t size) { atomic_pre_add_s64_peak(&my->my_size, size, &my->my_peak_size); atomic_pre_add_s64_peak(&my->my_count, 1, &my->my_peak_count); } -static inline void memoryinfo_append(memoryinfo_t *my, int64_t size) -{ +static inline void memoryinfo_append(memoryinfo_t* my, int64_t size) { atomic_pre_add_s64_peak(&my->my_size, size, &my->my_peak_size); } -static inline void memoryinfo_free(memoryinfo_t *my, int64_t size) -{ +static inline void memoryinfo_free(memoryinfo_t* my, int64_t size) { atomic_dec_s64(&my->my_size, size); atomic_dec_s64(&my->my_count, 1); } -static inline void memoryinfo_remove(memoryinfo_t *my, int64_t size) -{ +static inline void memoryinfo_remove(memoryinfo_t* my, int64_t size) { atomic_dec_s64(&my->my_size, size); } diff --git a/src/misc/dbl.c b/src/misc/dbl.c index 08bbdb891..5d391315a 100644 --- a/src/misc/dbl.c +++ b/src/misc/dbl.c @@ -27,61 +27,56 @@ #include "dbl.h" - -double -my_str2double(const char *str, const char **endp) -{ +double my_str2double(const char* str, const char** endp) { double ret = 0.0, t = 0.1; - int n = 0, e = 0; + int n = 0, e = 0; /* Negative */ - if(*str == '-') { + if (*str == '-') { n = 1; str++; } /* Integer */ - while(*str >= '0' && *str <= '9') + while (*str >= '0' && *str <= '9') ret = ret * 10 + *str++ - '0'; /* Fracton */ - if(*str == '.') { + if (*str == '.') { str++; - while(*str >= '0' && *str <= '9') { + while (*str >= '0' && *str <= '9') { ret += (*str++ - '0') * t; t /= 10; } } /* Negate */ - if (n) ret *= -1; + if (n) + ret *= -1; /* Exponential */ - if(*str == 'e' || *str == 'E') { + if (*str == 'e' || *str == 'E') { int esign = 1; str++; - - if(*str == '+') + + if (*str == '+') str++; - else if(*str == '-') { + else if (*str == '-') { str++; esign = -1; } - - while(*str >= '0' && *str <= '9') + + while (*str >= '0' && *str <= '9') e = e * 10 + *str++ - '0'; ret *= pow(10, e * esign); } - if(endp != NULL) + if (endp != NULL) *endp = str; return ret; } - - - /* ** The code that follow is based on "printf" code that dates from the ** 1980s. It is in the public domain. The original comments are @@ -134,54 +129,52 @@ my_str2double(const char *str, const char **endp) ** */ - -static char -getdigit(double *val, int *cnt) -{ - int digit; +static char getdigit(double* val, int* cnt) { + int digit; double d; - if( (*cnt)++ >= 16 ) return '0'; + if ((*cnt)++ >= 16) + return '0'; digit = (int)*val; - d = digit; + d = digit; digit += '0'; - *val = (*val - d)*10.0; + *val = (*val - d) * 10.0; return (char)digit; } #define xGENERIC 0 -#define xFLOAT 1 -#define xEXP 2 - +#define xFLOAT 1 +#define xEXP 2 -int -my_double2str(char *buf, size_t bufsize, double realvalue) -{ - int precision = -1; - char *bufpt; - char prefix; - char xtype = xGENERIC; - int idx, exp, e2; +int my_double2str(char* buf, size_t bufsize, double realvalue) { + int precision = -1; + char* bufpt; + char prefix; + char xtype = xGENERIC; + int idx, exp, e2; double rounder; - char flag_exp; - char flag_rtz; - char flag_dp; - char flag_alternateform = 0; - char flag_altform2 = 0; - int nsd; + char flag_exp; + char flag_rtz; + char flag_dp; + char flag_alternateform = 0; + char flag_altform2 = 0; + int nsd; - if(bufsize < 8) + if (bufsize < 8) return -1; - if( precision<0 ) precision = 20; /* Set default precision */ - if( precision>bufsize/2-10 ) precision = bufsize/2-10; - if( realvalue<0.0 ){ + if (precision < 0) + precision = 20; /* Set default precision */ + if (precision > bufsize / 2 - 10) + precision = bufsize / 2 - 10; + if (realvalue < 0.0) { realvalue = -realvalue; - prefix = '-'; - }else{ + prefix = '-'; + } else { prefix = 0; } - if( xtype==xGENERIC && precision>0 ) precision--; - for(idx=precision, rounder=0.5; idx>0; idx--, rounder*=0.1){} + if (xtype == xGENERIC && precision > 0) + precision--; + for (idx = precision, rounder = 0.5; idx > 0; idx--, rounder *= 0.1) {} #if 0 /* coverity - dead code 'xtype == xGENERIC' here */ if( xtype==xFLOAT ) realvalue += rounder; @@ -189,22 +182,37 @@ my_double2str(char *buf, size_t bufsize, double realvalue) /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ exp = 0; - if(isnan(realvalue)) { + if (isnan(realvalue)) { strcpy(buf, "NaN"); return 0; } - if( realvalue>0.0 ){ - while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; } - while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; } - while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; } - while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } - while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } - if( exp>350 ){ - if( prefix=='-' ){ - strcpy(buf, "-Inf"); - }else{ - strcpy(buf, "Inf"); + if (realvalue > 0.0) { + while (realvalue >= 1e32 && exp <= 350) { + realvalue *= 1e-32; + exp += 32; + } + while (realvalue >= 1e8 && exp <= 350) { + realvalue *= 1e-8; + exp += 8; + } + while (realvalue >= 10.0 && exp <= 350) { + realvalue *= 0.1; + exp++; + } + while (realvalue < 1e-8) { + realvalue *= 1e8; + exp -= 8; + } + while (realvalue < 1.0) { + realvalue *= 10.0; + exp--; + } + if (exp > 350) { + if (prefix == '-') { + strcpy(buf, "-Inf"); + } else { + strcpy(buf, "Inf"); } return 0; } @@ -215,18 +223,21 @@ my_double2str(char *buf, size_t bufsize, double realvalue) ** If the field type is etGENERIC, then convert to either etEXP ** or etFLOAT, as appropriate. */ - flag_exp = xtype==xEXP; - if( xtype != xFLOAT ){ + flag_exp = xtype == xEXP; + if (xtype != xFLOAT) { realvalue += rounder; - if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } + if (realvalue >= 10.0) { + realvalue *= 0.1; + exp++; + } } - if( xtype==xGENERIC ){ + if (xtype == xGENERIC) { flag_rtz = !flag_alternateform; - if( exp<-4 || exp>precision ){ + if (exp < -4 || exp > precision) { xtype = xEXP; - }else{ + } else { precision = precision - exp; - xtype = xFLOAT; + xtype = xFLOAT; } } #if 0 /* coverity - dead code - xtype == xGENERIC here */ @@ -234,71 +245,70 @@ my_double2str(char *buf, size_t bufsize, double realvalue) flag_rtz = 0; } #endif - if( xtype==xEXP ){ + if (xtype == xEXP) { e2 = 0; - }else{ + } else { e2 = exp; } - nsd = 0; - flag_dp = (precision>0 ?1:0) | flag_alternateform | flag_altform2; + nsd = 0; + flag_dp = (precision > 0 ? 1 : 0) | flag_alternateform | flag_altform2; /* The sign in front of the number */ - if( prefix ){ + if (prefix) { *(bufpt++) = prefix; } /* Digits prior to the decimal point */ - if( e2<0 ){ + if (e2 < 0) { *(bufpt++) = '0'; - }else{ - for(; e2>=0; e2--){ - *(bufpt++) = getdigit(&realvalue,&nsd); + } else { + for (; e2 >= 0; e2--) { + *(bufpt++) = getdigit(&realvalue, &nsd); } } /* The decimal point */ - if( flag_dp ){ + if (flag_dp) { *(bufpt++) = '.'; } /* "0" digits after the decimal point but before the first ** significant digit of the number */ - for(e2++; e2<0; precision--, e2++){ - assert( precision>0 ); + for (e2++; e2 < 0; precision--, e2++) { + assert(precision > 0); *(bufpt++) = '0'; } /* Significant digits after the decimal point */ - while( (precision--)>0 ){ - *(bufpt++) = getdigit(&realvalue,&nsd); + while ((precision--) > 0) { + *(bufpt++) = getdigit(&realvalue, &nsd); } /* Remove trailing zeros and the "." if no digits follow the "." */ - if( flag_rtz && flag_dp ){ - while( bufpt[-1]=='0' ) *(--bufpt) = 0; - assert( bufpt>buf ); - if( bufpt[-1]=='.' ){ + if (flag_rtz && flag_dp) { + while (bufpt[-1] == '0') + *(--bufpt) = 0; + assert(bufpt > buf); + if (bufpt[-1] == '.') { #if 0 /* coverity - dead code - flag_altform2 == 0 here */ if( flag_altform2 ){ *(bufpt++) = '0'; }else #endif - { - *(--bufpt) = 0; - } + { *(--bufpt) = 0; } } } /* Add the "eNNN" suffix */ - if( flag_exp || xtype==xEXP ){ + if (flag_exp || xtype == xEXP) { *(bufpt++) = 'e'; - if( exp<0 ){ - *(bufpt++) = '-'; exp = -exp; - }else{ + if (exp < 0) { + *(bufpt++) = '-'; + exp = -exp; + } else { *(bufpt++) = '+'; } - if( exp>=100 ){ - *(bufpt++) = (char)((exp/100)+'0'); /* 100's digit */ + if (exp >= 100) { + *(bufpt++) = (char)((exp / 100) + '0'); /* 100's digit */ exp %= 100; } - *(bufpt++) = (char)(exp/10+'0'); /* 10's digit */ - *(bufpt++) = (char)(exp%10+'0'); /* 1's digit */ + *(bufpt++) = (char)(exp / 10 + '0'); /* 10's digit */ + *(bufpt++) = (char)(exp % 10 + '0'); /* 1's digit */ } *bufpt = 0; return 0; } - diff --git a/src/misc/dbl.h b/src/misc/dbl.h index fc05259c7..97842ab56 100644 --- a/src/misc/dbl.h +++ b/src/misc/dbl.h @@ -1,5 +1,5 @@ #pragma once -double my_str2double(const char *str, const char **endp); +double my_str2double(const char* str, const char** endp); -int my_double2str(char *buf, size_t bufsize, double realvalue); +int my_double2str(char* buf, size_t bufsize, double realvalue); diff --git a/src/misc/json.c b/src/misc/json.c index 27be48412..59fc525ab 100644 --- a/src/misc/json.c +++ b/src/misc/json.c @@ -26,48 +26,49 @@ #include "dbl.h" #include "tvheadend.h" -#define NOT_THIS_TYPE ((void *)-1) +#define NOT_THIS_TYPE ((void*)-1) -static const char *json_parse_value(const char *s, void *parent, - const char *name, - const json_deserializer_t *jd, - void *opaque, - const char **failp, const char **failmsg); +static const char* json_parse_value(const char* s, + void* parent, + const char* name, + const json_deserializer_t* jd, + void* opaque, + const char** failp, + const char** failmsg); /** * Returns a newly allocated string */ -static char * -json_parse_string(const char *s, const char **endp, - const char **failp, const char **failmsg) -{ - const char *start; - char *r, *a, *b; - int l, esc = 0; +static char* +json_parse_string(const char* s, const char** endp, const char** failp, const char** failmsg) { + const char* start; + char * r, *a, *b; + int l, esc = 0; - while(*s > 0 && *s < 33) + while (*s > 0 && *s < 33) s++; - if(*s != '"') + if (*s != '"') return NOT_THIS_TYPE; s++; start = s; - while(1) { - if(*s == 0) { + while (1) { + if (*s == 0) { *failmsg = "Unexpected end of JSON message"; - *failp = s; + *failp = s; return NULL; } - if(*s == '\\') { + if (*s == '\\') { esc = 1; /* skip the escape */ s++; - if (*s == 'u') s += 4; + if (*s == 'u') + s += 4; // Note: we could detect the lack of support here! - } else if(*s == '"') { + } else if (*s == '"') { *endp = s + 1; @@ -77,61 +78,61 @@ json_parse_string(const char *s, const char **endp, memcpy(r, start, l); r[l] = 0; - if(esc) { - /* Do deescaping inplace */ - - a = b = r; - - while(*a) { - if(*a == '\\') { - a++; - if(*a == 'b') - *b++ = '\b'; - else if(*a == '\\') - *b++ = '\\'; - else if(*a == 'f') - *b++ = '\f'; - else if(*a == 'n') - *b++ = '\n'; - else if(*a == 'r') - *b++ = '\r'; - else if(*a == 't') - *b++ = '\t'; - else if(*a == 'u') { - // Unicode character - int i, v = 0; - - a++; - for(i = 0; i < 4; i++) { - v = v << 4; - switch(a[i]) { - case '0' ... '9': - v |= a[i] - '0'; - break; - case 'a' ... 'f': - v |= a[i] - 'a' + 10; - break; - case 'A' ... 'F': - v |= a[i] - 'F' + 10; - break; - default: - *failmsg = "Incorrect escape sequence"; - *failp = (a - r) + start; - free(r); - return NULL; - } - } - a+=3; - b += put_utf8(b, v); - } else { - *b++ = *a; - } - a++; - } else { - *b++ = *a++; - } - } - *b = 0; + if (esc) { + /* Do deescaping inplace */ + + a = b = r; + + while (*a) { + if (*a == '\\') { + a++; + if (*a == 'b') + *b++ = '\b'; + else if (*a == '\\') + *b++ = '\\'; + else if (*a == 'f') + *b++ = '\f'; + else if (*a == 'n') + *b++ = '\n'; + else if (*a == 'r') + *b++ = '\r'; + else if (*a == 't') + *b++ = '\t'; + else if (*a == 'u') { + // Unicode character + int i, v = 0; + + a++; + for (i = 0; i < 4; i++) { + v = v << 4; + switch (a[i]) { + case '0' ... '9': + v |= a[i] - '0'; + break; + case 'a' ... 'f': + v |= a[i] - 'a' + 10; + break; + case 'A' ... 'F': + v |= a[i] - 'F' + 10; + break; + default: + *failmsg = "Incorrect escape sequence"; + *failp = (a - r) + start; + free(r); + return NULL; + } + } + a += 3; + b += put_utf8(b, v); + } else { + *b++ = *a; + } + a++; + } else { + *b++ = *a++; + } + } + *b = 0; } return r; } @@ -139,80 +140,82 @@ json_parse_string(const char *s, const char **endp, } } - /** * */ -static void * -json_parse_map(const char *s, const char **endp, const json_deserializer_t *jd, - void *opaque, const char **failp, const char **failmsg) +static void* json_parse_map(const char* s, + const char** endp, + const json_deserializer_t* jd, + void* opaque, + const char** failp, + const char** failmsg) { - char *name; - const char *s2; - void *r; + char* name; + const char* s2; + void* r; - while(*s > 0 && *s < 33) + while (*s > 0 && *s < 33) s++; - if(*s != '{') + if (*s != '{') return NOT_THIS_TYPE; s++; r = jd->jd_create_map(opaque); - - while(*s > 0 && *s < 33) + + while (*s > 0 && *s < 33) s++; - if(*s != '}') { + if (*s != '}') { - while(1) { + while (1) { name = json_parse_string(s, &s2, failp, failmsg); - if(name == NOT_THIS_TYPE) { - *failmsg = "Expected string"; - *failp = s; - return NULL; + if (name == NOT_THIS_TYPE) { + *failmsg = "Expected string"; + *failp = s; + return NULL; } - if(name == NULL) - return NULL; + if (name == NULL) + return NULL; s = s2; - - while(*s > 0 && *s < 33) - s++; - - if(*s != ':') { - jd->jd_destroy_obj(opaque, r); - free(name); - *failmsg = "Expected ':'"; - *failp = s; - return NULL; + + while (*s > 0 && *s < 33) + s++; + + if (*s != ':') { + jd->jd_destroy_obj(opaque, r); + free(name); + *failmsg = "Expected ':'"; + *failp = s; + return NULL; } s++; s2 = json_parse_value(s, r, name, jd, opaque, failp, failmsg); free(name); - if(s2 == NULL) { - jd->jd_destroy_obj(opaque, r); - return NULL; + if (s2 == NULL) { + jd->jd_destroy_obj(opaque, r); + return NULL; } s = s2; - while(*s > 0 && *s < 33) - s++; + while (*s > 0 && *s < 33) + s++; - if(*s == '}') - break; + if (*s == '}') + break; - if(*s != ',') { - jd->jd_destroy_obj(opaque, r); - *failmsg = "Expected ','"; - *failp = s; - return NULL; + if (*s != ',') { + jd->jd_destroy_obj(opaque, r); + *failmsg = "Expected ','"; + *failp = s; + return NULL; } s++; } @@ -223,54 +226,55 @@ json_parse_map(const char *s, const char **endp, const json_deserializer_t *jd, return r; } - /** * */ -static void * -json_parse_list(const char *s, const char **endp, const json_deserializer_t *jd, - void *opaque, const char **failp, const char **failmsg) -{ - const char *s2; - void *r; - - while(*s > 0 && *s < 33) +static void* json_parse_list(const char* s, + const char** endp, + const json_deserializer_t* jd, + void* opaque, + const char** failp, + const char** failmsg) { + const char* s2; + void* r; + + while (*s > 0 && *s < 33) s++; - if(*s != '[') + if (*s != '[') return NOT_THIS_TYPE; s++; r = jd->jd_create_list(opaque); - - while(*s > 0 && *s < 33) + + while (*s > 0 && *s < 33) s++; - if(*s != ']') { + if (*s != ']') { - while(1) { + while (1) { s2 = json_parse_value(s, r, NULL, jd, opaque, failp, failmsg); - if(s2 == NULL) { - jd->jd_destroy_obj(opaque, r); - return NULL; + if (s2 == NULL) { + jd->jd_destroy_obj(opaque, r); + return NULL; } s = s2; - while(*s > 0 && *s < 33) - s++; + while (*s > 0 && *s < 33) + s++; - if(*s == ']') - break; + if (*s == ']') + break; - if(*s != ',') { - jd->jd_destroy_obj(opaque, r); - *failmsg = "Expected ','"; - *failp = s; - return NULL; + if (*s != ',') { + jd->jd_destroy_obj(opaque, r); + *failmsg = "Expected ','"; + *failp = s; + return NULL; } s++; } @@ -283,48 +287,43 @@ json_parse_list(const char *s, const char **endp, const json_deserializer_t *jd, /** * */ -static const char * -json_parse_double(const char *s, double *dp) -{ - const char *ep; - while(*s > 0 && *s < 33) +static const char* json_parse_double(const char* s, double* dp) { + const char* ep; + while (*s > 0 && *s < 33) s++; double d = my_str2double(s, &ep); - if(ep == s) + if (ep == s) return NULL; *dp = d; return ep; } - /** * */ -static char * -json_parse_integer(const char *s, int64_t *lp) -{ - char *ep; - while(*s > 0 && *s < 33) +static char* json_parse_integer(const char* s, int64_t* lp) { + char* ep; + while (*s > 0 && *s < 33) s++; - const char *s2 = s; - if(*s2 == '-') + const char* s2 = s; + if (*s2 == '-') s2++; - while(*s2 >= '0' && *s2 <= '9') + while (*s2 >= '0' && *s2 <= '9') s2++; - if(*s2 == 0) + if (*s2 == 0) return NULL; - if(s2[0] == '.' || s2[0] == 'e' || s2[0] == 'E') + if (s2[0] == '.' || s2[0] == 'e' || s2[0] == 'E') return NULL; // Is floating point int64_t v = strtoll(s, &ep, 10); - if(v == INT64_MIN || v == INT64_MAX) + if (v == INT64_MIN || v == INT64_MAX) return NULL; - if(ep == s) + if (ep == s) return NULL; *lp = v; @@ -334,105 +333,106 @@ json_parse_integer(const char *s, int64_t *lp) /** * */ -static const char * -json_parse_value(const char *s, void *parent, const char *name, - const json_deserializer_t *jd, void *opaque, - const char **failp, const char **failmsg) -{ - const char *s2; - char *str; - double d = 0; - int64_t s64 = 0; - void *c; - - if((c = json_parse_map(s, &s2, jd, opaque, failp, failmsg)) == NULL) +static const char* json_parse_value(const char* s, + void* parent, + const char* name, + const json_deserializer_t* jd, + void* opaque, + const char** failp, + const char** failmsg) { + const char* s2; + char* str; + double d = 0; + int64_t s64 = 0; + void* c; + + if ((c = json_parse_map(s, &s2, jd, opaque, failp, failmsg)) == NULL) return NULL; - if(c != NOT_THIS_TYPE) { + if (c != NOT_THIS_TYPE) { jd->jd_add_obj(opaque, parent, name, c); return s2; } - if((c = json_parse_list(s, &s2, jd, opaque, failp, failmsg)) == NULL) + if ((c = json_parse_list(s, &s2, jd, opaque, failp, failmsg)) == NULL) return NULL; - - if(c != NOT_THIS_TYPE) { + + if (c != NOT_THIS_TYPE) { jd->jd_add_obj(opaque, parent, name, c); return s2; } - if((str = json_parse_string(s, &s2, failp, failmsg)) == NULL) + if ((str = json_parse_string(s, &s2, failp, failmsg)) == NULL) return NULL; - if(str != NOT_THIS_TYPE) { + if (str != NOT_THIS_TYPE) { jd->jd_add_string(opaque, parent, name, str); return s2; } - if((s2 = json_parse_integer(s, &s64)) != NULL) { + if ((s2 = json_parse_integer(s, &s64)) != NULL) { jd->jd_add_s64(opaque, parent, name, s64); return s2; - } else if((s2 = json_parse_double(s, &d)) != NULL) { + } else if ((s2 = json_parse_double(s, &d)) != NULL) { jd->jd_add_double(opaque, parent, name, d); return s2; } - while(*s > 0 && *s < 33) + while (*s > 0 && *s < 33) s++; - if(!strncmp(s, "true", 4)) { + if (!strncmp(s, "true", 4)) { jd->jd_add_bool(opaque, parent, name, 1); return s + 4; } - if(!strncmp(s, "false", 5)) { + if (!strncmp(s, "false", 5)) { jd->jd_add_bool(opaque, parent, name, 0); return s + 5; } - if(!strncmp(s, "null", 4)) { + if (!strncmp(s, "null", 4)) { jd->jd_add_null(opaque, parent, name); return s + 4; } *failmsg = "Unknown token"; - *failp = s; + *failp = s; return NULL; } - /** * */ -void * -json_deserialize(const char *src, const json_deserializer_t *jd, void *opaque, - char *errbuf, size_t errlen) -{ - const char *end; - void *c; - const char *errmsg; - const char *errp; +void* json_deserialize(const char* src, + const json_deserializer_t* jd, + void* opaque, + char* errbuf, + size_t errlen) { + const char* end; + void* c; + const char* errmsg; + const char* errp; c = json_parse_map(src, &end, jd, opaque, &errp, &errmsg); - if(c == NOT_THIS_TYPE) + if (c == NOT_THIS_TYPE) c = json_parse_list(src, &end, jd, opaque, &errp, &errmsg); - if(c == NOT_THIS_TYPE) { + if (c == NOT_THIS_TYPE) { snprintf(errbuf, errlen, "Invalid JSON, expected '{' or '['"); return NULL; } - if(c == NULL) { - size_t len = strlen(src); + if (c == NULL) { + size_t len = strlen(src); ssize_t offset = errp - src; - if(offset > len || offset < 0) { + if (offset > len || offset < 0) { snprintf(errbuf, errlen, "%s at (bad) offset %d", errmsg, (int)offset); } else { offset -= 10; - if(offset < 0) - offset = 0; - snprintf(errbuf, errlen, "%s at offset %d : '%.20s'", errmsg, (int)offset, - src + offset); + if (offset < 0) + offset = 0; + snprintf(errbuf, errlen, "%s at offset %d : '%.20s'", errmsg, (int)offset, src + offset); } } return c; diff --git a/src/misc/json.h b/src/misc/json.h index f96436991..473a58842 100644 --- a/src/misc/json.h +++ b/src/misc/json.h @@ -2,31 +2,28 @@ #include typedef struct json_deserializer { - void *(*jd_create_map)(void *jd_opaque); - void *(*jd_create_list)(void *jd_opaque); + void* (*jd_create_map)(void* jd_opaque); + void* (*jd_create_list)(void* jd_opaque); - void (*jd_destroy_obj)(void *jd_opaque, void *obj); + void (*jd_destroy_obj)(void* jd_opaque, void* obj); - void (*jd_add_obj)(void *jd_opaque, void *parent, - const char *name, void *child); + void (*jd_add_obj)(void* jd_opaque, void* parent, const char* name, void* child); // str must be free'd by callee - void (*jd_add_string)(void *jd_opaque, void *parent, - const char *name, char *str); + void (*jd_add_string)(void* jd_opaque, void* parent, const char* name, char* str); - void (*jd_add_s64)(void *jd_opaque, void *parent, - const char *name, int64_t v); + void (*jd_add_s64)(void* jd_opaque, void* parent, const char* name, int64_t v); - void (*jd_add_double)(void *jd_opaque, void *parent, - const char *name, double d); + void (*jd_add_double)(void* jd_opaque, void* parent, const char* name, double d); - void (*jd_add_bool)(void *jd_opaque, void *parent, - const char *name, int v); + void (*jd_add_bool)(void* jd_opaque, void* parent, const char* name, int v); - void (*jd_add_null)(void *jd_opaque, void *parent, - const char *name); + void (*jd_add_null)(void* jd_opaque, void* parent, const char* name); } json_deserializer_t; -void *json_deserialize(const char *src, const json_deserializer_t *jd, - void *opaque, char *errbuf, size_t errlen); +void* json_deserialize(const char* src, + const json_deserializer_t* jd, + void* opaque, + char* errbuf, + size_t errlen); diff --git a/src/misc/m3u.c b/src/misc/m3u.c index cc5dc48e6..8174d1d28 100644 --- a/src/misc/m3u.c +++ b/src/misc/m3u.c @@ -24,12 +24,12 @@ /* * */ -static char *get_m3u_str(char *data, char **res, int *last) -{ +static char* get_m3u_str(char* data, char** res, int* last) { char *p = data, first = *data; if (first == '"' || first == '\'') { - data++; p++; + data++; + p++; while (*data && *data != first && *data != '\n' && *data != '\r') data++; if (*data == first) { @@ -52,8 +52,7 @@ static char *get_m3u_str(char *data, char **res, int *last) /* * */ -static void get_m3u_str_post(char **data, int delim) -{ +static void get_m3u_str_post(char** data, int delim) { if (delim == '\n' || delim == '\r') { (*data)--; **data = delim; @@ -63,38 +62,47 @@ static void get_m3u_str_post(char **data, int delim) /* * */ -static char *until_eol(char *d) -{ - while (*d && *d != '\r' && *d != '\n') d++; - if (*d) { *d = '\0'; d++; } - while (*d && (*d == '\r' || *d == '\n')) d++; +static char* until_eol(char* d) { + while (*d && *d != '\r' && *d != '\n') + d++; + if (*d) { + *d = '\0'; + d++; + } + while (*d && (*d == '\r' || *d == '\n')) + d++; return d; } /* * */ -static int is_full_url(const char *url) -{ - if (strncmp(url, "file://", 7) == 0) return 7; - if (strncmp(url, "pipe://", 7) == 0) return 7; - if (strncmp(url, "http://", 7) == 0) return 7; - if (strncmp(url, "https://", 8) == 0) return 8; - if (strncmp(url, "rtsp://", 7) == 0) return 7; - if (strncmp(url, "rtsps://", 8) == 0) return 8; - if (strncmp(url, "udp://", 6) == 0) return 6; - if (strncmp(url, "rtp://", 6) == 0) return 6; +static int is_full_url(const char* url) { + if (strncmp(url, "file://", 7) == 0) + return 7; + if (strncmp(url, "pipe://", 7) == 0) + return 7; + if (strncmp(url, "http://", 7) == 0) + return 7; + if (strncmp(url, "https://", 8) == 0) + return 8; + if (strncmp(url, "rtsp://", 7) == 0) + return 7; + if (strncmp(url, "rtsps://", 8) == 0) + return 8; + if (strncmp(url, "udp://", 6) == 0) + return 6; + if (strncmp(url, "rtp://", 6) == 0) + return 6; return 0; } /* * */ -static const char *get_url - (char *buf, size_t buflen, const char *rel, const char *url) -{ +static const char* get_url(char* buf, size_t buflen, const char* rel, const char* url) { char *url2, *p; - int l; + int l; if (url == NULL) return rel; @@ -120,19 +128,18 @@ static const char *get_url /* * Note: text in data pointer is not preserved (must be read/write) */ -htsmsg_t *parse_m3u - (char *data, const char *charset, const char *url) -{ - char *p, *x, *y; - char *charset_id = intlconv_charset_id(charset, 0, 1); - const char *multi_name; - int delim; - htsmsg_t *m = htsmsg_create_map(); - htsmsg_t *item = NULL, *l = NULL, *t, *key = NULL; - char buf[512]; +htsmsg_t* parse_m3u(char* data, const char* charset, const char* url) { + char * p, *x, *y; + char* charset_id = intlconv_charset_id(charset, 0, 1); + const char* multi_name; + int delim; + htsmsg_t* m = htsmsg_create_map(); + htsmsg_t * item = NULL, *l = NULL, *t, *key = NULL; + char buf[512]; - while (*data && *data <= ' ') data++; - p = data; + while (*data && *data <= ' ') + data++; + p = data; data = until_eol(data); if (strncmp(p, "#EXTM3U", 7)) { htsmsg_add_msg(m, "items", htsmsg_create_list()); @@ -144,23 +151,29 @@ htsmsg_t *parse_m3u item = htsmsg_create_map(); data += 8; p = data; - if (*data == '-') data++; - while (*data >= '0' && *data <= '9') data++; + if (*data == '-') + data++; + while (*data >= '0' && *data <= '9') + data++; delim = *data; *data = '\0'; htsmsg_add_s64(item, "m3u-duration", strtoll(p, NULL, 10)); *data = delim; - while (*data > ' ' && *data != ',') data++; + while (*data > ' ' && *data != ',') + data++; while (delim && delim != ',' && delim != '\n' && delim != '\r') { - while (*data && *data <= ' ') data++; - if (*data == '\0' || *data == ',') break; + while (*data && *data <= ' ') + data++; + if (*data == '\0' || *data == ',') + break; p = data++; - while (*data && *data != ',' && *data != '=') data++; + while (*data && *data != ',' && *data != '=') + data++; if (*data == '=') { *data = '\0'; - x = get_m3u_str(data + 1, &data, &delim); + x = get_m3u_str(data + 1, &data, &delim); if (*p && *x) { - y = intlconv_to_utf8safestr(charset_id, x, strlen(x)*2); + y = intlconv_to_utf8safestr(charset_id, x, strlen(x) * 2); htsmsg_add_str(item, p, y ?: ".invalid.charset."); free(y); } @@ -173,13 +186,14 @@ htsmsg_t *parse_m3u data++; } if (delim == ',') { - while (*data && *data <= ' ' && *data != '\n' && *data != '\r') data++; + while (*data && *data <= ' ' && *data != '\n' && *data != '\r') + data++; if (*data) p = data; } data = until_eol(data); if (p && *p) { - y = intlconv_to_utf8safestr(charset_id, p, strlen(p)*2); + y = intlconv_to_utf8safestr(charset_id, p, strlen(p) * 2); htsmsg_add_str(item, "m3u-name", y ?: ".invalid.charset."); free(y); } @@ -199,22 +213,26 @@ htsmsg_t *parse_m3u } else if (strncmp(data, "#EXT-X-STREAM-INF:", 18) == 0) { data += 18; multi_name = "stream-inf"; -multi: - t = htsmsg_create_map(); + multi: + t = htsmsg_create_map(); delim = 0; while (*data && delim != '\n' && delim != '\r') { - while (*data && *data <= ' ') data++; + while (*data && *data <= ' ') + data++; p = data; - while (*data && *data >= ' ' && *data != '=') data++; + while (*data && *data >= ' ' && *data != '=') + data++; if (*data == '=') { *data = '\0'; - x = get_m3u_str(data + 1, &data, &delim); + x = get_m3u_str(data + 1, &data, &delim); if (*x && *p) htsmsg_add_str(t, p, x); get_m3u_str_post(&data, delim); } else { - while (*data && *data <= ' ' && *data != '\n' && *data != '\r') data++; - if (*data != ',') break; + while (*data && *data <= ' ' && *data != '\n' && *data != '\r') + data++; + if (*data != ',') + break; } } if (strcmp(multi_name, "x-key") == 0) { @@ -248,26 +266,36 @@ multi: data = until_eol(data + 4); continue; } - while (*data && *data <= ' ') data++; - p = data; + while (*data && *data <= ' ') + data++; + p = data; data = until_eol(data); if (*p == '#') continue; if (*p && *p > ' ') { if (item == NULL) item = htsmsg_create_map(); - if (strncmp(p, "http://", 7) == 0 || - strncmp(p, "https://", 8) == 0) { + if (strncmp(p, "http://", 7) == 0 || strncmp(p, "https://", 8) == 0) { delim = 0; - x = p; - while (*x && *x != ' ' && *x != '|') x++; - if (*x) { delim = *x; *x = '\0'; x++; } + x = p; + while (*x && *x != ' ' && *x != '|') + x++; + if (*x) { + delim = *x; + *x = '\0'; + x++; + } t = NULL; while (*x) { - while (*x && *x <= ' ') x++; + while (*x && *x <= ' ') + x++; y = x; - while (*x && *x != delim && *x != '&') x++; - if (*x) { *x = '\0'; x++; } + while (*x && *x != delim && *x != '&') + x++; + if (*x) { + *x = '\0'; + x++; + } if (*y) { if (t == NULL) t = htsmsg_create_list(); diff --git a/src/misc/m3u.h b/src/misc/m3u.h index 8192138df..9037aebc6 100644 --- a/src/misc/m3u.h +++ b/src/misc/m3u.h @@ -1,3 +1,3 @@ #pragma once -htsmsg_t *parse_m3u(char *data, const char *charset, const char *url); +htsmsg_t* parse_m3u(char* data, const char* charset, const char* url); diff --git a/src/muxer.c b/src/muxer.c index 81b9cea4c..af5f6a67e 100644 --- a/src/muxer.c +++ b/src/muxer.c @@ -32,9 +32,9 @@ /* Newer platforms such as FreeBSD 11.1 support fdatasync so only alias on older systems */ #ifndef CONFIG_FDATASYNC #if defined(PLATFORM_DARWIN) -#define fdatasync(fd) fcntl(fd, F_FULLFSYNC) +#define fdatasync(fd) fcntl(fd, F_FULLFSYNC) #elif defined(PLATFORM_FREEBSD) -#define fdatasync(fd) fsync(fd) +#define fdatasync(fd) fsync(fd) #endif #endif @@ -42,141 +42,131 @@ * Mime type for containers containing only audio */ static struct strtab container_audio_mime[] = { - { "application/octet-stream", MC_UNKNOWN }, - { "audio/x-matroska", MC_MATROSKA }, - { "audio/x-matroska", MC_AVMATROSKA }, - { "audio/webm", MC_WEBM }, - { "audio/webm", MC_AVWEBM }, - { "audio/mp2t", MC_MPEGTS }, - { "audio/mpeg", MC_MPEGPS }, - { "audio/mpeg", MC_MPEG2AUDIO }, - { "audio/ac3", MC_AC3 }, - { "audio/ac4", MC_AC4 }, - { "audio/aac", MC_AAC }, - { "audio/aac", MC_MP4A }, - { "audio/ogg", MC_VORBIS }, - { "audio/mp4", MC_AVMP4 }, - { "application/octet-stream", MC_PASS }, - { "application/octet-stream", MC_RAW }, + {"application/octet-stream", MC_UNKNOWN}, + {"audio/x-matroska", MC_MATROSKA}, + {"audio/x-matroska", MC_AVMATROSKA}, + {"audio/webm", MC_WEBM}, + {"audio/webm", MC_AVWEBM}, + {"audio/mp2t", MC_MPEGTS}, + {"audio/mpeg", MC_MPEGPS}, + {"audio/mpeg", MC_MPEG2AUDIO}, + {"audio/ac3", MC_AC3}, + {"audio/ac4", MC_AC4}, + {"audio/aac", MC_AAC}, + {"audio/aac", MC_MP4A}, + {"audio/ogg", MC_VORBIS}, + {"audio/mp4", MC_AVMP4}, + {"application/octet-stream", MC_PASS}, + {"application/octet-stream", MC_RAW}, }; - /** * Mime type for containers */ static struct strtab container_video_mime[] = { - { "application/octet-stream", MC_UNKNOWN }, - { "video/x-matroska", MC_MATROSKA }, - { "video/x-matroska", MC_AVMATROSKA }, - { "video/webm", MC_WEBM }, - { "video/webm", MC_AVWEBM }, - { "video/mp2t", MC_MPEGTS }, - { "video/mpeg", MC_MPEGPS }, - { "video/mp4", MC_AVMP4 }, - { "application/octet-stream", MC_PASS }, - { "application/octet-stream", MC_RAW }, + {"application/octet-stream", MC_UNKNOWN}, + {"video/x-matroska", MC_MATROSKA}, + {"video/x-matroska", MC_AVMATROSKA}, + {"video/webm", MC_WEBM}, + {"video/webm", MC_AVWEBM}, + {"video/mp2t", MC_MPEGTS}, + {"video/mpeg", MC_MPEGPS}, + {"video/mp4", MC_AVMP4}, + {"application/octet-stream", MC_PASS}, + {"application/octet-stream", MC_RAW}, }; - /** * Name of the container */ static struct strtab container_name[] = { - { "unknown", MC_UNKNOWN }, - { "matroska", MC_MATROSKA }, - { "webm", MC_WEBM }, - { "mpegts", MC_MPEGTS }, - { "mpegps", MC_MPEGPS }, - { "pass", MC_PASS }, - { "raw", MC_RAW }, - { "avmatroska", MC_AVMATROSKA }, - { "avwebm", MC_AVWEBM }, - { "avmp4", MC_AVMP4 }, - { "mp2", MC_MPEG2AUDIO }, - { "ac3", MC_AC3 }, - { "aac", MC_AAC }, - { "mp4a", MC_MP4A }, - { "oga", MC_VORBIS }, - { "ac4", MC_AC4 }, + {"unknown", MC_UNKNOWN}, + {"matroska", MC_MATROSKA}, + {"webm", MC_WEBM}, + {"mpegts", MC_MPEGTS}, + {"mpegps", MC_MPEGPS}, + {"pass", MC_PASS}, + {"raw", MC_RAW}, + {"avmatroska", MC_AVMATROSKA}, + {"avwebm", MC_AVWEBM}, + {"avmp4", MC_AVMP4}, + {"mp2", MC_MPEG2AUDIO}, + {"ac3", MC_AC3}, + {"aac", MC_AAC}, + {"mp4a", MC_MP4A}, + {"oga", MC_VORBIS}, + {"ac4", MC_AC4}, }; - /** * filename suffix of audio-only streams */ static struct strtab container_audio_file_suffix[] = { - { "bin", MC_UNKNOWN }, - { "mka", MC_MATROSKA }, - { "webm", MC_WEBM }, - { "ts", MC_MPEGTS }, - { "mpeg", MC_MPEGPS }, - { "bin", MC_PASS }, - { "bin", MC_RAW }, - { "mka", MC_AVMATROSKA }, - { "webm", MC_AVWEBM }, - { "mp4", MC_AVMP4 }, - { "mp2", MC_MPEG2AUDIO }, - { "ac3", MC_AC3 }, - { "aac", MC_AAC }, - { "mp4a", MC_MP4A }, - { "oga", MC_VORBIS }, - { "ac4", MC_AC4 }, + {"bin", MC_UNKNOWN}, + {"mka", MC_MATROSKA}, + {"webm", MC_WEBM}, + {"ts", MC_MPEGTS}, + {"mpeg", MC_MPEGPS}, + {"bin", MC_PASS}, + {"bin", MC_RAW}, + {"mka", MC_AVMATROSKA}, + {"webm", MC_AVWEBM}, + {"mp4", MC_AVMP4}, + {"mp2", MC_MPEG2AUDIO}, + {"ac3", MC_AC3}, + {"aac", MC_AAC}, + {"mp4a", MC_MP4A}, + {"oga", MC_VORBIS}, + {"ac4", MC_AC4}, }; - /** * filename suffix of video streams */ static struct strtab container_video_file_suffix[] = { - { "bin", MC_UNKNOWN }, - { "mkv", MC_MATROSKA }, - { "webm", MC_WEBM }, - { "ts", MC_MPEGTS }, - { "mpeg", MC_MPEGPS }, - { "bin", MC_PASS }, - { "bin", MC_RAW }, - { "mkv", MC_AVMATROSKA }, - { "webm", MC_AVWEBM }, - { "mp4", MC_AVMP4 }, + {"bin", MC_UNKNOWN}, + {"mkv", MC_MATROSKA}, + {"webm", MC_WEBM}, + {"ts", MC_MPEGTS}, + {"mpeg", MC_MPEGPS}, + {"bin", MC_PASS}, + {"bin", MC_RAW}, + {"mkv", MC_AVMATROSKA}, + {"webm", MC_AVWEBM}, + {"mp4", MC_AVMP4}, }; - /** * Get the mime type for a container */ -const char* -muxer_container_type2mime(muxer_container_type_t mc, int video) -{ - const char *str; +const char* muxer_container_type2mime(muxer_container_type_t mc, int video) { + const char* str; - if(video) + if (video) str = val2str(mc, container_video_mime); else str = val2str(mc, container_audio_mime); - if(!str) + if (!str) str = val2str(MC_UNKNOWN, container_video_mime); return str; } - /** * Get the mime type for a filename */ -const char* -muxer_container_filename2mime(const char *filename, int video) -{ - int mc = MC_UNKNOWN; - const char *suffix; - - if(filename) { +const char* muxer_container_filename2mime(const char* filename, int video) { + int mc = MC_UNKNOWN; + const char* suffix; + + if (filename) { suffix = strrchr(filename, '.'); if (suffix == NULL) suffix = filename; else suffix++; - if(video) + if (video) mc = str2val(suffix, container_video_file_suffix); else mc = str2val(suffix, container_audio_file_suffix); @@ -185,89 +175,74 @@ muxer_container_filename2mime(const char *filename, int video) return muxer_container_type2mime(mc, 1); } - /** * Get the suffix used in file names */ -const char* -muxer_container_suffix(muxer_container_type_t mc, int video) -{ - const char *str; - if(video) +const char* muxer_container_suffix(muxer_container_type_t mc, int video) { + const char* str; + if (video) str = val2str(mc, container_video_file_suffix); else str = val2str(mc, container_audio_file_suffix); - if(!str) + if (!str) str = val2str(MC_UNKNOWN, container_video_file_suffix); return str; } - /** * Convert a container type to a string */ -const char* -muxer_container_type2txt(muxer_container_type_t mc) -{ - const char *str; +const char* muxer_container_type2txt(muxer_container_type_t mc) { + const char* str; str = val2str(mc, container_name); - if(!str) + if (!str) return "unknown"; - + return str; } - /** * Convert a container name to a container type */ -muxer_container_type_t -muxer_container_txt2type(const char *str) -{ +muxer_container_type_t muxer_container_txt2type(const char* str) { muxer_container_type_t mc; - - if(!str) + + if (!str) return MC_UNKNOWN; mc = str2val(str, container_name); - if(mc == -1) + if (mc == -1) return MC_UNKNOWN; return mc; } - /** * Convert a mime-string to a container type */ -muxer_container_type_t -muxer_container_mime2type(const char *str) -{ +muxer_container_type_t muxer_container_mime2type(const char* str) { muxer_container_type_t mc; - if(!str) + if (!str) return MC_UNKNOWN; mc = str2val(str, container_video_mime); - if(mc == -1) + if (mc == -1) mc = str2val(str, container_audio_mime); - if(mc == -1) + if (mc == -1) return MC_UNKNOWN; return mc; } - /** * Copy muxer settings */ -void -muxer_config_copy(muxer_config_t *dst, const muxer_config_t *src) -{ +void muxer_config_copy(muxer_config_t* dst, const muxer_config_t* src) { *dst = *src; if (src->m_type == MC_RAW || src->m_type == MC_PASS) { mystrset(&dst->u.pass.m_cmdline, src->u.pass.m_cmdline); @@ -275,13 +250,10 @@ muxer_config_copy(muxer_config_t *dst, const muxer_config_t *src) } } - /** * Free muxer settings */ -void -muxer_config_free(muxer_config_t *m_cfg) -{ +void muxer_config_free(muxer_config_t* m_cfg) { if (m_cfg->m_type == MC_RAW || m_cfg->m_type == MC_PASS) { free(m_cfg->u.pass.m_cmdline); free(m_cfg->u.pass.m_mime); @@ -289,61 +261,53 @@ muxer_config_free(muxer_config_t *m_cfg) memset(m_cfg, 0, sizeof(*m_cfg)); } - /** * Create muxer hints */ -muxer_hints_t * -muxer_hints_create(const char *agent) -{ - muxer_hints_t *hints = calloc(1, sizeof(*hints)); +muxer_hints_t* muxer_hints_create(const char* agent) { + muxer_hints_t* hints = calloc(1, sizeof(*hints)); mystrset(&hints->mh_agent, agent); return hints; } - /** * Free muxer hints */ -void -muxer_hints_free(muxer_hints_t *hints) -{ +void muxer_hints_free(muxer_hints_t* hints) { if (hints) free(hints->mh_agent); free(hints); } - /** * Create a new muxer */ -muxer_t* -muxer_create(muxer_config_t *m_cfg, muxer_hints_t *hints) -{ - muxer_t *m; +muxer_t* muxer_create(muxer_config_t* m_cfg, muxer_hints_t* hints) { + muxer_t* m; assert(m_cfg); m = pass_muxer_create(m_cfg, hints); - if(!m) + if (!m) m = mkv_muxer_create(m_cfg, hints); - if(!m) + if (!m) m = audioes_muxer_create(m_cfg, hints); #if CONFIG_LIBAV - if(!m) + if (!m) m = lav_muxer_create(m_cfg, hints); #endif - if(!m) { - tvherror(LS_MUXER, "Can't find a muxer that supports '%s' container", - muxer_container_type2txt(m_cfg->m_type)); + if (!m) { + tvherror(LS_MUXER, + "Can't find a muxer that supports '%s' container", + muxer_container_type2txt(m_cfg->m_type)); muxer_hints_free(hints); return NULL; } - + memcpy(&m->m_config, m_cfg, sizeof(muxer_config_t)); memset(m_cfg, 0, sizeof(*m_cfg)); m->m_hints = hints; @@ -354,19 +318,17 @@ muxer_create(muxer_config_t *m_cfg, muxer_hints_t *hints) /** * Figure out the file suffix by looking at the mime type */ -const char* -muxer_suffix(muxer_t *m, const struct streaming_start *ss) -{ - const char *mime; +const char* muxer_suffix(muxer_t* m, const struct streaming_start* ss) { + const char* mime; muxer_container_type_t mc; - int video; + int video; - if(!m || !ss) + if (!m || !ss) return NULL; mime = m->m_mime(m, ss); video = memcmp("audio", mime, 5); - mc = muxer_container_mime2type(mime); + mc = muxer_container_mime2type(mime); return muxer_container_suffix(mc, video); } @@ -374,23 +336,17 @@ muxer_suffix(muxer_t *m, const struct streaming_start *ss) /** * cache type conversions */ -static struct strtab cache_types[] = { - { "Unknown", MC_CACHE_UNKNOWN }, - { "System", MC_CACHE_SYSTEM }, - { "Do not keep", MC_CACHE_DONTKEEP }, - { "Sync", MC_CACHE_SYNC }, - { "Sync + Do not keep", MC_CACHE_SYNCDONTKEEP } -}; +static struct strtab cache_types[] = {{"Unknown", MC_CACHE_UNKNOWN}, + {"System", MC_CACHE_SYSTEM}, + {"Do not keep", MC_CACHE_DONTKEEP}, + {"Sync", MC_CACHE_SYNC}, + {"Sync + Do not keep", MC_CACHE_SYNCDONTKEEP}}; -const char* -muxer_cache_type2txt(muxer_cache_type_t c) -{ +const char* muxer_cache_type2txt(muxer_cache_type_t c) { return val2str(c, cache_types); } -muxer_cache_type_t -muxer_cache_txt2type(const char *str) -{ +muxer_cache_type_t muxer_cache_txt2type(const char* str) { int r = str2val(str, cache_types); if (r < 0) r = MC_CACHE_UNKNOWN; @@ -400,45 +356,41 @@ muxer_cache_txt2type(const char *str) /** * cache scheme */ -void -muxer_cache_update(muxer_t *m, int fd, off_t pos, size_t size) -{ +void muxer_cache_update(muxer_t* m, int fd, off_t pos, size_t size) { switch (m->m_config.m_cache) { - case MC_CACHE_UNKNOWN: - case MC_CACHE_SYSTEM: - break; - case MC_CACHE_SYNC: - fdatasync(fd); - break; - case MC_CACHE_SYNCDONTKEEP: - fdatasync(fd); - /* fall through */ - case MC_CACHE_DONTKEEP: + case MC_CACHE_UNKNOWN: + case MC_CACHE_SYSTEM: + break; + case MC_CACHE_SYNC: + fdatasync(fd); + break; + case MC_CACHE_SYNCDONTKEEP: + fdatasync(fd); + /* fall through */ + case MC_CACHE_DONTKEEP: #if defined(PLATFORM_DARWIN) - fcntl(fd, F_NOCACHE, 1); + fcntl(fd, F_NOCACHE, 1); #elif !ENABLE_ANDROID - posix_fadvise(fd, pos, size, POSIX_FADV_DONTNEED); + posix_fadvise(fd, pos, size, POSIX_FADV_DONTNEED); #endif - break; - default: - abort(); + break; + default: + abort(); } } /** * Get a list of supported cache schemes */ -int -muxer_cache_list(htsmsg_t *array) -{ - htsmsg_t *mc; - int c; - const char *s; +int muxer_cache_list(htsmsg_t* array) { + htsmsg_t* mc; + int c; + const char* s; for (c = 0; c <= MC_CACHE_LAST; c++) { mc = htsmsg_create_map(); - s = muxer_cache_type2txt(c); - htsmsg_add_u32(mc, "index", c); + s = muxer_cache_type2txt(c); + htsmsg_add_u32(mc, "index", c); htsmsg_add_str(mc, "description", s); htsmsg_add_msg(array, NULL, mc); } diff --git a/src/muxer.h b/src/muxer.h index 7cf591f96..a15151b57 100644 --- a/src/muxer.h +++ b/src/muxer.h @@ -24,25 +24,25 @@ #define MC_IS_EOS_ERROR(e) ((e) == EPIPE || (e) == ECONNRESET) -#define MC_CAP_ANOTHER_SERVICE (1<<0) /* I can stream another service (SID must match!) */ +#define MC_CAP_ANOTHER_SERVICE (1 << 0) /* I can stream another service (SID must match!) */ typedef enum { - MC_UNKNOWN = 0, - MC_MATROSKA = 1, - MC_MPEGTS = 2, - MC_MPEGPS = 3, - MC_PASS = 4, - MC_RAW = 5, - MC_WEBM = 6, - MC_AVMATROSKA = 7, - MC_AVWEBM = 8, - MC_AVMP4 = 9, - MC_MPEG2AUDIO = 10, - MC_AC3 = 11, - MC_AAC = 12, - MC_MP4A = 13, - MC_VORBIS = 14, - MC_AC4 = 15 + MC_UNKNOWN = 0, + MC_MATROSKA = 1, + MC_MPEGTS = 2, + MC_MPEGPS = 3, + MC_PASS = 4, + MC_RAW = 5, + MC_WEBM = 6, + MC_AVMATROSKA = 7, + MC_AVWEBM = 8, + MC_AVMP4 = 9, + MC_MPEG2AUDIO = 10, + MC_AC3 = 11, + MC_AAC = 12, + MC_MP4A = 13, + MC_VORBIS = 14, + MC_AC4 = 15 } muxer_container_type_t; typedef enum { @@ -56,45 +56,45 @@ typedef enum { /* Muxer configuration used when creating a muxer. */ typedef struct muxer_config { - int m_type; /* MC_* */ - int m_cache; + int m_type; /* MC_* */ + int m_cache; /* * directory_permissions should really be in dvr.h as it's not really * needed for the muxer, but it's kept with file_permissions for neatness */ - int m_file_permissions; - int m_directory_permissions; - int m_output_chunk; /* > 0 if muxer output needs writing in chunks */ + int m_file_permissions; + int m_directory_permissions; + int m_output_chunk; /* > 0 if muxer output needs writing in chunks */ /* * type specific section */ union { struct { - int m_rewrite_sid; - int m_rewrite_pat; - int m_rewrite_pmt; - int m_rewrite_sdt; - int m_rewrite_nit; - int m_rewrite_eit; - char *m_cmdline; - char *m_mime; - int m_killsig; - int m_killtimeout; + int m_rewrite_sid; + int m_rewrite_pat; + int m_rewrite_pmt; + int m_rewrite_sdt; + int m_rewrite_nit; + int m_rewrite_eit; + char* m_cmdline; + char* m_mime; + int m_killsig; + int m_killtimeout; } pass; struct { - int m_dvbsub_reorder; + int m_dvbsub_reorder; } mkv; struct { - int m_force_type; - int m_index; + int m_force_type; + int m_index; } audioes; } u; } muxer_config_t; typedef struct muxer_hints { - char *mh_agent; + char* mh_agent; } muxer_hints_t; struct muxer; @@ -104,90 +104,122 @@ struct epg_broadcast; struct service; typedef struct muxer { - int (*m_open_stream)(struct muxer *, int fd); /* Open for socket streaming */ - int (*m_open_file) (struct muxer *, const char *filename); /* Open for file storage */ - const char* (*m_mime) (struct muxer *, /* Figure out the mimetype */ - const struct streaming_start *); - int (*m_init) (struct muxer *, /* Init The muxer with streams */ - struct streaming_start *, - const char *); - int (*m_reconfigure)(struct muxer *, /* Reconfigure the muxer on */ - const struct streaming_start *); /* stream changes */ - int (*m_close) (struct muxer *); /* Close the muxer */ - void (*m_destroy) (struct muxer *); /* Free the memory */ - int (*m_write_meta) (struct muxer *, struct epg_broadcast *, - const char *comment); /* Append epg data */ - int (*m_write_pkt) (struct muxer *, /* Append a media packet */ - streaming_message_type_t, - void *); - int (*m_add_marker) (struct muxer *); /* Add a marker (or chapter) */ - - int m_eos; /* End of stream */ - int m_errors; /* Number of errors */ - int m_caps; /* Capabilities */ - muxer_config_t m_config; /* general configuration */ - muxer_hints_t *m_hints; /* other hints */ + int (*m_open_stream)(struct muxer*, int fd); /* Open for socket streaming */ + int (*m_open_file)(struct muxer*, const char* filename); /* Open for file storage */ + const char* (*m_mime)(struct muxer*, /* Figure out the mimetype */ + const struct streaming_start*); + int (*m_init)(struct muxer*, /* Init The muxer with streams */ + struct streaming_start*, + const char*); + int (*m_reconfigure)(struct muxer*, /* Reconfigure the muxer on */ + const struct streaming_start*); /* stream changes */ + int (*m_close)(struct muxer*); /* Close the muxer */ + void (*m_destroy)(struct muxer*); /* Free the memory */ + int (*m_write_meta)(struct muxer*, + struct epg_broadcast*, + const char* comment); /* Append epg data */ + int (*m_write_pkt)(struct muxer*, /* Append a media packet */ + streaming_message_type_t, + void*); + int (*m_add_marker)(struct muxer*); /* Add a marker (or chapter) */ + + int m_eos; /* End of stream */ + int m_errors; /* Number of errors */ + int m_caps; /* Capabilities */ + muxer_config_t m_config; /* general configuration */ + muxer_hints_t* m_hints; /* other hints */ } muxer_t; - /* type <==> string converters */ -const char * muxer_container_type2txt (muxer_container_type_t mc); -const char* muxer_container_type2mime (muxer_container_type_t mc, int video); -const char* muxer_container_filename2mime (const char *filename, int video); +const char* muxer_container_type2txt(muxer_container_type_t mc); +const char* muxer_container_type2mime(muxer_container_type_t mc, int video); +const char* muxer_container_filename2mime(const char* filename, int video); -muxer_container_type_t muxer_container_txt2type (const char *str); -muxer_container_type_t muxer_container_mime2type (const char *str); +muxer_container_type_t muxer_container_txt2type(const char* str); +muxer_container_type_t muxer_container_mime2type(const char* str); -const char* muxer_container_suffix(muxer_container_type_t mc, int video); +const char* muxer_container_suffix(muxer_container_type_t mc, int video); /* Muxer factory */ -muxer_t *muxer_create(muxer_config_t *m_cfg, muxer_hints_t *hints); +muxer_t* muxer_create(muxer_config_t* m_cfg, muxer_hints_t* hints); -void muxer_config_copy(muxer_config_t *dst, const muxer_config_t *src); +void muxer_config_copy(muxer_config_t* dst, const muxer_config_t* src); -void muxer_config_free(muxer_config_t *m_cfg); +void muxer_config_free(muxer_config_t* m_cfg); -muxer_hints_t *muxer_hints_create(const char *agent); +muxer_hints_t* muxer_hints_create(const char* agent); -void muxer_hints_free(muxer_hints_t *hints); +void muxer_hints_free(muxer_hints_t* hints); /* Wrapper functions */ -static inline int muxer_open_file (muxer_t *m, const char *filename) - { if(m && filename) return m->m_open_file(m, filename); return -1; } - -static inline int muxer_open_stream (muxer_t *m, int fd) - { if(m && fd >= 0) return m->m_open_stream(m, fd); return -1; } - -static inline int muxer_init (muxer_t *m, struct streaming_start *ss, const char *name) - { if(m && ss) return m->m_init(m, ss, name); return -1; } - -static inline int muxer_reconfigure (muxer_t *m, const struct streaming_start *ss) - { if(m && ss) return m->m_reconfigure(m, ss); return -1; } - -static inline int muxer_add_marker (muxer_t *m) - { if (m && m->m_add_marker) return m->m_add_marker(m); return -1; } - -static inline int muxer_close (muxer_t *m) - { if (m) return m->m_close(m); return -1; } - -static inline int muxer_destroy (muxer_t *m) - { if (m) { m->m_destroy(m); return 0; } return -1; } - -static inline int muxer_write_meta (muxer_t *m, struct epg_broadcast *eb, const char *comment) - { if (m) return m->m_write_meta(m, eb, comment); return -1; } - -static inline int muxer_write_pkt (muxer_t *m, streaming_message_type_t smt, void *data) - { if (m && data) return m->m_write_pkt(m, smt, data); return -1; } - -static inline const char* muxer_mime (muxer_t *m, const struct streaming_start *ss) - { if (m && ss) return m->m_mime(m, ss); return NULL; } - -const char* muxer_suffix (muxer_t *m, const struct streaming_start *ss); +static inline int muxer_open_file(muxer_t* m, const char* filename) { + if (m && filename) + return m->m_open_file(m, filename); + return -1; +} + +static inline int muxer_open_stream(muxer_t* m, int fd) { + if (m && fd >= 0) + return m->m_open_stream(m, fd); + return -1; +} + +static inline int muxer_init(muxer_t* m, struct streaming_start* ss, const char* name) { + if (m && ss) + return m->m_init(m, ss, name); + return -1; +} + +static inline int muxer_reconfigure(muxer_t* m, const struct streaming_start* ss) { + if (m && ss) + return m->m_reconfigure(m, ss); + return -1; +} + +static inline int muxer_add_marker(muxer_t* m) { + if (m && m->m_add_marker) + return m->m_add_marker(m); + return -1; +} + +static inline int muxer_close(muxer_t* m) { + if (m) + return m->m_close(m); + return -1; +} + +static inline int muxer_destroy(muxer_t* m) { + if (m) { + m->m_destroy(m); + return 0; + } + return -1; +} + +static inline int muxer_write_meta(muxer_t* m, struct epg_broadcast* eb, const char* comment) { + if (m) + return m->m_write_meta(m, eb, comment); + return -1; +} + +static inline int muxer_write_pkt(muxer_t* m, streaming_message_type_t smt, void* data) { + if (m && data) + return m->m_write_pkt(m, smt, data); + return -1; +} + +static inline const char* muxer_mime(muxer_t* m, const struct streaming_start* ss) { + if (m && ss) + return m->m_mime(m, ss); + return NULL; +} + +const char* muxer_suffix(muxer_t* m, const struct streaming_start* ss); /* Cache */ -const char * muxer_cache_type2txt(muxer_cache_type_t t); -muxer_cache_type_t muxer_cache_txt2type(const char *str); -void muxer_cache_update(muxer_t *m, int fd, off_t off, size_t size); -int muxer_cache_list(htsmsg_t *array); +const char* muxer_cache_type2txt(muxer_cache_type_t t); +muxer_cache_type_t muxer_cache_txt2type(const char* str); +void muxer_cache_update(muxer_t* m, int fd, off_t off, size_t size); +int muxer_cache_list(htsmsg_t* array); #endif diff --git a/src/muxer/ebml.c b/src/muxer/ebml.c index 6a8a71049..de59faf67 100644 --- a/src/muxer/ebml.c +++ b/src/muxer/ebml.c @@ -25,144 +25,116 @@ #include #include "ebml.h" -void -ebml_append_id(htsbuf_queue_t *q, uint32_t id) -{ +void ebml_append_id(htsbuf_queue_t* q, uint32_t id) { uint8_t u8[4] = {id >> 24, id >> 16, id >> 8, id}; - if(u8[0]) + if (u8[0]) return htsbuf_append(q, u8, 4); - if(u8[1]) - return htsbuf_append(q, u8+1, 3); - if(u8[2]) - return htsbuf_append(q, u8+2, 2); - return htsbuf_append(q, u8+3, 1); + if (u8[1]) + return htsbuf_append(q, u8 + 1, 3); + if (u8[2]) + return htsbuf_append(q, u8 + 2, 2); + return htsbuf_append(q, u8 + 3, 1); } -void -ebml_append_size(htsbuf_queue_t *q, uint32_t size) -{ - uint8_t u8[5] = { 0x08, size >> 24, size >> 16, size >> 8, size }; +void ebml_append_size(htsbuf_queue_t* q, uint32_t size) { + uint8_t u8[5] = {0x08, size >> 24, size >> 16, size >> 8, size}; - if(size < 0x7f) { + if (size < 0x7f) { u8[4] |= 0x80; - return htsbuf_append(q, u8+4, 1); + return htsbuf_append(q, u8 + 4, 1); } - if(size < 0x3fff) { + if (size < 0x3fff) { u8[3] |= 0x40; - return htsbuf_append(q, u8+3, 2); + return htsbuf_append(q, u8 + 3, 2); } - if(size < 0x1fffff) { + if (size < 0x1fffff) { u8[2] |= 0x20; - return htsbuf_append(q, u8+2, 3); + return htsbuf_append(q, u8 + 2, 3); } - if(size < 0x0fffffff) { + if (size < 0x0fffffff) { u8[1] |= 0x10; - return htsbuf_append(q, u8+1, 4); + return htsbuf_append(q, u8 + 1, 4); } return htsbuf_append(q, u8, 5); } - -void -ebml_append_xiph_size(htsbuf_queue_t *q, int size) -{ - int i; +void ebml_append_xiph_size(htsbuf_queue_t* q, int size) { + int i; uint8_t u8[4] = {0xff, size % 0xff}; - for(i=0; i> 56, ui >> 48, ui >> 40, ui >> 32, - ui >> 24, ui >> 16, ui >> 8, ui }; - int i = 0; - while( i < 7 && !u8[i] ) +void ebml_append_uint(htsbuf_queue_t* q, unsigned id, int64_t ui) { + uint8_t u8[8] = {ui >> 56, ui >> 48, ui >> 40, ui >> 32, ui >> 24, ui >> 16, ui >> 8, ui}; + int i = 0; + while (i < 7 && !u8[i]) ++i; return ebml_append_bin(q, id, u8 + i, 8 - i); } -void -ebml_append_float(htsbuf_queue_t *q, unsigned id, float f) -{ - union - { - float f; - unsigned u; - } u; - unsigned char c_f[4]; - - u.f = f; - c_f[0] = u.u >> 24; - c_f[1] = u.u >> 16; - c_f[2] = u.u >> 8; - c_f[3] = u.u; - - return ebml_append_bin(q, id, c_f, 4); +void ebml_append_float(htsbuf_queue_t* q, unsigned id, float f) { + union { + float f; + unsigned u; + } u; + unsigned char c_f[4]; + + u.f = f; + c_f[0] = u.u >> 24; + c_f[1] = u.u >> 16; + c_f[2] = u.u >> 8; + c_f[3] = u.u; + + return ebml_append_bin(q, id, c_f, 4); } -void -ebml_append_master(htsbuf_queue_t *q, uint32_t id, htsbuf_queue_t *p) -{ +void ebml_append_master(htsbuf_queue_t* q, uint32_t id, htsbuf_queue_t* p) { ebml_append_id(q, id); ebml_append_size(q, p->hq_size); htsbuf_appendq(q, p); free(p); } -void -ebml_append_void(htsbuf_queue_t *q) -{ +void ebml_append_void(htsbuf_queue_t* q) { char n[1] = {0}; ebml_append_bin(q, 0xec, n, 1); } - -void -ebml_append_pad(htsbuf_queue_t *q, size_t pad) -{ +void ebml_append_pad(htsbuf_queue_t* q, size_t pad) { assert(pad > 2); pad -= 2; assert(pad < 0x3fff); pad -= pad > 0x7e; - void *data = alloca(pad); + void* data = alloca(pad); memset(data, 0, pad); ebml_append_bin(q, 0xec, data, pad); } - -void -ebml_append_idid(htsbuf_queue_t *q, uint32_t id0, uint32_t id) -{ +void ebml_append_idid(htsbuf_queue_t* q, uint32_t id0, uint32_t id) { uint8_t u8[4] = {id >> 24, id >> 16, id >> 8, id}; - if(u8[0]) + if (u8[0]) return ebml_append_bin(q, id0, u8, 4); - if(u8[1]) - return ebml_append_bin(q, id0, u8+1, 3); - if(u8[2]) - return ebml_append_bin(q, id0, u8+2, 2); - return ebml_append_bin(q, id0, u8+3, 1); + if (u8[1]) + return ebml_append_bin(q, id0, u8 + 1, 3); + if (u8[2]) + return ebml_append_bin(q, id0, u8 + 2, 2); + return ebml_append_bin(q, id0, u8 + 3, 1); } diff --git a/src/muxer/ebml.h b/src/muxer/ebml.h index 368fee680..9d946dfc5 100644 --- a/src/muxer/ebml.h +++ b/src/muxer/ebml.h @@ -3,27 +3,26 @@ #include "htsbuf.h" -void ebml_append_id(htsbuf_queue_t *q, uint32_t id); +void ebml_append_id(htsbuf_queue_t* q, uint32_t id); -void ebml_append_size(htsbuf_queue_t *q, uint32_t size); +void ebml_append_size(htsbuf_queue_t* q, uint32_t size); -void ebml_append_xiph_size(htsbuf_queue_t *q, int size); +void ebml_append_xiph_size(htsbuf_queue_t* q, int size); -void ebml_append_bin(htsbuf_queue_t *q, unsigned id, - const void *data, size_t len); +void ebml_append_bin(htsbuf_queue_t* q, unsigned id, const void* data, size_t len); -void ebml_append_string(htsbuf_queue_t *q, unsigned id, const char *str); +void ebml_append_string(htsbuf_queue_t* q, unsigned id, const char* str); -void ebml_append_uint(htsbuf_queue_t *q, unsigned id, int64_t ui); +void ebml_append_uint(htsbuf_queue_t* q, unsigned id, int64_t ui); -void ebml_append_float(htsbuf_queue_t *q, unsigned id, float f); +void ebml_append_float(htsbuf_queue_t* q, unsigned id, float f); -void ebml_append_master(htsbuf_queue_t *q, uint32_t id, htsbuf_queue_t *p); +void ebml_append_master(htsbuf_queue_t* q, uint32_t id, htsbuf_queue_t* p); -void ebml_append_void(htsbuf_queue_t *q); +void ebml_append_void(htsbuf_queue_t* q); -void ebml_append_pad(htsbuf_queue_t *q, size_t pad); +void ebml_append_pad(htsbuf_queue_t* q, size_t pad); -void ebml_append_idid(htsbuf_queue_t *q, uint32_t id0, uint32_t id); +void ebml_append_idid(htsbuf_queue_t* q, uint32_t id0, uint32_t id); #endif // EBML_H__ diff --git a/src/muxer/muxer_audioes.c b/src/muxer/muxer_audioes.c index ab0ca2884..307ae3eb2 100644 --- a/src/muxer/muxer_audioes.c +++ b/src/muxer/muxer_audioes.c @@ -34,7 +34,7 @@ typedef struct audioes_muxer { int error; /* Info about the service */ - int am_index; + int am_index; /* File descriptor stuff */ int am_fd; @@ -43,42 +43,52 @@ typedef struct audioes_muxer { off_t am_off; /* Filename is also used for logging */ - char *am_filename; + char* am_filename; } audioes_muxer_t; - /** * */ -static int -audioes_muxer_type(streaming_component_type_t type) -{ +static int audioes_muxer_type(streaming_component_type_t type) { muxer_container_type_t mc = MC_UNKNOWN; switch (type) { - case SCT_MPEG2AUDIO: mc = MC_MPEG2AUDIO; break; - case SCT_AC3: mc = MC_AC3; break; - case SCT_EAC3: mc = MC_AC3; break; - case SCT_AAC: mc = MC_AAC; break; - case SCT_MP4A: mc = MC_MP4A; break; - case SCT_VORBIS: mc = MC_VORBIS; break; - case SCT_AC4: mc = MC_AC4; break; - default: break; + case SCT_MPEG2AUDIO: + mc = MC_MPEG2AUDIO; + break; + case SCT_AC3: + mc = MC_AC3; + break; + case SCT_EAC3: + mc = MC_AC3; + break; + case SCT_AAC: + mc = MC_AAC; + break; + case SCT_MP4A: + mc = MC_MP4A; + break; + case SCT_VORBIS: + mc = MC_VORBIS; + break; + case SCT_AC4: + mc = MC_AC4; + break; + default: + break; } return mc; } - /** * */ -static const streaming_start_component_t * -audioes_get_component(muxer_t *m, const struct streaming_start *ss) -{ - const streaming_start_component_t *ssc; - muxer_container_type_t mc = MC_UNKNOWN; - int i, count; +static const streaming_start_component_t* audioes_get_component(muxer_t* m, + const struct streaming_start* ss) { + const streaming_start_component_t* ssc; + muxer_container_type_t mc = MC_UNKNOWN; + int i, count; - for (i = count = 0; i < ss->ss_num_components;i++) { + for (i = count = 0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; if ((!ssc->ssc_disabled) && (SCT_ISAUDIO(ssc->es_type))) { if (m->m_config.u.audioes.m_force_type != MC_UNKNOWN) { @@ -94,15 +104,12 @@ audioes_get_component(muxer_t *m, const struct streaming_start *ss) return NULL; } - /** * Figure out the mimetype */ -static const char * -audioes_muxer_mime(muxer_t *m, const struct streaming_start *ss) -{ - muxer_container_type_t mc = MC_UNKNOWN; - const streaming_start_component_t *ssc; +static const char* audioes_muxer_mime(muxer_t* m, const struct streaming_start* ss) { + muxer_container_type_t mc = MC_UNKNOWN; + const streaming_start_component_t* ssc; if (m->m_config.u.audioes.m_force_type != MC_UNKNOWN) return muxer_container_type2mime(m->m_config.u.audioes.m_force_type, 0); @@ -114,15 +121,12 @@ audioes_muxer_mime(muxer_t *m, const struct streaming_start *ss) return muxer_container_type2mime(mc, 0); } - /** * Reconfigure the muxer */ -static int -audioes_muxer_reconfigure(muxer_t *m, const struct streaming_start *ss) -{ - audioes_muxer_t *am = (audioes_muxer_t*)m; - const streaming_start_component_t *ssc; +static int audioes_muxer_reconfigure(muxer_t* m, const struct streaming_start* ss) { + audioes_muxer_t* am = (audioes_muxer_t*)m; + const streaming_start_component_t* ssc; am->am_index = -1; @@ -133,24 +137,18 @@ audioes_muxer_reconfigure(muxer_t *m, const struct streaming_start *ss) return 0; } - /** * Init the builtin mkv muxer with streams */ -static int -audioes_muxer_init(muxer_t* m, struct streaming_start *ss, const char *name) -{ +static int audioes_muxer_init(muxer_t* m, struct streaming_start* ss, const char* name) { return audioes_muxer_reconfigure(m, ss); } - /* * Open the muxer as a stream muxer (using a non-seekable socket) */ -static int -audioes_muxer_open_stream(muxer_t *m, int fd) -{ - audioes_muxer_t *am = (audioes_muxer_t*)m; +static int audioes_muxer_open_stream(muxer_t* m, int fd) { + audioes_muxer_t* am = (audioes_muxer_t*)m; am->am_fd = fd; am->am_seekable = 0; @@ -160,32 +158,30 @@ audioes_muxer_open_stream(muxer_t *m, int fd) return 0; } - /** * Open the file and set the file descriptor */ -static int -audioes_muxer_open_file(muxer_t *m, const char *filename) -{ - int fd; - audioes_muxer_t *am = (audioes_muxer_t*)m; - - tvhtrace(LS_AUDIOES, "Creating file \"%s\" with file permissions \"%o\"", filename, am->m_config.m_file_permissions); - +static int audioes_muxer_open_file(muxer_t* m, const char* filename) { + int fd; + audioes_muxer_t* am = (audioes_muxer_t*)m; + + tvhtrace(LS_AUDIOES, + "Creating file \"%s\" with file permissions \"%o\"", + filename, + am->m_config.m_file_permissions); + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, am->m_config.m_file_permissions); - if(fd < 0) { + if (fd < 0) { am->am_error = errno; - tvherror(LS_AUDIOES, "%s: Unable to create file, open failed -- %s", - filename, strerror(errno)); + tvherror(LS_AUDIOES, "%s: Unable to create file, open failed -- %s", filename, strerror(errno)); am->m_errors++; return -1; } /* bypass umask settings */ if (fchmod(fd, am->m_config.m_file_permissions)) - tvherror(LS_AUDIOES, "%s: Unable to change permissions -- %s", - filename, strerror(errno)); + tvherror(LS_AUDIOES, "%s: Unable to change permissions -- %s", filename, strerror(errno)); am->am_seekable = 1; am->am_off = 0; @@ -197,12 +193,10 @@ audioes_muxer_open_file(muxer_t *m, const char *filename) /** * Write a packet to the muxer */ -static int -audioes_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data) -{ - th_pkt_t *pkt = (th_pkt_t*)data; - audioes_muxer_t *am = (audioes_muxer_t*)m; - size_t size; +static int audioes_muxer_write_pkt(muxer_t* m, streaming_message_type_t smt, void* data) { + th_pkt_t* pkt = (th_pkt_t*)data; + audioes_muxer_t* am = (audioes_muxer_t*)m; + size_t size; assert(smt == SMT_PACKET); @@ -222,8 +216,7 @@ audioes_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data) } else if (tvh_write(am->am_fd, pktbuf_ptr(pkt->pkt_payload), size)) { am->am_error = errno; if (!MC_IS_EOS_ERROR(errno)) { - tvherror(LS_AUDIOES, "%s: Write failed -- %s", am->am_filename, - strerror(errno)); + tvherror(LS_AUDIOES, "%s: Write failed -- %s", am->am_filename, strerror(errno)); } else { am->m_eos = 1; } @@ -242,30 +235,22 @@ audioes_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data) return am->error; } - /** * NOP */ -static int -audioes_muxer_write_meta(muxer_t *m, struct epg_broadcast *eb, const char *comment) -{ +static int audioes_muxer_write_meta(muxer_t* m, struct epg_broadcast* eb, const char* comment) { return 0; } - - /** * Close the muxer */ -static int -audioes_muxer_close(muxer_t *m) -{ - audioes_muxer_t *am = (audioes_muxer_t*)m; +static int audioes_muxer_close(muxer_t* m) { + audioes_muxer_t* am = (audioes_muxer_t*)m; if ((am->am_seekable) && (close(am->am_fd))) { am->am_error = errno; - tvherror(LS_AUDIOES, "%s: Unable to close file -- %s", - am->am_filename, strerror(errno)); + tvherror(LS_AUDIOES, "%s: Unable to close file -- %s", am->am_filename, strerror(errno)); am->m_errors++; return -1; } @@ -273,14 +258,11 @@ audioes_muxer_close(muxer_t *m) return 0; } - /** * Free all memory associated with the muxer */ -static void -audioes_muxer_destroy(muxer_t *m) -{ - audioes_muxer_t *am = (audioes_muxer_t*)m; +static void audioes_muxer_destroy(muxer_t* m) { + audioes_muxer_t* am = (audioes_muxer_t*)m; if (am->am_filename) free(am->am_filename); @@ -289,34 +271,26 @@ audioes_muxer_destroy(muxer_t *m) free(am); } - /** * Create a new builtin muxer */ -muxer_t* -audioes_muxer_create(const muxer_config_t *m_cfg, - const muxer_hints_t *hints) -{ - audioes_muxer_t *am; - - if(m_cfg->m_type != MC_MPEG2AUDIO && - m_cfg->m_type != MC_AC3 && - m_cfg->m_type != MC_AAC && - m_cfg->m_type != MC_MP4A && - m_cfg->m_type != MC_VORBIS && - m_cfg->m_type != MC_AC4) +muxer_t* audioes_muxer_create(const muxer_config_t* m_cfg, const muxer_hints_t* hints) { + audioes_muxer_t* am; + + if (m_cfg->m_type != MC_MPEG2AUDIO && m_cfg->m_type != MC_AC3 && m_cfg->m_type != MC_AAC && + m_cfg->m_type != MC_MP4A && m_cfg->m_type != MC_VORBIS && m_cfg->m_type != MC_AC4) return NULL; - am = calloc(1, sizeof(audioes_muxer_t)); - am->m_open_stream = audioes_muxer_open_stream; - am->m_open_file = audioes_muxer_open_file; - am->m_mime = audioes_muxer_mime; - am->m_init = audioes_muxer_init; - am->m_reconfigure = audioes_muxer_reconfigure; - am->m_write_meta = audioes_muxer_write_meta; - am->m_write_pkt = audioes_muxer_write_pkt; - am->m_close = audioes_muxer_close; - am->m_destroy = audioes_muxer_destroy; + am = calloc(1, sizeof(audioes_muxer_t)); + am->m_open_stream = audioes_muxer_open_stream; + am->m_open_file = audioes_muxer_open_file; + am->m_mime = audioes_muxer_mime; + am->m_init = audioes_muxer_init; + am->m_reconfigure = audioes_muxer_reconfigure; + am->m_write_meta = audioes_muxer_write_meta; + am->m_write_pkt = audioes_muxer_write_pkt; + am->m_close = audioes_muxer_close; + am->m_destroy = audioes_muxer_destroy; return (muxer_t*)am; } diff --git a/src/muxer/muxer_audioes.h b/src/muxer/muxer_audioes.h index ac1a73d2b..33c0a4d5f 100644 --- a/src/muxer/muxer_audioes.h +++ b/src/muxer/muxer_audioes.h @@ -21,6 +21,6 @@ #include "muxer.h" -muxer_t *audioes_muxer_create (const muxer_config_t *m_cfg, const muxer_hints_t *hints); +muxer_t* audioes_muxer_create(const muxer_config_t* m_cfg, const muxer_hints_t* hints); #endif diff --git a/src/muxer/muxer_libav.c b/src/muxer/muxer_libav.c index c7a190e78..c840a4f4a 100644 --- a/src/muxer/muxer_libav.c +++ b/src/muxer/muxer_libav.c @@ -38,28 +38,25 @@ typedef struct lav_muxer { muxer_t; - AVFormatContext *lm_oc; - AVBSFContext *ctx; - const AVBitStreamFilter *bsf_h264_filter; - const AVBitStreamFilter *bsf_hevc_filter; - const AVBitStreamFilter *bsf_vp9_filter; - int lm_fd; - int lm_init; + AVFormatContext* lm_oc; + AVBSFContext* ctx; + const AVBitStreamFilter* bsf_h264_filter; + const AVBitStreamFilter* bsf_hevc_filter; + const AVBitStreamFilter* bsf_vp9_filter; + int lm_fd; + int lm_init; } lav_muxer_t; #define MUX_BUF_SIZE 4096 static const AVRational mpeg_tc = {1, 90000}; - /** * Callback function for libavformat */ -static int -lav_muxer_write(void *opaque, uint8_t *buf, int buf_size) -{ - int r; - lav_muxer_t *lm = (lav_muxer_t*)opaque; +static int lav_muxer_write(void* opaque, uint8_t* buf, int buf_size) { + int r; + lav_muxer_t* lm = (lav_muxer_t*)opaque; if (lm->m_errors) { lm->m_errors++; @@ -69,96 +66,89 @@ lav_muxer_write(void *opaque, uint8_t *buf, int buf_size) r = write(lm->lm_fd, buf, buf_size); if (r != buf_size) lm->m_errors++; - + /* No room to notify about errors here. */ /* We need to complete av_write_trailer() to free */ /* all associated structures. */ return buf_size; } - /** * Add a stream to the muxer */ -static int -lav_muxer_add_stream(lav_muxer_t *lm, - const streaming_start_component_t *ssc) -{ - AVStream *st; - AVCodecContext *c; - const AVCodec *codec; - int rc = -1; +static int lav_muxer_add_stream(lav_muxer_t* lm, const streaming_start_component_t* ssc) { + AVStream* st; + AVCodecContext* c; + const AVCodec* codec; + int rc = -1; st = avformat_new_stream(lm->lm_oc, NULL); if (!st) return -1; st->id = ssc->es_index; - codec = avcodec_find_encoder(streaming_component_type2codec_id(ssc->es_type)); - c = avcodec_alloc_context3(codec); - - switch(lm->m_config.m_type) { - case MC_MATROSKA: - case MC_AVMATROSKA: - case MC_AVMP4: - st->time_base.num = 1000000; - st->time_base.den = 1; - break; - - case MC_MPEGPS: - c->rc_buffer_size = 224*1024*8; - //Fall-through - case MC_MPEGTS: - st->time_base.num = 90000; - st->time_base.den = 1; - break; - - default: - st->time_base = AV_TIME_BASE_Q; - break; + codec = avcodec_find_encoder(streaming_component_type2codec_id(ssc->es_type)); + c = avcodec_alloc_context3(codec); + + switch (lm->m_config.m_type) { + case MC_MATROSKA: + case MC_AVMATROSKA: + case MC_AVMP4: + st->time_base.num = 1000000; + st->time_base.den = 1; + break; + + case MC_MPEGPS: + c->rc_buffer_size = 224 * 1024 * 8; + // Fall-through + case MC_MPEGTS: + st->time_base.num = 90000; + st->time_base.den = 1; + break; + + default: + st->time_base = AV_TIME_BASE_Q; + break; } - if(ssc->ssc_gh) { + if (ssc->ssc_gh) { if (ssc->es_type == SCT_H264 || ssc->es_type == SCT_HEVC) { sbuf_t hdr; sbuf_init(&hdr); if (ssc->es_type == SCT_H264) { - isom_write_avcc(&hdr, pktbuf_ptr(ssc->ssc_gh), - pktbuf_len(ssc->ssc_gh)); + isom_write_avcc(&hdr, pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh)); } else { - isom_write_hvcc(&hdr, pktbuf_ptr(ssc->ssc_gh), - pktbuf_len(ssc->ssc_gh)); + isom_write_hvcc(&hdr, pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh)); } c->extradata_size = hdr.sb_ptr; - c->extradata = av_malloc(hdr.sb_ptr); + c->extradata = av_malloc(hdr.sb_ptr); memcpy(c->extradata, hdr.sb_data, hdr.sb_ptr); sbuf_free(&hdr); } else { c->extradata_size = pktbuf_len(ssc->ssc_gh); - c->extradata = av_malloc(c->extradata_size); - memcpy(c->extradata, pktbuf_ptr(ssc->ssc_gh), - pktbuf_len(ssc->ssc_gh)); + c->extradata = av_malloc(c->extradata_size); + memcpy(c->extradata, pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh)); } } - if(SCT_ISAUDIO(ssc->es_type)) { - c->codec_type = AVMEDIA_TYPE_AUDIO; - c->sample_fmt = AV_SAMPLE_FMT_S16; + if (SCT_ISAUDIO(ssc->es_type)) { + c->codec_type = AVMEDIA_TYPE_AUDIO; + c->sample_fmt = AV_SAMPLE_FMT_S16; - c->sample_rate = sri_to_rate(ssc->es_sri); - c->channels = ssc->es_channels; + c->sample_rate = sri_to_rate(ssc->es_sri); + c->channels = ssc->es_channels; #if 0 c->time_base.num = 1; c->time_base.den = c->sample_rate; #else - c->time_base = st->time_base; + c->time_base = st->time_base; #endif avcodec_parameters_from_context(st->codecpar, c); av_dict_set(&st->metadata, "language", ssc->es_lang, 0); - } else if(SCT_ISVIDEO(ssc->es_type)) { + } else if (SCT_ISVIDEO(ssc->es_type)) { c->codec_type = AVMEDIA_TYPE_VIDEO; c->width = ssc->es_width; c->height = ssc->es_height; @@ -171,7 +161,7 @@ lav_muxer_add_stream(lav_muxer_t *lm, if (lm->m_config.m_type == MC_AVMP4) { /* this is a whole hell */ - AVRational ratio = { c->height, c->width }; + AVRational ratio = {c->height, c->width}; c->sample_aspect_ratio = av_mul_q(c->sample_aspect_ratio, ratio); } @@ -181,44 +171,41 @@ lav_muxer_add_stream(lav_muxer_t *lm, if (ssc->es_type == SCT_H264) { if (av_bsf_alloc(lm->bsf_h264_filter, &lm->ctx)) { - tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for h264_mp4toannexb"); + tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for h264_mp4toannexb"); goto fail; } - } - else if (ssc->es_type == SCT_HEVC) { + } else if (ssc->es_type == SCT_HEVC) { if (av_bsf_alloc(lm->bsf_hevc_filter, &lm->ctx)) { - tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for hevc_mp4toannexb"); + tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for hevc_mp4toannexb"); goto fail; } - } - else if (ssc->es_type == SCT_VP9) { + } else if (ssc->es_type == SCT_VP9) { if (av_bsf_alloc(lm->bsf_vp9_filter, &lm->ctx)) { - tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for vp9_superframe "); + tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for vp9_superframe "); goto fail; } - } - else { + } else { if (av_bsf_alloc(lm->bsf_h264_filter, &lm->ctx)) { - tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for h264_mp4toannexb"); + tvherror(LS_LIBAV, "Failed to alloc AVBitStreamFilter for h264_mp4toannexb"); goto fail; } } - if(avcodec_parameters_copy(lm->ctx->par_in, st->codecpar)) { - tvherror(LS_LIBAV, "Failed to copy paramters to AVBSFContext"); + if (avcodec_parameters_copy(lm->ctx->par_in, st->codecpar)) { + tvherror(LS_LIBAV, "Failed to copy paramters to AVBSFContext"); goto fail; } lm->ctx->time_base_in = st->time_base; if (av_bsf_init(lm->ctx)) { - tvherror(LS_LIBAV, "Failed to init AVBSFContext"); + tvherror(LS_LIBAV, "Failed to init AVBSFContext"); goto fail; } - } else if(SCT_ISSUBTITLE(ssc->es_type)) { + } else if (SCT_ISSUBTITLE(ssc->es_type)) { c->codec_type = AVMEDIA_TYPE_SUBTITLE; avcodec_parameters_from_context(st->codecpar, c); av_dict_set(&st->metadata, "language", ssc->es_lang, 0); } - if(lm->lm_oc->oformat->flags & AVFMT_GLOBALHEADER) + if (lm->lm_oc->oformat->flags & AVFMT_GLOBALHEADER) c->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; rc = 0; @@ -229,161 +216,151 @@ fail: return rc; } - /** * Check if a container supports a given streaming component */ -static int -lav_muxer_support_stream(muxer_container_type_t mc, - streaming_component_type_t type) -{ +static int lav_muxer_support_stream(muxer_container_type_t mc, streaming_component_type_t type) { int ret = 0; - switch(mc) { - case MC_MATROSKA: - case MC_AVMATROSKA: - ret |= SCT_ISAUDIO(type); - ret |= SCT_ISVIDEO(type); - ret |= SCT_ISSUBTITLE(type); - break; - - case MC_WEBM: - case MC_AVWEBM: - ret |= type == SCT_VP8; - ret |= type == SCT_VP9; - ret |= type == SCT_VORBIS; - ret |= type == SCT_OPUS; - break; - - case MC_MPEGTS: - ret |= (type == SCT_MPEG2VIDEO); - ret |= (type == SCT_H264); - ret |= (type == SCT_HEVC); - - ret |= (type == SCT_MPEG2AUDIO); - ret |= (type == SCT_AC3); - ret |= (type == SCT_AAC); - ret |= (type == SCT_MP4A); - ret |= (type == SCT_EAC3); - ret |= (type == SCT_AC4); - - //Some pids lack pts, disable for now - //ret |= (type == SCT_TELETEXT); - ret |= (type == SCT_DVBSUB); - break; - - case MC_MPEGPS: - ret |= (type == SCT_MPEG2VIDEO); - ret |= (type == SCT_MPEG2AUDIO); - ret |= (type == SCT_AC3); - break; - - case MC_AVMP4: - ret |= (type == SCT_MPEG2VIDEO); - ret |= (type == SCT_H264); - ret |= (type == SCT_HEVC); - - ret |= (type == SCT_MPEG2AUDIO); - ret |= (type == SCT_AC3); - ret |= (type == SCT_AAC); - ret |= (type == SCT_MP4A); - ret |= (type == SCT_EAC3); - ret |= (type == SCT_AC4); - break; - - default: - break; + switch (mc) { + case MC_MATROSKA: + case MC_AVMATROSKA: + ret |= SCT_ISAUDIO(type); + ret |= SCT_ISVIDEO(type); + ret |= SCT_ISSUBTITLE(type); + break; + + case MC_WEBM: + case MC_AVWEBM: + ret |= type == SCT_VP8; + ret |= type == SCT_VP9; + ret |= type == SCT_VORBIS; + ret |= type == SCT_OPUS; + break; + + case MC_MPEGTS: + ret |= (type == SCT_MPEG2VIDEO); + ret |= (type == SCT_H264); + ret |= (type == SCT_HEVC); + + ret |= (type == SCT_MPEG2AUDIO); + ret |= (type == SCT_AC3); + ret |= (type == SCT_AAC); + ret |= (type == SCT_MP4A); + ret |= (type == SCT_EAC3); + ret |= (type == SCT_AC4); + + // Some pids lack pts, disable for now + // ret |= (type == SCT_TELETEXT); + ret |= (type == SCT_DVBSUB); + break; + + case MC_MPEGPS: + ret |= (type == SCT_MPEG2VIDEO); + ret |= (type == SCT_MPEG2AUDIO); + ret |= (type == SCT_AC3); + break; + + case MC_AVMP4: + ret |= (type == SCT_MPEG2VIDEO); + ret |= (type == SCT_H264); + ret |= (type == SCT_HEVC); + + ret |= (type == SCT_MPEG2AUDIO); + ret |= (type == SCT_AC3); + ret |= (type == SCT_AAC); + ret |= (type == SCT_MP4A); + ret |= (type == SCT_EAC3); + ret |= (type == SCT_AC4); + break; + + default: + break; } return ret; } - /** * Figure out the mime-type for the muxed data stream */ -static const char* -lav_muxer_mime(muxer_t* m, const struct streaming_start *ss) -{ - int i; - int has_audio; - int has_video; - const streaming_start_component_t *ssc; - +static const char* lav_muxer_mime(muxer_t* m, const struct streaming_start* ss) { + int i; + int has_audio; + int has_video; + const streaming_start_component_t* ssc; + has_audio = 0; has_video = 0; - for(i=0; i < ss->ss_num_components; i++) { + for (i = 0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; - if(ssc->ssc_disabled) + if (ssc->ssc_disabled) continue; - if(!lav_muxer_support_stream(m->m_config.m_type, ssc->es_type)) + if (!lav_muxer_support_stream(m->m_config.m_type, ssc->es_type)) continue; has_video |= SCT_ISVIDEO(ssc->es_type); has_audio |= SCT_ISAUDIO(ssc->es_type); } - if(has_video) + if (has_video) return muxer_container_type2mime(m->m_config.m_type, 1); - else if(has_audio) + else if (has_audio) return muxer_container_type2mime(m->m_config.m_type, 0); else return muxer_container_type2mime(MC_UNKNOWN, 0); } - /** * Init the muxer with streams */ -static int -lav_muxer_init(muxer_t* m, struct streaming_start *ss, const char *name) -{ - int i; - streaming_start_component_t *ssc; - AVFormatContext *oc; - AVDictionary *opts = NULL; - lav_muxer_t *lm = (lav_muxer_t*)m; - char app[128]; +static int lav_muxer_init(muxer_t* m, struct streaming_start* ss, const char* name) { + int i; + streaming_start_component_t* ssc; + AVFormatContext* oc; + AVDictionary* opts = NULL; + lav_muxer_t* lm = (lav_muxer_t*)m; + char app[128]; #if LIBAVCODEC_VERSION_MAJOR > 58 - const AVOutputFormat *fmt; + const AVOutputFormat* fmt; #else - AVOutputFormat *fmt; + AVOutputFormat* fmt; #endif - const char *muxer_name; - int rc = -1; + const char* muxer_name; + int rc = -1; snprintf(app, sizeof(app), "Tvheadend %s", tvheadend_version); oc = lm->lm_oc; - switch(lm->m_config.m_type) { - case MC_MPEGPS: - muxer_name = "dvd"; - break; - case MC_MPEGTS: - muxer_name = "mpegts"; - break; - case MC_MATROSKA: - case MC_AVMATROSKA: - muxer_name = "matroska"; - break; - case MC_WEBM: - case MC_AVWEBM: - muxer_name = "webm"; - break; - case MC_AVMP4: - muxer_name = "mp4"; - break; - default: - muxer_name = muxer_container_type2txt(lm->m_config.m_type); - break; + switch (lm->m_config.m_type) { + case MC_MPEGPS: + muxer_name = "dvd"; + break; + case MC_MPEGTS: + muxer_name = "mpegts"; + break; + case MC_MATROSKA: + case MC_AVMATROSKA: + muxer_name = "matroska"; + break; + case MC_WEBM: + case MC_AVWEBM: + muxer_name = "webm"; + break; + case MC_AVMP4: + muxer_name = "mp4"; + break; + default: + muxer_name = muxer_container_type2txt(lm->m_config.m_type); + break; } fmt = lm->lm_oc->oformat; - if(avformat_alloc_output_context2(&oc, fmt, muxer_name, NULL) < 0) { - tvherror(LS_LIBAV, "Can't find the '%s' muxer", muxer_name); + if (avformat_alloc_output_context2(&oc, fmt, muxer_name, NULL) < 0) { + tvherror(LS_LIBAV, "Can't find the '%s' muxer", muxer_name); return -1; } av_dict_set(&oc->metadata, "title", name, 0); @@ -392,59 +369,58 @@ lav_muxer_init(muxer_t* m, struct streaming_start *ss, const char *name) lm->bsf_h264_filter = av_bsf_get_by_name("h264_mp4toannexb"); if (lm->bsf_h264_filter == NULL) { - tvhwarn(LS_LIBAV, "Failed to get BSF: h264_mp4toannexb"); + tvhwarn(LS_LIBAV, "Failed to get BSF: h264_mp4toannexb"); } lm->bsf_hevc_filter = av_bsf_get_by_name("hevc_mp4toannexb"); if (lm->bsf_h264_filter == NULL) { - tvhwarn(LS_LIBAV, "Failed to get BSF: hevc_mp4toannexb"); + tvhwarn(LS_LIBAV, "Failed to get BSF: hevc_mp4toannexb"); } lm->bsf_vp9_filter = av_bsf_get_by_name("vp9_superframe"); if (lm->bsf_vp9_filter == NULL) { - tvhwarn(LS_LIBAV, "Failed to get BSF: vp9_superframe "); + tvhwarn(LS_LIBAV, "Failed to get BSF: vp9_superframe "); } oc->max_delay = 0.7 * AV_TIME_BASE; - for(i=0; i < ss->ss_num_components; i++) { + for (i = 0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; - if(ssc->ssc_disabled) + if (ssc->ssc_disabled) continue; - if(!lav_muxer_support_stream(lm->m_config.m_type, ssc->es_type)) { - tvhwarn(LS_LIBAV, "%s is not supported in %s", - streaming_component_type2txt(ssc->es_type), - muxer_container_type2txt(lm->m_config.m_type)); + if (!lav_muxer_support_stream(lm->m_config.m_type, ssc->es_type)) { + tvhwarn(LS_LIBAV, + "%s is not supported in %s", + streaming_component_type2txt(ssc->es_type), + muxer_container_type2txt(lm->m_config.m_type)); ssc->ssc_muxer_disabled = 1; continue; } - if(lav_muxer_add_stream(lm, ssc)) { - tvherror(LS_LIBAV, "Failed to add %s stream", - streaming_component_type2txt(ssc->es_type)); + if (lav_muxer_add_stream(lm, ssc)) { + tvherror(LS_LIBAV, "Failed to add %s stream", streaming_component_type2txt(ssc->es_type)); ssc->ssc_muxer_disabled = 1; continue; } } - if(lm->m_config.m_type == MC_AVMP4) { + if (lm->m_config.m_type == MC_AVMP4) { av_dict_set(&opts, "frag_duration", "1", 0); av_dict_set(&opts, "ism_lookahead", "0", 0); } - if(!lm->lm_oc->nb_streams) { - tvherror(LS_LIBAV, "No supported streams available"); + if (!lm->lm_oc->nb_streams) { + tvherror(LS_LIBAV, "No supported streams available"); lm->m_errors++; goto fail; - } else if(avformat_write_header(lm->lm_oc, &opts) < 0) { - tvherror(LS_LIBAV, "Failed to write %s header", - muxer_container_type2txt(lm->m_config.m_type)); + } else if (avformat_write_header(lm->lm_oc, &opts) < 0) { + tvherror(LS_LIBAV, "Failed to write %s header", muxer_container_type2txt(lm->m_config.m_type)); lm->m_errors++; goto fail; } lm->lm_init = 1; - rc = 0; + rc = 0; fail: if (opts) @@ -453,107 +429,93 @@ fail: return rc; } - /** * Handle changes to the streams (usually PMT updates) */ -static int -lav_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss) -{ - lav_muxer_t *lm = (lav_muxer_t*)m; +static int lav_muxer_reconfigure(muxer_t* m, const struct streaming_start* ss) { + lav_muxer_t* lm = (lav_muxer_t*)m; lm->m_errors++; return -1; } - /** * Open the muxer and write the header */ -static int -lav_muxer_open_stream(muxer_t *m, int fd) -{ - uint8_t *buf; - AVIOContext *pb; - lav_muxer_t *lm = (lav_muxer_t*)m; - - buf = av_malloc(MUX_BUF_SIZE); - pb = avio_alloc_context(buf, MUX_BUF_SIZE, 1, lm, NULL, - lav_muxer_write, NULL); - pb->seekable = 0; +static int lav_muxer_open_stream(muxer_t* m, int fd) { + uint8_t* buf; + AVIOContext* pb; + lav_muxer_t* lm = (lav_muxer_t*)m; + + buf = av_malloc(MUX_BUF_SIZE); + pb = avio_alloc_context(buf, MUX_BUF_SIZE, 1, lm, NULL, lav_muxer_write, NULL); + pb->seekable = 0; lm->lm_oc->pb = pb; - lm->lm_fd = fd; + lm->lm_fd = fd; return 0; } - -static int -lav_muxer_open_file(muxer_t *m, const char *filename) -{ - AVFormatContext *oc; - lav_muxer_t *lm = (lav_muxer_t*)m; - char buf[256]; - int r; +static int lav_muxer_open_file(muxer_t* m, const char* filename) { + AVFormatContext* oc; + lav_muxer_t* lm = (lav_muxer_t*)m; + char buf[256]; + int r; lm->lm_fd = -1; - oc = lm->lm_oc; + oc = lm->lm_oc; - if((r = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) { + if ((r = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE)) < 0) { av_strerror(r, buf, sizeof(buf)); - tvherror(LS_LIBAV, "%s: Could not open -- %s", filename, buf); + tvherror(LS_LIBAV, "%s: Could not open -- %s", filename, buf); lm->m_errors++; return -1; } /* bypass umask settings */ if (chmod(filename, lm->m_config.m_file_permissions)) - tvherror(LS_LIBAV, "%s: Unable to change permissions -- %s", - filename, strerror(errno)); + tvherror(LS_LIBAV, "%s: Unable to change permissions -- %s", filename, strerror(errno)); return 0; } - /** * Write a packet to the muxer */ -static int -lav_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data) -{ - int i; - AVFormatContext *oc; - AVStream *st; - AVPacket packet; - enum AVCodecID codec_id; - th_pkt_t *pkt = (th_pkt_t*)data, *opkt; - lav_muxer_t *lm = (lav_muxer_t*)m; - unsigned char *tofree; - int rc = 0; +static int lav_muxer_write_pkt(muxer_t* m, streaming_message_type_t smt, void* data) { + int i; + AVFormatContext* oc; + AVStream* st; + AVPacket packet; + enum AVCodecID codec_id; + th_pkt_t * pkt = (th_pkt_t*)data, *opkt; + lav_muxer_t* lm = (lav_muxer_t*)m; + unsigned char* tofree; + int rc = 0; assert(smt == SMT_PACKET); oc = lm->lm_oc; - if(!oc->nb_streams) { + if (!oc->nb_streams) { tvherror(LS_LIBAV, "No streams to mux"); rc = -1; goto ret; } - if(!lm->lm_init) { + if (!lm->lm_init) { tvherror(LS_LIBAV, "Muxer not initialized correctly"); rc = -1; goto ret; } - for(i=0; inb_streams; i++) { + for (i = 0; i < oc->nb_streams; i++) { st = oc->streams[i]; - if(st->id != pkt->pkt_componentindex) + if (st->id != pkt->pkt_componentindex) continue; - if(pkt->pkt_payload == NULL) + if (pkt->pkt_payload == NULL) continue; tofree = NULL; @@ -574,69 +536,64 @@ lav_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data) packet.size = pktbuf_len(pkt->pkt_payload); } - packet.stream_index = st->index; - - packet.pts = av_rescale_q_rnd(pkt->pkt_pts, mpeg_tc, st->time_base, - AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); - packet.dts = av_rescale_q_rnd(pkt->pkt_dts, mpeg_tc, st->time_base, - AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); - packet.duration = av_rescale_q_rnd(pkt->pkt_duration, mpeg_tc, st->time_base, - AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); - - if(!SCT_ISVIDEO(pkt->pkt_type) || pkt->v.pkt_frametype < PKT_P_FRAME) + + packet.pts = av_rescale_q_rnd(pkt->pkt_pts, + mpeg_tc, + st->time_base, + AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); + packet.dts = av_rescale_q_rnd(pkt->pkt_dts, + mpeg_tc, + st->time_base, + AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); + packet.duration = av_rescale_q_rnd(pkt->pkt_duration, + mpeg_tc, + st->time_base, + AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); + + if (!SCT_ISVIDEO(pkt->pkt_type) || pkt->v.pkt_frametype < PKT_P_FRAME) packet.flags |= AV_PKT_FLAG_KEY; - if((rc = av_interleaved_write_frame(oc, &packet))) - tvhwarn(LS_LIBAV, "Failed to write frame"); + if ((rc = av_interleaved_write_frame(oc, &packet))) + tvhwarn(LS_LIBAV, "Failed to write frame"); - if(tofree && tofree != pktbuf_ptr(pkt->pkt_payload)) + if (tofree && tofree != pktbuf_ptr(pkt->pkt_payload)) av_free(tofree); break; } - ret: +ret: lm->m_errors += (rc != 0); pkt_ref_dec(pkt); return rc; } - /** * NOP */ -static int -lav_muxer_write_meta(muxer_t *m, struct epg_broadcast *eb, const char *comment) -{ +static int lav_muxer_write_meta(muxer_t* m, struct epg_broadcast* eb, const char* comment) { return 0; } - /** * NOP */ -static int -lav_muxer_add_marker(muxer_t* m) -{ +static int lav_muxer_add_marker(muxer_t* m) { return 0; } - /** * Close the muxer and append trailer to output */ -static int -lav_muxer_close(muxer_t *m) -{ - AVFormatContext *oc; - int ret = 0; - lav_muxer_t *lm = (lav_muxer_t*)m; +static int lav_muxer_close(muxer_t* m) { + AVFormatContext* oc; + int ret = 0; + lav_muxer_t* lm = (lav_muxer_t*)m; - if(lm->lm_init && av_write_trailer(lm->lm_oc) < 0) { - tvhwarn(LS_LIBAV, "Failed to write %s trailer", - muxer_container_type2txt(lm->m_config.m_type)); + if (lm->lm_init && av_write_trailer(lm->lm_oc) < 0) { + tvhwarn(LS_LIBAV, "Failed to write %s trailer", muxer_container_type2txt(lm->m_config.m_type)); lm->m_errors++; ret = -1; } @@ -657,28 +614,25 @@ lav_muxer_close(muxer_t *m) return ret; } - /** * Free all memory associated with the muxer */ -static void -lav_muxer_destroy(muxer_t *m) -{ - int i; - lav_muxer_t *lm = (lav_muxer_t*)m; +static void lav_muxer_destroy(muxer_t* m) { + int i; + lav_muxer_t* lm = (lav_muxer_t*)m; - if(lm->ctx){ + if (lm->ctx) { if (av_bsf_send_packet(lm->ctx, NULL)) - tvhwarn(LS_LIBAV, "Failed to send packet to AVBSFContext (close)"); + tvhwarn(LS_LIBAV, "Failed to send packet to AVBSFContext (close)"); av_bsf_free(&lm->ctx); } if (lm->lm_oc) { - for(i=0; ilm_oc->nb_streams; i++) + for (i = 0; i < lm->lm_oc->nb_streams; i++) av_freep(&lm->lm_oc->streams[i]->codecpar->extradata); } - if(lm->lm_oc) { + if (lm->lm_oc) { avformat_free_context(lm->lm_oc); lm->lm_oc = NULL; } @@ -688,49 +642,45 @@ lav_muxer_destroy(muxer_t *m) free(lm); } - /** * Create a new libavformat based muxer */ -muxer_t* -lav_muxer_create(const muxer_config_t *m_cfg, - const muxer_hints_t *hints) -{ - const char *mux_name; - lav_muxer_t *lm; +muxer_t* lav_muxer_create(const muxer_config_t* m_cfg, const muxer_hints_t* hints) { + const char* mux_name; + lav_muxer_t* lm; #if LIBAVCODEC_VERSION_MAJOR > 58 - const AVOutputFormat *fmt; + const AVOutputFormat* fmt; #else - AVOutputFormat *fmt; + AVOutputFormat* fmt; #endif - switch(m_cfg->m_type) { - case MC_MPEGPS: - mux_name = "dvd"; - break; - case MC_MATROSKA: - case MC_AVMATROSKA: - mux_name = "matroska"; - break; - case MC_WEBM: - case MC_AVWEBM: - mux_name = "webm"; - break; - case MC_AVMP4: - mux_name = "mp4"; - break; - default: - mux_name = muxer_container_type2txt(m_cfg->m_type); - break; + switch (m_cfg->m_type) { + case MC_MPEGPS: + mux_name = "dvd"; + break; + case MC_MATROSKA: + case MC_AVMATROSKA: + mux_name = "matroska"; + break; + case MC_WEBM: + case MC_AVWEBM: + mux_name = "webm"; + break; + case MC_AVMP4: + mux_name = "mp4"; + break; + default: + mux_name = muxer_container_type2txt(m_cfg->m_type); + break; } fmt = av_guess_format(mux_name, NULL, NULL); - if(!fmt) { - tvherror(LS_LIBAV, "Can't find the '%s' muxer", mux_name); + if (!fmt) { + tvherror(LS_LIBAV, "Can't find the '%s' muxer", mux_name); return NULL; } - lm = calloc(1, sizeof(lav_muxer_t)); + lm = calloc(1, sizeof(lav_muxer_t)); lm->m_open_stream = lav_muxer_open_stream; lm->m_open_file = lav_muxer_open_file; lm->m_init = lav_muxer_init; diff --git a/src/muxer/muxer_libav.h b/src/muxer/muxer_libav.h index 3852948cb..376f73323 100644 --- a/src/muxer/muxer_libav.h +++ b/src/muxer/muxer_libav.h @@ -21,6 +21,6 @@ #include "muxer.h" -muxer_t *lav_muxer_create (const muxer_config_t *m_cfg, const muxer_hints_t *hints); +muxer_t* lav_muxer_create(const muxer_config_t* m_cfg, const muxer_hints_t* hints); #endif diff --git a/src/muxer/muxer_mkv.c b/src/muxer/muxer_mkv.c index a38d15af5..fbf8ce252 100644 --- a/src/muxer/muxer_mkv.c +++ b/src/muxer/muxer_mkv.c @@ -43,7 +43,6 @@ #include "parsers/parser_hevc.h" #include "muxer_mkv.h" - extern int dvr_iov_max; TAILQ_HEAD(mk_cue_queue, mk_cue); @@ -51,18 +50,17 @@ TAILQ_HEAD(mk_chapter_queue, mk_chapter); #define MATROSKA_TIMESCALE 1000000 // in nS - /** * */ typedef struct mk_track { - int index; - int avc; - int hevc; - int type; - int tracknum; - int tracktype; - int disabled; + int index; + int avc; + int hevc; + int type; + int tracknum; + int tracktype; + int disabled; int64_t nextpts; uint8_t channels; @@ -81,8 +79,8 @@ typedef struct mk_track { typedef struct mk_cue { TAILQ_ENTRY(mk_cue) link; int64_t ts; - int tracknum; - off_t cluster_pos; + int tracknum; + off_t cluster_pos; } mk_cue_t; /** @@ -91,28 +89,28 @@ typedef struct mk_cue { typedef struct mk_chapter { TAILQ_ENTRY(mk_chapter) link; uint32_t uuid; - int64_t ts; + int64_t ts; } mk_chapter_t; typedef struct mk_muxer { muxer_t; - int fd; - char *filename; - int error; + int fd; + char* filename; + int error; off_t fdpos; // Current position in file - int seekable; + int seekable; - mk_track_t *tracks; - int ntracks; - int has_video; + mk_track_t* tracks; + int ntracks; + int has_video; int64_t totduration; - htsbuf_queue_t *cluster; - int64_t cluster_tc; - off_t cluster_pos; - int64_t cluster_last_close; - int64_t cluster_maxsize; + htsbuf_queue_t* cluster; + int64_t cluster_tc; + off_t cluster_pos; + int64_t cluster_last_close; + int64_t cluster_maxsize; off_t segment_header_pos; @@ -126,11 +124,11 @@ typedef struct mk_muxer { int addcue; - struct mk_cue_queue cues; + struct mk_cue_queue cues; struct mk_chapter_queue chapters; uint8_t uuid[16]; - char *title; + char* title; int webm; int dvbsub_reorder; @@ -141,13 +139,12 @@ typedef struct mk_muxer { /* --- */ -static int mk_mux_insert_chapter(mk_muxer_t *mk); +static int mk_mux_insert_chapter(mk_muxer_t* mk); /* * */ -static int mk_pktref_cmp(const void *_a, const void *_b) -{ +static int mk_pktref_cmp(const void* _a, const void* _b) { const th_pktref_t *a = _a, *b = _b; return a->pr_pkt->pkt_pts - b->pr_pkt->pkt_pts; } @@ -155,10 +152,8 @@ static int mk_pktref_cmp(const void *_a, const void *_b) /* * */ -static htsbuf_queue_t * -mk_build_ebmlheader(mk_muxer_t *mk) -{ - htsbuf_queue_t *q = htsbuf_queue_alloc(0); +static htsbuf_queue_t* mk_build_ebmlheader(mk_muxer_t* mk) { + htsbuf_queue_t* q = htsbuf_queue_alloc(0); ebml_append_uint(q, 0x4286, 1); ebml_append_uint(q, 0x42f7, 1); @@ -170,226 +165,220 @@ mk_build_ebmlheader(mk_muxer_t *mk) return q; } - /** * lifted from avpriv_split_xiph_headers() in libavcodec/xiph.c */ -static int -mk_split_xiph_headers(uint8_t *extradata, int extradata_size, - int first_header_size, uint8_t *header_start[3], - int header_len[3]) -{ - int i; - - if (extradata_size >= 6 && RB16(extradata) == first_header_size) { - int overall_len = 6; - for (i=0; i<3; i++) { - header_len[i] = RB16(extradata); - extradata += 2; - header_start[i] = extradata; - extradata += header_len[i]; - if (overall_len > extradata_size - header_len[i]) - return -1; - overall_len += header_len[i]; - } - } else if (extradata_size >= 3 && extradata_size < INT_MAX - 0x1ff && extradata[0] == 2) { - int overall_len = 3; - extradata++; - for (i=0; i<2; i++, extradata++) { - header_len[i] = 0; - for (; overall_len < extradata_size && *extradata==0xff; extradata++) { - header_len[i] += 0xff; - overall_len += 0xff + 1; - } - header_len[i] += *extradata; - overall_len += *extradata; - if (overall_len > extradata_size) - return -1; - } - header_len[2] = extradata_size - overall_len; - header_start[0] = extradata; - header_start[1] = header_start[0] + header_len[0]; - header_start[2] = header_start[1] + header_len[1]; - } else { +static int mk_split_xiph_headers(uint8_t* extradata, + int extradata_size, + int first_header_size, + uint8_t* header_start[3], + int header_len[3]) { + int i; + + if (extradata_size >= 6 && RB16(extradata) == first_header_size) { + int overall_len = 6; + for (i = 0; i < 3; i++) { + header_len[i] = RB16(extradata); + extradata += 2; + header_start[i] = extradata; + extradata += header_len[i]; + if (overall_len > extradata_size - header_len[i]) + return -1; + overall_len += header_len[i]; + } + } else if (extradata_size >= 3 && extradata_size < INT_MAX - 0x1ff && extradata[0] == 2) { + int overall_len = 3; + extradata++; + for (i = 0; i < 2; i++, extradata++) { + header_len[i] = 0; + for (; overall_len < extradata_size && *extradata == 0xff; extradata++) { + header_len[i] += 0xff; + overall_len += 0xff + 1; + } + header_len[i] += *extradata; + overall_len += *extradata; + if (overall_len > extradata_size) return -1; } - return 0; + header_len[2] = extradata_size - overall_len; + header_start[0] = extradata; + header_start[1] = header_start[0] + header_len[0]; + header_start[2] = header_start[1] + header_len[1]; + } else { + return -1; + } + return 0; } - /** * */ -static htsbuf_queue_t * -mk_build_segment_info(mk_muxer_t *mk) -{ - htsbuf_queue_t *q = htsbuf_queue_alloc(0); - char app[128]; +static htsbuf_queue_t* mk_build_segment_info(mk_muxer_t* mk) { + htsbuf_queue_t* q = htsbuf_queue_alloc(0); + char app[128]; snprintf(app, sizeof(app), "Tvheadend %s", tvheadend_version); - if(!mk->webm) + if (!mk->webm) ebml_append_bin(q, 0x73a4, mk->uuid, sizeof(mk->uuid)); - if(!mk->webm) + if (!mk->webm) ebml_append_string(q, 0x7ba9, mk->title); ebml_append_string(q, 0x4d80, "Tvheadend Matroska muxer"); ebml_append_string(q, 0x5741, app); ebml_append_uint(q, 0x2ad7b1, MATROSKA_TIMESCALE); - if(mk->totduration) + if (mk->totduration) ebml_append_float(q, 0x4489, (float)mk->totduration); else ebml_append_pad(q, 7); // Must be equal to floatingpoint duration return q; } - /** * */ -static htsbuf_queue_t * -mk_build_tracks(mk_muxer_t *mk, streaming_start_t *ss) -{ - streaming_start_component_t *ssc; - const char *codec_id; - int i, tracktype; - htsbuf_queue_t *q = htsbuf_queue_alloc(0), *t; - int tracknum = 0; - uint8_t buf4[4]; - uint32_t bit_depth = 0; - mk_track_t *tr; - - mk->tracks = calloc(1, sizeof(mk_track_t) * ss->ss_num_components); - mk->ntracks = ss->ss_num_components; +static htsbuf_queue_t* mk_build_tracks(mk_muxer_t* mk, streaming_start_t* ss) { + streaming_start_component_t* ssc; + const char* codec_id; + int i, tracktype; + htsbuf_queue_t * q = htsbuf_queue_alloc(0), *t; + int tracknum = 0; + uint8_t buf4[4]; + uint32_t bit_depth = 0; + mk_track_t* tr; + + mk->tracks = calloc(1, sizeof(mk_track_t) * ss->ss_num_components); + mk->ntracks = ss->ss_num_components; mk->cluster_maxsize = 4000000; - for(i = 0; i < ss->ss_num_components; i++) { + for (i = 0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; - tr = &mk->tracks[i]; + tr = &mk->tracks[i]; tr->disabled = ssc->ssc_disabled; - tr->index = ssc->es_index; + tr->index = ssc->es_index; - if(tr->disabled) + if (tr->disabled) continue; - tr->type = ssc->es_type; - tr->channels = ssc->es_channels; + tr->type = ssc->es_type; + tr->channels = ssc->es_channels; tr->aspect_num = ssc->es_aspect_num; tr->aspect_den = ssc->es_aspect_den; tr->commercial = COMMERCIAL_UNKNOWN; - tr->sri = ssc->es_sri; - tr->nextpts = PTS_UNSET; + tr->sri = ssc->es_sri; + tr->nextpts = PTS_UNSET; if (mk->webm && ssc->es_type != SCT_VP8 && ssc->es_type != SCT_VORBIS) - tvhwarn(LS_MKV, "WEBM format supports only VP8+VORBIS streams (detected %s)", - streaming_component_type2txt(ssc->es_type)); - - switch(ssc->es_type) { - case SCT_MPEG2VIDEO: - tracktype = 1; - codec_id = "V_MPEG2"; - break; + tvhwarn(LS_MKV, + "WEBM format supports only VP8+VORBIS streams (detected %s)", + streaming_component_type2txt(ssc->es_type)); + + switch (ssc->es_type) { + case SCT_MPEG2VIDEO: + tracktype = 1; + codec_id = "V_MPEG2"; + break; - case SCT_H264: - tracktype = 1; - codec_id = "V_MPEG4/ISO/AVC"; - tr->avc = 1; - mk->cluster_maxsize = 10000000; - break; + case SCT_H264: + tracktype = 1; + codec_id = "V_MPEG4/ISO/AVC"; + tr->avc = 1; + mk->cluster_maxsize = 10000000; + break; - case SCT_HEVC: - tracktype = 1; - codec_id = "V_MPEGH/ISO/HEVC"; - mk->cluster_maxsize = 20000000; - tr->hevc = 1; - break; + case SCT_HEVC: + tracktype = 1; + codec_id = "V_MPEGH/ISO/HEVC"; + mk->cluster_maxsize = 20000000; + tr->hevc = 1; + break; - case SCT_VP8: - tracktype = 1; - codec_id = "V_VP8"; - mk->cluster_maxsize = 10000000; - break; + case SCT_VP8: + tracktype = 1; + codec_id = "V_VP8"; + mk->cluster_maxsize = 10000000; + break; - case SCT_VP9: - tracktype = 1; - codec_id = "V_VP9"; - mk->cluster_maxsize = 10000000; - break; + case SCT_VP9: + tracktype = 1; + codec_id = "V_VP9"; + mk->cluster_maxsize = 10000000; + break; - case SCT_THEORA: - tracktype = 1; - codec_id = "V_THEORA"; - mk->cluster_maxsize = 5242880; - break; + case SCT_THEORA: + tracktype = 1; + codec_id = "V_THEORA"; + mk->cluster_maxsize = 5242880; + break; - case SCT_MPEG2AUDIO: - tracktype = 2; - codec_id = "A_MPEG/L2"; - if (ssc->es_audio_version == 3) - codec_id = "A_MPEG/L3"; - else if (ssc->es_audio_version == 1) - codec_id = "A_MPEG/L1"; - break; + case SCT_MPEG2AUDIO: + tracktype = 2; + codec_id = "A_MPEG/L2"; + if (ssc->es_audio_version == 3) + codec_id = "A_MPEG/L3"; + else if (ssc->es_audio_version == 1) + codec_id = "A_MPEG/L1"; + break; - case SCT_AC3: - tracktype = 2; - codec_id = "A_AC3"; - break; + case SCT_AC3: + tracktype = 2; + codec_id = "A_AC3"; + break; - case SCT_EAC3: - tracktype = 2; - codec_id = "A_EAC3"; - break; + case SCT_EAC3: + tracktype = 2; + codec_id = "A_EAC3"; + break; - case SCT_AC4: - tracktype = 2; - codec_id = "A_AC4"; - break; + case SCT_AC4: + tracktype = 2; + codec_id = "A_AC4"; + break; - case SCT_MP4A: - case SCT_AAC: - tracktype = 2; - codec_id = "A_AAC"; - bit_depth = 16; - break; + case SCT_MP4A: + case SCT_AAC: + tracktype = 2; + codec_id = "A_AAC"; + bit_depth = 16; + break; - case SCT_VORBIS: - tracktype = 2; - codec_id = "A_VORBIS"; - break; + case SCT_VORBIS: + tracktype = 2; + codec_id = "A_VORBIS"; + break; - case SCT_OPUS: - tracktype = 2; - codec_id = "A_OPUS"; - break; + case SCT_OPUS: + tracktype = 2; + codec_id = "A_OPUS"; + break; - case SCT_FLAC: - tracktype = 2; - codec_id = "A_FLAC"; - break; + case SCT_FLAC: + tracktype = 2; + codec_id = "A_FLAC"; + break; - case SCT_DVBSUB: - if (mk->dvbsub_skip) - goto disable; - tracktype = 0x11; - codec_id = "S_DVBSUB"; - break; + case SCT_DVBSUB: + if (mk->dvbsub_skip) + goto disable; + tracktype = 0x11; + codec_id = "S_DVBSUB"; + break; - case SCT_TEXTSUB: - tracktype = 0x11; - codec_id = "S_TEXT/UTF8"; - break; + case SCT_TEXTSUB: + tracktype = 0x11; + codec_id = "S_TEXT/UTF8"; + break; - default: -disable: - ssc->ssc_muxer_disabled = 1; - tr->disabled = 1; - continue; + default: + disable: + ssc->ssc_muxer_disabled = 1; + tr->disabled = 1; + continue; } - tr->tracknum = ++tracknum; + tr->tracknum = ++tracknum; tr->tracktype = tracktype; mk->has_video |= (tracktype == 1); @@ -401,71 +390,71 @@ disable: ebml_append_uint(t, 0x9c, 0); // Lacing ebml_append_string(t, 0x86, codec_id); - if(ssc->es_lang[0]) + if (ssc->es_lang[0]) ebml_append_string(t, 0x22b59c, ssc->es_lang); - switch(ssc->es_type) { - case SCT_HEVC: - case SCT_H264: - case SCT_MPEG2VIDEO: - case SCT_MP4A: - case SCT_AAC: - case SCT_OPUS: - if(ssc->ssc_gh) { - sbuf_t hdr; - sbuf_init(&hdr); - if (tr->avc) { - isom_write_avcc(&hdr, pktbuf_ptr(ssc->ssc_gh), - pktbuf_len(ssc->ssc_gh)); - } else if (tr->hevc) { - isom_write_hvcc(&hdr, pktbuf_ptr(ssc->ssc_gh), - pktbuf_len(ssc->ssc_gh)); - } else { - sbuf_append(&hdr, pktbuf_ptr(ssc->ssc_gh), - pktbuf_len(ssc->ssc_gh)); + switch (ssc->es_type) { + case SCT_HEVC: + case SCT_H264: + case SCT_MPEG2VIDEO: + case SCT_MP4A: + case SCT_AAC: + case SCT_OPUS: + if (ssc->ssc_gh) { + sbuf_t hdr; + sbuf_init(&hdr); + if (tr->avc) { + isom_write_avcc(&hdr, pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh)); + } else if (tr->hevc) { + isom_write_hvcc(&hdr, pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh)); + } else { + sbuf_append(&hdr, pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh)); + } + ebml_append_bin(t, 0x63a2, hdr.sb_data, hdr.sb_ptr); + sbuf_free(&hdr); } - ebml_append_bin(t, 0x63a2, hdr.sb_data, hdr.sb_ptr); - sbuf_free(&hdr); - } - break; + break; - case SCT_THEORA: - case SCT_VORBIS: - if(ssc->ssc_gh) { - htsbuf_queue_t *cp; - uint8_t *header_start[3]; - int header_len[3]; - int j; - int first_header_size = ssc->es_type == SCT_VORBIS ? 30 : 42; - - if(mk_split_xiph_headers(pktbuf_ptr(ssc->ssc_gh), pktbuf_len(ssc->ssc_gh), - first_header_size, header_start, header_len)) { - tvherror(LS_MKV, "failed to split xiph headers"); - break; + case SCT_THEORA: + case SCT_VORBIS: + if (ssc->ssc_gh) { + htsbuf_queue_t* cp; + uint8_t* header_start[3]; + int header_len[3]; + int j; + int first_header_size = ssc->es_type == SCT_VORBIS ? 30 : 42; + + if (mk_split_xiph_headers(pktbuf_ptr(ssc->ssc_gh), + pktbuf_len(ssc->ssc_gh), + first_header_size, + header_start, + header_len)) { + tvherror(LS_MKV, "failed to split xiph headers"); + break; + } + cp = htsbuf_queue_alloc(0); + ebml_append_xiph_size(cp, 2); + for (j = 0; j < 2; j++) + ebml_append_xiph_size(cp, header_len[j]); + for (j = 0; j < 3; j++) + htsbuf_append(cp, header_start[j], header_len[j]); + ebml_append_master(t, 0x63a2, cp); } - cp = htsbuf_queue_alloc(0); - ebml_append_xiph_size(cp, 2); - for (j = 0; j < 2; j++) - ebml_append_xiph_size(cp, header_len[j]); - for (j = 0; j < 3; j++) - htsbuf_append(cp, header_start[j], header_len[j]); - ebml_append_master(t, 0x63a2, cp); - } - break; + break; - case SCT_DVBSUB: - buf4[0] = ssc->es_composition_id >> 8; - buf4[1] = ssc->es_composition_id; - buf4[2] = ssc->es_ancillary_id >> 8; - buf4[3] = ssc->es_ancillary_id; - ebml_append_bin(t, 0x63a2, buf4, 4); - break; + case SCT_DVBSUB: + buf4[0] = ssc->es_composition_id >> 8; + buf4[1] = ssc->es_composition_id; + buf4[2] = ssc->es_ancillary_id >> 8; + buf4[3] = ssc->es_ancillary_id; + ebml_append_bin(t, 0x63a2, buf4, 4); + break; } - if(SCT_ISVIDEO(ssc->es_type)) { - htsbuf_queue_t *vi = htsbuf_queue_alloc(0); + if (SCT_ISVIDEO(ssc->es_type)) { + htsbuf_queue_t* vi = htsbuf_queue_alloc(0); - if(ssc->es_frame_duration) { + if (ssc->es_frame_duration) { int d = ts_rescale(ssc->es_frame_duration, 1000000000); ebml_append_uint(t, 0x23e383, d); } @@ -476,7 +465,9 @@ disable: if (mk->webm) { ebml_append_uint(vi, 0x54b0, (ssc->es_height * ssc->es_aspect_num) / ssc->es_aspect_den); ebml_append_uint(vi, 0x54ba, ssc->es_height); - ebml_append_uint(vi, 0x54b2, 0); // DisplayUnit: pixels because DAR is not supported by webm + ebml_append_uint(vi, + 0x54b2, + 0); // DisplayUnit: pixels because DAR is not supported by webm } else { ebml_append_uint(vi, 0x54b0, ssc->es_aspect_num); ebml_append_uint(vi, 0x54ba, ssc->es_aspect_den); @@ -487,8 +478,8 @@ disable: ebml_append_master(t, 0xe0, vi); } - if(SCT_ISAUDIO(ssc->es_type)) { - htsbuf_queue_t *au = htsbuf_queue_alloc(0); + if (SCT_ISAUDIO(ssc->es_type)) { + htsbuf_queue_t* au = htsbuf_queue_alloc(0); ebml_append_float(au, 0xb5, sri_to_rate(ssc->es_sri)); if (ssc->es_ext_sri) @@ -500,38 +491,34 @@ disable: ebml_append_master(t, 0xe1, au); } - ebml_append_master(q, 0xae, t); } return q; } - /** * */ -static int -mk_write_to_fd(mk_muxer_t *mk, htsbuf_queue_t *hq) -{ - htsbuf_data_t *hd; - int i = 0; - off_t oldpos = mk->fdpos; - - TAILQ_FOREACH(hd, &hq->hq_q, hd_link) +static int mk_write_to_fd(mk_muxer_t* mk, htsbuf_queue_t* hq) { + htsbuf_data_t* hd; + int i = 0; + off_t oldpos = mk->fdpos; + + TAILQ_FOREACH (hd, &hq->hq_q, hd_link) i++; - struct iovec *iov = alloca(sizeof(struct iovec) * i); + struct iovec* iov = alloca(sizeof(struct iovec) * i); i = 0; - TAILQ_FOREACH(hd, &hq->hq_q, hd_link) { - iov[i ].iov_base = hd->hd_data + hd->hd_data_off; - iov[i++].iov_len = hd->hd_data_len - hd->hd_data_off; + TAILQ_FOREACH (hd, &hq->hq_q, hd_link) { + iov[i].iov_base = hd->hd_data + hd->hd_data_off; + iov[i++].iov_len = hd->hd_data_len - hd->hd_data_off; } do { ssize_t r; - int iovcnt = i < dvr_iov_max ? i : dvr_iov_max; - if((r = writev(mk->fd, iov, iovcnt)) == -1) { + int iovcnt = i < dvr_iov_max ? i : dvr_iov_max; + if ((r = writev(mk->fd, iov, iovcnt)) == -1) { if (ERRNO_AGAIN(errno)) continue; mk->error = errno; @@ -540,55 +527,46 @@ mk_write_to_fd(mk_muxer_t *mk, htsbuf_queue_t *hq) mk->fdpos += r; i -= iovcnt; iov += iovcnt; - } while(i); + } while (i); if (mk->seekable) - muxer_cache_update((muxer_t *)mk, mk->fd, oldpos, 0); + muxer_cache_update((muxer_t*)mk, mk->fd, oldpos, 0); return 0; } - /** * */ -static void -mk_write_queue(mk_muxer_t *mk, htsbuf_queue_t *q) -{ - if(!mk->error && mk_write_to_fd(mk, q) && !MC_IS_EOS_ERROR(mk->error)) +static void mk_write_queue(mk_muxer_t* mk, htsbuf_queue_t* q) { + if (!mk->error && mk_write_to_fd(mk, q) && !MC_IS_EOS_ERROR(mk->error)) tvherror(LS_MKV, "%s: Write failed -- %s", mk->filename, strerror(errno)); htsbuf_queue_flush(q); } - /** * */ -static void -mk_write_master(mk_muxer_t *mk, uint32_t id, htsbuf_queue_t *p) -{ +static void mk_write_master(mk_muxer_t* mk, uint32_t id, htsbuf_queue_t* p) { htsbuf_queue_t q; htsbuf_queue_init(&q, 0); ebml_append_master(&q, id, p); mk_write_queue(mk, &q); } - /** * */ -static htsbuf_queue_t * -mk_build_segment_header(int64_t size) -{ - htsbuf_queue_t *q = htsbuf_queue_alloc(0); - uint8_t u8[8]; +static htsbuf_queue_t* mk_build_segment_header(int64_t size) { + htsbuf_queue_t* q = htsbuf_queue_alloc(0); + uint8_t u8[8]; ebml_append_id(q, 0x18538067); u8[0] = 1; - if(size == 0) { - memset(u8+1, 0xff, 7); + if (size == 0) { + memset(u8 + 1, 0xff, 7); } else { u8[1] = size >> 56; u8[2] = size >> 48; @@ -603,64 +581,52 @@ mk_build_segment_header(int64_t size) return q; } - /** * */ -static void -mk_write_segment_header(mk_muxer_t *mk, int64_t size) -{ - htsbuf_queue_t *q; +static void mk_write_segment_header(mk_muxer_t* mk, int64_t size) { + htsbuf_queue_t* q; q = mk_build_segment_header(size); mk_write_queue(mk, q); htsbuf_queue_free(q); } - /** * */ -static htsbuf_queue_t * -mk_build_one_chapter(mk_chapter_t *ch) -{ - htsbuf_queue_t *q = htsbuf_queue_alloc(0); +static htsbuf_queue_t* mk_build_one_chapter(mk_chapter_t* ch) { + htsbuf_queue_t* q = htsbuf_queue_alloc(0); ebml_append_uint(q, 0x73C4, ch->uuid); ebml_append_uint(q, 0x91, ch->ts * MATROSKA_TIMESCALE); - ebml_append_uint(q, 0x98, 0); //ChapterFlagHidden - ebml_append_uint(q, 0x4598, 1); //ChapterFlagEnabled + ebml_append_uint(q, 0x98, 0); // ChapterFlagHidden + ebml_append_uint(q, 0x4598, 1); // ChapterFlagEnabled return q; } - /** * */ -static htsbuf_queue_t * -mk_build_edition_entry(mk_muxer_t *mk) -{ - mk_chapter_t *ch; - htsbuf_queue_t *q = htsbuf_queue_alloc(0); +static htsbuf_queue_t* mk_build_edition_entry(mk_muxer_t* mk) { + mk_chapter_t* ch; + htsbuf_queue_t* q = htsbuf_queue_alloc(0); - ebml_append_uint(q, 0x45bd, 0); //EditionFlagHidden - ebml_append_uint(q, 0x45db, 1); //EditionFlagDefault + ebml_append_uint(q, 0x45bd, 0); // EditionFlagHidden + ebml_append_uint(q, 0x45db, 1); // EditionFlagDefault - TAILQ_FOREACH(ch, &mk->chapters, link) { + TAILQ_FOREACH (ch, &mk->chapters, link) { ebml_append_master(q, 0xB6, mk_build_one_chapter(ch)); } return q; } - /** * */ -static htsbuf_queue_t * -mk_build_chapters(mk_muxer_t *mk) -{ - htsbuf_queue_t *q = htsbuf_queue_alloc(0); +static htsbuf_queue_t* mk_build_chapters(mk_muxer_t* mk) { + htsbuf_queue_t* q = htsbuf_queue_alloc(0); ebml_append_master(q, 0x45b9, mk_build_edition_entry(mk)); @@ -670,31 +636,29 @@ mk_build_chapters(mk_muxer_t *mk) /** * */ -static void -mk_write_chapters(mk_muxer_t *mk) -{ - if(TAILQ_FIRST(&mk->chapters) == NULL) +static void mk_write_chapters(mk_muxer_t* mk) { + if (TAILQ_FIRST(&mk->chapters) == NULL) return; mk->chapters_pos = mk->fdpos; mk_write_master(mk, 0x1043a770, mk_build_chapters(mk)); } - /** * */ -static htsbuf_queue_t * -build_tag_string(const char *name, const char *value, const char *lang, - int targettype, const char *targettypename) -{ - htsbuf_queue_t *q = htsbuf_queue_alloc(0); - htsbuf_queue_t *st = htsbuf_queue_alloc(0); - - htsbuf_queue_t *t = htsbuf_queue_alloc(0); +static htsbuf_queue_t* build_tag_string(const char* name, + const char* value, + const char* lang, + int targettype, + const char* targettypename) { + htsbuf_queue_t* q = htsbuf_queue_alloc(0); + htsbuf_queue_t* st = htsbuf_queue_alloc(0); + + htsbuf_queue_t* t = htsbuf_queue_alloc(0); ebml_append_uint(t, 0x68ca, targettype ?: 50); - if(targettypename) + if (targettypename) ebml_append_string(t, 0x63ca, targettypename); ebml_append_master(q, 0x63c0, t); @@ -707,49 +671,40 @@ build_tag_string(const char *name, const char *value, const char *lang, return q; } - /** * */ -static htsbuf_queue_t * -build_tag_int(const char *name, int value, - int targettype, const char *targettypename) -{ +static htsbuf_queue_t* +build_tag_int(const char* name, int value, int targettype, const char* targettypename) { char str[64]; snprintf(str, sizeof(str), "%d", value); return build_tag_string(name, str, NULL, targettype, targettypename); } - /** * */ -static void -addtag(htsbuf_queue_t *q, htsbuf_queue_t *t) -{ +static void addtag(htsbuf_queue_t* q, htsbuf_queue_t* t) { ebml_append_master(q, 0x7373, t); } - /** * */ -static htsbuf_queue_t * -_mk_build_metadata(const dvr_entry_t *de, const epg_broadcast_t *ebc, - const char *comment) -{ - htsbuf_queue_t *q = htsbuf_queue_alloc(0); - char datestr[64], ctype[100]; - const epg_genre_t *eg = NULL; - epg_genre_t eg0; - struct tm tm; - time_t t; - channel_t *ch = ebc ? ebc->channel : NULL; - lang_str_t *ls = NULL, *ls2 = NULL; - const char *lang; - const lang_code_list_t *langs; - epg_episode_num_t num; - int tmp_age; +static htsbuf_queue_t* +_mk_build_metadata(const dvr_entry_t* de, const epg_broadcast_t* ebc, const char* comment) { + htsbuf_queue_t* q = htsbuf_queue_alloc(0); + char datestr[64], ctype[100]; + const epg_genre_t* eg = NULL; + epg_genre_t eg0; + struct tm tm; + time_t t; + channel_t* ch = ebc ? ebc->channel : NULL; + lang_str_t * ls = NULL, *ls2 = NULL; + const char* lang; + const lang_code_list_t* langs; + epg_episode_num_t num; + int tmp_age; if (de || ebc) { localtime_r(de ? &de->de_start : &ebc->start, &tm); @@ -757,43 +712,44 @@ _mk_build_metadata(const dvr_entry_t *de, const epg_broadcast_t *ebc, t = time(NULL); localtime_r(&t, &tm); } - snprintf(datestr, sizeof(datestr), - "%04d-%02d-%02d %02d:%02d:%02d", - tm.tm_year + 1900, - tm.tm_mon + 1, - tm.tm_mday, - tm.tm_hour, - tm.tm_min, - tm.tm_sec); + snprintf(datestr, + sizeof(datestr), + "%04d-%02d-%02d %02d:%02d:%02d", + tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec); addtag(q, build_tag_string("DATE_BROADCASTED", datestr, NULL, 0, NULL)); addtag(q, build_tag_string("ORIGINAL_MEDIA_TYPE", "TV", NULL, 0, NULL)); - if(de && de->de_content_type) { + if (de && de->de_content_type) { memset(&eg0, 0, sizeof(eg0)); eg0.code = de->de_content_type; - eg = &eg0; + eg = &eg0; } else if (ebc) { eg = LIST_FIRST(&ebc->genre); } - if(eg && epg_genre_get_str(eg, 1, 0, ctype, 100, NULL)) + if (eg && epg_genre_get_str(eg, 1, 0, ctype, 100, NULL)) addtag(q, build_tag_string("CONTENT_TYPE", ctype, NULL, 0, NULL)); - //TODO - MKV The spec suggests that this tag can consist of multiple value types. - //https://www.matroska.org/technical/tagging.html + // TODO - MKV The spec suggests that this tag can consist of multiple value types. + // https://www.matroska.org/technical/tagging.html //==> Depending on the COUNTRY it’s the format of the rating of a movie //==> (P, R, X in the USA, an age in other countries or a URI defining a logo). tmp_age = ebc->age_rating; addtag(q, build_tag_int("LAW_RATING", tmp_age, 0, NULL)); - if(ch) - addtag(q, build_tag_string("TVCHANNEL", - channel_get_name(ch, channel_blank_name), NULL, 0, NULL)); + if (ch) + addtag(q, + build_tag_string("TVCHANNEL", channel_get_name(ch, channel_blank_name), NULL, 0, NULL)); if (ebc && ebc->summary) ls = ebc->summary; - if(de && de->de_desc) + if (de && de->de_desc) ls2 = de->de_desc; else if (ebc && ebc->description) ls2 = ebc->description; @@ -802,30 +758,26 @@ _mk_build_metadata(const dvr_entry_t *de, const epg_broadcast_t *ebc, ls = ls2; if (ls) { - lang_str_ele_t *e; - RB_FOREACH(e, ls, link) + lang_str_ele_t* e; + RB_FOREACH (e, ls, link) addtag(q, build_tag_string("SUMMARY", e->str, e->lang, 0, NULL)); } if (ls2 && ls != ls2) { - lang_str_ele_t *e; - RB_FOREACH(e, ls2, link) + lang_str_ele_t* e; + RB_FOREACH (e, ls2, link) addtag(q, build_tag_string("DESCRIPTION", e->str, e->lang, 0, NULL)); } epg_broadcast_get_epnum(ebc, &num); - if(num.e_num) - addtag(q, build_tag_int("PART_NUMBER", num.e_num, - 0, NULL)); - if(num.s_num) - addtag(q, build_tag_int("PART_NUMBER", num.s_num, - 60, "SEASON")); - if(num.p_num) - addtag(q, build_tag_int("PART_NUMBER", num.p_num, - 40, "PART")); + if (num.e_num) + addtag(q, build_tag_int("PART_NUMBER", num.e_num, 0, NULL)); + if (num.s_num) + addtag(q, build_tag_int("PART_NUMBER", num.s_num, 60, "SEASON")); + if (num.p_num) + addtag(q, build_tag_int("PART_NUMBER", num.p_num, 40, "PART")); if (num.text) - addtag(q, build_tag_string("SYNOPSIS", - num.text, NULL, 0, NULL)); + addtag(q, build_tag_string("SYNOPSIS", num.text, NULL, 0, NULL)); if (comment) { lang = "eng"; @@ -839,60 +791,47 @@ _mk_build_metadata(const dvr_entry_t *de, const epg_broadcast_t *ebc, return q; } - /** * */ -static htsbuf_queue_t * -mk_build_one_metaseek(mk_muxer_t *mk, uint32_t id, off_t pos) -{ - htsbuf_queue_t *q = htsbuf_queue_alloc(0); +static htsbuf_queue_t* mk_build_one_metaseek(mk_muxer_t* mk, uint32_t id, off_t pos) { + htsbuf_queue_t* q = htsbuf_queue_alloc(0); ebml_append_idid(q, 0x53ab, id); ebml_append_uint(q, 0x53ac, pos - mk->segment_pos); return q; } - /** * */ -static void -mk_append_master(mk_muxer_t *mk, htsbuf_queue_t *q, - off_t id1, off_t id2, off_t val) -{ +static void mk_append_master(mk_muxer_t* mk, htsbuf_queue_t* q, off_t id1, off_t id2, off_t val) { ebml_append_master(q, id1, mk_build_one_metaseek(mk, id2, val)); - } /** * */ -static htsbuf_queue_t * -mk_build_metaseek(mk_muxer_t *mk) -{ - htsbuf_queue_t *q = htsbuf_queue_alloc(0); +static htsbuf_queue_t* mk_build_metaseek(mk_muxer_t* mk) { + htsbuf_queue_t* q = htsbuf_queue_alloc(0); - if(mk->segmentinfo_pos) + if (mk->segmentinfo_pos) mk_append_master(mk, q, 0x4dbb, 0x1549a966, mk->segmentinfo_pos); - if(mk->trackinfo_pos) + if (mk->trackinfo_pos) mk_append_master(mk, q, 0x4dbb, 0x1654ae6b, mk->trackinfo_pos); - if(mk->metadata_pos) + if (mk->metadata_pos) mk_append_master(mk, q, 0x4dbb, 0x1254c367, mk->metadata_pos); - if(mk->cue_pos) + if (mk->cue_pos) mk_append_master(mk, q, 0x4dbb, 0x1c53bb6b, mk->cue_pos); - if(mk->chapters_pos) + if (mk->chapters_pos) mk_append_master(mk, q, 0x4dbb, 0x1043a770, mk->chapters_pos); return q; } - /** * */ -static void -mk_write_metaseek(mk_muxer_t *mk, int first) -{ +static void mk_write_metaseek(mk_muxer_t* mk, int first) { htsbuf_queue_t q; htsbuf_queue_init(&q, 0); @@ -903,36 +842,32 @@ mk_write_metaseek(mk_muxer_t *mk, int first) ebml_append_pad(&q, 500 - q.hq_size); - if(first) { + if (first) { mk_write_to_fd(mk, &q); - } else if(mk->seekable) { + } else if (mk->seekable) { off_t prev = mk->fdpos; - mk->fdpos = mk->segment_pos; - if(lseek(mk->fd, mk->segment_pos, SEEK_SET) == (off_t) -1) + mk->fdpos = mk->segment_pos; + if (lseek(mk->fd, mk->segment_pos, SEEK_SET) == (off_t)-1) mk->error = errno; mk_write_queue(mk, &q); mk->fdpos = prev; - if(lseek(mk->fd, mk->fdpos, SEEK_SET) == (off_t) -1) + if (lseek(mk->fd, mk->fdpos, SEEK_SET) == (off_t)-1) mk->error = errno; } htsbuf_queue_flush(&q); } - /** * */ -static htsbuf_queue_t * -mk_build_segment(mk_muxer_t *mk, - streaming_start_t *ss) -{ - htsbuf_queue_t *p = htsbuf_queue_alloc(0); +static htsbuf_queue_t* mk_build_segment(mk_muxer_t* mk, streaming_start_t* ss) { + htsbuf_queue_t* p = htsbuf_queue_alloc(0); assert(mk->segment_pos != 0); // Meta seek - if(mk->seekable) + if (mk->seekable) ebml_append_pad(p, 500); mk->segmentinfo_pos = mk->segment_pos + p->hq_size; @@ -944,33 +879,27 @@ mk_build_segment(mk_muxer_t *mk, return p; } - /** * */ -static void -addcue(mk_muxer_t *mk, int64_t pts, int tracknum) -{ - mk_cue_t *mc = malloc(sizeof(mk_cue_t)); - mc->ts = pts; - mc->tracknum = tracknum; +static void addcue(mk_muxer_t* mk, int64_t pts, int tracknum) { + mk_cue_t* mc = malloc(sizeof(mk_cue_t)); + mc->ts = pts; + mc->tracknum = tracknum; mc->cluster_pos = mk->cluster_pos; TAILQ_INSERT_TAIL(&mk->cues, mc, link); } - /** * */ -static void -mk_add_chapter0(mk_muxer_t *mk, uint32_t uuid, int64_t ts) -{ - mk_chapter_t *ch; +static void mk_add_chapter0(mk_muxer_t* mk, uint32_t uuid, int64_t ts) { + mk_chapter_t* ch; ch = malloc(sizeof(mk_chapter_t)); ch->uuid = uuid; - ch->ts = ts; + ch->ts = ts; TAILQ_INSERT_TAIL(&mk->chapters, ch, link); } @@ -978,16 +907,14 @@ mk_add_chapter0(mk_muxer_t *mk, uint32_t uuid, int64_t ts) /** * */ -static void -mk_add_chapter(mk_muxer_t *mk, int64_t ts) -{ - mk_chapter_t *ch; - int uuid; +static void mk_add_chapter(mk_muxer_t* mk, int64_t ts) { + mk_chapter_t* ch; + int uuid; ch = TAILQ_LAST(&mk->chapters, mk_chapter_queue); - if(ch) { + if (ch) { /* don't add a new chapter if the previous one was added less than 5s ago */ - if(ts - ch->ts < 5000) + if (ts - ch->ts < 5000) return; uuid = ch->uuid + 1; @@ -1006,130 +933,122 @@ mk_add_chapter(mk_muxer_t *mk, int64_t ts) /** * */ -static void -mk_close_cluster(mk_muxer_t *mk) -{ - if(mk->cluster != NULL) +static void mk_close_cluster(mk_muxer_t* mk) { + if (mk->cluster != NULL) mk_write_master(mk, 0x1f43b675, mk->cluster); - mk->cluster = NULL; + mk->cluster = NULL; mk->cluster_last_close = mclk(); } - /** * */ -static void -mk_write_frame_i(mk_muxer_t *mk, mk_track_t *t, th_pkt_t *pkt) -{ - int64_t pts = pkt->pkt_pts, delta, nxt; +static void mk_write_frame_i(mk_muxer_t* mk, mk_track_t* t, th_pkt_t* pkt) { + int64_t pts = pkt->pkt_pts, delta, nxt; unsigned char c_delta_flags[3]; - const int video = t->tracktype == 1; - const int audio = t->tracktype == 2; - int keyframe = 0, skippable = 0; + const int video = t->tracktype == 1; + const int audio = t->tracktype == 2; + int keyframe = 0, skippable = 0; if (video) { keyframe = pkt->v.pkt_frametype < PKT_P_FRAME; skippable = pkt->v.pkt_frametype == PKT_B_FRAME; } - uint8_t *data = pktbuf_ptr(pkt->pkt_payload); - size_t len = pktbuf_len(pkt->pkt_payload); + uint8_t* data = pktbuf_ptr(pkt->pkt_payload); + size_t len = pktbuf_len(pkt->pkt_payload); - if(!data || len <= 0) + if (!data || len <= 0) return; - if(pts == PTS_UNSET) + if (pts == PTS_UNSET) // This is our best guess, it might be wrong but... oh well pts = t->nextpts; - if(pts != PTS_UNSET) { + if (pts != PTS_UNSET) { t->nextpts = pts + (pkt->pkt_duration >> (video ? pkt->v.pkt_field : 0)); nxt = ts_rescale(t->nextpts, 1000000000 / MATROSKA_TIMESCALE); - pts = ts_rescale(pts, 1000000000 / MATROSKA_TIMESCALE); + pts = ts_rescale(pts, 1000000000 / MATROSKA_TIMESCALE); - if((t->tracktype == 1 || t->tracktype == 2) && mk->totduration < nxt) + if ((t->tracktype == 1 || t->tracktype == 2) && mk->totduration < nxt) mk->totduration = nxt; delta = pts - mk->cluster_tc; - if((keyframe || !mk->has_video) && (delta > 30000ll || delta < -30000ll)) + if ((keyframe || !mk->has_video) && (delta > 30000ll || delta < -30000ll)) mk_close_cluster(mk); } else { return; } - if(mk->cluster) { + if (mk->cluster) { - if(keyframe && - (mk->cluster->hq_size > mk->cluster_maxsize || - mk->cluster_last_close + sec2mono(1) < mclk())) + if (keyframe && + (mk->cluster->hq_size > mk->cluster_maxsize || + mk->cluster_last_close + sec2mono(1) < mclk())) mk_close_cluster(mk); - else if(!mk->has_video && - (mk->cluster->hq_size > mk->cluster_maxsize/40 || - mk->cluster_last_close + sec2mono(1) < mclk())) + else if (!mk->has_video && + (mk->cluster->hq_size > mk->cluster_maxsize / 40 || + mk->cluster_last_close + sec2mono(1) < mclk())) mk_close_cluster(mk); - else if(mk->cluster->hq_size > mk->cluster_maxsize) + else if (mk->cluster->hq_size > mk->cluster_maxsize) mk_close_cluster(mk); - } - if(mk->cluster == NULL) { + if (mk->cluster == NULL) { mk->cluster_tc = pts; - mk->cluster = htsbuf_queue_alloc(0); + mk->cluster = htsbuf_queue_alloc(0); mk->cluster_pos = mk->fdpos; - mk->addcue = 1; + mk->addcue = 1; ebml_append_uint(mk->cluster, 0xe7, mk->cluster_tc); delta = 0; } - if(mk->addcue && keyframe) { + if (mk->addcue && keyframe) { mk->addcue = 0; addcue(mk, pts, t->tracknum); } - if(t->type == SCT_AAC || t->type == SCT_MP4A) { + if (t->type == SCT_AAC || t->type == SCT_MP4A) { // Skip ADTS header - if(len < 7) + if (len < 7) return; len -= 7; data += 7; } - ebml_append_id(mk->cluster, 0xa3 ); // SimpleBlock + ebml_append_id(mk->cluster, 0xa3); // SimpleBlock ebml_append_size(mk->cluster, len + 4); ebml_append_size(mk->cluster, t->tracknum); c_delta_flags[0] = delta >> 8; c_delta_flags[1] = delta; - if (audio && pkt->a.pkt_keyframe) keyframe = 1; + if (audio && pkt->a.pkt_keyframe) + keyframe = 1; c_delta_flags[2] = (keyframe << 7) | skippable; htsbuf_append(mk->cluster, c_delta_flags, 3); htsbuf_append(mk->cluster, data, len); } - /** * */ -static void -mk_write_cues(mk_muxer_t *mk) -{ - mk_cue_t *mc; +static void mk_write_cues(mk_muxer_t* mk) { + mk_cue_t* mc; htsbuf_queue_t *q, *c, *p; - if(TAILQ_FIRST(&mk->cues) == NULL) + if (TAILQ_FIRST(&mk->cues) == NULL) return; q = htsbuf_queue_alloc(0); - while((mc = TAILQ_FIRST(&mk->cues)) != NULL) { + while ((mc = TAILQ_FIRST(&mk->cues)) != NULL) { TAILQ_REMOVE(&mk->cues, mc, link); c = htsbuf_queue_alloc(0); @@ -1149,16 +1068,13 @@ mk_write_cues(mk_muxer_t *mk) mk_write_master(mk, 0x1c53bb6b, q); } - /** * Append a packet to the muxer */ -static int -mk_mux_write_pkt(mk_muxer_t *mk, th_pkt_t *pkt) -{ - int i, mark; - mk_track_t *t = NULL; - th_pkt_t *opkt, *tpkt; +static int mk_mux_write_pkt(mk_muxer_t* mk, th_pkt_t* pkt) { + int i, mark; + mk_track_t* t = NULL; + th_pkt_t * opkt, *tpkt; for (i = 0; i < mk->ntracks; i++) { t = &mk->tracks[i]; @@ -1166,67 +1082,68 @@ mk_mux_write_pkt(mk_muxer_t *mk, th_pkt_t *pkt) break; } - if(i >= mk->ntracks || pkt->pkt_payload == NULL) { + if (i >= mk->ntracks || pkt->pkt_payload == NULL) { pkt_ref_dec(pkt); return mk->error; } - if (mk->dvbsub_reorder && - pkt->pkt_type == SCT_DVBSUB && + if (mk->dvbsub_reorder && pkt->pkt_type == SCT_DVBSUB && pts_diff(pkt->pkt_pcr, pkt->pkt_pts) > 90000) { - tvhtrace(LS_MKV, "insert pkt to holdq: pts %"PRId64", pcr %"PRId64", diff %"PRId64"\n", pkt->pkt_pcr, pkt->pkt_pts, pts_diff(pkt->pkt_pcr, pkt->pkt_pts)); + tvhtrace(LS_MKV, + "insert pkt to holdq: pts %" PRId64 ", pcr %" PRId64 ", diff %" PRId64 "\n", + pkt->pkt_pcr, + pkt->pkt_pts, + pts_diff(pkt->pkt_pcr, pkt->pkt_pts)); pktref_enqueue_sorted(&mk->holdq, pkt, mk_pktref_cmp); return mk->error; } mark = 0; - if(SCT_ISAUDIO(pkt->pkt_type)) { + if (SCT_ISAUDIO(pkt->pkt_type)) { while ((opkt = pktref_first(&mk->holdq)) != NULL) { if (pts_diff(pkt->pkt_pts, opkt->pkt_pts) > 90000) break; opkt = pktref_get_first(&mk->holdq); - tvhtrace(LS_MKV, "hold push, pts %"PRId64", audio pts %"PRId64"\n", opkt->pkt_pts, pkt->pkt_pts); + tvhtrace(LS_MKV, + "hold push, pts %" PRId64 ", audio pts %" PRId64 "\n", + opkt->pkt_pts, + pkt->pkt_pts); tpkt = pkt_copy_shallow(opkt); pkt_ref_dec(opkt); tpkt->pkt_pcr = tpkt->pkt_pts; mk_mux_write_pkt(mk, tpkt); } - if(pkt->a.pkt_channels != t->channels && - pkt->a.pkt_channels) { - mark = 1; + if (pkt->a.pkt_channels != t->channels && pkt->a.pkt_channels) { + mark = 1; t->channels = pkt->a.pkt_channels; } - if(pkt->a.pkt_sri != t->sri && - pkt->a.pkt_sri) { - mark = 1; - t->sri = pkt->a.pkt_sri; + if (pkt->a.pkt_sri != t->sri && pkt->a.pkt_sri) { + mark = 1; + t->sri = pkt->a.pkt_sri; t->ext_sri = pkt->a.pkt_ext_sri; } } else if (SCT_ISVIDEO(pkt->pkt_type)) { - if(pkt->v.pkt_aspect_num != t->aspect_num && - pkt->v.pkt_aspect_num) { - mark = 1; + if (pkt->v.pkt_aspect_num != t->aspect_num && pkt->v.pkt_aspect_num) { + mark = 1; t->aspect_num = pkt->v.pkt_aspect_num; } - if(pkt->v.pkt_aspect_den != t->aspect_den && - pkt->v.pkt_aspect_den) { - mark = 1; + if (pkt->v.pkt_aspect_den != t->aspect_den && pkt->v.pkt_aspect_den) { + mark = 1; t->aspect_den = pkt->v.pkt_aspect_den; } } - if(pkt->pkt_commercial != t->commercial && - pkt->pkt_commercial != COMMERCIAL_UNKNOWN) { - mark = 1; + if (pkt->pkt_commercial != t->commercial && pkt->pkt_commercial != COMMERCIAL_UNKNOWN) { + mark = 1; t->commercial = pkt->pkt_commercial; } - if(mark) + if (mark) mk_mux_insert_chapter(mk); - if(t->hevc) { + if (t->hevc) { pkt = hevc_convert_pkt(opkt = pkt); pkt_ref_dec(opkt); - } else if(t->avc) { + } else if (t->avc) { pkt = avc_convert_pkt(opkt = pkt); pkt_ref_dec(opkt); } @@ -1238,26 +1155,20 @@ mk_mux_write_pkt(mk_muxer_t *mk, th_pkt_t *pkt) return mk->error; } - /** * Insert a new chapter at the current location */ -static int -mk_mux_insert_chapter(mk_muxer_t *mk) -{ - if(mk->totduration != PTS_UNSET) +static int mk_mux_insert_chapter(mk_muxer_t* mk) { + if (mk->totduration != PTS_UNSET) mk_add_chapter(mk, mk->totduration); return mk->error; } - /** * Close the muxer */ -static int -mk_mux_close(mk_muxer_t *mk) -{ +static int mk_mux_close(mk_muxer_t* mk) { int64_t totsize; mk_close_cluster(mk); mk_write_cues(mk); @@ -1266,29 +1177,35 @@ mk_mux_close(mk_muxer_t *mk) mk_write_metaseek(mk, 0); totsize = mk->fdpos; - if(mk->seekable) { + if (mk->seekable) { // Rewrite segment info to update duration - if(lseek(mk->fd, mk->segmentinfo_pos, SEEK_SET) == mk->segmentinfo_pos) + if (lseek(mk->fd, mk->segmentinfo_pos, SEEK_SET) == mk->segmentinfo_pos) mk_write_master(mk, 0x1549a966, mk_build_segment_info(mk)); else { mk->error = errno; - tvherror(LS_MKV, "%s: Unable to write duration, seek failed -- %s", - mk->filename, strerror(errno)); + tvherror(LS_MKV, + "%s: Unable to write duration, seek failed -- %s", + mk->filename, + strerror(errno)); } // Rewrite segment header to update total size - if(lseek(mk->fd, mk->segment_header_pos, SEEK_SET) == mk->segment_header_pos) { + if (lseek(mk->fd, mk->segment_header_pos, SEEK_SET) == mk->segment_header_pos) { mk_write_segment_header(mk, totsize - mk->segment_header_pos - 12); } else { mk->error = errno; - tvherror(LS_MKV, "%s: Unable to write total size, seek failed -- %s", - mk->filename, strerror(errno)); + tvherror(LS_MKV, + "%s: Unable to write total size, seek failed -- %s", + mk->filename, + strerror(errno)); } - if(close(mk->fd)) { + if (close(mk->fd)) { mk->error = errno; - tvherror(LS_MKV, "%s: Unable to close the file descriptor, close failed -- %s", - mk->filename, strerror(errno)); + tvherror(LS_MKV, + "%s: Unable to close the file descriptor, close failed -- %s", + mk->filename, + strerror(errno)); } } @@ -1298,30 +1215,28 @@ mk_mux_close(mk_muxer_t *mk) /** * Figure out the mimetype */ -static const char* -mkv_muxer_mime(muxer_t* m, const struct streaming_start *ss) -{ - int i; - int has_audio; - int has_video; - const streaming_start_component_t *ssc; +static const char* mkv_muxer_mime(muxer_t* m, const struct streaming_start* ss) { + int i; + int has_audio; + int has_video; + const streaming_start_component_t* ssc; has_audio = 0; has_video = 0; - for(i=0; i < ss->ss_num_components; i++) { + for (i = 0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; - if(ssc->ssc_disabled) + if (ssc->ssc_disabled) continue; has_video |= SCT_ISVIDEO(ssc->es_type); has_audio |= SCT_ISAUDIO(ssc->es_type); } - if(has_video) + if (has_video) return muxer_container_type2mime(m->m_config.m_type, 1); - else if(has_audio) + else if (has_audio) return muxer_container_type2mime(m->m_config.m_type, 0); else return muxer_container_type2mime(MC_UNKNOWN, 0); @@ -1330,15 +1245,13 @@ mkv_muxer_mime(muxer_t* m, const struct streaming_start *ss) /** * Init the muxer with a title and some tracks */ -static int -mkv_muxer_init(muxer_t *m, streaming_start_t *ss, const char *name) -{ - mk_muxer_t *mk = (mk_muxer_t *)m; +static int mkv_muxer_init(muxer_t* m, streaming_start_t* ss, const char* name) { + mk_muxer_t* mk = (mk_muxer_t*)m; htsbuf_queue_t q, *a; uuid_random(mk->uuid, sizeof(mk->uuid)); - if(name) + if (name) mk->title = strdup(name); else mk->title = strdup(mk->filename); @@ -1351,12 +1264,12 @@ mkv_muxer_init(muxer_t *m, streaming_start_t *ss, const char *name) ebml_append_master(&q, 0x1a45dfa3, mk_build_ebmlheader(mk)); mk->segment_header_pos = q.hq_size; - a = mk_build_segment_header(0); + a = mk_build_segment_header(0); htsbuf_appendq(&q, a); htsbuf_queue_free(a); mk->segment_pos = q.hq_size; - a = mk_build_segment(mk, ss); + a = mk_build_segment(mk, ss); htsbuf_appendq(&q, a); htsbuf_queue_free(a); @@ -1367,16 +1280,13 @@ mkv_muxer_init(muxer_t *m, streaming_start_t *ss, const char *name) return mk->error; } - /** * Insert a new chapter at the current location */ -static int -mkv_muxer_add_marker(muxer_t* m) -{ - mk_muxer_t *mk = (mk_muxer_t*)m; +static int mkv_muxer_add_marker(muxer_t* m) { + mk_muxer_t* mk = (mk_muxer_t*)m; - if(mk_mux_insert_chapter(mk)) { + if (mk_mux_insert_chapter(mk)) { mk->m_errors++; return -1; } @@ -1384,89 +1294,74 @@ mkv_muxer_add_marker(muxer_t* m) return 0; } - /** * Multisegment matroska files do exist but I am not sure if they are supported * by many media players. For now, we'll treat it as an error. */ -static int -mkv_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss) -{ - mk_muxer_t *mk = (mk_muxer_t*)m; +static int mkv_muxer_reconfigure(muxer_t* m, const struct streaming_start* ss) { + mk_muxer_t* mk = (mk_muxer_t*)m; mk->m_errors++; return -1; } - /** * Open the muxer as a stream muxer (using a non-seekable socket) */ -static int -mkv_muxer_open_stream(muxer_t *m, int fd) -{ - mk_muxer_t *mk = (mk_muxer_t*)m; +static int mkv_muxer_open_stream(muxer_t* m, int fd) { + mk_muxer_t* mk = (mk_muxer_t*)m; - mk->filename = strdup("Live stream"); - mk->fd = fd; + mk->filename = strdup("Live stream"); + mk->fd = fd; mk->cluster_maxsize = 0; - mk->totduration = 0; + mk->totduration = 0; return 0; } - /** * Open a file */ -static int -mkv_muxer_open_file(muxer_t *m, const char *filename) -{ - mk_muxer_t *mk = (mk_muxer_t*)m; - int fd, permissions = mk->m_config.m_file_permissions; +static int mkv_muxer_open_file(muxer_t* m, const char* filename) { + mk_muxer_t* mk = (mk_muxer_t*)m; + int fd, permissions = mk->m_config.m_file_permissions; - tvhtrace(LS_MKV, "Creating file \"%s\" with file permissions \"%o\"", - filename, permissions); + tvhtrace(LS_MKV, "Creating file \"%s\" with file permissions \"%o\"", filename, permissions); fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, permissions); - if(fd < 0) { + if (fd < 0) { mk->error = errno; - tvherror(LS_MKV, "%s: Unable to create file, open failed -- %s", - mk->filename, strerror(errno)); + tvherror(LS_MKV, "%s: Unable to create file, open failed -- %s", mk->filename, strerror(errno)); mk->m_errors++; return -1; } /* bypass umask settings */ if (fchmod(fd, permissions)) - tvherror(LS_MKV, "%s: Unable to change permissions -- %s", - filename, strerror(errno)); + tvherror(LS_MKV, "%s: Unable to change permissions -- %s", filename, strerror(errno)); - mk->filename = strdup(filename); - mk->fd = fd; + mk->filename = strdup(filename); + mk->fd = fd; mk->cluster_maxsize = 2000000; - mk->seekable = 1; - mk->totduration = 0; + mk->seekable = 1; + mk->totduration = 0; return 0; } - /** * Write a packet to the muxer */ -static int -mkv_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data) -{ - th_pkt_t *pkt = (th_pkt_t*)data; - mk_muxer_t *mk = (mk_muxer_t*)m; - int r; +static int mkv_muxer_write_pkt(muxer_t* m, streaming_message_type_t smt, void* data) { + th_pkt_t* pkt = (th_pkt_t*)data; + mk_muxer_t* mk = (mk_muxer_t*)m; + int r; assert(smt == SMT_PACKET); - if((r = mk_mux_write_pkt(mk, pkt)) != 0) { + if ((r = mk_mux_write_pkt(mk, pkt)) != 0) { if (MC_IS_EOS_ERROR(r)) mk->m_eos = 1; mk->m_errors++; @@ -1476,18 +1371,14 @@ mkv_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data) return 0; } - /** * Append meta data when a channel changes its programme */ -static int -mkv_muxer_write_meta(muxer_t *m, struct epg_broadcast *eb, - const char *comment) -{ - mk_muxer_t *mk = (mk_muxer_t*)m; +static int mkv_muxer_write_meta(muxer_t* m, struct epg_broadcast* eb, const char* comment) { + mk_muxer_t* mk = (mk_muxer_t*)m; htsbuf_queue_t q; - if(!mk->metadata_pos) + if (!mk->metadata_pos) mk->metadata_pos = mk->fdpos; htsbuf_queue_init(&q, 0); @@ -1502,16 +1393,13 @@ mkv_muxer_write_meta(muxer_t *m, struct epg_broadcast *eb, return 0; } - /** * Close the muxer and append trailer to output */ -static int -mkv_muxer_close(muxer_t *m) -{ - mk_muxer_t *mk = (mk_muxer_t*)m; +static int mkv_muxer_close(muxer_t* m) { + mk_muxer_t* mk = (mk_muxer_t*)m; - if(mk_mux_close(mk)) { + if (mk_mux_close(mk)) { mk->m_errors++; return -1; } @@ -1521,19 +1409,16 @@ mkv_muxer_close(muxer_t *m) return 0; } - /** * Free all memory associated with the muxer */ -static void -mkv_muxer_destroy(muxer_t *m) -{ - mk_muxer_t *mk = (mk_muxer_t*)m; - mk_chapter_t *ch; +static void mkv_muxer_destroy(muxer_t* m) { + mk_muxer_t* mk = (mk_muxer_t*)m; + mk_chapter_t* ch; pktref_clear_queue(&mk->holdq); - while((ch = TAILQ_FIRST(&mk->chapters)) != NULL) { + while ((ch = TAILQ_FIRST(&mk->chapters)) != NULL) { TAILQ_REMOVE(&mk->chapters, ch, link); free(ch); } @@ -1549,17 +1434,14 @@ mkv_muxer_destroy(muxer_t *m) /** * Create a new builtin muxer */ -muxer_t* -mkv_muxer_create(const muxer_config_t *m_cfg, - const muxer_hints_t *hints) -{ - mk_muxer_t *mk; - const char *agent = hints ? hints->mh_agent : NULL; - - if(m_cfg->m_type != MC_MATROSKA && m_cfg->m_type != MC_WEBM) +muxer_t* mkv_muxer_create(const muxer_config_t* m_cfg, const muxer_hints_t* hints) { + mk_muxer_t* mk; + const char* agent = hints ? hints->mh_agent : NULL; + + if (m_cfg->m_type != MC_MATROSKA && m_cfg->m_type != MC_WEBM) return NULL; - mk = calloc(1, sizeof(mk_muxer_t)); + mk = calloc(1, sizeof(mk_muxer_t)); mk->m_open_stream = mkv_muxer_open_stream; mk->m_open_file = mkv_muxer_open_file; mk->m_mime = mkv_muxer_mime; @@ -1578,7 +1460,7 @@ mkv_muxer_create(const muxer_config_t *m_cfg, * VLC has no support for MKV S_DVBSUB codec format */ if (agent) - mk->dvbsub_skip = strstr(agent, "LibVLC/") != NULL; + mk->dvbsub_skip = strstr(agent, "LibVLC/") != NULL; TAILQ_INIT(&mk->holdq); diff --git a/src/muxer/muxer_mkv.h b/src/muxer/muxer_mkv.h index 9abd2e5a9..45b899514 100644 --- a/src/muxer/muxer_mkv.h +++ b/src/muxer/muxer_mkv.h @@ -21,6 +21,6 @@ #include "muxer.h" -muxer_t *mkv_muxer_create (const muxer_config_t *m_cfg, const muxer_hints_t *hints); +muxer_t* mkv_muxer_create(const muxer_config_t* m_cfg, const muxer_hints_t* hints); #endif /* MUXER_MKV_H_ */ diff --git a/src/muxer/muxer_pass.c b/src/muxer/muxer_pass.c index 95ba86e52..ece5bbff9 100644 --- a/src/muxer/muxer_pass.c +++ b/src/muxer/muxer_pass.c @@ -42,15 +42,15 @@ typedef struct pass_muxer { int pm_spawn_pid; /* Filename is also used for logging */ - char *pm_filename; + char* pm_filename; /* Streaming components */ - streaming_start_t *pm_ss; + streaming_start_t* pm_ss; /* TS muxing */ - uint8_t pm_rewrite_sdt; - uint8_t pm_rewrite_nit; - uint8_t pm_rewrite_eit; + uint8_t pm_rewrite_sdt; + uint8_t pm_rewrite_nit; + uint8_t pm_rewrite_eit; uint16_t pm_pmt_pid; uint16_t pm_src_sid; @@ -68,19 +68,15 @@ typedef struct pass_muxer { } pass_muxer_t; - -static void -pass_muxer_write(muxer_t *m, const void *data, size_t size); +static void pass_muxer_write(muxer_t* m, const void* data, size_t size); /* * Rewrite a PAT packet to only include the service included in the transport stream. */ -static void -pass_muxer_pat_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) -{ - pass_muxer_t *pm; - uint8_t out[16], *ob; - int ol, l; +static void pass_muxer_pat_cb(mpegts_psi_table_t* mt, const uint8_t* buf, int len) { + pass_muxer_t* pm; + uint8_t out[16], *ob; + int ol, l; if (buf[0]) return; @@ -95,15 +91,15 @@ pass_muxer_pat_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) out[4] = pm->pm_dst_tsid; out[7] = 0; - out[8] = pm->pm_dst_sid >> 8; - out[9] = pm->pm_dst_sid; + out[8] = pm->pm_dst_sid >> 8; + out[9] = pm->pm_dst_sid; out[10] = 0xe0 | ((pm->pm_pmt_pid & 0x1f00) >> 8); out[11] = pm->pm_pmt_pid & 0x00ff; ol = dvb_table_append_crc32(out, 12, sizeof(out)); if (ol > 0 && (l = dvb_table_remux(mt, out, ol, &ob)) > 0) { - pass_muxer_write((muxer_t *)pm, ob, l); + pass_muxer_write((muxer_t*)pm, ob, l); free(ob); } } @@ -111,21 +107,19 @@ pass_muxer_pat_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) /* * */ -static void -pass_muxer_pmt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) -{ - pass_muxer_t *pm; - uint8_t out[1024], *ob; - uint16_t sid, pid; - int l, ol, i; - const streaming_start_component_t *ssc; +static void pass_muxer_pmt_cb(mpegts_psi_table_t* mt, const uint8_t* buf, int len) { + pass_muxer_t* pm; + uint8_t out[1024], *ob; + uint16_t sid, pid; + int l, ol, i; + const streaming_start_component_t* ssc; memcpy(out, buf, ol = 3); buf += ol; len -= ol; sid = (buf[0] << 8) | buf[1]; - l = (buf[7] & 0x0f) << 8 | buf[8]; + l = (buf[7] & 0x0f) << 8 | buf[8]; if (l > len - 9) return; @@ -138,13 +132,13 @@ pass_muxer_pmt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) out[ol + 1] = pm->pm_dst_sid & 0xff; memcpy(out + ol + 2, buf + 2, 7); - ol += 9; /* skip common descriptors */ + ol += 9; /* skip common descriptors */ buf += 9 + l; len -= 9 + l; /* no common descriptors */ - out[7+3] &= 0xf0; - out[8+3] = 0; + out[7 + 3] &= 0xf0; + out[8 + 3] = 0; while (len >= 5) { pid = (buf[1] & 0x1f) << 8 | buf[2]; @@ -179,7 +173,7 @@ pass_muxer_pmt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) ol = dvb_table_append_crc32(out, ol, sizeof(out)); if (ol > 0 && (l = dvb_table_remux(mt, out, ol, &ob)) > 0) { - pass_muxer_write((muxer_t *)pm, ob, l); + pass_muxer_write((muxer_t*)pm, ob, l); free(ob); } } @@ -187,20 +181,18 @@ pass_muxer_pmt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) /* * */ -static void -pass_muxer_sdt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) -{ - pass_muxer_t *pm; - uint8_t out[1024], *ob; - uint16_t sid; - int l, ol; +static void pass_muxer_sdt_cb(mpegts_psi_table_t* mt, const uint8_t* buf, int len) { + pass_muxer_t* pm; + uint8_t out[1024], *ob; + uint16_t sid; + int l, ol; /* filter out the other transponders */ if (buf[0] != 0x42) return; pm = (pass_muxer_t*)mt->mt_opaque; - ol = 8 + 3; + ol = 8 + 3; memcpy(out, buf, ol); buf += ol; len -= ol; @@ -212,7 +204,7 @@ pass_muxer_sdt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) while (len >= 5) { sid = (buf[0] << 8) | buf[1]; - l = (buf[3] & 0x0f) << 8 | buf[4]; + l = (buf[3] & 0x0f) << 8 | buf[4]; if (l > len - 5) return; if (sid != pm->pm_src_sid) { @@ -240,7 +232,7 @@ pass_muxer_sdt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) ol = dvb_table_append_crc32(out, ol, sizeof(out)); if (ol > 0 && (l = dvb_table_remux(mt, out, ol, &ob)) > 0) { - pass_muxer_write((muxer_t *)pm, ob, l); + pass_muxer_write((muxer_t*)pm, ob, l); free(ob); } } @@ -248,12 +240,10 @@ pass_muxer_sdt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) /* * */ -static void -pass_muxer_nit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) -{ - pass_muxer_t *pm; - uint8_t out[4096], *ob, dtag; - int l, ol, lptr, dlen; +static void pass_muxer_nit_cb(mpegts_psi_table_t* mt, const uint8_t* buf, int len) { + pass_muxer_t* pm; + uint8_t out[4096], *ob, dtag; + int l, ol, lptr, dlen; /* filter out the other networks */ if (buf[0] != 0x40) @@ -288,7 +278,7 @@ pass_muxer_nit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) dlen += 2; buf += dlen; len -= dlen; - l -= dlen; + l -= dlen; } out[8] &= 0xf0; out[8] |= ((ol - 10) >> 8) & 0x0f; @@ -317,8 +307,8 @@ pass_muxer_nit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) out[ol++] = pm->pm_dst_sid; out[ol++] = 0x11; /* update section length */ - out[lptr+0] = 0xf0 | (ol - lptr - 2) >> 8; - out[lptr+1] = (ol - lptr - 2) & 0xff; + out[lptr + 0] = 0xf0 | (ol - lptr - 2) >> 8; + out[lptr + 1] = (ol - lptr - 2) & 0xff; /* update section length */ out[1] = (out[1] & 0xf0) | ((ol + 4 - 3) >> 8); @@ -327,7 +317,7 @@ pass_muxer_nit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) ol = dvb_table_append_crc32(out, ol, sizeof(out)); if (ol > 0 && (l = dvb_table_remux(mt, out, ol, &ob)) > 0) { - pass_muxer_write((muxer_t *)pm, ob, l); + pass_muxer_write((muxer_t*)pm, ob, l); free(ob); } } @@ -335,29 +325,27 @@ pass_muxer_nit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) /* * */ -static void -pass_muxer_eit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) -{ - pass_muxer_t *pm; - uint16_t sid; - uint8_t *sbuf, *out; - int olen; +static void pass_muxer_eit_cb(mpegts_psi_table_t* mt, const uint8_t* buf, int len) { + pass_muxer_t* pm; + uint16_t sid; + uint8_t * sbuf, *out; + int olen; /* filter out wrong tables */ if (buf[0] < 0x4e || buf[0] > 0x6f || len < 14) return; - pm = (pass_muxer_t*)mt->mt_opaque; + pm = (pass_muxer_t*)mt->mt_opaque; sid = (buf[3] << 8) | buf[4]; /* TODO: set free_CA_mode bit to zero */ sbuf = malloc(len + 4); memcpy(sbuf, buf, len); - sbuf[3] = pm->pm_dst_sid >> 8; - sbuf[4] = pm->pm_dst_sid; - sbuf[8] = pm->pm_dst_tsid >> 8; - sbuf[9] = pm->pm_dst_tsid; + sbuf[3] = pm->pm_dst_sid >> 8; + sbuf[4] = pm->pm_dst_sid; + sbuf[8] = pm->pm_dst_tsid >> 8; + sbuf[9] = pm->pm_dst_tsid; sbuf[10] = pm->pm_dst_onid >> 8; sbuf[11] = pm->pm_dst_onid; @@ -370,7 +358,7 @@ pass_muxer_eit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) len = dvb_table_append_crc32(sbuf, len, len + 4); if (len > 0 && (olen = dvb_table_remux(mt, sbuf, len, &out)) > 0) { - pass_muxer_write((muxer_t *)pm, out, olen); + pass_muxer_write((muxer_t*)pm, out, olen); free(out); } @@ -380,16 +368,14 @@ pass_muxer_eit_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) /** * Figure out the mime-type for the muxed data stream */ -static const char* -pass_muxer_mime(muxer_t* m, const struct streaming_start *ss) -{ - int i; - int has_audio; - int has_video; - muxer_container_type_t mc; - const streaming_start_component_t *ssc; - const source_info_t *si = &ss->ss_si; - const char *mime = m->m_config.u.pass.m_mime; +static const char* pass_muxer_mime(muxer_t* m, const struct streaming_start* ss) { + int i; + int has_audio; + int has_video; + muxer_container_type_t mc; + const streaming_start_component_t* ssc; + const source_info_t* si = &ss->ss_si; + const char* mime = m->m_config.u.pass.m_mime; if (mime && mime[0]) return mime; @@ -397,60 +383,57 @@ pass_muxer_mime(muxer_t* m, const struct streaming_start *ss) has_audio = 0; has_video = 0; - for(i=0; i < ss->ss_num_components; i++) { + for (i = 0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; - if(ssc->ssc_disabled) + if (ssc->ssc_disabled) continue; has_video |= SCT_ISVIDEO(ssc->es_type); has_audio |= SCT_ISAUDIO(ssc->es_type); } - if(si->si_type == S_MPEG_TS) + if (si->si_type == S_MPEG_TS) mc = MC_MPEGTS; - else if(si->si_type == S_MPEG_PS) + else if (si->si_type == S_MPEG_PS) mc = MC_MPEGPS; else mc = MC_UNKNOWN; - if(has_video) + if (has_video) return muxer_container_type2mime(mc, 1); - else if(has_audio) + else if (has_audio) return muxer_container_type2mime(mc, 0); else return muxer_container_type2mime(MC_UNKNOWN, 0); } - /** * Generate the pmt and pat from a streaming start message */ -static int -pass_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss) -{ - pass_muxer_t *pm = (pass_muxer_t*)m; - const streaming_start_component_t *ssc; - int i; - - pm->pm_src_sid = ss->ss_service_id; - pm->pm_src_tsid = ss->ss_si.si_tsid; - pm->pm_src_onid = ss->ss_si.si_onid; +static int pass_muxer_reconfigure(muxer_t* m, const struct streaming_start* ss) { + pass_muxer_t* pm = (pass_muxer_t*)m; + const streaming_start_component_t* ssc; + int i; + + pm->pm_src_sid = ss->ss_service_id; + pm->pm_src_tsid = ss->ss_si.si_tsid; + pm->pm_src_onid = ss->ss_si.si_onid; if (pm->m_config.u.pass.m_rewrite_sid > 0) { - pm->pm_dst_sid = pm->m_config.u.pass.m_rewrite_sid; - pm->pm_dst_tsid = 1; - pm->pm_dst_onid = 1; + pm->pm_dst_sid = pm->m_config.u.pass.m_rewrite_sid; + pm->pm_dst_tsid = 1; + pm->pm_dst_onid = 1; } else { - pm->pm_dst_sid = pm->pm_src_sid; - pm->pm_dst_tsid = pm->pm_src_tsid; - pm->pm_dst_onid = pm->pm_src_onid; + pm->pm_dst_sid = pm->pm_src_sid; + pm->pm_dst_tsid = pm->pm_src_tsid; + pm->pm_dst_onid = pm->pm_src_onid; } pm->pm_pmt_pid = ss->ss_pmt_pid; pm->pm_rewrite_sdt = !!pm->m_config.u.pass.m_rewrite_sdt; pm->pm_rewrite_nit = !!pm->m_config.u.pass.m_rewrite_nit; pm->pm_rewrite_eit = !!pm->m_config.u.pass.m_rewrite_eit; - for(i=0; i < ss->ss_num_components; i++) { + for (i = 0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; if (!SCT_ISVIDEO(ssc->es_type) && !SCT_ISAUDIO(ssc->es_type)) continue; @@ -468,7 +451,6 @@ pass_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss) } } - if (pm->m_config.u.pass.m_rewrite_pmt) { if (pm->pm_ss) @@ -476,31 +458,31 @@ pass_muxer_reconfigure(muxer_t* m, const struct streaming_start *ss) pm->pm_ss = streaming_start_copy(ss); dvb_table_parse_done(&pm->pm_pmt); - dvb_table_parse_init(&pm->pm_pmt, "pass-pmt", LS_TBL_PASS, pm->pm_pmt_pid, - DVB_PMT_BASE, DVB_PMT_MASK, pm); + dvb_table_parse_init(&pm->pm_pmt, + "pass-pmt", + LS_TBL_PASS, + pm->pm_pmt_pid, + DVB_PMT_BASE, + DVB_PMT_MASK, + pm); } return 0; } - /** * Init the passthrough muxer with streams */ -static int -pass_muxer_init(muxer_t* m, struct streaming_start *ss, const char *name) -{ +static int pass_muxer_init(muxer_t* m, struct streaming_start* ss, const char* name) { return pass_muxer_reconfigure(m, ss); } /** * Open the spawned task on demand */ -static int -pass_muxer_open2(pass_muxer_t *pm) -{ - const char *cmdline = pm->m_config.u.pass.m_cmdline; - char **argv = NULL; +static int pass_muxer_open2(pass_muxer_t* pm) { + const char* cmdline = pm->m_config.u.pass.m_cmdline; + char** argv = NULL; pm->pm_spawn_pid = -1; if (cmdline && cmdline[0]) { @@ -527,10 +509,8 @@ error: /** * Open the muxer as a stream muxer (using a non-seekable socket) */ -static int -pass_muxer_open_stream(muxer_t *m, int fd) -{ - pass_muxer_t *pm = (pass_muxer_t*)m; +static int pass_muxer_open_stream(muxer_t* m, int fd) { + pass_muxer_t* pm = (pass_muxer_t*)m; pm->pm_off = 0; pm->pm_ofd = fd; @@ -540,32 +520,30 @@ pass_muxer_open_stream(muxer_t *m, int fd) return pass_muxer_open2(pm); } - /** * Open the file and set the file descriptor */ -static int -pass_muxer_open_file(muxer_t *m, const char *filename) -{ - int fd; - pass_muxer_t *pm = (pass_muxer_t*)m; - - tvhtrace(LS_PASS, "Creating file \"%s\" with file permissions \"%o\"", filename, pm->m_config.m_file_permissions); - +static int pass_muxer_open_file(muxer_t* m, const char* filename) { + int fd; + pass_muxer_t* pm = (pass_muxer_t*)m; + + tvhtrace(LS_PASS, + "Creating file \"%s\" with file permissions \"%o\"", + filename, + pm->m_config.m_file_permissions); + fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, pm->m_config.m_file_permissions); - if(fd < 0) { + if (fd < 0) { pm->pm_error = errno; - tvherror(LS_PASS, "%s: Unable to create file, open failed -- %s", - filename, strerror(errno)); + tvherror(LS_PASS, "%s: Unable to create file, open failed -- %s", filename, strerror(errno)); pm->m_errors++; return -1; } /* bypass umask settings */ if (fchmod(fd, pm->m_config.m_file_permissions)) - tvherror(LS_PASS, "%s: Unable to change permissions -- %s", - filename, strerror(errno)); + tvherror(LS_PASS, "%s: Unable to change permissions -- %s", filename, strerror(errno)); pm->pm_off = 0; pm->pm_seekable = 1; @@ -575,32 +553,28 @@ pass_muxer_open_file(muxer_t *m, const char *filename) return pass_muxer_open2(pm); } - /** * Write data to the file descriptor */ -static void -pass_muxer_write(muxer_t *m, const void *data, size_t size) -{ - pass_muxer_t *pm = (pass_muxer_t*)m; - int ret; +static void pass_muxer_write(muxer_t* m, const void* data, size_t size) { + pass_muxer_t* pm = (pass_muxer_t*)m; + int ret; - if(pm->pm_error) { + if (pm->pm_error) { pm->m_errors++; return; - } - + } + if (pm->m_config.m_output_chunk > 0) { ret = tvh_write_in_chunks(pm->pm_fd, data, size, pm->m_config.m_output_chunk); } else { ret = tvh_write(pm->pm_fd, data, size); } - if(ret) { + if (ret) { pm->pm_error = errno; if (!MC_IS_EOS_ERROR(errno)) - tvherror(LS_PASS, "%s: Write failed -- %s", pm->pm_filename, - strerror(errno)); + tvherror(LS_PASS, "%s: Write failed -- %s", pm->pm_filename, strerror(errno)); else /* this is an end-of-streaming notification */ m->m_eos = 1; @@ -616,34 +590,30 @@ pass_muxer_write(muxer_t *m, const void *data, size_t size) } } - /** * Write TS packets to the file descriptor */ -static void -pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb) -{ - pass_muxer_t *pm = (pass_muxer_t*)m; - int l, pid; - uint8_t *tsb, *pkt = pktbuf_ptr(pb); - size_t len = pktbuf_len(pb), len2; - +static void pass_muxer_write_ts(muxer_t* m, pktbuf_t* pb) { + pass_muxer_t* pm = (pass_muxer_t*)m; + int l, pid; + uint8_t * tsb, *pkt = pktbuf_ptr(pb); + size_t len = pktbuf_len(pb), len2; + /* Rewrite PAT/PMT in operation */ if (pm->m_config.u.pass.m_rewrite_pat || pm->m_config.u.pass.m_rewrite_pmt || pm->pm_rewrite_sdt || pm->pm_rewrite_nit || pm->pm_rewrite_eit) { - for (tsb = pktbuf_ptr(pb), len2 = pktbuf_len(pb), len = 0; - len2 > 0; tsb += l, len2 -= l) { + for (tsb = pktbuf_ptr(pb), len2 = pktbuf_len(pb), len = 0; len2 > 0; tsb += l, len2 -= l) { pid = (tsb[1] & 0x1f) << 8 | tsb[2]; - l = mpegts_word_count(tsb, len2, 0x001FFF00); + l = mpegts_word_count(tsb, len2, 0x001FFF00); /* Process */ - if ( (pm->m_config.u.pass.m_rewrite_pat && pid == DVB_PAT_PID) || - (pm->m_config.u.pass.m_rewrite_pmt && pid == pm->pm_pmt_pid) || - (pm->pm_rewrite_sdt && pid == DVB_SDT_PID) || - (pm->pm_rewrite_nit && pid == DVB_NIT_PID) || - (pm->pm_rewrite_eit && pid == DVB_EIT_PID) ) { + if ((pm->m_config.u.pass.m_rewrite_pat && pid == DVB_PAT_PID) || + (pm->m_config.u.pass.m_rewrite_pmt && pid == pm->pm_pmt_pid) || + (pm->pm_rewrite_sdt && pid == DVB_SDT_PID) || + (pm->pm_rewrite_nit && pid == DVB_NIT_PID) || + (pm->pm_rewrite_eit && pid == DVB_EIT_PID)) { /* Flush */ if (len) @@ -658,30 +628,29 @@ pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb) dvb_table_parse(&pm->pm_pat, "-", tsb, l, 1, 0, pass_muxer_pat_cb); - /* SDT */ + /* SDT */ } else if (pid == DVB_SDT_PID) { - + dvb_table_parse(&pm->pm_sdt, "-", tsb, l, 1, 0, pass_muxer_sdt_cb); - /* NIT */ + /* NIT */ } else if (pid == DVB_NIT_PID) { - + dvb_table_parse(&pm->pm_nit, "-", tsb, l, 1, 0, pass_muxer_nit_cb); - /* EIT */ + /* EIT */ } else if (pid == DVB_EIT_PID) { - + dvb_table_parse(&pm->pm_eit, "-", tsb, l, 1, 0, pass_muxer_eit_cb); } - + /* PMT */ if (pid == pm->pm_pmt_pid) { dvb_table_parse(&pm->pm_pmt, "-", tsb, l, 1, 0, pass_muxer_pmt_cb); - } - /* Record */ + /* Record */ } else { len += l; } @@ -692,25 +661,22 @@ pass_muxer_write_ts(muxer_t *m, pktbuf_t *pb) pass_muxer_write(m, pkt, len); } - /** * Write a packet directly to the file descriptor */ -static int -pass_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data) -{ - pktbuf_t *pb = (pktbuf_t*)data; - pass_muxer_t *pm = (pass_muxer_t*)m; +static int pass_muxer_write_pkt(muxer_t* m, streaming_message_type_t smt, void* data) { + pktbuf_t* pb = (pktbuf_t*)data; + pass_muxer_t* pm = (pass_muxer_t*)m; assert(smt == SMT_MPEGTS); - switch(smt) { - case SMT_MPEGTS: - pass_muxer_write_ts(m, pb); - break; - default: - //TODO: add support for v4l (MPEG-PS) - break; + switch (smt) { + case SMT_MPEGTS: + pass_muxer_write_ts(m, pb); + break; + default: + // TODO: add support for v4l (MPEG-PS) + break; } pktbuf_ref_dec(pb); @@ -718,32 +684,29 @@ pass_muxer_write_pkt(muxer_t *m, streaming_message_type_t smt, void *data) return pm->pm_error; } - /** * NOP */ -static int -pass_muxer_write_meta(muxer_t *m, struct epg_broadcast *eb, const char *comment) -{ +static int pass_muxer_write_meta(muxer_t* m, struct epg_broadcast* eb, const char* comment) { return 0; } - /** * Close the file descriptor */ -static int -pass_muxer_close(muxer_t *m) -{ - pass_muxer_t *pm = (pass_muxer_t*)m; - - if(pm->pm_spawn_pid > 0) - spawn_kill(pm->pm_spawn_pid, tvh_kill_to_sig(pm->m_config.u.pass.m_killsig), - pm->m_config.u.pass.m_killtimeout); - if(pm->pm_seekable && close(pm->pm_ofd)) { +static int pass_muxer_close(muxer_t* m) { + pass_muxer_t* pm = (pass_muxer_t*)m; + + if (pm->pm_spawn_pid > 0) + spawn_kill(pm->pm_spawn_pid, + tvh_kill_to_sig(pm->m_config.u.pass.m_killsig), + pm->m_config.u.pass.m_killtimeout); + if (pm->pm_seekable && close(pm->pm_ofd)) { pm->pm_error = errno; - tvherror(LS_PASS, "%s: Unable to close file, close failed -- %s", - pm->pm_filename, strerror(errno)); + tvherror(LS_PASS, + "%s: Unable to close file, close failed -- %s", + pm->pm_filename, + strerror(errno)); pm->m_errors++; return -1; } @@ -751,16 +714,13 @@ pass_muxer_close(muxer_t *m) return 0; } - /** * Free all memory associated with the muxer */ -static void -pass_muxer_destroy(muxer_t *m) -{ - pass_muxer_t *pm = (pass_muxer_t*)m; +static void pass_muxer_destroy(muxer_t* m) { + pass_muxer_t* pm = (pass_muxer_t*)m; - if(pm->pm_filename) + if (pm->pm_filename) free(pm->pm_filename); if (pm->pm_ss) @@ -777,46 +737,55 @@ pass_muxer_destroy(muxer_t *m) free(pm); } - /** * Create a new passthrough muxer */ -muxer_t* -pass_muxer_create(const muxer_config_t *m_cfg, - const muxer_hints_t *hints) -{ - pass_muxer_t *pm; +muxer_t* pass_muxer_create(const muxer_config_t* m_cfg, const muxer_hints_t* hints) { + pass_muxer_t* pm; - if(m_cfg->m_type != MC_PASS && m_cfg->m_type != MC_RAW) + if (m_cfg->m_type != MC_PASS && m_cfg->m_type != MC_RAW) return NULL; - pm = calloc(1, sizeof(pass_muxer_t)); - pm->m_open_stream = pass_muxer_open_stream; - pm->m_open_file = pass_muxer_open_file; - pm->m_init = pass_muxer_init; - pm->m_reconfigure = pass_muxer_reconfigure; - pm->m_mime = pass_muxer_mime; - pm->m_write_meta = pass_muxer_write_meta; - pm->m_write_pkt = pass_muxer_write_pkt; - pm->m_close = pass_muxer_close; - pm->m_destroy = pass_muxer_destroy; - pm->pm_fd = -1; - pm->pm_ofd = -1; - pm->pm_spawn_pid = -1; - - dvb_table_parse_init(&pm->pm_pat, "pass-pat", LS_TBL_PASS, DVB_PAT_PID, - DVB_PAT_BASE, DVB_PAT_MASK, pm); - dvb_table_parse_init(&pm->pm_pmt, "pass-pmt", LS_TBL_PASS, 100, - DVB_PMT_BASE, DVB_PMT_MASK, pm); - dvb_table_parse_init(&pm->pm_sdt, "pass-sdt", LS_TBL_PASS, DVB_SDT_PID, - DVB_SDT_BASE, DVB_SDT_MASK, pm); - dvb_table_parse_init(&pm->pm_nit, "pass-nit", LS_TBL_PASS, DVB_NIT_PID, - DVB_NIT_BASE, DVB_NIT_MASK, pm); - dvb_table_parse_init(&pm->pm_eit, "pass-eit", LS_TBL_PASS, DVB_EIT_PID, - 0, 0, pm); + pm = calloc(1, sizeof(pass_muxer_t)); + pm->m_open_stream = pass_muxer_open_stream; + pm->m_open_file = pass_muxer_open_file; + pm->m_init = pass_muxer_init; + pm->m_reconfigure = pass_muxer_reconfigure; + pm->m_mime = pass_muxer_mime; + pm->m_write_meta = pass_muxer_write_meta; + pm->m_write_pkt = pass_muxer_write_pkt; + pm->m_close = pass_muxer_close; + pm->m_destroy = pass_muxer_destroy; + pm->pm_fd = -1; + pm->pm_ofd = -1; + pm->pm_spawn_pid = -1; + + dvb_table_parse_init(&pm->pm_pat, + "pass-pat", + LS_TBL_PASS, + DVB_PAT_PID, + DVB_PAT_BASE, + DVB_PAT_MASK, + pm); + dvb_table_parse_init(&pm->pm_pmt, "pass-pmt", LS_TBL_PASS, 100, DVB_PMT_BASE, DVB_PMT_MASK, pm); + dvb_table_parse_init(&pm->pm_sdt, + "pass-sdt", + LS_TBL_PASS, + DVB_SDT_PID, + DVB_SDT_BASE, + DVB_SDT_MASK, + pm); + dvb_table_parse_init(&pm->pm_nit, + "pass-nit", + LS_TBL_PASS, + DVB_NIT_PID, + DVB_NIT_BASE, + DVB_NIT_MASK, + pm); + dvb_table_parse_init(&pm->pm_eit, "pass-eit", LS_TBL_PASS, DVB_EIT_PID, 0, 0, pm); if (m_cfg->u.pass.m_rewrite_sid > 0) pm->m_caps |= MC_CAP_ANOTHER_SERVICE; - return (muxer_t *)pm; + return (muxer_t*)pm; } diff --git a/src/muxer/muxer_pass.h b/src/muxer/muxer_pass.h index 0cf269438..64a75abb9 100644 --- a/src/muxer/muxer_pass.h +++ b/src/muxer/muxer_pass.h @@ -21,6 +21,6 @@ #include "muxer.h" -muxer_t *pass_muxer_create (const muxer_config_t *m_cfg, const muxer_hints_t *hints); +muxer_t* pass_muxer_create(const muxer_config_t* m_cfg, const muxer_hints_t* hints); #endif diff --git a/src/notify.c b/src/notify.c index 056d5df6a..a9551f924 100644 --- a/src/notify.c +++ b/src/notify.c @@ -26,34 +26,27 @@ #include "notify.h" #include "webui/webui.h" -static tvh_cond_t notify_cond; -static tvh_mutex_t notify_mutex; -static htsmsg_t *notify_queue; -static pthread_t notify_tid; -static void* notify_thread(void* p); - -void -notify_by_msg(const char *class, htsmsg_t *m, int isrestricted, int rewrite) -{ +static tvh_cond_t notify_cond; +static tvh_mutex_t notify_mutex; +static htsmsg_t* notify_queue; +static pthread_t notify_tid; +static void* notify_thread(void* p); + +void notify_by_msg(const char* class, htsmsg_t* m, int isrestricted, int rewrite) { htsmsg_add_str(m, "notificationClass", class); comet_mailbox_add_message(m, 0, isrestricted, rewrite); htsmsg_destroy(m); } - -void -notify_reload(const char *class) -{ - htsmsg_t *m = htsmsg_create_map(); +void notify_reload(const char* class) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_u32(m, "reload", 1); notify_by_msg(class, m, 0, 0); } -void -notify_delayed(const char *id, const char *event, const char *action) -{ - htsmsg_t *m = NULL, *e = NULL; - htsmsg_field_t *f; +void notify_delayed(const char* id, const char* event, const char* action) { + htsmsg_t * m = NULL, *e = NULL; + htsmsg_field_t* f; if (!tvheadend_is_running()) return; @@ -72,19 +65,17 @@ notify_delayed(const char *id, const char *event, const char *action) if (e == NULL) e = htsmsg_add_msg(m, action, htsmsg_create_list()); HTSMSG_FOREACH(f, e) - if (strcmp(htsmsg_field_get_str(f) ?: "", id) == 0) - goto skip; + if (strcmp(htsmsg_field_get_str(f) ?: "", id) == 0) + goto skip; htsmsg_add_str(e, NULL, id); tvh_cond_signal(¬ify_cond, 0); skip: tvh_mutex_unlock(¬ify_mutex); } -void * -notify_thread ( void *p ) -{ - htsmsg_t *q = NULL; - htsmsg_field_t *f; +void* notify_thread(void* p) { + htsmsg_t* q = NULL; + htsmsg_field_t* f; tvh_mutex_lock(¬ify_mutex); @@ -103,7 +94,7 @@ notify_thread ( void *p ) tvh_mutex_lock(&global_lock); HTSMSG_FOREACH(f, q) - notify_by_msg(htsmsg_field_name(f), htsmsg_detach_submsg(f), 0, 0); + notify_by_msg(htsmsg_field_name(f), htsmsg_detach_submsg(f), 0, 0); /* Finished */ tvh_mutex_unlock(&global_lock); @@ -122,16 +113,14 @@ notify_thread ( void *p ) * */ -void notify_init( void ) -{ +void notify_init(void) { notify_queue = NULL; tvh_mutex_init(¬ify_mutex, NULL); tvh_cond_init(¬ify_cond, 1); tvh_thread_create(¬ify_tid, NULL, notify_thread, NULL, "notify"); } -void notify_done( void ) -{ +void notify_done(void) { tvh_mutex_lock(¬ify_mutex); tvh_cond_signal(¬ify_cond, 0); tvh_mutex_unlock(¬ify_mutex); diff --git a/src/notify.h b/src/notify.h index e7bf18b53..672c3ecd8 100644 --- a/src/notify.h +++ b/src/notify.h @@ -24,11 +24,11 @@ #define NOTIFY_REWRITE_TITLE 1 #define NOTIFY_REWRITE_SUBSCRIPTIONS 2 -void notify_by_msg(const char *class, htsmsg_t *m, int isrestricted, int rewrite); +void notify_by_msg(const char* class, htsmsg_t* m, int isrestricted, int rewrite); -void notify_reload(const char *class); +void notify_reload(const char* class); -void notify_delayed(const char *id, const char *event, const char *action); +void notify_delayed(const char* id, const char* event, const char* action); void notify_init(void); void notify_done(void); diff --git a/src/packet.c b/src/packet.c index 58f841956..3eea41ec5 100644 --- a/src/packet.c +++ b/src/packet.c @@ -16,7 +16,6 @@ * along with this program. If not, see . */ - #include "tvheadend.h" #include "streaming.h" #include "packet.h" @@ -28,16 +27,14 @@ #define PKTBUF_DATA_ALIGN 64 #endif -memoryinfo_t pkt_memoryinfo = { .my_name = "Packets" }; -memoryinfo_t pktbuf_memoryinfo = { .my_name = "Packet buffers" }; -memoryinfo_t pktref_memoryinfo = { .my_name = "Packet references" }; +memoryinfo_t pkt_memoryinfo = {.my_name = "Packets"}; +memoryinfo_t pktbuf_memoryinfo = {.my_name = "Packet buffers"}; +memoryinfo_t pktref_memoryinfo = {.my_name = "Packet references"}; /* * */ -static void -pkt_destroy(th_pkt_t *pkt) -{ +static void pkt_destroy(th_pkt_t* pkt) { if (pkt) { pktbuf_ref_dec(pkt->pkt_payload); pktbuf_ref_dec(pkt->pkt_meta); @@ -47,17 +44,18 @@ pkt_destroy(th_pkt_t *pkt) } } - /** * Allocate a new packet and give it a refcount of one (which caller is * suppoed to take care of) */ -th_pkt_t * -pkt_alloc(streaming_component_type_t type, const uint8_t *data, size_t datalen, - int64_t pts, int64_t dts, int64_t pcr) -{ - th_pkt_t *pkt; - pktbuf_t *payload; +th_pkt_t* pkt_alloc(streaming_component_type_t type, + const uint8_t* data, + size_t datalen, + int64_t pts, + int64_t dts, + int64_t pcr) { + th_pkt_t* pkt; + pktbuf_t* payload; if (datalen > 0) { payload = pktbuf_alloc(data, datalen); @@ -69,11 +67,11 @@ pkt_alloc(streaming_component_type_t type, const uint8_t *data, size_t datalen, pkt = calloc(1, sizeof(th_pkt_t)); if (pkt) { - pkt->pkt_type = type; - pkt->pkt_payload = payload; - pkt->pkt_dts = dts; - pkt->pkt_pts = pts; - pkt->pkt_pcr = pcr; + pkt->pkt_type = type; + pkt->pkt_payload = payload; + pkt->pkt_dts = dts; + pkt->pkt_pts = pts; + pkt->pkt_pcr = pcr; pkt->pkt_refcount = 1; memoryinfo_alloc(&pkt_memoryinfo, sizeof(*pkt)); } else { @@ -83,14 +81,11 @@ pkt_alloc(streaming_component_type_t type, const uint8_t *data, size_t datalen, return pkt; } - /** * */ -th_pkt_t * -pkt_copy_shallow(th_pkt_t *pkt) -{ - th_pkt_t *n = malloc(sizeof(th_pkt_t)); +th_pkt_t* pkt_copy_shallow(th_pkt_t* pkt) { + th_pkt_t* n = malloc(sizeof(th_pkt_t)); if (n) { blacklisted_memcpy(n, pkt, sizeof(*pkt)); @@ -106,14 +101,11 @@ pkt_copy_shallow(th_pkt_t *pkt) return n; } - /** * */ -th_pkt_t * -pkt_copy_nodata(th_pkt_t *pkt) -{ - th_pkt_t *n = malloc(sizeof(th_pkt_t)); +th_pkt_t* pkt_copy_nodata(th_pkt_t* pkt) { + th_pkt_t* n = malloc(sizeof(th_pkt_t)); if (n) { blacklisted_memcpy(n, pkt, sizeof(*pkt)); @@ -128,44 +120,33 @@ pkt_copy_nodata(th_pkt_t *pkt) return n; } - /** * */ -void -pkt_ref_dec(th_pkt_t *pkt) -{ - if((atomic_add(&pkt->pkt_refcount, -1)) == 1) +void pkt_ref_dec(th_pkt_t* pkt) { + if ((atomic_add(&pkt->pkt_refcount, -1)) == 1) pkt_destroy(pkt); } - /** * */ -void -pkt_ref_inc(th_pkt_t *pkt) -{ +void pkt_ref_inc(th_pkt_t* pkt) { atomic_add(&pkt->pkt_refcount, 1); } /** * */ -void -pkt_ref_inc_poly(th_pkt_t *pkt, int n) -{ +void pkt_ref_inc_poly(th_pkt_t* pkt, int n) { atomic_add(&pkt->pkt_refcount, n); } /** * */ -void -pkt_trace_(const char *file, int line, int subsys, th_pkt_t *pkt, - const char *fmt, ...) -{ - char buf[512], _pcr[22], _dts[22], _pts[22], _type[2], _meta[20]; +void pkt_trace_(const char* file, int line, int subsys, th_pkt_t* pkt, const char* fmt, ...) { + char buf[512], _pcr[22], _dts[22], _pts[22], _type[2], _meta[20]; va_list args; va_start(args, fmt); @@ -179,23 +160,25 @@ pkt_trace_(const char *file, int line, int subsys, th_pkt_t *pkt, snprintf(_meta, sizeof(_meta), " meta %zu", pktbuf_len(pkt->pkt_meta)); else _meta[0] = '\0'; - snprintf(buf, sizeof(buf), - "%s%spkt stream %d %s%s%s" - " pcr %s dts %s pts %s" - " dur %d len %zu err %i%s%s", - fmt ? fmt : "", - fmt ? " (" : "", - pkt->pkt_componentindex, - streaming_component_type2txt(pkt->pkt_type), - _type[0] ? " type " : "", _type, - pts_to_string(pkt->pkt_pcr, _pcr), - pts_to_string(pkt->pkt_dts, _dts), - pts_to_string(pkt->pkt_pts, _pts), - pkt->pkt_duration, - pktbuf_len(pkt->pkt_payload), - pkt->pkt_err, - _meta, - fmt ? ")" : ""); + snprintf(buf, + sizeof(buf), + "%s%spkt stream %d %s%s%s" + " pcr %s dts %s pts %s" + " dur %d len %zu err %i%s%s", + fmt ? fmt : "", + fmt ? " (" : "", + pkt->pkt_componentindex, + streaming_component_type2txt(pkt->pkt_type), + _type[0] ? " type " : "", + _type, + pts_to_string(pkt->pkt_pcr, _pcr), + pts_to_string(pkt->pkt_dts, _dts), + pts_to_string(pkt->pkt_pts, _pts), + pkt->pkt_duration, + pktbuf_len(pkt->pkt_payload), + pkt->pkt_err, + _meta, + fmt ? ")" : ""); tvhlogv(file, line, LOG_TRACE, subsys, buf, &args); va_end(args); } @@ -203,13 +186,11 @@ pkt_trace_(const char *file, int line, int subsys, th_pkt_t *pkt, /** * */ -void -pktref_clear_queue(struct th_pktref_queue *q) -{ - th_pktref_t *pr; +void pktref_clear_queue(struct th_pktref_queue* q) { + th_pktref_t* pr; if (q) { - while((pr = TAILQ_FIRST(q)) != NULL) { + while ((pr = TAILQ_FIRST(q)) != NULL) { TAILQ_REMOVE(q, pr, pr_link); pkt_ref_dec(pr->pr_pkt); free(pr); @@ -218,14 +199,11 @@ pktref_clear_queue(struct th_pktref_queue *q) } } - /** * Reference count is transfered to queue */ -void -pktref_enqueue(struct th_pktref_queue *q, th_pkt_t *pkt) -{ - th_pktref_t *pr = malloc(sizeof(th_pktref_t)); +void pktref_enqueue(struct th_pktref_queue* q, th_pkt_t* pkt) { + th_pktref_t* pr = malloc(sizeof(th_pktref_t)); if (pr) { pr->pr_pkt = pkt; TAILQ_INSERT_TAIL(q, pr, pr_link); @@ -233,15 +211,13 @@ pktref_enqueue(struct th_pktref_queue *q, th_pkt_t *pkt) } } - /** * Reference count is transfered to queue */ -void -pktref_enqueue_sorted(struct th_pktref_queue *q, th_pkt_t *pkt, - int (*cmp)(const void *, const void *)) -{ - th_pktref_t *pr = malloc(sizeof(th_pktref_t)); +void pktref_enqueue_sorted(struct th_pktref_queue* q, + th_pkt_t* pkt, + int (*cmp)(const void*, const void*)) { + th_pktref_t* pr = malloc(sizeof(th_pktref_t)); if (pr) { pr->pr_pkt = pkt; TAILQ_INSERT_SORTED(q, pr, pr_link, cmp); @@ -249,13 +225,10 @@ pktref_enqueue_sorted(struct th_pktref_queue *q, th_pkt_t *pkt, } } - /** * */ -void -pktref_remove(struct th_pktref_queue *q, th_pktref_t *pr) -{ +void pktref_remove(struct th_pktref_queue* q, th_pktref_t* pr) { if (pr) { if (q) TAILQ_REMOVE(q, pr, pr_link); @@ -268,10 +241,8 @@ pktref_remove(struct th_pktref_queue *q, th_pktref_t *pr) /** * */ -th_pkt_t * -pktref_first(struct th_pktref_queue *q) -{ - th_pktref_t *pr; +th_pkt_t* pktref_first(struct th_pktref_queue* q) { + th_pktref_t* pr; pr = TAILQ_FIRST(q); if (pr) @@ -282,11 +253,9 @@ pktref_first(struct th_pktref_queue *q) /** * */ -th_pkt_t * -pktref_get_first(struct th_pktref_queue *q) -{ - th_pktref_t *pr; - th_pkt_t *pkt; +th_pkt_t* pktref_get_first(struct th_pktref_queue* q) { + th_pktref_t* pr; + th_pkt_t* pkt; pr = TAILQ_FIRST(q); if (pr) { @@ -302,10 +271,8 @@ pktref_get_first(struct th_pktref_queue *q) /** * */ -void -pktref_insert_head(struct th_pktref_queue *q, th_pkt_t *pkt) -{ - th_pktref_t *pr; +void pktref_insert_head(struct th_pktref_queue* q, th_pkt_t* pkt) { + th_pktref_t* pr; pr = pktref_create(pkt); TAILQ_INSERT_HEAD(q, pr, pr_link); @@ -314,10 +281,8 @@ pktref_insert_head(struct th_pktref_queue *q, th_pkt_t *pkt) /** * */ -th_pktref_t * -pktref_create(th_pkt_t *pkt) -{ - th_pktref_t *pr = malloc(sizeof(th_pktref_t)); +th_pktref_t* pktref_create(th_pkt_t* pkt) { + th_pktref_t* pr = malloc(sizeof(th_pktref_t)); if (pr) { pr->pr_pkt = pkt; memoryinfo_alloc(&pktref_memoryinfo, sizeof(*pr)); @@ -329,9 +294,7 @@ pktref_create(th_pkt_t *pkt) * */ -void -pktbuf_destroy(pktbuf_t *pb) -{ +void pktbuf_destroy(pktbuf_t* pb) { if (pb) { memoryinfo_free(&pktbuf_memoryinfo, sizeof(*pb) + pb->pb_size); free(pb->pb_data); @@ -339,11 +302,9 @@ pktbuf_destroy(pktbuf_t *pb) } } -void -pktbuf_ref_dec(pktbuf_t *pb) -{ +void pktbuf_ref_dec(pktbuf_t* pb) { if (pb) { - if((atomic_add(&pb->pb_refcount, -1)) == 1) { + if ((atomic_add(&pb->pb_refcount, -1)) == 1) { memoryinfo_free(&pktbuf_memoryinfo, sizeof(*pb) + pb->pb_size); free(pb->pb_data); free(pb); @@ -351,9 +312,7 @@ pktbuf_ref_dec(pktbuf_t *pb) } } -pktbuf_t * -pktbuf_ref_inc(pktbuf_t *pb) -{ +pktbuf_t* pktbuf_ref_inc(pktbuf_t* pb) { if (pb) { atomic_add(&pb->pb_refcount, 1); return pb; @@ -361,14 +320,12 @@ pktbuf_ref_inc(pktbuf_t *pb) return NULL; } -pktbuf_t * -pktbuf_alloc(const uint8_t *data, size_t size) -{ - pktbuf_t *pb; - uint8_t *buffer; +pktbuf_t* pktbuf_alloc(const uint8_t* data, size_t size) { + pktbuf_t* pb; + uint8_t* buffer; buffer = size > 0 ? malloc(size) : NULL; - if (buffer) {\ + if (buffer) { if (data != NULL) memcpy(buffer, data, size); } else if (size > 0) { @@ -380,30 +337,26 @@ pktbuf_alloc(const uint8_t *data, size_t size) return NULL; } pb->pb_refcount = 1; - pb->pb_data = buffer; - pb->pb_size = size; - pb->pb_err = 0; + pb->pb_data = buffer; + pb->pb_size = size; + pb->pb_err = 0; memoryinfo_alloc(&pktbuf_memoryinfo, sizeof(*pb) + size); return pb; } -pktbuf_t * -pktbuf_make(void *data, size_t size) -{ - pktbuf_t *pb = malloc(sizeof(pktbuf_t)); +pktbuf_t* pktbuf_make(void* data, size_t size) { + pktbuf_t* pb = malloc(sizeof(pktbuf_t)); if (pb) { pb->pb_refcount = 1; - pb->pb_size = size; - pb->pb_data = data; + pb->pb_size = size; + pb->pb_data = data; memoryinfo_alloc(&pktbuf_memoryinfo, sizeof(*pb) + pb->pb_size); } return pb; } -pktbuf_t * -pktbuf_append(pktbuf_t *pb, const void *data, size_t size) -{ - void *ndata; +pktbuf_t* pktbuf_append(pktbuf_t* pb, const void* data, size_t size) { + void* ndata; if (pb == NULL) return pktbuf_alloc(data, size); ndata = realloc(pb->pb_data, pb->pb_size + size); @@ -420,10 +373,9 @@ pktbuf_append(pktbuf_t *pb, const void *data, size_t size) * */ -const char *pts_to_string(int64_t pts, char *buf) -{ +const char* pts_to_string(int64_t pts, char* buf) { if (pts == PTS_UNSET) return strcpy(buf, ""); - snprintf(buf, 22, "%"PRId64, pts); + snprintf(buf, 22, "%" PRId64, pts); return buf; } diff --git a/src/packet.h b/src/packet.h index 3b2bed91e..a9478fe5a 100644 --- a/src/packet.h +++ b/src/packet.h @@ -27,10 +27,10 @@ struct memoryinfo; * Packet buffer */ typedef struct pktbuf { - int pb_refcount; - int pb_err; - uint8_t *pb_data; - size_t pb_size; + int pb_refcount; + int pb_err; + uint8_t* pb_data; + size_t pb_size; } pktbuf_t; /** @@ -39,13 +39,15 @@ typedef struct pktbuf { #define PKT_I_FRAME 1 #define PKT_P_FRAME 2 #define PKT_B_FRAME 3 -#define PKT_NTYPES 4 - -static inline char pkt_frametype_to_char ( int frametype ) -{ - if (frametype == PKT_I_FRAME) return 'I'; - if (frametype == PKT_P_FRAME) return 'P'; - if (frametype == PKT_B_FRAME) return 'B'; +#define PKT_NTYPES 4 + +static inline char pkt_frametype_to_char(int frametype) { + if (frametype == PKT_I_FRAME) + return 'I'; + if (frametype == PKT_P_FRAME) + return 'P'; + if (frametype == PKT_B_FRAME) + return 'B'; return ' '; } @@ -53,8 +55,8 @@ typedef struct th_pkt { int64_t pkt_dts; int64_t pkt_pts; int64_t pkt_pcr; - int pkt_duration; - int pkt_refcount; + int pkt_duration; + int pkt_refcount; uint8_t pkt_type; uint8_t pkt_err; @@ -64,7 +66,7 @@ typedef struct th_pkt { union { struct { uint8_t pkt_frametype; - uint8_t pkt_field; // Set if packet is only a half frame (a field) + uint8_t pkt_field; // Set if packet is only a half frame (a field) uint16_t pkt_aspect_num; uint16_t pkt_aspect_den; @@ -77,8 +79,8 @@ typedef struct th_pkt { } a; }; - pktbuf_t *pkt_meta; - pktbuf_t *pkt_payload; + pktbuf_t* pkt_meta; + pktbuf_t* pkt_payload; } th_pkt_t; @@ -87,7 +89,7 @@ typedef struct th_pkt { */ typedef struct th_pktref { TAILQ_ENTRY(th_pktref) pr_link; - th_pkt_t *pr_pkt; + th_pkt_t* pr_pkt; } th_pktref_t; TAILQ_HEAD(th_pktref_queue, th_pktref); @@ -102,48 +104,50 @@ extern struct memoryinfo pktref_memoryinfo; /** * */ -void pkt_ref_dec(th_pkt_t *pkt); +void pkt_ref_dec(th_pkt_t* pkt); -void pkt_ref_inc(th_pkt_t *pkt); +void pkt_ref_inc(th_pkt_t* pkt); -void pkt_ref_inc_poly(th_pkt_t *pkt, int n); +void pkt_ref_inc_poly(th_pkt_t* pkt, int n); -void pktref_clear_queue(struct th_pktref_queue *q); +void pktref_clear_queue(struct th_pktref_queue* q); // Reference count is transfered to queue -void pktref_enqueue(struct th_pktref_queue *q, th_pkt_t *pkt); +void pktref_enqueue(struct th_pktref_queue* q, th_pkt_t* pkt); // Reference count is transfered to queue -void pktref_enqueue_sorted(struct th_pktref_queue *q, th_pkt_t *pkt, - int (*cmp)(const void *, const void *)); +void pktref_enqueue_sorted(struct th_pktref_queue* q, + th_pkt_t* pkt, + int (*cmp)(const void*, const void*)); -void pktref_remove(struct th_pktref_queue *q, th_pktref_t *pr); +void pktref_remove(struct th_pktref_queue* q, th_pktref_t* pr); -th_pkt_t *pktref_first(struct th_pktref_queue *q); +th_pkt_t* pktref_first(struct th_pktref_queue* q); -th_pkt_t *pktref_get_first(struct th_pktref_queue *q); +th_pkt_t* pktref_get_first(struct th_pktref_queue* q); -void pktref_insert_head(struct th_pktref_queue *q, th_pkt_t *pkt); +void pktref_insert_head(struct th_pktref_queue* q, th_pkt_t* pkt); -#define PKTREF_FOREACH(item, queue) TAILQ_FOREACH((item), (queue), pr_link) +#define PKTREF_FOREACH(item, queue) TAILQ_FOREACH ((item), (queue), pr_link) -th_pkt_t *pkt_alloc(streaming_component_type_t type, - const uint8_t *data, size_t datalen, - int64_t pts, int64_t dts, int64_t pcr); +th_pkt_t* pkt_alloc(streaming_component_type_t type, + const uint8_t* data, + size_t datalen, + int64_t pts, + int64_t dts, + int64_t pcr); -th_pkt_t *pkt_copy_shallow(th_pkt_t *pkt); +th_pkt_t* pkt_copy_shallow(th_pkt_t* pkt); -th_pkt_t *pkt_copy_nodata(th_pkt_t *pkt); +th_pkt_t* pkt_copy_nodata(th_pkt_t* pkt); -th_pktref_t *pktref_create(th_pkt_t *pkt); +th_pktref_t* pktref_create(th_pkt_t* pkt); -void pkt_trace_ - (const char *file, int line, int subsys, th_pkt_t *pkt, - const char *fmt, ...); +void pkt_trace_(const char* file, int line, int subsys, th_pkt_t* pkt, const char* fmt, ...); -#define pkt_trace(subsys, pkt, fmt, ...) \ - do { \ - if (tvhtrace_enabled()) \ +#define pkt_trace(subsys, pkt, fmt, ...) \ + do { \ + if (tvhtrace_enabled()) \ pkt_trace_(__FILE__, __LINE__, subsys, pkt, fmt, ##__VA_ARGS__); \ } while (0) @@ -151,27 +155,30 @@ void pkt_trace_ * */ -void pktbuf_ref_dec(pktbuf_t *pb); +void pktbuf_ref_dec(pktbuf_t* pb); -void pktbuf_destroy(pktbuf_t *pb); +void pktbuf_destroy(pktbuf_t* pb); -pktbuf_t *pktbuf_ref_inc(pktbuf_t *pb); +pktbuf_t* pktbuf_ref_inc(pktbuf_t* pb); -pktbuf_t *pktbuf_alloc(const uint8_t *data, size_t size); +pktbuf_t* pktbuf_alloc(const uint8_t* data, size_t size); -pktbuf_t *pktbuf_make(void *data, size_t size); +pktbuf_t* pktbuf_make(void* data, size_t size); -pktbuf_t *pktbuf_append(pktbuf_t *pb, const void *data, size_t size); +pktbuf_t* pktbuf_append(pktbuf_t* pb, const void* data, size_t size); -static inline size_t pktbuf_len(pktbuf_t *pb) { return pb ? pb->pb_size : 0; } -static inline uint8_t *pktbuf_ptr(pktbuf_t *pb) { return pb->pb_data; } +static inline size_t pktbuf_len(pktbuf_t* pb) { + return pb ? pb->pb_size : 0; +} +static inline uint8_t* pktbuf_ptr(pktbuf_t* pb) { + return pb->pb_data; +} /* * */ -static inline int64_t pts_diff(int64_t a, int64_t b) -{ +static inline int64_t pts_diff(int64_t a, int64_t b) { if (a == PTS_UNSET || b == PTS_UNSET) return PTS_UNSET; a &= PTS_MASK; @@ -184,8 +191,7 @@ static inline int64_t pts_diff(int64_t a, int64_t b) return PTS_UNSET; } -static inline int pts_is_greater_or_equal(int64_t base, int64_t value) -{ +static inline int pts_is_greater_or_equal(int64_t base, int64_t value) { if (base == PTS_UNSET || value == PTS_UNSET) return -1; if (value >= base) @@ -195,6 +201,6 @@ static inline int pts_is_greater_or_equal(int64_t base, int64_t value) return 0; } -const char *pts_to_string(int64_t pts, char *buf); +const char* pts_to_string(int64_t pts, char* buf); #endif /* PACKET_H_ */ diff --git a/src/parsers/bitstream.c b/src/parsers/bitstream.c index 921ee0ef0..dc4ffd25a 100644 --- a/src/parsers/bitstream.c +++ b/src/parsers/bitstream.c @@ -20,40 +20,32 @@ #include #include "bitstream.h" - -int -init_rbits(bitstream_t *bs, const uint8_t *data, uint32_t bits) -{ - bs->wdata = NULL; - bs->rdata = data; +int init_rbits(bitstream_t* bs, const uint8_t* data, uint32_t bits) { + bs->wdata = NULL; + bs->rdata = data; bs->offset = 0; - bs->len = bits; + bs->len = bits; return 0; } - -int -init_wbits(bitstream_t *bs, uint8_t *data, uint32_t bits) -{ - bs->wdata = data; - bs->rdata = NULL; +int init_wbits(bitstream_t* bs, uint8_t* data, uint32_t bits) { + bs->wdata = data; + bs->rdata = NULL; bs->offset = 0; - bs->len = bits; + bs->len = bits; return 0; } -uint32_t -read_bits(bitstream_t *bs, uint32_t num) -{ +uint32_t read_bits(bitstream_t* bs, uint32_t num) { uint32_t r = 0; - while(num > 0) { - if(bs->offset >= bs->len) + while (num > 0) { + if (bs->offset >= bs->len) return 0; num--; - if(bs->rdata[bs->offset / 8] & (1 << (7 - (bs->offset & 7)))) + if (bs->rdata[bs->offset / 8] & (1 << (7 - (bs->offset & 7)))) r |= 1 << num; bs->offset++; @@ -61,18 +53,16 @@ read_bits(bitstream_t *bs, uint32_t num) return r; } -uint64_t -read_bits64(bitstream_t *bs, uint32_t num) -{ +uint64_t read_bits64(bitstream_t* bs, uint32_t num) { uint64_t r = 0; - while(num > 0) { - if(bs->offset >= bs->len) + while (num > 0) { + if (bs->offset >= bs->len) return 0; num--; - if(bs->rdata[bs->offset / 8] & (1 << (7 - (bs->offset & 7)))) + if (bs->rdata[bs->offset / 8] & (1 << (7 - (bs->offset & 7)))) r |= (int64_t)1 << num; bs->offset++; @@ -80,18 +70,16 @@ read_bits64(bitstream_t *bs, uint32_t num) return r; } -uint32_t -show_bits(bitstream_t *bs, uint32_t num) -{ +uint32_t show_bits(bitstream_t* bs, uint32_t num) { uint32_t r = 0, offset = bs->offset; - while(num > 0) { - if(offset >= bs->len) + while (num > 0) { + if (offset >= bs->len) return 0; num--; - if(bs->rdata[offset / 8] & (1 << (7 - (offset & 7)))) + if (bs->rdata[offset / 8] & (1 << (7 - (offset & 7)))) r |= 1 << num; offset++; @@ -99,13 +87,11 @@ show_bits(bitstream_t *bs, uint32_t num) return r; } -uint32_t -read_golomb_ue(bitstream_t *bs) -{ +uint32_t read_golomb_ue(bitstream_t* bs) { uint32_t b; - int lzb = -1; + int lzb = -1; - for(b = 0; !b && !bs_eof(bs) && lzb < 32; lzb++) + for (b = 0; !b && !bs_eof(bs) && lzb < 32; lzb++) b = read_bits1(bs); if (lzb < 0 || lzb > 31) @@ -113,29 +99,23 @@ read_golomb_ue(bitstream_t *bs) return (1 << lzb) - 1 + read_bits(bs, lzb); } - -int32_t -read_golomb_se(bitstream_t *bs) -{ +int32_t read_golomb_se(bitstream_t* bs) { uint32_t v; v = read_golomb_ue(bs); - if(v == 0) + if (v == 0) return 0; return (v & 1) ? ((v + 1) >> 1) : -(v >> 1); } - -void -put_bits(bitstream_t *bs, uint32_t val, uint32_t num) -{ - while(num > 0) { - if(bs->offset >= bs->len) +void put_bits(bitstream_t* bs, uint32_t val, uint32_t num) { + while (num > 0) { + if (bs->offset >= bs->len) return; num--; - if(val & (1 << num)) + if (val & (1 << num)) bs->wdata[bs->offset / 8] |= 1 << (7 - (bs->offset & 7)); else bs->wdata[bs->offset / 8] &= ~(1 << (7 - (bs->offset & 7))); diff --git a/src/parsers/bitstream.h b/src/parsers/bitstream.h index f1bcf16df..c83abed6d 100644 --- a/src/parsers/bitstream.h +++ b/src/parsers/bitstream.h @@ -20,52 +20,53 @@ #define BITSTREAM_H_ typedef struct bitstream { - const uint8_t *rdata; - uint8_t *wdata; - uint32_t offset; - uint32_t len; + const uint8_t* rdata; + uint8_t* wdata; + uint32_t offset; + uint32_t len; } bitstream_t; -static inline void skip_bits(bitstream_t *bs, uint32_t num) - { bs->offset += num; } +static inline void skip_bits(bitstream_t* bs, uint32_t num) { + bs->offset += num; +} -static inline void skip_bits1(bitstream_t *bs) - { bs->offset++; } +static inline void skip_bits1(bitstream_t* bs) { + bs->offset++; +} -int init_rbits(bitstream_t *bs, const uint8_t *data, uint32_t bits); +int init_rbits(bitstream_t* bs, const uint8_t* data, uint32_t bits); -int init_wbits(bitstream_t *bs, uint8_t *data, uint32_t bits); +int init_wbits(bitstream_t* bs, uint8_t* data, uint32_t bits); -uint32_t read_bits(bitstream_t *gb, uint32_t num); +uint32_t read_bits(bitstream_t* gb, uint32_t num); -uint64_t read_bits64(bitstream_t *gb, uint32_t num); +uint64_t read_bits64(bitstream_t* gb, uint32_t num); -uint32_t show_bits(bitstream_t *gb, uint32_t num); +uint32_t show_bits(bitstream_t* gb, uint32_t num); -static inline unsigned int read_bits1(bitstream_t *gb) - { return read_bits(gb, 1); } +static inline unsigned int read_bits1(bitstream_t* gb) { + return read_bits(gb, 1); +} -unsigned int read_golomb_ue(bitstream_t *gb); +unsigned int read_golomb_ue(bitstream_t* gb); -signed int read_golomb_se(bitstream_t *gb); +signed int read_golomb_se(bitstream_t* gb); -static inline uint32_t remaining_bits(bitstream_t *gb) - { return gb->len - gb->offset; } +static inline uint32_t remaining_bits(bitstream_t* gb) { + return gb->len - gb->offset; +} -void put_bits(bitstream_t *bs, uint32_t val, uint32_t num); +void put_bits(bitstream_t* bs, uint32_t val, uint32_t num); -static inline int bs_eof(const bitstream_t *bs) - { return bs->offset >= bs->len; } +static inline int bs_eof(const bitstream_t* bs) { + return bs->offset >= bs->len; +} -static inline uint32_t -RB32(const uint8_t *d) -{ +static inline uint32_t RB32(const uint8_t* d) { return (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3]; } -static inline uint32_t -RB24(const uint8_t *d) -{ +static inline uint32_t RB24(const uint8_t* d) { return (d[0] << 16) | (d[1] << 8) | d[2]; } diff --git a/src/parsers/message.c b/src/parsers/message.c index a56ea7bed..c4842ae92 100644 --- a/src/parsers/message.c +++ b/src/parsers/message.c @@ -26,45 +26,45 @@ /** * */ -static inline parser_es_t * -parser_find_es(parser_t *prs, int pid) -{ - elementary_stream_t *es; +static inline parser_es_t* parser_find_es(parser_t* prs, int pid) { + elementary_stream_t* es; - TAILQ_FOREACH(es, &prs->prs_components.set_all, es_link) + TAILQ_FOREACH (es, &prs->prs_components.set_all, es_link) if (es->es_pid == pid) - return (parser_es_t *)es; + return (parser_es_t*)es; return NULL; } /** * Extract PCR clocks */ -static void ts_recv_pcr(parser_t *t, const uint8_t *tsb) -{ +static void ts_recv_pcr(parser_t* t, const uint8_t* tsb) { int64_t pcr; - pcr = (uint64_t)tsb[6] << 25; - pcr |= (uint64_t)tsb[7] << 17; - pcr |= (uint64_t)tsb[8] << 9; - pcr |= (uint64_t)tsb[9] << 1; + pcr = (uint64_t)tsb[6] << 25; + pcr |= (uint64_t)tsb[7] << 17; + pcr |= (uint64_t)tsb[8] << 9; + pcr |= (uint64_t)tsb[9] << 1; pcr |= ((uint64_t)tsb[10] >> 7) & 0x01; /* handle the broken info using candidate variable */ if (t->prs_current_pcr == PTS_UNSET || t->prs_current_pcr_guess || pts_diff(t->prs_current_pcr, pcr) <= (int64_t)t->prs_pcr_boundary || (t->prs_candidate_pcr != PTS_UNSET && - pts_diff(t->prs_candidate_pcr, pcr) <= (int64_t)t->prs_pcr_boundary)) { + pts_diff(t->prs_candidate_pcr, pcr) <= (int64_t)t->prs_pcr_boundary)) { if (pcr != t->prs_current_pcr) { if (t->prs_current_pcr == PTS_UNSET) - tvhtrace(LS_PCR, "%s: initial : %"PRId64, service_nicename(t->prs_service), pcr); + tvhtrace(LS_PCR, "%s: initial : %" PRId64, service_nicename(t->prs_service), pcr); else - tvhtrace(LS_PCR, "%s: change : %"PRId64"%s", service_nicename(t->prs_service), pcr, - t->prs_candidate_pcr != PTS_UNSET ? " (candidate)" : ""); - t->prs_current_pcr = pcr; + tvhtrace(LS_PCR, + "%s: change : %" PRId64 "%s", + service_nicename(t->prs_service), + pcr, + t->prs_candidate_pcr != PTS_UNSET ? " (candidate)" : ""); + t->prs_current_pcr = pcr; t->prs_current_pcr_guess = 0; } t->prs_candidate_pcr = PTS_UNSET; } else { - tvhtrace(LS_PCR, "%s: candidate: %"PRId64, service_nicename(t->prs_service), pcr); + tvhtrace(LS_PCR, "%s: candidate: %" PRId64, service_nicename(t->prs_service), pcr); t->prs_candidate_pcr = pcr; } } @@ -72,11 +72,9 @@ static void ts_recv_pcr(parser_t *t, const uint8_t *tsb) /* * Extract PCR from audio */ -static void ts_recv_pcr_audio - (parser_t *t, parser_es_t *st, const uint8_t *buf, int len) -{ +static void ts_recv_pcr_audio(parser_t* t, parser_es_t* st, const uint8_t* buf, int len) { int64_t dts, pts, d; - int hdr, flags, hlen; + int hdr, flags, hlen; if (buf[3] != 0xbd && buf[3] != 0xc0) return; @@ -84,13 +82,13 @@ static void ts_recv_pcr_audio if (len < 9) return; - buf += 6; - len -= 6; + buf += 6; + len -= 6; hdr = buf[0]; flags = buf[1]; hlen = buf[2]; - buf += 3; - len -= 3; + buf += 3; + len -= 3; if (len < hlen || (hdr & 0xc0) != 0x80) return; @@ -120,7 +118,7 @@ static void ts_recv_pcr_audio } if (st->es_last_pcr != t->prs_current_pcr) { - st->es_last_pcr = t->prs_current_pcr; + st->es_last_pcr = t->prs_current_pcr; st->es_last_pcr_dts = dts; return; } @@ -128,37 +126,39 @@ static void ts_recv_pcr_audio d = pts_diff(st->es_last_pcr_dts, dts); if (d == PTS_UNSET || d < 30000) return; - if (d < 10*90000) + if (d < 10 * 90000) t->prs_current_pcr += d; set: if (t->prs_current_pcr == PTS_UNSET && d != PTS_UNSET && d < 30000) { - t->prs_current_pcr = (dts - 2*90000) & PTS_MASK; + t->prs_current_pcr = (dts - 2 * 90000) & PTS_MASK; t->prs_current_pcr_guess = 1; } - tvhtrace(LS_PCR, "%s: audio DTS: %"PRId64" dts %"PRId64" [%s/%d]", - service_nicename(t->prs_service), t->prs_current_pcr, dts, - streaming_component_type2txt(st->es_type), st->es_pid); - st->es_last_pcr = t->prs_current_pcr; + tvhtrace(LS_PCR, + "%s: audio DTS: %" PRId64 " dts %" PRId64 " [%s/%d]", + service_nicename(t->prs_service), + t->prs_current_pcr, + dts, + streaming_component_type2txt(st->es_type), + st->es_pid); + st->es_last_pcr = t->prs_current_pcr; st->es_last_pcr_dts = dts; } /** * HBBTV */ -static void -ts_recv_hbbtv1_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) -{ - parser_es_t *pes = (parser_es_t *)mt->mt_opaque; - parser_t *prs = pes->es_parser; - htsmsg_t *apps = dvb_psi_parse_hbbtv(mt, buf, len, NULL); +static void ts_recv_hbbtv1_cb(mpegts_psi_table_t* mt, const uint8_t* buf, int len) { + parser_es_t* pes = (parser_es_t*)mt->mt_opaque; + parser_t* prs = pes->es_parser; + htsmsg_t* apps = dvb_psi_parse_hbbtv(mt, buf, len, NULL); if (apps) { - void *bin; + void* bin; size_t binlen; parse_mpeg_ts(prs, pes, buf, len, 1, 0); - if (!htsmsg_binary2_serialize(apps, &bin, &binlen, 128*1024)) { + if (!htsmsg_binary2_serialize(apps, &bin, &binlen, 128 * 1024)) { parse_mpeg_ts(prs, pes, bin, binlen, 1, 0); free(bin); } @@ -169,19 +169,18 @@ ts_recv_hbbtv1_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) /** * */ -static void parser_input_mpegts(parser_t *prs, pktbuf_t *pb) -{ - const uint8_t *tsb = pb->pb_data; - size_t len = pb->pb_size; - int err = pb->pb_err; - int pid, last_pid = -1; - int pusi, error, off; - parser_es_t *pes = NULL; +static void parser_input_mpegts(parser_t* prs, pktbuf_t* pb) { + const uint8_t* tsb = pb->pb_data; + size_t len = pb->pb_size; + int err = pb->pb_err; + int pid, last_pid = -1; + int pusi, error, off; + parser_es_t* pes = NULL; for (; len > 0; tsb += 188, len -= 188) { pid = (tsb[1] & 0x1f) << 8 | tsb[2]; if (pid != last_pid) { - pes = parser_find_es(prs, pid); + pes = parser_find_es(prs, pid); last_pid = pid; if (err && pes) { /* FIXME: we have global error count */ @@ -198,16 +197,15 @@ static void parser_input_mpegts(parser_t *prs, pktbuf_t *pb) if (tsb[3] & 0x20) { off = tsb[4] + 5; - if (pes->es_pid == prs->prs_pcr_pid && !error && off > 10 && - (tsb[5] & 0x10) != 0 && off <= 188) + if (pes->es_pid == prs->prs_pcr_pid && !error && off > 10 && (tsb[5] & 0x10) != 0 && + off <= 188) ts_recv_pcr(prs, tsb); } else { off = 4; } - if (pusi && !error && off < 188 - 16 && - tsb[off] == 0 && tsb[off+1] == 0 && tsb[off+2] == 1 && - SCT_ISAUDIO(pes->es_type)) { + if (pusi && !error && off < 188 - 16 && tsb[off] == 0 && tsb[off + 1] == 0 && + tsb[off + 2] == 1 && SCT_ISAUDIO(pes->es_type)) { ts_recv_pcr_audio(prs, pes, tsb + off, 188 - off); } else if (pes->es_type == SCT_HBBTV) { dvb_table_parse(&pes->es_psi, "parser", tsb, 188, 1, 0, ts_recv_hbbtv1_cb); @@ -222,31 +220,34 @@ static void parser_input_mpegts(parser_t *prs, pktbuf_t *pb) /** * */ -static void parser_init_es(parser_es_t *pes, parser_t *prs) -{ - pes->es_parser = prs; +static void parser_init_es(parser_es_t* pes, parser_t* prs) { + pes->es_parser = prs; pes->es_parse_callback = NULL; - pes->es_incomplete = 0; - pes->es_header_mode = 0; - pes->es_parser_state = 0; - pes->es_blank = 0; - pes->es_startcond = 0xffffffff; - pes->es_curdts = PTS_UNSET; - pes->es_curpts = PTS_UNSET; - pes->es_prevdts = PTS_UNSET; - pes->es_last_pcr = PTS_UNSET; - pes->es_last_pcr_dts = PTS_UNSET; + pes->es_incomplete = 0; + pes->es_header_mode = 0; + pes->es_parser_state = 0; + pes->es_blank = 0; + pes->es_startcond = 0xffffffff; + pes->es_curdts = PTS_UNSET; + pes->es_curpts = PTS_UNSET; + pes->es_prevdts = PTS_UNSET; + pes->es_last_pcr = PTS_UNSET; + pes->es_last_pcr_dts = PTS_UNSET; TAILQ_INIT(&pes->es_backlog); if (pes->es_type == SCT_HBBTV && pes->es_psi.mt_name == NULL) - dvb_table_parse_init(&pes->es_psi, "hbbtv", LS_TS, pes->es_pid, - DVB_HBBTV_BASE, DVB_HBBTV_MASK, pes); + dvb_table_parse_init(&pes->es_psi, + "hbbtv", + LS_TS, + pes->es_pid, + DVB_HBBTV_BASE, + DVB_HBBTV_MASK, + pes); } /** * */ -static void parser_clean_es(parser_es_t *pes) -{ +static void parser_clean_es(parser_es_t* pes) { free(pes->es_priv); pes->es_priv = NULL; @@ -260,24 +261,22 @@ static void parser_clean_es(parser_es_t *pes) sbuf_free(&pes->es_buf); sbuf_free(&pes->es_buf_a); - if(pes->es_curpkt != NULL) { + if (pes->es_curpkt != NULL) { pkt_ref_dec(pes->es_curpkt); pes->es_curpkt = NULL; } free(pes->es_global_data); - pes->es_global_data = NULL; + pes->es_global_data = NULL; pes->es_global_data_len = 0; tvhlog_limit_reset(&pes->es_pes_log); tvhlog_limit_reset(&pes->es_pcr_log); } -static void -parser_do_rstlog(parser_t *prs) -{ - streaming_message_t *sm; - th_pkt_t *pkt; +static void parser_do_rstlog(parser_t* prs) { + streaming_message_t* sm; + th_pkt_t* pkt; while ((sm = TAILQ_FIRST(&prs->prs_rstlog)) != NULL) { TAILQ_REMOVE(&prs->prs_rstlog, sm, sm_link); pkt = sm->sm_data; @@ -291,29 +290,28 @@ parser_do_rstlog(parser_t *prs) /** * */ -static void parser_input_start(parser_t *prs, streaming_message_t *sm) -{ - streaming_start_t *ss = sm->sm_data; - elementary_set_t *set = &prs->prs_components; - elementary_stream_t *es; - - TAILQ_FOREACH(es, &set->set_all, es_link) - parser_clean_es((parser_es_t *)es); +static void parser_input_start(parser_t* prs, streaming_message_t* sm) { + streaming_start_t* ss = sm->sm_data; + elementary_set_t* set = &prs->prs_components; + elementary_stream_t* es; + + TAILQ_FOREACH (es, &set->set_all, es_link) + parser_clean_es((parser_es_t*)es); elementary_set_clean(set, prs->prs_service, 1); elementary_stream_create_from_start(set, ss, sizeof(parser_es_t)); - TAILQ_FOREACH(es, &set->set_all, es_link) { - parser_init_es((parser_es_t *)es, prs); + TAILQ_FOREACH (es, &set->set_all, es_link) { + parser_init_es((parser_es_t*)es, prs); TAILQ_INSERT_TAIL(&set->set_filter, es, es_filter_link); } - prs->prs_pcr_pid = ss->ss_pcr_pid; - prs->prs_current_pcr = PTS_UNSET; - prs->prs_candidate_pcr = PTS_UNSET; + prs->prs_pcr_pid = ss->ss_pcr_pid; + prs->prs_current_pcr = PTS_UNSET; + prs->prs_candidate_pcr = PTS_UNSET; prs->prs_current_pcr_guess = 0; - prs->prs_pcr_boundary = 90000; + prs->prs_pcr_boundary = 90000; if (elementary_stream_has_no_audio(set, 1)) - prs->prs_pcr_boundary = 6*90000; + prs->prs_pcr_boundary = 6 * 90000; streaming_target_deliver2(prs->prs_output, sm); /* do_rstlog */ @@ -325,80 +323,66 @@ static void parser_input_start(parser_t *prs, streaming_message_t *sm) /** * */ -static void -parser_input(void *opaque, streaming_message_t *sm) -{ - parser_t *prs = opaque; - - switch(sm->sm_type) { - case SMT_MPEGTS: - parser_input_mpegts(prs, (pktbuf_t *)sm->sm_data); - streaming_msg_free(sm); - break; - case SMT_START: - parser_input_start(prs, sm); - break; - default: - streaming_target_deliver2(prs->prs_output, sm); - break; +static void parser_input(void* opaque, streaming_message_t* sm) { + parser_t* prs = opaque; + + switch (sm->sm_type) { + case SMT_MPEGTS: + parser_input_mpegts(prs, (pktbuf_t*)sm->sm_data); + streaming_msg_free(sm); + break; + case SMT_START: + parser_input_start(prs, sm); + break; + default: + streaming_target_deliver2(prs->prs_output, sm); + break; } } -static htsmsg_t * -parser_input_info(void *opaque, htsmsg_t *list) -{ - parser_t *prs = opaque; - streaming_target_t *st = prs->prs_output; +static htsmsg_t* parser_input_info(void* opaque, htsmsg_t* list) { + parser_t* prs = opaque; + streaming_target_t* st = prs->prs_output; htsmsg_add_str(list, NULL, "parser input"); return st->st_ops.st_info(st->st_opaque, list); } -static streaming_ops_t parser_input_ops = { - .st_cb = parser_input, - .st_info = parser_input_info -}; +static streaming_ops_t parser_input_ops = {.st_cb = parser_input, .st_info = parser_input_info}; /** * Parser get output target */ -streaming_target_t * -parser_output(streaming_target_t *pad) -{ - return ((parser_t *)pad)->prs_output; +streaming_target_t* parser_output(streaming_target_t* pad) { + return ((parser_t*)pad)->prs_output; } /** * Parser create */ -streaming_target_t * -parser_create(streaming_target_t *output, th_subscription_t *ts) -{ - parser_t *prs = calloc(1, sizeof(parser_t)); - service_t *t = ts->ths_service; +streaming_target_t* parser_create(streaming_target_t* output, th_subscription_t* ts) { + parser_t* prs = calloc(1, sizeof(parser_t)); + service_t* t = ts->ths_service; - prs->prs_output = output; + prs->prs_output = output; prs->prs_subscription = ts; - prs->prs_service = t; + prs->prs_service = t; TAILQ_INIT(&prs->prs_rstlog); elementary_set_init(&prs->prs_components, LS_PARSER, service_nicename(t), t); streaming_target_init(&prs->prs_input, &parser_input_ops, prs, 0); return &prs->prs_input; - } /* * Parser destroy */ -void -parser_destroy(streaming_target_t *pad) -{ - parser_t *prs = (parser_t *)pad; - elementary_stream_t *es; - parser_es_t *pes; +void parser_destroy(streaming_target_t* pad) { + parser_t* prs = (parser_t*)pad; + elementary_stream_t* es; + parser_es_t* pes; streaming_queue_clear(&prs->prs_rstlog); - TAILQ_FOREACH(es, &prs->prs_components.set_all, es_link) { - pes = (parser_es_t *)es; + TAILQ_FOREACH (es, &prs->prs_components.set_all, es_link) { + pes = (parser_es_t*)es; parser_clean_es(pes); if (pes->es_psi.mt_name) dvb_table_parse_done(&pes->es_psi); diff --git a/src/parsers/parser_avc.c b/src/parsers/parser_avc.c index eb6d2d6a9..45e0da067 100644 --- a/src/parsers/parser_avc.c +++ b/src/parsers/parser_avc.c @@ -24,10 +24,8 @@ #include "parser_h264.h" #include "bitstream.h" -static const uint8_t * -avc_find_startcode_internal(const uint8_t *p, const uint8_t *end) -{ - const uint8_t *a = p + 4 - ((intptr_t)p & 3); +static const uint8_t* avc_find_startcode_internal(const uint8_t* p, const uint8_t* end) { + const uint8_t* a = p + 4 - ((intptr_t)p & 3); for (end -= 3; p < a && p < end; p++) { if (p[0] == 0 && p[1] == 0 && p[2] == 1) @@ -36,20 +34,20 @@ avc_find_startcode_internal(const uint8_t *p, const uint8_t *end) for (end -= 3; p < end; p += 4) { uint32_t x = *(const uint32_t*)p; -// if ((x - 0x01000100) & (~x) & 0x80008000) // little endian -// if ((x - 0x00010001) & (~x) & 0x00800080) // big endian + // if ((x - 0x01000100) & (~x) & 0x80008000) // little endian + // if ((x - 0x00010001) & (~x) & 0x00800080) // big endian if ((x - 0x01010101) & (~x) & 0x80808080) { // generic if (p[1] == 0) { - if (p[0] == 0 && p[2] == 1) - return p; - if (p[2] == 0 && p[3] == 1) - return p+1; + if (p[0] == 0 && p[2] == 1) + return p; + if (p[2] == 0 && p[3] == 1) + return p + 1; } if (p[3] == 0) { - if (p[2] == 0 && p[4] == 1) - return p+2; - if (p[4] == 0 && p[5] == 1) - return p+3; + if (p[2] == 0 && p[4] == 1) + return p + 2; + if (p[4] == 0 && p[5] == 1) + return p + 3; } } } @@ -62,27 +60,26 @@ avc_find_startcode_internal(const uint8_t *p, const uint8_t *end) return end + 3; } -const uint8_t * -avc_find_startcode(const uint8_t *p, const uint8_t *end) -{ - const uint8_t *out= avc_find_startcode_internal(p, end); - while(p 4) { unsigned int size; - uint8_t nal_type; + uint8_t nal_type; size = MIN(RB32(buf), end - buf - 4); buf += 4; nal_type = buf[0] & 0x1f; if ((nal_type == H264_NAL_SPS) && (size >= 4) && (size <= UINT16_MAX)) { - sps_array = realloc(sps_array,sizeof(uint8_t*)*(sps_count+1)); - sps_size_array = realloc(sps_size_array,sizeof(uint32_t)*(sps_count+1)); - sps_array[sps_count] = buf; + sps_array = realloc(sps_array, sizeof(uint8_t*) * (sps_count + 1)); + sps_size_array = realloc(sps_size_array, sizeof(uint32_t) * (sps_count + 1)); + sps_array[sps_count] = buf; sps_size_array[sps_count] = size; sps_count++; } else if ((nal_type == H264_NAL_PPS) && (size <= UINT16_MAX)) { - pps_size_array = realloc(pps_size_array,sizeof(uint32_t)*(pps_count+1)); - pps_array = realloc(pps_array,sizeof (uint8_t*)*(pps_count+1)); - pps_array[pps_count] = buf; + pps_size_array = realloc(pps_size_array, sizeof(uint32_t) * (pps_count + 1)); + pps_array = realloc(pps_array, sizeof(uint8_t*) * (pps_count + 1)); + pps_array[pps_count] = buf; pps_size_array[pps_count] = size; pps_count++; } buf += size; } - if(!sps_count || !pps_count) { + if (!sps_count || !pps_count) { ret = -1; goto end; } - sbuf_put_byte(sb, 1); /* version */ + sbuf_put_byte(sb, 1); /* version */ sbuf_put_byte(sb, sps_array[0][1]); /* profile */ sbuf_put_byte(sb, sps_array[0][2]); /* profile compat */ sbuf_put_byte(sb, sps_array[0][3]); /* level */ sbuf_put_byte(sb, 0xff); /* 6 bits reserved (111111) + 2 bits nal size length - 1 (11) */ - sbuf_put_byte(sb, 0xe0+sps_count); /* 3 bits reserved (111) + 5 bits number of sps (00001) */ - for (i=0;ipkt_payload), - pktbuf_len(src->pkt_payload)); - + avc_parse_nal_units(&payload, pktbuf_ptr(src->pkt_payload), pktbuf_len(src->pkt_payload)); + pkt->pkt_payload = pktbuf_make(payload.sb_data, payload.sb_ptr); return pkt; } diff --git a/src/parsers/parser_avc.h b/src/parsers/parser_avc.h index 4ff0effa6..23637d8ed 100644 --- a/src/parsers/parser_avc.h +++ b/src/parsers/parser_avc.h @@ -26,12 +26,12 @@ #include "packet.h" #include "sbuf.h" -const uint8_t * avc_find_startcode(const uint8_t *p, const uint8_t *end); +const uint8_t* avc_find_startcode(const uint8_t* p, const uint8_t* end); -int avc_parse_nal_units(sbuf_t *sb, const uint8_t *buf_in, int size); +int avc_parse_nal_units(sbuf_t* sb, const uint8_t* buf_in, int size); -int isom_write_avcc(sbuf_t *sb, const uint8_t *src, int len); +int isom_write_avcc(sbuf_t* sb, const uint8_t* src, int len); -th_pkt_t *avc_convert_pkt(th_pkt_t *src); +th_pkt_t* avc_convert_pkt(th_pkt_t* src); -#endif +#endif diff --git a/src/parsers/parser_h264.c b/src/parsers/parser_h264.c index ade299a63..82d0bb438 100644 --- a/src/parsers/parser_h264.c +++ b/src/parsers/parser_h264.c @@ -34,21 +34,19 @@ #include "bitstream.h" #include "service.h" -#define MAX_SPS_COUNT 32 -#define MAX_PPS_COUNT 256 +#define MAX_SPS_COUNT 32 +#define MAX_PPS_COUNT 256 /** * H.264 parser, nal escaper */ -void * -h264_nal_deescape(bitstream_t *bs, const uint8_t *data, int size) -{ - uint_fast8_t c; - uint8_t *d; +void* h264_nal_deescape(bitstream_t* bs, const uint8_t* data, int size) { + uint_fast8_t c; + uint8_t* d; const uint8_t *end, *end2; bs->rdata = d = malloc(size); - bs->offset = 0; + bs->offset = 0; end2 = data + size; @@ -67,42 +65,40 @@ h264_nal_deescape(bitstream_t *bs, const uint8_t *data, int size) data += 2; } } - } while (data < end2) *d++ = *data++; bs->len = (d - bs->rdata) * 8; - return (void *)bs->rdata; + return (void*)bs->rdata; } - /** * Level to CPB size table */ static const int h264_lev2cpbsize[][2] = { - {10, 175}, - {11, 500}, - {12, 1000}, - {13, 2000}, - {20, 2000}, - {21, 4000}, - {22, 4000}, - {30, 10000}, - {31, 14000}, - {32, 20000}, - {40, 25000}, - {41, 62500}, - {42, 62500}, - {50, 135000}, - {51, 240000}, - {-1, -1}, + {10, 175}, + {11, 500}, + {12, 1000}, + {13, 2000}, + {20, 2000}, + {21, 4000}, + {22, 4000}, + {30, 10000}, + {31, 14000}, + {32, 20000}, + {40, 25000}, + {41, 62500}, + {42, 62500}, + {50, 135000}, + {51, 240000}, + {-1, -1}, }; typedef struct h264_sps { - uint8_t valid: 1; + uint8_t valid : 1; uint8_t mbs_only_flag; uint8_t aff; uint8_t fixed_rate; @@ -117,7 +113,7 @@ typedef struct h264_sps { } h264_sps_t; typedef struct h264_pps { - uint8_t valid: 1; + uint8_t valid : 1; uint8_t sps_id; } h264_pps_t; @@ -130,56 +126,51 @@ typedef struct h264_private { } h264_private_t; - - static const uint16_t h264_aspect[17][2] = { - {0, 1}, - {1, 1}, - {12, 11}, - {10, 11}, - {16, 11}, - {40, 33}, - {24, 11}, - {20, 11}, - {32, 11}, - {80, 33}, - {18, 11}, - {15, 11}, - {64, 33}, - {160,99}, - {4, 3}, - {3, 2}, - {2, 1}, + {0, 1}, + {1, 1}, + {12, 11}, + {10, 11}, + {16, 11}, + {40, 33}, + {24, 11}, + {20, 11}, + {32, 11}, + {80, 33}, + {18, 11}, + {15, 11}, + {64, 33}, + {160, 99}, + {4, 3}, + {3, 2}, + {2, 1}, }; - -static int -decode_vui(h264_sps_t *sps, bitstream_t *bs) -{ +static int decode_vui(h264_sps_t* sps, bitstream_t* bs) { sps->aspect_num = 1; sps->aspect_den = 1; if (read_bits1(bs)) { uint32_t aspect = read_bits(bs, 8); - if(aspect == 255) { + if (aspect == 255) { sps->aspect_num = read_bits(bs, 16); sps->aspect_den = read_bits(bs, 16); - } else if(aspect < ARRAY_SIZE(h264_aspect)) { + } else if (aspect < ARRAY_SIZE(h264_aspect)) { sps->aspect_num = h264_aspect[aspect][0]; sps->aspect_den = h264_aspect[aspect][1]; } } - if (read_bits1(bs)) /* overscan_info_present_flag */ - skip_bits1(bs); /* overscan_appropriate_flag */ + if (read_bits1(bs)) /* overscan_info_present_flag */ + skip_bits1(bs); /* overscan_appropriate_flag */ - if (read_bits1(bs)) { /* video_signal_type_present_flag */ - skip_bits(bs, 3); /* video_format */ - skip_bits1(bs); /* video_full_range_flag */ - if(read_bits1(bs)){ /* colour_description_present_flag */ - skip_bits(bs, 8); /* colour_primaries */ - skip_bits(bs, 8); /* transfer_characteristics */ - skip_bits(bs, 8); /* matrix_coefficients */ + if (read_bits1(bs)) { /* video_signal_type_present_flag */ + skip_bits(bs, 3); /* video_format */ + skip_bits1(bs); /* video_full_range_flag */ + if (read_bits1(bs)) { /* colour_description_present_flag */ + skip_bits(bs, 8); /* colour_primaries */ + skip_bits(bs, 8); /* transfer_characteristics */ + skip_bits(bs, 8); /* matrix_coefficients */ } } @@ -188,7 +179,7 @@ decode_vui(h264_sps_t *sps, bitstream_t *bs) read_golomb_ue(bs); /* chroma_sample_location_type_bottom_field */ } - if (!read_bits1(bs)) /* We need timing info */ + if (!read_bits1(bs)) /* We need timing info */ return 0; if (remaining_bits(bs) < 65) @@ -200,55 +191,48 @@ decode_vui(h264_sps_t *sps, bitstream_t *bs) return 0; } - - -static void -decode_scaling_list(bitstream_t *bs, int size) -{ +static void decode_scaling_list(bitstream_t* bs, int size) { int i, last = 8, next = 8; - if(!read_bits1(bs)) + if (!read_bits1(bs)) return; /* matrix not written */ - for (i=0;ies_priv) == NULL) { p = st->es_priv = calloc(1, sizeof(h264_private_t)); - p->start = mclk(); + p->start = mclk(); } profile_idc = read_bits(bs, 8); - skip_bits1(bs); //constraint_set0_flag - skip_bits1(bs); //constraint_set1_flag - skip_bits1(bs); //constraint_set2_flag - skip_bits1(bs); //constraint_set3_flag + skip_bits1(bs); // constraint_set0_flag + skip_bits1(bs); // constraint_set1_flag + skip_bits1(bs); // constraint_set2_flag + skip_bits1(bs); // constraint_set3_flag skip_bits(bs, 4); // reserved level_idc = read_bits(bs, 8); sps_id = read_golomb_ue(bs); - if(sps_id >= MAX_SPS_COUNT) + if (sps_id >= MAX_SPS_COUNT) return -1; sps = &p->sps[sps_id]; - i = 0; + i = 0; cbpsize = -1; while (h264_lev2cpbsize[i][0] != -1) { if (h264_lev2cpbsize[i][0] >= level_idc) { @@ -260,15 +244,15 @@ h264_decode_seq_parameter_set(parser_es_t *st, bitstream_t *bs) if (cbpsize == -1) return -1; - if (profile_idc >= 100){ //high profile + if (profile_idc >= 100) { // high profile tmp = read_golomb_ue(bs); - if (tmp == 3) //chroma_format_idc - read_bits1(bs); //residual_color_transform_flag - read_golomb_ue(bs); //bit_depth_luma_minus8 - read_golomb_ue(bs); //bit_depth_chroma_minus8 - read_bits1(bs); //transform_bypass + if (tmp == 3) // chroma_format_idc + read_bits1(bs); // residual_color_transform_flag + read_golomb_ue(bs); // bit_depth_luma_minus8 + read_golomb_ue(bs); // bit_depth_chroma_minus8 + read_bits1(bs); // transform_bypass - if(read_bits1(bs)) { + if (read_bits1(bs)) { /* Scaling matrices */ decode_scaling_list(bs, 16); decode_scaling_list(bs, 16); @@ -279,24 +263,23 @@ h264_decode_seq_parameter_set(parser_es_t *st, bitstream_t *bs) decode_scaling_list(bs, 64); decode_scaling_list(bs, 64); - } } max_frame_num_bits = read_golomb_ue(bs) + 4; - poc_type = read_golomb_ue(bs); // pic_order_cnt_type + poc_type = read_golomb_ue(bs); // pic_order_cnt_type - if(poc_type == 0){ + if (poc_type == 0) { read_golomb_ue(bs); - } else if(poc_type == 1){ + } else if (poc_type == 1) { skip_bits1(bs); read_golomb_se(bs); read_golomb_se(bs); tmp = read_golomb_ue(bs); /* poc_cycle_length */ - for(i = 0; i < tmp; i++) + for (i = 0; i < tmp; i++) read_golomb_se(bs); - }else if(poc_type != 2){ + } else if (poc_type != 2) { /* Illegal poc */ return -1; } @@ -309,15 +292,15 @@ h264_decode_seq_parameter_set(parser_es_t *st, bitstream_t *bs) height = read_golomb_ue(bs) + 1; /* mb height */ mbs_only_flag = read_bits1(bs); - aff = 0; - if(!mbs_only_flag) + aff = 0; + if (!mbs_only_flag) aff = read_bits1(bs); read_bits1(bs); /* CROP */ crop_left = crop_right = crop_top = crop_bottom = 0; - if (read_bits1(bs)){ + if (read_bits1(bs)) { crop_left = read_golomb_ue(bs) * 2; crop_right = read_golomb_ue(bs) * 2; crop_top = read_golomb_ue(bs) * 2; @@ -329,53 +312,46 @@ h264_decode_seq_parameter_set(parser_es_t *st, bitstream_t *bs) return -1; sps->max_frame_num_bits = max_frame_num_bits; - sps->mbs_only_flag = mbs_only_flag; - sps->aff = aff; - sps->cbpsize = cbpsize * 125; /* Convert from kbit to bytes */ - sps->width = width * 16 - crop_left - crop_right; - sps->height = height * 16 - crop_top - crop_bottom; - sps->valid = 1; + sps->mbs_only_flag = mbs_only_flag; + sps->aff = aff; + sps->cbpsize = cbpsize * 125; /* Convert from kbit to bytes */ + sps->width = width * 16 - crop_left - crop_right; + sps->height = height * 16 - crop_top - crop_bottom; + sps->valid = 1; return 0; } +int h264_decode_pic_parameter_set(parser_es_t* st, bitstream_t* bs) { + h264_private_t* p; + uint32_t pps_id, sps_id; -int -h264_decode_pic_parameter_set(parser_es_t *st, bitstream_t *bs) -{ - h264_private_t *p; - uint32_t pps_id, sps_id; - - if((p = st->es_priv) == NULL) { + if ((p = st->es_priv) == NULL) { p = st->es_priv = calloc(1, sizeof(h264_private_t)); - p->start = mclk(); + p->start = mclk(); } - + pps_id = read_golomb_ue(bs); - if(pps_id >= MAX_PPS_COUNT) + if (pps_id >= MAX_PPS_COUNT) return 0; sps_id = read_golomb_ue(bs); - if(sps_id >= MAX_SPS_COUNT) + if (sps_id >= MAX_SPS_COUNT) return -1; if (!p->sps[sps_id].valid) return -1; p->pps[pps_id].sps_id = sps_id; - p->pps[pps_id].valid = 1; + p->pps[pps_id].valid = 1; return 0; } - -int -h264_decode_slice_header(parser_es_t *st, bitstream_t *bs, int *pkttype, - int *isfield) -{ - h264_private_t *p; - h264_pps_t *pps; - h264_sps_t *sps; - uint32_t slice_type, pps_id, width, height, v; - uint64_t d; +int h264_decode_slice_header(parser_es_t* st, bitstream_t* bs, int* pkttype, int* isfield) { + h264_private_t* p; + h264_pps_t* pps; + h264_sps_t* sps; + uint32_t slice_type, pps_id, width, height, v; + uint64_t d; *pkttype = 0; *isfield = 0; @@ -387,7 +363,7 @@ h264_decode_slice_header(parser_es_t *st, bitstream_t *bs, int *pkttype, slice_type = read_golomb_ue(bs); if (slice_type > 4) - slice_type -= 5; /* Fixed slice type per frame */ + slice_type -= 5; /* Fixed slice type per frame */ pps_id = read_golomb_ue(bs); if (pps_id >= MAX_PPS_COUNT) @@ -402,18 +378,18 @@ h264_decode_slice_header(parser_es_t *st, bitstream_t *bs, int *pkttype, if (!sps->max_frame_num_bits) return -1; - switch(slice_type) { - case 0: - *pkttype = PKT_P_FRAME; - break; - case 1: - *pkttype = PKT_B_FRAME; - break; - case 2: - *pkttype = PKT_I_FRAME; - break; - default: - return -1; + switch (slice_type) { + case 0: + *pkttype = PKT_P_FRAME; + break; + case 1: + *pkttype = PKT_B_FRAME; + break; + case 2: + *pkttype = PKT_I_FRAME; + break; + default: + return -1; } skip_bits(bs, sps->max_frame_num_bits); @@ -444,10 +420,10 @@ h264_decode_slice_header(parser_es_t *st, bitstream_t *bs, int *pkttype, parser_set_stream_vparam(st, width, height, d); if (sps->aspect_num && sps->aspect_den) { - width *= sps->aspect_num; + width *= sps->aspect_num; height *= sps->aspect_den; if (width && height) { - v = gcdU32(width, height); + v = gcdU32(width, height); st->es_aspect_num = width / v; st->es_aspect_den = height / v; } diff --git a/src/parsers/parser_h264.h b/src/parsers/parser_h264.h index 79d8241fe..cc09a038d 100644 --- a/src/parsers/parser_h264.h +++ b/src/parsers/parser_h264.h @@ -36,13 +36,12 @@ #define H264_NAL_SPS_EXT 13 #define H264_NAL_AUXILIARY_SLICE 19 -void *h264_nal_deescape(bitstream_t *bs, const uint8_t *data, int size); +void* h264_nal_deescape(bitstream_t* bs, const uint8_t* data, int size); -int h264_decode_seq_parameter_set(parser_es_t *st, bitstream_t *bs); +int h264_decode_seq_parameter_set(parser_es_t* st, bitstream_t* bs); -int h264_decode_pic_parameter_set(parser_es_t *st, bitstream_t *bs); +int h264_decode_pic_parameter_set(parser_es_t* st, bitstream_t* bs); -int h264_decode_slice_header(parser_es_t *st, bitstream_t *bs, - int *pkttype, int *isfield); +int h264_decode_slice_header(parser_es_t* st, bitstream_t* bs, int* pkttype, int* isfield); #endif /* PARSER_H264_H_ */ diff --git a/src/parsers/parser_hevc.c b/src/parsers/parser_hevc.c index c46de5a2b..d5c984763 100644 --- a/src/parsers/parser_hevc.c +++ b/src/parsers/parser_hevc.c @@ -46,12 +46,12 @@ #define IS_IRAP_NAL(nal_type) (nal_type >= 16 && nal_type <= 23) -#define MAX_REFS 16 +#define MAX_REFS 16 #define MAX_SPATIAL_SEGMENTATION 4096 // max. value of u(12) field -#define MAX_SUB_LAYERS 7 -#define MAX_VPS_COUNT 16 -#define MAX_SPS_COUNT 32 -#define MAX_PPS_COUNT 256 +#define MAX_SUB_LAYERS 7 +#define MAX_VPS_COUNT 16 +#define MAX_SPS_COUNT 32 +#define MAX_PPS_COUNT 256 #define MAX_SHORT_TERM_RPS_COUNT 64 #define B_SLICE 0 @@ -59,1004 +59,966 @@ #define I_SLICE 2 typedef struct HVCCNALUnitArray { - uint8_t NAL_unit_type; - uint16_t numNalus; - uint16_t *nalUnitLength; - uint8_t **nalUnit; + uint8_t NAL_unit_type; + uint16_t numNalus; + uint16_t* nalUnitLength; + uint8_t** nalUnit; } HVCCNALUnitArray; typedef struct HEVCDecoderConfigurationRecord { - uint8_t configurationVersion; - uint8_t general_profile_space; - uint8_t general_tier_flag; - uint8_t general_profile_idc; - uint32_t general_profile_compatibility_flags; - uint64_t general_constraint_indicator_flags; - uint8_t general_level_idc; - uint16_t min_spatial_segmentation_idc; - uint8_t parallelismType; - uint8_t chromaFormat; - uint8_t bitDepthLumaMinus8; - uint8_t bitDepthChromaMinus8; - uint16_t avgFrameRate; - uint8_t constantFrameRate; - uint8_t numTemporalLayers; - uint8_t temporalIdNested; - uint8_t lengthSizeMinusOne; - uint8_t numOfArrays; - HVCCNALUnitArray *array; + uint8_t configurationVersion; + uint8_t general_profile_space; + uint8_t general_tier_flag; + uint8_t general_profile_idc; + uint32_t general_profile_compatibility_flags; + uint64_t general_constraint_indicator_flags; + uint8_t general_level_idc; + uint16_t min_spatial_segmentation_idc; + uint8_t parallelismType; + uint8_t chromaFormat; + uint8_t bitDepthLumaMinus8; + uint8_t bitDepthChromaMinus8; + uint16_t avgFrameRate; + uint8_t constantFrameRate; + uint8_t numTemporalLayers; + uint8_t temporalIdNested; + uint8_t lengthSizeMinusOne; + uint8_t numOfArrays; + HVCCNALUnitArray* array; } HEVCDecoderConfigurationRecord; typedef struct HVCCProfileTierLevel { - uint8_t profile_space; - uint8_t tier_flag; - uint8_t profile_idc; - uint32_t profile_compatibility_flags; - uint64_t constraint_indicator_flags; - uint8_t level_idc; + uint8_t profile_space; + uint8_t tier_flag; + uint8_t profile_idc; + uint32_t profile_compatibility_flags; + uint64_t constraint_indicator_flags; + uint8_t level_idc; } HVCCProfileTierLevel; -static void hvcc_update_ptl(HEVCDecoderConfigurationRecord *hvcc, - HVCCProfileTierLevel *ptl) -{ - /* - * The value of general_profile_space in all the parameter sets must be - * identical. - */ - hvcc->general_profile_space = ptl->profile_space; - - /* - * The level indication general_level_idc must indicate a level of - * capability equal to or greater than the highest level indicated for the - * highest tier in all the parameter sets. - */ - if (hvcc->general_tier_flag < ptl->tier_flag) - hvcc->general_level_idc = ptl->level_idc; - else - hvcc->general_level_idc = MAX(hvcc->general_level_idc, ptl->level_idc); +static void hvcc_update_ptl(HEVCDecoderConfigurationRecord* hvcc, HVCCProfileTierLevel* ptl) { + /* + * The value of general_profile_space in all the parameter sets must be + * identical. + */ + hvcc->general_profile_space = ptl->profile_space; + + /* + * The level indication general_level_idc must indicate a level of + * capability equal to or greater than the highest level indicated for the + * highest tier in all the parameter sets. + */ + if (hvcc->general_tier_flag < ptl->tier_flag) + hvcc->general_level_idc = ptl->level_idc; + else + hvcc->general_level_idc = MAX(hvcc->general_level_idc, ptl->level_idc); + + /* + * The tier indication general_tier_flag must indicate a tier equal to or + * greater than the highest tier indicated in all the parameter sets. + */ + hvcc->general_tier_flag = MAX(hvcc->general_tier_flag, ptl->tier_flag); + + /* + * The profile indication general_profile_idc must indicate a profile to + * which the stream associated with this configuration record conforms. + * + * If the sequence parameter sets are marked with different profiles, then + * the stream may need examination to determine which profile, if any, the + * entire stream conforms to. If the entire stream is not examined, or the + * examination reveals that there is no profile to which the entire stream + * conforms, then the entire stream must be split into two or more + * sub-streams with separate configuration records in which these rules can + * be met. + * + * Note: set the profile to the highest value for the sake of simplicity. + */ + hvcc->general_profile_idc = MAX(hvcc->general_profile_idc, ptl->profile_idc); + + /* + * Each bit in general_profile_compatibility_flags may only be set if all + * the parameter sets set that bit. + */ + hvcc->general_profile_compatibility_flags &= ptl->profile_compatibility_flags; + + /* + * Each bit in general_constraint_indicator_flags may only be set if all + * the parameter sets set that bit. + */ + hvcc->general_constraint_indicator_flags &= ptl->constraint_indicator_flags; +} - /* - * The tier indication general_tier_flag must indicate a tier equal to or - * greater than the highest tier indicated in all the parameter sets. - */ - hvcc->general_tier_flag = MAX(hvcc->general_tier_flag, ptl->tier_flag); +static int +hvcc_parse_ptl(bitstream_t* gb, HEVCDecoderConfigurationRecord* hvcc, unsigned int max_sub_layers) { + unsigned int i; + HVCCProfileTierLevel general_ptl; + uint8_t sub_layer_profile_present_flag[MAX_SUB_LAYERS]; + uint8_t sub_layer_level_present_flag[MAX_SUB_LAYERS]; - /* - * The profile indication general_profile_idc must indicate a profile to - * which the stream associated with this configuration record conforms. - * - * If the sequence parameter sets are marked with different profiles, then - * the stream may need examination to determine which profile, if any, the - * entire stream conforms to. If the entire stream is not examined, or the - * examination reveals that there is no profile to which the entire stream - * conforms, then the entire stream must be split into two or more - * sub-streams with separate configuration records in which these rules can - * be met. - * - * Note: set the profile to the highest value for the sake of simplicity. - */ - hvcc->general_profile_idc = MAX(hvcc->general_profile_idc, ptl->profile_idc); + if (remaining_bits(gb) < 2 + 1 + 5 + 32 + 4 + 16 + 16 + 12) + return -1; - /* - * Each bit in general_profile_compatibility_flags may only be set if all - * the parameter sets set that bit. - */ - hvcc->general_profile_compatibility_flags &= ptl->profile_compatibility_flags; + general_ptl.profile_space = read_bits(gb, 2); + general_ptl.tier_flag = read_bits1(gb); + general_ptl.profile_idc = read_bits(gb, 5); + general_ptl.profile_compatibility_flags = read_bits(gb, 32); + if (general_ptl.profile_idc == 0) { + for (i = 0; i < 32; i++) + if (general_ptl.profile_compatibility_flags & (1 << (31 - i))) + general_ptl.profile_idc = i; + } + general_ptl.constraint_indicator_flags = read_bits64(gb, 48); - /* - * Each bit in general_constraint_indicator_flags may only be set if all - * the parameter sets set that bit. - */ - hvcc->general_constraint_indicator_flags &= ptl->constraint_indicator_flags; -} + if (remaining_bits(gb) < 8 + (8 * 2 * (max_sub_layers - 1 > 0))) + return -1; -static int hvcc_parse_ptl(bitstream_t *gb, - HEVCDecoderConfigurationRecord *hvcc, - unsigned int max_sub_layers) -{ - unsigned int i; - HVCCProfileTierLevel general_ptl; - uint8_t sub_layer_profile_present_flag[MAX_SUB_LAYERS]; - uint8_t sub_layer_level_present_flag[MAX_SUB_LAYERS]; + general_ptl.level_idc = read_bits(gb, 8); + if (hvcc) + hvcc_update_ptl(hvcc, &general_ptl); - if (remaining_bits(gb) < 2+1+5 + 32 + 4 + 16 + 16 + 12) - return -1; + for (i = 0; i < max_sub_layers - 1; i++) { + sub_layer_profile_present_flag[i] = read_bits1(gb); + sub_layer_level_present_flag[i] = read_bits1(gb); + } - general_ptl.profile_space = read_bits(gb, 2); - general_ptl.tier_flag = read_bits1(gb); - general_ptl.profile_idc = read_bits(gb, 5); - general_ptl.profile_compatibility_flags = read_bits(gb, 32); - if (general_ptl.profile_idc == 0) { - for (i = 0; i < 32; i++) - if (general_ptl.profile_compatibility_flags & (1 << (31-i))) - general_ptl.profile_idc = i; + if (max_sub_layers - 1 > 0) + for (i = max_sub_layers - 1; i < 8; i++) + skip_bits(gb, 2); // reserved_zero_2bits[i] + + for (i = 0; i < max_sub_layers - 1; i++) { + if (sub_layer_profile_present_flag[i]) { + /* + * sub_layer_profile_space[i] u(2) + * sub_layer_tier_flag[i] u(1) + * sub_layer_profile_idc[i] u(5) + * sub_layer_profile_compatibility_flag[i][0..31] u(32) + * sub_layer_progressive_source_flag[i] u(1) + * sub_layer_interlaced_source_flag[i] u(1) + * sub_layer_non_packed_constraint_flag[i] u(1) + * sub_layer_frame_only_constraint_flag[i] u(1) + * sub_layer_reserved_zero_44bits[i] u(44) + */ + skip_bits(gb, 32); + skip_bits(gb, 32); + skip_bits(gb, 24); } - general_ptl.constraint_indicator_flags = read_bits64(gb, 48); - - if (remaining_bits(gb) < 8 + (8*2 * (max_sub_layers - 1 > 0))) - return -1; - general_ptl.level_idc = read_bits(gb, 8); - if (hvcc) - hvcc_update_ptl(hvcc, &general_ptl); + if (sub_layer_level_present_flag[i]) + skip_bits(gb, 8); + } + return 0; +} - for (i = 0; i < max_sub_layers - 1; i++) { - sub_layer_profile_present_flag[i] = read_bits1(gb); - sub_layer_level_present_flag[i] = read_bits1(gb); - } +static void skip_sub_layer_hrd_parameters(bitstream_t* gb, + unsigned int cpb_cnt, + uint8_t sub_pic_hrd_params_present_flag) { + unsigned int i; - if (max_sub_layers - 1 > 0) - for (i = max_sub_layers - 1; i < 8; i++) - skip_bits(gb, 2); // reserved_zero_2bits[i] - - for (i = 0; i < max_sub_layers - 1; i++) { - if (sub_layer_profile_present_flag[i]) { - /* - * sub_layer_profile_space[i] u(2) - * sub_layer_tier_flag[i] u(1) - * sub_layer_profile_idc[i] u(5) - * sub_layer_profile_compatibility_flag[i][0..31] u(32) - * sub_layer_progressive_source_flag[i] u(1) - * sub_layer_interlaced_source_flag[i] u(1) - * sub_layer_non_packed_constraint_flag[i] u(1) - * sub_layer_frame_only_constraint_flag[i] u(1) - * sub_layer_reserved_zero_44bits[i] u(44) - */ - skip_bits(gb, 32); - skip_bits(gb, 32); - skip_bits(gb, 24); - } + for (i = 0; i < cpb_cnt; i++) { + read_golomb_ue(gb); // bit_rate_value_minus1 + read_golomb_ue(gb); // cpb_size_value_minus1 - if (sub_layer_level_present_flag[i]) - skip_bits(gb, 8); + if (sub_pic_hrd_params_present_flag) { + read_golomb_ue(gb); // cpb_size_du_value_minus1 + read_golomb_ue(gb); // bit_rate_du_value_minus1 } - return 0; -} -static void skip_sub_layer_hrd_parameters(bitstream_t *gb, - unsigned int cpb_cnt, - uint8_t sub_pic_hrd_params_present_flag) -{ - unsigned int i; + skip_bits1(gb); // cbr_flag + } +} - for (i = 0; i < cpb_cnt; i++) { - read_golomb_ue(gb); // bit_rate_value_minus1 - read_golomb_ue(gb); // cpb_size_value_minus1 +static int +skip_hrd_parameters(bitstream_t* gb, uint8_t cprms_present_flag, unsigned int max_sub_layers) { + unsigned int i; + uint8_t sub_pic_hrd_params_present_flag = 0; + uint8_t nal_hrd_parameters_present_flag = 0; + uint8_t vcl_hrd_parameters_present_flag = 0; - if (sub_pic_hrd_params_present_flag) { - read_golomb_ue(gb); // cpb_size_du_value_minus1 - read_golomb_ue(gb); // bit_rate_du_value_minus1 - } + if (cprms_present_flag) { + nal_hrd_parameters_present_flag = read_bits1(gb); + vcl_hrd_parameters_present_flag = read_bits1(gb); - skip_bits1(gb); // cbr_flag - } -} + if (nal_hrd_parameters_present_flag || vcl_hrd_parameters_present_flag) { + sub_pic_hrd_params_present_flag = read_bits1(gb); -static int skip_hrd_parameters(bitstream_t *gb, uint8_t cprms_present_flag, - unsigned int max_sub_layers) -{ - unsigned int i; - uint8_t sub_pic_hrd_params_present_flag = 0; - uint8_t nal_hrd_parameters_present_flag = 0; - uint8_t vcl_hrd_parameters_present_flag = 0; - - if (cprms_present_flag) { - nal_hrd_parameters_present_flag = read_bits1(gb); - vcl_hrd_parameters_present_flag = read_bits1(gb); - - if (nal_hrd_parameters_present_flag || - vcl_hrd_parameters_present_flag) { - sub_pic_hrd_params_present_flag = read_bits1(gb); - - if (sub_pic_hrd_params_present_flag) - /* - * tick_divisor_minus2 u(8) - * du_cpb_removal_delay_increment_length_minus1 u(5) - * sub_pic_cpb_params_in_pic_timing_sei_flag u(1) - * dpb_output_delay_du_length_minus1 u(5) - */ - skip_bits(gb, 19); - - /* - * bit_rate_scale u(4) - * cpb_size_scale u(4) - */ - skip_bits(gb, 8); - - if (sub_pic_hrd_params_present_flag) - skip_bits(gb, 4); // cpb_size_du_scale - - /* - * initial_cpb_removal_delay_length_minus1 u(5) - * au_cpb_removal_delay_length_minus1 u(5) - * dpb_output_delay_length_minus1 u(5) - */ - skip_bits(gb, 15); - } + if (sub_pic_hrd_params_present_flag) + /* + * tick_divisor_minus2 u(8) + * du_cpb_removal_delay_increment_length_minus1 u(5) + * sub_pic_cpb_params_in_pic_timing_sei_flag u(1) + * dpb_output_delay_du_length_minus1 u(5) + */ + skip_bits(gb, 19); + + /* + * bit_rate_scale u(4) + * cpb_size_scale u(4) + */ + skip_bits(gb, 8); + + if (sub_pic_hrd_params_present_flag) + skip_bits(gb, 4); // cpb_size_du_scale + + /* + * initial_cpb_removal_delay_length_minus1 u(5) + * au_cpb_removal_delay_length_minus1 u(5) + * dpb_output_delay_length_minus1 u(5) + */ + skip_bits(gb, 15); } + } - for (i = 0; i < max_sub_layers; i++) { - unsigned int cpb_cnt = 0; - uint8_t low_delay_hrd_flag = 0; - uint8_t fixed_pic_rate_within_cvs_flag = 0; - uint8_t fixed_pic_rate_general_flag = read_bits1(gb); - - if (!fixed_pic_rate_general_flag) - fixed_pic_rate_within_cvs_flag = read_bits1(gb); - - if (fixed_pic_rate_within_cvs_flag) - read_golomb_ue(gb); // elemental_duration_in_tc_minus1 - else - low_delay_hrd_flag = read_bits1(gb); + for (i = 0; i < max_sub_layers; i++) { + unsigned int cpb_cnt = 0; + uint8_t low_delay_hrd_flag = 0; + uint8_t fixed_pic_rate_within_cvs_flag = 0; + uint8_t fixed_pic_rate_general_flag = read_bits1(gb); - if (!low_delay_hrd_flag) { - cpb_cnt = read_golomb_ue(gb) + 1; - if (cpb_cnt > 32) - return -1; - } + if (!fixed_pic_rate_general_flag) + fixed_pic_rate_within_cvs_flag = read_bits1(gb); - if (nal_hrd_parameters_present_flag) - skip_sub_layer_hrd_parameters(gb, cpb_cnt, sub_pic_hrd_params_present_flag); + if (fixed_pic_rate_within_cvs_flag) + read_golomb_ue(gb); // elemental_duration_in_tc_minus1 + else + low_delay_hrd_flag = read_bits1(gb); - if (vcl_hrd_parameters_present_flag) - skip_sub_layer_hrd_parameters(gb, cpb_cnt, sub_pic_hrd_params_present_flag); + if (!low_delay_hrd_flag) { + cpb_cnt = read_golomb_ue(gb) + 1; + if (cpb_cnt > 32) + return -1; } - return 0; -} + if (nal_hrd_parameters_present_flag) + skip_sub_layer_hrd_parameters(gb, cpb_cnt, sub_pic_hrd_params_present_flag); -static void skip_timing_info(bitstream_t *gb) -{ - skip_bits(gb, 32); // num_units_in_tick - skip_bits(gb, 32); // time_scale + if (vcl_hrd_parameters_present_flag) + skip_sub_layer_hrd_parameters(gb, cpb_cnt, sub_pic_hrd_params_present_flag); + } - if (read_bits1(gb)) // poc_proportional_to_timing_flag - read_golomb_ue(gb); // num_ticks_poc_diff_one_minus1 + return 0; } -static void hvcc_parse_vui(bitstream_t *gb, - HEVCDecoderConfigurationRecord *hvcc, - unsigned int max_sub_layers) -{ - unsigned int min_spatial_segmentation_idc; - - if (read_bits1(gb)) // aspect_ratio_info_present_flag - if (read_bits(gb, 8) == 255) // aspect_ratio_idc - skip_bits(gb, 32); // sar_width u(16), sar_height u(16) - - if (read_bits1(gb)) // overscan_info_present_flag - skip_bits1(gb); // overscan_appropriate_flag - - if (read_bits1(gb)) { // video_signal_type_present_flag - skip_bits(gb, 4); // video_format u(3), video_full_range_flag u(1) - - if (read_bits1(gb)) // colour_description_present_flag - /* - * colour_primaries u(8) - * transfer_characteristics u(8) - * matrix_coeffs u(8) - */ - skip_bits(gb, 24); - } - - if (read_bits1(gb)) { // chroma_loc_info_present_flag - read_golomb_ue(gb); // chroma_sample_loc_type_top_field - read_golomb_ue(gb); // chroma_sample_loc_type_bottom_field - } +static void skip_timing_info(bitstream_t* gb) { + skip_bits(gb, 32); // num_units_in_tick + skip_bits(gb, 32); // time_scale - /* - * neutral_chroma_indication_flag u(1) - * field_seq_flag u(1) - * frame_field_info_present_flag u(1) - */ - skip_bits(gb, 3); + if (read_bits1(gb)) // poc_proportional_to_timing_flag + read_golomb_ue(gb); // num_ticks_poc_diff_one_minus1 +} - if (read_bits1(gb)) { // default_display_window_flag - read_golomb_ue(gb); // def_disp_win_left_offset - read_golomb_ue(gb); // def_disp_win_right_offset - read_golomb_ue(gb); // def_disp_win_top_offset - read_golomb_ue(gb); // def_disp_win_bottom_offset - } +static void +hvcc_parse_vui(bitstream_t* gb, HEVCDecoderConfigurationRecord* hvcc, unsigned int max_sub_layers) { + unsigned int min_spatial_segmentation_idc; - if (read_bits1(gb)) { // vui_timing_info_present_flag - skip_timing_info(gb); + if (read_bits1(gb)) // aspect_ratio_info_present_flag + if (read_bits(gb, 8) == 255) // aspect_ratio_idc + skip_bits(gb, 32); // sar_width u(16), sar_height u(16) - if (read_bits1(gb)) // vui_hrd_parameters_present_flag - skip_hrd_parameters(gb, 1, max_sub_layers); - } + if (read_bits1(gb)) // overscan_info_present_flag + skip_bits1(gb); // overscan_appropriate_flag - if (read_bits1(gb)) { // bitstream_restriction_flag - /* - * tiles_fixed_structure_flag u(1) - * motion_vectors_over_pic_boundaries_flag u(1) - * restricted_ref_pic_lists_flag u(1) - */ - skip_bits(gb, 3); + if (read_bits1(gb)) { // video_signal_type_present_flag + skip_bits(gb, 4); // video_format u(3), video_full_range_flag u(1) - min_spatial_segmentation_idc = read_golomb_ue(gb); + if (read_bits1(gb)) // colour_description_present_flag + /* + * colour_primaries u(8) + * transfer_characteristics u(8) + * matrix_coeffs u(8) + */ + skip_bits(gb, 24); + } - /* - * unsigned int(12) min_spatial_segmentation_idc; - * - * The min_spatial_segmentation_idc indication must indicate a level of - * spatial segmentation equal to or less than the lowest level of - * spatial segmentation indicated in all the parameter sets. - */ - hvcc->min_spatial_segmentation_idc = MIN(hvcc->min_spatial_segmentation_idc, - min_spatial_segmentation_idc); + if (read_bits1(gb)) { // chroma_loc_info_present_flag + read_golomb_ue(gb); // chroma_sample_loc_type_top_field + read_golomb_ue(gb); // chroma_sample_loc_type_bottom_field + } - read_golomb_ue(gb); // max_bytes_per_pic_denom - read_golomb_ue(gb); // max_bits_per_min_cu_denom - read_golomb_ue(gb); // log2_max_mv_length_horizontal - read_golomb_ue(gb); // log2_max_mv_length_vertical - } -} + /* + * neutral_chroma_indication_flag u(1) + * field_seq_flag u(1) + * frame_field_info_present_flag u(1) + */ + skip_bits(gb, 3); + + if (read_bits1(gb)) { // default_display_window_flag + read_golomb_ue(gb); // def_disp_win_left_offset + read_golomb_ue(gb); // def_disp_win_right_offset + read_golomb_ue(gb); // def_disp_win_top_offset + read_golomb_ue(gb); // def_disp_win_bottom_offset + } -static void skip_sub_layer_ordering_info(bitstream_t *gb) -{ - read_golomb_ue(gb); // max_dec_pic_buffering_minus1 - read_golomb_ue(gb); // max_num_reorder_pics - read_golomb_ue(gb); // max_latency_increase_plus1 -} + if (read_bits1(gb)) { // vui_timing_info_present_flag + skip_timing_info(gb); -static int hvcc_parse_vps(bitstream_t *gb, - HEVCDecoderConfigurationRecord *hvcc) -{ - unsigned int vps_max_sub_layers; + if (read_bits1(gb)) // vui_hrd_parameters_present_flag + skip_hrd_parameters(gb, 1, max_sub_layers); + } + if (read_bits1(gb)) { // bitstream_restriction_flag /* - * vps_video_parameter_set_id u(4) - * vps_reserved_three_2bits u(2) - * vps_max_layers_minus1 u(6) + * tiles_fixed_structure_flag u(1) + * motion_vectors_over_pic_boundaries_flag u(1) + * restricted_ref_pic_lists_flag u(1) */ - skip_bits(gb, 12); + skip_bits(gb, 3); - vps_max_sub_layers = read_bits(gb, 3) + 1; + min_spatial_segmentation_idc = read_golomb_ue(gb); /* - * numTemporalLayers greater than 1 indicates that the stream to which this - * configuration record applies is temporally scalable and the contained - * number of temporal layers (also referred to as temporal sub-layer or - * sub-layer in ISO/IEC 23008-2) is equal to numTemporalLayers. Value 1 - * indicates that the stream is not temporally scalable. Value 0 indicates - * that it is unknown whether the stream is temporally scalable. + * unsigned int(12) min_spatial_segmentation_idc; + * + * The min_spatial_segmentation_idc indication must indicate a level of + * spatial segmentation equal to or less than the lowest level of + * spatial segmentation indicated in all the parameter sets. */ - hvcc->numTemporalLayers = MAX(hvcc->numTemporalLayers, vps_max_sub_layers); + hvcc->min_spatial_segmentation_idc = + MIN(hvcc->min_spatial_segmentation_idc, min_spatial_segmentation_idc); - /* - * vps_temporal_id_nesting_flag u(1) - * vps_reserved_0xffff_16bits u(16) - */ - skip_bits(gb, 17); + read_golomb_ue(gb); // max_bytes_per_pic_denom + read_golomb_ue(gb); // max_bits_per_min_cu_denom + read_golomb_ue(gb); // log2_max_mv_length_horizontal + read_golomb_ue(gb); // log2_max_mv_length_vertical + } +} - if (hvcc_parse_ptl(gb, hvcc, vps_max_sub_layers)) - return -1; +static void skip_sub_layer_ordering_info(bitstream_t* gb) { + read_golomb_ue(gb); // max_dec_pic_buffering_minus1 + read_golomb_ue(gb); // max_num_reorder_pics + read_golomb_ue(gb); // max_latency_increase_plus1 +} + +static int hvcc_parse_vps(bitstream_t* gb, HEVCDecoderConfigurationRecord* hvcc) { + unsigned int vps_max_sub_layers; + + /* + * vps_video_parameter_set_id u(4) + * vps_reserved_three_2bits u(2) + * vps_max_layers_minus1 u(6) + */ + skip_bits(gb, 12); + + vps_max_sub_layers = read_bits(gb, 3) + 1; + + /* + * numTemporalLayers greater than 1 indicates that the stream to which this + * configuration record applies is temporally scalable and the contained + * number of temporal layers (also referred to as temporal sub-layer or + * sub-layer in ISO/IEC 23008-2) is equal to numTemporalLayers. Value 1 + * indicates that the stream is not temporally scalable. Value 0 indicates + * that it is unknown whether the stream is temporally scalable. + */ + hvcc->numTemporalLayers = MAX(hvcc->numTemporalLayers, vps_max_sub_layers); + + /* + * vps_temporal_id_nesting_flag u(1) + * vps_reserved_0xffff_16bits u(16) + */ + skip_bits(gb, 17); + + if (hvcc_parse_ptl(gb, hvcc, vps_max_sub_layers)) + return -1; - /* nothing useful for hvcC past this point */ - return 0; + /* nothing useful for hvcC past this point */ + return 0; } -static void skip_scaling_list_data(bitstream_t *gb) -{ - int i, j, k, num_coeffs; +static void skip_scaling_list_data(bitstream_t* gb) { + int i, j, k, num_coeffs; - for (i = 0; i < 4; i++) - for (j = 0; j < (i == 3 ? 2 : 6); j++) - if (!read_bits1(gb)) // scaling_list_pred_mode_flag[i][j] - read_golomb_ue(gb); // scaling_list_pred_matrix_id_delta[i][j] - else { - num_coeffs = MIN(64, 1 << (4 + (i << 1))); + for (i = 0; i < 4; i++) + for (j = 0; j < (i == 3 ? 2 : 6); j++) + if (!read_bits1(gb)) // scaling_list_pred_mode_flag[i][j] + read_golomb_ue(gb); // scaling_list_pred_matrix_id_delta[i][j] + else { + num_coeffs = MIN(64, 1 << (4 + (i << 1))); - if (i > 1) - read_golomb_se(gb); // scaling_list_dc_coef_minus8[i-2][j] + if (i > 1) + read_golomb_se(gb); // scaling_list_dc_coef_minus8[i-2][j] - for (k = 0; k < num_coeffs; k++) - read_golomb_se(gb); // scaling_list_delta_coef - } + for (k = 0; k < num_coeffs; k++) + read_golomb_se(gb); // scaling_list_delta_coef + } } -static int parse_rps(bitstream_t *gb, unsigned int rps_idx, - unsigned int num_rps, - unsigned int num_delta_pocs[MAX_SHORT_TERM_RPS_COUNT]) -{ - unsigned int i; +static int parse_rps(bitstream_t* gb, + unsigned int rps_idx, + unsigned int num_rps, + unsigned int num_delta_pocs[MAX_SHORT_TERM_RPS_COUNT]) { + unsigned int i; - if (rps_idx && read_bits1(gb)) { // inter_ref_pic_set_prediction_flag - /* this should only happen for slice headers, and this isn't one */ - if (rps_idx >= num_rps) - return -1; + if (rps_idx && read_bits1(gb)) { // inter_ref_pic_set_prediction_flag + /* this should only happen for slice headers, and this isn't one */ + if (rps_idx >= num_rps) + return -1; - skip_bits1 (gb); // delta_rps_sign - read_golomb_ue(gb); // abs_delta_rps_minus1 + skip_bits1(gb); // delta_rps_sign + read_golomb_ue(gb); // abs_delta_rps_minus1 - num_delta_pocs[rps_idx] = 0; + num_delta_pocs[rps_idx] = 0; - /* - * From libavcodec/hevc_ps.c: - * - * if (is_slice_header) { - * //foo - * } else - * rps_ridx = &sps->st_rps[rps - sps->st_rps - 1]; - * - * where: - * rps: &sps->st_rps[rps_idx] - * sps->st_rps: &sps->st_rps[0] - * is_slice_header: rps_idx == num_rps - * - * thus: - * if (num_rps != rps_idx) - * rps_ridx = &sps->st_rps[rps_idx - 1]; - * - * NumDeltaPocs[RefRpsIdx]: num_delta_pocs[rps_idx - 1] - */ - for (i = 0; i <= num_delta_pocs[rps_idx - 1]; i++) { - uint8_t use_delta_flag = 0; - uint8_t used_by_curr_pic_flag = read_bits1(gb); - if (!used_by_curr_pic_flag) - use_delta_flag = read_bits1(gb); - - if (used_by_curr_pic_flag || use_delta_flag) - num_delta_pocs[rps_idx]++; - } - } else { - unsigned int num_negative_pics = read_golomb_ue(gb); - unsigned int num_positive_pics = read_golomb_ue(gb); + /* + * From libavcodec/hevc_ps.c: + * + * if (is_slice_header) { + * //foo + * } else + * rps_ridx = &sps->st_rps[rps - sps->st_rps - 1]; + * + * where: + * rps: &sps->st_rps[rps_idx] + * sps->st_rps: &sps->st_rps[0] + * is_slice_header: rps_idx == num_rps + * + * thus: + * if (num_rps != rps_idx) + * rps_ridx = &sps->st_rps[rps_idx - 1]; + * + * NumDeltaPocs[RefRpsIdx]: num_delta_pocs[rps_idx - 1] + */ + for (i = 0; i <= num_delta_pocs[rps_idx - 1]; i++) { + uint8_t use_delta_flag = 0; + uint8_t used_by_curr_pic_flag = read_bits1(gb); + if (!used_by_curr_pic_flag) + use_delta_flag = read_bits1(gb); + + if (used_by_curr_pic_flag || use_delta_flag) + num_delta_pocs[rps_idx]++; + } + } else { + unsigned int num_negative_pics = read_golomb_ue(gb); + unsigned int num_positive_pics = read_golomb_ue(gb); - if ((num_positive_pics + (uint64_t)num_negative_pics) * 2 > remaining_bits(gb)) - return -1; + if ((num_positive_pics + (uint64_t)num_negative_pics) * 2 > remaining_bits(gb)) + return -1; - num_delta_pocs[rps_idx] = num_negative_pics + num_positive_pics; + num_delta_pocs[rps_idx] = num_negative_pics + num_positive_pics; - for (i = 0; i < num_negative_pics; i++) { - read_golomb_ue(gb); // delta_poc_s0_minus1[rps_idx] - skip_bits1 (gb); // used_by_curr_pic_s0_flag[rps_idx] - } + for (i = 0; i < num_negative_pics; i++) { + read_golomb_ue(gb); // delta_poc_s0_minus1[rps_idx] + skip_bits1(gb); // used_by_curr_pic_s0_flag[rps_idx] + } - for (i = 0; i < num_positive_pics; i++) { - read_golomb_ue(gb); // delta_poc_s1_minus1[rps_idx] - skip_bits1 (gb); // used_by_curr_pic_s1_flag[rps_idx] - } + for (i = 0; i < num_positive_pics; i++) { + read_golomb_ue(gb); // delta_poc_s1_minus1[rps_idx] + skip_bits1(gb); // used_by_curr_pic_s1_flag[rps_idx] } + } - return 0; + return 0; } -static int hvcc_parse_sps(bitstream_t *gb, - HEVCDecoderConfigurationRecord *hvcc) -{ - unsigned int i, sps_max_sub_layers, log2_max_pic_order_cnt_lsb_minus4; - unsigned int num_short_term_ref_pic_sets, num_delta_pocs[MAX_SHORT_TERM_RPS_COUNT]; +static int hvcc_parse_sps(bitstream_t* gb, HEVCDecoderConfigurationRecord* hvcc) { + unsigned int i, sps_max_sub_layers, log2_max_pic_order_cnt_lsb_minus4; + unsigned int num_short_term_ref_pic_sets, num_delta_pocs[MAX_SHORT_TERM_RPS_COUNT]; - skip_bits(gb, 4); // sps_video_parameter_set_id + skip_bits(gb, 4); // sps_video_parameter_set_id - sps_max_sub_layers = read_bits (gb, 3) + 1; + sps_max_sub_layers = read_bits(gb, 3) + 1; - /* - * numTemporalLayers greater than 1 indicates that the stream to which this - * configuration record applies is temporally scalable and the contained - * number of temporal layers (also referred to as temporal sub-layer or - * sub-layer in ISO/IEC 23008-2) is equal to numTemporalLayers. Value 1 - * indicates that the stream is not temporally scalable. Value 0 indicates - * that it is unknown whether the stream is temporally scalable. - */ - hvcc->numTemporalLayers = MAX(hvcc->numTemporalLayers, sps_max_sub_layers); + /* + * numTemporalLayers greater than 1 indicates that the stream to which this + * configuration record applies is temporally scalable and the contained + * number of temporal layers (also referred to as temporal sub-layer or + * sub-layer in ISO/IEC 23008-2) is equal to numTemporalLayers. Value 1 + * indicates that the stream is not temporally scalable. Value 0 indicates + * that it is unknown whether the stream is temporally scalable. + */ + hvcc->numTemporalLayers = MAX(hvcc->numTemporalLayers, sps_max_sub_layers); - hvcc->temporalIdNested = read_bits1(gb); + hvcc->temporalIdNested = read_bits1(gb); - hvcc_parse_ptl(gb, hvcc, sps_max_sub_layers); + hvcc_parse_ptl(gb, hvcc, sps_max_sub_layers); - read_golomb_ue(gb); // sps_seq_parameter_set_id + read_golomb_ue(gb); // sps_seq_parameter_set_id - hvcc->chromaFormat = read_golomb_ue(gb); + hvcc->chromaFormat = read_golomb_ue(gb); - if (hvcc->chromaFormat == 3) - skip_bits1(gb); // separate_colour_plane_flag + if (hvcc->chromaFormat == 3) + skip_bits1(gb); // separate_colour_plane_flag - read_golomb_ue(gb); // pic_width_in_luma_samples - read_golomb_ue(gb); // pic_height_in_luma_samples + read_golomb_ue(gb); // pic_width_in_luma_samples + read_golomb_ue(gb); // pic_height_in_luma_samples - if (read_bits1(gb)) { // conformance_window_flag - read_golomb_ue(gb); // conf_win_left_offset - read_golomb_ue(gb); // conf_win_right_offset - read_golomb_ue(gb); // conf_win_top_offset - read_golomb_ue(gb); // conf_win_bottom_offset - } + if (read_bits1(gb)) { // conformance_window_flag + read_golomb_ue(gb); // conf_win_left_offset + read_golomb_ue(gb); // conf_win_right_offset + read_golomb_ue(gb); // conf_win_top_offset + read_golomb_ue(gb); // conf_win_bottom_offset + } - hvcc->bitDepthLumaMinus8 = read_golomb_ue(gb); - hvcc->bitDepthChromaMinus8 = read_golomb_ue(gb); - log2_max_pic_order_cnt_lsb_minus4 = read_golomb_ue(gb); - - /* sps_sub_layer_ordering_info_present_flag */ - i = read_bits1(gb) ? 1 : sps_max_sub_layers; - for (; i < sps_max_sub_layers; i++) - skip_sub_layer_ordering_info(gb); - - read_golomb_ue(gb); // log2_min_luma_coding_block_size_minus3 - read_golomb_ue(gb); // log2_diff_max_min_luma_coding_block_size - read_golomb_ue(gb); // log2_min_transform_block_size_minus2 - read_golomb_ue(gb); // log2_diff_max_min_transform_block_size - read_golomb_ue(gb); // max_transform_hierarchy_depth_inter - read_golomb_ue(gb); // max_transform_hierarchy_depth_intra - - if (read_bits1(gb) && // scaling_list_enabled_flag - read_bits1(gb)) // sps_scaling_list_data_present_flag - skip_scaling_list_data(gb); - - skip_bits1(gb); // amp_enabled_flag - skip_bits1(gb); // sample_adaptive_offset_enabled_flag - - if (read_bits1(gb)) { // pcm_enabled_flag - skip_bits (gb, 4); // pcm_sample_bit_depth_luma_minus1 - skip_bits (gb, 4); // pcm_sample_bit_depth_chroma_minus1 - read_golomb_ue(gb); // log2_min_pcm_luma_coding_block_size_minus3 - read_golomb_ue(gb); // log2_diff_max_min_pcm_luma_coding_block_size - skip_bits1 (gb); // pcm_loop_filter_disabled_flag - } + hvcc->bitDepthLumaMinus8 = read_golomb_ue(gb); + hvcc->bitDepthChromaMinus8 = read_golomb_ue(gb); + log2_max_pic_order_cnt_lsb_minus4 = read_golomb_ue(gb); + + /* sps_sub_layer_ordering_info_present_flag */ + i = read_bits1(gb) ? 1 : sps_max_sub_layers; + for (; i < sps_max_sub_layers; i++) + skip_sub_layer_ordering_info(gb); + + read_golomb_ue(gb); // log2_min_luma_coding_block_size_minus3 + read_golomb_ue(gb); // log2_diff_max_min_luma_coding_block_size + read_golomb_ue(gb); // log2_min_transform_block_size_minus2 + read_golomb_ue(gb); // log2_diff_max_min_transform_block_size + read_golomb_ue(gb); // max_transform_hierarchy_depth_inter + read_golomb_ue(gb); // max_transform_hierarchy_depth_intra + + if (read_bits1(gb) && // scaling_list_enabled_flag + read_bits1(gb)) // sps_scaling_list_data_present_flag + skip_scaling_list_data(gb); + + skip_bits1(gb); // amp_enabled_flag + skip_bits1(gb); // sample_adaptive_offset_enabled_flag + + if (read_bits1(gb)) { // pcm_enabled_flag + skip_bits(gb, 4); // pcm_sample_bit_depth_luma_minus1 + skip_bits(gb, 4); // pcm_sample_bit_depth_chroma_minus1 + read_golomb_ue(gb); // log2_min_pcm_luma_coding_block_size_minus3 + read_golomb_ue(gb); // log2_diff_max_min_pcm_luma_coding_block_size + skip_bits1(gb); // pcm_loop_filter_disabled_flag + } - num_short_term_ref_pic_sets = read_golomb_ue(gb); - if (num_short_term_ref_pic_sets > MAX_SHORT_TERM_RPS_COUNT) - return -1; + num_short_term_ref_pic_sets = read_golomb_ue(gb); + if (num_short_term_ref_pic_sets > MAX_SHORT_TERM_RPS_COUNT) + return -1; - for (i = 0; i < num_short_term_ref_pic_sets; i++) { - int ret = parse_rps(gb, i, num_short_term_ref_pic_sets, num_delta_pocs); - if (ret < 0) - return ret; - } + for (i = 0; i < num_short_term_ref_pic_sets; i++) { + int ret = parse_rps(gb, i, num_short_term_ref_pic_sets, num_delta_pocs); + if (ret < 0) + return ret; + } - if (read_bits1(gb)) { // long_term_ref_pics_present_flag - unsigned num_long_term_ref_pics_sps = read_golomb_ue(gb); - if (num_long_term_ref_pics_sps > 31U) - return -1; - for (i = 0; i < num_long_term_ref_pics_sps; i++) { // num_long_term_ref_pics_sps - int len = MIN(log2_max_pic_order_cnt_lsb_minus4 + 4, 16); - skip_bits (gb, len); // lt_ref_pic_poc_lsb_sps[i] - skip_bits1(gb); // used_by_curr_pic_lt_sps_flag[i] - } + if (read_bits1(gb)) { // long_term_ref_pics_present_flag + unsigned num_long_term_ref_pics_sps = read_golomb_ue(gb); + if (num_long_term_ref_pics_sps > 31U) + return -1; + for (i = 0; i < num_long_term_ref_pics_sps; i++) { // num_long_term_ref_pics_sps + int len = MIN(log2_max_pic_order_cnt_lsb_minus4 + 4, 16); + skip_bits(gb, len); // lt_ref_pic_poc_lsb_sps[i] + skip_bits1(gb); // used_by_curr_pic_lt_sps_flag[i] } + } - skip_bits1(gb); // sps_temporal_mvp_enabled_flag - skip_bits1(gb); // strong_intra_smoothing_enabled_flag + skip_bits1(gb); // sps_temporal_mvp_enabled_flag + skip_bits1(gb); // strong_intra_smoothing_enabled_flag - if (read_bits1(gb)) // vui_parameters_present_flag - hvcc_parse_vui(gb, hvcc, sps_max_sub_layers); + if (read_bits1(gb)) // vui_parameters_present_flag + hvcc_parse_vui(gb, hvcc, sps_max_sub_layers); - /* nothing useful for hvcC past this point */ - return 0; + /* nothing useful for hvcC past this point */ + return 0; } -static int hvcc_parse_pps(bitstream_t *gb, - HEVCDecoderConfigurationRecord *hvcc) -{ - uint8_t tiles_enabled_flag, entropy_coding_sync_enabled_flag; - - read_golomb_ue(gb); // pps_pic_parameter_set_id - read_golomb_ue(gb); // pps_seq_parameter_set_id - - /* - * dependent_slice_segments_enabled_flag u(1) - * output_flag_present_flag u(1) - * num_extra_slice_header_bits u(3) - * sign_data_hiding_enabled_flag u(1) - * cabac_init_present_flag u(1) - */ - skip_bits(gb, 7); - - read_golomb_ue(gb); // num_ref_idx_l0_default_active_minus1 - read_golomb_ue(gb); // num_ref_idx_l1_default_active_minus1 - read_golomb_se(gb); // init_qp_minus26 - - /* - * constrained_intra_pred_flag u(1) - * transform_skip_enabled_flag u(1) - */ - skip_bits(gb, 2); +static int hvcc_parse_pps(bitstream_t* gb, HEVCDecoderConfigurationRecord* hvcc) { + uint8_t tiles_enabled_flag, entropy_coding_sync_enabled_flag; + + read_golomb_ue(gb); // pps_pic_parameter_set_id + read_golomb_ue(gb); // pps_seq_parameter_set_id + + /* + * dependent_slice_segments_enabled_flag u(1) + * output_flag_present_flag u(1) + * num_extra_slice_header_bits u(3) + * sign_data_hiding_enabled_flag u(1) + * cabac_init_present_flag u(1) + */ + skip_bits(gb, 7); + + read_golomb_ue(gb); // num_ref_idx_l0_default_active_minus1 + read_golomb_ue(gb); // num_ref_idx_l1_default_active_minus1 + read_golomb_se(gb); // init_qp_minus26 + + /* + * constrained_intra_pred_flag u(1) + * transform_skip_enabled_flag u(1) + */ + skip_bits(gb, 2); + + if (read_bits1(gb)) // cu_qp_delta_enabled_flag + read_golomb_ue(gb); // diff_cu_qp_delta_depth + + read_golomb_se(gb); // pps_cb_qp_offset + read_golomb_se(gb); // pps_cr_qp_offset + + /* + * pps_slice_chroma_qp_offsets_present_flag u(1) + * weighted_pred_flag u(1) + * weighted_bipred_flag u(1) + * transquant_bypass_enabled_flag u(1) + */ + skip_bits(gb, 4); + + tiles_enabled_flag = read_bits1(gb); + entropy_coding_sync_enabled_flag = read_bits1(gb); + + if (entropy_coding_sync_enabled_flag && tiles_enabled_flag) + hvcc->parallelismType = 0; // mixed-type parallel decoding + else if (entropy_coding_sync_enabled_flag) + hvcc->parallelismType = 3; // wavefront-based parallel decoding + else if (tiles_enabled_flag) + hvcc->parallelismType = 2; // tile-based parallel decoding + else + hvcc->parallelismType = 1; // slice-based parallel decoding - if (read_bits1(gb)) // cu_qp_delta_enabled_flag - read_golomb_ue(gb); // diff_cu_qp_delta_depth + /* nothing useful for hvcC past this point */ + return 0; +} - read_golomb_se(gb); // pps_cb_qp_offset - read_golomb_se(gb); // pps_cr_qp_offset +static uint8_t* nal_unit_extract_rbsp(const uint8_t* src, uint32_t src_len, uint32_t* dst_len) { + uint8_t* dst; + uint32_t i, len; - /* - * pps_slice_chroma_qp_offsets_present_flag u(1) - * weighted_pred_flag u(1) - * weighted_bipred_flag u(1) - * transquant_bypass_enabled_flag u(1) - */ - skip_bits(gb, 4); + dst = malloc(src_len); + if (!dst) + return NULL; - tiles_enabled_flag = read_bits1(gb); - entropy_coding_sync_enabled_flag = read_bits1(gb); + /* NAL unit header (2 bytes) */ + i = len = 0; + while (i < 2 && i < src_len) + dst[len++] = src[i++]; - if (entropy_coding_sync_enabled_flag && tiles_enabled_flag) - hvcc->parallelismType = 0; // mixed-type parallel decoding - else if (entropy_coding_sync_enabled_flag) - hvcc->parallelismType = 3; // wavefront-based parallel decoding - else if (tiles_enabled_flag) - hvcc->parallelismType = 2; // tile-based parallel decoding - else - hvcc->parallelismType = 1; // slice-based parallel decoding + while (i + 2 < src_len) + if (!src[i] && !src[i + 1] && src[i + 2] == 3) { + dst[len++] = src[i++]; + dst[len++] = src[i++]; + i++; // remove emulation_prevention_three_byte + } else + dst[len++] = src[i++]; - /* nothing useful for hvcC past this point */ - return 0; -} + while (i < src_len) + dst[len++] = src[i++]; -static uint8_t *nal_unit_extract_rbsp(const uint8_t *src, uint32_t src_len, - uint32_t *dst_len) -{ - uint8_t *dst; - uint32_t i, len; - - dst = malloc(src_len); - if (!dst) - return NULL; - - /* NAL unit header (2 bytes) */ - i = len = 0; - while (i < 2 && i < src_len) - dst[len++] = src[i++]; - - while (i + 2 < src_len) - if (!src[i] && !src[i + 1] && src[i + 2] == 3) { - dst[len++] = src[i++]; - dst[len++] = src[i++]; - i++; // remove emulation_prevention_three_byte - } else - dst[len++] = src[i++]; - - while (i < src_len) - dst[len++] = src[i++]; - - *dst_len = len; - return dst; + *dst_len = len; + return dst; } +static void nal_unit_parse_header(bitstream_t* gb, uint8_t* nal_type) { + skip_bits1(gb); // forbidden_zero_bit + *nal_type = read_bits(gb, 6); -static void nal_unit_parse_header(bitstream_t *gb, uint8_t *nal_type) -{ - skip_bits1(gb); // forbidden_zero_bit - - *nal_type = read_bits(gb, 6); - - /* - * nuh_layer_id u(6) - * nuh_temporal_id_plus1 u(3) - */ - skip_bits(gb, 9); + /* + * nuh_layer_id u(6) + * nuh_temporal_id_plus1 u(3) + */ + skip_bits(gb, 9); } -static int hvcc_array_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, - uint8_t nal_type, - HEVCDecoderConfigurationRecord *hvcc) -{ - uint8_t index; - uint16_t numNalus; - HVCCNALUnitArray *array; - void *n; +static int hvcc_array_add_nal_unit(uint8_t* nal_buf, + uint32_t nal_size, + uint8_t nal_type, + HEVCDecoderConfigurationRecord* hvcc) { + uint8_t index; + uint16_t numNalus; + HVCCNALUnitArray* array; + void* n; - for (index = 0; index < hvcc->numOfArrays; index++) - if (hvcc->array[index].NAL_unit_type == nal_type) - break; + for (index = 0; index < hvcc->numOfArrays; index++) + if (hvcc->array[index].NAL_unit_type == nal_type) + break; - if (index >= hvcc->numOfArrays) { - uint8_t i; + if (index >= hvcc->numOfArrays) { + uint8_t i; - n = realloc(hvcc->array, (index + 1) * sizeof(HVCCNALUnitArray)); - if (n == NULL) - return -1; - hvcc->array = n; + n = realloc(hvcc->array, (index + 1) * sizeof(HVCCNALUnitArray)); + if (n == NULL) + return -1; + hvcc->array = n; - for (i = hvcc->numOfArrays; i <= index; i++) - memset(&hvcc->array[i], 0, sizeof(HVCCNALUnitArray)); - hvcc->numOfArrays = index + 1; - } + for (i = hvcc->numOfArrays; i <= index; i++) + memset(&hvcc->array[i], 0, sizeof(HVCCNALUnitArray)); + hvcc->numOfArrays = index + 1; + } - array = &hvcc->array[index]; - numNalus = array->numNalus; + array = &hvcc->array[index]; + numNalus = array->numNalus; - n = realloc(array->nalUnit, (numNalus + 1) * sizeof(uint8_t*)); - if (n == NULL) - return -1; - array->nalUnit = n; + n = realloc(array->nalUnit, (numNalus + 1) * sizeof(uint8_t*)); + if (n == NULL) + return -1; + array->nalUnit = n; - n = realloc(array->nalUnitLength, (numNalus + 1) * sizeof(uint16_t)); - if (n == NULL) - return -1; - array->nalUnitLength = n; + n = realloc(array->nalUnitLength, (numNalus + 1) * sizeof(uint16_t)); + if (n == NULL) + return -1; + array->nalUnitLength = n; - array->nalUnit [numNalus] = nal_buf; - array->nalUnitLength[numNalus] = nal_size; - array->NAL_unit_type = nal_type; - array->numNalus++; + array->nalUnit[numNalus] = nal_buf; + array->nalUnitLength[numNalus] = nal_size; + array->NAL_unit_type = nal_type; + array->numNalus++; - return 0; + return 0; } -static int hvcc_add_nal_unit(uint8_t *nal_buf, uint32_t nal_size, - HEVCDecoderConfigurationRecord *hvcc) -{ - int ret = 0; - bitstream_t bs; - uint8_t nal_type; - uint8_t *rbsp_buf; - uint32_t rbsp_size; - - rbsp_buf = nal_unit_extract_rbsp(nal_buf, nal_size, &rbsp_size); - if (!rbsp_buf) { - ret = -1; - goto end; - } +static int +hvcc_add_nal_unit(uint8_t* nal_buf, uint32_t nal_size, HEVCDecoderConfigurationRecord* hvcc) { + int ret = 0; + bitstream_t bs; + uint8_t nal_type; + uint8_t* rbsp_buf; + uint32_t rbsp_size; + + rbsp_buf = nal_unit_extract_rbsp(nal_buf, nal_size, &rbsp_size); + if (!rbsp_buf) { + ret = -1; + goto end; + } - ret = init_rbits(&bs, rbsp_buf, rbsp_size); - if (ret < 0) - goto end; + ret = init_rbits(&bs, rbsp_buf, rbsp_size); + if (ret < 0) + goto end; - nal_unit_parse_header(&bs, &nal_type); + nal_unit_parse_header(&bs, &nal_type); - /* - * Note: only 'declarative' SEI messages are allowed in - * hvcC. Perhaps the SEI playload type should be checked - * and non-declarative SEI messages discarded? - */ - switch (nal_type) { + /* + * Note: only 'declarative' SEI messages are allowed in + * hvcC. Perhaps the SEI playload type should be checked + * and non-declarative SEI messages discarded? + */ + switch (nal_type) { case HEVC_NAL_VPS: case HEVC_NAL_SPS: case HEVC_NAL_PPS: case HEVC_NAL_SEI_PREFIX: case HEVC_NAL_SEI_SUFFIX: - ret = hvcc_array_add_nal_unit(nal_buf, nal_size, nal_type, hvcc); - if (ret < 0) - goto end; - else if (nal_type == HEVC_NAL_VPS) - ret = hvcc_parse_vps(&bs, hvcc); - else if (nal_type == HEVC_NAL_SPS) - ret = hvcc_parse_sps(&bs, hvcc); - else if (nal_type == HEVC_NAL_PPS) - ret = hvcc_parse_pps(&bs, hvcc); - if (ret < 0) - goto end; - break; - default: - ret = -1; + ret = hvcc_array_add_nal_unit(nal_buf, nal_size, nal_type, hvcc); + if (ret < 0) goto end; - } + else if (nal_type == HEVC_NAL_VPS) + ret = hvcc_parse_vps(&bs, hvcc); + else if (nal_type == HEVC_NAL_SPS) + ret = hvcc_parse_sps(&bs, hvcc); + else if (nal_type == HEVC_NAL_PPS) + ret = hvcc_parse_pps(&bs, hvcc); + if (ret < 0) + goto end; + break; + default: + ret = -1; + goto end; + } end: - free(rbsp_buf); - return ret; + free(rbsp_buf); + return ret; } -static void hvcc_init(HEVCDecoderConfigurationRecord *hvcc) -{ - memset(hvcc, 0, sizeof(HEVCDecoderConfigurationRecord)); - hvcc->configurationVersion = 1; - hvcc->lengthSizeMinusOne = 3; // 4 bytes - - /* - * The following fields have all their valid bits set by default, - * the ProfileTierLevel parsing code will unset them when needed. - */ - hvcc->general_profile_compatibility_flags = 0xffffffff; - hvcc->general_constraint_indicator_flags = 0xffffffffffffLL; - - /* - * Initialize this field with an invalid value which can be used to detect - * whether we didn't see any VUI (in which case it should be reset to zero). - */ - hvcc->min_spatial_segmentation_idc = MAX_SPATIAL_SEGMENTATION + 1; +static void hvcc_init(HEVCDecoderConfigurationRecord* hvcc) { + memset(hvcc, 0, sizeof(HEVCDecoderConfigurationRecord)); + hvcc->configurationVersion = 1; + hvcc->lengthSizeMinusOne = 3; // 4 bytes + + /* + * The following fields have all their valid bits set by default, + * the ProfileTierLevel parsing code will unset them when needed. + */ + hvcc->general_profile_compatibility_flags = 0xffffffff; + hvcc->general_constraint_indicator_flags = 0xffffffffffffLL; + + /* + * Initialize this field with an invalid value which can be used to detect + * whether we didn't see any VUI (in which case it should be reset to zero). + */ + hvcc->min_spatial_segmentation_idc = MAX_SPATIAL_SEGMENTATION + 1; } -static void hvcc_close(HEVCDecoderConfigurationRecord *hvcc) -{ - uint8_t i; +static void hvcc_close(HEVCDecoderConfigurationRecord* hvcc) { + uint8_t i; - for (i = 0; i < hvcc->numOfArrays; i++) { - hvcc->array[i].numNalus = 0; - free(hvcc->array[i].nalUnit); - hvcc->array[i].nalUnit = NULL; - free(hvcc->array[i].nalUnitLength); - hvcc->array[i].nalUnitLength = NULL; - } + for (i = 0; i < hvcc->numOfArrays; i++) { + hvcc->array[i].numNalus = 0; + free(hvcc->array[i].nalUnit); + hvcc->array[i].nalUnit = NULL; + free(hvcc->array[i].nalUnitLength); + hvcc->array[i].nalUnitLength = NULL; + } - hvcc->numOfArrays = 0; - free(hvcc->array); - hvcc->array = NULL; + hvcc->numOfArrays = 0; + free(hvcc->array); + hvcc->array = NULL; } -static int hvcc_write(sbuf_t *pb, HEVCDecoderConfigurationRecord *hvcc) -{ - uint8_t i; - uint16_t j, vps_count = 0, sps_count = 0, pps_count = 0; - - /* - * We only support writing HEVCDecoderConfigurationRecord version 1. - */ - hvcc->configurationVersion = 1; - - /* - * If min_spatial_segmentation_idc is invalid, reset to 0 (unspecified). - */ - if (hvcc->min_spatial_segmentation_idc > MAX_SPATIAL_SEGMENTATION) - hvcc->min_spatial_segmentation_idc = 0; - - /* - * parallelismType indicates the type of parallelism that is used to meet - * the restrictions imposed by min_spatial_segmentation_idc when the value - * of min_spatial_segmentation_idc is greater than 0. - */ - if (!hvcc->min_spatial_segmentation_idc) - hvcc->parallelismType = 0; +static int hvcc_write(sbuf_t* pb, HEVCDecoderConfigurationRecord* hvcc) { + uint8_t i; + uint16_t j, vps_count = 0, sps_count = 0, pps_count = 0; + + /* + * We only support writing HEVCDecoderConfigurationRecord version 1. + */ + hvcc->configurationVersion = 1; + + /* + * If min_spatial_segmentation_idc is invalid, reset to 0 (unspecified). + */ + if (hvcc->min_spatial_segmentation_idc > MAX_SPATIAL_SEGMENTATION) + hvcc->min_spatial_segmentation_idc = 0; + + /* + * parallelismType indicates the type of parallelism that is used to meet + * the restrictions imposed by min_spatial_segmentation_idc when the value + * of min_spatial_segmentation_idc is greater than 0. + */ + if (!hvcc->min_spatial_segmentation_idc) + hvcc->parallelismType = 0; + + /* + * It's unclear how to properly compute these fields, so + * let's always set them to values meaning 'unspecified'. + */ + hvcc->avgFrameRate = 0; + hvcc->constantFrameRate = 0; + + tvhtrace(LS_HEVC, "configurationVersion: %" PRIu8, hvcc->configurationVersion); + tvhtrace(LS_HEVC, "general_profile_space: %" PRIu8, hvcc->general_profile_space); + tvhtrace(LS_HEVC, "general_tier_flag: %" PRIu8, hvcc->general_tier_flag); + tvhtrace(LS_HEVC, "general_profile_idc: %" PRIu8, hvcc->general_profile_idc); + tvhtrace(LS_HEVC, + "general_profile_compatibility_flags: 0x%08" PRIx32, + hvcc->general_profile_compatibility_flags); + tvhtrace(LS_HEVC, + "general_constraint_indicator_flags: 0x%012" PRIx64, + hvcc->general_constraint_indicator_flags); + tvhtrace(LS_HEVC, "general_level_idc: %" PRIu8, hvcc->general_level_idc); + tvhtrace(LS_HEVC, + "min_spatial_segmentation_idc: %" PRIu16, + hvcc->min_spatial_segmentation_idc); + tvhtrace(LS_HEVC, "parallelismType: %" PRIu8, hvcc->parallelismType); + tvhtrace(LS_HEVC, "chromaFormat: %" PRIu8, hvcc->chromaFormat); + tvhtrace(LS_HEVC, "bitDepthLumaMinus8: %" PRIu8, hvcc->bitDepthLumaMinus8); + tvhtrace(LS_HEVC, "bitDepthChromaMinus8: %" PRIu8, hvcc->bitDepthChromaMinus8); + tvhtrace(LS_HEVC, "avgFrameRate: %" PRIu16, hvcc->avgFrameRate); + tvhtrace(LS_HEVC, "constantFrameRate: %" PRIu8, hvcc->constantFrameRate); + tvhtrace(LS_HEVC, "numTemporalLayers: %" PRIu8, hvcc->numTemporalLayers); + tvhtrace(LS_HEVC, "temporalIdNested: %" PRIu8, hvcc->temporalIdNested); + tvhtrace(LS_HEVC, "lengthSizeMinusOne: %" PRIu8, hvcc->lengthSizeMinusOne); + tvhtrace(LS_HEVC, "numOfArrays: %" PRIu8, hvcc->numOfArrays); + for (i = 0; i < hvcc->numOfArrays; i++) { + tvhtrace(LS_HEVC, + "NAL_unit_type[%" PRIu8 "]: %" PRIu8, + i, + hvcc->array[i].NAL_unit_type); + tvhtrace(LS_HEVC, + "numNalus[%" PRIu8 "]: %" PRIu16, + i, + hvcc->array[i].numNalus); + for (j = 0; j < hvcc->array[i].numNalus; j++) + tvhtrace(LS_HEVC, + "nalUnitLength[%" PRIu8 "][%" PRIu16 "]: %" PRIu16, + i, + j, + hvcc->array[i].nalUnitLength[j]); + } - /* - * It's unclear how to properly compute these fields, so - * let's always set them to values meaning 'unspecified'. - */ - hvcc->avgFrameRate = 0; - hvcc->constantFrameRate = 0; - - tvhtrace(LS_HEVC, "configurationVersion: %"PRIu8, - hvcc->configurationVersion); - tvhtrace(LS_HEVC, "general_profile_space: %"PRIu8, - hvcc->general_profile_space); - tvhtrace(LS_HEVC, "general_tier_flag: %"PRIu8, - hvcc->general_tier_flag); - tvhtrace(LS_HEVC, "general_profile_idc: %"PRIu8, - hvcc->general_profile_idc); - tvhtrace(LS_HEVC, "general_profile_compatibility_flags: 0x%08"PRIx32, - hvcc->general_profile_compatibility_flags); - tvhtrace(LS_HEVC, "general_constraint_indicator_flags: 0x%012"PRIx64, - hvcc->general_constraint_indicator_flags); - tvhtrace(LS_HEVC, "general_level_idc: %"PRIu8, - hvcc->general_level_idc); - tvhtrace(LS_HEVC, "min_spatial_segmentation_idc: %"PRIu16, - hvcc->min_spatial_segmentation_idc); - tvhtrace(LS_HEVC, "parallelismType: %"PRIu8, - hvcc->parallelismType); - tvhtrace(LS_HEVC, "chromaFormat: %"PRIu8, - hvcc->chromaFormat); - tvhtrace(LS_HEVC, "bitDepthLumaMinus8: %"PRIu8, - hvcc->bitDepthLumaMinus8); - tvhtrace(LS_HEVC, "bitDepthChromaMinus8: %"PRIu8, - hvcc->bitDepthChromaMinus8); - tvhtrace(LS_HEVC, "avgFrameRate: %"PRIu16, - hvcc->avgFrameRate); - tvhtrace(LS_HEVC, "constantFrameRate: %"PRIu8, - hvcc->constantFrameRate); - tvhtrace(LS_HEVC, "numTemporalLayers: %"PRIu8, - hvcc->numTemporalLayers); - tvhtrace(LS_HEVC, "temporalIdNested: %"PRIu8, - hvcc->temporalIdNested); - tvhtrace(LS_HEVC, "lengthSizeMinusOne: %"PRIu8, - hvcc->lengthSizeMinusOne); - tvhtrace(LS_HEVC, "numOfArrays: %"PRIu8, - hvcc->numOfArrays); - for (i = 0; i < hvcc->numOfArrays; i++) { - tvhtrace(LS_HEVC, "NAL_unit_type[%"PRIu8"]: %"PRIu8, - i, hvcc->array[i].NAL_unit_type); - tvhtrace(LS_HEVC, "numNalus[%"PRIu8"]: %"PRIu16, - i, hvcc->array[i].numNalus); - for (j = 0; j < hvcc->array[i].numNalus; j++) - tvhtrace(LS_HEVC, - "nalUnitLength[%"PRIu8"][%"PRIu16"]: %"PRIu16, - i, j, hvcc->array[i].nalUnitLength[j]); + /* + * We need at least one of each: VPS, SPS and PPS. + */ + for (i = 0; i < hvcc->numOfArrays; i++) + switch (hvcc->array[i].NAL_unit_type) { + case HEVC_NAL_VPS: + vps_count += hvcc->array[i].numNalus; + break; + case HEVC_NAL_SPS: + sps_count += hvcc->array[i].numNalus; + break; + case HEVC_NAL_PPS: + pps_count += hvcc->array[i].numNalus; + break; + default: + break; } + if (!vps_count || vps_count > MAX_VPS_COUNT || !sps_count || sps_count > MAX_SPS_COUNT || + !pps_count || pps_count > MAX_PPS_COUNT) + return -1; + /* unsigned int(8) configurationVersion = 1; */ + sbuf_put_byte(pb, hvcc->configurationVersion); + + /* + * unsigned int(2) general_profile_space; + * unsigned int(1) general_tier_flag; + * unsigned int(5) general_profile_idc; + */ + sbuf_put_byte(pb, + hvcc->general_profile_space << 6 | hvcc->general_tier_flag << 5 | hvcc->general_profile_idc); + + /* unsigned int(32) general_profile_compatibility_flags; */ + sbuf_put_be32(pb, hvcc->general_profile_compatibility_flags); + + /* unsigned int(48) general_constraint_indicator_flags; */ + sbuf_put_be32(pb, hvcc->general_constraint_indicator_flags >> 16); + sbuf_put_be16(pb, hvcc->general_constraint_indicator_flags); + + /* unsigned int(8) general_level_idc; */ + sbuf_put_byte(pb, hvcc->general_level_idc); + + /* + * bit(4) reserved = ‘1111’b; + * unsigned int(12) min_spatial_segmentation_idc; + */ + sbuf_put_be16(pb, hvcc->min_spatial_segmentation_idc | 0xf000); + + /* + * bit(6) reserved = ‘111111’b; + * unsigned int(2) parallelismType; + */ + sbuf_put_byte(pb, hvcc->parallelismType | 0xfc); + + /* + * bit(6) reserved = ‘111111’b; + * unsigned int(2) chromaFormat; + */ + sbuf_put_byte(pb, hvcc->chromaFormat | 0xfc); + + /* + * bit(5) reserved = ‘11111’b; + * unsigned int(3) bitDepthLumaMinus8; + */ + sbuf_put_byte(pb, hvcc->bitDepthLumaMinus8 | 0xf8); + + /* + * bit(5) reserved = ‘11111’b; + * unsigned int(3) bitDepthChromaMinus8; + */ + sbuf_put_byte(pb, hvcc->bitDepthChromaMinus8 | 0xf8); + + /* bit(16) avgFrameRate; */ + sbuf_put_be16(pb, hvcc->avgFrameRate); + + /* + * bit(2) constantFrameRate; + * bit(3) numTemporalLayers; + * bit(1) temporalIdNested; + * unsigned int(2) lengthSizeMinusOne; + */ + sbuf_put_byte(pb, + hvcc->constantFrameRate << 6 | hvcc->numTemporalLayers << 3 | hvcc->temporalIdNested << 2 | + hvcc->lengthSizeMinusOne); + + /* unsigned int(8) numOfArrays; */ + sbuf_put_byte(pb, hvcc->numOfArrays); + + for (i = 0; i < hvcc->numOfArrays; i++) { /* - * We need at least one of each: VPS, SPS and PPS. - */ - for (i = 0; i < hvcc->numOfArrays; i++) - switch (hvcc->array[i].NAL_unit_type) { - case HEVC_NAL_VPS: - vps_count += hvcc->array[i].numNalus; - break; - case HEVC_NAL_SPS: - sps_count += hvcc->array[i].numNalus; - break; - case HEVC_NAL_PPS: - pps_count += hvcc->array[i].numNalus; - break; - default: - break; - } - if (!vps_count || vps_count > MAX_VPS_COUNT || - !sps_count || sps_count > MAX_SPS_COUNT || - !pps_count || pps_count > MAX_PPS_COUNT) - return -1; - - /* unsigned int(8) configurationVersion = 1; */ - sbuf_put_byte(pb, hvcc->configurationVersion); - - /* - * unsigned int(2) general_profile_space; - * unsigned int(1) general_tier_flag; - * unsigned int(5) general_profile_idc; - */ - sbuf_put_byte(pb, hvcc->general_profile_space << 6 | - hvcc->general_tier_flag << 5 | - hvcc->general_profile_idc); - - /* unsigned int(32) general_profile_compatibility_flags; */ - sbuf_put_be32(pb, hvcc->general_profile_compatibility_flags); - - /* unsigned int(48) general_constraint_indicator_flags; */ - sbuf_put_be32(pb, hvcc->general_constraint_indicator_flags >> 16); - sbuf_put_be16(pb, hvcc->general_constraint_indicator_flags); - - /* unsigned int(8) general_level_idc; */ - sbuf_put_byte(pb, hvcc->general_level_idc); - - /* - * bit(4) reserved = ‘1111’b; - * unsigned int(12) min_spatial_segmentation_idc; - */ - sbuf_put_be16(pb, hvcc->min_spatial_segmentation_idc | 0xf000); - - /* - * bit(6) reserved = ‘111111’b; - * unsigned int(2) parallelismType; - */ - sbuf_put_byte(pb, hvcc->parallelismType | 0xfc); - - /* - * bit(6) reserved = ‘111111’b; - * unsigned int(2) chromaFormat; - */ - sbuf_put_byte(pb, hvcc->chromaFormat | 0xfc); - - /* - * bit(5) reserved = ‘11111’b; - * unsigned int(3) bitDepthLumaMinus8; - */ - sbuf_put_byte(pb, hvcc->bitDepthLumaMinus8 | 0xf8); - - /* - * bit(5) reserved = ‘11111’b; - * unsigned int(3) bitDepthChromaMinus8; + * bit(1) array_completeness; + * unsigned int(1) reserved = 0; + * unsigned int(6) NAL_unit_type; */ - sbuf_put_byte(pb, hvcc->bitDepthChromaMinus8 | 0xf8); + sbuf_put_byte(pb, (0 << 7) | (hvcc->array[i].NAL_unit_type & 0x3f)); - /* bit(16) avgFrameRate; */ - sbuf_put_be16(pb, hvcc->avgFrameRate); + /* unsigned int(16) numNalus; */ + sbuf_put_be16(pb, hvcc->array[i].numNalus); - /* - * bit(2) constantFrameRate; - * bit(3) numTemporalLayers; - * bit(1) temporalIdNested; - * unsigned int(2) lengthSizeMinusOne; - */ - sbuf_put_byte(pb, hvcc->constantFrameRate << 6 | - hvcc->numTemporalLayers << 3 | - hvcc->temporalIdNested << 2 | - hvcc->lengthSizeMinusOne); - - /* unsigned int(8) numOfArrays; */ - sbuf_put_byte(pb, hvcc->numOfArrays); + for (j = 0; j < hvcc->array[i].numNalus; j++) { + /* unsigned int(16) nalUnitLength; */ + sbuf_put_be16(pb, hvcc->array[i].nalUnitLength[j]); - for (i = 0; i < hvcc->numOfArrays; i++) { - /* - * bit(1) array_completeness; - * unsigned int(1) reserved = 0; - * unsigned int(6) NAL_unit_type; - */ - sbuf_put_byte(pb, (0 << 7) | - (hvcc->array[i].NAL_unit_type & 0x3f)); - - /* unsigned int(16) numNalus; */ - sbuf_put_be16(pb, hvcc->array[i].numNalus); - - for (j = 0; j < hvcc->array[i].numNalus; j++) { - /* unsigned int(16) nalUnitLength; */ - sbuf_put_be16(pb, hvcc->array[i].nalUnitLength[j]); - - /* bit(8*nalUnitLength) nalUnit; */ - sbuf_append(pb, hvcc->array[i].nalUnit[j], - hvcc->array[i].nalUnitLength[j]); - } + /* bit(8*nalUnitLength) nalUnit; */ + sbuf_append(pb, hvcc->array[i].nalUnit[j], hvcc->array[i].nalUnitLength[j]); } + } - return 0; + return 0; } #if 0 @@ -1125,76 +1087,72 @@ int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out, } #endif -int isom_write_hvcc(sbuf_t *pb, const uint8_t *data, int size) -{ - int ret = 0; - sbuf_t sb; - uint8_t *buf, *end; - HEVCDecoderConfigurationRecord hvcc; - - sbuf_init(&sb); - hvcc_init(&hvcc); - - if (size < 6) { - /* We can't write a valid hvcC from the provided data */ - ret = -1; - goto end; - } else if (*data == 1) { - /* Data is already hvcC-formatted */ - sbuf_append(pb, data, size); - goto end; - } else if (!(RB24(data) == 1 || RB32(data) == 1)) { - /* Not a valid Annex B start code prefix */ - ret = -1; - goto end; - } +int isom_write_hvcc(sbuf_t* pb, const uint8_t* data, int size) { + int ret = 0; + sbuf_t sb; + uint8_t * buf, *end; + HEVCDecoderConfigurationRecord hvcc; + + sbuf_init(&sb); + hvcc_init(&hvcc); + + if (size < 6) { + /* We can't write a valid hvcC from the provided data */ + ret = -1; + goto end; + } else if (*data == 1) { + /* Data is already hvcC-formatted */ + sbuf_append(pb, data, size); + goto end; + } else if (!(RB24(data) == 1 || RB32(data) == 1)) { + /* Not a valid Annex B start code prefix */ + ret = -1; + goto end; + } - size = avc_parse_nal_units(&sb, data, size); + size = avc_parse_nal_units(&sb, data, size); - buf = sb.sb_data; - end = buf + size; + buf = sb.sb_data; + end = buf + size; - while (end - buf > 4) { - uint32_t len = MIN(RB32(buf), end - buf - 4); - uint8_t type = (buf[4] >> 1) & 0x3f; + while (end - buf > 4) { + uint32_t len = MIN(RB32(buf), end - buf - 4); + uint8_t type = (buf[4] >> 1) & 0x3f; - buf += 4; + buf += 4; - switch (type) { - case HEVC_NAL_VPS: - case HEVC_NAL_SPS: - case HEVC_NAL_PPS: - case HEVC_NAL_SEI_PREFIX: - case HEVC_NAL_SEI_SUFFIX: - ret = hvcc_add_nal_unit(buf, len, &hvcc); - if (ret < 0) - goto end; - break; - default: - break; - } - - buf += len; + switch (type) { + case HEVC_NAL_VPS: + case HEVC_NAL_SPS: + case HEVC_NAL_PPS: + case HEVC_NAL_SEI_PREFIX: + case HEVC_NAL_SEI_SUFFIX: + ret = hvcc_add_nal_unit(buf, len, &hvcc); + if (ret < 0) + goto end; + break; + default: + break; } - ret = hvcc_write(pb, &hvcc); + buf += len; + } + + ret = hvcc_write(pb, &hvcc); end: - hvcc_close(&hvcc); - sbuf_free(&sb); - return ret; + hvcc_close(&hvcc); + sbuf_free(&sb); + return ret; } -th_pkt_t * -hevc_convert_pkt(th_pkt_t *src) -{ - sbuf_t payload; - th_pkt_t *pkt = pkt_copy_nodata(src); +th_pkt_t* hevc_convert_pkt(th_pkt_t* src) { + sbuf_t payload; + th_pkt_t* pkt = pkt_copy_nodata(src); sbuf_init(&payload); - avc_parse_nal_units(&payload, pktbuf_ptr(src->pkt_payload), - pktbuf_len(src->pkt_payload)); + avc_parse_nal_units(&payload, pktbuf_ptr(src->pkt_payload), pktbuf_len(src->pkt_payload)); pkt->pkt_payload = pktbuf_make(payload.sb_data, payload.sb_ptr); return pkt; @@ -1205,7 +1163,7 @@ hevc_convert_pkt(th_pkt_t *src) */ typedef struct hevc_vps { - uint8_t valid: 1; + uint8_t valid : 1; uint32_t num_units_in_tick; uint32_t time_scale; } hevc_vps_t; @@ -1220,18 +1178,18 @@ typedef struct hevc_vui { } hevc_vui_t; typedef struct hevc_sps { - uint8_t valid: 1; - uint8_t vps_id; - uint32_t width; - uint32_t height; - uint32_t ctb_width; - uint32_t ctb_height; + uint8_t valid : 1; + uint8_t vps_id; + uint32_t width; + uint32_t height; + uint32_t ctb_width; + uint32_t ctb_height; hevc_vui_t vui; } hevc_sps_t; typedef struct hevc_pps { - uint8_t valid: 1; - uint8_t dependent_slice_segments: 1; + uint8_t valid : 1; + uint8_t dependent_slice_segments : 1; uint8_t sps_id; uint8_t num_extra_slice_header_bits; } hevc_pps_t; @@ -1245,27 +1203,26 @@ typedef struct hevc_private { } hevc_private_t; static const uint8_t vui_sar[][2] = { - { 0, 1 }, - { 1, 1 }, - { 12, 11 }, - { 10, 11 }, - { 16, 11 }, - { 40, 33 }, - { 24, 11 }, - { 20, 11 }, - { 32, 11 }, - { 80, 33 }, - { 18, 11 }, - { 15, 11 }, - { 64, 33 }, - { 160, 99 }, - { 4, 3 }, - { 3, 2 }, - { 2, 1 }, + {0, 1}, + {1, 1}, + {12, 11}, + {10, 11}, + {16, 11}, + {40, 33}, + {24, 11}, + {20, 11}, + {32, 11}, + {80, 33}, + {18, 11}, + {15, 11}, + {64, 33}, + {160, 99}, + {4, 3}, + {3, 2}, + {2, 1}, }; -static uint_fast32_t ilog2(uint32_t v) -{ +static uint_fast32_t ilog2(uint32_t v) { uint_fast32_t r = 0; while (v) { v >>= 1; @@ -1274,33 +1231,29 @@ static uint_fast32_t ilog2(uint32_t v) return r; } -static inline int check_width(uint32_t w) -{ +static inline int check_width(uint32_t w) { return w < 100 || w > 16384; } -static inline int check_height(uint32_t h) -{ +static inline int check_height(uint32_t h) { return h < 100 || h > 16384; } -int -hevc_decode_vps(parser_es_t *st, bitstream_t *bs) -{ - hevc_private_t *p; - hevc_vps_t *vps; - uint32_t vps_id, max_sub_layers; - uint32_t sub_layer_ordering_info_present; - uint32_t max_layer_id, num_layer_sets; - uint32_t u, v; +int hevc_decode_vps(parser_es_t* st, bitstream_t* bs) { + hevc_private_t* p; + hevc_vps_t* vps; + uint32_t vps_id, max_sub_layers; + uint32_t sub_layer_ordering_info_present; + uint32_t max_layer_id, num_layer_sets; + uint32_t u, v; if (read_bits1(bs)) /* zero bit */ return -1; - if((p = st->es_priv) == NULL) + if ((p = st->es_priv) == NULL) p = st->es_priv = calloc(1, sizeof(hevc_private_t)); - skip_bits(bs, 15); /* NAL type, Layer ID, Temporal ID */ + skip_bits(bs, 15); /* NAL type, Layer ID, Temporal ID */ vps_id = read_bits(bs, 4); if (vps_id >= MAX_VPS_COUNT) @@ -1312,7 +1265,7 @@ hevc_decode_vps(parser_es_t *st, bitstream_t *bs) skip_bits(bs, 6); /* vps_max_sublayers */ max_sub_layers = read_bits(bs, 3) + 1; - skip_bits1(bs); /* vps_temporal_id_nesting */ + skip_bits1(bs); /* vps_temporal_id_nesting */ if (read_bits(bs, 16) != 0xffff) /* reserved */ return -1; @@ -1323,8 +1276,8 @@ hevc_decode_vps(parser_es_t *st, bitstream_t *bs) hvcc_parse_ptl(bs, NULL, max_sub_layers); sub_layer_ordering_info_present = read_bits1(bs); - u = sub_layer_ordering_info_present ? 0 : max_sub_layers - 1; - for ( ; u < max_sub_layers; u++) { + u = sub_layer_ordering_info_present ? 0 : max_sub_layers - 1; + for (; u < max_sub_layers; u++) { read_golomb_ue(bs); /* vps_max_dec_pic_buffering */ read_golomb_ue(bs); /* vps_num_reorder_pics */ read_golomb_ue(bs); /* vps_max_latency_increase */ @@ -1338,7 +1291,7 @@ hevc_decode_vps(parser_es_t *st, bitstream_t *bs) for (u = 1; u < num_layer_sets; u++) for (v = 0; v < max_layer_id; v++) - skip_bits1(bs); /* layer_id_included */ + skip_bits1(bs); /* layer_id_included */ vps->valid = 1; @@ -1349,10 +1302,8 @@ hevc_decode_vps(parser_es_t *st, bitstream_t *bs) return 0; } -static int -hevc_decode_vui(hevc_vui_t *vui, bitstream_t *bs) -{ - uint32_t u, sar_num, sar_den; +static int hevc_decode_vui(hevc_vui_t* vui, bitstream_t* bs) { + uint32_t u, sar_num, sar_den; bitstream_t backup; sar_num = 1; @@ -1374,13 +1325,13 @@ hevc_decode_vui(hevc_vui_t *vui, bitstream_t *bs) if (read_bits1(bs)) /* overscan_info_present */ skip_bits1(bs); /* overscan_appropriate */ - if (read_bits1(bs)) { /* video_signal_type_present */ - skip_bits(bs, 3); /* video_format */ - skip_bits1(bs); /* video_full_range */ + if (read_bits1(bs)) { /* video_signal_type_present */ + skip_bits(bs, 3); /* video_format */ + skip_bits1(bs); /* video_full_range */ if (read_bits1(bs)) { /* colour_description_present */ - skip_bits(bs, 8); /* colour_primaries */ - skip_bits(bs, 8); /* transfer_characteristic */ - skip_bits(bs, 8); /* matrix_coeffs */ + skip_bits(bs, 8); /* colour_primaries */ + skip_bits(bs, 8); /* transfer_characteristic */ + skip_bits(bs, 8); /* matrix_coeffs */ } } @@ -1399,7 +1350,7 @@ hevc_decode_vui(hevc_vui_t *vui, bitstream_t *bs) u = read_bits1(bs); /* default_display_window */ /* Backup context in case an alternate header is detected */ memcpy(&backup, bs, sizeof(backup)); - if (u) { /* default_display_window */ + if (u) { /* default_display_window */ read_golomb_ue(bs); /* left_offset */ read_golomb_ue(bs); /* right_offset */ read_golomb_ue(bs); /* top_offset */ @@ -1418,28 +1369,26 @@ hevc_decode_vui(hevc_vui_t *vui, bitstream_t *bs) return 0; } -int -hevc_decode_sps(parser_es_t *st, bitstream_t *bs) -{ - hevc_private_t *p; - hevc_vps_t *vps; - hevc_sps_t *sps; - uint32_t vps_id, sps_id, max_sub_layers, u, v, i; - uint32_t width, height; - uint32_t chroma_format_idc, bit_depth, bit_depth_chroma; - uint32_t log2_max_poc_lsb; - uint32_t log2_min_cb_size, log2_min_tb_size; - uint32_t log2_diff_max_min_coding_block_size; - uint32_t log2_diff_max_min_transform_block_size; - uint32_t log2_ctb_size, nb_st_rps; +int hevc_decode_sps(parser_es_t* st, bitstream_t* bs) { + hevc_private_t* p; + hevc_vps_t* vps; + hevc_sps_t* sps; + uint32_t vps_id, sps_id, max_sub_layers, u, v, i; + uint32_t width, height; + uint32_t chroma_format_idc, bit_depth, bit_depth_chroma; + uint32_t log2_max_poc_lsb; + uint32_t log2_min_cb_size, log2_min_tb_size; + uint32_t log2_diff_max_min_coding_block_size; + uint32_t log2_diff_max_min_transform_block_size; + uint32_t log2_ctb_size, nb_st_rps; if (read_bits1(bs)) /* zero bit */ return -1; - if((p = st->es_priv) == NULL) + if ((p = st->es_priv) == NULL) p = st->es_priv = calloc(1, sizeof(hevc_private_t)); - skip_bits(bs, 15); /* NAL type, Layer ID, Temporal ID */ + skip_bits(bs, 15); /* NAL type, Layer ID, Temporal ID */ vps_id = read_bits(bs, 4); if (vps_id >= MAX_VPS_COUNT) @@ -1451,7 +1400,7 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) max_sub_layers = read_bits(bs, 3) + 1; if (max_sub_layers > MAX_SUB_LAYERS) return -1; - skip_bits1(bs); /* temporal_id_nesting */ + skip_bits1(bs); /* temporal_id_nesting */ hvcc_parse_ptl(bs, NULL, max_sub_layers); @@ -1462,7 +1411,7 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) chroma_format_idc = read_golomb_ue(bs); if (chroma_format_idc == 3) - if (read_bits1(bs)) /* separate_colour_plane */ + if (read_bits1(bs)) /* separate_colour_plane */ chroma_format_idc = 0; width = read_golomb_ue(bs); height = read_golomb_ue(bs); @@ -1485,7 +1434,7 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) if (log2_max_poc_lsb > 16) return -1; - u = read_bits1(bs); /* sublayer_ordering_info */ + u = read_bits1(bs); /* sublayer_ordering_info */ for (u = u ? 0 : max_sub_layers - 1; u < max_sub_layers; u++) { read_golomb_ue(bs); /* max_dec_pic_buffering */ read_golomb_ue(bs); /* num_reorder_pics */ @@ -1508,12 +1457,12 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) read_golomb_ue(bs); /* max_transform_hierarchy_depth_inter */ read_golomb_ue(bs); /* max_transform_hierarchy_depth_intra */ - if (read_bits1(bs)) { /* scaling_list_enable_flag */ + if (read_bits1(bs)) { /* scaling_list_enable_flag */ if (read_bits1(bs)) { /* scaling_list_data */ for (u = 0; u < 4; u++) { for (v = 0; v < 6; v += ((u == 3) ? 3 : 1)) { if (!read_bits1(bs)) { /* scaling_list_pred_mode */ - read_golomb_ue(bs); /* delta */ + read_golomb_ue(bs); /* delta */ } else { if (u > 1) read_golomb_se(bs); /* scaling_list_dc_coef */ @@ -1543,25 +1492,25 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) for (u = 0; u < nb_st_rps; u++) { if (u > 0 && read_bits1(bs)) { /* rps_predict */ - skip_bits1(bs); /* delta_rps_sign */ - read_golomb_ue(bs); /* abs_delta_rps */ + skip_bits1(bs); /* delta_rps_sign */ + read_golomb_ue(bs); /* abs_delta_rps */ } else { u = read_golomb_ue(bs); /* rps->num_negative_pics */ v = read_golomb_ue(bs); /* nb_positive_pics */ if (u > MAX_REFS || v > MAX_REFS) return -1; for (i = 0; i < u; i++) { - read_golomb_ue(bs); /* delta_poc */ - skip_bits1(bs); /* used */ + read_golomb_ue(bs); /* delta_poc */ + skip_bits1(bs); /* used */ } for (i = 0; i < v; i++) { - read_golomb_ue(bs); /* delta_poc */ - skip_bits1(bs); /* used */ + read_golomb_ue(bs); /* delta_poc */ + skip_bits1(bs); /* used */ } } } - if (read_bits1(bs)) { /* long_term_ref_pics_present */ + if (read_bits1(bs)) { /* long_term_ref_pics_present */ u = read_golomb_ue(bs); /* num_long_term_ref_pics_sps */ if (u > 31) return -1; @@ -1574,44 +1523,41 @@ hevc_decode_sps(parser_es_t *st, bitstream_t *bs) skip_bits1(bs); /* sps_temporal_mvp_enabled_flag */ skip_bits1(bs); /* sps_strong_intra_smoothing_enable_flag */ - if (read_bits1(bs)) /* vui_present */ + if (read_bits1(bs)) /* vui_present */ if (hevc_decode_vui(&sps->vui, bs)) return -1; - if (!vps->num_units_in_tick && !vps->time_scale && - !sps->vui.num_units_in_tick && !sps->vui.time_scale) + if (!vps->num_units_in_tick && !vps->time_scale && !sps->vui.num_units_in_tick && + !sps->vui.time_scale) return -1; - sps->width = width; + sps->width = width; sps->height = height; - log2_ctb_size = log2_min_cb_size + - log2_diff_max_min_coding_block_size; + log2_ctb_size = log2_min_cb_size + log2_diff_max_min_coding_block_size; if (log2_ctb_size > 18) return -1; - sps->ctb_width = (width + (1 << log2_ctb_size) - 1) >> log2_ctb_size; + sps->ctb_width = (width + (1 << log2_ctb_size) - 1) >> log2_ctb_size; sps->ctb_height = (height + (1 << log2_ctb_size) - 1) >> log2_ctb_size; sps->vps_id = vps_id; - sps->valid = 1; + sps->valid = 1; return 0; } -int -hevc_decode_pps(parser_es_t *st, bitstream_t *bs) -{ - hevc_private_t *p; - hevc_pps_t *pps; - uint32_t pps_id, sps_id; +int hevc_decode_pps(parser_es_t* st, bitstream_t* bs) { + hevc_private_t* p; + hevc_pps_t* pps; + uint32_t pps_id, sps_id; if (read_bits1(bs)) /* zero bit */ return -1; - if((p = st->es_priv) == NULL) + if ((p = st->es_priv) == NULL) p = st->es_priv = calloc(1, sizeof(hevc_private_t)); - skip_bits(bs, 15); /* NAL type, Layer ID, Temporal ID */ + skip_bits(bs, 15); /* NAL type, Layer ID, Temporal ID */ pps_id = read_golomb_ue(bs); if (pps_id >= MAX_PPS_COUNT) @@ -1622,7 +1568,7 @@ hevc_decode_pps(parser_es_t *st, bitstream_t *bs) if (sps_id >= MAX_SPS_COUNT || !p->sps[sps_id].valid) return -1; - pps->sps_id = sps_id; + pps->sps_id = sps_id; pps->dependent_slice_segments = read_bits1(bs); skip_bits1(bs); /* output_flag_present */ pps->num_extra_slice_header_bits = read_bits(bs, 3); @@ -1631,32 +1577,30 @@ hevc_decode_pps(parser_es_t *st, bitstream_t *bs) return 0; } -int -hevc_decode_slice_header(parser_es_t *st, bitstream_t *bs, int *pkttype) -{ - hevc_private_t *p; - hevc_vps_t *vps; - hevc_sps_t *sps; - hevc_pps_t *pps; - int nal_type; - int first_slice_in_pic, dependent_slice_segment; - uint32_t pps_id, sps_id, vps_id, u, v, width, height; - uint64_t d; +int hevc_decode_slice_header(parser_es_t* st, bitstream_t* bs, int* pkttype) { + hevc_private_t* p; + hevc_vps_t* vps; + hevc_sps_t* sps; + hevc_pps_t* pps; + int nal_type; + int first_slice_in_pic, dependent_slice_segment; + uint32_t pps_id, sps_id, vps_id, u, v, width, height; + uint64_t d; if (read_bits1(bs)) /* zero bit */ return -1; - if((p = st->es_priv) == NULL) - p = st->es_priv = calloc(1, sizeof(hevc_private_t)); + if ((p = st->es_priv) == NULL) + p = st->es_priv = calloc(1, sizeof(hevc_private_t)); nal_type = read_bits(bs, 6); - skip_bits(bs, 6); /* Layer ID */ - skip_bits(bs, 3); /* Temporal ID */ + skip_bits(bs, 6); /* Layer ID */ + skip_bits(bs, 3); /* Temporal ID */ first_slice_in_pic = read_bits1(bs); if (IS_IRAP_NAL(nal_type)) - skip_bits1(bs); /* no_output_of_prior_pics_flag */ + skip_bits1(bs); /* no_output_of_prior_pics_flag */ pps_id = read_golomb_ue(bs); if (pps_id >= MAX_PPS_COUNT) @@ -1690,10 +1634,17 @@ hevc_decode_slice_header(parser_es_t *st, bitstream_t *bs, int *pkttype) skip_bits1(bs); switch (read_golomb_ue(bs)) { - case B_SLICE: *pkttype = PKT_B_FRAME; break; - case P_SLICE: *pkttype = PKT_P_FRAME; break; - case I_SLICE: *pkttype = PKT_I_FRAME; break; - default: return -1; + case B_SLICE: + *pkttype = PKT_B_FRAME; + break; + case P_SLICE: + *pkttype = PKT_P_FRAME; + break; + case I_SLICE: + *pkttype = PKT_I_FRAME; + break; + default: + return -1; } vps_id = sps->vps_id; @@ -1713,10 +1664,10 @@ hevc_decode_slice_header(parser_es_t *st, bitstream_t *bs, int *pkttype) parser_set_stream_vparam(st, width, height, d); if (sps->vui.sar.num && sps->vui.sar.den) { - width *= sps->vui.sar.num; + width *= sps->vui.sar.num; height *= sps->vui.sar.den; if (width && height) { - v = gcdU32(width, height); + v = gcdU32(width, height); st->es_aspect_num = width / v; st->es_aspect_den = height / v; } diff --git a/src/parsers/parser_hevc.h b/src/parsers/parser_hevc.h index 0c73e21bd..689244c61 100644 --- a/src/parsers/parser_hevc.h +++ b/src/parsers/parser_hevc.h @@ -25,17 +25,17 @@ #include "packet.h" #include "bitstream.h" -#define HEVC_NAL_TRAIL_N 0 -#define HEVC_NAL_TRAIL_R 1 +#define HEVC_NAL_TRAIL_N 0 +#define HEVC_NAL_TRAIL_R 1 -#define HEVC_NAL_TSA_N 2 -#define HEVC_NAL_TSA_R 3 -#define HEVC_NAL_STSA_N 4 -#define HEVC_NAL_STSA_R 5 -#define HEVC_NAL_RADL_N 6 -#define HEVC_NAL_RADL_R 7 -#define HEVC_NAL_RASL_N 8 -#define HEVC_NAL_RASL_R 9 +#define HEVC_NAL_TSA_N 2 +#define HEVC_NAL_TSA_R 3 +#define HEVC_NAL_STSA_N 4 +#define HEVC_NAL_STSA_R 5 +#define HEVC_NAL_RADL_N 6 +#define HEVC_NAL_RADL_R 7 +#define HEVC_NAL_RASL_N 8 +#define HEVC_NAL_RASL_R 9 #define HEVC_NAL_BLA_W_LP 16 #define HEVC_NAL_BLA_W_RADL 17 @@ -54,14 +54,14 @@ #define HEVC_NAL_SEI_PREFIX 39 #define HEVC_NAL_SEI_SUFFIX 40 -int isom_write_hvcc(sbuf_t *pb, const uint8_t *src, int size); +int isom_write_hvcc(sbuf_t* pb, const uint8_t* src, int size); -th_pkt_t * hevc_convert_pkt(th_pkt_t *src); +th_pkt_t* hevc_convert_pkt(th_pkt_t* src); -int hevc_decode_vps(parser_es_t *st, bitstream_t *bs); -int hevc_decode_sps(parser_es_t *st, bitstream_t *bs); -int hevc_decode_pps(parser_es_t *st, bitstream_t *bs); +int hevc_decode_vps(parser_es_t* st, bitstream_t* bs); +int hevc_decode_sps(parser_es_t* st, bitstream_t* bs); +int hevc_decode_pps(parser_es_t* st, bitstream_t* bs); -int hevc_decode_slice_header(parser_es_t *st, bitstream_t *bs, int *pkttype); +int hevc_decode_slice_header(parser_es_t* st, bitstream_t* bs, int* pkttype); #endif /* PARSER_HEVC_H */ diff --git a/src/parsers/parser_latm.c b/src/parsers/parser_latm.c index 5f21f1ddf..8c5595c7b 100644 --- a/src/parsers/parser_latm.c +++ b/src/parsers/parser_latm.c @@ -49,42 +49,39 @@ typedef struct latm_private { } latm_private_t; - - -static uint32_t -latm_get_value(bitstream_t *bs) -{ - return read_bits(bs, read_bits(bs, 2) * 8); +static uint32_t latm_get_value(bitstream_t* bs) { + return read_bits(bs, read_bits(bs, 2) * 8); } -#define AOT_AAC_MAIN 1 -#define AOT_AAC_LC 2 -#define AOT_AAC_SSR 3 -#define AOT_AAC_LTP 4 -#define AOT_SBR 5 +#define AOT_AAC_MAIN 1 +#define AOT_AAC_LC 2 +#define AOT_AAC_SSR 3 +#define AOT_AAC_LTP 4 +#define AOT_SBR 5 #define AOT_PS 26 #define AOT_ESCAPE 28 -static inline int adts_aot(int aot) -{ +static inline int adts_aot(int aot) { switch (aot) { - case AOT_AAC_MAIN: return 0; - case AOT_AAC_LC : return 1; - case AOT_AAC_SSR : return 2; - default: return 3; /* reserved or LTP */ + case AOT_AAC_MAIN: + return 0; + case AOT_AAC_LC: + return 1; + case AOT_AAC_SSR: + return 2; + default: + return 3; /* reserved or LTP */ } } -static inline int read_aot(bitstream_t *bs) -{ +static inline int read_aot(bitstream_t* bs) { int aot = read_bits(bs, 5); if (aot == AOT_ESCAPE) aot = read_bits(bs, 6); return aot; } -static inline int read_sr(bitstream_t *bs, int *sri) -{ +static inline int read_sr(bitstream_t* bs, int* sri) { *sri = read_bits(bs, 4); if (*sri == 0x0f) return read_bits(bs, 24); @@ -92,28 +89,24 @@ static inline int read_sr(bitstream_t *bs, int *sri) return sri_to_rate(*sri); } -static int -read_audio_specific_config(parser_es_t *st, latm_private_t *latm, bitstream_t *bs) -{ +static int read_audio_specific_config(parser_es_t* st, latm_private_t* latm, bitstream_t* bs) { int aot, sr, sri; if ((bs->offset % 8) != 0) return -1; - aot = read_aot(bs); - sr = read_sr(bs, &latm->sri); + aot = read_aot(bs); + sr = read_sr(bs, &latm->sri); latm->channel_config = read_bits(bs, 4); - if (sr < 7350 || sr > 96000 || - latm->channel_config == 0 || latm->channel_config > 7) + if (sr < 7350 || sr > 96000 || latm->channel_config == 0 || latm->channel_config > 7) return -1; st->es_frame_duration = 1024 * 90000 / sr; latm->ext_sri = 0; - if (aot == AOT_SBR || - (aot == AOT_PS && !(show_bits(bs, 3) & 3 && !(show_bits(bs, 9) & 0x3f)))) { - sr = read_sr(bs, &latm->ext_sri); + if (aot == AOT_SBR || (aot == AOT_PS && !(show_bits(bs, 3) & 3 && !(show_bits(bs, 9) & 0x3f)))) { + sr = read_sr(bs, &latm->ext_sri); if (sr < 7350 || sr > 96000) return -1; latm->ext_sri++; // zero means "not set" @@ -131,43 +124,40 @@ read_audio_specific_config(parser_es_t *st, latm_private_t *latm, bitstream_t *b latm->aot = aot; - if (read_bits1(bs)) // framelen_flag + if (read_bits1(bs)) // framelen_flag return -1; - if (read_bits1(bs)) // depends_on_coder + if (read_bits1(bs)) // depends_on_coder skip_bits(bs, 14); - if (read_bits1(bs)) // ext_flag - skip_bits(bs, 1); // ext3_flag + if (read_bits1(bs)) // ext_flag + skip_bits(bs, 1); // ext3_flag return 0; } - -static int -read_stream_mux_config(parser_es_t *st, latm_private_t *latm, bitstream_t *bs) -{ - int audio_mux_version = read_bits1(bs); +static int read_stream_mux_config(parser_es_t* st, latm_private_t* latm, bitstream_t* bs) { + int audio_mux_version = read_bits1(bs); latm->audio_mux_version_A = 0; - if (audio_mux_version) // audioMuxVersion + if (audio_mux_version) // audioMuxVersion latm->audio_mux_version_A = read_bits1(bs); if (latm->audio_mux_version_A) return 0; - if(audio_mux_version) - latm_get_value(bs); // taraFullness + if (audio_mux_version) + latm_get_value(bs); // taraFullness - skip_bits(bs, 1); // allStreamSameTimeFraming = 1 - skip_bits(bs, 6); // numSubFrames = 0 + skip_bits(bs, 1); // allStreamSameTimeFraming = 1 + skip_bits(bs, 6); // numSubFrames = 0 - if (read_bits(bs, 4)) // numPrograms = 0 + if (read_bits(bs, 4)) // numPrograms = 0 return -1; // for each program (only one in DVB) - if (read_bits(bs, 3)) // numLayer = 0 + if (read_bits(bs, 3)) // numLayer = 0 return -1; // for each layer (which there is only one in DVB) - if(!audio_mux_version) { + if (!audio_mux_version) { if (read_audio_specific_config(st, latm, bs) < 0) return -1; } else { @@ -181,26 +171,26 @@ read_stream_mux_config(parser_es_t *st, latm_private_t *latm, bitstream_t *bs) // these are not needed... perhaps latm->frame_length_type = read_bits(bs, 3); - switch(latm->frame_length_type) { - case 0: - read_bits(bs, 8); - break; - case 1: - read_bits(bs, 9); - break; - case 3: - case 4: - case 5: - read_bits(bs, 6); // celp_table_index - break; - case 6: - case 7: - read_bits(bs, 1); // hvxc_table_index - break; + switch (latm->frame_length_type) { + case 0: + read_bits(bs, 8); + break; + case 1: + read_bits(bs, 9); + break; + case 3: + case 4: + case 5: + read_bits(bs, 6); // celp_table_index + break; + case 6: + case 7: + read_bits(bs, 1); // hvxc_table_index + break; } - if(read_bits1(bs)) { // other data? -#if 0 // coverity - dead code - see above + if (read_bits1(bs)) { // other data? +#if 0 // coverity - dead code - see above if(audio_mux_version) latm_get_value(bs); // other_data_bits else @@ -208,14 +198,14 @@ read_stream_mux_config(parser_es_t *st, latm_private_t *latm, bitstream_t *bs) { int esc; do { - esc = read_bits1(bs); - skip_bits(bs, 8); + esc = read_bits1(bs); + skip_bits(bs, 8); } while (esc); } } - if(read_bits1(bs)) // crc present? - skip_bits(bs, 8); // config_crc + if (read_bits1(bs)) // crc present? + skip_bits(bs, 8); // config_crc latm->configured = 1; return 0; } @@ -223,28 +213,25 @@ read_stream_mux_config(parser_es_t *st, latm_private_t *latm, bitstream_t *bs) /** * Parse AAC LATM */ -th_pkt_t * -parse_latm_audio_mux_element(parser_t *t, parser_es_t *st, - const uint8_t *data, int len) -{ - latm_private_t *latm; - bitstream_t bs, out; - int slot_len, tmp, i; - uint8_t *buf; +th_pkt_t* parse_latm_audio_mux_element(parser_t* t, parser_es_t* st, const uint8_t* data, int len) { + latm_private_t* latm; + bitstream_t bs, out; + int slot_len, tmp, i; + uint8_t* buf; init_rbits(&bs, data, len * 8); - if((latm = st->es_priv) == NULL) + if ((latm = st->es_priv) == NULL) latm = st->es_priv = calloc(1, sizeof(latm_private_t)); - if(!read_bits1(&bs)) + if (!read_bits1(&bs)) if (read_stream_mux_config(st, latm, &bs) < 0) return NULL; - if(!latm->configured) + if (!latm->configured) return NULL; - if(latm->frame_length_type != 0) + if (latm->frame_length_type != 0) return NULL; slot_len = 0; @@ -256,11 +243,11 @@ parse_latm_audio_mux_element(parser_t *t, parser_es_t *st, if (slot_len * 8 > remaining_bits(&bs)) return NULL; - if(st->es_curdts == PTS_UNSET) + if (st->es_curdts == PTS_UNSET) return NULL; - th_pkt_t *pkt = pkt_alloc(st->es_type, NULL, slot_len + 7, - st->es_curdts, st->es_curdts, t->prs_current_pcr); + th_pkt_t* pkt = + pkt_alloc(st->es_type, NULL, slot_len + 7, st->es_curdts, st->es_curdts, t->prs_current_pcr); pkt->pkt_commercial = t->prs_tt_commercial_advice; pkt->pkt_duration = st->es_frame_duration; @@ -277,13 +264,13 @@ parse_latm_audio_mux_element(parser_t *t, parser_es_t *st, put_bits(&out, 1, 1); // Protection absent put_bits(&out, adts_aot(latm->aot), 2); put_bits(&out, latm->sri, 4); - put_bits(&out, 1, 1); // Private bit + put_bits(&out, 1, 1); // Private bit put_bits(&out, latm->channel_config, 3); - put_bits(&out, 1, 1); // Original - put_bits(&out, 1, 1); // Copy - - put_bits(&out, 1, 1); // Copyright identification bit - put_bits(&out, 1, 1); // Copyright identification start + put_bits(&out, 1, 1); // Original + put_bits(&out, 1, 1); // Copy + + put_bits(&out, 1, 1); // Copyright identification bit + put_bits(&out, 1, 1); // Copyright identification start put_bits(&out, slot_len + 7, 13); put_bits(&out, 0x7ff, 11); // Buffer fullness put_bits(&out, 0, 2); // RDB in frame @@ -292,7 +279,7 @@ parse_latm_audio_mux_element(parser_t *t, parser_es_t *st, /* AAC RDB */ buf = pktbuf_ptr(pkt->pkt_payload) + 7; - for(i = 0; i < slot_len; i++) + for (i = 0; i < slot_len; i++) *buf++ = read_bits(&bs, 8); st->es_curdts += st->es_frame_duration; diff --git a/src/parsers/parser_latm.h b/src/parsers/parser_latm.h index 4251bb2f4..753d8ad81 100644 --- a/src/parsers/parser_latm.h +++ b/src/parsers/parser_latm.h @@ -19,8 +19,6 @@ #ifndef PARSER_LATM_H_ #define PARSER_LATM_H_ -th_pkt_t *parse_latm_audio_mux_element(parser_t *t, - parser_es_t *st, - const uint8_t *data, int len); +th_pkt_t* parse_latm_audio_mux_element(parser_t* t, parser_es_t* st, const uint8_t* data, int len); #endif /* PARSER_LATM_H_ */ diff --git a/src/parsers/parser_teletext.c b/src/parsers/parser_teletext.c index ff39eb6ac..2d8178a3a 100644 --- a/src/parsers/parser_teletext.c +++ b/src/parsers/parser_teletext.c @@ -33,68 +33,289 @@ * */ typedef struct tt_mag { - int ttm_curpage; + int ttm_curpage; int64_t ttm_current_pts; uint8_t ttm_charset[2]; uint8_t ttm_national; - uint8_t ttm_page[23*40 + 1]; + uint8_t ttm_page[23 * 40 + 1]; int64_t ttm_last_sub_pts; uint8_t ttm_last_sub_text[MAX_SUB_TEXT_SIZE]; } tt_mag_t; - /** * */ typedef struct tt_private { tt_mag_t ttp_mags[8]; - int ttp_rundown_valid; - uint8_t ttp_rundown[23*40 + 1]; + int ttp_rundown_valid; + uint8_t ttp_rundown[23 * 40 + 1]; } tt_private_t; +static void teletext_rundown_copy(tt_private_t* ttp, tt_mag_t* ttm); -static void teletext_rundown_copy(tt_private_t *ttp, tt_mag_t *ttm); - -static void teletext_rundown_scan(parser_t *t, tt_private_t *ttp); +static void teletext_rundown_scan(parser_t* t, tt_private_t* ttp); -#define bitreverse(b) \ -(((b) * 0x0202020202ULL & 0x010884422010ULL) % 1023) +#define bitreverse(b) (((b) * 0x0202020202ULL & 0x010884422010ULL) % 1023) static const uint8_t hamtable[] = { - 0x01, 0xff, 0x81, 0x01, 0xff, 0x00, 0x01, 0xff, - 0xff, 0x02, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x07, - 0xff, 0x00, 0x01, 0xff, 0x00, 0x80, 0xff, 0x00, - 0x06, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x03, 0xff, - 0xff, 0x0c, 0x01, 0xff, 0x04, 0xff, 0xff, 0x07, - 0x06, 0xff, 0xff, 0x07, 0xff, 0x07, 0x07, 0x87, - 0x06, 0xff, 0xff, 0x05, 0xff, 0x00, 0x0d, 0xff, - 0x86, 0x06, 0x06, 0xff, 0x06, 0xff, 0xff, 0x07, - 0xff, 0x02, 0x01, 0xff, 0x04, 0xff, 0xff, 0x09, - 0x02, 0x82, 0xff, 0x02, 0xff, 0x02, 0x03, 0xff, - 0x08, 0xff, 0xff, 0x05, 0xff, 0x00, 0x03, 0xff, - 0xff, 0x02, 0x03, 0xff, 0x03, 0xff, 0x83, 0x03, - 0x04, 0xff, 0xff, 0x05, 0x84, 0x04, 0x04, 0xff, - 0xff, 0x02, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x07, - 0xff, 0x05, 0x05, 0x85, 0x04, 0xff, 0xff, 0x05, - 0x06, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x03, 0xff, - 0xff, 0x0c, 0x01, 0xff, 0x0a, 0xff, 0xff, 0x09, - 0x0a, 0xff, 0xff, 0x0b, 0x8a, 0x0a, 0x0a, 0xff, - 0x08, 0xff, 0xff, 0x0b, 0xff, 0x00, 0x0d, 0xff, - 0xff, 0x0b, 0x0b, 0x8b, 0x0a, 0xff, 0xff, 0x0b, - 0x0c, 0x8c, 0xff, 0x0c, 0xff, 0x0c, 0x0d, 0xff, - 0xff, 0x0c, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x07, - 0xff, 0x0c, 0x0d, 0xff, 0x0d, 0xff, 0x8d, 0x0d, - 0x06, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x0d, 0xff, - 0x08, 0xff, 0xff, 0x09, 0xff, 0x09, 0x09, 0x89, - 0xff, 0x02, 0x0f, 0xff, 0x0a, 0xff, 0xff, 0x09, - 0x88, 0x08, 0x08, 0xff, 0x08, 0xff, 0xff, 0x09, - 0x08, 0xff, 0xff, 0x0b, 0xff, 0x0e, 0x03, 0xff, - 0xff, 0x0c, 0x0f, 0xff, 0x04, 0xff, 0xff, 0x09, - 0x0f, 0xff, 0x8f, 0x0f, 0xff, 0x0e, 0x0f, 0xff, - 0x08, 0xff, 0xff, 0x05, 0xff, 0x0e, 0x0d, 0xff, - 0xff, 0x0e, 0x0f, 0xff, 0x0e, 0x8e, 0xff, 0x0e, + 0x01, + 0xff, + 0x81, + 0x01, + 0xff, + 0x00, + 0x01, + 0xff, + 0xff, + 0x02, + 0x01, + 0xff, + 0x0a, + 0xff, + 0xff, + 0x07, + 0xff, + 0x00, + 0x01, + 0xff, + 0x00, + 0x80, + 0xff, + 0x00, + 0x06, + 0xff, + 0xff, + 0x0b, + 0xff, + 0x00, + 0x03, + 0xff, + 0xff, + 0x0c, + 0x01, + 0xff, + 0x04, + 0xff, + 0xff, + 0x07, + 0x06, + 0xff, + 0xff, + 0x07, + 0xff, + 0x07, + 0x07, + 0x87, + 0x06, + 0xff, + 0xff, + 0x05, + 0xff, + 0x00, + 0x0d, + 0xff, + 0x86, + 0x06, + 0x06, + 0xff, + 0x06, + 0xff, + 0xff, + 0x07, + 0xff, + 0x02, + 0x01, + 0xff, + 0x04, + 0xff, + 0xff, + 0x09, + 0x02, + 0x82, + 0xff, + 0x02, + 0xff, + 0x02, + 0x03, + 0xff, + 0x08, + 0xff, + 0xff, + 0x05, + 0xff, + 0x00, + 0x03, + 0xff, + 0xff, + 0x02, + 0x03, + 0xff, + 0x03, + 0xff, + 0x83, + 0x03, + 0x04, + 0xff, + 0xff, + 0x05, + 0x84, + 0x04, + 0x04, + 0xff, + 0xff, + 0x02, + 0x0f, + 0xff, + 0x04, + 0xff, + 0xff, + 0x07, + 0xff, + 0x05, + 0x05, + 0x85, + 0x04, + 0xff, + 0xff, + 0x05, + 0x06, + 0xff, + 0xff, + 0x05, + 0xff, + 0x0e, + 0x03, + 0xff, + 0xff, + 0x0c, + 0x01, + 0xff, + 0x0a, + 0xff, + 0xff, + 0x09, + 0x0a, + 0xff, + 0xff, + 0x0b, + 0x8a, + 0x0a, + 0x0a, + 0xff, + 0x08, + 0xff, + 0xff, + 0x0b, + 0xff, + 0x00, + 0x0d, + 0xff, + 0xff, + 0x0b, + 0x0b, + 0x8b, + 0x0a, + 0xff, + 0xff, + 0x0b, + 0x0c, + 0x8c, + 0xff, + 0x0c, + 0xff, + 0x0c, + 0x0d, + 0xff, + 0xff, + 0x0c, + 0x0f, + 0xff, + 0x0a, + 0xff, + 0xff, + 0x07, + 0xff, + 0x0c, + 0x0d, + 0xff, + 0x0d, + 0xff, + 0x8d, + 0x0d, + 0x06, + 0xff, + 0xff, + 0x0b, + 0xff, + 0x0e, + 0x0d, + 0xff, + 0x08, + 0xff, + 0xff, + 0x09, + 0xff, + 0x09, + 0x09, + 0x89, + 0xff, + 0x02, + 0x0f, + 0xff, + 0x0a, + 0xff, + 0xff, + 0x09, + 0x88, + 0x08, + 0x08, + 0xff, + 0x08, + 0xff, + 0xff, + 0x09, + 0x08, + 0xff, + 0xff, + 0x0b, + 0xff, + 0x0e, + 0x03, + 0xff, + 0xff, + 0x0c, + 0x0f, + 0xff, + 0x04, + 0xff, + 0xff, + 0x09, + 0x0f, + 0xff, + 0x8f, + 0x0f, + 0xff, + 0x0e, + 0x0f, + 0xff, + 0x08, + 0xff, + 0xff, + 0x05, + 0xff, + 0x0e, + 0x0d, + 0xff, + 0xff, + 0x0e, + 0x0f, + 0xff, + 0x0e, + 0x8e, + 0xff, + 0x0e, }; /* @@ -120,23 +341,23 @@ static const uint8_t hamtable[] = { * Teletext Latin G0 national option subsets according to * ETS 300 706, Section 15.2; Section 15.6.2 Table 36. */ -#define SUBSET_NONE 0 -#define SUBSET_CZECH_SLOVAK 1 /* Cesky / Slovencina */ -#define SUBSET_ENGLISH 2 /* English */ -#define SUBSET_ESTONIAN 3 /* Eesti */ -#define SUBSET_FRENCH 4 /* Français */ -#define SUBSET_GERMAN 5 /* German / Deutch */ -#define SUBSET_ITALIAN 6 /* Italiano */ -#define SUBSET_LETT_LITH 7 /* Lettish / Lietuviskai */ -#define SUBSET_POLISH 8 /* Polski */ -#define SUBSET_PORTUG_SPANISH 9 /* Português / Español */ -#define SUBSET_RUMANIAN 10 /* Româna */ -#define SUBSET_SERB_CRO_SLO 11 /* Srpski / Hrvatski / Slovenscina */ -#define SUBSET_SWE_FIN_HUN 12 /* Svenska / Suomi / Magyar */ -#define SUBSET_TURKISH 13 /* Türkçe */ -#define SUBSET_LAST SUBSET_TURKISH - -#define SUBSET_CHARMAP_COUNT 13 +#define SUBSET_NONE 0 +#define SUBSET_CZECH_SLOVAK 1 /* Cesky / Slovencina */ +#define SUBSET_ENGLISH 2 /* English */ +#define SUBSET_ESTONIAN 3 /* Eesti */ +#define SUBSET_FRENCH 4 /* Français */ +#define SUBSET_GERMAN 5 /* German / Deutch */ +#define SUBSET_ITALIAN 6 /* Italiano */ +#define SUBSET_LETT_LITH 7 /* Lettish / Lietuviskai */ +#define SUBSET_POLISH 8 /* Polski */ +#define SUBSET_PORTUG_SPANISH 9 /* Português / Español */ +#define SUBSET_RUMANIAN 10 /* Româna */ +#define SUBSET_SERB_CRO_SLO 11 /* Srpski / Hrvatski / Slovenscina */ +#define SUBSET_SWE_FIN_HUN 12 /* Svenska / Suomi / Magyar */ +#define SUBSET_TURKISH 13 /* Türkçe */ +#define SUBSET_LAST SUBSET_TURKISH + +#define SUBSET_CHARMAP_COUNT 13 /* * Teletext font descriptors @@ -146,115 +367,115 @@ static const uint8_t hamtable[] = { * Note the fourth byte is unused (it's just a pad) */ uint8_t char_table[88][4] = { - /* Western and Central Europe */ - /* 00 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ENGLISH }, - /* 01 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_GERMAN }, - /* 02 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_SWE_FIN_HUN }, - /* 03 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ITALIAN }, - /* 04 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_FRENCH }, - /* 05 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_PORTUG_SPANISH }, - /* 06 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_CZECH_SLOVAK }, - /* 07 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE }, - - /* Eastern Europe */ - /* 08 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_POLISH }, - /* 09 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_GERMAN }, - /* 10 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_SWE_FIN_HUN }, - /* 11 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ITALIAN }, - /* 12 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_FRENCH }, - /* 13 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE }, - /* 14 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_CZECH_SLOVAK }, - /* 15 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE }, - - /* Western Europe and Turkey */ - /* 16 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ENGLISH }, - /* 17 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_GERMAN }, - /* 18 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_SWE_FIN_HUN }, - /* 19 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ITALIAN }, - /* 20 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_FRENCH }, - /* 21 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_PORTUG_SPANISH }, - /* 22 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_TURKISH }, - /* 23 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE }, - - /* Central and Southeast Europe */ - /* 24 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE }, - /* 25 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE }, - /* 26 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE }, - /* 27 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE }, - /* 28 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE }, - /* 29 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_SERB_CRO_SLO }, - /* 30 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE }, - /* 31 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_RUMANIAN }, - - /* Cyrillic */ - /* 32 */ { CHARSET_CYRILLIC_1_G0, CHARSET_CYRILLIC_G2, SUBSET_NONE }, - /* 33 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_GERMAN }, - /* 34 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ESTONIAN }, - /* 35 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_LETT_LITH }, - /* 36 */ { CHARSET_CYRILLIC_2_G0, CHARSET_CYRILLIC_G2, SUBSET_NONE }, - /* 37 */ { CHARSET_CYRILLIC_3_G0, CHARSET_CYRILLIC_G2, SUBSET_NONE }, - /* 38 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_CZECH_SLOVAK }, - /* 39 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - - /* Unused */ - /* 40 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 41 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 42 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 43 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 44 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 45 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 46 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 47 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - - /* Misc */ - /* 48 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 49 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 50 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 51 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 52 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 53 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 54 */ { CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_TURKISH }, - /* 55 */ { CHARSET_GREEK_G0, CHARSET_GREEK_G2, SUBSET_NONE }, - - /* Unused */ - /* 56 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 57 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 58 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 59 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 60 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 61 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 62 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 63 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - - /* Arabic */ - /* 64 */ { CHARSET_LATIN_G0, CHARSET_ARABIC_G2, SUBSET_ENGLISH }, - /* 65 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 66 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 67 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 68 */ { CHARSET_LATIN_G0, CHARSET_ARABIC_G2, SUBSET_FRENCH }, - /* 69 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 70 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 71 */ { CHARSET_ARABIC_G0, CHARSET_ARABIC_G2, SUBSET_NONE }, - - /* Unused */ - /* 72 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 73 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 74 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 75 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 76 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 77 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 78 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 79 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - - /* Misc */ - /* 80 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 81 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 82 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 83 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 84 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 85 */ { CHARSET_HEBREW_G0, CHARSET_ARABIC_G2, SUBSET_NONE }, - /* 86 */ { CHARSET_NONE, CHARSET_NONE, SUBSET_NONE }, - /* 87 */ { CHARSET_ARABIC_G0, CHARSET_ARABIC_G2, SUBSET_NONE }, + /* Western and Central Europe */ + /* 00 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ENGLISH}, + /* 01 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_GERMAN}, + /* 02 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_SWE_FIN_HUN}, + /* 03 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ITALIAN}, + /* 04 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_FRENCH}, + /* 05 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_PORTUG_SPANISH}, + /* 06 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_CZECH_SLOVAK}, + /* 07 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE}, + + /* Eastern Europe */ + /* 08 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_POLISH}, + /* 09 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_GERMAN}, + /* 10 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_SWE_FIN_HUN}, + /* 11 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ITALIAN}, + /* 12 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_FRENCH}, + /* 13 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE}, + /* 14 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_CZECH_SLOVAK}, + /* 15 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE}, + + /* Western Europe and Turkey */ + /* 16 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ENGLISH}, + /* 17 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_GERMAN}, + /* 18 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_SWE_FIN_HUN}, + /* 19 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ITALIAN}, + /* 20 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_FRENCH}, + /* 21 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_PORTUG_SPANISH}, + /* 22 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_TURKISH}, + /* 23 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE}, + + /* Central and Southeast Europe */ + /* 24 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE}, + /* 25 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE}, + /* 26 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE}, + /* 27 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE}, + /* 28 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE}, + /* 29 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_SERB_CRO_SLO}, + /* 30 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_NONE}, + /* 31 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_RUMANIAN}, + + /* Cyrillic */ + /* 32 */ {CHARSET_CYRILLIC_1_G0, CHARSET_CYRILLIC_G2, SUBSET_NONE}, + /* 33 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_GERMAN}, + /* 34 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_ESTONIAN}, + /* 35 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_LETT_LITH}, + /* 36 */ {CHARSET_CYRILLIC_2_G0, CHARSET_CYRILLIC_G2, SUBSET_NONE}, + /* 37 */ {CHARSET_CYRILLIC_3_G0, CHARSET_CYRILLIC_G2, SUBSET_NONE}, + /* 38 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_CZECH_SLOVAK}, + /* 39 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + + /* Unused */ + /* 40 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 41 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 42 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 43 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 44 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 45 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 46 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 47 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + + /* Misc */ + /* 48 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 49 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 50 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 51 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 52 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 53 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 54 */ {CHARSET_LATIN_G0, CHARSET_LATIN_G2, SUBSET_TURKISH}, + /* 55 */ {CHARSET_GREEK_G0, CHARSET_GREEK_G2, SUBSET_NONE}, + + /* Unused */ + /* 56 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 57 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 58 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 59 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 60 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 61 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 62 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 63 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + + /* Arabic */ + /* 64 */ {CHARSET_LATIN_G0, CHARSET_ARABIC_G2, SUBSET_ENGLISH}, + /* 65 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 66 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 67 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 68 */ {CHARSET_LATIN_G0, CHARSET_ARABIC_G2, SUBSET_FRENCH}, + /* 69 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 70 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 71 */ {CHARSET_ARABIC_G0, CHARSET_ARABIC_G2, SUBSET_NONE}, + + /* Unused */ + /* 72 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 73 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 74 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 75 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 76 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 77 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 78 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 79 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + + /* Misc */ + /* 80 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 81 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 82 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 83 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 84 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 85 */ {CHARSET_HEBREW_G0, CHARSET_ARABIC_G2, SUBSET_NONE}, + /* 86 */ {CHARSET_NONE, CHARSET_NONE, SUBSET_NONE}, + /* 87 */ {CHARSET_ARABIC_G0, CHARSET_ARABIC_G2, SUBSET_NONE}, }; /* @@ -272,219 +493,1025 @@ uint8_t char_table[88][4] = { * * [13][0] Turkish currency symbol not in Unicode, use '$'. */ -static const uint16_t -teletext_subset[SUBSET_LAST+1][SUBSET_CHARMAP_COUNT] = { - { 0x0023, 0x0024, 0x0040, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F, - 0x0060, 0x007B, 0x007C, 0x007D, 0x007E }, - { 0x0023, 0x016F, 0x010D, 0x0165, 0x017E, 0x00FD, 0x00ED, 0x0159, - 0x00E9, 0x00E1, 0x011B, 0x00FA, 0x0161 }, - { 0x00A3, 0x0024, 0x0040, 0x2190, 0x00BD, 0x2192, 0x2191, 0x0023, - 0x2014, 0x00BC, 0x2016, 0x00BE, 0x00F7 }, - { 0x0023, 0x00F5, 0x0160, 0x00C4, 0x00D6, 0x017D, 0x00DC, 0x00D5, - 0x0161, 0x00E4, 0x00F6, 0x017E, 0x00FC }, - { 0x00E9, 0x00EF, 0x00E0, 0x00EB, 0x00EA, 0x00F9, 0x00EE, 0x0023, - 0x00E8, 0x00E2, 0x00F4, 0x00FB, 0x00E7 }, - { 0x0023, 0x0024, 0x00A7, 0x00C4, 0x00D6, 0x00DC, 0x005E, 0x005F, - 0x00B0, 0x00E4, 0x00F6, 0x00FC, 0x00DF }, - { 0x00A3, 0x0024, 0x00E9, 0x00B0, 0x00E7, 0x2192, 0x2191, 0x0023, - 0x00F9, 0x00E0, 0x00F2, 0x00E8, 0x00EC }, - { 0x0023, 0x0024, 0x0160, 0x0117, 0x0229, 0x017D, 0x010D, 0x016B, - 0x0161, 0x0105, 0x0173, 0x017E, 0x012F }, - { 0x0023, 0x0144, 0x0105, 0x01B5, 0x015A, 0x0141, 0x0107, 0x00F3, - 0x0119, 0x017C, 0x015B, 0x0142, 0x017A }, - { 0x00E7, 0x0024, 0x00A1, 0x00E1, 0x00E9, 0x00ED, 0x00F3, 0x00FA, - 0x00BF, 0x00FC, 0x00F1, 0x00E8, 0x00E0 }, - { 0x0023, 0x00A4, 0x0162, 0x00C2, 0x015E, 0x01CD, 0x00CD, 0x0131, - 0x0163, 0x00E2, 0x015F, 0X01CE, 0x00EE }, - { 0x0023, 0x00CB, 0x010C, 0x0106, 0x017D, 0x00D0, 0x0160, 0x00EB, - 0x010D, 0x0107, 0x017E, 0x00F0, 0x0161 }, - { 0x0023, 0x00A4, 0x00C9, 0x00C4, 0x00D6, 0x00C5, 0x00DC, 0x005F, - 0x00E9, 0x00E4, 0x00F6, 0x00E5, 0x00FC }, - { 0x0024, 0x011F, 0x0130, 0x015E, 0x00D6, 0x00C7, 0x00DC, 0x011E, - 0x0131, 0x015F, 0x00F6, 0x00E7, 0x00FC } -}; +static const uint16_t teletext_subset[SUBSET_LAST + 1][SUBSET_CHARMAP_COUNT] = {{0x0023, + 0x0024, + 0x0040, + 0x005B, + 0x005C, + 0x005D, + 0x005E, + 0x005F, + 0x0060, + 0x007B, + 0x007C, + 0x007D, + 0x007E}, + {0x0023, + 0x016F, + 0x010D, + 0x0165, + 0x017E, + 0x00FD, + 0x00ED, + 0x0159, + 0x00E9, + 0x00E1, + 0x011B, + 0x00FA, + 0x0161}, + {0x00A3, + 0x0024, + 0x0040, + 0x2190, + 0x00BD, + 0x2192, + 0x2191, + 0x0023, + 0x2014, + 0x00BC, + 0x2016, + 0x00BE, + 0x00F7}, + {0x0023, + 0x00F5, + 0x0160, + 0x00C4, + 0x00D6, + 0x017D, + 0x00DC, + 0x00D5, + 0x0161, + 0x00E4, + 0x00F6, + 0x017E, + 0x00FC}, + {0x00E9, + 0x00EF, + 0x00E0, + 0x00EB, + 0x00EA, + 0x00F9, + 0x00EE, + 0x0023, + 0x00E8, + 0x00E2, + 0x00F4, + 0x00FB, + 0x00E7}, + {0x0023, + 0x0024, + 0x00A7, + 0x00C4, + 0x00D6, + 0x00DC, + 0x005E, + 0x005F, + 0x00B0, + 0x00E4, + 0x00F6, + 0x00FC, + 0x00DF}, + {0x00A3, + 0x0024, + 0x00E9, + 0x00B0, + 0x00E7, + 0x2192, + 0x2191, + 0x0023, + 0x00F9, + 0x00E0, + 0x00F2, + 0x00E8, + 0x00EC}, + {0x0023, + 0x0024, + 0x0160, + 0x0117, + 0x0229, + 0x017D, + 0x010D, + 0x016B, + 0x0161, + 0x0105, + 0x0173, + 0x017E, + 0x012F}, + {0x0023, + 0x0144, + 0x0105, + 0x01B5, + 0x015A, + 0x0141, + 0x0107, + 0x00F3, + 0x0119, + 0x017C, + 0x015B, + 0x0142, + 0x017A}, + {0x00E7, + 0x0024, + 0x00A1, + 0x00E1, + 0x00E9, + 0x00ED, + 0x00F3, + 0x00FA, + 0x00BF, + 0x00FC, + 0x00F1, + 0x00E8, + 0x00E0}, + {0x0023, + 0x00A4, + 0x0162, + 0x00C2, + 0x015E, + 0x01CD, + 0x00CD, + 0x0131, + 0x0163, + 0x00E2, + 0x015F, + 0X01CE, + 0x00EE}, + {0x0023, + 0x00CB, + 0x010C, + 0x0106, + 0x017D, + 0x00D0, + 0x0160, + 0x00EB, + 0x010D, + 0x0107, + 0x017E, + 0x00F0, + 0x0161}, + {0x0023, + 0x00A4, + 0x00C9, + 0x00C4, + 0x00D6, + 0x00C5, + 0x00DC, + 0x005F, + 0x00E9, + 0x00E4, + 0x00F6, + 0x00E5, + 0x00FC}, + {0x0024, + 0x011F, + 0x0130, + 0x015E, + 0x00D6, + 0x00C7, + 0x00DC, + 0x011E, + 0x0131, + 0x015F, + 0x00F6, + 0x00E7, + 0x00FC}}; /* * ETS 300 706 Table 37: Latin G2 Supplementary Set * * 0x49 seems to be dot below; not in Unicode (except combining), use U+002E. */ -static const uint16_t -latin_g2[96] = { - /* 0x20 */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x0024, 0x00A5, 0x0023, 0x00A7, - /* 0x28 */ 0x00A4, 0x2018, 0x201C, 0x00AB, 0x2190, 0x2191, 0x2192, 0x2193, - /* 0x30 */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00D7, 0x00B5, 0x00B6, 0x00B7, - /* 0x38 */ 0x00F7, 0x2019, 0x201D, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, - /* 0x40 */ 0x0020, 0x02CB, 0x02CA, 0x02C6, 0x02DC, 0x02C9, 0x02D8, 0x02D9, - /* 0x48 */ 0x00A8, 0x002E, 0x02DA, 0x02CF, 0x02CD, 0x02DD, 0x02DB, 0x02C7, - /* 0x50 */ 0x2014, 0x00B9, 0x00AE, 0x00A9, 0x2122, 0x266A, 0x20A0, 0x2030, - /* 0x58 */ 0x0251, 0x0020, 0x0020, 0x0020, 0x215B, 0x215C, 0x215D, 0x215E, - /* 0x60 */ 0x2126, 0x00C6, 0x00D0, 0x00AA, 0x0126, 0x0020, 0x0132, 0x013F, - /* 0x68 */ 0x0141, 0x00D8, 0x0152, 0x00BA, 0x00DE, 0x0166, 0x014A, 0x0149, - /* 0x70 */ 0x0138, 0x00E6, 0x0111, 0x00F0, 0x0127, 0x0131, 0x0133, 0x0140, - /* 0x78 */ 0x0142, 0x00F8, 0x0153, 0x00DF, 0x00FE, 0x0167, 0x014B, 0x25A0 -}; +static const uint16_t latin_g2[96] = { + /* 0x20 */ 0x00A0, + 0x00A1, + 0x00A2, + 0x00A3, + 0x0024, + 0x00A5, + 0x0023, + 0x00A7, + /* 0x28 */ 0x00A4, + 0x2018, + 0x201C, + 0x00AB, + 0x2190, + 0x2191, + 0x2192, + 0x2193, + /* 0x30 */ 0x00B0, + 0x00B1, + 0x00B2, + 0x00B3, + 0x00D7, + 0x00B5, + 0x00B6, + 0x00B7, + /* 0x38 */ 0x00F7, + 0x2019, + 0x201D, + 0x00BB, + 0x00BC, + 0x00BD, + 0x00BE, + 0x00BF, + /* 0x40 */ 0x0020, + 0x02CB, + 0x02CA, + 0x02C6, + 0x02DC, + 0x02C9, + 0x02D8, + 0x02D9, + /* 0x48 */ 0x00A8, + 0x002E, + 0x02DA, + 0x02CF, + 0x02CD, + 0x02DD, + 0x02DB, + 0x02C7, + /* 0x50 */ 0x2014, + 0x00B9, + 0x00AE, + 0x00A9, + 0x2122, + 0x266A, + 0x20A0, + 0x2030, + /* 0x58 */ 0x0251, + 0x0020, + 0x0020, + 0x0020, + 0x215B, + 0x215C, + 0x215D, + 0x215E, + /* 0x60 */ 0x2126, + 0x00C6, + 0x00D0, + 0x00AA, + 0x0126, + 0x0020, + 0x0132, + 0x013F, + /* 0x68 */ 0x0141, + 0x00D8, + 0x0152, + 0x00BA, + 0x00DE, + 0x0166, + 0x014A, + 0x0149, + /* 0x70 */ 0x0138, + 0x00E6, + 0x0111, + 0x00F0, + 0x0127, + 0x0131, + 0x0133, + 0x0140, + /* 0x78 */ 0x0142, + 0x00F8, + 0x0153, + 0x00DF, + 0x00FE, + 0x0167, + 0x014B, + 0x25A0}; /* * ETS 300 706 Table 38: Cyrillic G0 Primary Set - Option 1 - Serbian/Croatian */ -static const uint16_t -cyrillic_1_g0[64] = { - /* 0x40 */ 0x0427, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, - /* 0x48 */ 0x0425, 0x0418, 0x0408, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, - /* 0x50 */ 0x041F, 0x040C, 0x0420, 0x0421, 0x0422, 0x0423, 0x0412, 0x0403, - /* 0x58 */ 0x0409, 0x040A, 0x0417, 0x040B, 0x0416, 0x0402, 0x0428, 0x040F, - /* 0x60 */ 0x0447, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, - /* 0x68 */ 0x0445, 0x0438, 0x0458, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, - /* 0x70 */ 0x043F, 0x045C, 0x0440, 0x0441, 0x0442, 0x0443, 0x0432, 0x0453, - /* 0x78 */ 0x0459, 0x045A, 0x0437, 0x045B, 0x0436, 0x0452, 0x0448, 0x25A0 -}; +static const uint16_t cyrillic_1_g0[64] = { + /* 0x40 */ 0x0427, + 0x0410, + 0x0411, + 0x0426, + 0x0414, + 0x0415, + 0x0424, + 0x0413, + /* 0x48 */ 0x0425, + 0x0418, + 0x0408, + 0x041A, + 0x041B, + 0x041C, + 0x041D, + 0x041E, + /* 0x50 */ 0x041F, + 0x040C, + 0x0420, + 0x0421, + 0x0422, + 0x0423, + 0x0412, + 0x0403, + /* 0x58 */ 0x0409, + 0x040A, + 0x0417, + 0x040B, + 0x0416, + 0x0402, + 0x0428, + 0x040F, + /* 0x60 */ 0x0447, + 0x0430, + 0x0431, + 0x0446, + 0x0434, + 0x0435, + 0x0444, + 0x0433, + /* 0x68 */ 0x0445, + 0x0438, + 0x0458, + 0x043A, + 0x043B, + 0x043C, + 0x043D, + 0x043E, + /* 0x70 */ 0x043F, + 0x045C, + 0x0440, + 0x0441, + 0x0442, + 0x0443, + 0x0432, + 0x0453, + /* 0x78 */ 0x0459, + 0x045A, + 0x0437, + 0x045B, + 0x0436, + 0x0452, + 0x0448, + 0x25A0}; /* * ETS 300 706 Table 39: Cyrillic G0 Primary Set - Option 2 - Russian/Bulgarian */ -static const uint16_t -cyrillic_2_g0[64] = { - /* 0x40 */ 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, - /* 0x48 */ 0x0425, 0x0418, 0x040D, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, - /* 0x50 */ 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, - /* 0x58 */ 0x042C, 0x042A, 0x0417, 0x0428, 0x042D, 0x0429, 0x0427, 0x042B, - /* 0x60 */ 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, - /* 0x68 */ 0x0445, 0x0438, 0x045D, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, - /* 0x70 */ 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, - /* 0x78 */ 0x044C, 0x044A, 0x0437, 0x0448, 0x044D, 0x0449, 0x0447, 0x25A0 -}; +static const uint16_t cyrillic_2_g0[64] = { + /* 0x40 */ 0x042E, + 0x0410, + 0x0411, + 0x0426, + 0x0414, + 0x0415, + 0x0424, + 0x0413, + /* 0x48 */ 0x0425, + 0x0418, + 0x040D, + 0x041A, + 0x041B, + 0x041C, + 0x041D, + 0x041E, + /* 0x50 */ 0x041F, + 0x042F, + 0x0420, + 0x0421, + 0x0422, + 0x0423, + 0x0416, + 0x0412, + /* 0x58 */ 0x042C, + 0x042A, + 0x0417, + 0x0428, + 0x042D, + 0x0429, + 0x0427, + 0x042B, + /* 0x60 */ 0x044E, + 0x0430, + 0x0431, + 0x0446, + 0x0434, + 0x0435, + 0x0444, + 0x0433, + /* 0x68 */ 0x0445, + 0x0438, + 0x045D, + 0x043A, + 0x043B, + 0x043C, + 0x043D, + 0x043E, + /* 0x70 */ 0x043F, + 0x044F, + 0x0440, + 0x0441, + 0x0442, + 0x0443, + 0x0436, + 0x0432, + /* 0x78 */ 0x044C, + 0x044A, + 0x0437, + 0x0448, + 0x044D, + 0x0449, + 0x0447, + 0x25A0}; /* * ETS 300 706 Table 40: Cyrillic G0 Primary Set - Option 3 - Ukrainian */ -static const uint16_t -cyrillic_3_g0[64] = { - /* 0x40 */ 0x042E, 0x0410, 0x0411, 0x0426, 0x0414, 0x0415, 0x0424, 0x0413, - /* 0x48 */ 0x0425, 0x0418, 0x040D, 0x041A, 0x041B, 0x041C, 0x041D, 0x041E, - /* 0x50 */ 0x041F, 0x042F, 0x0420, 0x0421, 0x0422, 0x0423, 0x0416, 0x0412, - /* 0x58 */ 0x042C, 0x0406, 0x0417, 0x0428, 0x0404, 0x0429, 0x0427, 0x0407, - /* 0x60 */ 0x044E, 0x0430, 0x0431, 0x0446, 0x0434, 0x0435, 0x0444, 0x0433, - /* 0x68 */ 0x0445, 0x0438, 0x045D, 0x043A, 0x043B, 0x043C, 0x043D, 0x043E, - /* 0x70 */ 0x043F, 0x044F, 0x0440, 0x0441, 0x0442, 0x0443, 0x0436, 0x0432, - /* 0x78 */ 0x044C, 0x0456, 0x0437, 0x0448, 0x0454, 0x0449, 0x0447, 0x25A0 -}; +static const uint16_t cyrillic_3_g0[64] = { + /* 0x40 */ 0x042E, + 0x0410, + 0x0411, + 0x0426, + 0x0414, + 0x0415, + 0x0424, + 0x0413, + /* 0x48 */ 0x0425, + 0x0418, + 0x040D, + 0x041A, + 0x041B, + 0x041C, + 0x041D, + 0x041E, + /* 0x50 */ 0x041F, + 0x042F, + 0x0420, + 0x0421, + 0x0422, + 0x0423, + 0x0416, + 0x0412, + /* 0x58 */ 0x042C, + 0x0406, + 0x0417, + 0x0428, + 0x0404, + 0x0429, + 0x0427, + 0x0407, + /* 0x60 */ 0x044E, + 0x0430, + 0x0431, + 0x0446, + 0x0434, + 0x0435, + 0x0444, + 0x0433, + /* 0x68 */ 0x0445, + 0x0438, + 0x045D, + 0x043A, + 0x043B, + 0x043C, + 0x043D, + 0x043E, + /* 0x70 */ 0x043F, + 0x044F, + 0x0440, + 0x0441, + 0x0442, + 0x0443, + 0x0436, + 0x0432, + /* 0x78 */ 0x044C, + 0x0456, + 0x0437, + 0x0448, + 0x0454, + 0x0449, + 0x0447, + 0x25A0}; /* * ETS 300 706 Table 41: Cyrillic G2 Supplementary Set */ -static const uint16_t -cyrillic_g2[96] = { - /* 0x20 */ 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x0020, 0x00A5, 0x0023, 0x00A7, - /* 0x28 */ 0x0020, 0x2018, 0x201C, 0x00AB, 0x2190, 0x2191, 0x2192, 0x2193, - /* 0x30 */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00D7, 0x00B5, 0x00B6, 0x00B7, - /* 0x38 */ 0x00F7, 0x2019, 0x201D, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, - /* 0x40 */ 0x0020, 0x02CB, 0x02CA, 0x02C6, 0x02DC, 0x02C9, 0x02D8, 0x02D9, - /* 0x48 */ 0x00A8, 0x002E, 0x02DA, 0x02CF, 0x02CD, 0x02DD, 0x02DB, 0x02C7, - /* 0x50 */ 0x2014, 0x00B9, 0x00AE, 0x00A9, 0x2122, 0x266A, 0x20A0, 0x2030, - /* 0x58 */ 0x0251, 0x0141, 0x0142, 0x00DF, 0x215B, 0x215C, 0x215D, 0x215E, - /* 0x60 */ 0x0044, 0x0045, 0x0046, 0x0047, 0x0049, 0x004A, 0x004B, 0x004C, - /* 0x68 */ 0x004E, 0x0051, 0x0052, 0x0053, 0x0055, 0x0056, 0x0057, 0x005A, - /* 0x70 */ 0x0064, 0x0065, 0x0066, 0x0067, 0x0069, 0x006A, 0x006B, 0x006C, - /* 0x78 */ 0x006E, 0x0071, 0x0072, 0x0073, 0x0075, 0x0076, 0x0077, 0x007A -}; +static const uint16_t cyrillic_g2[96] = { + /* 0x20 */ 0x00A0, + 0x00A1, + 0x00A2, + 0x00A3, + 0x0020, + 0x00A5, + 0x0023, + 0x00A7, + /* 0x28 */ 0x0020, + 0x2018, + 0x201C, + 0x00AB, + 0x2190, + 0x2191, + 0x2192, + 0x2193, + /* 0x30 */ 0x00B0, + 0x00B1, + 0x00B2, + 0x00B3, + 0x00D7, + 0x00B5, + 0x00B6, + 0x00B7, + /* 0x38 */ 0x00F7, + 0x2019, + 0x201D, + 0x00BB, + 0x00BC, + 0x00BD, + 0x00BE, + 0x00BF, + /* 0x40 */ 0x0020, + 0x02CB, + 0x02CA, + 0x02C6, + 0x02DC, + 0x02C9, + 0x02D8, + 0x02D9, + /* 0x48 */ 0x00A8, + 0x002E, + 0x02DA, + 0x02CF, + 0x02CD, + 0x02DD, + 0x02DB, + 0x02C7, + /* 0x50 */ 0x2014, + 0x00B9, + 0x00AE, + 0x00A9, + 0x2122, + 0x266A, + 0x20A0, + 0x2030, + /* 0x58 */ 0x0251, + 0x0141, + 0x0142, + 0x00DF, + 0x215B, + 0x215C, + 0x215D, + 0x215E, + /* 0x60 */ 0x0044, + 0x0045, + 0x0046, + 0x0047, + 0x0049, + 0x004A, + 0x004B, + 0x004C, + /* 0x68 */ 0x004E, + 0x0051, + 0x0052, + 0x0053, + 0x0055, + 0x0056, + 0x0057, + 0x005A, + /* 0x70 */ 0x0064, + 0x0065, + 0x0066, + 0x0067, + 0x0069, + 0x006A, + 0x006B, + 0x006C, + /* 0x78 */ 0x006E, + 0x0071, + 0x0072, + 0x0073, + 0x0075, + 0x0076, + 0x0077, + 0x007A}; /* * ETS 300 706 Table 42: Greek G0 Primary Set */ -static const uint16_t -greek_g0[64] = { - /* 0x40 */ 0x0390, 0x0391, 0x0392, 0x0393, 0x0394, 0x0395, 0x0396, 0x0397, - /* 0x48 */ 0x0398, 0x0399, 0x039A, 0x039B, 0x039C, 0x039D, 0x039E, 0x039F, - /* 0x50 */ 0x03A0, 0x03A1, 0x0374, 0x03A3, 0x03A4, 0x03A5, 0x03A6, 0x03A7, - /* 0x58 */ 0x03A8, 0x03A9, 0x03AA, 0x03AB, 0x03AC, 0x03AD, 0x03AE, 0x03AF, - /* 0x60 */ 0x03B0, 0x03B1, 0x03B2, 0x03B3, 0x03B4, 0x03B5, 0x03B6, 0x03B7, - /* 0x68 */ 0x03B8, 0x03B9, 0x03BA, 0x03BB, 0x03BC, 0x03BD, 0x03BE, 0x03BF, - /* 0x70 */ 0x03C0, 0x03C1, 0x03C2, 0x03C3, 0x03C4, 0x03C5, 0x03C6, 0x03C7, - /* 0x78 */ 0x03C8, 0x03C9, 0x03CA, 0x03CB, 0x03CC, 0x03CD, 0x03CE, 0x25A0 -}; +static const uint16_t greek_g0[64] = { + /* 0x40 */ 0x0390, + 0x0391, + 0x0392, + 0x0393, + 0x0394, + 0x0395, + 0x0396, + 0x0397, + /* 0x48 */ 0x0398, + 0x0399, + 0x039A, + 0x039B, + 0x039C, + 0x039D, + 0x039E, + 0x039F, + /* 0x50 */ 0x03A0, + 0x03A1, + 0x0374, + 0x03A3, + 0x03A4, + 0x03A5, + 0x03A6, + 0x03A7, + /* 0x58 */ 0x03A8, + 0x03A9, + 0x03AA, + 0x03AB, + 0x03AC, + 0x03AD, + 0x03AE, + 0x03AF, + /* 0x60 */ 0x03B0, + 0x03B1, + 0x03B2, + 0x03B3, + 0x03B4, + 0x03B5, + 0x03B6, + 0x03B7, + /* 0x68 */ 0x03B8, + 0x03B9, + 0x03BA, + 0x03BB, + 0x03BC, + 0x03BD, + 0x03BE, + 0x03BF, + /* 0x70 */ 0x03C0, + 0x03C1, + 0x03C2, + 0x03C3, + 0x03C4, + 0x03C5, + 0x03C6, + 0x03C7, + /* 0x78 */ 0x03C8, + 0x03C9, + 0x03CA, + 0x03CB, + 0x03CC, + 0x03CD, + 0x03CE, + 0x25A0}; /* * ETS 300 706 Table 43: Greek G2 Supplementary Set */ -static const uint16_t -greek_g2[96] = { - /* 0x20 */ 0x00A0, 0x0061, 0x0062, 0x00A3, 0x0065, 0x0068, 0x0069, 0x00A7, - /* 0x28 */ 0x003A, 0x2018, 0x201C, 0x006B, 0x2190, 0x2191, 0x2192, 0x2193, - /* 0x30 */ 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x0078, 0x006D, 0x006E, 0x0070, - /* 0x38 */ 0x00F7, 0x2019, 0x201D, 0x0074, 0x00BC, 0x00BD, 0x00BE, 0x0078, - /* 0x40 */ 0x0020, 0x02CB, 0x02CA, 0x02C6, 0x02DC, 0x02C9, 0x02D8, 0x02D9, - /* 0x48 */ 0x00A8, 0x002E, 0x02DA, 0x02CF, 0x02CD, 0x02DD, 0x02DB, 0x02C7, - /* 0x50 */ 0x003F, 0x00B9, 0x00AE, 0x00A9, 0x2122, 0x266A, 0x20A0, 0x2030, - /* 0x58 */ 0x0251, 0x038A, 0x038E, 0x038F, 0x215B, 0x215C, 0x215D, 0x215E, - /* 0x60 */ 0x0043, 0x0044, 0x0046, 0x0047, 0x004A, 0x004C, 0x0051, 0x0052, - /* 0x68 */ 0x0053, 0x0055, 0x0056, 0x0057, 0x0059, 0x005A, 0x0386, 0x0389, - /* 0x70 */ 0x0063, 0x0064, 0x0066, 0x0067, 0x006A, 0x006C, 0x0071, 0x0072, - /* 0x78 */ 0x0073, 0x0075, 0x0076, 0x0077, 0x0079, 0x007A, 0x0388, 0x25A0 -}; +static const uint16_t greek_g2[96] = { + /* 0x20 */ 0x00A0, + 0x0061, + 0x0062, + 0x00A3, + 0x0065, + 0x0068, + 0x0069, + 0x00A7, + /* 0x28 */ 0x003A, + 0x2018, + 0x201C, + 0x006B, + 0x2190, + 0x2191, + 0x2192, + 0x2193, + /* 0x30 */ 0x00B0, + 0x00B1, + 0x00B2, + 0x00B3, + 0x0078, + 0x006D, + 0x006E, + 0x0070, + /* 0x38 */ 0x00F7, + 0x2019, + 0x201D, + 0x0074, + 0x00BC, + 0x00BD, + 0x00BE, + 0x0078, + /* 0x40 */ 0x0020, + 0x02CB, + 0x02CA, + 0x02C6, + 0x02DC, + 0x02C9, + 0x02D8, + 0x02D9, + /* 0x48 */ 0x00A8, + 0x002E, + 0x02DA, + 0x02CF, + 0x02CD, + 0x02DD, + 0x02DB, + 0x02C7, + /* 0x50 */ 0x003F, + 0x00B9, + 0x00AE, + 0x00A9, + 0x2122, + 0x266A, + 0x20A0, + 0x2030, + /* 0x58 */ 0x0251, + 0x038A, + 0x038E, + 0x038F, + 0x215B, + 0x215C, + 0x215D, + 0x215E, + /* 0x60 */ 0x0043, + 0x0044, + 0x0046, + 0x0047, + 0x004A, + 0x004C, + 0x0051, + 0x0052, + /* 0x68 */ 0x0053, + 0x0055, + 0x0056, + 0x0057, + 0x0059, + 0x005A, + 0x0386, + 0x0389, + /* 0x70 */ 0x0063, + 0x0064, + 0x0066, + 0x0067, + 0x006A, + 0x006C, + 0x0071, + 0x0072, + /* 0x78 */ 0x0073, + 0x0075, + 0x0076, + 0x0077, + 0x0079, + 0x007A, + 0x0388, + 0x25A0}; /* * ETS 300 706 Table 44: Arabic G0 Primary Set */ -static const uint16_t -arabic_g0[96] = { - /* 0x20 */ 0x0020, 0x0021, 0x0022, 0x00A3, 0x0024, 0x0025, 0x0000, 0x0000, - /* 0x28 */ 0x0029, 0x0028, 0x002A, 0x002B, 0x060C, 0x002D, 0x002E, 0x002F, - /* 0x30 */ 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, - /* 0x38 */ 0x0038, 0x0039, 0x003A, 0x061B, 0x003E, 0x003D, 0x003C, 0x061F, - /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x50 */ 0x0630, 0x0631, 0x0632, 0x0633, 0x0634, 0x0635, 0x0636, 0x0637, - /* 0x58 */ 0x0638, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0023, - /* 0x60 */ 0x0640, 0x0641, 0x0642, 0x0643, 0x0644, 0x0645, 0x0646, 0x0647, - /* 0x68 */ 0x0648, 0x0649, 0x064A, 0x062B, 0x062D, 0x062C, 0x062E, 0x0000, - /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x25A0 -}; +static const uint16_t arabic_g0[96] = { + /* 0x20 */ 0x0020, + 0x0021, + 0x0022, + 0x00A3, + 0x0024, + 0x0025, + 0x0000, + 0x0000, + /* 0x28 */ 0x0029, + 0x0028, + 0x002A, + 0x002B, + 0x060C, + 0x002D, + 0x002E, + 0x002F, + /* 0x30 */ 0x0030, + 0x0031, + 0x0032, + 0x0033, + 0x0034, + 0x0035, + 0x0036, + 0x0037, + /* 0x38 */ 0x0038, + 0x0039, + 0x003A, + 0x061B, + 0x003E, + 0x003D, + 0x003C, + 0x061F, + /* 0x40 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x48 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x50 */ 0x0630, + 0x0631, + 0x0632, + 0x0633, + 0x0634, + 0x0635, + 0x0636, + 0x0637, + /* 0x58 */ 0x0638, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0023, + /* 0x60 */ 0x0640, + 0x0641, + 0x0642, + 0x0643, + 0x0644, + 0x0645, + 0x0646, + 0x0647, + /* 0x68 */ 0x0648, + 0x0649, + 0x064A, + 0x062B, + 0x062D, + 0x062C, + 0x062E, + 0x0000, + /* 0x70 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x78 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x25A0}; /* * ETS 300 706 Table 45: Arabic G2 Supplementary Set */ -static const uint16_t -arabic_g2[96] = { - /* 0x20 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x28 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x30 */ 0x0660, 0x0661, 0x0662, 0x0663, 0x0664, 0x0665, 0x0666, 0x0667, - /* 0x38 */ 0x0668, 0x0669, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x40 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x48 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x50 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x58 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x60 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x68 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x70 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, - /* 0x78 */ 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 -}; +static const uint16_t arabic_g2[96] = { + /* 0x20 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x28 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x30 */ 0x0660, + 0x0661, + 0x0662, + 0x0663, + 0x0664, + 0x0665, + 0x0666, + 0x0667, + /* 0x38 */ 0x0668, + 0x0669, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x40 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x48 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x50 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x58 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x60 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x68 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x70 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + /* 0x78 */ 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000, + 0x0000}; /* * ETS 300 706 Table 46: Hebrew G0 Primary Set */ -static const uint16_t -hebrew_g0[37] = { - /* 0x5b */ 0x2190, 0x00BD, 0x2192, 0x2191, 0x0023, - /* 0x60 */ 0x05D0, 0x05D1, 0x05D2, 0x05D3, 0x05D4, 0x05D5, 0x05D6, 0x05D7, - /* 0x68 */ 0x05D8, 0x05D9, 0x05DA, 0x05DB, 0x05DC, 0x05DD, 0x05DE, 0x05DF, - /* 0x70 */ 0x05E0, 0x05E1, 0x05E2, 0x05E3, 0x05E4, 0x05E5, 0x05E6, 0x05E7, - /* 0x78 */ 0x05E8, 0x05E9, 0x05EA, 0x20AA, 0x2016, 0x00BE, 0x00F7, 0x25A0 -}; +static const uint16_t hebrew_g0[37] = { + /* 0x5b */ 0x2190, + 0x00BD, + 0x2192, + 0x2191, + 0x0023, + /* 0x60 */ 0x05D0, + 0x05D1, + 0x05D2, + 0x05D3, + 0x05D4, + 0x05D5, + 0x05D6, + 0x05D7, + /* 0x68 */ 0x05D8, + 0x05D9, + 0x05DA, + 0x05DB, + 0x05DC, + 0x05DD, + 0x05DE, + 0x05DF, + /* 0x70 */ 0x05E0, + 0x05E1, + 0x05E2, + 0x05E3, + 0x05E4, + 0x05E5, + 0x05E6, + 0x05E7, + /* 0x78 */ 0x05E8, + 0x05E9, + 0x05EA, + 0x20AA, + 0x2016, + 0x00BE, + 0x00F7, + 0x25A0}; static const uint8_t* COLOR_MAP[8] = { - // black (grey for visibility), red, green, yellow, blue, magenta, cyan, white - (uint8_t*) "", - (uint8_t*) "", - (uint8_t*) "", - (uint8_t*) "", - (uint8_t*) "", - (uint8_t*) "", - (uint8_t*) "", - (uint8_t*) "" -}; -static const uint8_t* CLOSE_FONT = (uint8_t*) ""; + // black (grey for visibility), red, green, yellow, blue, magenta, cyan, white + (uint8_t*)"", + (uint8_t*)"", + (uint8_t*)"", + (uint8_t*)"", + (uint8_t*)"", + (uint8_t*)"", + (uint8_t*)"", + (uint8_t*)""}; +static const uint8_t* CLOSE_FONT = (uint8_t*)""; /** * cs Teletext character set as listed in ETS 300 706 section 15. @@ -494,106 +1521,98 @@ static const uint8_t* CLOSE_FONT = (uint8_t*) ""; * * Translate Teletext character code to Unicode. */ -static uint16_t -teletext_to_ucs2(uint8_t cs, uint8_t ss, uint8_t c) -{ +static uint16_t teletext_to_ucs2(uint8_t cs, uint8_t ss, uint8_t c) { int i; if (c < 0x20 || c > 0x7f) return 0; switch (cs) { - case CHARSET_LATIN_G0: - /* shortcut */ - if (0xF8000019UL & (1 << (c & 31))) { - if (ss > 0) { - assert(ss < 14); - for (i = 0; i < SUBSET_CHARMAP_COUNT; i++) - if (c == teletext_subset[0][i]) - return teletext_subset[ss][i]; + case CHARSET_LATIN_G0: + /* shortcut */ + if (0xF8000019UL & (1 << (c & 31))) { + if (ss > 0) { + assert(ss < 14); + for (i = 0; i < SUBSET_CHARMAP_COUNT; i++) + if (c == teletext_subset[0][i]) + return teletext_subset[ss][i]; + } + if (c == 0x24) + return 0x00A4u; + else if (c == 0x7C) + return 0x00A6u; + else if (c == 0x7F) + return 0x25A0u; } - if (c == 0x24) - return 0x00A4u; - else if (c == 0x7C) - return 0x00A6u; - else if (c == 0x7F) - return 0x25A0u; - } - return c; - - case CHARSET_LATIN_G2: - return latin_g2[c - 0x20]; - - case CHARSET_CYRILLIC_1_G0: - return c < 0x40 ? c : cyrillic_1_g0[c - 0x40]; - - case CHARSET_CYRILLIC_2_G0: - if (c == 0x26) - return 0x044Bu; - else if (c < 0x40) - return c; - else - return cyrillic_2_g0[c - 0x40]; - - case CHARSET_CYRILLIC_3_G0: - if (c == 0x26) - return 0x00EFu; - else if (c < 0x40) return c; - else - return cyrillic_3_g0[c - 0x40]; - - case CHARSET_CYRILLIC_G2: - return cyrillic_g2[c - 0x20]; - - case CHARSET_GREEK_G0: - if (c == 0x3C) - return 0x00ABu; - else if (c == 0x3E) - return 0x00BBu; - else if (c < 0x40) - return c; - else - return greek_g0[c - 0x40]; - - case CHARSET_GREEK_G2: - return greek_g2[c - 0x20]; - case CHARSET_ARABIC_G0: - return arabic_g0[c - 0x20]; - - case CHARSET_ARABIC_G2: - return arabic_g2[c - 0x20]; - - case CHARSET_HEBREW_G0: - return c < 0x5b ? c : hebrew_g0[c - 0x5b]; - - case CHARSET_BLOCK_MOSAIC_G1: - return 0; - - case CHARSET_SMOOTH_MOSAIC_G3: - return 0; - - default: - return 0; + case CHARSET_LATIN_G2: + return latin_g2[c - 0x20]; + + case CHARSET_CYRILLIC_1_G0: + return c < 0x40 ? c : cyrillic_1_g0[c - 0x40]; + + case CHARSET_CYRILLIC_2_G0: + if (c == 0x26) + return 0x044Bu; + else if (c < 0x40) + return c; + else + return cyrillic_2_g0[c - 0x40]; + + case CHARSET_CYRILLIC_3_G0: + if (c == 0x26) + return 0x00EFu; + else if (c < 0x40) + return c; + else + return cyrillic_3_g0[c - 0x40]; + + case CHARSET_CYRILLIC_G2: + return cyrillic_g2[c - 0x20]; + + case CHARSET_GREEK_G0: + if (c == 0x3C) + return 0x00ABu; + else if (c == 0x3E) + return 0x00BBu; + else if (c < 0x40) + return c; + else + return greek_g0[c - 0x40]; + + case CHARSET_GREEK_G2: + return greek_g2[c - 0x20]; + + case CHARSET_ARABIC_G0: + return arabic_g0[c - 0x20]; + + case CHARSET_ARABIC_G2: + return arabic_g2[c - 0x20]; + + case CHARSET_HEBREW_G0: + return c < 0x5b ? c : hebrew_g0[c - 0x5b]; + + case CHARSET_BLOCK_MOSAIC_G1: + return 0; + + case CHARSET_SMOOTH_MOSAIC_G3: + return 0; + + default: + return 0; } } -static inline uint8_t -ham_decode8(uint8_t a) -{ +static inline uint8_t ham_decode8(uint8_t a) { return hamtable[a] & 0xf; } -static uint8_t -ham_decode16(uint8_t *p) -{ +static uint8_t ham_decode16(uint8_t* p) { return (ham_decode8(p[1]) << 4) | ham_decode8(p[0]); } -static uint32_t -ham_decode24(uint8_t *p) -{ +static uint32_t ham_decode24(uint8_t* p) { /* note: no parity checking / correction */ uint32_t r = ((p[0] >> 2) & 1) | ((p[0] & 0xf0) >> 3); r |= (((uint32_t)p[1]) & 0x7f) << 5; @@ -604,19 +1623,17 @@ ham_decode24(uint8_t *p) /** * */ -static time_t -tt_construct_unix_time(uint8_t *buf) -{ - time_t t, r[3], v[3]; - int i; +static time_t tt_construct_unix_time(uint8_t* buf) { + time_t t, r[3], v[3]; + int i; struct tm tm; t = gclk(); localtime_r(&t, &tm); - tm.tm_hour = atoi((char *)buf); - tm.tm_min = atoi((char *)buf + 3); - tm.tm_sec = atoi((char *)buf + 6); + tm.tm_hour = atoi((char*)buf); + tm.tm_min = atoi((char*)buf + 3); + tm.tm_sec = atoi((char*)buf + 6); r[0] = mktime(&tm); tm.tm_mday--; @@ -624,51 +1641,43 @@ tt_construct_unix_time(uint8_t *buf) tm.tm_mday += 2; r[2] = mktime(&tm); - for(i = 0; i < 3; i++) + for (i = 0; i < 3; i++) v[i] = labs(r[i] - t); - - if(v[0] < v[1] && v[0] < v[2]) + + if (v[0] < v[1] && v[0] < v[2]) return r[0]; - if(v[1] < v[2] && v[1] < v[0]) + if (v[1] < v[2] && v[1] < v[0]) return r[1]; return r[2]; } - /** * */ -static int -is_tt_clock(const uint8_t *str) -{ - return - isdigit(str[0]) && isdigit(str[1]) && str[2] == ':' && - isdigit(str[3]) && isdigit(str[4]) && str[5] == ':' && - isdigit(str[6]) && isdigit(str[7]); +static int is_tt_clock(const uint8_t* str) { + return isdigit(str[0]) && isdigit(str[1]) && str[2] == ':' && isdigit(str[3]) && + isdigit(str[4]) && str[5] == ':' && isdigit(str[6]) && isdigit(str[7]); } - /** * */ -static int -update_tt_clock(parser_t *t, const uint8_t *buf) -{ +static int update_tt_clock(parser_t* t, const uint8_t* buf) { uint8_t str[10]; - int i; - time_t ti; + int i; + time_t ti; - for(i = 0; i < 8; i++) + for (i = 0; i < 8; i++) str[i] = buf[i] & 0x7f; str[8] = 0; - if(!is_tt_clock(str)) + if (!is_tt_clock(str)) return 0; ti = tt_construct_unix_time(str); - if(t->prs_tt_clock == ti) + if (t->prs_tt_clock == ti) return 0; t->prs_tt_clock = ti; @@ -676,9 +1685,7 @@ update_tt_clock(parser_t *t, const uint8_t *buf) return 1; } -static uint8_t * -get_cset(uint8_t off) -{ +static uint8_t* get_cset(uint8_t off) { if (off >= ARRAY_SIZE(char_table)) return NULL; if (char_table[off][0] == CHARSET_NONE) @@ -686,14 +1693,12 @@ get_cset(uint8_t off) return char_table[off]; } -static int -extract_subtitle(parser_t *t, parser_es_t *st, tt_mag_t *ttm, int64_t pts) -{ - int i, j, start, off = 0; - int k, current_color, is_font_tag_open, use_color_subs = 1; - uint8_t sub[MAX_SUB_TEXT_SIZE]; +static int extract_subtitle(parser_t* t, parser_es_t* st, tt_mag_t* ttm, int64_t pts) { + int i, j, start, off = 0; + int k, current_color, is_font_tag_open, use_color_subs = 1; + uint8_t sub[MAX_SUB_TEXT_SIZE]; uint8_t *cset, ch; - int is_box = 0; + int is_box = 0; if ((cset = get_cset((ttm->ttm_charset[0] & ~7) + ttm->ttm_national)) == NULL) if ((cset = get_cset(ttm->ttm_charset[0])) == NULL) @@ -701,69 +1706,69 @@ extract_subtitle(parser_t *t, parser_es_t *st, tt_mag_t *ttm, int64_t pts) for (i = 0; i < 23; i++) { is_font_tag_open = 0; - current_color = 7; /* white = default */ - start = off; + current_color = 7; /* white = default */ + start = off; for (j = 0; j < 40; j++) { ch = ttm->ttm_page[40 * i + j]; - switch(ch) { - case 0 ... 7: - if (use_color_subs) { - if (ch != current_color) { - if (is_font_tag_open) { - for (k = 0; k < 7; k++) { - if (off < sizeof(sub) - 1) - sub[off++] = CLOSE_FONT[k]; + switch (ch) { + case 0 ... 7: + if (use_color_subs) { + if (ch != current_color) { + if (is_font_tag_open) { + for (k = 0; k < 7; k++) { + if (off < sizeof(sub) - 1) + sub[off++] = CLOSE_FONT[k]; + } + is_font_tag_open = 0; } - is_font_tag_open = 0; - } - /* no need for font-tag for default-color */ - if (ch != 7) { - for (k = 0; k < 22; k++) { - if (off < sizeof(sub) - 1) - sub[off++] = COLOR_MAP[ch][k]; + /* no need for font-tag for default-color */ + if (ch != 7) { + for (k = 0; k < 22; k++) { + if (off < sizeof(sub) - 1) + sub[off++] = COLOR_MAP[ch][k]; + } + is_font_tag_open = 1; } - is_font_tag_open = 1; + current_color = ch; } - current_color = ch; } - } - break; - - case 0x0a: - is_box = 0; - break; - - case 0x0b: - is_box = 1; - break; - - default: - if (ch >= 0x20 && is_box && (start != off || ch > 0x20)) { - - uint16_t ucs2 = teletext_to_ucs2(cset[0], cset[2], ch); - - /* ucs2 -> utf8 conversion */ - if (ucs2 == 0) { - /* nothing */ - } else if (ucs2 < 0x80) { - if (off < sizeof(sub) - 1) - sub[off++] = ucs2; - } else if (ucs2 < 0x800) { - if (off + 1 < sizeof(sub) - 1) { - sub[off++] = (ucs2 >> 6) | 0xc0; - sub[off++] = (ucs2 & 0x3f) | 0x80; - } - } else { - assert(ucs2 < 0xd800 || ucs2 >= 0xe000); - if (off + 2 < sizeof(sub) - 1) { - sub[off++] = (ucs2 >> 12) | 0xe0; - sub[off++] = ((ucs2 >> 6) & 0x3f) | 0x80; - sub[off++] = (ucs2 & 0x3f) | 0x80; + break; + + case 0x0a: + is_box = 0; + break; + + case 0x0b: + is_box = 1; + break; + + default: + if (ch >= 0x20 && is_box && (start != off || ch > 0x20)) { + + uint16_t ucs2 = teletext_to_ucs2(cset[0], cset[2], ch); + + /* ucs2 -> utf8 conversion */ + if (ucs2 == 0) { + /* nothing */ + } else if (ucs2 < 0x80) { + if (off < sizeof(sub) - 1) + sub[off++] = ucs2; + } else if (ucs2 < 0x800) { + if (off + 1 < sizeof(sub) - 1) { + sub[off++] = (ucs2 >> 6) | 0xc0; + sub[off++] = (ucs2 & 0x3f) | 0x80; + } + } else { + assert(ucs2 < 0xd800 || ucs2 >= 0xe000); + if (off + 2 < sizeof(sub) - 1) { + sub[off++] = (ucs2 >> 12) | 0xe0; + sub[off++] = ((ucs2 >> 6) & 0x3f) | 0x80; + sub[off++] = (ucs2 & 0x3f) | 0x80; + } } } - } } } if (use_color_subs && is_font_tag_open) { @@ -773,12 +1778,12 @@ extract_subtitle(parser_t *t, parser_es_t *st, tt_mag_t *ttm, int64_t pts) } is_font_tag_open = 0; } - if(start != off && off < sizeof(sub) - 1) + if (start != off && off < sizeof(sub) - 1) sub[off++] = '\n'; } /* Avoid multiple blank subtitles */ - if(off == 0 && st->es_blank) + if (off == 0 && st->es_blank) return 0; st->es_blank = !off; @@ -786,13 +1791,13 @@ extract_subtitle(parser_t *t, parser_es_t *st, tt_mag_t *ttm, int64_t pts) sub[off++] = 0; /* Check for a duplicate */ - if (strcmp((char *)ttm->ttm_last_sub_text, (char *)sub) == 0) + if (strcmp((char*)ttm->ttm_last_sub_text, (char*)sub) == 0) return 0; ttm->ttm_last_sub_pts = pts; - strcpy((char *)ttm->ttm_last_sub_text, (char *)sub); + strcpy((char*)ttm->ttm_last_sub_text, (char*)sub); - th_pkt_t *pkt = pkt_alloc(st->es_type, sub, off, pts, pts, pts); + th_pkt_t* pkt = pkt_alloc(st->es_type, sub, off, pts, pts, pts); pkt->pkt_componentindex = st->es_index; streaming_target_deliver2(t->prs_output, streaming_msg_create_pkt(pkt)); @@ -833,21 +1838,18 @@ dump_page(tt_mag_t *ttm) } #endif +static void tt_subtitle_deliver(parser_t* t, parser_es_t* parent, tt_mag_t* ttm) { + elementary_stream_t* es; + parser_es_t* st; -static void -tt_subtitle_deliver(parser_t *t, parser_es_t *parent, tt_mag_t *ttm) -{ - elementary_stream_t *es; - parser_es_t *st; - - if(ttm->ttm_current_pts == PTS_UNSET) + if (ttm->ttm_current_pts == PTS_UNSET) return; - TAILQ_FOREACH(es, &t->prs_components.set_filter, es_filter_link) { - st = (parser_es_t *)es; - if (st->es_type != SCT_TEXTSUB) continue; - if (parent->es_pid == st->es_parent_pid && - ttm->ttm_curpage == st->es_pid - PID_TELETEXT_BASE) { + TAILQ_FOREACH (es, &t->prs_components.set_filter, es_filter_link) { + st = (parser_es_t*)es; + if (st->es_type != SCT_TEXTSUB) + continue; + if (parent->es_pid == st->es_parent_pid && ttm->ttm_curpage == st->es_pid - PID_TELETEXT_BASE) { if (extract_subtitle(t, st, ttm, ttm->ttm_current_pts)) ttm->ttm_current_pts++; // Avoid duplicate (non-monotonic) PTS } @@ -857,16 +1859,14 @@ tt_subtitle_deliver(parser_t *t, parser_es_t *parent, tt_mag_t *ttm) /** * */ -static void -tt_decode_line(parser_t *t, parser_es_t *st, uint8_t *buf) -{ - uint8_t mpag, line, s12, c; - int page, magidx, i; - tt_mag_t *ttm; - tt_private_t *ttp; - uint32_t trip1, trip2; - - if(st->es_priv == NULL) { +static void tt_decode_line(parser_t* t, parser_es_t* st, uint8_t* buf) { + uint8_t mpag, line, s12, c; + int page, magidx, i; + tt_mag_t* ttm; + tt_private_t* ttp; + uint32_t trip1, trip2; + + if (st->es_priv == NULL) { /* Allocate privdata for reassembly */ ttp = st->es_priv = calloc(1, sizeof(tt_private_t)); } else { @@ -879,92 +1879,86 @@ tt_decode_line(parser_t *t, parser_es_t *st, uint8_t *buf) line = mpag >> 3; - switch(line) { - case 0: - if(ttm->ttm_curpage != 0) { + switch (line) { + case 0: + if (ttm->ttm_curpage != 0) { - tt_subtitle_deliver(t, st, ttm); + tt_subtitle_deliver(t, st, ttm); - if(ttm->ttm_curpage == 192) - teletext_rundown_copy(ttp, ttm); + if (ttm->ttm_curpage == 192) + teletext_rundown_copy(ttp, ttm); - memset(ttm->ttm_page, ' ', 23 * 40); - ttm->ttm_curpage = 0; - } + memset(ttm->ttm_page, ' ', 23 * 40); + ttm->ttm_curpage = 0; + } - if((page = ham_decode16(buf + 2)) == 0xff) - return; + if ((page = ham_decode16(buf + 2)) == 0xff) + return; - /* The page is BDC encoded, mag 0 is displayed as page 800+ */ - page = (magidx ?: 8) * 100 + (page >> 4) * 10 + (page & 0xf); + /* The page is BDC encoded, mag 0 is displayed as page 800+ */ + page = (magidx ?: 8) * 100 + (page >> 4) * 10 + (page & 0xf); - ttm->ttm_curpage = page; + ttm->ttm_curpage = page; - s12 = ham_decode16(buf + 4); - c = ham_decode16(buf + 8); + s12 = ham_decode16(buf + 4); + c = ham_decode16(buf + 8); - /* The national bits are reversed in specification, Table 32 */ - ttm->ttm_national = ((c >> 7) & 1) | - ((c >> 5) & 2) | - ((c >> 3) & 4); + /* The national bits are reversed in specification, Table 32 */ + ttm->ttm_national = ((c >> 7) & 1) | ((c >> 5) & 2) | ((c >> 3) & 4); - if(s12 & 0x80) { - /* Erase page */ - memset(ttm->ttm_page, ' ', 23 * 40); - } + if (s12 & 0x80) { + /* Erase page */ + memset(ttm->ttm_page, ' ', 23 * 40); + } - if(update_tt_clock(t, buf + 34)) - teletext_rundown_scan(t, ttp); + if (update_tt_clock(t, buf + 34)) + teletext_rundown_scan(t, ttp); - ttm->ttm_current_pts = t->prs_current_pcr + (int64_t)st->es_service->s_pts_shift * 900; - break; + ttm->ttm_current_pts = t->prs_current_pcr + (int64_t)st->es_service->s_pts_shift * 900; + break; - case 1 ... 23: - for(i = 0; i < 40; i++) { - c = buf[i + 2] & 0x7f; - ttm->ttm_page[i + 40 * (line - 1)] = c; - } - break; - - case 28: - case 29: - if (ham_decode8(buf[2]) != 0) break; /* designation must be 0 */ - trip1 = ham_decode24(buf + 3); - trip2 = ham_decode24(buf + 6); - /* extract the character set designation and national option selection bits */ - ttm->ttm_charset[0] = (trip1 >> 7) & 0x7f; - ttm->ttm_charset[1] = (trip1 >> 14) | ((trip2 & 7) << 4); - break; - - default: - break; + case 1 ... 23: + for (i = 0; i < 40; i++) { + c = buf[i + 2] & 0x7f; + ttm->ttm_page[i + 40 * (line - 1)] = c; + } + break; + + case 28: + case 29: + if (ham_decode8(buf[2]) != 0) + break; /* designation must be 0 */ + trip1 = ham_decode24(buf + 3); + trip2 = ham_decode24(buf + 6); + /* extract the character set designation and national option selection bits */ + ttm->ttm_charset[0] = (trip1 >> 7) & 0x7f; + ttm->ttm_charset[1] = (trip1 >> 14) | ((trip2 & 7) << 4); + break; + + default: + break; } } - /** * */ -void -teletext_input - (parser_t *t, parser_es_t *st, const uint8_t *data, int len) -{ - int j; +void teletext_input(parser_t* t, parser_es_t* st, const uint8_t* data, int len) { + int j; uint8_t buf[42]; - data++; len--; /* first byte: 0x10 ? */ + data++; + len--; /* first byte: 0x10 ? */ for (; len >= 46; data += 46, len -= 46) { if (*data == 2 || *data == 3) { - for(j = 0; j < 42; j++) - buf[j] = bitreverse(data[4 + j]); + for (j = 0; j < 42; j++) + buf[j] = bitreverse(data[4 + j]); tt_decode_line(t, st, buf); } - } + } } - - /** * Swedish TV4 rundown dump (page 192) * @@ -994,79 +1988,68 @@ TV4 | 54 56 34 | 20 20 20 */ - -static int -tt_time_to_len(const uint8_t *buf) -{ - int l; +static int tt_time_to_len(const uint8_t* buf) { + int l; char str[10]; - memcpy(str, buf, 8); str[2] = 0; str[5] = 0; str[8] = 0; - + l = atoi(str + 0) * 3600 + atoi(str + 3) * 60 + atoi(str + 6); return l; } /* - * Decode the Swedish TV4 teletext rundown page to figure out if we are + * Decode the Swedish TV4 teletext rundown page to figure out if we are * currently in a commercial break */ -static void -teletext_rundown_copy(tt_private_t *ttp, tt_mag_t *ttm) -{ +static void teletext_rundown_copy(tt_private_t* ttp, tt_mag_t* ttm) { /* Sanity check */ - if(memcmp((char *)ttm->ttm_page + 2, "Starttid", strlen("Starttid")) || - memcmp((char *)ttm->ttm_page + 11, "Titel", strlen("Titel")) || - memcmp((char *)ttm->ttm_page + 21 * 40, "TV4", strlen("TV4"))) + if (memcmp((char*)ttm->ttm_page + 2, "Starttid", strlen("Starttid")) || + memcmp((char*)ttm->ttm_page + 11, "Titel", strlen("Titel")) || + memcmp((char*)ttm->ttm_page + 21 * 40, "TV4", strlen("TV4"))) return; - + memcpy(ttp->ttp_rundown, ttm->ttm_page, 23 * 40); ttp->ttp_rundown_valid = 1; } - -static void -teletext_rundown_scan(parser_t *prs, tt_private_t *ttp) -{ - int i; - uint8_t *l; - mpegts_service_t *t; - time_t now = prs->prs_tt_clock, start, stop; +static void teletext_rundown_scan(parser_t* prs, tt_private_t* ttp) { + int i; + uint8_t* l; + mpegts_service_t* t; + time_t now = prs->prs_tt_clock, start, stop; commercial_advice_t ca; - if(ttp->ttp_rundown_valid == 0) + if (ttp->ttp_rundown_valid == 0) return; - if(TAILQ_EMPTY(&prs->prs_components.set_filter)) + if (TAILQ_EMPTY(&prs->prs_components.set_filter)) return; - t = (mpegts_service_t *)prs->prs_service; - if(t == NULL) + t = (mpegts_service_t*)prs->prs_service; + if (t == NULL) return; - if(t->s_dvb_svcname && - strcmp("TV4", t->s_dvb_svcname) && - strcmp("TV4 HD", t->s_dvb_svcname)) + if (t->s_dvb_svcname && strcmp("TV4", t->s_dvb_svcname) && strcmp("TV4 HD", t->s_dvb_svcname)) return; - for(i = 0; i < 23; i++) { + for (i = 0; i < 23; i++) { l = ttp->ttp_rundown + 40 * i; - if((l[1] & 0xf0) != 0x00 || !is_tt_clock(l + 32) || !is_tt_clock(l + 2)) + if ((l[1] & 0xf0) != 0x00 || !is_tt_clock(l + 32) || !is_tt_clock(l + 2)) continue; - - if(!memcmp(l + 11, "Nyhetspuff", strlen("Nyhetspuff"))) + + if (!memcmp(l + 11, "Nyhetspuff", strlen("Nyhetspuff"))) ca = COMMERCIAL_YES; else ca = (l[1] & 0xf) == 7 ? COMMERCIAL_NO : COMMERCIAL_YES; start = tt_construct_unix_time(l + 2); stop = start + tt_time_to_len(l + 32); - - if(start <= now && stop > now) + + if (start <= now && stop > now) prs->prs_tt_commercial_advice = ca; } } diff --git a/src/parsers/parser_teletext.h b/src/parsers/parser_teletext.h index 2f44b386d..540f9cc95 100644 --- a/src/parsers/parser_teletext.h +++ b/src/parsers/parser_teletext.h @@ -21,6 +21,6 @@ #define PID_TELETEXT_BASE 0x2000 -void teletext_input(parser_t *t, parser_es_t *st, const uint8_t *data, int len); +void teletext_input(parser_t* t, parser_es_t* st, const uint8_t* data, int len); #endif /* TELETEXT_H */ diff --git a/src/parsers/parsers.c b/src/parsers/parsers.c index 7c20d01d2..2c47b0dae 100644 --- a/src/parsers/parsers.c +++ b/src/parsers/parsers.c @@ -38,41 +38,35 @@ /* backlog special mask */ #define PTS_BACKLOG (PTS_MASK + 1) -static inline int -is_ssc(uint32_t sc) -{ +static inline int is_ssc(uint32_t sc) { return (sc & ~0x0f) == 0x1e0; } -static inline int -pts_is_backlog(int64_t pts) -{ +static inline int pts_is_backlog(int64_t pts) { return pts != PTS_UNSET && (pts & PTS_BACKLOG) != 0; } -static inline int64_t -pts_no_backlog(int64_t pts) -{ +static inline int64_t pts_no_backlog(int64_t pts) { return pts_is_backlog(pts) ? (pts & ~PTS_BACKLOG) : pts; } -typedef int (packet_parser_t)(parser_t *t, parser_es_t *st, size_t len, - uint32_t next_startcode, int sc_offset); +typedef int(packet_parser_t)(parser_t* t, + parser_es_t* st, + size_t len, + uint32_t next_startcode, + int sc_offset); -typedef void (aparser_t)(parser_t *t, parser_es_t *st, th_pkt_t *pkt); +typedef void(aparser_t)(parser_t* t, parser_es_t* st, th_pkt_t* pkt); -static void parser_deliver(parser_t *t, parser_es_t *st, th_pkt_t *pkt); +static void parser_deliver(parser_t* t, parser_es_t* st, th_pkt_t* pkt); /** * */ -static th_pkt_t * -parser_error_packet(parser_t *t, parser_es_t *st, int error) -{ - th_pkt_t *pkt; +static th_pkt_t* parser_error_packet(parser_t* t, parser_es_t* st, int error) { + th_pkt_t* pkt; - pkt = pkt_alloc(st->es_type, NULL, 0, - PTS_UNSET, PTS_UNSET, t->prs_current_pcr); + pkt = pkt_alloc(st->es_type, NULL, 0, PTS_UNSET, PTS_UNSET, t->prs_current_pcr); pkt->pkt_err = error; return pkt; } @@ -80,10 +74,8 @@ parser_error_packet(parser_t *t, parser_es_t *st, int error) /** * Deliver errors */ -static void -parser_deliver_error(parser_t *t, parser_es_t *st) -{ - th_pkt_t *pkt; +static void parser_deliver_error(parser_t* t, parser_es_t* st) { + th_pkt_t* pkt; if (!st->es_buf.sb_err) return; @@ -92,26 +84,20 @@ parser_deliver_error(parser_t *t, parser_es_t *st) st->es_buf.sb_err = 0; } - - /** * prs_rstlog */ -static void -parser_rstlog(parser_t *t, th_pkt_t *pkt) -{ - streaming_message_t *sm = streaming_msg_create_pkt(pkt); - streaming_message_t *clone = streaming_msg_clone(sm); +static void parser_rstlog(parser_t* t, th_pkt_t* pkt) { + streaming_message_t* sm = streaming_msg_create_pkt(pkt); + streaming_message_t* clone = streaming_msg_clone(sm); streaming_msg_free(sm); - TAILQ_INSERT_TAIL (&t->prs_rstlog, clone, sm_link); + TAILQ_INSERT_TAIL(&t->prs_rstlog, clone, sm_link); } /** * */ -static void -parser_deliver(parser_t *t, parser_es_t *st, th_pkt_t *pkt) -{ +static void parser_deliver(parser_t* t, parser_es_t* st, th_pkt_t* pkt) { int64_t d, diff; assert(pkt->pkt_type == st->es_type); @@ -125,13 +111,15 @@ parser_deliver(parser_t *t, parser_es_t *st, th_pkt_t *pkt) goto deliver; } - diff = st->es_type == SCT_DVBSUB ? 8*90000 : 6*90000; - d = pts_diff(pkt->pkt_pcr, (pkt->pkt_dts + 30000) & PTS_MASK); + diff = st->es_type == SCT_DVBSUB ? 8 * 90000 : 6 * 90000; + d = pts_diff(pkt->pkt_pcr, (pkt->pkt_dts + 30000) & PTS_MASK); if (d > diff || d == PTS_UNSET) { if (d != PTS_UNSET && tvhlog_limit(&st->es_pcr_log, 2)) - tvhwarn(LS_PARSER, "%s: DTS and PCR diff is very big (%"PRId64")", - st->es_nicename, pts_diff(pkt->pkt_pcr, pkt->pkt_pts)); + tvhwarn(LS_PARSER, + "%s: DTS and PCR diff is very big (%" PRId64 ")", + st->es_nicename, + pts_diff(pkt->pkt_pcr, pkt->pkt_pts)); pkt_trace(LS_PARSER, pkt, "pcr drop"); pkt_ref_dec(pkt); pkt = parser_error_packet(t, st, 1); @@ -147,7 +135,7 @@ deliver: } /* Forward packet */ - if(atomic_get(&st->es_service->s_pending_restart) == 1) { + if (atomic_get(&st->es_service->s_pending_restart) == 1) { /* Queue pkt to prs_rstlog if pending restart */ pkt_trace(LS_PARSER, pkt, "deliver to rstlog"); parser_rstlog(t, pkt); @@ -158,23 +146,20 @@ deliver: /* Decrease our own reference to the packet */ pkt_ref_dec(pkt); - } /** * Do backlog (fix DTS & PTS and reparse slices - frame type, field etc.) */ -static void -parser_backlog(parser_t *t, parser_es_t *st, th_pkt_t *pkt) -{ - streaming_message_t *sm = streaming_msg_create_pkt(pkt); +static void parser_backlog(parser_t* t, parser_es_t* st, th_pkt_t* pkt) { + streaming_message_t* sm = streaming_msg_create_pkt(pkt); TAILQ_INSERT_TAIL(&st->es_backlog, sm, sm_link); pkt_ref_dec(pkt); /* streaming_msg_create_pkt increses ref counter */ #if ENABLE_TRACE if (tvhtrace_enabled()) { - int64_t dts = pkt->pkt_dts; - int64_t pts = pkt->pkt_pts; + int64_t dts = pkt->pkt_dts; + int64_t pts = pkt->pkt_pts; pkt->pkt_dts = pts_no_backlog(dts); pkt->pkt_pts = pts_no_backlog(pts); pkt_trace(LS_PARSER, pkt, "backlog"); @@ -184,23 +169,22 @@ parser_backlog(parser_t *t, parser_es_t *st, th_pkt_t *pkt) #endif } -static void -parser_do_backlog(parser_t *t, parser_es_t *st, - void (*pkt_cb)(parser_t *t, parser_es_t *st, th_pkt_t *pkt), - pktbuf_t *meta) -{ - streaming_message_t *sm; - int64_t prevdts = PTS_UNSET, absdts = PTS_UNSET; - int64_t prevpts = PTS_UNSET, abspts = PTS_UNSET; - th_pkt_t *pkt, *npkt; - size_t metalen; +static void parser_do_backlog(parser_t* t, + parser_es_t* st, + void (*pkt_cb)(parser_t* t, parser_es_t* st, th_pkt_t* pkt), + pktbuf_t* meta) { + streaming_message_t* sm; + int64_t prevdts = PTS_UNSET, absdts = PTS_UNSET; + int64_t prevpts = PTS_UNSET, abspts = PTS_UNSET; + th_pkt_t * pkt, *npkt; + size_t metalen; tvhtrace(LS_PARSER, - "pkt bcklog %2d %-12s - backlog flush start - (meta %ld)", - st->es_index, - streaming_component_type2txt(st->es_type), - meta ? (long)pktbuf_len(meta) : -1); - TAILQ_FOREACH(sm, &st->es_backlog, sm_link) { + "pkt bcklog %2d %-12s - backlog flush start - (meta %ld)", + st->es_index, + streaming_component_type2txt(st->es_type), + meta ? (long)pktbuf_len(meta) : -1); + TAILQ_FOREACH (sm, &st->es_backlog, sm_link) { pkt = sm->sm_data; if (pkt->pkt_meta) { meta = pkt->pkt_meta; @@ -230,11 +214,12 @@ parser_do_backlog(parser_t *t, parser_es_t *st, /* insert the metadata into payload of the first packet, too */ npkt = pkt_copy_shallow(pkt); pktbuf_ref_dec(npkt->pkt_payload); - metalen = pktbuf_len(meta); + metalen = pktbuf_len(meta); npkt->pkt_payload = pktbuf_alloc(NULL, metalen + pktbuf_len(pkt->pkt_payload)); memcpy(pktbuf_ptr(npkt->pkt_payload), pktbuf_ptr(meta), metalen); memcpy(pktbuf_ptr(npkt->pkt_payload) + metalen, - pktbuf_ptr(pkt->pkt_payload), pktbuf_len(pkt->pkt_payload)); + pktbuf_ptr(pkt->pkt_payload), + pktbuf_len(pkt->pkt_payload)); npkt->pkt_payload->pb_err = pkt->pkt_payload->pb_err + meta->pb_err; pkt_ref_dec(pkt); pkt = npkt; @@ -267,23 +252,19 @@ parser_do_backlog(parser_t *t, parser_es_t *st, streaming_msg_free(sm); } tvhtrace(LS_PARSER, - "pkt bcklog %2d %-12s - backlog flush end -", - st->es_index, - streaming_component_type2txt(st->es_type)); + "pkt bcklog %2d %-12s - backlog flush end -", + st->es_index, + streaming_component_type2txt(st->es_type)); } - /** * PES header parser * * Extract DTS and PTS and update current values in stream */ -static int -parse_pes_header(parser_t *t, parser_es_t *st, - const uint8_t *buf, size_t len) -{ +static int parse_pes_header(parser_t* t, parser_es_t* st, const uint8_t* buf, size_t len) { int64_t dts, pts, d, d2; - int hdr, flags, hlen; + int hdr, flags, hlen; if (len < 3) return -1; @@ -291,21 +272,21 @@ parse_pes_header(parser_t *t, parser_es_t *st, hdr = buf[0]; flags = buf[1]; hlen = buf[2]; - buf += 3; - len -= 3; + buf += 3; + len -= 3; - if(len < hlen || (hdr & 0xc0) != 0x80) + if (len < hlen || (hdr & 0xc0) != 0x80) goto err; - if((flags & 0xc0) == 0xc0) { - if(hlen < 10) + if ((flags & 0xc0) == 0xc0) { + if (hlen < 10) goto err; pts = getpts(buf); dts = getpts(buf + 5); d = (pts - dts) & PTS_MASK; - if(d > 180000) { + if (d > 180000) { /* More than two seconds of PTS/DTS delta, probably corrupt */ if (st->es_curpts != PTS_UNSET && st->es_frame_duration > 10) { /* try to do a recovery for this: @@ -325,16 +306,16 @@ parse_pes_header(parser_t *t, parser_es_t *st, pts = dts = PTS_UNSET; } - } else if((flags & 0xc0) == 0x80) { - if(hlen < 5) + } else if ((flags & 0xc0) == 0x80) { + if (hlen < 5) goto err; dts = pts = getpts(buf); } else return hlen + 3; - cont: - if(st->es_buf.sb_err) { +cont: + if (st->es_buf.sb_err) { st->es_curdts = PTS_UNSET; st->es_curpts = PTS_UNSET; } else { @@ -343,12 +324,11 @@ parse_pes_header(parser_t *t, parser_es_t *st, } return hlen + 3; - err: +err: st->es_curdts = PTS_UNSET; st->es_curpts = PTS_UNSET; if (tvhlog_limit(&st->es_pes_log, 10)) - tvhwarn(LS_TS, "%s Corrupted PES header (errors %zi)", - st->es_nicename, st->es_pes_log.count); + tvhwarn(LS_TS, "%s Corrupted PES header (errors %zi)", st->es_nicename, st->es_pes_log.count); return -1; } @@ -358,36 +338,42 @@ parse_pes_header(parser_t *t, parser_es_t *st, * We scan for startcodes a'la 0x000001xx and let a specific parser * derive further information. */ -static void -parse_pes(parser_t *t, parser_es_t *st, const uint8_t *data, int len, - int start, packet_parser_t *vp) -{ +static void parse_pes(parser_t* t, + parser_es_t* st, + const uint8_t* data, + int len, + int start, + packet_parser_t* vp) { uint_fast32_t sc = st->es_startcond; - uint16_t plen; - int i, j, r, hlen, tmp, off; + uint16_t plen; + int i, j, r, hlen, tmp, off; if (start) { st->es_parser_state = 1; if (data[0] != 0 && data[1] != 0 && data[2] != 1) if (tvhlog_limit(&st->es_pes_log, 10)) - tvhwarn(LS_TS, "%s: Invalid start code %02x:%02x:%02x", - st->es_nicename, data[0], data[1], data[2]); + tvhwarn(LS_TS, + "%s: Invalid start code %02x:%02x:%02x", + st->es_nicename, + data[0], + data[1], + data[2]); st->es_incomplete = 0; if (st->es_header_mode) { - st->es_buf.sb_ptr = st->es_header_offset; + st->es_buf.sb_ptr = st->es_header_offset; st->es_header_mode = 0; } } - if(st->es_parser_state == 0) + if (st->es_parser_state == 0) return; - for(i = 0; i < len; ) { + for (i = 0; i < len;) { - if(st->es_header_mode) { - r = len - i; + if (st->es_header_mode) { + r = len - i; off = st->es_header_offset; - j = st->es_buf.sb_ptr - off; + j = st->es_buf.sb_ptr - off; if (j < 5) { tmp = MIN(r, 5 - j); sbuf_append(&st->es_buf, data + i, tmp); @@ -398,28 +384,27 @@ parse_pes(parser_t *t, parser_es_t *st, const uint8_t *data, int len, if (j < 5) break; - plen = st->es_buf.sb_data[off] << 8 | st->es_buf.sb_data[off+1]; + plen = st->es_buf.sb_data[off] << 8 | st->es_buf.sb_data[off + 1]; st->es_incomplete = plen >= 0xffdf; - hlen = st->es_buf.sb_data[off+4]; + hlen = st->es_buf.sb_data[off + 4]; - if(j < hlen + 5) { + if (j < hlen + 5) { tmp = MIN(r, hlen); sbuf_append(&st->es_buf, data + i, tmp); j += tmp; r -= tmp; i += tmp; } - if(j < hlen + 5) + if (j < hlen + 5) break; - + parse_pes_header(t, st, st->es_buf.sb_data + off + 2, hlen + 3); st->es_header_mode = 0; - st->es_buf.sb_ptr = off; - if(off > 2) - sc = st->es_buf.sb_data[off-3] << 16 | - st->es_buf.sb_data[off-2] << 8 | - st->es_buf.sb_data[off-1]; + st->es_buf.sb_ptr = off; + if (off > 2) + sc = st->es_buf.sb_data[off - 3] << 16 | st->es_buf.sb_data[off - 2] << 8 | + st->es_buf.sb_data[off - 1]; continue; } @@ -428,38 +413,38 @@ parse_pes(parser_t *t, parser_es_t *st, const uint8_t *data, int len, j = i; do { sc = (sc << 8) | data[i++]; - if((sc & 0xffffff00) == 0x00000100) + if ((sc & 0xffffff00) == 0x00000100) goto found; } while (i < len); sbuf_append(&st->es_buf, data + j, len - j); break; -found: + found: sbuf_append(&st->es_buf, data + j, i - j); - if(sc == 0x100 && (len-i)>2) { - if (data[0] == 0 && data[i+1] == 0x01 && data[i+2] == 0xe0) + if (sc == 0x100 && (len - i) > 2) { + if (data[0] == 0 && data[i + 1] == 0x01 && data[i + 2] == 0xe0) continue; } r = st->es_buf.sb_ptr - st->es_startcode_offset - 4; - if(r > 0 && st->es_startcode != 0) { + if (r > 0 && st->es_startcode != 0) { r = vp(t, st, r, sc, st->es_startcode_offset); - - if(r == PARSER_SKIP) + + if (r == PARSER_SKIP) continue; - if(r == PARSER_HEADER) { + if (r == PARSER_HEADER) { st->es_buf.sb_ptr -= 4; - st->es_header_mode = 1; + st->es_header_mode = 1; st->es_header_offset = st->es_buf.sb_ptr; - sc = -1; + sc = -1; continue; } } else r = PARSER_RESET; - if(r == PARSER_DROP) { + if (r == PARSER_DROP) { assert(st->es_buf.sb_data != NULL); @@ -470,7 +455,7 @@ found: } else /* APPEND or RESET */ { - if(r == PARSER_RESET) { + if (r == PARSER_RESET) { /* Reset packet parser upon length error or if parser tells us so */ parser_deliver_error(t, st); @@ -478,35 +463,32 @@ found: sbuf_put_be32(&st->es_buf, sc); } assert(st->es_buf.sb_data != NULL); - st->es_startcode = sc; + st->es_startcode = sc; st->es_startcode_offset = st->es_buf.sb_ptr - 4; - } } - st->es_startcond = sc; + st->es_startcond = sc; } /** * */ static int -depacketize(parser_t *t, parser_es_t *st, size_t len, - uint32_t next_startcode, int sc_offset) -{ - const uint8_t *buf = st->es_buf.sb_data + sc_offset; - uint32_t sc = st->es_startcode; - int hlen, plen; +depacketize(parser_t* t, parser_es_t* st, size_t len, uint32_t next_startcode, int sc_offset) { + const uint8_t* buf = st->es_buf.sb_data + sc_offset; + uint32_t sc = st->es_startcode; + int hlen, plen; - if((sc != 0x1bd && (sc & ~0x1f) != 0x1c0) || len < 9) + if ((sc != 0x1bd && (sc & ~0x1f) != 0x1c0) || len < 9) return PARSER_RESET; plen = (buf[4] << 8) | buf[5]; - if(plen + 6 > len) + if (plen + 6 > len) return PARSER_SKIP; - if(plen + 6 < len) + if (plen + 6 < len) return PARSER_RESET; buf += 6; @@ -514,7 +496,7 @@ depacketize(parser_t *t, parser_es_t *st, size_t len, hlen = parse_pes_header(t, st, buf, len); - if(hlen < 0) + if (hlen < 0) return PARSER_RESET; buf += hlen; @@ -529,89 +511,85 @@ depacketize(parser_t *t, parser_es_t *st, size_t len, /** * */ -static void -makeapkt(parser_t *t, parser_es_t *st, const void *buf, - int len, int64_t dts, int duration, int channels, int sri) -{ - th_pkt_t *pkt = pkt_alloc(st->es_type, buf, len, dts, dts, t->prs_current_pcr); +static void makeapkt(parser_t* t, + parser_es_t* st, + const void* buf, + int len, + int64_t dts, + int duration, + int channels, + int sri) { + th_pkt_t* pkt = pkt_alloc(st->es_type, buf, len, dts, dts, t->prs_current_pcr); pkt->pkt_commercial = t->prs_tt_commercial_advice; - pkt->pkt_duration = duration; + pkt->pkt_duration = duration; pkt->a.pkt_keyframe = 1; pkt->a.pkt_channels = channels; - pkt->a.pkt_sri = sri; - pkt->pkt_err = st->es_buf_a.sb_err; + pkt->a.pkt_sri = sri; + pkt->pkt_err = st->es_buf_a.sb_err; st->es_buf_a.sb_err = 0; parser_deliver(t, st, pkt); - st->es_curdts = PTS_UNSET; + st->es_curdts = PTS_UNSET; st->es_nextdts = dts + duration; } - /** * Parse AAC MP4A */ -static const int aac_sample_rates[16] = -{ - 96000, - 88200, - 64000, - 48000, - 44100, - 32000, - 24000, - 22050, - 16000, - 12000, - 11025, - 8000, - 7350, - 0, - 0, - 0 -}; +static const int aac_sample_rates[16] = {96000, + 88200, + 64000, + 48000, + 44100, + 32000, + 24000, + 22050, + 16000, + 12000, + 11025, + 8000, + 7350, + 0, + 0, + 0}; /** * Inspect ADTS header */ -static int -mp4a_valid_frame(const uint8_t *buf) -{ +static int mp4a_valid_frame(const uint8_t* buf) { return (buf[0] == 0xff) && ((buf[1] & 0xf6) == 0xf0); } -static void parse_mp4a_data(parser_t *t, parser_es_t *st, - int skip_next_check) -{ - int i, len; - const uint8_t *buf; +static void parse_mp4a_data(parser_t* t, parser_es_t* st, int skip_next_check) { + int i, len; + const uint8_t* buf; - again: +again: buf = st->es_buf_a.sb_data; len = st->es_buf_a.sb_ptr; - for(i = 0; i < len - 6; i++) { - const uint8_t *p = buf + i; + for (i = 0; i < len - 6; i++) { + const uint8_t* p = buf + i; - if(mp4a_valid_frame(p)) { + if (mp4a_valid_frame(p)) { int fsize = ((p[3] & 0x03) << 11) | (p[4] << 3) | ((p[5] & 0xe0) >> 5); int sr_index = (p[2] & 0x3c) >> 2; int sr = aac_sample_rates[sr_index]; - if(sr && fsize) { - int duration = 90000 * 1024 / sr; - int64_t dts = st->es_curdts; - int sri = rate_to_sri(sr); + if (sr && fsize) { + int duration = 90000 * 1024 / sr; + int64_t dts = st->es_curdts; + int sri = rate_to_sri(sr); - if(dts == PTS_UNSET) + if (dts == PTS_UNSET) dts = st->es_nextdts; - if(dts != PTS_UNSET && len >= i + fsize + (skip_next_check ? 0 : 6) && - (skip_next_check || mp4a_valid_frame(p + fsize))) { + if (dts != PTS_UNSET && len >= i + fsize + (skip_next_check ? 0 : 6) && + (skip_next_check || mp4a_valid_frame(p + fsize))) { int channels = ((p[2] & 0x01) << 2) | ((p[3] & 0xc0) >> 6); @@ -627,81 +605,78 @@ static void parse_mp4a_data(parser_t *t, parser_es_t *st, /** * Parse AAC LATM and ADTS */ -static void -parse_aac(parser_t *t, parser_es_t *st, const uint8_t *data, - int len, int start) -{ - int l, muxlen, p, latm; - th_pkt_t *pkt; - int64_t olddts = PTS_UNSET, oldpts = PTS_UNSET; +static void parse_aac(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start) { + int l, muxlen, p, latm; + th_pkt_t* pkt; + int64_t olddts = PTS_UNSET, oldpts = PTS_UNSET; - if(st->es_parser_state == 0) { + if (st->es_parser_state == 0) { if (start) { /* Payload unit start */ st->es_parser_state = 1; - st->es_parser_ptr = 0; + st->es_parser_ptr = 0; sbuf_reset(&st->es_buf, 4000); } else { return; } } - if(start) { + if (start) { int hlen; - if(len < 9) + if (len < 9) return; - if((data[0] != 0 && data[1] != 0 && data[2] != 1) || - (data[3] != 0xbd && (data[3] & ~0x1f) != 0xc0)) { /* startcode */ + if ((data[0] != 0 && data[1] != 0 && data[2] != 1) || + (data[3] != 0xbd && (data[3] & ~0x1f) != 0xc0)) { /* startcode */ sbuf_reset(&st->es_buf, 4000); return; } olddts = st->es_curdts; oldpts = st->es_curpts; - hlen = parse_pes_header(t, st, data + 6, len - 6); + hlen = parse_pes_header(t, st, data + 6, len - 6); if (hlen >= 0 && st->es_buf.sb_ptr) { st->es_curdts = olddts; st->es_curpts = oldpts; } - if(hlen < 0) + if (hlen < 0) return; data += 6 + hlen; - len -= 6 + hlen; + len -= 6 + hlen; } sbuf_append(&st->es_buf, data, len); - p = 0; + p = 0; latm = -1; - while((l = st->es_buf.sb_ptr - p) > 3) { - const uint8_t *d = st->es_buf.sb_data + p; + while ((l = st->es_buf.sb_ptr - p) > 3) { + const uint8_t* d = st->es_buf.sb_data + p; /* Startcode check */ - if(d[0] == 0 && d[1] == 0 && d[2] == 1) { + if (d[0] == 0 && d[1] == 0 && d[2] == 1) { p += 4; - /* LATM */ - } else if(latm != 0 && d[0] == 0x56 && (d[1] & 0xe0) == 0xe0) { + /* LATM */ + } else if (latm != 0 && d[0] == 0x56 && (d[1] & 0xe0) == 0xe0) { muxlen = (d[1] & 0x1f) << 8 | d[2]; - if(l < muxlen + 3) + if (l < muxlen + 3) break; latm = 1; - pkt = parse_latm_audio_mux_element(t, st, d + 3, muxlen); + pkt = parse_latm_audio_mux_element(t, st, d + 3, muxlen); - if(pkt != NULL) { + if (pkt != NULL) { pkt->pkt_err = st->es_buf.sb_err; parser_deliver(t, st, pkt); st->es_buf.sb_err = 0; } p += muxlen + 3; - /* ADTS */ - } else if(latm <= 0 && d[0] == 0xff && (d[1] & 0xf0) == 0xf0) { + /* ADTS */ + } else if (latm <= 0 && d[0] == 0xff && (d[1] & 0xf0) == 0xf0) { if (l < 7) break; @@ -722,7 +697,7 @@ parse_aac(parser_t *t, parser_es_t *st, const uint8_t *data, p += muxlen; - /* Wrong bytestream */ + /* Wrong bytestream */ } else { tvhtrace(LS_PARSER, "AAC skip byte %02x", d[0]); p++; @@ -733,82 +708,91 @@ parse_aac(parser_t *t, parser_es_t *st, const uint8_t *data, sbuf_cut(&st->es_buf, p); } - /** * MPEG layer 1/2/3 parser */ static const int mpa_br[2][3][16] = { -{ - {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0}, - {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0}, - {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}, -}, -{ - {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}, - {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}, -} -}; + { + {0, 32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448, 0}, + {0, 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384, 0}, + {0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0}, + }, + { + {0, 32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256, 0}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}, + {0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}, + }}; static const int mpa_sr[4] = {44100, 48000, 32000, 0}; -static const int mpa_sri[4] = {4, 3, 5, 0}; - -static inline int -mpa_valid_frame(uint32_t h) -{ - if ((h & 0xffe00000) != 0xffe00000) return 0; /* start bits */ - if ((h & (3<<17)) == 0) return 0; /* unknown MPEG audio layer */ - if ((h & (15<<12)) == (15<<12)) return 0; /* invalid bitrate */ - if ((h & (3<<10)) == (3<<10)) return 0; /* invalid frequency */ +static const int mpa_sri[4] = {4, 3, 5, 0}; + +static inline int mpa_valid_frame(uint32_t h) { + if ((h & 0xffe00000) != 0xffe00000) + return 0; /* start bits */ + if ((h & (3 << 17)) == 0) + return 0; /* unknown MPEG audio layer */ + if ((h & (15 << 12)) == (15 << 12)) + return 0; /* invalid bitrate */ + if ((h & (3 << 10)) == (3 << 10)) + return 0; /* invalid frequency */ return 1; } /** * */ -static int -parse_mpa123(parser_t *t, parser_es_t *st) -{ - int i, len, layer, lsf, mpeg25, br, sr, pad; - int fsize, fsize2, channels, duration; - int64_t dts; - uint32_t h; - const uint8_t *buf; +static int parse_mpa123(parser_t* t, parser_es_t* st) { + int i, len, layer, lsf, mpeg25, br, sr, pad; + int fsize, fsize2, channels, duration; + int64_t dts; + uint32_t h; + const uint8_t* buf; buf = st->es_buf_a.sb_data; len = st->es_buf_a.sb_ptr; for (i = fsize2 = 0; i < len - 4; i++) { - if (!mpa_valid_frame(h = RB32(buf + i))) continue; + if (!mpa_valid_frame(h = RB32(buf + i))) + continue; layer = 4 - ((h >> 17) & 3); lsf = mpeg25 = 1; - pad = (h >> 9) & 1; - if (h & (1<<20)) { - lsf = ((h >> 19) & 1) ^ 1; + pad = (h >> 9) & 1; + if (h & (1 << 20)) { + lsf = ((h >> 19) & 1) ^ 1; mpeg25 = 0; } sr = mpa_sr[(h >> 10) & 3] >> (lsf + mpeg25); br = (h >> 12) & 0xf; - if (br == 0 || sr == 0) continue; + if (br == 0 || sr == 0) + continue; br = mpa_br[lsf][layer - 1][br]; - if (br == 0) continue; + if (br == 0) + continue; switch (layer) { - case 1: fsize = (((br * 12000) / sr) + pad) * 4; break; - case 2: fsize = ((br * 144000) / sr) + pad; break; - case 3: fsize = ((br * 144000) / (sr << lsf)) + pad; break; - default: fsize = 0; + case 1: + fsize = (((br * 12000) / sr) + pad) * 4; + break; + case 2: + fsize = ((br * 144000) / sr) + pad; + break; + case 3: + fsize = ((br * 144000) / (sr << lsf)) + pad; + break; + default: + fsize = 0; } duration = 90000 * 1152 / sr; channels = ((h >> 6) & 3) == 3 ? 1 : 2; - dts = st->es_curdts; + dts = st->es_curdts; if (dts == PTS_UNSET) { dts = st->es_nextdts; - if(dts == PTS_UNSET) continue; + if (dts == PTS_UNSET) + continue; } if (len < i + fsize + 4) { @@ -818,15 +802,17 @@ parse_mpa123(parser_t *t, parser_es_t *st) } if (mpa_valid_frame(RB32(buf + i + fsize))) { -ok: + ok: if (st->es_audio_version < layer) { - tvhtrace(LS_PARSER, "mpeg audio version change %02d: val=%d (old=%d)", - st->es_index, layer, st->es_audio_version); + tvhtrace(LS_PARSER, + "mpeg audio version change %02d: val=%d (old=%d)", + st->es_index, + layer, + st->es_audio_version); st->es_audio_version = layer; - service_update_elementary_stream(st->es_service, (elementary_stream_t *)st); + service_update_elementary_stream(st->es_service, (elementary_stream_t*)st); } - makeapkt(t, st, buf + i, fsize, dts, duration, - channels, mpa_sri[(buf[i+2] >> 2) & 3]); + makeapkt(t, st, buf + i, fsize, dts, duration, channels, mpa_sri[(buf[i + 2] >> 2) & 3]); i += fsize - 1; fsize2 = fsize; } @@ -840,76 +826,69 @@ ok: /** * */ -static int -parse_mpa(parser_t *t, parser_es_t *st, size_t ilen, - uint32_t next_startcode, int sc_offset) -{ +static int +parse_mpa(parser_t* t, parser_es_t* st, size_t ilen, uint32_t next_startcode, int sc_offset) { int r; - - if((r = depacketize(t, st, ilen, next_startcode, sc_offset)) != PARSER_APPEND) + + if ((r = depacketize(t, st, ilen, next_startcode, sc_offset)) != PARSER_APPEND) return r; return parse_mpa123(t, st); } -static void parse_pes_mpa(parser_t *t, parser_es_t *st, - const uint8_t *data, int len, int start) -{ +static void parse_pes_mpa(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start) { return parse_pes(t, st, data, len, start, parse_mpa); } - /** * (E)AC3 audio parser */ static const int ac3_freq_tab[4] = {48000, 44100, 32000, 0}; static const uint16_t ac3_frame_size_tab[38][3] = { - { 64, 69, 96 }, - { 64, 70, 96 }, - { 80, 87, 120 }, - { 80, 88, 120 }, - { 96, 104, 144 }, - { 96, 105, 144 }, - { 112, 121, 168 }, - { 112, 122, 168 }, - { 128, 139, 192 }, - { 128, 140, 192 }, - { 160, 174, 240 }, - { 160, 175, 240 }, - { 192, 208, 288 }, - { 192, 209, 288 }, - { 224, 243, 336 }, - { 224, 244, 336 }, - { 256, 278, 384 }, - { 256, 279, 384 }, - { 320, 348, 480 }, - { 320, 349, 480 }, - { 384, 417, 576 }, - { 384, 418, 576 }, - { 448, 487, 672 }, - { 448, 488, 672 }, - { 512, 557, 768 }, - { 512, 558, 768 }, - { 640, 696, 960 }, - { 640, 697, 960 }, - { 768, 835, 1152 }, - { 768, 836, 1152 }, - { 896, 975, 1344 }, - { 896, 976, 1344 }, - { 1024, 1114, 1536 }, - { 1024, 1115, 1536 }, - { 1152, 1253, 1728 }, - { 1152, 1254, 1728 }, - { 1280, 1393, 1920 }, - { 1280, 1394, 1920 }, + {64, 69, 96}, + {64, 70, 96}, + {80, 87, 120}, + {80, 88, 120}, + {96, 104, 144}, + {96, 105, 144}, + {112, 121, 168}, + {112, 122, 168}, + {128, 139, 192}, + {128, 140, 192}, + {160, 174, 240}, + {160, 175, 240}, + {192, 208, 288}, + {192, 209, 288}, + {224, 243, 336}, + {224, 244, 336}, + {256, 278, 384}, + {256, 279, 384}, + {320, 348, 480}, + {320, 349, 480}, + {384, 417, 576}, + {384, 418, 576}, + {448, 487, 672}, + {448, 488, 672}, + {512, 557, 768}, + {512, 558, 768}, + {640, 696, 960}, + {640, 697, 960}, + {768, 835, 1152}, + {768, 836, 1152}, + {896, 975, 1344}, + {896, 976, 1344}, + {1024, 1114, 1536}, + {1024, 1115, 1536}, + {1152, 1253, 1728}, + {1152, 1254, 1728}, + {1280, 1393, 1920}, + {1280, 1394, 1920}, }; /** * Inspect 6 bytes (E)AC3 header */ -static int -ac3_valid_frame(const uint8_t *buf) -{ +static int ac3_valid_frame(const uint8_t* buf) { uint_fast8_t bs; if (buf[0] != 0x0b || buf[1] != 0x77) @@ -918,22 +897,21 @@ ac3_valid_frame(const uint8_t *buf) if (bs <= 10) { return (buf[4] & 0xc0) != 0xc0 && (buf[4] & 0x3f) < 0x26 ? 1 : 0; } else { - if (bs > 16) return 0; + if (bs > 16) + return 0; return (buf[4] & 0xc0) != 0xc0 ? 2 : 0; } } -static const char acmodtab[8] = {2,1,2,3,3,4,4,5}; +static const char acmodtab[8] = {2, 1, 2, 3, 3, 4, 4, 5}; -static int -parse_ac3(parser_t *t, parser_es_t *st, size_t ilen, - uint32_t next_startcode, int sc_offset) -{ - int i, len, count, ver, bsid, fscod, frmsizcod, fsize, fsize2, duration, sri; - int sr, sr2, rate, acmod, lfeon, channels, versions[2], verchg = 0; - int64_t dts; +static int +parse_ac3(parser_t* t, parser_es_t* st, size_t ilen, uint32_t next_startcode, int sc_offset) { + int i, len, count, ver, bsid, fscod, frmsizcod, fsize, fsize2, duration, sri; + int sr, sr2, rate, acmod, lfeon, channels, versions[2], verchg = 0; + int64_t dts; const uint8_t *buf, *p; - bitstream_t bs; + bitstream_t bs; if ((i = depacketize(t, st, ilen, next_startcode, sc_offset)) != PARSER_APPEND) return i; @@ -948,7 +926,8 @@ again: len = st->es_buf_a.sb_ptr; for (i = count = fsize2 = 0; i < len - 6; i++) { - if (!(ver = ac3_valid_frame(p = buf + i))) continue; + if (!(ver = ac3_valid_frame(p = buf + i))) + continue; versions[ver - 1]++; if (ver == 1) { @@ -958,7 +937,8 @@ again: fsize = ac3_frame_size_tab[frmsizcod][fscod] * 2; bsid -= 8; - if (bsid < 0) bsid = 0; + if (bsid < 0) + bsid = 0; rate = ac3_freq_tab[fscod] >> bsid; } else { @@ -967,21 +947,24 @@ again: sr = p[4] >> 6; if (sr == 3) { sr2 = (p[4] >> 4) & 0x3; - if (sr2 == 3) continue; + if (sr2 == 3) + continue; rate = ac3_freq_tab[sr2] / 2; } else { rate = ac3_freq_tab[sr]; } } - if (rate == 0) continue; + if (rate == 0) + continue; duration = 90000 * 1536 / rate; - sri = rate_to_sri(rate); + sri = rate_to_sri(rate); dts = st->es_curdts; if (dts == PTS_UNSET) { dts = st->es_nextdts; - if(dts == PTS_UNSET) continue; + if (dts == PTS_UNSET) + continue; } if (len < i + fsize + 6) { @@ -991,7 +974,7 @@ again: } if ((ver = ac3_valid_frame(p + fsize)) != 0) { -ok: + ok: if (ver == st->es_audio_version) { if (ver == 1) { init_rbits(&bs, p + 5, (fsize - 5) * 8); @@ -1000,11 +983,11 @@ ok: read_bits(&bs, 3); // bsmod acmod = read_bits(&bs, 3); - if((acmod & 0x1) && (acmod != 0x1)) + if ((acmod & 0x1) && (acmod != 0x1)) read_bits(&bs, 2); // cmixlen - if(acmod & 0x4) + if (acmod & 0x4) read_bits(&bs, 2); // surmixlev - if(acmod == 0x2) + if (acmod == 0x2) read_bits(&bs, 2); // dsurmod lfeon = read_bits(&bs, 1); @@ -1038,13 +1021,10 @@ ok: return PARSER_RESET; } -static void parse_pes_ac3(parser_t *t, parser_es_t *st, - const uint8_t *data, int len, int start) -{ +static void parse_pes_ac3(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start) { return parse_pes(t, st, data, len, start, parse_ac3); } - /** * * MPEG2 video parser @@ -1055,33 +1035,31 @@ static void parse_pes_ac3(parser_t *t, parser_es_t *st, * MPEG2VIDEO frame duration table (in 90kHz clock domain) */ const unsigned int mpeg2video_framedurations[16] = { - 0, - 3753, - 3750, - 3600, - 3003, - 3000, - 1800, - 1501, - 1500, + 0, + 3753, + 3750, + 3600, + 3003, + 3000, + 1800, + 1501, + 1500, }; /** * Parse mpeg2video picture start */ static int -parse_mpeg2video_pic_start(parser_t *t, parser_es_t *st, int *frametype, - bitstream_t *bs) -{ +parse_mpeg2video_pic_start(parser_t* t, parser_es_t* st, int* frametype, bitstream_t* bs) { int pct; - if(bs->len < 29) + if (bs->len < 29) return PARSER_RESET; skip_bits(bs, 10); /* temporal reference */ pct = read_bits(bs, 3); - if(pct < PKT_I_FRAME || pct > PKT_B_FRAME) + if (pct < PKT_I_FRAME || pct > PKT_B_FRAME) return PARSER_RESET; /* Illegal picture_coding_type */ *frametype = pct; @@ -1099,72 +1077,71 @@ parse_mpeg2video_pic_start(parser_t *t, parser_es_t *st, int *frametype, /** * */ -void -parser_set_stream_vparam(parser_es_t *st, int width, int height, - int duration) -{ +void parser_set_stream_vparam(parser_es_t* st, int width, int height, int duration) { int need_save = 0; - tvhtrace(LS_PARSER, "vparam %02d: w=%d h=%d d=%d (old w=%d h=%d d=%d meta=%d)", - st->es_index, width, height, duration, st->es_width, st->es_height, - st->es_frame_duration, st->es_meta_change); - if(st->es_width == 0 && st->es_height == 0 && st->es_frame_duration < 2) { - need_save = 1; + tvhtrace(LS_PARSER, + "vparam %02d: w=%d h=%d d=%d (old w=%d h=%d d=%d meta=%d)", + st->es_index, + width, + height, + duration, + st->es_width, + st->es_height, + st->es_frame_duration, + st->es_meta_change); + if (st->es_width == 0 && st->es_height == 0 && st->es_frame_duration < 2) { + need_save = 1; st->es_meta_change = 0; - } else if(st->es_width != width || st->es_height != height || - st->es_frame_duration != duration) { + } else if (st->es_width != width || st->es_height != height || + st->es_frame_duration != duration) { st->es_meta_change++; - if(st->es_meta_change == 2) + if (st->es_meta_change == 2) need_save = 1; } else { st->es_meta_change = 0; } - if(need_save) { - st->es_width = width; - st->es_height = height; + if (need_save) { + st->es_width = width; + st->es_height = height; st->es_frame_duration = duration; - service_update_elementary_stream(st->es_service, (elementary_stream_t *)st); + service_update_elementary_stream(st->es_service, (elementary_stream_t*)st); } } - -static const uint8_t mpeg2_aspect[16][2]={ - {0,1}, - {1,1}, - {4,3}, - {16,9}, - {221,100}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, - {0,1}, +static const uint8_t mpeg2_aspect[16][2] = { + {0, 1}, + {1, 1}, + {4, 3}, + {16, 9}, + {221, 100}, + {0, 1}, + {0, 1}, + {0, 1}, + {0, 1}, + {0, 1}, + {0, 1}, + {0, 1}, + {0, 1}, + {0, 1}, + {0, 1}, + {0, 1}, }; - /** * Parse mpeg2video sequence start */ -static int -parse_mpeg2video_seq_start(parser_t *t, parser_es_t *st, - bitstream_t *bs) -{ +static int parse_mpeg2video_seq_start(parser_t* t, parser_es_t* st, bitstream_t* bs) { int width, height, aspect, duration; - if(bs->len < 61) + if (bs->len < 61) return PARSER_RESET; - - width = read_bits(bs, 12); + + width = read_bits(bs, 12); height = read_bits(bs, 12); aspect = read_bits(bs, 4); @@ -1175,7 +1152,7 @@ parse_mpeg2video_seq_start(parser_t *t, parser_es_t *st, skip_bits(bs, 18); skip_bits(bs, 1); - + #if 0 int v = read_bits(bs, 10) * 16 * 1024 / 8; st->es_vbv_size = v; @@ -1185,33 +1162,26 @@ parse_mpeg2video_seq_start(parser_t *t, parser_es_t *st, return PARSER_APPEND; } - /** * */ -static int -drop_trailing_zeroes(const uint8_t *buf, size_t len) -{ - while(len > 3 && (buf[len - 3] | buf[len - 2] | buf[len - 1]) == 0) +static int drop_trailing_zeroes(const uint8_t* buf, size_t len) { + while (len > 3 && (buf[len - 3] | buf[len - 2] | buf[len - 1]) == 0) len--; return len; } - /** * */ -static void -parser_global_data_move(parser_es_t *st, const uint8_t *data, size_t len, int reset) -{ +static void parser_global_data_move(parser_es_t* st, const uint8_t* data, size_t len, int reset) { if (reset) { free(st->es_global_data); - st->es_global_data = NULL; + st->es_global_data = NULL; st->es_global_data_len = 0; } else { - int len2 = drop_trailing_zeroes(data, len); - st->es_global_data = realloc(st->es_global_data, - st->es_global_data_len + len2); + int len2 = drop_trailing_zeroes(data, len); + st->es_global_data = realloc(st->es_global_data, st->es_global_data_len + len2); memcpy(st->es_global_data + st->es_global_data_len, data, len2); st->es_global_data_len += len2; } @@ -1230,152 +1200,147 @@ parser_global_data_move(parser_es_t *st, const uint8_t *data, size_t len, int re * */ static int -parse_mpeg2video(parser_t *t, parser_es_t *st, size_t len, - uint32_t next_startcode, int sc_offset) -{ - const uint8_t *buf = st->es_buf.sb_data + sc_offset; - bitstream_t bs; - int frametype; - th_pkt_t *pkt; +parse_mpeg2video(parser_t* t, parser_es_t* st, size_t len, uint32_t next_startcode, int sc_offset) { + const uint8_t* buf = st->es_buf.sb_data + sc_offset; + bitstream_t bs; + int frametype; + th_pkt_t* pkt; - if(next_startcode == 0x1e0) + if (next_startcode == 0x1e0) return PARSER_HEADER; init_rbits(&bs, buf + 4, (len - 4) * 8); - switch(st->es_startcode & 0xff) { - case 0xe0 ... 0xef: - /* System start codes for video */ - if(len < 9) - return PARSER_RESET; - - parse_pes_header(t, st, buf + 6, len - 6); - return PARSER_RESET; + switch (st->es_startcode & 0xff) { + case 0xe0 ... 0xef: + /* System start codes for video */ + if (len < 9) + return PARSER_RESET; - case 0x00: - /* Picture start code */ - if(st->es_frame_duration == 0) + parse_pes_header(t, st, buf + 6, len - 6); return PARSER_RESET; - if(parse_mpeg2video_pic_start(t, st, &frametype, &bs) != PARSER_APPEND) - return PARSER_RESET; + case 0x00: + /* Picture start code */ + if (st->es_frame_duration == 0) + return PARSER_RESET; - if(st->es_curpkt != NULL) - pkt_ref_dec(st->es_curpkt); + if (parse_mpeg2video_pic_start(t, st, &frametype, &bs) != PARSER_APPEND) + return PARSER_RESET; - pkt = pkt_alloc(st->es_type, NULL, 0, st->es_curpts, st->es_curdts, t->prs_current_pcr); - pkt->v.pkt_frametype = frametype; - pkt->pkt_duration = st->es_frame_duration; - pkt->pkt_commercial = t->prs_tt_commercial_advice; + if (st->es_curpkt != NULL) + pkt_ref_dec(st->es_curpkt); - st->es_curpkt = pkt; + pkt = pkt_alloc(st->es_type, NULL, 0, st->es_curpts, st->es_curdts, t->prs_current_pcr); + pkt->v.pkt_frametype = frametype; + pkt->pkt_duration = st->es_frame_duration; + pkt->pkt_commercial = t->prs_tt_commercial_advice; - /* If we know the frame duration, increase DTS accordingly */ - if(st->es_curdts != PTS_UNSET) - st->es_curdts += st->es_frame_duration; + st->es_curpkt = pkt; - /* PTS cannot be extrapolated (it's not linear) */ - st->es_curpts = PTS_UNSET; + /* If we know the frame duration, increase DTS accordingly */ + if (st->es_curdts != PTS_UNSET) + st->es_curdts += st->es_frame_duration; - break; + /* PTS cannot be extrapolated (it's not linear) */ + st->es_curpts = PTS_UNSET; - case 0xb3: - /* Sequence start code */ - if(!st->es_buf.sb_err) { - if(parse_mpeg2video_seq_start(t, st, &bs) != PARSER_APPEND) - return PARSER_RESET; - parser_global_data_move(st, buf, len, 0); - if (!st->es_priv) - st->es_priv = malloc(1); /* starting mark */ - } - return PARSER_DROP; + break; - case 0xb5: - if(len < 5) - return PARSER_RESET; - switch(buf[4] >> 4) { - case 0x1: - // Sequence Extension - if(!st->es_buf.sb_err) - parser_global_data_move(st, buf, len, 0); - return PARSER_DROP; - case 0x2: - // Sequence Display Extension - if(!st->es_buf.sb_err) + case 0xb3: + /* Sequence start code */ + if (!st->es_buf.sb_err) { + if (parse_mpeg2video_seq_start(t, st, &bs) != PARSER_APPEND) + return PARSER_RESET; parser_global_data_move(st, buf, len, 0); + if (!st->es_priv) + st->es_priv = malloc(1); /* starting mark */ + } return PARSER_DROP; - } - break; - - case 0x01 ... 0xaf: - /* Slices */ - if(next_startcode == 0x100 || next_startcode > 0x1af) { - /* Last picture slice (because next not a slice) */ - th_pkt_t *pkt = st->es_curpkt; - size_t metalen = 0; - if(pkt == NULL) { - /* no packet, may've been discarded by sanity checks here */ + case 0xb5: + if (len < 5) return PARSER_RESET; + switch (buf[4] >> 4) { + case 0x1: + // Sequence Extension + if (!st->es_buf.sb_err) + parser_global_data_move(st, buf, len, 0); + return PARSER_DROP; + case 0x2: + // Sequence Display Extension + if (!st->es_buf.sb_err) + parser_global_data_move(st, buf, len, 0); + return PARSER_DROP; } + break; - if(st->es_global_data) { - pkt->pkt_meta = pktbuf_make(st->es_global_data, - metalen = st->es_global_data_len); - st->es_global_data = NULL; - st->es_global_data_len = 0; - } + case 0x01 ... 0xaf: + /* Slices */ - if (st->es_buf.sb_err) { - pkt->pkt_err = st->es_buf.sb_err; - st->es_buf.sb_err = 0; - } - if (metalen) { - pkt->pkt_payload = pktbuf_alloc(NULL, metalen + st->es_buf.sb_ptr - 4); - memcpy(pktbuf_ptr(pkt->pkt_payload), pktbuf_ptr(pkt->pkt_meta), metalen); - memcpy(pktbuf_ptr(pkt->pkt_payload) + metalen, st->es_buf.sb_data, st->es_buf.sb_ptr - 4); - } else { - pkt->pkt_payload = pktbuf_make(st->es_buf.sb_data, - st->es_buf.sb_ptr - 4); - sbuf_steal_data(&st->es_buf); - } - pkt->pkt_duration = st->es_frame_duration; + if (next_startcode == 0x100 || next_startcode > 0x1af) { + /* Last picture slice (because next not a slice) */ + th_pkt_t* pkt = st->es_curpkt; + size_t metalen = 0; + if (pkt == NULL) { + /* no packet, may've been discarded by sanity checks here */ + return PARSER_RESET; + } - if (st->es_priv) { - if (!TAILQ_EMPTY(&st->es_backlog)) - parser_do_backlog(t, st, NULL, pkt->pkt_meta); - parser_deliver(t, st, pkt); - } else if (config.parser_backlog) { - parser_backlog(t, st, pkt); - } else { - pkt_ref_dec(pkt); - } - st->es_curpkt = NULL; + if (st->es_global_data) { + pkt->pkt_meta = pktbuf_make(st->es_global_data, metalen = st->es_global_data_len); + st->es_global_data = NULL; + st->es_global_data_len = 0; + } - return PARSER_RESET; - } - break; + if (st->es_buf.sb_err) { + pkt->pkt_err = st->es_buf.sb_err; + st->es_buf.sb_err = 0; + } + if (metalen) { + pkt->pkt_payload = pktbuf_alloc(NULL, metalen + st->es_buf.sb_ptr - 4); + memcpy(pktbuf_ptr(pkt->pkt_payload), pktbuf_ptr(pkt->pkt_meta), metalen); + memcpy(pktbuf_ptr(pkt->pkt_payload) + metalen, st->es_buf.sb_data, st->es_buf.sb_ptr - 4); + } else { + pkt->pkt_payload = pktbuf_make(st->es_buf.sb_data, st->es_buf.sb_ptr - 4); + sbuf_steal_data(&st->es_buf); + } + pkt->pkt_duration = st->es_frame_duration; + + if (st->es_priv) { + if (!TAILQ_EMPTY(&st->es_backlog)) + parser_do_backlog(t, st, NULL, pkt->pkt_meta); + parser_deliver(t, st, pkt); + } else if (config.parser_backlog) { + parser_backlog(t, st, pkt); + } else { + pkt_ref_dec(pkt); + } + st->es_curpkt = NULL; - case 0xb8: - // GOP header - if(!st->es_buf.sb_err) - parser_global_data_move(st, buf, len, 0); - return PARSER_DROP; + return PARSER_RESET; + } + break; - case 0xb2: - // User data - break; + case 0xb8: + // GOP header + if (!st->es_buf.sb_err) + parser_global_data_move(st, buf, len, 0); + return PARSER_DROP; - default: - break; + case 0xb2: + // User data + break; + + default: + break; } return PARSER_APPEND; } -static void parse_pes_mpeg2video(parser_t *t, parser_es_t *st, - const uint8_t *data, int len, int start) -{ +static void +parse_pes_mpeg2video(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start) { return parse_pes(t, st, data, len, start, parse_mpeg2video); } @@ -1384,13 +1349,11 @@ static void parse_pes_mpeg2video(parser_t *t, parser_es_t *st, * H.264 (AVC) parser * */ -static void -parse_h264_backlog(parser_t *t, parser_es_t *st, th_pkt_t *pkt) -{ - int len, l2, pkttype = 0, isfield = 0, nal_type; +static void parse_h264_backlog(parser_t* t, parser_es_t* st, th_pkt_t* pkt) { + int len, l2, pkttype = 0, isfield = 0, nal_type; const uint8_t *end, *nal_start, *nal_end; - bitstream_t bs; - void *f; + bitstream_t bs; + void* f; if (pkt->pkt_payload == NULL) return; @@ -1398,19 +1361,20 @@ parse_h264_backlog(parser_t *t, parser_es_t *st, th_pkt_t *pkt) if (len <= 1) return; nal_start = pktbuf_ptr(pkt->pkt_payload); - end = nal_start + len; + end = nal_start + len; while (1) { - while (nal_start < end && !*(nal_start++)); + while (nal_start < end && !*(nal_start++)) + ; if (nal_start == end) break; nal_end = avc_find_startcode(nal_start, end); - len = nal_end - nal_start; + len = nal_end - nal_start; if (len > 3) { nal_type = nal_start[0] & 0x1f; if (nal_type == H264_NAL_IDR_SLICE || nal_type == H264_NAL_SLICE) { l2 = len - 1 > 64 ? 64 : len - 1; - f = h264_nal_deescape(&bs, nal_start + 1, l2); - if(h264_decode_slice_header(st, &bs, &pkttype, &isfield)) + f = h264_nal_deescape(&bs, nal_start + 1, l2); + if (h264_decode_slice_header(st, &bs, &pkttype, &isfield)) pkttype = isfield = 0; free(f); if (pkttype > 0) @@ -1421,24 +1385,22 @@ parse_h264_backlog(parser_t *t, parser_es_t *st, th_pkt_t *pkt) } pkt->v.pkt_frametype = pkttype; - pkt->v.pkt_field = isfield; - pkt->pkt_duration = st->es_frame_duration; + pkt->v.pkt_field = isfield; + pkt->pkt_duration = st->es_frame_duration; } -static void -parse_h264_deliver(parser_t *t, parser_es_t *st, th_pkt_t *pkt) -{ +static void parse_h264_deliver(parser_t* t, parser_es_t* st, th_pkt_t* pkt) { if (pkt->v.pkt_frametype > 0) { if (TAILQ_EMPTY(&st->es_backlog)) { if (pkt->v.pkt_frametype > 0) { -deliver: + deliver: parser_deliver(t, st, pkt); return; } } else if (pkt->v.pkt_frametype > 0 && - (st->es_curdts != PTS_UNSET && (st->es_curdts & PTS_BACKLOG) == 0) && - (st->es_curpts != PTS_UNSET && (st->es_curpts & PTS_BACKLOG) == 0) && - st->es_frame_duration > 1) { + (st->es_curdts != PTS_UNSET && (st->es_curdts & PTS_BACKLOG) == 0) && + (st->es_curpts != PTS_UNSET && (st->es_curpts & PTS_BACKLOG) == 0) && + st->es_frame_duration > 1) { parser_do_backlog(t, st, parse_h264_backlog, pkt ? pkt->pkt_meta : NULL); goto deliver; } @@ -1450,15 +1412,13 @@ deliver: } static int -parse_h264(parser_t *t, parser_es_t *st, size_t len, - uint32_t next_startcode, int sc_offset) -{ - const uint8_t *buf = st->es_buf.sb_data + sc_offset; - uint32_t sc = st->es_startcode; - int l2, pkttype, isfield; - bitstream_t bs; - int ret = PARSER_APPEND; - th_pkt_t *pkt = st->es_curpkt; +parse_h264(parser_t* t, parser_es_t* st, size_t len, uint32_t next_startcode, int sc_offset) { + const uint8_t* buf = st->es_buf.sb_data + sc_offset; + uint32_t sc = st->es_startcode; + int l2, pkttype, isfield; + bitstream_t bs; + int ret = PARSER_APPEND; + th_pkt_t* pkt = st->es_curpkt; /* delimiter - finished frame */ if ((sc & 0x1f) == H264_NAL_AUD && pkt) { @@ -1481,12 +1441,13 @@ parse_h264(parser_t *t, parser_es_t *st, size_t len, } } - if(is_ssc(sc)) { + if (is_ssc(sc)) { /* System start codes for video */ - if(len >= 9) { + if (len >= 9) { uint16_t plen = buf[4] << 8 | buf[5]; - pkt = st->es_curpkt; - if (plen >= 0xffe9) st->es_incomplete = 1; + pkt = st->es_curpkt; + if (plen >= 0xffe9) + st->es_incomplete = 1; l2 = parse_pes_header(t, st, buf + 6, len - 6); if (l2 < 0) return PARSER_DROP; @@ -1513,8 +1474,8 @@ parse_h264(parser_t *t, parser_es_t *st, size_t len, st->es_prevdts = st->es_curdts; return PARSER_RESET; } - - if(sc == 0x10c) { + + if (sc == 0x10c) { // Padding st->es_buf.sb_ptr -= len; @@ -1522,73 +1483,72 @@ parse_h264(parser_t *t, parser_es_t *st, size_t len, } else { - switch(sc & 0x1f) { - - case H264_NAL_SPS: - if(!st->es_buf.sb_err) { - void *f = h264_nal_deescape(&bs, buf + 4, len - 4); - int r = h264_decode_seq_parameter_set(st, &bs); - free(f); - parser_global_data_move(st, buf, len, r); - } - ret = PARSER_DROP; - break; + switch (sc & 0x1f) { - case H264_NAL_PPS: - if(!st->es_buf.sb_err) { - void *f = h264_nal_deescape(&bs, buf + 4, len - 4); - int r = h264_decode_pic_parameter_set(st, &bs); - free(f); - parser_global_data_move(st, buf, len, r); - } - ret = PARSER_DROP; - break; + case H264_NAL_SPS: + if (!st->es_buf.sb_err) { + void* f = h264_nal_deescape(&bs, buf + 4, len - 4); + int r = h264_decode_seq_parameter_set(st, &bs); + free(f); + parser_global_data_move(st, buf, len, r); + } + ret = PARSER_DROP; + break; - case H264_NAL_IDR_SLICE: - case H264_NAL_SLICE: - if (st->es_curpkt != NULL) + case H264_NAL_PPS: + if (!st->es_buf.sb_err) { + void* f = h264_nal_deescape(&bs, buf + 4, len - 4); + int r = h264_decode_pic_parameter_set(st, &bs); + free(f); + parser_global_data_move(st, buf, len, r); + } + ret = PARSER_DROP; break; - /* we just want the first stuff */ - l2 = len - 4 > 64 ? 64 : len - 4; - void *f = h264_nal_deescape(&bs, buf + 4, l2); - if(h264_decode_slice_header(st, &bs, &pkttype, &isfield)) - pkttype = isfield = 0; - free(f); + case H264_NAL_IDR_SLICE: + case H264_NAL_SLICE: + if (st->es_curpkt != NULL) + break; - if (st->es_frame_duration == 0) - st->es_frame_duration = 1; + /* we just want the first stuff */ + l2 = len - 4 > 64 ? 64 : len - 4; + void* f = h264_nal_deescape(&bs, buf + 4, l2); + if (h264_decode_slice_header(st, &bs, &pkttype, &isfield)) + pkttype = isfield = 0; + free(f); - pkt = pkt_alloc(st->es_type, NULL, 0, st->es_curpts, st->es_curdts, t->prs_current_pcr); - pkt->v.pkt_frametype = pkttype; - pkt->v.pkt_field = isfield; - pkt->pkt_duration = st->es_frame_duration; - pkt->pkt_commercial = t->prs_tt_commercial_advice; - st->es_curpkt = pkt; - break; + if (st->es_frame_duration == 0) + st->es_frame_duration = 1; - default: - break; + pkt = pkt_alloc(st->es_type, NULL, 0, st->es_curpts, st->es_curdts, t->prs_current_pcr); + pkt->v.pkt_frametype = pkttype; + pkt->v.pkt_field = isfield; + pkt->pkt_duration = st->es_frame_duration; + pkt->pkt_commercial = t->prs_tt_commercial_advice; + st->es_curpkt = pkt; + break; + + default: + break; } } - if(is_ssc(next_startcode) || (next_startcode & 0x1f) == H264_NAL_AUD) { + if (is_ssc(next_startcode) || (next_startcode & 0x1f) == H264_NAL_AUD) { /* Complete frame - new start code or delimiter */ if (st->es_incomplete) return PARSER_HEADER; - pkt = st->es_curpkt; + pkt = st->es_curpkt; size_t metalen = 0; - if(pkt != NULL && pkt->pkt_payload == NULL) { - if(st->es_global_data) { - pkt->pkt_meta = pktbuf_make(st->es_global_data, - metalen = st->es_global_data_len); - st->es_global_data = NULL; + if (pkt != NULL && pkt->pkt_payload == NULL) { + if (st->es_global_data) { + pkt->pkt_meta = pktbuf_make(st->es_global_data, metalen = st->es_global_data_len); + st->es_global_data = NULL; st->es_global_data_len = 0; } if (st->es_buf.sb_err) { - pkt->pkt_err = st->es_buf.sb_err; + pkt->pkt_err = st->es_buf.sb_err; st->es_buf.sb_err = 0; } if (metalen) { @@ -1596,8 +1556,7 @@ parse_h264(parser_t *t, parser_es_t *st, size_t len, memcpy(pktbuf_ptr(pkt->pkt_payload), pktbuf_ptr(pkt->pkt_meta), metalen); memcpy(pktbuf_ptr(pkt->pkt_payload) + metalen, st->es_buf.sb_data, st->es_buf.sb_ptr - 4); } else { - pkt->pkt_payload = pktbuf_make(st->es_buf.sb_data, - st->es_buf.sb_ptr - 4); + pkt->pkt_payload = pktbuf_make(st->es_buf.sb_data, st->es_buf.sb_ptr - 4); sbuf_steal_data(&st->es_buf); } } @@ -1607,35 +1566,31 @@ parse_h264(parser_t *t, parser_es_t *st, size_t len, return ret; } -static void parse_pes_h264(parser_t *t, parser_es_t *st, - const uint8_t *data, int len, int start) -{ +static void parse_pes_h264(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start) { return parse_pes(t, st, data, len, start, parse_h264); } - /** * * H.265 (HEVC) parser * */ static int -parse_hevc(parser_t *t, parser_es_t *st, size_t len, - uint32_t next_startcode, int sc_offset) -{ - const uint8_t *buf = st->es_buf.sb_data + sc_offset; - uint32_t sc = st->es_startcode; - int nal_type = (sc >> 1) & 0x3f; - int l2, pkttype, r; - bitstream_t bs; - int ret = PARSER_APPEND; - - if(is_ssc(sc)) { +parse_hevc(parser_t* t, parser_es_t* st, size_t len, uint32_t next_startcode, int sc_offset) { + const uint8_t* buf = st->es_buf.sb_data + sc_offset; + uint32_t sc = st->es_startcode; + int nal_type = (sc >> 1) & 0x3f; + int l2, pkttype, r; + bitstream_t bs; + int ret = PARSER_APPEND; + + if (is_ssc(sc)) { /* System start codes for video */ - if(len >= 9) { - uint16_t plen = buf[4] << 8 | buf[5]; - th_pkt_t *pkt = st->es_curpkt; - if (plen >= 0xffe9) st->es_incomplete = 1; + if (len >= 9) { + uint16_t plen = buf[4] << 8 | buf[5]; + th_pkt_t* pkt = st->es_curpkt; + if (plen >= 0xffe9) + st->es_incomplete = 1; l2 = parse_pes_header(t, st, buf + 6, len - 6); if (l2 < 0) return PARSER_DROP; @@ -1663,70 +1618,71 @@ parse_hevc(parser_t *t, parser_es_t *st, size_t len, return PARSER_DROP; switch (nal_type) { - case HEVC_NAL_TRAIL_N: - case HEVC_NAL_TRAIL_R: - case HEVC_NAL_TSA_N: - case HEVC_NAL_TSA_R: - case HEVC_NAL_STSA_N: - case HEVC_NAL_STSA_R: - case HEVC_NAL_RADL_N: - case HEVC_NAL_RADL_R: - case HEVC_NAL_RASL_N: - case HEVC_NAL_RASL_R: - case HEVC_NAL_BLA_W_LP: - case HEVC_NAL_BLA_W_RADL: - case HEVC_NAL_BLA_N_LP: - case HEVC_NAL_IDR_W_RADL: - case HEVC_NAL_IDR_N_LP: - case HEVC_NAL_CRA_NUT: - if (st->es_curpkt != NULL) - break; - - l2 = len - 3 > 64 ? 64 : len - 3; - void *f = h264_nal_deescape(&bs, buf + 3, l2); - r = hevc_decode_slice_header(st, &bs, &pkttype); - free(f); - if (r < 0) - return PARSER_RESET; - if (r > 0) - return PARSER_APPEND; - - st->es_curpkt = pkt_alloc(st->es_type, NULL, 0, st->es_curpts, st->es_curdts, t->prs_current_pcr); - st->es_curpkt->v.pkt_frametype = pkttype; - st->es_curpkt->v.pkt_field = 0; - st->es_curpkt->pkt_duration = st->es_frame_duration; - st->es_curpkt->pkt_commercial = t->prs_tt_commercial_advice; - break; + case HEVC_NAL_TRAIL_N: + case HEVC_NAL_TRAIL_R: + case HEVC_NAL_TSA_N: + case HEVC_NAL_TSA_R: + case HEVC_NAL_STSA_N: + case HEVC_NAL_STSA_R: + case HEVC_NAL_RADL_N: + case HEVC_NAL_RADL_R: + case HEVC_NAL_RASL_N: + case HEVC_NAL_RASL_R: + case HEVC_NAL_BLA_W_LP: + case HEVC_NAL_BLA_W_RADL: + case HEVC_NAL_BLA_N_LP: + case HEVC_NAL_IDR_W_RADL: + case HEVC_NAL_IDR_N_LP: + case HEVC_NAL_CRA_NUT: + if (st->es_curpkt != NULL) + break; - case HEVC_NAL_VPS: - if(!st->es_buf.sb_err) { - void *f = h264_nal_deescape(&bs, buf + 3, len - 3); - int r = hevc_decode_vps(st, &bs); + l2 = len - 3 > 64 ? 64 : len - 3; + void* f = h264_nal_deescape(&bs, buf + 3, l2); + r = hevc_decode_slice_header(st, &bs, &pkttype); free(f); - parser_global_data_move(st, buf, len, r); - } - ret = PARSER_DROP; - break; + if (r < 0) + return PARSER_RESET; + if (r > 0) + return PARSER_APPEND; + + st->es_curpkt = + pkt_alloc(st->es_type, NULL, 0, st->es_curpts, st->es_curdts, t->prs_current_pcr); + st->es_curpkt->v.pkt_frametype = pkttype; + st->es_curpkt->v.pkt_field = 0; + st->es_curpkt->pkt_duration = st->es_frame_duration; + st->es_curpkt->pkt_commercial = t->prs_tt_commercial_advice; + break; - case HEVC_NAL_SPS: - if(!st->es_buf.sb_err) { - void *f = h264_nal_deescape(&bs, buf + 3, len - 3); - int r = hevc_decode_sps(st, &bs); - free(f); - parser_global_data_move(st, buf, len, r); - } - ret = PARSER_DROP; - break; + case HEVC_NAL_VPS: + if (!st->es_buf.sb_err) { + void* f = h264_nal_deescape(&bs, buf + 3, len - 3); + int r = hevc_decode_vps(st, &bs); + free(f); + parser_global_data_move(st, buf, len, r); + } + ret = PARSER_DROP; + break; - case HEVC_NAL_PPS: - if(!st->es_buf.sb_err) { - void *f = h264_nal_deescape(&bs, buf + 3, len - 3); - int r = hevc_decode_pps(st, &bs); - free(f); - parser_global_data_move(st, buf, len, r); - } - ret = PARSER_DROP; - break; + case HEVC_NAL_SPS: + if (!st->es_buf.sb_err) { + void* f = h264_nal_deescape(&bs, buf + 3, len - 3); + int r = hevc_decode_sps(st, &bs); + free(f); + parser_global_data_move(st, buf, len, r); + } + ret = PARSER_DROP; + break; + + case HEVC_NAL_PPS: + if (!st->es_buf.sb_err) { + void* f = h264_nal_deescape(&bs, buf + 3, len - 3); + int r = hevc_decode_pps(st, &bs); + free(f); + parser_global_data_move(st, buf, len, r); + } + ret = PARSER_DROP; + break; #if 0 case HEVC_NAL_SEI_PREFIX: @@ -1739,28 +1695,26 @@ parse_hevc(parser_t *t, parser_es_t *st, size_t len, break; #endif - default: - break; + default: + break; } - if(is_ssc(next_startcode) || - ((next_startcode >> 1) & 0x3f) == HEVC_NAL_AUD) { + if (is_ssc(next_startcode) || ((next_startcode >> 1) & 0x3f) == HEVC_NAL_AUD) { /* Complete frame - new start code or delimiter */ if (st->es_incomplete) return PARSER_HEADER; - th_pkt_t *pkt = st->es_curpkt; - size_t metalen = 0; + th_pkt_t* pkt = st->es_curpkt; + size_t metalen = 0; - if(pkt != NULL && pkt->pkt_payload == NULL) { - if(st->es_global_data) { - pkt->pkt_meta = pktbuf_make(st->es_global_data, - metalen = st->es_global_data_len); - st->es_global_data = NULL; + if (pkt != NULL && pkt->pkt_payload == NULL) { + if (st->es_global_data) { + pkt->pkt_meta = pktbuf_make(st->es_global_data, metalen = st->es_global_data_len); + st->es_global_data = NULL; st->es_global_data_len = 0; } if (st->es_buf.sb_err) { - pkt->pkt_err = st->es_buf.sb_err; + pkt->pkt_err = st->es_buf.sb_err; st->es_buf.sb_err = 0; } if (metalen) { @@ -1768,8 +1722,7 @@ parse_hevc(parser_t *t, parser_es_t *st, size_t len, memcpy(pktbuf_ptr(pkt->pkt_payload), pktbuf_ptr(pkt->pkt_meta), metalen); memcpy(pktbuf_ptr(pkt->pkt_payload) + metalen, st->es_buf.sb_data, st->es_buf.sb_ptr - 4); } else { - pkt->pkt_payload = pktbuf_make(st->es_buf.sb_data, - st->es_buf.sb_ptr - 4); + pkt->pkt_payload = pktbuf_make(st->es_buf.sb_data, st->es_buf.sb_ptr - 4); sbuf_steal_data(&st->es_buf); } } @@ -1779,73 +1732,68 @@ parse_hevc(parser_t *t, parser_es_t *st, size_t len, return ret; } -static void parse_pes_hevc(parser_t *t, parser_es_t *st, - const uint8_t *data, int len, int start) -{ +static void parse_pes_hevc(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start) { return parse_pes(t, st, data, len, start, parse_hevc); } - /** * http://broadcasting.ru/pdf-standard-specifications/subtitling/dvb-sub/en300743.v1.2.1.pdf */ -static void -parse_subtitles(parser_t *t, parser_es_t *st, const uint8_t *data, - int len, int start) -{ - th_pkt_t *pkt; - int psize, hlen; - const uint8_t *buf; - const uint8_t *d; +static void parse_subtitles(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start) { + th_pkt_t* pkt; + int psize, hlen; + const uint8_t* buf; + const uint8_t* d; - if(start) { + if (start) { /* Payload unit start */ st->es_parser_state = 1; sbuf_reset(&st->es_buf, 4000); } - if(st->es_parser_state == 0) + if (st->es_parser_state == 0) return; sbuf_append(&st->es_buf, data, len); - if(st->es_buf.sb_ptr < 6) + if (st->es_buf.sb_ptr < 6) return; - d = st->es_buf.sb_data; + d = st->es_buf.sb_data; uint32_t startcode = (d[0] << 24) | (d[1] << 16) | (d[2] << 8) | d[3]; - if(startcode == 0x1be) { + if (startcode == 0x1be) { st->es_parser_state = 0; return; } psize = d[4] << 8 | d[5]; - if(st->es_buf.sb_ptr != psize + 6) + if (st->es_buf.sb_ptr != psize + 6) return; st->es_parser_state = 0; hlen = parse_pes_header(t, st, d + 6, st->es_buf.sb_ptr - 6); - if(hlen < 0) + if (hlen < 0) return; psize -= hlen; buf = d + 6 + hlen; - - if(psize < 2 || buf[0] != 0x20 || buf[1] != 0x00) + + if (psize < 2 || buf[0] != 0x20 || buf[1] != 0x00) return; psize -= 2; buf += 2; - if(psize >= 6) { + if (psize >= 6) { // end_of_PES_data_field_marker - if(buf[psize - 1] == 0xff) { - pkt = pkt_alloc(st->es_type, buf, psize - 1, st->es_curpts, st->es_curdts, t->prs_current_pcr); + if (buf[psize - 1] == 0xff) { + pkt = + pkt_alloc(st->es_type, buf, psize - 1, st->es_curpts, st->es_curdts, t->prs_current_pcr); pkt->pkt_commercial = t->prs_tt_commercial_advice; - pkt->pkt_err = st->es_buf.sb_err; + pkt->pkt_err = st->es_buf.sb_err; parser_deliver(t, st, pkt); sbuf_reset(&st->es_buf, 4000); } @@ -1855,50 +1803,51 @@ parse_subtitles(parser_t *t, parser_es_t *st, const uint8_t *data, /** * Teletext parser */ -static void -parse_teletext(parser_t *t, parser_es_t *st, const uint8_t *data, - int len, int start) -{ - th_pkt_t *pkt; - int psize, hlen; - const uint8_t *buf; - const uint8_t *d; +static void parse_teletext(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start) { + th_pkt_t* pkt; + int psize, hlen; + const uint8_t* buf; + const uint8_t* d; - if(start) { + if (start) { st->es_parser_state = 1; - st->es_parser_ptr = 0; + st->es_parser_ptr = 0; sbuf_reset(&st->es_buf, 4000); } - if(st->es_parser_state == 0) + if (st->es_parser_state == 0) return; sbuf_append(&st->es_buf, data, len); - if(st->es_buf.sb_ptr < 6) + if (st->es_buf.sb_ptr < 6) return; d = st->es_buf.sb_data; psize = d[4] << 8 | d[5]; - if(st->es_buf.sb_ptr != psize + 6) + if (st->es_buf.sb_ptr != psize + 6) return; st->es_parser_state = 0; hlen = parse_pes_header(t, st, d + 6, st->es_buf.sb_ptr - 6); - if(hlen < 0) + if (hlen < 0) return; psize -= hlen; buf = d + 6 + hlen; - - if(psize >= 46 && t->prs_current_pcr != PTS_UNSET) { + + if (psize >= 46 && t->prs_current_pcr != PTS_UNSET) { teletext_input(t, st, buf, psize); - pkt = pkt_alloc(st->es_type, buf, psize, - t->prs_current_pcr, t->prs_current_pcr, t->prs_current_pcr); + pkt = pkt_alloc(st->es_type, + buf, + psize, + t->prs_current_pcr, + t->prs_current_pcr, + t->prs_current_pcr); pkt->pkt_commercial = t->prs_tt_commercial_advice; - pkt->pkt_err = st->es_buf.sb_err; + pkt->pkt_err = st->es_buf.sb_err; parser_deliver(t, st, pkt); sbuf_reset(&st->es_buf, 4000); } @@ -1907,12 +1856,9 @@ parse_teletext(parser_t *t, parser_es_t *st, const uint8_t *data, /** * Hbbtv parser (=forwarder) */ -static void -parse_hbbtv(parser_t *t, parser_es_t *st, const uint8_t *data, - int len, int start) -{ - th_pkt_t *pkt = pkt_alloc(st->es_type, data, len, - t->prs_current_pcr, t->prs_current_pcr, t->prs_current_pcr); +static void parse_hbbtv(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start) { + th_pkt_t* pkt = + pkt_alloc(st->es_type, data, len, t->prs_current_pcr, t->prs_current_pcr, t->prs_current_pcr); pkt->pkt_err = st->es_buf.sb_err; parser_deliver(t, st, pkt); } @@ -1920,50 +1866,51 @@ parse_hbbtv(parser_t *t, parser_es_t *st, const uint8_t *data, /** * RDS parser */ -static void -parse_rds(parser_t *t, parser_es_t *st, const uint8_t *data, - int len, int start) -{ - th_pkt_t *pkt; - int psize, hlen; - const uint8_t *buf; - const uint8_t *d; +static void parse_rds(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start) { + th_pkt_t* pkt; + int psize, hlen; + const uint8_t* buf; + const uint8_t* d; - if(start) { + if (start) { /* Payload unit start */ st->es_parser_state = 1; sbuf_reset(&st->es_buf, 4000); } - if(st->es_parser_state == 0) + if (st->es_parser_state == 0) return; sbuf_append(&st->es_buf, data, len); - if(st->es_buf.sb_ptr < 6) + if (st->es_buf.sb_ptr < 6) return; d = st->es_buf.sb_data; psize = d[4] << 8 | d[5]; - if(st->es_buf.sb_ptr != psize + 6) + if (st->es_buf.sb_ptr != psize + 6) return; st->es_parser_state = 0; hlen = parse_pes_header(t, st, d + 6, st->es_buf.sb_ptr - 6); - if(hlen < 0) + if (hlen < 0) return; psize -= hlen; buf = d + 6 + hlen; - if(psize < 2 || buf[0] != 0xfe || buf[psize-1] != 0xff) + if (psize < 2 || buf[0] != 0xfe || buf[psize - 1] != 0xff) return; - if(psize > 2) { - pkt = pkt_alloc(st->es_type, buf, psize, - t->prs_current_pcr, t->prs_current_pcr, t->prs_current_pcr); + if (psize > 2) { + pkt = pkt_alloc(st->es_type, + buf, + psize, + t->prs_current_pcr, + t->prs_current_pcr, + t->prs_current_pcr); pkt->pkt_err = st->es_buf.sb_err; parser_deliver(t, st, pkt); sbuf_reset(&st->es_buf, 4000); @@ -1992,22 +1939,17 @@ static int data_noise(const uint8_t *data, int len) return 0; } #else -static inline int data_noise(const uint8_t *data, int len) { return 0; } +static inline int data_noise(const uint8_t* data, int len) { + return 0; +} #endif -static void -parse_none(parser_t *t, parser_es_t *st, const uint8_t *data, - int len, int start) -{ -} +static void parse_none(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start) {} /** * Parse raw mpeg data - single TS packet */ -void -parse_mpeg_ts(parser_t *t, parser_es_t *st, const uint8_t *data, - int len, int start, int err) -{ +void parse_mpeg_ts(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start, int err) { if (err) { if (start) parser_deliver_error(t, st); @@ -2022,52 +1964,52 @@ parse_mpeg_ts(parser_t *t, parser_es_t *st, const uint8_t *data, return; } - switch(st->es_type) { - case SCT_MPEG2VIDEO: - st->es_parse_callback = parse_pes_mpeg2video; - break; + switch (st->es_type) { + case SCT_MPEG2VIDEO: + st->es_parse_callback = parse_pes_mpeg2video; + break; - case SCT_H264: - st->es_parse_callback = parse_pes_h264; - break; + case SCT_H264: + st->es_parse_callback = parse_pes_h264; + break; - case SCT_HEVC: - st->es_parse_callback = parse_pes_hevc; - break; + case SCT_HEVC: + st->es_parse_callback = parse_pes_hevc; + break; - case SCT_MPEG2AUDIO: - st->es_parse_callback = parse_pes_mpa; - break; + case SCT_MPEG2AUDIO: + st->es_parse_callback = parse_pes_mpa; + break; - case SCT_AC3: - case SCT_EAC3: - st->es_parse_callback = parse_pes_ac3; - break; + case SCT_AC3: + case SCT_EAC3: + st->es_parse_callback = parse_pes_ac3; + break; - case SCT_DVBSUB: - st->es_parse_callback = parse_subtitles; - break; + case SCT_DVBSUB: + st->es_parse_callback = parse_subtitles; + break; - case SCT_AAC: - case SCT_MP4A: - st->es_parse_callback = parse_aac; - break; + case SCT_AAC: + case SCT_MP4A: + st->es_parse_callback = parse_aac; + break; - case SCT_TELETEXT: - st->es_parse_callback = parse_teletext; - break; + case SCT_TELETEXT: + st->es_parse_callback = parse_teletext; + break; - case SCT_HBBTV: - st->es_parse_callback = parse_hbbtv; - break; + case SCT_HBBTV: + st->es_parse_callback = parse_hbbtv; + break; - case SCT_RDS: - st->es_parse_callback = parse_rds; - break; + case SCT_RDS: + st->es_parse_callback = parse_rds; + break; - default: - st->es_parse_callback = parse_none; - break; + default: + st->es_parse_callback = parse_none; + break; } st->es_parse_callback(t, st, data, len, start); diff --git a/src/parsers/parsers.h b/src/parsers/parsers.h index 404d69dd5..7722c3814 100644 --- a/src/parsers/parsers.h +++ b/src/parsers/parsers.h @@ -26,48 +26,48 @@ #include "packet.h" typedef struct parser_es parser_es_t; -typedef struct parser parser_t; +typedef struct parser parser_t; struct th_subscription; -typedef void (parse_callback_t) - (parser_t *t, parser_es_t *st, const uint8_t *data, int len, int start); +typedef void( + parse_callback_t)(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start); /* parser elementary stream */ struct parser_es { elementary_stream_t; /* Parent */ - parser_t *es_parser; + parser_t* es_parser; /* State */ - parse_callback_t *es_parse_callback; - sbuf_t es_buf; - uint8_t es_incomplete; - uint8_t es_header_mode; - uint32_t es_header_offset; - uint32_t es_startcond; - uint32_t es_startcode; - uint32_t es_startcode_offset; - int es_parser_state; - int es_parser_ptr; - int es_meta_change; - void *es_priv; /* Parser private data */ - sbuf_t es_buf_a; /* Audio packet reassembly */ - uint8_t *es_global_data; - int es_global_data_len; - struct th_pkt *es_curpkt; + parse_callback_t* es_parse_callback; + sbuf_t es_buf; + uint8_t es_incomplete; + uint8_t es_header_mode; + uint32_t es_header_offset; + uint32_t es_startcond; + uint32_t es_startcode; + uint32_t es_startcode_offset; + int es_parser_state; + int es_parser_ptr; + int es_meta_change; + void* es_priv; /* Parser private data */ + sbuf_t es_buf_a; /* Audio packet reassembly */ + uint8_t* es_global_data; + int es_global_data_len; + struct th_pkt* es_curpkt; struct streaming_message_queue es_backlog; - tvhlog_limit_t es_pes_log; - mpegts_psi_table_t es_psi; + tvhlog_limit_t es_pes_log; + mpegts_psi_table_t es_psi; /* Clocks */ - int64_t es_curpts; - int64_t es_curdts; - int64_t es_prevdts; - int64_t es_nextdts; + int64_t es_curpts; + int64_t es_curdts; + int64_t es_prevdts; + int64_t es_nextdts; /* Misc */ - char es_blank; /* Teletext: last subtitle was blank */ + char es_blank; /* Teletext: last subtitle was blank */ /* PCR clocks */ - int64_t es_last_pcr; - int64_t es_last_pcr_dts; + int64_t es_last_pcr; + int64_t es_last_pcr_dts; tvhlog_limit_t es_pcr_log; }; @@ -76,11 +76,11 @@ struct parser { streaming_target_t prs_input; - streaming_target_t *prs_output; + streaming_target_t* prs_output; - th_subscription_t *prs_subscription; + th_subscription_t* prs_subscription; - service_t *prs_service; + service_t* prs_service; /* Elementary streams */ elementary_set_t prs_components; @@ -89,33 +89,27 @@ struct parser { uint16_t prs_pcr_pid; /* PCR clocks */ - int64_t prs_current_pcr; - int64_t prs_candidate_pcr; - int64_t prs_pcr_boundary; - uint8_t prs_current_pcr_guess; + int64_t prs_current_pcr; + int64_t prs_candidate_pcr; + int64_t prs_pcr_boundary; + uint8_t prs_current_pcr_guess; /* Teletext */ commercial_advice_t prs_tt_commercial_advice; - time_t prs_tt_clock; /* Network clock as determined by teletext decoder */ + time_t prs_tt_clock; /* Network clock as determined by teletext decoder */ /* restart_pending log */ struct streaming_message_queue prs_rstlog; }; -static inline int64_t -getpts(const uint8_t *p) -{ - int a = p[0]; +static inline int64_t getpts(const uint8_t* p) { + int a = p[0]; int b = (p[1] << 8) | p[2]; int c = (p[3] << 8) | p[4]; if ((a & 1) && (b & 1) && (c & 1)) { - return - ((int64_t)((a >> 1) & 0x07) << 30) | - ((int64_t)((b >> 1) ) << 15) | - ((int64_t)((c >> 1) )) - ; + return ((int64_t)((a >> 1) & 0x07) << 30) | ((int64_t)((b >> 1)) << 15) | ((int64_t)((c >> 1))); } else { // Marker bits not present @@ -123,18 +117,17 @@ getpts(const uint8_t *p) } } -streaming_target_t * parser_create(streaming_target_t *output, struct th_subscription *ts); +streaming_target_t* parser_create(streaming_target_t* output, struct th_subscription* ts); -void parser_destroy(streaming_target_t *pad); +void parser_destroy(streaming_target_t* pad); -streaming_target_t * parser_output(streaming_target_t *pad); +streaming_target_t* parser_output(streaming_target_t* pad); -void parse_mpeg_ts(parser_t *t, parser_es_t *st, const uint8_t *data, - int len, int start, int err); +void parse_mpeg_ts(parser_t* t, parser_es_t* st, const uint8_t* data, int len, int start, int err); -void parser_enqueue_packet(struct service *t, parser_es_t *st, th_pkt_t *pkt); +void parser_enqueue_packet(struct service* t, parser_es_t* st, th_pkt_t* pkt); -void parser_set_stream_vparam(parser_es_t *st, int width, int height, int duration); +void parser_set_stream_vparam(parser_es_t* st, int width, int height, int duration); extern const unsigned int mpeg2video_framedurations[16]; diff --git a/src/plumbing/globalheaders.c b/src/plumbing/globalheaders.c index ecd560ec6..a51026493 100644 --- a/src/plumbing/globalheaders.c +++ b/src/plumbing/globalheaders.c @@ -24,51 +24,40 @@ typedef struct globalheaders { streaming_target_t gh_input; - streaming_target_t *gh_output; + streaming_target_t* gh_output; struct th_pktref_queue gh_holdq; - streaming_start_t *gh_ss; + streaming_start_t* gh_ss; int gh_passthru; } globalheaders_t; /* note: there up to 2.5 sec diffs in some sources! */ -#define MAX_SCAN_TIME 5000 // in ms -#define MAX_NOPKT_TIME 2500 // in ms +#define MAX_SCAN_TIME 5000 // in ms +#define MAX_NOPKT_TIME 2500 // in ms /** * */ -static inline int -gh_require_meta(int type) -{ - return type == SCT_HEVC || - type == SCT_H264 || - type == SCT_MPEG2VIDEO || - type == SCT_MP4A || - type == SCT_AAC || - type == SCT_VORBIS || - type == SCT_THEORA; +static inline int gh_require_meta(int type) { + return type == SCT_HEVC || type == SCT_H264 || type == SCT_MPEG2VIDEO || type == SCT_MP4A || + type == SCT_AAC || type == SCT_VORBIS || type == SCT_THEORA; } /** * */ -static inline int -gh_is_audiovideo(int type) -{ +static inline int gh_is_audiovideo(int type) { return SCT_ISVIDEO(type) || SCT_ISAUDIO(type); } /** * */ -static void -gh_flush(globalheaders_t *gh) -{ - if(gh->gh_ss != NULL) { +static void gh_flush(globalheaders_t* gh) { + if (gh->gh_ss != NULL) { streaming_start_unref(gh->gh_ss); gh->gh_ss = NULL; } @@ -76,33 +65,30 @@ gh_flush(globalheaders_t *gh) pktref_clear_queue(&gh->gh_holdq); } - /** * */ -static void -apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt) -{ - if(ssc->es_frame_duration == 0 && pkt->pkt_duration != 0) +static void apply_header(streaming_start_component_t* ssc, th_pkt_t* pkt) { + if (ssc->es_frame_duration == 0 && pkt->pkt_duration != 0) ssc->es_frame_duration = pkt->pkt_duration; - if(SCT_ISAUDIO(ssc->es_type) && !ssc->es_channels) { + if (SCT_ISAUDIO(ssc->es_type) && !ssc->es_channels) { ssc->es_channels = pkt->a.pkt_channels; ssc->es_sri = pkt->a.pkt_sri; ssc->es_ext_sri = pkt->a.pkt_ext_sri; } - if(SCT_ISVIDEO(ssc->es_type)) { - if(pkt->v.pkt_aspect_num && pkt->v.pkt_aspect_den) { + if (SCT_ISVIDEO(ssc->es_type)) { + if (pkt->v.pkt_aspect_num && pkt->v.pkt_aspect_den) { ssc->es_aspect_num = pkt->v.pkt_aspect_num; ssc->es_aspect_den = pkt->v.pkt_aspect_den; } } - if(ssc->ssc_gh != NULL) + if (ssc->ssc_gh != NULL) return; - if(pkt->pkt_meta != NULL) { + if (pkt->pkt_meta != NULL) { ssc->ssc_gh = pkt->pkt_meta; pktbuf_ref_inc(ssc->ssc_gh); return; @@ -110,11 +96,11 @@ apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt) if (ssc->es_type == SCT_MP4A || ssc->es_type == SCT_AAC) { ssc->ssc_gh = pktbuf_alloc(NULL, pkt->a.pkt_ext_sri ? 5 : 2); - uint8_t *d = pktbuf_ptr(ssc->ssc_gh); + uint8_t* d = pktbuf_ptr(ssc->ssc_gh); const int profile = 2; /* AAC LC */ - d[0] = (profile << 3) | ((pkt->a.pkt_sri & 0xe) >> 1); - d[1] = ((pkt->a.pkt_sri & 0x1) << 7) | (pkt->a.pkt_channels << 3); + d[0] = (profile << 3) | ((pkt->a.pkt_sri & 0xe) >> 1); + d[1] = ((pkt->a.pkt_sri & 0x1) << 7) | (pkt->a.pkt_channels << 3); if (pkt->a.pkt_ext_sri) { /* SBR extension */ d[2] = 0x56; d[3] = 0xe5; @@ -123,53 +109,47 @@ apply_header(streaming_start_component_t *ssc, th_pkt_t *pkt) } } - /** * */ -static int -header_complete(streaming_start_component_t *ssc, int not_so_picky) -{ +static int header_complete(streaming_start_component_t* ssc, int not_so_picky) { int is_video = SCT_ISVIDEO(ssc->es_type); int is_audio = !is_video && SCT_ISAUDIO(ssc->es_type); - if((is_audio || is_video) && ssc->es_frame_duration == 0) + if ((is_audio || is_video) && ssc->es_frame_duration == 0) return 0; - if(is_video) { - if(!not_so_picky && (ssc->es_aspect_num == 0 || ssc->es_aspect_den == 0 || - ssc->es_width == 0 || ssc->es_height == 0)) + if (is_video) { + if (!not_so_picky && + (ssc->es_aspect_num == 0 || ssc->es_aspect_den == 0 || ssc->es_width == 0 || + ssc->es_height == 0)) return 0; } - if(is_audio && !ssc->es_channels) + if (is_audio && !ssc->es_channels) return 0; - if(ssc->ssc_gh == NULL && gh_require_meta(ssc->es_type)) + if (ssc->ssc_gh == NULL && gh_require_meta(ssc->es_type)) return 0; return 1; } - /** * */ -static int64_t -gh_queue_delay(globalheaders_t *gh, int index) -{ - th_pktref_t *f = TAILQ_FIRST(&gh->gh_holdq); - th_pktref_t *l = TAILQ_LAST(&gh->gh_holdq, th_pktref_queue); - streaming_start_component_t *ssc; - int64_t diff; +static int64_t gh_queue_delay(globalheaders_t* gh, int index) { + th_pktref_t* f = TAILQ_FIRST(&gh->gh_holdq); + th_pktref_t* l = TAILQ_LAST(&gh->gh_holdq, th_pktref_queue); + streaming_start_component_t* ssc; + int64_t diff; /* * Find only packets which require the meta data. Ignore others. */ while (f != l) { if (f->pr_pkt->pkt_dts != PTS_UNSET) { - ssc = streaming_start_component_find_by_index - (gh->gh_ss, f->pr_pkt->pkt_componentindex); + ssc = streaming_start_component_find_by_index(gh->gh_ss, f->pr_pkt->pkt_componentindex); if (ssc && ssc->es_index == index) break; } @@ -177,8 +157,7 @@ gh_queue_delay(globalheaders_t *gh, int index) } while (l != f) { if (l->pr_pkt->pkt_dts != PTS_UNSET) { - ssc = streaming_start_component_find_by_index - (gh->gh_ss, l->pr_pkt->pkt_componentindex); + ssc = streaming_start_component_find_by_index(gh->gh_ss, l->pr_pkt->pkt_componentindex); if (ssc && ssc->es_index == index) break; } @@ -200,25 +179,21 @@ gh_queue_delay(globalheaders_t *gh, int index) return diff; } - /** * */ -static int -headers_complete(globalheaders_t *gh) -{ - streaming_start_t *ss = gh->gh_ss; - streaming_start_component_t *ssc; - int64_t *qd = alloca(ss->ss_num_components * sizeof(int64_t)); - int64_t qd_max = 0; - int i, threshold = 0; +static int headers_complete(globalheaders_t* gh) { + streaming_start_t* ss = gh->gh_ss; + streaming_start_component_t* ssc; + int64_t* qd = alloca(ss->ss_num_components * sizeof(int64_t)); + int64_t qd_max = 0; + int i, threshold = 0; assert(ss != NULL); - for(i = 0; i < ss->ss_num_components; i++) { - ssc = &ss->ss_components[i]; - qd[i] = gh_is_audiovideo(ssc->es_type) ? - gh_queue_delay(gh, ssc->es_index) : 0; + for (i = 0; i < ss->ss_num_components; i++) { + ssc = &ss->ss_components[i]; + qd[i] = gh_is_audiovideo(ssc->es_type) ? gh_queue_delay(gh, ssc->es_index) : 0; if (qd[i] > qd_max) qd_max = qd[i]; } @@ -228,23 +203,29 @@ headers_complete(globalheaders_t *gh) threshold = qd_max > MAX_SCAN_TIME * 90; - for(i = 0; i < ss->ss_num_components; i++) { + for (i = 0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; - if(!header_complete(ssc, threshold)) { + if (!header_complete(ssc, threshold)) { /* * disable stream only when * - half timeout is reached without any packets seen * - maximal timeout is reached without metadata */ - if(threshold || (qd[i] <= 0 && qd_max > (MAX_NOPKT_TIME * 90))) { - ssc->ssc_disabled = 1; - tvhdebug(LS_GLOBALHEADERS, "gh disable stream %d %s%s%s (PID %i) threshold %d qd %"PRId64" qd_max %"PRId64, - ssc->es_index, streaming_component_type2txt(ssc->es_type), - ssc->es_lang[0] ? " " : "", ssc->es_lang, ssc->es_pid, - threshold, qd[i], qd_max); + if (threshold || (qd[i] <= 0 && qd_max > (MAX_NOPKT_TIME * 90))) { + ssc->ssc_disabled = 1; + tvhdebug(LS_GLOBALHEADERS, + "gh disable stream %d %s%s%s (PID %i) threshold %d qd %" PRId64 " qd_max %" PRId64, + ssc->es_index, + streaming_component_type2txt(ssc->es_type), + ssc->es_lang[0] ? " " : "", + ssc->es_lang, + ssc->es_pid, + threshold, + qd[i], + qd_max); } else { - return 0; + return 0; } } else { ssc->ssc_disabled = 0; @@ -252,192 +233,175 @@ headers_complete(globalheaders_t *gh) } if (tvhtrace_enabled()) { - for(i = 0; i < ss->ss_num_components; i++) { + for (i = 0; i < ss->ss_num_components; i++) { ssc = &ss->ss_components[i]; - tvhtrace(LS_GLOBALHEADERS, "stream %d %s%s%s (PID %i) complete time %"PRId64"%s", - ssc->es_index, streaming_component_type2txt(ssc->es_type), - ssc->es_lang[0] ? " " : "", ssc->es_lang, ssc->es_pid, - gh_queue_delay(gh, ssc->es_index), - ssc->ssc_disabled ? " disabled" : ""); + tvhtrace(LS_GLOBALHEADERS, + "stream %d %s%s%s (PID %i) complete time %" PRId64 "%s", + ssc->es_index, + streaming_component_type2txt(ssc->es_type), + ssc->es_lang[0] ? " " : "", + ssc->es_lang, + ssc->es_pid, + gh_queue_delay(gh, ssc->es_index), + ssc->ssc_disabled ? " disabled" : ""); } } return 1; } - /** * */ -static void -gh_start(globalheaders_t *gh, streaming_message_t *sm) -{ +static void gh_start(globalheaders_t* gh, streaming_message_t* sm) { gh->gh_ss = streaming_start_copy(sm->sm_data); streaming_msg_free(sm); } - /** * */ -static void -gh_hold(globalheaders_t *gh, streaming_message_t *sm) -{ - th_pkt_t *pkt; - streaming_start_component_t *ssc; - - switch(sm->sm_type) { - case SMT_PACKET: - pkt = sm->sm_data; - ssc = streaming_start_component_find_by_index(gh->gh_ss, - pkt->pkt_componentindex); - if (ssc == NULL) { - tvherror(LS_GLOBALHEADERS, "Unable to find component %d", pkt->pkt_componentindex); - streaming_msg_free(sm); - return; - } +static void gh_hold(globalheaders_t* gh, streaming_message_t* sm) { + th_pkt_t* pkt; + streaming_start_component_t* ssc; + + switch (sm->sm_type) { + case SMT_PACKET: + pkt = sm->sm_data; + ssc = streaming_start_component_find_by_index(gh->gh_ss, pkt->pkt_componentindex); + if (ssc == NULL) { + tvherror(LS_GLOBALHEADERS, "Unable to find component %d", pkt->pkt_componentindex); + streaming_msg_free(sm); + return; + } - pkt_trace(LS_GLOBALHEADERS, pkt, "hold receive"); + pkt_trace(LS_GLOBALHEADERS, pkt, "hold receive"); - pkt_ref_inc(pkt); + pkt_ref_inc(pkt); - if (pkt->pkt_err == 0) - apply_header(ssc, pkt); + if (pkt->pkt_err == 0) + apply_header(ssc, pkt); - pktref_enqueue(&gh->gh_holdq, pkt); + pktref_enqueue(&gh->gh_holdq, pkt); - streaming_msg_free(sm); + streaming_msg_free(sm); - if(!gh_is_audiovideo(ssc->es_type)) - break; + if (!gh_is_audiovideo(ssc->es_type)) + break; - if(!headers_complete(gh)) - break; + if (!headers_complete(gh)) + break; - // Send our modified start - sm = streaming_msg_create_data(SMT_START, - streaming_start_copy(gh->gh_ss)); - streaming_target_deliver2(gh->gh_output, sm); + // Send our modified start + sm = streaming_msg_create_data(SMT_START, streaming_start_copy(gh->gh_ss)); + streaming_target_deliver2(gh->gh_output, sm); - // Send all pending packets - while((pkt = pktref_get_first(&gh->gh_holdq)) != NULL) { - if (pkt->pkt_payload) { - sm = streaming_msg_create_pkt(pkt); - streaming_target_deliver2(gh->gh_output, sm); + // Send all pending packets + while ((pkt = pktref_get_first(&gh->gh_holdq)) != NULL) { + if (pkt->pkt_payload) { + sm = streaming_msg_create_pkt(pkt); + streaming_target_deliver2(gh->gh_output, sm); + } + pkt_ref_dec(pkt); } - pkt_ref_dec(pkt); - } - gh->gh_passthru = 1; - break; + gh->gh_passthru = 1; + break; - case SMT_START: - if (gh->gh_ss) + case SMT_START: + if (gh->gh_ss) + gh_flush(gh); + gh_start(gh, sm); + break; + + case SMT_STOP: gh_flush(gh); - gh_start(gh, sm); - break; - - case SMT_STOP: - gh_flush(gh); - streaming_msg_free(sm); - break; - - case SMT_GRACE: - case SMT_EXIT: - case SMT_SERVICE_STATUS: - case SMT_SIGNAL_STATUS: - case SMT_DESCRAMBLE_INFO: - case SMT_NOSTART: - case SMT_NOSTART_WARN: - case SMT_MPEGTS: - case SMT_SPEED: - case SMT_SKIP: - case SMT_TIMESHIFT_STATUS: - streaming_target_deliver2(gh->gh_output, sm); - break; + streaming_msg_free(sm); + break; + + case SMT_GRACE: + case SMT_EXIT: + case SMT_SERVICE_STATUS: + case SMT_SIGNAL_STATUS: + case SMT_DESCRAMBLE_INFO: + case SMT_NOSTART: + case SMT_NOSTART_WARN: + case SMT_MPEGTS: + case SMT_SPEED: + case SMT_SKIP: + case SMT_TIMESHIFT_STATUS: + streaming_target_deliver2(gh->gh_output, sm); + break; } } - /** * */ -static void -gh_pass(globalheaders_t *gh, streaming_message_t *sm) -{ - th_pkt_t *pkt; - switch(sm->sm_type) { - case SMT_START: - /* stop */ - gh->gh_passthru = 0; - gh_flush(gh); - /* restart */ - gh_start(gh, sm); - break; - - case SMT_STOP: - gh->gh_passthru = 0; - gh_flush(gh); - // FALLTHRU - case SMT_GRACE: - case SMT_EXIT: - case SMT_SERVICE_STATUS: - case SMT_SIGNAL_STATUS: - case SMT_DESCRAMBLE_INFO: - case SMT_NOSTART: - case SMT_NOSTART_WARN: - case SMT_MPEGTS: - case SMT_SKIP: - case SMT_SPEED: - case SMT_TIMESHIFT_STATUS: - streaming_target_deliver2(gh->gh_output, sm); - break; - case SMT_PACKET: - pkt = sm->sm_data; - if (pkt->pkt_payload || pkt->pkt_err) +static void gh_pass(globalheaders_t* gh, streaming_message_t* sm) { + th_pkt_t* pkt; + switch (sm->sm_type) { + case SMT_START: + /* stop */ + gh->gh_passthru = 0; + gh_flush(gh); + /* restart */ + gh_start(gh, sm); + break; + + case SMT_STOP: + gh->gh_passthru = 0; + gh_flush(gh); + // FALLTHRU + case SMT_GRACE: + case SMT_EXIT: + case SMT_SERVICE_STATUS: + case SMT_SIGNAL_STATUS: + case SMT_DESCRAMBLE_INFO: + case SMT_NOSTART: + case SMT_NOSTART_WARN: + case SMT_MPEGTS: + case SMT_SKIP: + case SMT_SPEED: + case SMT_TIMESHIFT_STATUS: streaming_target_deliver2(gh->gh_output, sm); - else - streaming_msg_free(sm); - break; + break; + case SMT_PACKET: + pkt = sm->sm_data; + if (pkt->pkt_payload || pkt->pkt_err) + streaming_target_deliver2(gh->gh_output, sm); + else + streaming_msg_free(sm); + break; } } - /** * */ -static void -globalheaders_input(void *opaque, streaming_message_t *sm) -{ - globalheaders_t *gh = opaque; +static void globalheaders_input(void* opaque, streaming_message_t* sm) { + globalheaders_t* gh = opaque; - if(gh->gh_passthru) + if (gh->gh_passthru) gh_pass(gh, sm); else gh_hold(gh, sm); } -static htsmsg_t * -globalheaders_input_info(void *opaque, htsmsg_t *list) -{ - globalheaders_t *gh = opaque; - streaming_target_t *st = gh->gh_output; +static htsmsg_t* globalheaders_input_info(void* opaque, htsmsg_t* list) { + globalheaders_t* gh = opaque; + streaming_target_t* st = gh->gh_output; htsmsg_add_str(list, NULL, "globalheaders input"); return st->st_ops.st_info(st->st_opaque, list); } -static streaming_ops_t globalheaders_input_ops = { - .st_cb = globalheaders_input, - .st_info = globalheaders_input_info -}; - +static streaming_ops_t globalheaders_input_ops = {.st_cb = globalheaders_input, + .st_info = globalheaders_input_info}; /** * */ -streaming_target_t * -globalheaders_create(streaming_target_t *output) -{ - globalheaders_t *gh = calloc(1, sizeof(globalheaders_t)); +streaming_target_t* globalheaders_create(streaming_target_t* output) { + globalheaders_t* gh = calloc(1, sizeof(globalheaders_t)); TAILQ_INIT(&gh->gh_holdq); @@ -446,14 +410,11 @@ globalheaders_create(streaming_target_t *output) return &gh->gh_input; } - /** * */ -void -globalheaders_destroy(streaming_target_t *pad) -{ - globalheaders_t *gh = (globalheaders_t *)pad; +void globalheaders_destroy(streaming_target_t* pad) { + globalheaders_t* gh = (globalheaders_t*)pad; gh_flush(gh); free(gh); } diff --git a/src/plumbing/globalheaders.h b/src/plumbing/globalheaders.h index dff742e5f..56db5a6e2 100644 --- a/src/plumbing/globalheaders.h +++ b/src/plumbing/globalheaders.h @@ -21,9 +21,8 @@ #include "tvheadend.h" -streaming_target_t *globalheaders_create(streaming_target_t *output); - -void globalheaders_destroy(streaming_target_t *gh); +streaming_target_t* globalheaders_create(streaming_target_t* output); +void globalheaders_destroy(streaming_target_t* gh); #endif // GLOBALHEADERS_H__ diff --git a/src/plumbing/tsfix.c b/src/plumbing/tsfix.c index 08a4c9498..4f00dc2f5 100644 --- a/src/plumbing/tsfix.c +++ b/src/plumbing/tsfix.c @@ -20,9 +20,9 @@ #include "streaming.h" #include "tsfix.h" -#define REF_OK 0 -#define REF_ERROR 1 -#define REF_DROP 2 +#define REF_OK 0 +#define REF_ERROR 1 +#define REF_DROP 2 LIST_HEAD(tfstream_list, tfstream); @@ -36,11 +36,11 @@ typedef struct tfstream { int tfs_index; streaming_component_type_t tfs_type; - uint8_t tfs_video; - uint8_t tfs_audio; - uint8_t tfs_subtitle; + uint8_t tfs_video; + uint8_t tfs_audio; + uint8_t tfs_subtitle; - int tfs_bad_dts; + int tfs_bad_dts; int64_t tfs_local_ref; int64_t tfs_last_dts_norm; int64_t tfs_dts_epoch; @@ -49,39 +49,35 @@ typedef struct tfstream { int tfs_seen; - struct tfstream *tfs_parent; + struct tfstream* tfs_parent; } tfstream_t; - /** * */ typedef struct tsfix { streaming_target_t tf_input; - streaming_target_t *tf_output; + streaming_target_t* tf_output; struct tfstream_list tf_streams; - int tf_hasvideo; - int tf_wait_for_video; - int64_t tf_tsref; - int64_t tf_start_time; - int64_t dts_offset; - int dts_offset_apply; + int tf_hasvideo; + int tf_wait_for_video; + int64_t tf_tsref; + int64_t tf_start_time; + int64_t dts_offset; + int dts_offset_apply; struct th_pktref_queue tf_ptsq; struct th_pktref_queue tf_backlog; } tsfix_t; - /** * Compute the timestamp deltas */ -static int64_t -tsfix_ts_diff(int64_t ts1, int64_t ts2) -{ +static int64_t tsfix_ts_diff(int64_t ts1, int64_t ts2) { int64_t r; ts1 &= PTS_MASK; ts2 &= PTS_MASK; @@ -101,25 +97,20 @@ tsfix_ts_diff(int64_t ts1, int64_t ts2) /** * */ -static void -tsfix_destroy_streams(tsfix_t *tf) -{ - tfstream_t *tfs; +static void tsfix_destroy_streams(tsfix_t* tf) { + tfstream_t* tfs; pktref_clear_queue(&tf->tf_ptsq); pktref_clear_queue(&tf->tf_backlog); - while((tfs = LIST_FIRST(&tf->tf_streams)) != NULL) { + while ((tfs = LIST_FIRST(&tf->tf_streams)) != NULL) { LIST_REMOVE(tfs, tfs_link); free(tfs); } } - -static tfstream_t * -tfs_find(tsfix_t *tf, th_pkt_t *pkt) -{ - tfstream_t *tfs; - LIST_FOREACH(tfs, &tf->tf_streams, tfs_link) - if(pkt->pkt_componentindex == tfs->tfs_index) +static tfstream_t* tfs_find(tsfix_t* tf, th_pkt_t* pkt) { + tfstream_t* tfs; + LIST_FOREACH (tfs, &tf->tf_streams, tfs_link) + if (pkt->pkt_componentindex == tfs->tfs_index) break; return tfs; } @@ -127,10 +118,8 @@ tfs_find(tsfix_t *tf, th_pkt_t *pkt) /** * */ -static tfstream_t * -tsfix_add_stream(tsfix_t *tf, int index, streaming_component_type_t type) -{ - tfstream_t *tfs = calloc(1, sizeof(tfstream_t)); +static tfstream_t* tsfix_add_stream(tsfix_t* tf, int index, streaming_component_type_t type) { + tfstream_t* tfs = calloc(1, sizeof(tfstream_t)); tfs->tfs_type = type; if (SCT_ISVIDEO(type)) @@ -140,30 +129,27 @@ tsfix_add_stream(tsfix_t *tf, int index, streaming_component_type_t type) else if (SCT_ISSUBTITLE(type)) tfs->tfs_subtitle = 1; - tfs->tfs_index = index; - tfs->tfs_local_ref = PTS_UNSET; + tfs->tfs_index = index; + tfs->tfs_local_ref = PTS_UNSET; tfs->tfs_last_dts_norm = PTS_UNSET; - tfs->tfs_last_dts_in = PTS_UNSET; - tfs->tfs_dts_epoch = 0; - tfs->tfs_seen = 0; + tfs->tfs_last_dts_in = PTS_UNSET; + tfs->tfs_dts_epoch = 0; + tfs->tfs_seen = 0; LIST_INSERT_HEAD(&tf->tf_streams, tfs, tfs_link); return tfs; } - /** * */ -static void -tsfix_start(tsfix_t *tf, streaming_start_t *ss) -{ - int i, hasvideo = 0, vwait = 0; - tfstream_t *tfs; - - for(i = 0; i < ss->ss_num_components; i++) { - const streaming_start_component_t *ssc = &ss->ss_components[i]; - tfs = tsfix_add_stream(tf, ssc->es_index, ssc->es_type); +static void tsfix_start(tsfix_t* tf, streaming_start_t* ss) { + int i, hasvideo = 0, vwait = 0; + tfstream_t* tfs; + + for (i = 0; i < ss->ss_num_components; i++) { + const streaming_start_component_t* ssc = &ss->ss_components[i]; + tfs = tsfix_add_stream(tf, ssc->es_index, ssc->es_type); if (tfs->tfs_video) { if (ssc->es_width == 0 || ssc->es_height == 0) /* only first video stream may be valid */ @@ -175,28 +161,22 @@ tsfix_start(tsfix_t *tf, streaming_start_t *ss) TAILQ_INIT(&tf->tf_ptsq); TAILQ_INIT(&tf->tf_backlog); - tf->tf_tsref = PTS_UNSET; - tf->tf_hasvideo = hasvideo; + tf->tf_tsref = PTS_UNSET; + tf->tf_hasvideo = hasvideo; tf->tf_wait_for_video = vwait; } - /** * */ -static void -tsfix_stop(tsfix_t *tf) -{ +static void tsfix_stop(tsfix_t* tf) { tsfix_destroy_streams(tf); } - /** * */ -static void -tsfix_packet_drop(tfstream_t *tfs, th_pkt_t *pkt, const char *reason) -{ +static void tsfix_packet_drop(tfstream_t* tfs, th_pkt_t* pkt, const char* reason) { if (tvhtrace_enabled()) { char buf[64]; snprintf(buf, sizeof(buf), "drop %s", reason); @@ -208,12 +188,10 @@ tsfix_packet_drop(tfstream_t *tfs, th_pkt_t *pkt, const char *reason) /** * */ -static void -normalize_ts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt, int backlog) -{ +static void normalize_ts(tsfix_t* tf, tfstream_t* tfs, th_pkt_t* pkt, int backlog) { int64_t ref, dts, odts, opts, d; - if(tf->tf_tsref == PTS_UNSET) { + if (tf->tf_tsref == PTS_UNSET) { if (backlog) { if (pkt->pkt_dts != PTS_UNSET) tfs->tfs_seen = 1; @@ -223,7 +201,7 @@ normalize_ts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt, int backlog) return; } - ref = tfs->tfs_local_ref != PTS_UNSET ? tfs->tfs_local_ref : tf->tf_tsref; + ref = tfs->tfs_local_ref != PTS_UNSET ? tfs->tfs_local_ref : tf->tf_tsref; odts = pkt->pkt_dts; opts = pkt->pkt_pts; @@ -249,10 +227,10 @@ normalize_ts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt, int backlog) return; } } else { - const int64_t nlimit = -1; /* allow negative values - rounding errors? */ - int64_t low = 90000; /* one second */ - int64_t upper = 2*90000; /* two seconds */ - d = dts + tfs->tfs_dts_epoch - tfs->tfs_last_dts_norm; + const int64_t nlimit = -1; /* allow negative values - rounding errors? */ + int64_t low = 90000; /* one second */ + int64_t upper = 2 * 90000; /* two seconds */ + d = dts + tfs->tfs_dts_epoch - tfs->tfs_last_dts_norm; if (tfs->tfs_subtitle) { /* @@ -269,18 +247,19 @@ normalize_ts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt, int backlog) tsfix_packet_drop(tfs, pkt, "possible wrong discontinuity"); return; } - tfs->tfs_bad_dts++; + tfs->tfs_bad_dts++; if (tfs->tfs_bad_dts < 5) { - tvhwarn(LS_TSFIX, - "transport stream %s, DTS discontinuity. " - "DTS = %" PRId64 ", last = %" PRId64, - streaming_component_type2txt(tfs->tfs_type), - dts, tfs->tfs_last_dts_norm); - } + tvhwarn(LS_TSFIX, + "transport stream %s, DTS discontinuity. " + "DTS = %" PRId64 ", last = %" PRId64, + streaming_component_type2txt(tfs->tfs_type), + dts, + tfs->tfs_last_dts_norm); + } } else { - /* DTS wrapped, increase upper bits */ - tfs->tfs_dts_epoch += PTS_MASK + 1; - tfs->tfs_bad_dts = 0; + /* DTS wrapped, increase upper bits */ + tfs->tfs_dts_epoch += PTS_MASK + 1; + tfs->tfs_bad_dts = 0; } } else { tfs->tfs_bad_dts = 0; @@ -290,12 +269,12 @@ normalize_ts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt, int backlog) dts += tfs->tfs_dts_epoch; tfs->tfs_last_dts_norm = dts; - if(pkt->pkt_pts != PTS_UNSET) { + if (pkt->pkt_pts != PTS_UNSET) { /* Compute delta between PTS and DTS (and watch out for 33 bit wrap) */ - d = ((pkt->pkt_pts & PTS_MASK) - pkt->pkt_dts) & PTS_MASK; + d = ((pkt->pkt_pts & PTS_MASK) - pkt->pkt_dts) & PTS_MASK; pkt->pkt_pts = dts + d; } - if(pkt->pkt_pcr != PTS_UNSET) { + if (pkt->pkt_pcr != PTS_UNSET) { /* Compute delta between PCR and DTS (and watch out for 33 bit wrap) */ d = ((pkt->pkt_pcr & PTS_MASK) - pkt->pkt_dts) & PTS_MASK; if (d > PTS_MASK / 2) @@ -313,13 +292,16 @@ normalize_ts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt, int backlog) deliver: if (tvhtrace_enabled()) { char _odts[22], _opts[22]; - pkt_trace(LS_TSFIX, pkt, - "deliver odts %s opts %s ref %"PRId64" epoch %"PRId64, - pts_to_string(odts, _odts), pts_to_string(opts, _opts), - ref, tfs->tfs_dts_epoch); + pkt_trace(LS_TSFIX, + pkt, + "deliver odts %s opts %s ref %" PRId64 " epoch %" PRId64, + pts_to_string(odts, _odts), + pts_to_string(opts, _opts), + ref, + tfs->tfs_dts_epoch); } - streaming_message_t *sm = streaming_msg_create_pkt(pkt); + streaming_message_t* sm = streaming_msg_create_pkt(pkt); streaming_target_deliver2(tf->tf_output, sm); pkt_ref_dec(pkt); } @@ -327,22 +309,16 @@ deliver: /** * */ -static inline int -txfix_need_to_update_ref(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt) -{ - return tfs->tfs_local_ref == PTS_UNSET && - tf->tf_tsref != PTS_UNSET && - pkt->pkt_dts != PTS_UNSET; +static inline int txfix_need_to_update_ref(tsfix_t* tf, tfstream_t* tfs, th_pkt_t* pkt) { + return tfs->tfs_local_ref == PTS_UNSET && tf->tf_tsref != PTS_UNSET && pkt->pkt_dts != PTS_UNSET; } /** * */ -static int -tsfix_update_ref(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt) -{ - tfstream_t *tfs2; - int64_t diff; +static int tsfix_update_ref(tsfix_t* tf, tfstream_t* tfs, th_pkt_t* pkt) { + tfstream_t* tfs2; + int64_t diff; if (pkt->pkt_err) return REF_ERROR; @@ -350,21 +326,25 @@ tsfix_update_ref(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt) if (tfs->tfs_audio) { diff = tsfix_ts_diff(tf->tf_tsref, pkt->pkt_dts); if (diff > 3 * 90000) { - tvhwarn(LS_TSFIX, "The timediff for %s is big (%"PRId64"), using current dts", - streaming_component_type2txt(tfs->tfs_type), diff); + tvhwarn(LS_TSFIX, + "The timediff for %s is big (%" PRId64 "), using current dts", + streaming_component_type2txt(tfs->tfs_type), + diff); tfs->tfs_local_ref = pkt->pkt_dts; } else { tfs->tfs_local_ref = tf->tf_tsref; } } else if (tfs->tfs_type == SCT_DVBSUB || tfs->tfs_type == SCT_TEXTSUB) { /* find first valid audio stream and check the dts timediffs */ - LIST_FOREACH(tfs2, &tf->tf_streams, tfs_link) + LIST_FOREACH (tfs2, &tf->tf_streams, tfs_link) if (tfs2->tfs_audio && tfs2->tfs_last_dts_in != PTS_UNSET) { diff = tsfix_ts_diff(tfs2->tfs_last_dts_in, pkt->pkt_dts); if (diff > 6 * 90000) { - tvhwarn(LS_TSFIX, "The timediff for %s is big (%"PRId64"), using audio dts", - streaming_component_type2txt(tfs->tfs_type), diff); - tfs->tfs_parent = tfs2; + tvhwarn(LS_TSFIX, + "The timediff for %s is big (%" PRId64 "), using audio dts", + streaming_component_type2txt(tfs->tfs_type), + diff); + tfs->tfs_parent = tfs2; tfs->tfs_local_ref = tfs2->tfs_local_ref; } else { tfs->tfs_local_ref = tf->tf_tsref; @@ -376,7 +356,7 @@ tsfix_update_ref(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt) } else if (tfs->tfs_type == SCT_TELETEXT) { diff = tsfix_ts_diff(tf->tf_tsref, pkt->pkt_dts); if (diff > 2 * 90000) { - tvhwarn(LS_TSFIX, "The timediff for TELETEXT is big (%"PRId64"), using current dts", diff); + tvhwarn(LS_TSFIX, "The timediff for TELETEXT is big (%" PRId64 "), using current dts", diff); tfs->tfs_local_ref = pkt->pkt_dts; } else { tfs->tfs_local_ref = tf->tf_tsref; @@ -388,14 +368,12 @@ tsfix_update_ref(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt) /** * */ -static void -tsfix_backlog(tsfix_t *tf) -{ - th_pkt_t *pkt; - tfstream_t *tfs; - int r; - - while((pkt = pktref_get_first(&tf->tf_backlog)) != NULL) { +static void tsfix_backlog(tsfix_t* tf) { + th_pkt_t* pkt; + tfstream_t* tfs; + int r; + + while ((pkt = pktref_get_first(&tf->tf_backlog)) != NULL) { tfs = tfs_find(tf, pkt); if (txfix_need_to_update_ref(tf, tfs, pkt)) { r = tsfix_update_ref(tf, tfs, pkt); @@ -408,32 +386,31 @@ tsfix_backlog(tsfix_t *tf) } } - /** * */ -static int64_t -tsfix_backlog_diff(tsfix_t *tf) -{ - th_pkt_t *pkt; - th_pktref_t *pr; - tfstream_t *tfs; - int64_t res = 0; +static int64_t tsfix_backlog_diff(tsfix_t* tf) { + th_pkt_t* pkt; + th_pktref_t* pr; + tfstream_t* tfs; + int64_t res = 0; PKTREF_FOREACH(pr, &tf->tf_backlog) { pkt = pr->pr_pkt; - if (pkt->pkt_dts == PTS_UNSET) continue; - if (pkt->pkt_dts >= tf->tf_tsref) continue; - if (tf->tf_tsref > (PTS_MASK * 3) / 4 && - pkt->pkt_dts < PTS_MASK / 4) continue; + if (pkt->pkt_dts == PTS_UNSET) + continue; + if (pkt->pkt_dts >= tf->tf_tsref) + continue; + if (tf->tf_tsref > (PTS_MASK * 3) / 4 && pkt->pkt_dts < PTS_MASK / 4) + continue; tfs = tfs_find(tf, pkt); - if (!tfs->tfs_audio && !tfs->tfs_video) continue; + if (!tfs->tfs_audio && !tfs->tfs_video) + continue; res = MAX(tsfix_ts_diff(pkt->pkt_dts, tf->tf_tsref), res); } return res; } - /** * * Recover unset PTS. @@ -453,105 +430,103 @@ tsfix_backlog_diff(tsfix_t *tf) * 12: B dts 4922741536 pts rpts 4922741536 * 13: I dts 4922745136 pts 4922755936 rpts 4922755936 */ -static void -recover_pts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt) -{ - th_pktref_t *srch; - int total; +static void recover_pts(tsfix_t* tf, tfstream_t* tfs, th_pkt_t* pkt) { + th_pktref_t* srch; + int total; pktref_enqueue(&tf->tf_ptsq, pkt); - while((pkt = pktref_get_first(&tf->tf_ptsq)) != NULL) { + while ((pkt = pktref_get_first(&tf->tf_ptsq)) != NULL) { tfs = tfs_find(tf, pkt); - switch(tfs->tfs_type) { + switch (tfs->tfs_type) { - case SCT_MPEG2VIDEO: + case SCT_MPEG2VIDEO: - switch(pkt->v.pkt_frametype) { - case PKT_B_FRAME: - if (pkt->pkt_pts == PTS_UNSET) { - /* B-frames have same PTS as DTS, pass them on */ - tvhtrace(LS_TSFIX, "%-12s PTS b-frame set to %"PRId64" (old %"PRId64")", - streaming_component_type2txt(tfs->tfs_type), - pkt->pkt_dts, pkt->pkt_pts); - pkt->pkt_pts = pkt->pkt_dts; - } - break; - - case PKT_I_FRAME: - case PKT_P_FRAME: - if (pkt->pkt_pts == PTS_UNSET) { - /* Presentation occures at DTS of next I or P frame, - try to find it */ - total = 0; - PKTREF_FOREACH(srch, &tf->tf_ptsq) { - if (pkt->pkt_componentindex != tfs->tfs_index) - continue; - total++; - if (srch->pr_pkt->v.pkt_frametype <= PKT_P_FRAME && - pts_is_greater_or_equal(pkt->pkt_dts, srch->pr_pkt->pkt_dts) > 0 && - pts_diff(pkt->pkt_dts, srch->pr_pkt->pkt_dts) < 10 * 90000) { - tvhtrace(LS_TSFIX, "%-12s PTS *-frame set to %"PRId64" (old %"PRId64"), DTS %"PRId64, - streaming_component_type2txt(tfs->tfs_type), - srch->pr_pkt->pkt_dts, pkt->pkt_pts, pkt->pkt_dts); - pkt->pkt_pts = srch->pr_pkt->pkt_dts; - break; - } - } - if (srch == NULL) { - if (total < 50) { - /* return packet back to tf_ptsq */ - pktref_insert_head(&tf->tf_ptsq, pkt); - } else { - tsfix_packet_drop(tfs, pkt, "mpeg2video overflow"); + switch (pkt->v.pkt_frametype) { + case PKT_B_FRAME: + if (pkt->pkt_pts == PTS_UNSET) { + /* B-frames have same PTS as DTS, pass them on */ + tvhtrace(LS_TSFIX, + "%-12s PTS b-frame set to %" PRId64 " (old %" PRId64 ")", + streaming_component_type2txt(tfs->tfs_type), + pkt->pkt_dts, + pkt->pkt_pts); + pkt->pkt_pts = pkt->pkt_dts; + } + break; + + case PKT_I_FRAME: + case PKT_P_FRAME: + if (pkt->pkt_pts == PTS_UNSET) { + /* Presentation occures at DTS of next I or P frame, + try to find it */ + total = 0; + PKTREF_FOREACH(srch, &tf->tf_ptsq) { + if (pkt->pkt_componentindex != tfs->tfs_index) + continue; + total++; + if (srch->pr_pkt->v.pkt_frametype <= PKT_P_FRAME && + pts_is_greater_or_equal(pkt->pkt_dts, srch->pr_pkt->pkt_dts) > 0 && + pts_diff(pkt->pkt_dts, srch->pr_pkt->pkt_dts) < 10 * 90000) { + tvhtrace(LS_TSFIX, + "%-12s PTS *-frame set to %" PRId64 " (old %" PRId64 "), DTS %" PRId64, + streaming_component_type2txt(tfs->tfs_type), + srch->pr_pkt->pkt_dts, + pkt->pkt_pts, + pkt->pkt_dts); + pkt->pkt_pts = srch->pr_pkt->pkt_dts; + break; + } + } + if (srch == NULL) { + if (total < 50) { + /* return packet back to tf_ptsq */ + pktref_insert_head(&tf->tf_ptsq, pkt); + } else { + tsfix_packet_drop(tfs, pkt, "mpeg2video overflow"); + } + return; /* not arrived yet or invalid, wait */ + } } - return; /* not arrived yet or invalid, wait */ - } } - } - break; + break; - default: - break; + default: + break; } normalize_ts(tf, tfs, pkt, 1); } } - /** * Compute PTS (if not known) */ -static void -compute_pts(tsfix_t *tf, tfstream_t *tfs, th_pkt_t *pkt) -{ +static void compute_pts(tsfix_t* tf, tfstream_t* tfs, th_pkt_t* pkt) { // If PTS is missing, set it to DTS if not video - if(pkt->pkt_pts == PTS_UNSET && !tfs->tfs_video) { + if (pkt->pkt_pts == PTS_UNSET && !tfs->tfs_video) { pkt->pkt_pts = pkt->pkt_dts; - tvhtrace(LS_TSFIX, "%-12s PTS set to %"PRId64, - streaming_component_type2txt(tfs->tfs_type), - pkt->pkt_pts); + tvhtrace(LS_TSFIX, + "%-12s PTS set to %" PRId64, + streaming_component_type2txt(tfs->tfs_type), + pkt->pkt_pts); } /* PTS known and no other packets in queue, deliver at once */ - if(pkt->pkt_pts != PTS_UNSET && TAILQ_FIRST(&tf->tf_ptsq) == NULL) + if (pkt->pkt_pts != PTS_UNSET && TAILQ_FIRST(&tf->tf_ptsq) == NULL) normalize_ts(tf, tfs, pkt, 1); else recover_pts(tf, tfs, pkt); } - /** * */ -static void -tsfix_input_packet(tsfix_t *tf, streaming_message_t *sm) -{ - th_pkt_t *pkt; +static void tsfix_input_packet(tsfix_t* tf, streaming_message_t* sm) { + th_pkt_t* pkt; tfstream_t *tfs, *tfs2; - int64_t diff, diff2, threshold; - int r; + int64_t diff, diff2, threshold; + int r; pkt = pkt_copy_shallow(sm->sm_data); tfs = tfs_find(tf, pkt); @@ -564,13 +539,13 @@ tsfix_input_packet(tsfix_t *tf, streaming_message_t *sm) if (tf->tf_tsref == PTS_UNSET && pkt->pkt_dts != PTS_UNSET && ((!tf->tf_hasvideo && tfs->tfs_audio) || - (tfs->tfs_video && pkt->v.pkt_frametype == PKT_I_FRAME))) { + (tfs->tfs_video && pkt->v.pkt_frametype == PKT_I_FRAME))) { if (pkt->pkt_err) { tsfix_packet_drop(tfs, pkt, "ref1"); return; } threshold = 22500; - LIST_FOREACH(tfs2, &tf->tf_streams, tfs_link) + LIST_FOREACH (tfs2, &tf->tf_streams, tfs_link) if (tfs != tfs2 && (tfs2->tfs_audio || tfs2->tfs_video) && !tfs2->tfs_seen) { threshold = 90000; break; @@ -583,10 +558,22 @@ tsfix_input_packet(tsfix_t *tf, streaming_message_t *sm) if (diff > 160000) diff = 160000; tf->tf_tsref = (tf->tf_tsref - diff) % PTS_MASK; - tvhtrace(LS_TSFIX, "reference clock set to %"PRId64" (dts %"PRId64" pcr %"PRId64" backlog %"PRId64")", tf->tf_tsref, pkt->pkt_dts, pkt->pkt_pcr, diff2); + tvhtrace(LS_TSFIX, + "reference clock set to %" PRId64 " (dts %" PRId64 " pcr %" PRId64 " backlog %" PRId64 + ")", + tf->tf_tsref, + pkt->pkt_dts, + pkt->pkt_pcr, + diff2); tsfix_backlog(tf); } else { - tvhtrace(LS_TSFIX, "reference clock set to %"PRId64" (dts %"PRId64" pcr %"PRId64" backlog %"PRId64")", tf->tf_tsref, pkt->pkt_dts, pkt->pkt_pcr, diff2); + tvhtrace(LS_TSFIX, + "reference clock set to %" PRId64 " (dts %" PRId64 " pcr %" PRId64 " backlog %" PRId64 + ")", + tf->tf_tsref, + pkt->pkt_dts, + pkt->pkt_pcr, + diff2); } } else if (txfix_need_to_update_ref(tf, tfs, pkt)) { r = tsfix_update_ref(tf, tfs, pkt); @@ -610,9 +597,13 @@ tsfix_input_packet(tsfix_t *tf, streaming_message_t *sm) if (pkt->pkt_payload != NULL || pkt->pkt_pts != PTS_UNSET) { pkt->pkt_dts = (tfs->tfs_last_dts_in + pdur) & PTS_MASK; - tvhtrace(LS_TSFIX, "%-12s DTS set to last %"PRId64" +%d == %"PRId64", PTS = %"PRId64, - streaming_component_type2txt(tfs->tfs_type), - tfs->tfs_last_dts_in, pdur, pkt->pkt_dts, pkt->pkt_pts); + tvhtrace(LS_TSFIX, + "%-12s DTS set to last %" PRId64 " +%d == %" PRId64 ", PTS = %" PRId64, + streaming_component_type2txt(tfs->tfs_type), + tfs->tfs_last_dts_in, + pdur, + pkt->pkt_dts, + pkt->pkt_pts); } } @@ -624,90 +615,79 @@ tsfix_input_packet(tsfix_t *tf, streaming_message_t *sm) compute_pts(tf, tfs, pkt); } - /** * */ -static void -tsfix_input(void *opaque, streaming_message_t *sm) -{ - tsfix_t *tf = opaque; - - switch(sm->sm_type) { - case SMT_PACKET: - if (tf->tf_wait_for_video) { - streaming_msg_free(sm); +static void tsfix_input(void* opaque, streaming_message_t* sm) { + tsfix_t* tf = opaque; + + switch (sm->sm_type) { + case SMT_PACKET: + if (tf->tf_wait_for_video) { + streaming_msg_free(sm); + return; + } + tsfix_input_packet(tf, sm); return; - } - tsfix_input_packet(tf, sm); - return; - case SMT_START: - tsfix_stop(tf); - tsfix_start(tf, sm->sm_data); - if (tf->tf_wait_for_video) { + case SMT_START: + tsfix_stop(tf); + tsfix_start(tf, sm->sm_data); + if (tf->tf_wait_for_video) { + streaming_msg_free(sm); + return; + } + break; + case SMT_STOP: + tsfix_stop(tf); + break; + case SMT_TIMESHIFT_STATUS: + if (tf->dts_offset == PTS_UNSET) { + timeshift_status_t* status; + status = sm->sm_data; + tf->dts_offset = status->shift; + } streaming_msg_free(sm); return; - } - break; - case SMT_STOP: - tsfix_stop(tf); - break; - case SMT_TIMESHIFT_STATUS: - if(tf->dts_offset == PTS_UNSET) { - timeshift_status_t *status; - status = sm->sm_data; - tf->dts_offset = status->shift; - } - streaming_msg_free(sm); - return; - case SMT_SKIP: - if(tf->dts_offset != PTS_UNSET) { - tf->dts_offset_apply = 1; - } - break; - case SMT_GRACE: - case SMT_EXIT: - case SMT_SERVICE_STATUS: - case SMT_SIGNAL_STATUS: - case SMT_DESCRAMBLE_INFO: - case SMT_NOSTART: - case SMT_NOSTART_WARN: - case SMT_MPEGTS: - case SMT_SPEED: - break; + case SMT_SKIP: + if (tf->dts_offset != PTS_UNSET) { + tf->dts_offset_apply = 1; + } + break; + case SMT_GRACE: + case SMT_EXIT: + case SMT_SERVICE_STATUS: + case SMT_SIGNAL_STATUS: + case SMT_DESCRAMBLE_INFO: + case SMT_NOSTART: + case SMT_NOSTART_WARN: + case SMT_MPEGTS: + case SMT_SPEED: + break; } streaming_target_deliver2(tf->tf_output, sm); } -static htsmsg_t * -tsfix_input_info(void *opaque, htsmsg_t *list) -{ - tsfix_t *tf = opaque; - streaming_target_t *st = tf->tf_output; +static htsmsg_t* tsfix_input_info(void* opaque, htsmsg_t* list) { + tsfix_t* tf = opaque; + streaming_target_t* st = tf->tf_output; htsmsg_add_str(list, NULL, "tsfix input"); return st->st_ops.st_info(st->st_opaque, list); } -static streaming_ops_t tsfix_input_ops = { - .st_cb = tsfix_input, - .st_info = tsfix_input_info -}; - +static streaming_ops_t tsfix_input_ops = {.st_cb = tsfix_input, .st_info = tsfix_input_info}; /** * */ -streaming_target_t * -tsfix_create(streaming_target_t *output) -{ - tsfix_t *tf = calloc(1, sizeof(tsfix_t)); +streaming_target_t* tsfix_create(streaming_target_t* output) { + tsfix_t* tf = calloc(1, sizeof(tsfix_t)); TAILQ_INIT(&tf->tf_ptsq); - tf->tf_output = output; + tf->tf_output = output; tf->tf_start_time = mclk(); - tf->dts_offset = PTS_UNSET; + tf->dts_offset = PTS_UNSET; streaming_target_init(&tf->tf_input, &tsfix_input_ops, tf, 0); return &tf->tf_input; } @@ -715,10 +695,8 @@ tsfix_create(streaming_target_t *output) /** * */ -void -tsfix_destroy(streaming_target_t *pad) -{ - tsfix_t *tf = (tsfix_t *)pad; +void tsfix_destroy(streaming_target_t* pad) { + tsfix_t* tf = (tsfix_t*)pad; tsfix_destroy_streams(tf); free(tf); diff --git a/src/plumbing/tsfix.h b/src/plumbing/tsfix.h index 7e6f7bd0b..80d546390 100644 --- a/src/plumbing/tsfix.h +++ b/src/plumbing/tsfix.h @@ -21,9 +21,8 @@ #include "tvheadend.h" -streaming_target_t *tsfix_create(streaming_target_t *output); - -void tsfix_destroy(streaming_target_t *gh); +streaming_target_t* tsfix_create(streaming_target_t* output); +void tsfix_destroy(streaming_target_t* gh); #endif // TSFIX_H__ diff --git a/src/profile.c b/src/profile.c index 3a0bc8d62..5de8682bc 100644 --- a/src/profile.c +++ b/src/profile.c @@ -39,22 +39,20 @@ extern const idclass_t profile_htsp_class; profile_builders_queue profile_builders; struct profile_entry_queue profiles; -static LIST_HEAD(,profile_chain) profile_chains; +static LIST_HEAD(, profile_chain) profile_chains; -static profile_t *profile_default; +static profile_t* profile_default; /* * */ -void -profile_register(const idclass_t *clazz, profile_builder_t builder) -{ +void profile_register(const idclass_t* clazz, profile_builder_t builder) { profile_build_t *pb = calloc(1, sizeof(*pb)), *pb2; idclass_register(clazz); pb->clazz = clazz; pb->build = builder; - pb2 = LIST_FIRST(&profile_builders); + pb2 = LIST_FIRST(&profile_builders); if (pb2) { /* append tail */ while (LIST_NEXT(pb2, link)) @@ -65,24 +63,19 @@ profile_register(const idclass_t *clazz, profile_builder_t builder) } } -static profile_build_t * -profile_class_find(const char *name) -{ - profile_build_t *pb; - LIST_FOREACH(pb, &profile_builders, link) { +static profile_build_t* profile_class_find(const char* name) { + profile_build_t* pb; + LIST_FOREACH (pb, &profile_builders, link) { if (strcmp(pb->clazz->ic_class, name) == 0) return pb; } return NULL; } -profile_t * -profile_create - (const char *uuid, htsmsg_t *conf, int save) -{ - profile_t *pro = NULL; - profile_build_t *pb = NULL; - const char *s; +profile_t* profile_create(const char* uuid, htsmsg_t* conf, int save) { + profile_t* pro = NULL; + profile_build_t* pb = NULL; + const char* s; lock_assert(&global_lock); @@ -99,7 +92,7 @@ profile_create } LIST_INIT(&pro->pro_dvr_configs); LIST_INIT(&pro->pro_accesses); - pro->pro_swservice = 1; + pro->pro_swservice = 1; pro->pro_contaccess = 1; pro->pro_ca_timeout = 2000; if (idnode_insert(&pro->pro_id, uuid, pb->clazz, 0)) { @@ -123,9 +116,7 @@ profile_create return pro; } -void -profile_release_(profile_t *pro) -{ +void profile_release_(profile_t* pro) { if (pro->pro_free) pro->pro_free(pro); free(pro->pro_name); @@ -133,9 +124,7 @@ profile_release_(profile_t *pro) free(pro); } -static void -profile_delete(profile_t *pro, int delconf) -{ +static void profile_delete(profile_t* pro, int delconf) { char ubuf[UUID_HEX_SIZE]; idnode_save_check(&pro->pro_id, delconf); pro->pro_enabled = 0; @@ -150,12 +139,10 @@ profile_delete(profile_t *pro, int delconf) profile_release(pro); } -static htsmsg_t * -profile_class_save ( idnode_t *in, char *filename, size_t fsize ) -{ - profile_t *pro = (profile_t *)in; - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* profile_class_save(idnode_t* in, char* filename, size_t fsize) { + profile_t* pro = (profile_t*)in; + htsmsg_t* c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; if (pro == profile_default) pro->pro_enabled = 1; idnode_save(in, c); @@ -168,11 +155,8 @@ profile_class_save ( idnode_t *in, char *filename, size_t fsize ) return c; } -static void -profile_class_get_title - ( idnode_t *in, const char *lang, char *dst, size_t dstsize ) -{ - profile_t *pro = (profile_t *)in; +static void profile_class_get_title(idnode_t* in, const char* lang, char* dst, size_t dstsize) { + profile_t* pro = (profile_t*)in; if (pro->pro_name && pro->pro_name[0]) { snprintf(dst, dstsize, "%s", pro->pro_name); } else { @@ -180,55 +164,43 @@ profile_class_get_title } } -static void -profile_class_delete(idnode_t *self) -{ - profile_t *pro = (profile_t *)self; +static void profile_class_delete(idnode_t* self) { + profile_t* pro = (profile_t*)self; if (pro->pro_shield) return; profile_delete(pro, 1); } -static uint32_t -profile_class_enabled_opts(void *o, uint32_t opts) -{ - profile_t *pro = o; - uint32_t r = 0; +static uint32_t profile_class_enabled_opts(void* o, uint32_t opts) { + profile_t* pro = o; + uint32_t r = 0; if (pro && profile_default == pro) r |= PO_RDONLY; return r; } -static const void * -profile_class_class_get(void *o) -{ - profile_t *pro = o; - static const char *ret; +static const void* profile_class_class_get(void* o) { + profile_t* pro = o; + static const char* ret; ret = pro->pro_id.in_class->ic_class; return &ret; } -static int -profile_class_class_set(void *o, const void *v) -{ +static int profile_class_class_set(void* o, const void* v) { /* just ignore, create fcn does the right job */ return 0; } -static const void * -profile_class_default_get(void *o) -{ +static const void* profile_class_default_get(void* o) { static int res; res = o == profile_default; return &res; } -static int -profile_class_default_set(void *o, const void *v) -{ +static int profile_class_default_set(void* o, const void* v) { profile_t *pro = o, *old; - if (*(int *)v && pro != profile_default) { - old = profile_default; + if (*(int*)v && pro != profile_default) { + old = profile_default; profile_default = pro; if (old) idnode_changed(&old->pro_id); @@ -237,248 +209,215 @@ profile_class_default_set(void *o, const void *v) return 0; } -static uint32_t -profile_class_name_opts(void *o, uint32_t opts) -{ - profile_t *pro = o; - uint32_t r = 0; +static uint32_t profile_class_name_opts(void* o, uint32_t opts) { + profile_t* pro = o; + uint32_t r = 0; if (pro && pro->pro_shield) r |= PO_RDONLY; return r; } -static htsmsg_t * -profile_class_priority_list ( void *o, const char *lang ) -{ +static htsmsg_t* profile_class_priority_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Unset (default)"), PROFILE_SPRIO_NOTSET }, - { N_("Important"), PROFILE_SPRIO_IMPORTANT }, - { N_("High"), PROFILE_SPRIO_HIGH, }, - { N_("Normal"), PROFILE_SPRIO_NORMAL }, - { N_("Low"), PROFILE_SPRIO_LOW }, - { N_("Unimportant"), PROFILE_SPRIO_UNIMPORTANT }, - { N_("DVR override: important"), PROFILE_SPRIO_DVR_IMPORTANT }, - { N_("DVR override: high"), PROFILE_SPRIO_DVR_HIGH }, - { N_("DVR override: normal"), PROFILE_SPRIO_DVR_NORMAL }, - { N_("DVR override: low"), PROFILE_SPRIO_DVR_LOW }, - { N_("DVR override: unimportant"), PROFILE_SPRIO_DVR_UNIMPORTANT }, + {N_("Unset (default)"), PROFILE_SPRIO_NOTSET}, + {N_("Important"), PROFILE_SPRIO_IMPORTANT}, + { + N_("High"), + PROFILE_SPRIO_HIGH, + }, + {N_("Normal"), PROFILE_SPRIO_NORMAL}, + {N_("Low"), PROFILE_SPRIO_LOW}, + {N_("Unimportant"), PROFILE_SPRIO_UNIMPORTANT}, + {N_("DVR override: important"), PROFILE_SPRIO_DVR_IMPORTANT}, + {N_("DVR override: high"), PROFILE_SPRIO_DVR_HIGH}, + {N_("DVR override: normal"), PROFILE_SPRIO_DVR_NORMAL}, + {N_("DVR override: low"), PROFILE_SPRIO_DVR_LOW}, + {N_("DVR override: unimportant"), PROFILE_SPRIO_DVR_UNIMPORTANT}, }; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -profile_class_svfilter_list ( void *o, const char *lang ) -{ +static htsmsg_t* profile_class_svfilter_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("None"), PROFILE_SVF_NONE }, - { N_("SD: standard definition"), PROFILE_SVF_SD }, - { N_("HD: high definition"), PROFILE_SVF_HD }, - { N_("FHD: full high definition"), PROFILE_SVF_FHD }, - { N_("UHD: ultra high definition"), PROFILE_SVF_UHD }, + {N_("None"), PROFILE_SVF_NONE}, + {N_("SD: standard definition"), PROFILE_SVF_SD}, + {N_("HD: high definition"), PROFILE_SVF_HD}, + {N_("FHD: full high definition"), PROFILE_SVF_FHD}, + {N_("UHD: ultra high definition"), PROFILE_SVF_UHD}, }; return strtab2htsmsg(tab, 1, lang); } CLASS_DOC(profile) -const idclass_t profile_class = -{ - .ic_class = "profile", - .ic_caption = N_("Stream - Stream Profiles"), - .ic_event = "profile", - .ic_doc = tvh_doc_profile_class, - .ic_perm_def = ACCESS_ADMIN, - .ic_save = profile_class_save, - .ic_get_title = profile_class_get_title, - .ic_delete = profile_class_delete, - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "class", - .name = N_("Class"), - .opts = PO_RDONLY | PO_HIDDEN, - .get = profile_class_class_get, - .set = profile_class_class_set, - .group = 1 - }, - { - .type = PT_STR, - .id = "name", - .name = N_("Profile name"), - .desc = N_("The name of the profile."), - .off = offsetof(profile_t, pro_name), - .get_opts = profile_class_name_opts, - .notify = idnode_notify_title_changed_lang, - .group = 1 - }, - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable profile."), - .off = offsetof(profile_t, pro_enabled), - .get_opts = profile_class_enabled_opts, - .group = 1, - .def.i = 1 - }, - { - .type = PT_BOOL, - .id = "default", - .name = N_("Default"), - .desc = N_("Set as default profile."), - .set = profile_class_default_set, - .get = profile_class_default_get, - .opts = PO_EXPERT, - .group = 1 - }, - { - .type = PT_STR, - .id = "comment", - .name = N_("Comment"), - .desc = N_("Free-form text field. You can enter whatever you " - "like here."), - .off = offsetof(profile_t, pro_comment), - .group = 1 - }, - { - .type = PT_INT, - .id = "timeout", - .name = N_("Data timeout (sec) (0=infinite)"), - .desc = N_("The number of seconds to wait for data. " - "It handles the situations where no data " - "are received at start or the input stream " - "is stalled."), - .off = offsetof(profile_t, pro_timeout), - .def.i = 5, - .group = 1 - }, - { - .type = PT_INT, - .id = "priority", - .name = N_("Default priority"), - .desc = N_("If no specific priority was requested. This " - "gives certain users a higher priority by " - "assigning a streaming profile with a higher " - "priority."), - .list = profile_class_priority_list, - .off = offsetof(profile_t, pro_prio), - .opts = PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, - .def.i = PROFILE_SPRIO_NORMAL, - .group = 1 - }, - { - .type = PT_INT, - .id = "fpriority", - .name = N_("Force priority"), - .desc = N_("Force profile to use this priority."), - .off = offsetof(profile_t, pro_fprio), - .opts = PO_EXPERT, - .group = 1 - }, - { - .type = PT_BOOL, - .id = "restart", - .name = N_("Restart on error"), - .desc = N_("Restart streaming on error. This is useful for " - "DVR so a recording isn't aborted if an error occurs."), - .off = offsetof(profile_t, pro_restart), - .opts = PO_EXPERT, - .def.i = 0, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "contaccess", - .name = N_("Continue if descrambling fails"), - .desc = N_("Don't abort streaming when an encrypted stream " - "can't be decrypted by a CA client that normally " - "should be able to decrypt the stream."), - .off = offsetof(profile_t, pro_contaccess), - .opts = PO_EXPERT, - .def.i = 1, - .group = 1, - }, - { - .type = PT_INT, - .id = "catimeout", - .name = N_("Descrambling timeout (ms)"), - .desc = N_("Check the descrambling status after this timeout."), - .off = offsetof(profile_t, pro_ca_timeout), - .opts = PO_EXPERT, - .def.i = 2000, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "swservice", - .name = N_("Switch to another service"), - .desc = N_("If something fails, try to switch to a different " - "service on another network. Do not try to iterate " - "through all inputs/tuners which are capable to " - "receive the service."), - .off = offsetof(profile_t, pro_swservice), - .opts = PO_EXPERT, - .def.i = 1, - .group = 1 - }, - { - .type = PT_INT, - .id = "svfilter", - .name = N_("Preferred service video type"), - .desc = N_("The selected video type should be preferred when " - "multiple services are available for a channel."), - .list = profile_class_svfilter_list, - .off = offsetof(profile_t, pro_svfilter), - .opts = PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, - .def.i = PROFILE_SVF_NONE, - .group = 1 - }, - { } - } -}; +const idclass_t profile_class = {.ic_class = "profile", + .ic_caption = N_("Stream - Stream Profiles"), + .ic_event = "profile", + .ic_doc = tvh_doc_profile_class, + .ic_perm_def = ACCESS_ADMIN, + .ic_save = profile_class_save, + .ic_get_title = profile_class_get_title, + .ic_delete = profile_class_delete, + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + {}}, + .ic_properties = (const property_t[]){{.type = PT_STR, + .id = "class", + .name = N_("Class"), + .opts = PO_RDONLY | PO_HIDDEN, + .get = profile_class_class_get, + .set = profile_class_class_set, + .group = 1}, + {.type = PT_STR, + .id = "name", + .name = N_("Profile name"), + .desc = N_("The name of the profile."), + .off = offsetof(profile_t, pro_name), + .get_opts = profile_class_name_opts, + .notify = idnode_notify_title_changed_lang, + .group = 1}, + {.type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable profile."), + .off = offsetof(profile_t, pro_enabled), + .get_opts = profile_class_enabled_opts, + .group = 1, + .def.i = 1}, + {.type = PT_BOOL, + .id = "default", + .name = N_("Default"), + .desc = N_("Set as default profile."), + .set = profile_class_default_set, + .get = profile_class_default_get, + .opts = PO_EXPERT, + .group = 1}, + {.type = PT_STR, + .id = "comment", + .name = N_("Comment"), + .desc = N_("Free-form text field. You can enter whatever you " + "like here."), + .off = offsetof(profile_t, pro_comment), + .group = 1}, + {.type = PT_INT, + .id = "timeout", + .name = N_("Data timeout (sec) (0=infinite)"), + .desc = N_("The number of seconds to wait for data. " + "It handles the situations where no data " + "are received at start or the input stream " + "is stalled."), + .off = offsetof(profile_t, pro_timeout), + .def.i = 5, + .group = 1}, + {.type = PT_INT, + .id = "priority", + .name = N_("Default priority"), + .desc = N_("If no specific priority was requested. This " + "gives certain users a higher priority by " + "assigning a streaming profile with a higher " + "priority."), + .list = profile_class_priority_list, + .off = offsetof(profile_t, pro_prio), + .opts = PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, + .def.i = PROFILE_SPRIO_NORMAL, + .group = 1}, + {.type = PT_INT, + .id = "fpriority", + .name = N_("Force priority"), + .desc = N_("Force profile to use this priority."), + .off = offsetof(profile_t, pro_fprio), + .opts = PO_EXPERT, + .group = 1}, + { + .type = PT_BOOL, + .id = "restart", + .name = N_("Restart on error"), + .desc = N_("Restart streaming on error. This is useful for " + "DVR so a recording isn't aborted if an error occurs."), + .off = offsetof(profile_t, pro_restart), + .opts = PO_EXPERT, + .def.i = 0, + .group = 1, + }, + { + .type = PT_BOOL, + .id = "contaccess", + .name = N_("Continue if descrambling fails"), + .desc = N_("Don't abort streaming when an encrypted stream " + "can't be decrypted by a CA client that normally " + "should be able to decrypt the stream."), + .off = offsetof(profile_t, pro_contaccess), + .opts = PO_EXPERT, + .def.i = 1, + .group = 1, + }, + { + .type = PT_INT, + .id = "catimeout", + .name = N_("Descrambling timeout (ms)"), + .desc = N_("Check the descrambling status after this timeout."), + .off = offsetof(profile_t, pro_ca_timeout), + .opts = PO_EXPERT, + .def.i = 2000, + .group = 1, + }, + {.type = PT_BOOL, + .id = "swservice", + .name = N_("Switch to another service"), + .desc = N_("If something fails, try to switch to a different " + "service on another network. Do not try to iterate " + "through all inputs/tuners which are capable to " + "receive the service."), + .off = offsetof(profile_t, pro_swservice), + .opts = PO_EXPERT, + .def.i = 1, + .group = 1}, + {.type = PT_INT, + .id = "svfilter", + .name = N_("Preferred service video type"), + .desc = N_("The selected video type should be preferred when " + "multiple services are available for a channel."), + .list = profile_class_svfilter_list, + .off = offsetof(profile_t, pro_svfilter), + .opts = PO_SORTKEY | PO_ADVANCED | PO_DOC_NLIST, + .def.i = PROFILE_SVF_NONE, + .group = 1}, + {}}}; /* * */ -const char * -profile_get_name(profile_t *pro) -{ - if (pro->pro_name && *pro->pro_name) return pro->pro_name; +const char* profile_get_name(profile_t* pro) { + if (pro->pro_name && *pro->pro_name) + return pro->pro_name; return ""; } /* * */ -static profile_t * -profile_find_by_name2(const char *name, const char *alt, int all) -{ - profile_t *pro; +static profile_t* profile_find_by_name2(const char* name, const char* alt, int all) { + profile_t* pro; lock_assert(&global_lock); if (!name && alt) { name = alt; - alt = NULL; + alt = NULL; } if (!name) return profile_default; - TAILQ_FOREACH(pro, &profiles, pro_link) { + TAILQ_FOREACH (pro, &profiles, pro_link) { if ((all || pro->pro_enabled) && !strcmp(profile_get_name(pro), name)) return pro; } if (alt) { - TAILQ_FOREACH(pro, &profiles, pro_link) { + TAILQ_FOREACH (pro, &profiles, pro_link) { if ((all || pro->pro_enabled) && !strcmp(profile_get_name(pro), alt)) return pro; } @@ -490,18 +429,14 @@ profile_find_by_name2(const char *name, const char *alt, int all) /* * */ -profile_t * -profile_find_by_name(const char *name, const char *alt) -{ +profile_t* profile_find_by_name(const char* name, const char* alt) { return profile_find_by_name2(name, alt, 0); } /* * */ -int -profile_verify(profile_t *pro, int sflags) -{ +int profile_verify(profile_t* pro, int sflags) { if (!pro) return 0; if (!pro->pro_enabled) @@ -511,21 +446,18 @@ profile_verify(profile_t *pro, int sflags) if ((sflags & SUBSCRIPTION_HTSP) == 0 && !pro->pro_open) return 0; sflags &= pro->pro_sflags; - sflags &= SUBSCRIPTION_PACKET|SUBSCRIPTION_MPEGTS; + sflags &= SUBSCRIPTION_PACKET | SUBSCRIPTION_MPEGTS; return sflags ? 1 : 0; } /* * */ -profile_t * -profile_find_by_list - (htsmsg_t *uuids, const char *name, const char *alt, int sflags) -{ - profile_t *pro, *res = NULL; - htsmsg_field_t *f; - const char *uuid, *uuid2; - char ubuf[UUID_HEX_SIZE]; +profile_t* profile_find_by_list(htsmsg_t* uuids, const char* name, const char* alt, int sflags) { + profile_t * pro, *res = NULL; + htsmsg_field_t* f; + const char * uuid, *uuid2; + char ubuf[UUID_HEX_SIZE]; pro = profile_find_by_uuid(name); if (!pro) @@ -558,14 +490,12 @@ profile_find_by_list /* * */ -char * -profile_validate_name(const char *name) -{ - profile_t *pro; +char* profile_validate_name(const char* name) { + profile_t* pro; lock_assert(&global_lock); - TAILQ_FOREACH(pro, &profiles, pro_link) { + TAILQ_FOREACH (pro, &profiles, pro_link) { if (name && !strcmp(profile_get_name(pro), name)) return strdup(name); } @@ -579,15 +509,13 @@ profile_validate_name(const char *name) /* * */ -htsmsg_t * -profile_class_get_list(void *o, const char *lang) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_t *p = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "profile/list"); +htsmsg_t* profile_class_get_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_t* p = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "profile/list"); htsmsg_add_str(m, "event", "profile"); - htsmsg_add_u32(p, "all", 1); + htsmsg_add_u32(p, "all", 1); htsmsg_add_msg(m, "params", p); return m; } @@ -595,16 +523,14 @@ profile_class_get_list(void *o, const char *lang) /* * */ -void -profile_get_htsp_list(htsmsg_t *array, htsmsg_t *filter) -{ - profile_t *pro; - htsmsg_t *m; - htsmsg_field_t *f; - const char *uuid, *s; - char ubuf[UUID_HEX_SIZE]; - - TAILQ_FOREACH(pro, &profiles, pro_link) { +void profile_get_htsp_list(htsmsg_t* array, htsmsg_t* filter) { + profile_t* pro; + htsmsg_t* m; + htsmsg_field_t* f; + const char * uuid, *s; + char ubuf[UUID_HEX_SIZE]; + + TAILQ_FOREACH (pro, &profiles, pro_link) { if (!pro->pro_work) continue; uuid = idnode_uuid_as_str(&pro->pro_id, ubuf); @@ -629,18 +555,15 @@ profile_get_htsp_list(htsmsg_t *array, htsmsg_t *filter) /* * */ -static void -profile_deliver(profile_chain_t *prch, streaming_message_t *sm) -{ +static void profile_deliver(profile_chain_t* prch, streaming_message_t* sm) { if (prch->prch_start_pending) { - profile_sharer_t *prsh = prch->prch_sharer; - streaming_message_t *sm2; + profile_sharer_t* prsh = prch->prch_sharer; + streaming_message_t* sm2; if (!prsh->prsh_start_msg) { streaming_msg_free(sm); return; } - sm2 = streaming_msg_create_data(SMT_START, - streaming_start_copy(prsh->prsh_start_msg)); + sm2 = streaming_msg_create_data(SMT_START, streaming_start_copy(prsh->prsh_start_msg)); streaming_target_deliver(prch->prch_post_share, sm2); prch->prch_start_pending = 0; } @@ -651,11 +574,9 @@ profile_deliver(profile_chain_t *prch, streaming_message_t *sm) /* * */ -static void -profile_input(void *opaque, streaming_message_t *sm) -{ - profile_chain_t *prch = opaque, *prch2; - profile_sharer_t *prsh = prch->prch_sharer; +static void profile_input(void* opaque, streaming_message_t* sm) { + profile_chain_t * prch = opaque, *prch2; + profile_sharer_t* prsh = prch->prch_sharer; if (prsh == NULL) { streaming_msg_free(sm); @@ -673,7 +594,7 @@ profile_input(void *opaque, streaming_message_t *sm) prch->prch_stop = 1; /* elect new master */ prsh->prsh_master = NULL; - LIST_FOREACH(prch2, &prsh->prsh_chains, prch_sharer_link) + LIST_FOREACH (prch2, &prsh->prsh_chains, prch_sharer_link) if (!prch2->prch_stop) { prsh->prsh_master = prch2; break; @@ -688,7 +609,7 @@ profile_input(void *opaque, streaming_message_t *sm) if (sm->sm_type == SMT_STOP) { prch->prch_stop = 1; } else if (sm->sm_type == SMT_START) { - prch->prch_stop = 0; + prch->prch_stop = 0; prch->prch_start_pending = 1; streaming_msg_free(sm); sm = NULL; @@ -701,33 +622,26 @@ direct: profile_deliver(prch, sm); } -static htsmsg_t * -profile_input_info(void *opaque, htsmsg_t *list) -{ - profile_chain_t *prch = opaque; - streaming_target_t *st = prch->prch_share; +static htsmsg_t* profile_input_info(void* opaque, htsmsg_t* list) { + profile_chain_t* prch = opaque; + streaming_target_t* st = prch->prch_share; htsmsg_add_str(list, NULL, "profile input"); st->st_ops.st_info(st->st_opaque, list); st = prch->prch_post_share; return st->st_ops.st_info(st->st_opaque, list); } -static streaming_ops_t profile_input_ops = { - .st_cb = profile_input, - .st_info = profile_input_info -}; +static streaming_ops_t profile_input_ops = {.st_cb = profile_input, .st_info = profile_input_info}; /* * */ -static void -profile_input_queue(void *opaque, streaming_message_t *sm) -{ - profile_chain_t *prch = opaque; - profile_sharer_t *prsh = prch->prch_sharer; - profile_sharer_message_t *psm = malloc(sizeof(*psm)); - psm->psm_prch = prch; - psm->psm_sm = sm; +static void profile_input_queue(void* opaque, streaming_message_t* sm) { + profile_chain_t* prch = opaque; + profile_sharer_t* prsh = prch->prch_sharer; + profile_sharer_message_t* psm = malloc(sizeof(*psm)); + psm->psm_prch = prch; + psm->psm_sm = sm; tvh_mutex_lock(&prsh->prsh_queue_mutex); if (prsh->prsh_queue_run) { TAILQ_INSERT_TAIL(&prsh->prsh_queue, psm, psm_link); @@ -739,45 +653,38 @@ profile_input_queue(void *opaque, streaming_message_t *sm) tvh_mutex_unlock(&prsh->prsh_queue_mutex); } -static htsmsg_t * -profile_input_queue_info(void *opaque, htsmsg_t *list) -{ +static htsmsg_t* profile_input_queue_info(void* opaque, htsmsg_t* list) { htsmsg_add_str(list, NULL, "profile queue input"); profile_input_info(opaque, list); return list; } -static streaming_ops_t profile_input_queue_ops = { - .st_cb = profile_input_queue, - .st_info = profile_input_queue_info -}; +static streaming_ops_t profile_input_queue_ops = {.st_cb = profile_input_queue, + .st_info = profile_input_queue_info}; /* * */ -static void -profile_sharer_deliver(profile_chain_t *prch, streaming_message_t *sm) -{ +static void profile_sharer_deliver(profile_chain_t* prch, streaming_message_t* sm) { if (sm->sm_type == SMT_PACKET) { if (!prch->prch_ts_delta) goto deliver; - th_pkt_t *pkt = sm->sm_data; + th_pkt_t* pkt = sm->sm_data; if (prch->prch_ts_delta == PTS_UNSET) prch->prch_ts_delta = MAX(0, pkt->pkt_dts - 10000); /* * time correction here */ - if (pkt->pkt_pts >= prch->prch_ts_delta && - pkt->pkt_dts >= prch->prch_ts_delta && + if (pkt->pkt_pts >= prch->prch_ts_delta && pkt->pkt_dts >= prch->prch_ts_delta && pkt->pkt_pcr >= prch->prch_ts_delta) { - th_pkt_t *n = pkt_copy_shallow(pkt); + th_pkt_t* n = pkt_copy_shallow(pkt); pkt_ref_dec(pkt); n->pkt_pts -= prch->prch_ts_delta; n->pkt_dts -= prch->prch_ts_delta; n->pkt_pcr -= prch->prch_ts_delta; sm->sm_data = n; } else { - pkt_trace(LS_PROFILE, pkt, "packet drop (delta %"PRId64")", prch->prch_ts_delta); + pkt_trace(LS_PROFILE, pkt, "packet drop (delta %" PRId64 ")", prch->prch_ts_delta); streaming_msg_free(sm); return; } @@ -789,11 +696,9 @@ deliver: /* * */ -static void -profile_sharer_input(void *opaque, streaming_message_t *sm) -{ - profile_sharer_t *prsh = opaque; - profile_chain_t *prch, *next, *run = NULL; +static void profile_sharer_input(void* opaque, streaming_message_t* sm) { + profile_sharer_t* prsh = opaque; + profile_chain_t * prch, *next, *run = NULL; if (sm->sm_type == SMT_STOP) { if (prsh->prsh_start_msg) @@ -831,29 +736,23 @@ profile_sharer_input(void *opaque, streaming_message_t *sm) streaming_msg_free(sm); } -static htsmsg_t * -profile_sharer_input_info(void *opaque, htsmsg_t *list) -{ +static htsmsg_t* profile_sharer_input_info(void* opaque, htsmsg_t* list) { htsmsg_add_str(list, NULL, "profile sharer input"); return list; } -static streaming_ops_t profile_sharer_input_ops = { - .st_cb = profile_sharer_input, - .st_info = profile_sharer_input_info -}; +static streaming_ops_t profile_sharer_input_ops = {.st_cb = profile_sharer_input, + .st_info = profile_sharer_input_info}; /* * */ -static profile_sharer_t * -profile_sharer_find(profile_chain_t *prch) -{ - profile_sharer_t *prsh = NULL; - profile_chain_t *prch2; - int do_queue = prch->prch_can_share != NULL; - - LIST_FOREACH(prch2, &profile_chains, prch_link) { +static profile_sharer_t* profile_sharer_find(profile_chain_t* prch) { + profile_sharer_t* prsh = NULL; + profile_chain_t* prch2; + int do_queue = prch->prch_can_share != NULL; + + LIST_FOREACH (prch2, &profile_chains, prch_link) { if (prch2->prch_id != prch->prch_id) continue; if (prch2 == prch) @@ -864,7 +763,7 @@ profile_sharer_find(profile_chain_t *prch) } } if (!prsh) { - prsh = calloc(1, sizeof(*prsh)); + prsh = calloc(1, sizeof(*prsh)); prsh->prsh_do_queue = do_queue; tvh_mutex_init(&prsh->prsh_queue_mutex, NULL); tvh_cond_init(&prsh->prsh_queue_cond, 1); @@ -878,12 +777,10 @@ profile_sharer_find(profile_chain_t *prch) /* * */ -static void * -profile_sharer_thread(void *aux) -{ - profile_sharer_t *prsh = aux; - profile_sharer_message_t *psm; - int run = 1; +static void* profile_sharer_thread(void* aux) { + profile_sharer_t* prsh = aux; + profile_sharer_message_t* psm; + int run = 1; while (run) { tvh_mutex_lock(&prsh->prsh_queue_mutex); @@ -909,9 +806,7 @@ profile_sharer_thread(void *aux) /* * */ -static int -profile_sharer_postinit(profile_sharer_t *prsh) -{ +static int profile_sharer_postinit(profile_sharer_t* prsh) { int r; if (!prsh->prsh_do_queue) @@ -919,8 +814,7 @@ profile_sharer_postinit(profile_sharer_t *prsh) if (prsh->prsh_queue_run) return 0; prsh->prsh_queue_run = 1; - r = tvh_thread_create(&prsh->prsh_queue_thread, NULL, - profile_sharer_thread, prsh, "sharer"); + r = tvh_thread_create(&prsh->prsh_queue_thread, NULL, profile_sharer_thread, prsh, "sharer"); if (r) { prsh->prsh_queue_run = 0; tvherror(LS_PROFILE, "unable to create sharer thread"); @@ -932,10 +826,7 @@ profile_sharer_postinit(profile_sharer_t *prsh) * */ static int -profile_sharer_create(profile_sharer_t *prsh, - profile_chain_t *prch, - streaming_target_t *dst) -{ +profile_sharer_create(profile_sharer_t* prsh, profile_chain_t* prch, streaming_target_t* dst) { prch->prch_post_share = dst; tvh_mutex_lock(&prsh->prsh_queue_mutex); prch->prch_ts_delta = LIST_EMPTY(&prsh->prsh_chains) ? 0 : PTS_UNSET; @@ -950,10 +841,8 @@ profile_sharer_create(profile_sharer_t *prsh, /* * */ -static void -profile_sharer_destroy(profile_chain_t *prch) -{ - profile_sharer_t *prsh = prch->prch_sharer; +static void profile_sharer_destroy(profile_chain_t* prch) { + profile_sharer_t* prsh = prch->prch_sharer; profile_sharer_message_t *psm, *psm2; if (prsh == NULL) @@ -964,7 +853,7 @@ profile_sharer_destroy(profile_chain_t *prch) tvh_mutex_lock(&prsh->prsh_queue_mutex); prsh->prsh_queue_run = 0; tvh_cond_signal(&prsh->prsh_queue_cond, 0); - prch->prch_sharer = NULL; + prch->prch_sharer = NULL; prch->prch_post_share = NULL; tvh_mutex_unlock(&prsh->prsh_queue_mutex); pthread_join(prsh->prsh_queue_thread, NULL); @@ -988,37 +877,35 @@ profile_sharer_destroy(profile_chain_t *prch) tvh_mutex_lock(&prsh->prsh_queue_mutex); for (psm = TAILQ_FIRST(&prsh->prsh_queue); psm; psm = psm2) { psm2 = TAILQ_NEXT(psm, psm_link); - if (psm->psm_prch != prch) continue; - if (psm->psm_sm->sm_type == SMT_PACKET || - psm->psm_sm->sm_type == SMT_MPEGTS) + if (psm->psm_prch != prch) + continue; + if (psm->psm_sm->sm_type == SMT_PACKET || psm->psm_sm->sm_type == SMT_MPEGTS) streaming_msg_free(psm->psm_sm); else profile_input(psm->psm_prch, psm->psm_sm); TAILQ_REMOVE(&prsh->prsh_queue, psm, psm_link); free(psm); } - prch->prch_sharer = NULL; + prch->prch_sharer = NULL; prch->prch_post_share = NULL; if (prsh->prsh_master == prch) prsh->prsh_master = NULL; tvh_mutex_unlock(&prsh->prsh_queue_mutex); } else { tvh_mutex_lock(&prsh->prsh_queue_mutex); - prch->prch_sharer = NULL; + prch->prch_sharer = NULL; prch->prch_post_share = NULL; if (prsh->prsh_master == prch) prsh->prsh_master = NULL; tvh_mutex_unlock(&prsh->prsh_queue_mutex); - } + } } } /* * */ -void -profile_chain_init(profile_chain_t *prch, profile_t *pro, void *id, int queue) -{ +void profile_chain_init(profile_chain_t* prch, profile_t* pro, void* id, int queue) { memset(prch, 0, sizeof(*prch)); if (pro) profile_grab(pro); @@ -1030,17 +917,17 @@ profile_chain_init(profile_chain_t *prch, profile_t *pro, void *id, int queue) } LIST_INSERT_HEAD(&profile_chains, prch, prch_link); prch->prch_linked = 1; - prch->prch_stop = 1; + prch->prch_stop = 1; } /* * */ -int -profile_chain_work(profile_chain_t *prch, struct streaming_target *dst, - uint32_t timeshift_period, profile_work_flags_t flags) -{ - profile_t *pro = prch->prch_pro; +int profile_chain_work(profile_chain_t* prch, + struct streaming_target* dst, + uint32_t timeshift_period, + profile_work_flags_t flags) { + profile_t* pro = prch->prch_pro; if (pro && pro->pro_work) return pro->pro_work(prch, dst, timeshift_period, flags); return -1; @@ -1049,12 +936,11 @@ profile_chain_work(profile_chain_t *prch, struct streaming_target *dst, /* * */ -int -profile_chain_reopen(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags) -{ - profile_t *pro = prch->prch_pro; +int profile_chain_reopen(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags) { + profile_t* pro = prch->prch_pro; if (pro && pro->pro_reopen) return pro->pro_reopen(prch, m_cfg, hints, flags); return -1; @@ -1063,13 +949,12 @@ profile_chain_reopen(profile_chain_t *prch, /* * */ -int -profile_chain_open(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, - int flags, size_t qsize) -{ - profile_t *pro = prch->prch_pro; +int profile_chain_open(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags, + size_t qsize) { + profile_t* pro = prch->prch_pro; if (pro && pro->pro_open) return pro->pro_open(prch, m_cfg, hints, flags, qsize); return -1; @@ -1078,9 +963,7 @@ profile_chain_open(profile_chain_t *prch, /* * */ -int -profile_chain_raw_open(profile_chain_t *prch, void *id, size_t qsize, int muxer) -{ +int profile_chain_raw_open(profile_chain_t* prch, void* id, size_t qsize, int muxer) { muxer_config_t c; memset(prch, 0, sizeof(*prch)); @@ -1088,10 +971,10 @@ profile_chain_raw_open(profile_chain_t *prch, void *id, size_t qsize, int muxer) prch->prch_flags = SUBSCRIPTION_MPEGTS; streaming_queue_init(&prch->prch_sq, SMT_PACKET, qsize); prch->prch_sq_used = 1; - prch->prch_st = &prch->prch_sq.sq_st; + prch->prch_st = &prch->prch_sq.sq_st; if (muxer) { memset(&c, 0, sizeof(c)); - c.m_type = MC_RAW; + c.m_type = MC_RAW; prch->prch_muxer = muxer_create(&c, NULL); } return 0; @@ -1101,22 +984,19 @@ profile_chain_raw_open(profile_chain_t *prch, void *id, size_t qsize, int muxer) * */ -static const int prio2weight[] = { - [PROFILE_SPRIO_DVR_IMPORTANT] = 525, - [PROFILE_SPRIO_DVR_HIGH] = 425, - [PROFILE_SPRIO_DVR_NORMAL] = 325, - [PROFILE_SPRIO_DVR_LOW] = 225, - [PROFILE_SPRIO_DVR_UNIMPORTANT] = 175, - [PROFILE_SPRIO_IMPORTANT] = 150, - [PROFILE_SPRIO_HIGH] = 125, - [PROFILE_SPRIO_NORMAL] = 100, - [PROFILE_SPRIO_LOW] = 75, - [PROFILE_SPRIO_UNIMPORTANT] = 50, - [PROFILE_SPRIO_NOTSET] = 0 -}; - -int profile_chain_weight(profile_chain_t *prch, int custom) -{ +static const int prio2weight[] = {[PROFILE_SPRIO_DVR_IMPORTANT] = 525, + [PROFILE_SPRIO_DVR_HIGH] = 425, + [PROFILE_SPRIO_DVR_NORMAL] = 325, + [PROFILE_SPRIO_DVR_LOW] = 225, + [PROFILE_SPRIO_DVR_UNIMPORTANT] = 175, + [PROFILE_SPRIO_IMPORTANT] = 150, + [PROFILE_SPRIO_HIGH] = 125, + [PROFILE_SPRIO_NORMAL] = 100, + [PROFILE_SPRIO_LOW] = 75, + [PROFILE_SPRIO_UNIMPORTANT] = 50, + [PROFILE_SPRIO_NOTSET] = 0}; + +int profile_chain_weight(profile_chain_t* prch, int custom) { int w, w2; w = 100; @@ -1127,7 +1007,7 @@ int profile_chain_weight(profile_chain_t *prch, int custom) w = 150; w2 = prch->prch_pro->pro_prio; if (w2 > 0 && w2 < ARRAY_SIZE(prio2weight)) - w = prio2weight[w2]; + w = prio2weight[w2]; } else { if (custom > 0) return custom; @@ -1138,9 +1018,7 @@ int profile_chain_weight(profile_chain_t *prch, int custom) /* * */ -void -profile_chain_close(profile_chain_t *prch) -{ +void profile_chain_close(profile_chain_t* prch) { if (prch == NULL) return; @@ -1152,7 +1030,7 @@ profile_chain_close(profile_chain_t *prch) prch->prch_timeshift = NULL; } #if ENABLE_IPTV - if(prch->prch_rtsp) { + if (prch->prch_rtsp) { rtsp_st_destroy(prch->prch_rtsp); prch->prch_rtsp = NULL; } @@ -1194,23 +1072,17 @@ profile_chain_close(profile_chain_t *prch) /* * HTSP Profile Class */ -const idclass_t profile_htsp_class = -{ - .ic_super = &profile_class, - .ic_class = "profile-htsp", - .ic_caption = N_("HTSP Stream Profile"), - .ic_properties = (const property_t[]){ - /* Ready for future extensions */ - { } - } -}; - -static int -profile_htsp_work(profile_chain_t *prch, - streaming_target_t *dst, - uint32_t timeshift_period, profile_work_flags_t flags) -{ - profile_sharer_t *prsh; +const idclass_t profile_htsp_class = {.ic_super = &profile_class, + .ic_class = "profile-htsp", + .ic_caption = N_("HTSP Stream Profile"), + .ic_properties = (const property_t[]){/* Ready for future extensions */ + {}}}; + +static int profile_htsp_work(profile_chain_t* prch, + streaming_target_t* dst, + uint32_t timeshift_period, + profile_work_flags_t flags) { + profile_sharer_t* prsh; prsh = profile_sharer_find(prch); if (!prsh) @@ -1226,8 +1098,8 @@ profile_htsp_work(profile_chain_t *prch, dst = prch->prch_rtsp = rtsp_st_create(dst, prch); else #endif - if (timeshift_period > 0) - dst = prch->prch_timeshift = timeshift_create(dst, timeshift_period); + if (timeshift_period > 0) + dst = prch->prch_timeshift = timeshift_create(dst, timeshift_period); #endif dst = prch->prch_gh = globalheaders_create(dst); @@ -1237,9 +1109,9 @@ profile_htsp_work(profile_chain_t *prch, prch->prch_flags = SUBSCRIPTION_PACKET; streaming_target_init(&prch->prch_input, - prsh->prsh_do_queue ? - &profile_input_queue_ops : &profile_input_ops, prch, - 0); + prsh->prsh_do_queue ? &profile_input_queue_ops : &profile_input_ops, + prch, + 0); prch->prch_st = &prch->prch_input; if (profile_sharer_postinit(prsh)) goto fail; @@ -1250,10 +1122,8 @@ fail: return -1; } -static profile_t * -profile_htsp_builder(void) -{ - profile_t *pro = calloc(1, sizeof(*pro)); +static profile_t* profile_htsp_builder(void) { + profile_t* pro = calloc(1, sizeof(*pro)); pro->pro_sflags = SUBSCRIPTION_PACKET; pro->pro_work = profile_htsp_work; return pro; @@ -1265,18 +1135,16 @@ profile_htsp_builder(void) typedef struct profile_mpegts { profile_t; uint16_t pro_rewrite_sid; - int pro_rewrite_pmt; - int pro_rewrite_pat; - int pro_rewrite_sdt; - int pro_rewrite_nit; - int pro_rewrite_eit; + int pro_rewrite_pmt; + int pro_rewrite_pat; + int pro_rewrite_sdt; + int pro_rewrite_nit; + int pro_rewrite_eit; } profile_mpegts_t; -static int -profile_pass_rewrite_sid_set (void *in, const void *v) -{ - profile_mpegts_t *pro = (profile_mpegts_t *)in; - const uint16_t *val = v; +static int profile_pass_rewrite_sid_set(void* in, const void* v) { + profile_mpegts_t* pro = (profile_mpegts_t*)in; + const uint16_t* val = v; if (*val != pro->pro_rewrite_sid) { if (*val > 0) { pro->pro_rewrite_pmt = 1; @@ -1291,12 +1159,11 @@ profile_pass_rewrite_sid_set (void *in, const void *v) return 0; } -static int -profile_pass_int_set (void *in, const void *v, int *prop) -{ - profile_mpegts_t *pro = (profile_mpegts_t *)in; - int val = *(int *)v; - if (pro->pro_rewrite_sid > 0) val = 1; +static int profile_pass_int_set(void* in, const void* v, int* prop) { + profile_mpegts_t* pro = (profile_mpegts_t*)in; + int val = *(int*)v; + if (pro->pro_rewrite_sid > 0) + val = 1; if (val != *prop) { *prop = val; return 1; @@ -1304,151 +1171,122 @@ profile_pass_int_set (void *in, const void *v, int *prop) return 0; } -static int -profile_pass_rewrite_pmt_set (void *in, const void *v) -{ - return profile_pass_int_set(in, v, &((profile_mpegts_t *)in)->pro_rewrite_pmt); -} - -static int -profile_pass_rewrite_pat_set (void *in, const void *v) -{ - return profile_pass_int_set(in, v, &((profile_mpegts_t *)in)->pro_rewrite_pat); -} - -static int -profile_pass_rewrite_sdt_set (void *in, const void *v) -{ - return profile_pass_int_set(in, v, &((profile_mpegts_t *)in)->pro_rewrite_sdt); -} - -static int -profile_pass_rewrite_nit_set (void *in, const void *v) -{ - return profile_pass_int_set(in, v, &((profile_mpegts_t *)in)->pro_rewrite_nit); -} - -static int -profile_pass_rewrite_eit_set (void *in, const void *v) -{ - return profile_pass_int_set(in, v, &((profile_mpegts_t *)in)->pro_rewrite_eit); -} - -const idclass_t profile_mpegts_pass_class = -{ - .ic_super = &profile_class, - .ic_class = "profile-mpegts", - .ic_caption = N_("MPEG-TS Pass-thru/built-in"), - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - { - .name = N_("Rewrite MPEG-TS SI Table(s) Settings"), - .number = 2, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_U16, - .id = "sid", - .name = N_("Rewrite Service ID"), - .desc = N_("Rewrite service identifier (SID) using the specified " - "value (usually 1). Zero means no rewrite."), - .off = offsetof(profile_mpegts_t, pro_rewrite_sid), - .set = profile_pass_rewrite_sid_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 2 - }, - { - .type = PT_BOOL, - .id = "rewrite_pmt", - .name = N_("Rewrite PMT"), - .desc = N_("Rewrite PMT (Program Map Table) packets to only " - "include information about the currently-streamed " - "service. " - "Rewrite can be unset only if 'Rewrite Service ID' " - "is set to zero."), - .off = offsetof(profile_mpegts_t, pro_rewrite_pmt), - .set = profile_pass_rewrite_pmt_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 2 - }, - { - .type = PT_BOOL, - .id = "rewrite_pat", - .name = N_("Rewrite PAT"), - .desc = N_("Rewrite PAT (Program Association Table) packets " - "to only include information about the currently-" - "streamed service. " - "Rewrite can be unset only if 'Rewrite Service ID' " - "is set to zero."), - .off = offsetof(profile_mpegts_t, pro_rewrite_pat), - .set = profile_pass_rewrite_pat_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 2 - }, - { - .type = PT_BOOL, - .id = "rewrite_sdt", - .name = N_("Rewrite SDT"), - .desc = N_("Rewrite SDT (Service Description Table) packets " - "to only include information about the currently-" - "streamed service. " - "Rewrite can be unset only if 'Rewrite Service ID' " - "is set to zero."), - .off = offsetof(profile_mpegts_t, pro_rewrite_sdt), - .set = profile_pass_rewrite_sdt_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 2 - }, - { - .type = PT_BOOL, - .id = "rewrite_nit", - .name = N_("Rewrite NIT"), - .desc = N_("Rewrite NIT (Network Information Table) packets " - "to only include information about the currently-" - "streamed service. " - "Rewrite can be unset only if 'Rewrite Service ID' " - "is set to zero."), - .off = offsetof(profile_mpegts_t, pro_rewrite_nit), - .set = profile_pass_rewrite_nit_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 2 - }, - { - .type = PT_BOOL, - .id = "rewrite_eit", - .name = N_("Rewrite EIT"), - .desc = N_("Rewrite EIT (Event Information Table) packets " - "to only include information about the currently-" - "streamed service. " - "Rewrite can be unset only if 'Rewrite Service ID' " - "is set to zero."), - .off = offsetof(profile_mpegts_t, pro_rewrite_eit), - .set = profile_pass_rewrite_eit_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 2 - }, - { } - } -}; - -static int -profile_mpegts_pass_reopen(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags) -{ - profile_mpegts_t *pro = (profile_mpegts_t *)prch->prch_pro; - muxer_config_t c; +static int profile_pass_rewrite_pmt_set(void* in, const void* v) { + return profile_pass_int_set(in, v, &((profile_mpegts_t*)in)->pro_rewrite_pmt); +} + +static int profile_pass_rewrite_pat_set(void* in, const void* v) { + return profile_pass_int_set(in, v, &((profile_mpegts_t*)in)->pro_rewrite_pat); +} + +static int profile_pass_rewrite_sdt_set(void* in, const void* v) { + return profile_pass_int_set(in, v, &((profile_mpegts_t*)in)->pro_rewrite_sdt); +} + +static int profile_pass_rewrite_nit_set(void* in, const void* v) { + return profile_pass_int_set(in, v, &((profile_mpegts_t*)in)->pro_rewrite_nit); +} + +static int profile_pass_rewrite_eit_set(void* in, const void* v) { + return profile_pass_int_set(in, v, &((profile_mpegts_t*)in)->pro_rewrite_eit); +} + +const idclass_t profile_mpegts_pass_class = {.ic_super = &profile_class, + .ic_class = "profile-mpegts", + .ic_caption = N_("MPEG-TS Pass-thru/built-in"), + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + { + .name = N_("Rewrite MPEG-TS SI Table(s) Settings"), + .number = 2, + }, + {}}, + .ic_properties = + (const property_t[]){{.type = PT_U16, + .id = "sid", + .name = N_("Rewrite Service ID"), + .desc = N_("Rewrite service identifier (SID) using the specified " + "value (usually 1). Zero means no rewrite."), + .off = offsetof(profile_mpegts_t, pro_rewrite_sid), + .set = profile_pass_rewrite_sid_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 2}, + {.type = PT_BOOL, + .id = "rewrite_pmt", + .name = N_("Rewrite PMT"), + .desc = N_("Rewrite PMT (Program Map Table) packets to only " + "include information about the currently-streamed " + "service. " + "Rewrite can be unset only if 'Rewrite Service ID' " + "is set to zero."), + .off = offsetof(profile_mpegts_t, pro_rewrite_pmt), + .set = profile_pass_rewrite_pmt_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 2}, + {.type = PT_BOOL, + .id = "rewrite_pat", + .name = N_("Rewrite PAT"), + .desc = N_("Rewrite PAT (Program Association Table) packets " + "to only include information about the currently-" + "streamed service. " + "Rewrite can be unset only if 'Rewrite Service ID' " + "is set to zero."), + .off = offsetof(profile_mpegts_t, pro_rewrite_pat), + .set = profile_pass_rewrite_pat_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 2}, + {.type = PT_BOOL, + .id = "rewrite_sdt", + .name = N_("Rewrite SDT"), + .desc = N_("Rewrite SDT (Service Description Table) packets " + "to only include information about the currently-" + "streamed service. " + "Rewrite can be unset only if 'Rewrite Service ID' " + "is set to zero."), + .off = offsetof(profile_mpegts_t, pro_rewrite_sdt), + .set = profile_pass_rewrite_sdt_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 2}, + {.type = PT_BOOL, + .id = "rewrite_nit", + .name = N_("Rewrite NIT"), + .desc = N_("Rewrite NIT (Network Information Table) packets " + "to only include information about the currently-" + "streamed service. " + "Rewrite can be unset only if 'Rewrite Service ID' " + "is set to zero."), + .off = offsetof(profile_mpegts_t, pro_rewrite_nit), + .set = profile_pass_rewrite_nit_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 2}, + {.type = PT_BOOL, + .id = "rewrite_eit", + .name = N_("Rewrite EIT"), + .desc = N_("Rewrite EIT (Event Information Table) packets " + "to only include information about the currently-" + "streamed service. " + "Rewrite can be unset only if 'Rewrite Service ID' " + "is set to zero."), + .off = offsetof(profile_mpegts_t, pro_rewrite_eit), + .set = profile_pass_rewrite_eit_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 2}, + {}}}; + +static int profile_mpegts_pass_reopen(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags) { + profile_mpegts_t* pro = (profile_mpegts_t*)prch->prch_pro; + muxer_config_t c; if (m_cfg) muxer_config_copy(&c, m_cfg); /* do not alter the original parameter */ @@ -1468,36 +1306,33 @@ profile_mpegts_pass_reopen(profile_chain_t *prch, return 0; } -static int -profile_mpegts_pass_open(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, - int flags, size_t qsize) -{ +static int profile_mpegts_pass_open(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags, + size_t qsize) { prch->prch_flags = SUBSCRIPTION_MPEGTS; prch->prch_sq.sq_st.st_reject_filter = SMT_PACKET; - prch->prch_sq.sq_maxsize = qsize; + prch->prch_sq.sq_maxsize = qsize; - prch->prch_st = &prch->prch_sq.sq_st; + prch->prch_st = &prch->prch_sq.sq_st; return profile_mpegts_pass_reopen(prch, m_cfg, hints, flags); } -static profile_t * -profile_mpegts_pass_builder(void) -{ - profile_mpegts_t *pro = calloc(1, sizeof(*pro)); - pro->pro_sflags = SUBSCRIPTION_MPEGTS; - pro->pro_reopen = profile_mpegts_pass_reopen; - pro->pro_open = profile_mpegts_pass_open; - pro->pro_rewrite_sid = 1; - pro->pro_rewrite_pat = 1; - pro->pro_rewrite_pmt = 1; - pro->pro_rewrite_sdt = 1; - pro->pro_rewrite_nit = 1; - pro->pro_rewrite_eit = 1; - return (profile_t *)pro; +static profile_t* profile_mpegts_pass_builder(void) { + profile_mpegts_t* pro = calloc(1, sizeof(*pro)); + pro->pro_sflags = SUBSCRIPTION_MPEGTS; + pro->pro_reopen = profile_mpegts_pass_reopen; + pro->pro_open = profile_mpegts_pass_open; + pro->pro_rewrite_sid = 1; + pro->pro_rewrite_pat = 1; + pro->pro_rewrite_pmt = 1; + pro->pro_rewrite_sdt = 1; + pro->pro_rewrite_nit = 1; + pro->pro_rewrite_eit = 1; + return (profile_t*)pro; } /* @@ -1505,23 +1340,21 @@ profile_mpegts_pass_builder(void) */ typedef struct profile_mpegts_spawn { profile_t; - char *pro_cmdline; - char *pro_mime; - int pro_killsig; - int pro_killtimeout; + char* pro_cmdline; + char* pro_mime; + int pro_killsig; + int pro_killtimeout; uint16_t pro_rewrite_sid; - int pro_rewrite_pmt; - int pro_rewrite_pat; - int pro_rewrite_sdt; - int pro_rewrite_nit; - int pro_rewrite_eit; + int pro_rewrite_pmt; + int pro_rewrite_pat; + int pro_rewrite_sdt; + int pro_rewrite_nit; + int pro_rewrite_eit; } profile_mpegts_spawn_t; -static int -profile_spawn_rewrite_sid_set (void *in, const void *v) -{ - profile_mpegts_spawn_t *pro = (profile_mpegts_spawn_t *)in; - const uint16_t *val = v; +static int profile_spawn_rewrite_sid_set(void* in, const void* v) { + profile_mpegts_spawn_t* pro = (profile_mpegts_spawn_t*)in; + const uint16_t* val = v; if (*val != pro->pro_rewrite_sid) { if (*val > 0) { pro->pro_rewrite_pmt = 1; @@ -1536,12 +1369,11 @@ profile_spawn_rewrite_sid_set (void *in, const void *v) return 0; } -static int -profile_spawn_int_set (void *in, const void *v, int *prop) -{ - profile_mpegts_spawn_t *pro = (profile_mpegts_spawn_t *)in; - int val = *(int *)v; - if (pro->pro_rewrite_sid > 0) val = 1; +static int profile_spawn_int_set(void* in, const void* v, int* prop) { + profile_mpegts_spawn_t* pro = (profile_mpegts_spawn_t*)in; + int val = *(int*)v; + if (pro->pro_rewrite_sid > 0) + val = 1; if (val != *prop) { *prop = val; return 1; @@ -1549,196 +1381,158 @@ profile_spawn_int_set (void *in, const void *v, int *prop) return 0; } -static int -profile_spawn_rewrite_pmt_set (void *in, const void *v) -{ - return profile_spawn_int_set(in, v, &((profile_mpegts_spawn_t *)in)->pro_rewrite_pmt); -} - -static int -profile_spawn_rewrite_pat_set (void *in, const void *v) -{ - return profile_spawn_int_set(in, v, &((profile_mpegts_spawn_t *)in)->pro_rewrite_pat); -} - -static int -profile_spawn_rewrite_sdt_set (void *in, const void *v) -{ - return profile_spawn_int_set(in, v, &((profile_mpegts_spawn_t *)in)->pro_rewrite_sdt); -} - -static int -profile_spawn_rewrite_nit_set (void *in, const void *v) -{ - return profile_spawn_int_set(in, v, &((profile_mpegts_spawn_t *)in)->pro_rewrite_nit); -} - -static int -profile_spawn_rewrite_eit_set (void *in, const void *v) -{ - return profile_spawn_int_set(in, v, &((profile_mpegts_spawn_t *)in)->pro_rewrite_eit); -} - - -const idclass_t profile_mpegts_spawn_class = -{ - .ic_super = &profile_class, - .ic_class = "profile-mpegts-spawn", - .ic_caption = N_("MPEG-TS Spawn/built-in"), - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - { - .name = N_("Spawn Settings"), - .number = 2, - }, - { - .name = N_("Rewrite MPEG-TS SI Table(s) Settings"), - .number = 3, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "cmdline", - .name = N_("Command line"), - .desc = N_("Command line to run a task which accepts MPEG-TS stream" - " on stdin and writes output to stdout in format specified" - " by the selected mime type."), - .off = offsetof(profile_mpegts_spawn_t, pro_cmdline), - .opts = PO_MULTILINE, - .group = 2 - }, - { - .type = PT_STR, - .id = "mime", - .name = N_("Mime type"), - .desc = N_("Mime type string (for example 'video/mp2t')."), - .off = offsetof(profile_mpegts_spawn_t, pro_mime), - .group = 2 - }, - { - .type = PT_INT, - .id = "killsig", - .name = N_("Kill signal (pipe)"), - .desc = N_("Kill signal to send to the spawn."), - .off = offsetof(profile_mpegts_spawn_t, pro_killsig), - .list = proplib_kill_list, - .opts = PO_EXPERT | PO_DOC_NLIST, - .def.i = TVH_KILL_TERM, - .group = 2 - }, - { - .type = PT_INT, - .id = "kill_timeout", - .name = N_("Kill timeout (pipe/secs)"), - .desc = N_("Number of seconds to wait for spawn to die."), - .off = offsetof(profile_mpegts_spawn_t, pro_killtimeout), - .opts = PO_EXPERT, - .def.i = 15, - .group = 2 - }, - { - .type = PT_U16, - .id = "sid", - .name = N_("Rewrite Service ID"), - .desc = N_("Rewrite service identifier (SID) using the specified " - "value (usually 1). Zero means no rewrite."), - .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_sid), - .set = profile_spawn_rewrite_sid_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 3 - }, - { - .type = PT_BOOL, - .id = "rewrite_pmt", - .name = N_("Rewrite PMT"), - .desc = N_("Rewrite PMT (Program Map Table) packets to only " - "include information about the currently-streamed " - "service. " - "Rewrite can be unset only if 'Rewrite Service ID' " - "is set to zero."), - .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_pmt), - .set = profile_spawn_rewrite_pmt_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 3 - }, - { - .type = PT_BOOL, - .id = "rewrite_pat", - .name = N_("Rewrite PAT"), - .desc = N_("Rewrite PAT (Program Association Table) packets " - "to only include information about the currently-" - "streamed service. " - "Rewrite can be unset only if 'Rewrite Service ID' " - "is set to zero."), - .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_pat), - .set = profile_spawn_rewrite_pat_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 3 - }, - { - .type = PT_BOOL, - .id = "rewrite_sdt", - .name = N_("Rewrite SDT"), - .desc = N_("Rewrite SDT (Service Description Table) packets " - "to only include information about the currently-" - "streamed service. " - "Rewrite can be unset only if 'Rewrite Service ID' " - "is set to zero."), - .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_sdt), - .set = profile_spawn_rewrite_sdt_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 3 - }, - { - .type = PT_BOOL, - .id = "rewrite_nit", - .name = N_("Rewrite NIT"), - .desc = N_("Rewrite NIT (Network Information Table) packets " - "to only include information about the currently-" - "streamed service. " - "Rewrite can be unset only if 'Rewrite Service ID' " - "is set to zero."), - .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_nit), - .set = profile_spawn_rewrite_nit_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 3 - }, - { - .type = PT_BOOL, - .id = "rewrite_eit", - .name = N_("Rewrite EIT"), - .desc = N_("Rewrite EIT (Event Information Table) packets " - "to only include information about the currently-" - "streamed service. " - "Rewrite can be unset only if 'Rewrite Service ID' " - "is set to zero."), - .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_eit), - .set = profile_spawn_rewrite_eit_set, - .opts = PO_EXPERT, - .def.i = 1, - .group = 3 - }, - { } - } -}; - -static int -profile_mpegts_spawn_reopen(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags) -{ - profile_mpegts_spawn_t *pro = (profile_mpegts_spawn_t *)prch->prch_pro; - muxer_config_t c; +static int profile_spawn_rewrite_pmt_set(void* in, const void* v) { + return profile_spawn_int_set(in, v, &((profile_mpegts_spawn_t*)in)->pro_rewrite_pmt); +} + +static int profile_spawn_rewrite_pat_set(void* in, const void* v) { + return profile_spawn_int_set(in, v, &((profile_mpegts_spawn_t*)in)->pro_rewrite_pat); +} + +static int profile_spawn_rewrite_sdt_set(void* in, const void* v) { + return profile_spawn_int_set(in, v, &((profile_mpegts_spawn_t*)in)->pro_rewrite_sdt); +} + +static int profile_spawn_rewrite_nit_set(void* in, const void* v) { + return profile_spawn_int_set(in, v, &((profile_mpegts_spawn_t*)in)->pro_rewrite_nit); +} + +static int profile_spawn_rewrite_eit_set(void* in, const void* v) { + return profile_spawn_int_set(in, v, &((profile_mpegts_spawn_t*)in)->pro_rewrite_eit); +} + +const idclass_t profile_mpegts_spawn_class = {.ic_super = &profile_class, + .ic_class = "profile-mpegts-spawn", + .ic_caption = N_("MPEG-TS Spawn/built-in"), + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + { + .name = N_("Spawn Settings"), + .number = 2, + }, + { + .name = N_("Rewrite MPEG-TS SI Table(s) Settings"), + .number = 3, + }, + {}}, + .ic_properties = (const property_t[]){ + {.type = PT_STR, + .id = "cmdline", + .name = N_("Command line"), + .desc = N_("Command line to run a task which accepts MPEG-TS stream" + " on stdin and writes output to stdout in format specified" + " by the selected mime type."), + .off = offsetof(profile_mpegts_spawn_t, pro_cmdline), + .opts = PO_MULTILINE, + .group = 2}, + {.type = PT_STR, + .id = "mime", + .name = N_("Mime type"), + .desc = N_("Mime type string (for example 'video/mp2t')."), + .off = offsetof(profile_mpegts_spawn_t, pro_mime), + .group = 2}, + {.type = PT_INT, + .id = "killsig", + .name = N_("Kill signal (pipe)"), + .desc = N_("Kill signal to send to the spawn."), + .off = offsetof(profile_mpegts_spawn_t, pro_killsig), + .list = proplib_kill_list, + .opts = PO_EXPERT | PO_DOC_NLIST, + .def.i = TVH_KILL_TERM, + .group = 2}, + {.type = PT_INT, + .id = "kill_timeout", + .name = N_("Kill timeout (pipe/secs)"), + .desc = N_("Number of seconds to wait for spawn to die."), + .off = offsetof(profile_mpegts_spawn_t, pro_killtimeout), + .opts = PO_EXPERT, + .def.i = 15, + .group = 2}, + {.type = PT_U16, + .id = "sid", + .name = N_("Rewrite Service ID"), + .desc = N_("Rewrite service identifier (SID) using the specified " + "value (usually 1). Zero means no rewrite."), + .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_sid), + .set = profile_spawn_rewrite_sid_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 3}, + {.type = PT_BOOL, + .id = "rewrite_pmt", + .name = N_("Rewrite PMT"), + .desc = N_("Rewrite PMT (Program Map Table) packets to only " + "include information about the currently-streamed " + "service. " + "Rewrite can be unset only if 'Rewrite Service ID' " + "is set to zero."), + .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_pmt), + .set = profile_spawn_rewrite_pmt_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 3}, + {.type = PT_BOOL, + .id = "rewrite_pat", + .name = N_("Rewrite PAT"), + .desc = N_("Rewrite PAT (Program Association Table) packets " + "to only include information about the currently-" + "streamed service. " + "Rewrite can be unset only if 'Rewrite Service ID' " + "is set to zero."), + .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_pat), + .set = profile_spawn_rewrite_pat_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 3}, + {.type = PT_BOOL, + .id = "rewrite_sdt", + .name = N_("Rewrite SDT"), + .desc = N_("Rewrite SDT (Service Description Table) packets " + "to only include information about the currently-" + "streamed service. " + "Rewrite can be unset only if 'Rewrite Service ID' " + "is set to zero."), + .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_sdt), + .set = profile_spawn_rewrite_sdt_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 3}, + {.type = PT_BOOL, + .id = "rewrite_nit", + .name = N_("Rewrite NIT"), + .desc = N_("Rewrite NIT (Network Information Table) packets " + "to only include information about the currently-" + "streamed service. " + "Rewrite can be unset only if 'Rewrite Service ID' " + "is set to zero."), + .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_nit), + .set = profile_spawn_rewrite_nit_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 3}, + {.type = PT_BOOL, + .id = "rewrite_eit", + .name = N_("Rewrite EIT"), + .desc = N_("Rewrite EIT (Event Information Table) packets " + "to only include information about the currently-" + "streamed service. " + "Rewrite can be unset only if 'Rewrite Service ID' " + "is set to zero."), + .off = offsetof(profile_mpegts_spawn_t, pro_rewrite_eit), + .set = profile_spawn_rewrite_eit_set, + .opts = PO_EXPERT, + .def.i = 1, + .group = 3}, + {}}}; + +static int profile_mpegts_spawn_reopen(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags) { + profile_mpegts_spawn_t* pro = (profile_mpegts_spawn_t*)prch->prch_pro; + muxer_config_t c; if (m_cfg) muxer_config_copy(&c, m_cfg); /* do not alter the original parameter */ @@ -1755,7 +1549,7 @@ profile_mpegts_spawn_reopen(profile_chain_t *prch, mystrset(&c.u.pass.m_cmdline, pro->pro_cmdline); mystrset(&c.u.pass.m_mime, pro->pro_mime); - c.u.pass.m_killsig = pro->pro_killsig; + c.u.pass.m_killsig = pro->pro_killsig; c.u.pass.m_killtimeout = pro->pro_killtimeout; assert(!prch->prch_muxer); @@ -1763,47 +1557,42 @@ profile_mpegts_spawn_reopen(profile_chain_t *prch, return 0; } -static int -profile_mpegts_spawn_open(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, - int flags, size_t qsize) -{ +static int profile_mpegts_spawn_open(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags, + size_t qsize) { prch->prch_flags = SUBSCRIPTION_MPEGTS; prch->prch_sq.sq_st.st_reject_filter = SMT_PACKET; - prch->prch_sq.sq_maxsize = qsize; + prch->prch_sq.sq_maxsize = qsize; - prch->prch_st = &prch->prch_sq.sq_st; + prch->prch_st = &prch->prch_sq.sq_st; return profile_mpegts_spawn_reopen(prch, m_cfg, hints, flags); } -static void -profile_mpegts_spawn_free(profile_t *_pro) -{ - profile_mpegts_spawn_t *pro = (profile_mpegts_spawn_t *)_pro; +static void profile_mpegts_spawn_free(profile_t* _pro) { + profile_mpegts_spawn_t* pro = (profile_mpegts_spawn_t*)_pro; free(pro->pro_cmdline); free(pro->pro_mime); } -static profile_t * -profile_mpegts_spawn_builder(void) -{ - profile_mpegts_spawn_t *pro = calloc(1, sizeof(*pro)); - pro->pro_sflags = SUBSCRIPTION_MPEGTS; - pro->pro_free = profile_mpegts_spawn_free; - pro->pro_reopen = profile_mpegts_spawn_reopen; - pro->pro_open = profile_mpegts_spawn_open; - pro->pro_rewrite_sid = 1; - pro->pro_rewrite_pat = 1; - pro->pro_rewrite_pmt = 1; - pro->pro_rewrite_sdt = 1; - pro->pro_rewrite_nit = 1; - pro->pro_rewrite_eit = 1; - pro->pro_killsig = TVH_KILL_TERM; - pro->pro_killtimeout = 15; - return (profile_t *)pro; +static profile_t* profile_mpegts_spawn_builder(void) { + profile_mpegts_spawn_t* pro = calloc(1, sizeof(*pro)); + pro->pro_sflags = SUBSCRIPTION_MPEGTS; + pro->pro_free = profile_mpegts_spawn_free; + pro->pro_reopen = profile_mpegts_spawn_reopen; + pro->pro_open = profile_mpegts_spawn_open; + pro->pro_rewrite_sid = 1; + pro->pro_rewrite_pat = 1; + pro->pro_rewrite_pmt = 1; + pro->pro_rewrite_sdt = 1; + pro->pro_rewrite_nit = 1; + pro->pro_rewrite_eit = 1; + pro->pro_killsig = TVH_KILL_TERM; + pro->pro_killtimeout = 15; + return (profile_t*)pro; } /* @@ -1815,54 +1604,42 @@ typedef struct profile_matroska { int pro_dvbsub_reorder; } profile_matroska_t; -const idclass_t profile_matroska_class = -{ - .ic_super = &profile_class, - .ic_class = "profile-matroska", - .ic_caption = N_("Matroska (mkv)/built-in"), - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - { - .name = N_("Matroska Specific Settings"), - .number = 2, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "webm", - .name = N_("WEBM"), - .desc = N_("Use WEBM format."), - .off = offsetof(profile_matroska_t, pro_webm), - .opts = PO_ADVANCED, - .def.i = 0, - .group = 2 - }, - { - .type = PT_BOOL, - .id = "dvbsub_reorder", - .name = N_("Reorder DVBSUB"), - .desc = N_("Reorder DVB subtitle packets."), - .off = offsetof(profile_matroska_t, pro_dvbsub_reorder), - .opts = PO_ADVANCED, - .def.i = 1, - .group = 2 - }, - { } - } -}; - -static int -profile_matroska_reopen(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags) -{ - profile_matroska_t *pro = (profile_matroska_t *)prch->prch_pro; - muxer_config_t c; +const idclass_t profile_matroska_class = {.ic_super = &profile_class, + .ic_class = "profile-matroska", + .ic_caption = N_("Matroska (mkv)/built-in"), + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + { + .name = N_("Matroska Specific Settings"), + .number = 2, + }, + {}}, + .ic_properties = (const property_t[]){{.type = PT_BOOL, + .id = "webm", + .name = N_("WEBM"), + .desc = N_("Use WEBM format."), + .off = offsetof(profile_matroska_t, pro_webm), + .opts = PO_ADVANCED, + .def.i = 0, + .group = 2}, + {.type = PT_BOOL, + .id = "dvbsub_reorder", + .name = N_("Reorder DVBSUB"), + .desc = N_("Reorder DVB subtitle packets."), + .off = offsetof(profile_matroska_t, pro_dvbsub_reorder), + .opts = PO_ADVANCED, + .def.i = 1, + .group = 2}, + {}}}; + +static int profile_matroska_reopen(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags) { + profile_matroska_t* pro = (profile_matroska_t*)prch->prch_pro; + muxer_config_t c; if (m_cfg) muxer_config_copy(&c, m_cfg); /* do not alter the original parameter */ @@ -1880,36 +1657,32 @@ profile_matroska_reopen(profile_chain_t *prch, return 0; } -static int -profile_matroska_open(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, - int flags, size_t qsize) -{ - streaming_target_t *dst; +static int profile_matroska_open(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags, + size_t qsize) { + streaming_target_t* dst; - prch->prch_flags = SUBSCRIPTION_PACKET; + prch->prch_flags = SUBSCRIPTION_PACKET; prch->prch_sq.sq_maxsize = qsize; - dst = prch->prch_gh = globalheaders_create(&prch->prch_sq.sq_st); + dst = prch->prch_gh = globalheaders_create(&prch->prch_sq.sq_st); dst = prch->prch_tsfix = tsfix_create(dst); - prch->prch_st = dst; + prch->prch_st = dst; return profile_matroska_reopen(prch, m_cfg, hints, flags); } -static profile_t * -profile_matroska_builder(void) -{ - profile_matroska_t *pro = calloc(1, sizeof(*pro)); - pro->pro_sflags = SUBSCRIPTION_PACKET; - pro->pro_reopen = profile_matroska_reopen; - pro->pro_open = profile_matroska_open; +static profile_t* profile_matroska_builder(void) { + profile_matroska_t* pro = calloc(1, sizeof(*pro)); + pro->pro_sflags = SUBSCRIPTION_PACKET; + pro->pro_reopen = profile_matroska_reopen; + pro->pro_open = profile_matroska_open; pro->pro_dvbsub_reorder = 1; - return (profile_t *)pro; + return (profile_t*)pro; } - /* * Audioes Muxer */ @@ -1919,80 +1692,76 @@ typedef struct profile_audio { int pro_index; } profile_audio_t; -static htsmsg_t * -profile_class_mc_audio_list ( void *o, const char *lang ) -{ +static htsmsg_t* profile_class_mc_audio_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Any"), MC_UNKNOWN }, - { N_("MPEG-2 audio"), MC_MPEG2AUDIO, }, - { N_("AC3 audio"), MC_AC3, }, - { N_("AAC audio"), MC_AAC }, - { N_("MP4 audio"), MC_MP4A }, - { N_("Vorbis audio"), MC_VORBIS }, - { N_("AC-4 audio"), MC_AC4, }, + {N_("Any"), MC_UNKNOWN}, + { + N_("MPEG-2 audio"), + MC_MPEG2AUDIO, + }, + { + N_("AC3 audio"), + MC_AC3, + }, + {N_("AAC audio"), MC_AAC}, + {N_("MP4 audio"), MC_MP4A}, + {N_("Vorbis audio"), MC_VORBIS}, + { + N_("AC-4 audio"), + MC_AC4, + }, }; return strtab2htsmsg(tab, 1, lang); } -const idclass_t profile_audio_class = -{ - .ic_super = &profile_class, - .ic_class = "profile-audio", - .ic_caption = N_("Audio stream"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "type", - .name = N_("Audio type"), - .desc = N_("Pick the stream with given audio type only."), - .opts = PO_DOC_NLIST, - .off = offsetof(profile_audio_t, pro_mc), - .list = profile_class_mc_audio_list, - .group = 1 - }, - { - .type = PT_INT, - .id = "index", - .name = N_("Stream index"), - .desc = N_("Stream index (starts with zero)."), - .off = offsetof(profile_audio_t, pro_index), - .group = 1 - }, - { } - } -}; - - -static int -profile_audio_reopen(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags) -{ - muxer_config_t c; - profile_audio_t *pro = (profile_audio_t *)prch->prch_pro; +const idclass_t profile_audio_class = {.ic_super = &profile_class, + .ic_class = "profile-audio", + .ic_caption = N_("Audio stream"), + .ic_properties = + (const property_t[]){{.type = PT_INT, + .id = "type", + .name = N_("Audio type"), + .desc = N_("Pick the stream with given audio type only."), + .opts = PO_DOC_NLIST, + .off = offsetof(profile_audio_t, pro_mc), + .list = profile_class_mc_audio_list, + .group = 1}, + {.type = PT_INT, + .id = "index", + .name = N_("Stream index"), + .desc = N_("Stream index (starts with zero)."), + .off = offsetof(profile_audio_t, pro_index), + .group = 1}, + {}}}; + +static int profile_audio_reopen(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags) { + muxer_config_t c; + profile_audio_t* pro = (profile_audio_t*)prch->prch_pro; if (m_cfg) muxer_config_copy(&c, m_cfg); /* do not alter the original parameter */ else memset(&c, 0, sizeof(c)); - c.m_type = pro->pro_mc != MC_UNKNOWN ? pro->pro_mc : MC_MPEG2AUDIO; + c.m_type = pro->pro_mc != MC_UNKNOWN ? pro->pro_mc : MC_MPEG2AUDIO; c.u.audioes.m_force_type = pro->pro_mc; - c.u.audioes.m_index = pro->pro_index; + c.u.audioes.m_index = pro->pro_index; assert(!prch->prch_muxer); prch->prch_muxer = muxer_create(&c, hints); return 0; } -static int -profile_audio_open(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, - int flags, size_t qsize) -{ +static int profile_audio_open(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags, + size_t qsize) { int r; - prch->prch_flags = SUBSCRIPTION_PACKET; + prch->prch_flags = SUBSCRIPTION_PACKET; prch->prch_sq.sq_maxsize = qsize; r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0, 0); @@ -2004,17 +1773,14 @@ profile_audio_open(profile_chain_t *prch, return profile_audio_reopen(prch, m_cfg, hints, flags); } -static profile_t * -profile_audio_builder(void) -{ - profile_audio_t *pro = calloc(1, sizeof(*pro)); - pro->pro_sflags = SUBSCRIPTION_PACKET; - pro->pro_reopen = profile_audio_reopen; - pro->pro_open = profile_audio_open; - return (profile_t *)pro; +static profile_t* profile_audio_builder(void) { + profile_audio_t* pro = calloc(1, sizeof(*pro)); + pro->pro_sflags = SUBSCRIPTION_PACKET; + pro->pro_reopen = profile_audio_reopen; + pro->pro_open = profile_audio_open; + return (profile_t*)pro; } - #if ENABLE_LIBAV /* @@ -2024,21 +1790,15 @@ typedef struct profile_libav_mpegts { profile_t; } profile_libav_mpegts_t; -const idclass_t profile_libav_mpegts_class = -{ - .ic_super = &profile_class, - .ic_class = "profile-libav-mpegts", - .ic_caption = N_("MPEG-TS/av-lib"), - .ic_properties = (const property_t[]){ - { } - } -}; +const idclass_t profile_libav_mpegts_class = {.ic_super = &profile_class, + .ic_class = "profile-libav-mpegts", + .ic_caption = N_("MPEG-TS/av-lib"), + .ic_properties = (const property_t[]){{}}}; -static int -profile_libav_mpegts_reopen(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags) -{ +static int profile_libav_mpegts_reopen(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags) { muxer_config_t c; if (m_cfg) @@ -2052,15 +1812,14 @@ profile_libav_mpegts_reopen(profile_chain_t *prch, return 0; } -static int -profile_libav_mpegts_open(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, - int flags, size_t qsize) -{ +static int profile_libav_mpegts_open(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags, + size_t qsize) { int r; - prch->prch_flags = SUBSCRIPTION_PACKET; + prch->prch_flags = SUBSCRIPTION_PACKET; prch->prch_sq.sq_maxsize = qsize; r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0, 0); @@ -2072,14 +1831,12 @@ profile_libav_mpegts_open(profile_chain_t *prch, return profile_libav_mpegts_reopen(prch, m_cfg, hints, flags); } -static profile_t * -profile_libav_mpegts_builder(void) -{ - profile_libav_mpegts_t *pro = calloc(1, sizeof(*pro)); - pro->pro_sflags = SUBSCRIPTION_PACKET; - pro->pro_reopen = profile_libav_mpegts_reopen; - pro->pro_open = profile_libav_mpegts_open; - return (profile_t *)pro; +static profile_t* profile_libav_mpegts_builder(void) { + profile_libav_mpegts_t* pro = calloc(1, sizeof(*pro)); + pro->pro_sflags = SUBSCRIPTION_PACKET; + pro->pro_reopen = profile_libav_mpegts_reopen; + pro->pro_open = profile_libav_mpegts_open; + return (profile_t*)pro; } /* @@ -2090,44 +1847,34 @@ typedef struct profile_libav_matroska { int pro_webm; } profile_libav_matroska_t; -const idclass_t profile_libav_matroska_class = -{ - .ic_super = &profile_class, - .ic_class = "profile-libav-matroska", - .ic_caption = N_("Matroska/av-lib"), - .ic_groups = (const property_group_t[]) { - { - .name = N_("Configuration"), - .number = 1, - }, - { - .name = N_("Matroska specific"), - .number = 2, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "webm", - .name = N_("WEBM"), - .desc = N_("Use WEBM format."), - .off = offsetof(profile_libav_matroska_t, pro_webm), - .opts = PO_ADVANCED, - .def.i = 0, - .group = 2 - }, - { } - } -}; - -static int -profile_libav_matroska_reopen(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags) -{ - profile_libav_matroska_t *pro = (profile_libav_matroska_t *)prch->prch_pro; - muxer_config_t c; +const idclass_t profile_libav_matroska_class = {.ic_super = &profile_class, + .ic_class = "profile-libav-matroska", + .ic_caption = N_("Matroska/av-lib"), + .ic_groups = (const property_group_t[]){{ + .name = N_("Configuration"), + .number = 1, + }, + { + .name = N_("Matroska specific"), + .number = 2, + }, + {}}, + .ic_properties = (const property_t[]){{.type = PT_BOOL, + .id = "webm", + .name = N_("WEBM"), + .desc = N_("Use WEBM format."), + .off = offsetof(profile_libav_matroska_t, pro_webm), + .opts = PO_ADVANCED, + .def.i = 0, + .group = 2}, + {}}}; + +static int profile_libav_matroska_reopen(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags) { + profile_libav_matroska_t* pro = (profile_libav_matroska_t*)prch->prch_pro; + muxer_config_t c; if (m_cfg) muxer_config_copy(&c, m_cfg); /* do not alter the original parameter */ @@ -2143,15 +1890,14 @@ profile_libav_matroska_reopen(profile_chain_t *prch, return 0; } -static int -profile_libav_matroska_open(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, - int flags, size_t qsize) -{ +static int profile_libav_matroska_open(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags, + size_t qsize) { int r; - prch->prch_flags = SUBSCRIPTION_PACKET; + prch->prch_flags = SUBSCRIPTION_PACKET; prch->prch_sq.sq_maxsize = qsize; r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0, 0); @@ -2163,14 +1909,12 @@ profile_libav_matroska_open(profile_chain_t *prch, return profile_libav_matroska_reopen(prch, m_cfg, hints, flags); } -static profile_t * -profile_libav_matroska_builder(void) -{ - profile_libav_matroska_t *pro = calloc(1, sizeof(*pro)); - pro->pro_sflags = SUBSCRIPTION_PACKET; - pro->pro_reopen = profile_libav_matroska_reopen; - pro->pro_open = profile_libav_matroska_open; - return (profile_t *)pro; +static profile_t* profile_libav_matroska_builder(void) { + profile_libav_matroska_t* pro = calloc(1, sizeof(*pro)); + pro->pro_sflags = SUBSCRIPTION_PACKET; + pro->pro_reopen = profile_libav_matroska_reopen; + pro->pro_open = profile_libav_matroska_open; + return (profile_t*)pro; } /* @@ -2180,18 +1924,16 @@ typedef struct profile_libav_mp4 { profile_t; } profile_libav_mp4_t; -const idclass_t profile_libav_mp4_class = -{ - .ic_super = &profile_class, - .ic_class = "profile-libav-mp4", - .ic_caption = N_("MP4/av-lib"), +const idclass_t profile_libav_mp4_class = { + .ic_super = &profile_class, + .ic_class = "profile-libav-mp4", + .ic_caption = N_("MP4/av-lib"), }; -static int -profile_libav_mp4_reopen(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags) -{ +static int profile_libav_mp4_reopen(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags) { muxer_config_t c; if (m_cfg) @@ -2206,15 +1948,14 @@ profile_libav_mp4_reopen(profile_chain_t *prch, return 0; } -static int -profile_libav_mp4_open(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, - int flags, size_t qsize) -{ +static int profile_libav_mp4_open(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags, + size_t qsize) { int r; - prch->prch_flags = SUBSCRIPTION_PACKET; + prch->prch_flags = SUBSCRIPTION_PACKET; prch->prch_sq.sq_maxsize = qsize; r = profile_htsp_work(prch, &prch->prch_sq.sq_st, 0, 0); @@ -2226,14 +1967,12 @@ profile_libav_mp4_open(profile_chain_t *prch, return profile_libav_mp4_reopen(prch, m_cfg, hints, flags); } -static profile_t * -profile_libav_mp4_builder(void) -{ - profile_libav_mp4_t *pro = calloc(1, sizeof(*pro)); - pro->pro_sflags = SUBSCRIPTION_PACKET; - pro->pro_reopen = profile_libav_mp4_reopen; - pro->pro_open = profile_libav_mp4_open; - return (profile_t *)pro; +static profile_t* profile_libav_mp4_builder(void) { + profile_libav_mp4_t* pro = calloc(1, sizeof(*pro)); + pro->pro_sflags = SUBSCRIPTION_PACKET; + pro->pro_reopen = profile_libav_mp4_reopen; + pro->pro_open = profile_libav_mp4_open; + return (profile_t*)pro; } /* @@ -2243,36 +1982,37 @@ profile_libav_mp4_builder(void) typedef struct profile_transcode { profile_t; int pro_mc; - char *pro_vcodec; - char *pro_src_vcodec; - char *pro_acodec; - char *pro_src_acodec; - char *pro_scodec; - char *pro_src_scodec; + char* pro_vcodec; + char* pro_src_vcodec; + char* pro_acodec; + char* pro_src_acodec; + char* pro_scodec; + char* pro_src_scodec; } profile_transcode_t; - -static htsmsg_t * -profile_class_mc_list ( void *o, const char *lang ) -{ +static htsmsg_t* profile_class_mc_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("Not set"), MC_UNKNOWN }, - { N_("Matroska (mkv)/built-in"), MC_MATROSKA, }, - { N_("WEBM/built-in"), MC_WEBM, }, - { N_("MPEG-TS/av-lib"), MC_MPEGTS }, - { N_("MPEG-PS (DVD)/av-lib"), MC_MPEGPS }, - { N_("Raw Audio Stream"), MC_MPEG2AUDIO }, - { N_("Matroska (mkv)/av-lib"), MC_AVMATROSKA }, - { N_("WEBM/av-lib"), MC_AVWEBM }, - { N_("MP4/av-lib"), MC_AVMP4 }, + {N_("Not set"), MC_UNKNOWN}, + { + N_("Matroska (mkv)/built-in"), + MC_MATROSKA, + }, + { + N_("WEBM/built-in"), + MC_WEBM, + }, + {N_("MPEG-TS/av-lib"), MC_MPEGTS}, + {N_("MPEG-PS (DVD)/av-lib"), MC_MPEGPS}, + {N_("Raw Audio Stream"), MC_MPEG2AUDIO}, + {N_("Matroska (mkv)/av-lib"), MC_AVMATROSKA}, + {N_("WEBM/av-lib"), MC_AVWEBM}, + {N_("MP4/av-lib"), MC_AVMP4}, }; return strtab2htsmsg(tab, 1, lang); } -static int -htsmsg_add_entry(htsmsg_t *list, const char *key, const char *val) -{ - htsmsg_t *map = NULL; +static int htsmsg_add_entry(htsmsg_t* list, const char* key, const char* val) { + htsmsg_t* map = NULL; if ((map = htsmsg_create_map())) { htsmsg_add_str(map, "key", key); @@ -2283,14 +2023,12 @@ htsmsg_add_entry(htsmsg_t *list, const char *key, const char *val) return -1; } -static htsmsg_t * -profile_class_codec_profile_make_list(const char *lang) -{ - htsmsg_t *list = NULL; +static htsmsg_t* profile_class_codec_profile_make_list(const char* lang) { + htsmsg_t* list = NULL; if ((list = htsmsg_create_list())) { if (htsmsg_add_entry(list, "", tvh_gettext_lang(lang, N_("Disabled"))) || - htsmsg_add_entry(list, "copy", tvh_gettext_lang(lang, N_("Copy")))) { + htsmsg_add_entry(list, "copy", tvh_gettext_lang(lang, N_("Copy")))) { htsmsg_destroy(list); list = NULL; } @@ -2298,11 +2036,9 @@ profile_class_codec_profile_make_list(const char *lang) return list; } -static htsmsg_t * -profile_class_codec_profiles_list(enum AVMediaType media_type, const char *lang) -{ - htsmsg_t *list = NULL, *profiles = NULL, *map = NULL; - htsmsg_field_t *field; +static htsmsg_t* profile_class_codec_profiles_list(enum AVMediaType media_type, const char* lang) { + htsmsg_t * list = NULL, *profiles = NULL, *map = NULL; + htsmsg_field_t* field; if ((list = profile_class_codec_profile_make_list(lang)) && (profiles = codec_get_profiles_list(media_type))) { @@ -2320,19 +2056,13 @@ profile_class_codec_profiles_list(enum AVMediaType media_type, const char *lang) return list; } -static htsmsg_t * -profile_class_pro_vcodec_list(void *o, const char *lang) -{ +static htsmsg_t* profile_class_pro_vcodec_list(void* o, const char* lang) { return profile_class_codec_profiles_list(AVMEDIA_TYPE_VIDEO, lang); } -static int -profile_class_src_codec_set(profile_transcode_t *pro, - char **str, - const void *p) -{ - char *s = htsmsg_list_2_csv((htsmsg_t *)p, ',', 0); - int change = 0; +static int profile_class_src_codec_set(profile_transcode_t* pro, char** str, const void* p) { + char* s = htsmsg_list_2_csv((htsmsg_t*)p, ',', 0); + int change = 0; if (s) { change = strcmp(*str ?: "", s) != 0; free(*str); @@ -2341,214 +2071,166 @@ profile_class_src_codec_set(profile_transcode_t *pro, return change; } -static const void * -profile_class_src_codec_get(profile_transcode_t *pro, - char *str) -{ +static const void* profile_class_src_codec_get(profile_transcode_t* pro, char* str) { return htsmsg_csv_2_list(str, ','); } static const struct strtab_str profile_class_src_vcodec_tab[] = { - { "MPEG2VIDEO", "MPEG2VIDEO" }, - { "H264", "H264" }, - { "VP8", "VP8" }, - { "HEVC", "HEVC" }, - { "VP9", "VP9" }, - { "THEORA", "THEORA" }, + {"MPEG2VIDEO", "MPEG2VIDEO"}, + {"H264", "H264"}, + {"VP8", "VP8"}, + {"HEVC", "HEVC"}, + {"VP9", "VP9"}, + {"THEORA", "THEORA"}, }; -static int -profile_class_src_vcodec_set ( void *obj, const void *p ) -{ - profile_transcode_t *pro = (profile_transcode_t *)obj; +static int profile_class_src_vcodec_set(void* obj, const void* p) { + profile_transcode_t* pro = (profile_transcode_t*)obj; return profile_class_src_codec_set(pro, &pro->pro_src_vcodec, p); } -static const void * -profile_class_src_vcodec_get ( void *obj ) -{ - profile_transcode_t *pro = (profile_transcode_t *)obj; +static const void* profile_class_src_vcodec_get(void* obj) { + profile_transcode_t* pro = (profile_transcode_t*)obj; return profile_class_src_codec_get(pro, pro->pro_src_vcodec); } -static htsmsg_t * -profile_class_src_vcodec_list ( void *o, const char *lang ) -{ +static htsmsg_t* profile_class_src_vcodec_list(void* o, const char* lang) { return strtab2htsmsg_str(profile_class_src_vcodec_tab, 1, lang); } -static htsmsg_t * -profile_class_pro_acodec_list(void *o, const char *lang) -{ +static htsmsg_t* profile_class_pro_acodec_list(void* o, const char* lang) { return profile_class_codec_profiles_list(AVMEDIA_TYPE_AUDIO, lang); } static const struct strtab_str profile_class_src_acodec_tab[] = { - { "MPEG2AUDIO", "MPEG2AUDIO" }, - { "AC3", "AC3" }, - { "AAC", "AAC" }, - { "MP4A", "MP4A" }, - { "EAC3", "EAC3" }, - { "VORBIS", "VORBIS" }, - { "OPUS", "OPUS" }, - { "AC-4", "AC-4" }, + {"MPEG2AUDIO", "MPEG2AUDIO"}, + {"AC3", "AC3"}, + {"AAC", "AAC"}, + {"MP4A", "MP4A"}, + {"EAC3", "EAC3"}, + {"VORBIS", "VORBIS"}, + {"OPUS", "OPUS"}, + {"AC-4", "AC-4"}, }; -static int -profile_class_src_acodec_set ( void *obj, const void *p ) -{ - profile_transcode_t *pro = (profile_transcode_t *)obj; +static int profile_class_src_acodec_set(void* obj, const void* p) { + profile_transcode_t* pro = (profile_transcode_t*)obj; return profile_class_src_codec_set(pro, &pro->pro_src_acodec, p); } -static const void * -profile_class_src_acodec_get ( void *obj ) -{ - profile_transcode_t *pro = (profile_transcode_t *)obj; +static const void* profile_class_src_acodec_get(void* obj) { + profile_transcode_t* pro = (profile_transcode_t*)obj; return profile_class_src_codec_get(pro, pro->pro_src_acodec); } -static htsmsg_t * -profile_class_src_acodec_list ( void *o, const char *lang ) -{ +static htsmsg_t* profile_class_src_acodec_list(void* o, const char* lang) { return strtab2htsmsg_str(profile_class_src_acodec_tab, 1, lang); } -static htsmsg_t * -profile_class_pro_scodec_list(void *o, const char *lang) -{ +static htsmsg_t* profile_class_pro_scodec_list(void* o, const char* lang) { return profile_class_codec_profiles_list(AVMEDIA_TYPE_SUBTITLE, lang); } static const struct strtab_str profile_class_src_scodec_tab[] = { - { "DVBSUB", "DVBSUB" }, - { "TEXTSUB", "TEXTSUB" }, + {"DVBSUB", "DVBSUB"}, + {"TEXTSUB", "TEXTSUB"}, }; -static int -profile_class_src_scodec_set ( void *obj, const void *p ) -{ - profile_transcode_t *pro = (profile_transcode_t *)obj; +static int profile_class_src_scodec_set(void* obj, const void* p) { + profile_transcode_t* pro = (profile_transcode_t*)obj; return profile_class_src_codec_set(pro, &pro->pro_src_scodec, p); } -static const void * -profile_class_src_scodec_get ( void *obj ) -{ - profile_transcode_t *pro = (profile_transcode_t *)obj; +static const void* profile_class_src_scodec_get(void* obj) { + profile_transcode_t* pro = (profile_transcode_t*)obj; return profile_class_src_codec_get(pro, pro->pro_src_scodec); } -static htsmsg_t * -profile_class_src_scodec_list ( void *o, const char *lang ) -{ +static htsmsg_t* profile_class_src_scodec_list(void* o, const char* lang) { return strtab2htsmsg_str(profile_class_src_scodec_tab, 1, lang); } -const idclass_t profile_transcode_class = -{ - .ic_super = &profile_class, - .ic_class = "profile-transcode", - .ic_caption = N_("Transcode/av-lib"), - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - { - .name = N_("Transcoding Settings"), - .number = 2, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "container", - .name = N_("Container"), - .desc = N_("Container to use for the transcoded stream."), - .off = offsetof(profile_transcode_t, pro_mc), - .def.i = MC_MATROSKA, - .list = profile_class_mc_list, - .opts = PO_DOC_NLIST, - .group = 1 - }, - { - .type = PT_STR, - .id = "pro_vcodec", - .name = N_("Video codec profile"), - .desc = N_("Select video codec profile to use for transcoding."), - .off = offsetof(profile_transcode_t, pro_vcodec), - .list = profile_class_pro_vcodec_list, - .opts = PO_ADVANCED | PO_DOC_NLIST, - .group = 2 - }, - { - .type = PT_STR, - .islist = 1, - .id = "src_vcodec", - .name = N_("Source video codec"), - .desc = N_("Transcode video only for selected codecs."), - .get = profile_class_src_vcodec_get, - .set = profile_class_src_vcodec_set, - .list = profile_class_src_vcodec_list, - .opts = PO_ADVANCED | PO_DOC_NLIST, - .group = 2 - }, - { - .type = PT_STR, - .id = "pro_acodec", - .name = N_("Audio codec profile"), - .desc = N_("Select audio codec profile to use for transcoding."), - .off = offsetof(profile_transcode_t, pro_acodec), - .list = profile_class_pro_acodec_list, - .opts = PO_ADVANCED | PO_DOC_NLIST, - .group = 2 - }, - { - .type = PT_STR, - .islist = 1, - .id = "src_acodec", - .name = N_("Source audio codec"), - .desc = N_("Transcode audio only for selected codecs."), - .get = profile_class_src_acodec_get, - .set = profile_class_src_acodec_set, - .list = profile_class_src_acodec_list, - .opts = PO_ADVANCED | PO_DOC_NLIST, - .group = 2 - }, - { - .type = PT_STR, - .id = "pro_scodec", - .name = N_("Subtitle codec profile"), - .desc = N_("Select subtitle codec profile to use for transcoding."), - .off = offsetof(profile_transcode_t, pro_scodec), - .list = profile_class_pro_scodec_list, - .opts = PO_ADVANCED | PO_DOC_NLIST, - .group = 2 - }, - { - .type = PT_STR, - .islist = 1, - .id = "src_scodec", - .name = N_("Source subtitle codec"), - .desc = N_("Transcode subtitle only for selected codecs."), - .get = profile_class_src_scodec_get, - .set = profile_class_src_scodec_set, - .list = profile_class_src_scodec_list, - .opts = PO_ADVANCED | PO_DOC_NLIST, - .group = 2 - }, - { } - } -}; - -static int -profile_transcode_can_share(profile_chain_t *prch, - profile_chain_t *joiner) -{ - profile_transcode_t *pro1 = (profile_transcode_t *)prch->prch_pro; - profile_transcode_t *pro2 = (profile_transcode_t *)joiner->prch_pro; +const idclass_t profile_transcode_class = {.ic_super = &profile_class, + .ic_class = "profile-transcode", + .ic_caption = N_("Transcode/av-lib"), + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + { + .name = N_("Transcoding Settings"), + .number = 2, + }, + {}}, + .ic_properties = + (const property_t[]){{.type = PT_INT, + .id = "container", + .name = N_("Container"), + .desc = N_("Container to use for the transcoded stream."), + .off = offsetof(profile_transcode_t, pro_mc), + .def.i = MC_MATROSKA, + .list = profile_class_mc_list, + .opts = PO_DOC_NLIST, + .group = 1}, + {.type = PT_STR, + .id = "pro_vcodec", + .name = N_("Video codec profile"), + .desc = N_("Select video codec profile to use for transcoding."), + .off = offsetof(profile_transcode_t, pro_vcodec), + .list = profile_class_pro_vcodec_list, + .opts = PO_ADVANCED | PO_DOC_NLIST, + .group = 2}, + {.type = PT_STR, + .islist = 1, + .id = "src_vcodec", + .name = N_("Source video codec"), + .desc = N_("Transcode video only for selected codecs."), + .get = profile_class_src_vcodec_get, + .set = profile_class_src_vcodec_set, + .list = profile_class_src_vcodec_list, + .opts = PO_ADVANCED | PO_DOC_NLIST, + .group = 2}, + {.type = PT_STR, + .id = "pro_acodec", + .name = N_("Audio codec profile"), + .desc = N_("Select audio codec profile to use for transcoding."), + .off = offsetof(profile_transcode_t, pro_acodec), + .list = profile_class_pro_acodec_list, + .opts = PO_ADVANCED | PO_DOC_NLIST, + .group = 2}, + {.type = PT_STR, + .islist = 1, + .id = "src_acodec", + .name = N_("Source audio codec"), + .desc = N_("Transcode audio only for selected codecs."), + .get = profile_class_src_acodec_get, + .set = profile_class_src_acodec_set, + .list = profile_class_src_acodec_list, + .opts = PO_ADVANCED | PO_DOC_NLIST, + .group = 2}, + {.type = PT_STR, + .id = "pro_scodec", + .name = N_("Subtitle codec profile"), + .desc = N_("Select subtitle codec profile to use for transcoding."), + .off = offsetof(profile_transcode_t, pro_scodec), + .list = profile_class_pro_scodec_list, + .opts = PO_ADVANCED | PO_DOC_NLIST, + .group = 2}, + {.type = PT_STR, + .islist = 1, + .id = "src_scodec", + .name = N_("Source subtitle codec"), + .desc = N_("Transcode subtitle only for selected codecs."), + .get = profile_class_src_scodec_get, + .set = profile_class_src_scodec_set, + .list = profile_class_src_scodec_list, + .opts = PO_ADVANCED | PO_DOC_NLIST, + .group = 2}, + {}}}; + +static int profile_transcode_can_share(profile_chain_t* prch, profile_chain_t* joiner) { + profile_transcode_t* pro1 = (profile_transcode_t*)prch->prch_pro; + profile_transcode_t* pro2 = (profile_transcode_t*)joiner->prch_pro; if (pro1 == pro2) return 1; if (!idnode_is_instance(&pro2->pro_id, &profile_transcode_class)) @@ -2572,15 +2254,14 @@ profile_transcode_can_share(profile_chain_t *prch, return 1; } -static int -profile_transcode_work(profile_chain_t *prch, - streaming_target_t *dst, - uint32_t timeshift_period, profile_work_flags_t flags) -{ - profile_sharer_t *prsh; - profile_transcode_t *pro = (profile_transcode_t *)prch->prch_pro; - const char *profiles[AVMEDIA_TYPE_NB] = { NULL }; - const char *src_codecs[AVMEDIA_TYPE_NB] = { NULL }; +static int profile_transcode_work(profile_chain_t* prch, + streaming_target_t* dst, + uint32_t timeshift_period, + profile_work_flags_t flags) { + profile_sharer_t* prsh; + profile_transcode_t* pro = (profile_transcode_t*)prch->prch_pro; + const char* profiles[AVMEDIA_TYPE_NB] = {NULL}; + const char* src_codecs[AVMEDIA_TYPE_NB] = {NULL}; prsh = profile_sharer_find(prch); if (!prsh) @@ -2588,12 +2269,12 @@ profile_transcode_work(profile_chain_t *prch, prch->prch_can_share = profile_transcode_can_share; - profiles[AVMEDIA_TYPE_VIDEO] = pro->pro_vcodec ?: ""; - profiles[AVMEDIA_TYPE_AUDIO] = pro->pro_acodec ?: ""; + profiles[AVMEDIA_TYPE_VIDEO] = pro->pro_vcodec ?: ""; + profiles[AVMEDIA_TYPE_AUDIO] = pro->pro_acodec ?: ""; profiles[AVMEDIA_TYPE_SUBTITLE] = pro->pro_scodec ?: ""; - src_codecs[AVMEDIA_TYPE_VIDEO] = pro->pro_src_vcodec ?: ""; - src_codecs[AVMEDIA_TYPE_AUDIO] = pro->pro_src_acodec ?: ""; + src_codecs[AVMEDIA_TYPE_VIDEO] = pro->pro_src_vcodec ?: ""; + src_codecs[AVMEDIA_TYPE_AUDIO] = pro->pro_src_acodec ?: ""; src_codecs[AVMEDIA_TYPE_SUBTITLE] = pro->pro_src_scodec ?: ""; dst = prch->prch_gh = globalheaders_create(dst); @@ -2606,17 +2287,16 @@ profile_transcode_work(profile_chain_t *prch, goto fail; if (!prsh->prsh_transcoder) { assert(!prsh->prsh_tsfix); - dst = prsh->prsh_transcoder = transcoder_create(&prsh->prsh_input, - profiles, src_codecs); + dst = prsh->prsh_transcoder = transcoder_create(&prsh->prsh_input, profiles, src_codecs); if (!dst) goto fail; prsh->prsh_tsfix = tsfix_create(dst); } prch->prch_share = prsh->prsh_tsfix; streaming_target_init(&prch->prch_input, - prsh->prsh_do_queue ? - &profile_input_queue_ops : &profile_input_ops, prch, - 0); + prsh->prsh_do_queue ? &profile_input_queue_ops : &profile_input_ops, + prch, + 0); prch->prch_st = &prch->prch_input; if (profile_sharer_postinit(prsh)) goto fail; @@ -2626,34 +2306,31 @@ fail: return -1; } -static int -profile_transcode_mc_valid(int mc) -{ +static int profile_transcode_mc_valid(int mc) { switch (mc) { - case MC_MATROSKA: - case MC_WEBM: - case MC_MPEGTS: - case MC_MPEGPS: - case MC_MPEG2AUDIO: - case MC_AC3: - case MC_AC4: - case MC_AAC: - case MC_VORBIS: - case MC_AVMATROSKA: - case MC_AVMP4: - return 1; - default: - return 0; - } -} - -static int -profile_transcode_reopen(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags) -{ - profile_transcode_t *pro = (profile_transcode_t *)prch->prch_pro; - muxer_config_t c; + case MC_MATROSKA: + case MC_WEBM: + case MC_MPEGTS: + case MC_MPEGPS: + case MC_MPEG2AUDIO: + case MC_AC3: + case MC_AC4: + case MC_AAC: + case MC_VORBIS: + case MC_AVMATROSKA: + case MC_AVMP4: + return 1; + default: + return 0; + } +} + +static int profile_transcode_reopen(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags) { + profile_transcode_t* pro = (profile_transcode_t*)prch->prch_pro; + muxer_config_t c; if (m_cfg) muxer_config_copy(&c, m_cfg); /* do not alter the original parameter */ @@ -2670,17 +2347,16 @@ profile_transcode_reopen(profile_chain_t *prch, return 0; } -static int -profile_transcode_open(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, - int flags, size_t qsize) -{ +static int profile_transcode_open(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags, + size_t qsize) { int r; prch->prch_can_share = profile_transcode_can_share; - prch->prch_flags = SUBSCRIPTION_PACKET; + prch->prch_flags = SUBSCRIPTION_PACKET; prch->prch_sq.sq_maxsize = qsize; r = profile_transcode_work(prch, &prch->prch_sq.sq_st, 0, 0); @@ -2692,10 +2368,8 @@ profile_transcode_open(profile_chain_t *prch, return profile_transcode_reopen(prch, m_cfg, hints, flags); } -static void -profile_transcode_free(profile_t *_pro) -{ - profile_transcode_t *pro = (profile_transcode_t *)_pro; +static void profile_transcode_free(profile_t* _pro) { + profile_transcode_t* pro = (profile_transcode_t*)_pro; free(pro->pro_vcodec); free(pro->pro_src_vcodec); free(pro->pro_acodec); @@ -2704,16 +2378,14 @@ profile_transcode_free(profile_t *_pro) free(pro->pro_src_scodec); } -static profile_t * -profile_transcode_builder(void) -{ - profile_transcode_t *pro = calloc(1, sizeof(*pro)); - pro->pro_sflags = SUBSCRIPTION_PACKET; - pro->pro_free = profile_transcode_free; - pro->pro_work = profile_transcode_work; - pro->pro_reopen = profile_transcode_reopen; - pro->pro_open = profile_transcode_open; - return (profile_t *)pro; +static profile_t* profile_transcode_builder(void) { + profile_transcode_t* pro = calloc(1, sizeof(*pro)); + pro->pro_sflags = SUBSCRIPTION_PACKET; + pro->pro_free = profile_transcode_free; + pro->pro_work = profile_transcode_work; + pro->pro_reopen = profile_transcode_reopen; + pro->pro_open = profile_transcode_open; + return (profile_t*)pro; } #endif /* ENABLE_TRANSCODE */ @@ -2721,13 +2393,11 @@ profile_transcode_builder(void) /* * Initialize */ -void -profile_init(void) -{ - htsmsg_t *c, *e; - htsmsg_field_t *f; - profile_t *pro; - const char *name; +void profile_init(void) { + htsmsg_t * c, *e; + htsmsg_field_t* f; + profile_t* pro; + const char* name; LIST_INIT(&profile_builders); TAILQ_INIT(&profiles); @@ -2783,7 +2453,7 @@ profile_init(void) continue; pro = profile_find_by_name2(name, NULL, 1); if (pro == NULL || strcmp(profile_get_name(pro), name)) { -transcoder_create: + transcoder_create: htsmsg_add_str(e, "class", "profile-transcode"); if (!htsmsg_field_find(e, "enabled")) htsmsg_add_bool(e, "enabled", 1); @@ -2793,7 +2463,7 @@ transcoder_create: htsmsg_add_bool(e, "shield", 1); (void)profile_create(NULL, e, 1); } else if (pro && idnode_is_instance(&pro->pro_id, &profile_transcode_class)) { - profile_transcode_t *prot = (profile_transcode_t *)pro; + profile_transcode_t* prot = (profile_transcode_t*)pro; if (tvh_str_default(prot->pro_vcodec, NULL) == NULL) { profile_delete(pro, 1); goto transcoder_create; @@ -2813,11 +2483,9 @@ transcoder_create: } } -void -profile_done(void) -{ - profile_t *pro; - profile_build_t *pb; +void profile_done(void) { + profile_t* pro; + profile_build_t* pb; tvh_mutex_lock(&global_lock); profile_default = NULL; diff --git a/src/profile.h b/src/profile.h index 0496c6911..6ae9e7558 100644 --- a/src/profile.h +++ b/src/profile.h @@ -45,10 +45,7 @@ typedef enum { PROFILE_SVF_UHD } profile_svfilter_t; -typedef enum { - PROFILE_WORK_NONE = 0, - PROFILE_WORK_REMOTE_TS -} profile_work_flags_t; +typedef enum { PROFILE_WORK_NONE = 0, PROFILE_WORK_REMOTE_TS } profile_work_flags_t; struct profile; struct muxer; @@ -63,11 +60,11 @@ TAILQ_HEAD(profile_entry_queue, profile); extern struct profile_entry_queue profiles; -typedef struct profile *(*profile_builder_t)(void); +typedef struct profile* (*profile_builder_t)(void); typedef struct profile_build { LIST_ENTRY(profile_build) link; - const idclass_t *clazz; + const idclass_t* clazz; profile_builder_t build; } profile_build_t; @@ -77,35 +74,34 @@ extern profile_builders_queue profile_builders; typedef struct profile_chain { LIST_ENTRY(profile_chain) prch_link; - int prch_linked; + int prch_linked; - struct profile_sharer *prch_sharer; + struct profile_sharer* prch_sharer; LIST_ENTRY(profile_chain) prch_sharer_link; - struct profile *prch_pro; - void *prch_id; - - int64_t prch_ts_delta; - - int prch_flags; - int prch_stop; - int prch_start_pending; - int prch_sq_used; - struct streaming_queue prch_sq; - struct streaming_target *prch_post_share; - struct streaming_target *prch_st; - struct muxer *prch_muxer; - struct streaming_target *prch_gh; - struct streaming_target *prch_tsfix; + struct profile* prch_pro; + void* prch_id; + + int64_t prch_ts_delta; + + int prch_flags; + int prch_stop; + int prch_start_pending; + int prch_sq_used; + struct streaming_queue prch_sq; + struct streaming_target* prch_post_share; + struct streaming_target* prch_st; + struct muxer* prch_muxer; + struct streaming_target* prch_gh; + struct streaming_target* prch_tsfix; #if ENABLE_TIMESHIFT - struct streaming_target *prch_timeshift; - struct streaming_target *prch_rtsp; + struct streaming_target* prch_timeshift; + struct streaming_target* prch_rtsp; #endif - struct streaming_target prch_input; - struct streaming_target *prch_share; + struct streaming_target prch_input; + struct streaming_target* prch_share; - int (*prch_can_share)(struct profile_chain *prch, - struct profile_chain *joiner); + int (*prch_can_share)(struct profile_chain* prch, struct profile_chain* joiner); } profile_chain_t; typedef struct profile { @@ -114,100 +110,108 @@ typedef struct profile { int pro_refcount; - LIST_HEAD(,dvr_config) pro_dvr_configs; + LIST_HEAD(, dvr_config) pro_dvr_configs; idnode_list_head_t pro_accesses; - int pro_sflags; - int pro_enabled; - int pro_shield; - char *pro_name; - char *pro_comment; - int pro_prio; - int pro_fprio; - int pro_timeout; - int pro_restart; - int pro_contaccess; - int pro_ca_timeout; - int pro_swservice; - int pro_svfilter; - - void (*pro_free)(struct profile *pro); - void (*pro_conf_changed)(struct profile *pro); - - int (*pro_work)(profile_chain_t *prch, struct streaming_target *dst, - uint32_t timeshift_period, profile_work_flags_t flags); - int (*pro_reopen)(profile_chain_t *prch, muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags); - int (*pro_open)(profile_chain_t *prch, muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags, size_t qsize); + int pro_sflags; + int pro_enabled; + int pro_shield; + char* pro_name; + char* pro_comment; + int pro_prio; + int pro_fprio; + int pro_timeout; + int pro_restart; + int pro_contaccess; + int pro_ca_timeout; + int pro_swservice; + int pro_svfilter; + + void (*pro_free)(struct profile* pro); + void (*pro_conf_changed)(struct profile* pro); + + int (*pro_work)(profile_chain_t* prch, + struct streaming_target* dst, + uint32_t timeshift_period, + profile_work_flags_t flags); + int (*pro_reopen)(profile_chain_t* prch, muxer_config_t* m_cfg, muxer_hints_t* hints, int flags); + int (*pro_open)(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags, + size_t qsize); } profile_t; typedef struct profile_sharer_message { TAILQ_ENTRY(profile_sharer_message) psm_link; - profile_chain_t *psm_prch; - streaming_message_t *psm_sm; + profile_chain_t* psm_prch; + streaming_message_t* psm_sm; } profile_sharer_message_t; typedef struct profile_sharer { - uint32_t prsh_do_queue: 1; - uint32_t prsh_queue_run: 1; - pthread_t prsh_queue_thread; - tvh_mutex_t prsh_queue_mutex; - tvh_cond_t prsh_queue_cond; - TAILQ_HEAD(,profile_sharer_message) prsh_queue; - streaming_target_t prsh_input; - LIST_HEAD(,profile_chain) prsh_chains; - struct profile_chain *prsh_master; - struct streaming_start *prsh_start_msg; - struct streaming_target *prsh_tsfix; + uint32_t prsh_do_queue : 1; + uint32_t prsh_queue_run : 1; + pthread_t prsh_queue_thread; + tvh_mutex_t prsh_queue_mutex; + tvh_cond_t prsh_queue_cond; + TAILQ_HEAD(, profile_sharer_message) prsh_queue; + streaming_target_t prsh_input; + LIST_HEAD(, profile_chain) prsh_chains; + struct profile_chain* prsh_master; + struct streaming_start* prsh_start_msg; + struct streaming_target* prsh_tsfix; #if ENABLE_LIBAV - struct streaming_target *prsh_transcoder; + struct streaming_target* prsh_transcoder; #endif } profile_sharer_t; -void profile_register(const idclass_t *clazz, profile_builder_t builder); - -profile_t *profile_create - (const char *uuid, htsmsg_t *conf, int save); - -static inline void profile_grab( profile_t *pro ) - { pro->pro_refcount++; } - -void profile_release_( profile_t *pro ); -static inline void profile_release( profile_t *pro ) - { - assert(pro->pro_refcount > 0); - if (--pro->pro_refcount == 0) profile_release_(pro); - } - -int profile_chain_work(profile_chain_t *prch, struct streaming_target *dst, - uint32_t timeshift_period, profile_work_flags_t flags); -int profile_chain_reopen(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, int flags); -int profile_chain_open(profile_chain_t *prch, - muxer_config_t *m_cfg, - muxer_hints_t *hints, - int flags, size_t qsize); -void profile_chain_init(profile_chain_t *prch, profile_t *pro, void *id, int queue); -int profile_chain_raw_open(profile_chain_t *prch, void *id, size_t qsize, int muxer); -void profile_chain_close(profile_chain_t *prch); -int profile_chain_weight(profile_chain_t *prch, int custom); - -static inline profile_t *profile_find_by_uuid(const char *uuid) - { return (profile_t*)idnode_find(uuid, &profile_class, NULL); } -profile_t *profile_find_by_name(const char *name, const char *alt); -profile_t *profile_find_by_list(htsmsg_t *uuids, const char *name, - const char *alt, int sflags); -int profile_verify(profile_t *pro, int sflags); - -htsmsg_t * profile_class_get_list(void *o, const char *lang); - -char *profile_validate_name(const char *name); - -const char *profile_get_name(profile_t *pro); - -void profile_get_htsp_list(htsmsg_t *array, htsmsg_t *filter); +void profile_register(const idclass_t* clazz, profile_builder_t builder); + +profile_t* profile_create(const char* uuid, htsmsg_t* conf, int save); + +static inline void profile_grab(profile_t* pro) { + pro->pro_refcount++; +} + +void profile_release_(profile_t* pro); +static inline void profile_release(profile_t* pro) { + assert(pro->pro_refcount > 0); + if (--pro->pro_refcount == 0) + profile_release_(pro); +} + +int profile_chain_work(profile_chain_t* prch, + struct streaming_target* dst, + uint32_t timeshift_period, + profile_work_flags_t flags); +int profile_chain_reopen(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags); +int profile_chain_open(profile_chain_t* prch, + muxer_config_t* m_cfg, + muxer_hints_t* hints, + int flags, + size_t qsize); +void profile_chain_init(profile_chain_t* prch, profile_t* pro, void* id, int queue); +int profile_chain_raw_open(profile_chain_t* prch, void* id, size_t qsize, int muxer); +void profile_chain_close(profile_chain_t* prch); +int profile_chain_weight(profile_chain_t* prch, int custom); + +static inline profile_t* profile_find_by_uuid(const char* uuid) { + return (profile_t*)idnode_find(uuid, &profile_class, NULL); +} +profile_t* profile_find_by_name(const char* name, const char* alt); +profile_t* profile_find_by_list(htsmsg_t* uuids, const char* name, const char* alt, int sflags); +int profile_verify(profile_t* pro, int sflags); + +htsmsg_t* profile_class_get_list(void* o, const char* lang); + +char* profile_validate_name(const char* name); + +const char* profile_get_name(profile_t* pro); + +void profile_get_htsp_list(htsmsg_t* array, htsmsg_t* filter); void profile_init(void); void profile_done(void); diff --git a/src/prop.c b/src/prop.c index e91f75b31..1aaa80cfc 100644 --- a/src/prop.c +++ b/src/prop.c @@ -25,9 +25,9 @@ #include "tvh_locale.h" #include "lang_str.h" -char prop_sbuf[PROP_SBUF_LEN]; -const char *prop_sbuf_ptr = prop_sbuf; -const char *prop_ptr; +char prop_sbuf[PROP_SBUF_LEN]; +const char* prop_sbuf_ptr = prop_sbuf; +const char* prop_ptr; /* ************************************************************************** * Utilities @@ -37,25 +37,22 @@ const char *prop_ptr; * */ static const struct strtab typetab[] = { - { "bool", PT_BOOL }, - { "int", PT_INT }, - { "str", PT_STR }, - { "u16", PT_U16 }, - { "u32", PT_U32 }, - { "s64", PT_S64 }, - { "s64", PT_S64_ATOMIC }, - { "dbl", PT_DBL }, - { "time", PT_TIME }, - { "langstr", PT_LANGSTR }, - { "perm", PT_PERM }, + {"bool", PT_BOOL}, + {"int", PT_INT}, + {"str", PT_STR}, + {"u16", PT_U16}, + {"u32", PT_U32}, + {"s64", PT_S64}, + {"s64", PT_S64_ATOMIC}, + {"dbl", PT_DBL}, + {"time", PT_TIME}, + {"langstr", PT_LANGSTR}, + {"perm", PT_PERM}, }; - -const property_t * -prop_find(const property_t *p, const char *id) -{ - for(; p->id; p++) - if(!strcmp(id, p->id)) +const property_t* prop_find(const property_t* p, const char* id) { + for (; p->id; p++) + if (!strcmp(id, p->id)) return p; return NULL; } @@ -67,42 +64,47 @@ prop_find(const property_t *p, const char *id) /** * */ -int -prop_write_values - (void *obj, const property_t *pl, htsmsg_t *m, int optmask, - htsmsg_t *updated) -{ - int save, save2 = 0; - htsmsg_field_t *f; - const property_t *p; - void *cur; - const void *snew; - void *dnew; - double dbl; - int i; - int64_t s64; - uint32_t u32, opts; - uint16_t u16; - time_t tm; -#define PROP_UPDATE(v, t)\ - snew = &v;\ - if (!p->set && (*((t*)cur) != *((t*)snew))) {\ - save = 1;\ - *((t*)cur) = *((t*)snew);\ - } (void)0 - - if (!pl) return 0; +int prop_write_values(void* obj, + const property_t* pl, + htsmsg_t* m, + int optmask, + htsmsg_t* updated) { + int save, save2 = 0; + htsmsg_field_t* f; + const property_t* p; + void* cur; + const void* snew; + void* dnew; + double dbl; + int i; + int64_t s64; + uint32_t u32, opts; + uint16_t u16; + time_t tm; +#define PROP_UPDATE(v, t) \ + snew = &v; \ + if (!p->set && (*((t*)cur) != *((t*)snew))) { \ + save = 1; \ + *((t*)cur) = *((t*)snew); \ + } \ + (void)0 + + if (!pl) + return 0; for (p = pl; p->id; p++) { - if (p->type == PT_NONE) continue; + if (p->type == PT_NONE) + continue; f = htsmsg_field_find(m, p->id); - if (!f) continue; + if (!f) + continue; /* Ignore */ opts = p->get_opts ? p->get_opts(obj, p->opts) : p->opts; - if(opts & optmask) continue; + if (opts & optmask) + continue; /* Sanity check */ assert(p->set || p->off); @@ -114,131 +116,131 @@ prop_write_values /* List */ if (p->islist) - snew = (f->hmf_type == HMF_MAP) ? - htsmsg_field_get_map(f) : - htsmsg_field_get_list(f); + snew = (f->hmf_type == HMF_MAP) ? htsmsg_field_get_map(f) : htsmsg_field_get_list(f); /* Singular */ else { switch (p->type) { - case PT_BOOL: { - if (htsmsg_field_get_bool(f, &i)) - continue; - PROP_UPDATE(i, int); - break; - } - case PT_INT: { - if (htsmsg_field_get_s64(f, &s64)) - continue; - i = s64; - PROP_UPDATE(i, int); - break; - } - case PT_U16: { - if (htsmsg_field_get_u32(f, &u32)) - continue; - u16 = (uint16_t)u32; - PROP_UPDATE(u16, uint16_t); - break; - } - case PT_U32: { - if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) { - char *s; - if (!(snew = htsmsg_field_get_str(f))) + case PT_BOOL: { + if (htsmsg_field_get_bool(f, &i)) continue; - u32 = atol(snew) * p->intextra; - if ((s = strchr(snew, '.')) != NULL) - u32 += (atol(s + 1) % p->intextra); - } else { - if (htsmsg_field_get_u32(f, &u32)) + PROP_UPDATE(i, int); + break; + } + case PT_INT: { + if (htsmsg_field_get_s64(f, &s64)) continue; + i = s64; + PROP_UPDATE(i, int); + break; } - PROP_UPDATE(u32, uint32_t); - break; - } - case PT_S64: { - if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) { - if (!(snew = htsmsg_field_get_str(f))) + case PT_U16: { + if (htsmsg_field_get_u32(f, &u32)) continue; - s64 = prop_intsplit_from_str(snew, p->intextra); - } else { - if (htsmsg_field_get_s64(f, &s64)) + u16 = (uint16_t)u32; + PROP_UPDATE(u16, uint16_t); + break; + } + case PT_U32: { + if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) { + char* s; + if (!(snew = htsmsg_field_get_str(f))) + continue; + u32 = atol(snew) * p->intextra; + if ((s = strchr(snew, '.')) != NULL) + u32 += (atol(s + 1) % p->intextra); + } else { + if (htsmsg_field_get_u32(f, &u32)) + continue; + } + PROP_UPDATE(u32, uint32_t); + break; + } + case PT_S64: { + if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) { + if (!(snew = htsmsg_field_get_str(f))) + continue; + s64 = prop_intsplit_from_str(snew, p->intextra); + } else { + if (htsmsg_field_get_s64(f, &s64)) + continue; + } + PROP_UPDATE(s64, int64_t); + break; + } + case PT_S64_ATOMIC: + break; + case PT_DBL: { + if (htsmsg_field_get_dbl(f, &dbl)) continue; + PROP_UPDATE(dbl, double); + break; } - PROP_UPDATE(s64, int64_t); - break; - } - case PT_S64_ATOMIC: - break; - case PT_DBL: { - if (htsmsg_field_get_dbl(f, &dbl)) - continue; - PROP_UPDATE(dbl, double); - break; - } - case PT_STR: { - char **str = cur; - if (!(snew = htsmsg_field_get_str(f))) - continue; - if (opts & PO_TRIM) { - if (*(char *)snew <= ' ' || ((char *)snew)[strlen(snew)-1] <= ' ') { - const char *x = snew; - char *y; - while (*x && *x <= ' ') x++; - snew = dnew = strdup(x); - if (*x) { - y = dnew + strlen(dnew); - while (y != x) { - y--; - if (*y <= ' ') break; + case PT_STR: { + char** str = cur; + if (!(snew = htsmsg_field_get_str(f))) + continue; + if (opts & PO_TRIM) { + if (*(char*)snew <= ' ' || ((char*)snew)[strlen(snew) - 1] <= ' ') { + const char* x = snew; + char* y; + while (*x && *x <= ' ') + x++; + snew = dnew = strdup(x); + if (*x) { + y = dnew + strlen(dnew); + while (y != x) { + y--; + if (*y <= ' ') + break; + } + *y = '\0'; } - *y = '\0'; } } + if (!p->set && strcmp((*str) ?: "", snew)) { + /* make sure that the string is valid all time */ + void* old = *str; + *str = strdup(snew); + free(old); + save = 1; + } + break; } - if (!p->set && strcmp((*str) ?: "", snew)) { - /* make sure that the string is valid all time */ - void *old = *str; - *str = strdup(snew); - free(old); - save = 1; + case PT_TIME: { + if (htsmsg_field_get_s64(f, &s64)) + continue; + tm = s64; + PROP_UPDATE(tm, time_t); + break; } - break; - } - case PT_TIME: { - if (htsmsg_field_get_s64(f, &s64)) - continue; - tm = s64; - PROP_UPDATE(tm, time_t); - break; - } - case PT_LANGSTR: { - lang_str_t **lstr1 = cur; - lang_str_t *lstr2; - snew = htsmsg_field_get_map(f); - if (!snew) - continue; - if (!p->set) { - lstr2 = lang_str_deserialize_map((htsmsg_t *)snew); - if (lang_str_compare(*lstr1, lstr2)) { - lang_str_destroy(*lstr1); - *lstr1 = lstr2; - save = 1; - } else { - lang_str_destroy(lstr2); + case PT_LANGSTR: { + lang_str_t** lstr1 = cur; + lang_str_t* lstr2; + snew = htsmsg_field_get_map(f); + if (!snew) + continue; + if (!p->set) { + lstr2 = lang_str_deserialize_map((htsmsg_t*)snew); + if (lang_str_compare(*lstr1, lstr2)) { + lang_str_destroy(*lstr1); + *lstr1 = lstr2; + save = 1; + } else { + lang_str_destroy(lstr2); + } } + break; } - break; - } - case PT_PERM: { - if (!(snew = htsmsg_field_get_str(f))) - continue; - u32 = (int)strtol(snew, NULL, 0); - PROP_UPDATE(u32, uint32_t); - break; - } - case PT_NONE: - break; + case PT_PERM: { + if (!(snew = htsmsg_field_get_str(f))) + continue; + u32 = (int)strtol(snew, NULL, 0); + PROP_UPDATE(u32, uint32_t); + break; + } + case PT_NONE: + break; } } @@ -270,20 +272,23 @@ prop_write_values /** * */ -static void -prop_read_value - (void *obj, const property_t *p, htsmsg_t *m, const char *name, - int optmask, const char *lang) -{ - const char *s; - const void *val = obj + p->off; - uint32_t u32; - char buf[24]; +static void prop_read_value(void* obj, + const property_t* p, + htsmsg_t* m, + const char* name, + int optmask, + const char* lang) { + const char* s; + const void* val = obj + p->off; + uint32_t u32; + char buf[24]; /* Ignore */ u32 = p->get_opts ? p->get_opts(obj, p->opts) : p->opts; - if (u32 & optmask) return; - if (p->type == PT_NONE) return; + if (u32 & optmask) + return; + if (p->type == PT_NONE) + return; /* Sanity check */ assert(p->get || p->off); @@ -299,65 +304,66 @@ prop_read_value if (val) htsmsg_add_msg(m, name, (htsmsg_t*)val); - /* Single */ + /* Single */ } else { - switch(p->type) { - case PT_BOOL: - htsmsg_add_bool(m, name, *(int *)val); - break; - case PT_INT: - htsmsg_add_s64(m, name, *(int *)val); - break; - case PT_U16: - htsmsg_add_u32(m, name, *(uint16_t *)val); - break; - case PT_U32: - if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) { - uint32_t maj = *(int64_t *)val / p->intextra; - uint32_t min = *(int64_t *)val % p->intextra; - if (min) { - snprintf(buf, sizeof(buf), "%u.%u", (unsigned int)maj, (unsigned int)min); - htsmsg_add_str(m, name, buf); + switch (p->type) { + case PT_BOOL: + htsmsg_add_bool(m, name, *(int*)val); + break; + case PT_INT: + htsmsg_add_s64(m, name, *(int*)val); + break; + case PT_U16: + htsmsg_add_u32(m, name, *(uint16_t*)val); + break; + case PT_U32: + if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) { + uint32_t maj = *(int64_t*)val / p->intextra; + uint32_t min = *(int64_t*)val % p->intextra; + if (min) { + snprintf(buf, sizeof(buf), "%u.%u", (unsigned int)maj, (unsigned int)min); + htsmsg_add_str(m, name, buf); + } else + htsmsg_add_s64(m, name, maj); } else - htsmsg_add_s64(m, name, maj); - } else - htsmsg_add_u32(m, name, *(uint32_t *)val); - break; - case PT_S64: - if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) { - int64_t maj = *(int64_t *)val / p->intextra; - int64_t min = *(int64_t *)val % p->intextra; - if (min) { - snprintf(buf, sizeof(buf), "%lu.%lu", (unsigned long)maj, (unsigned long)min); - htsmsg_add_str(m, name, buf); + htsmsg_add_u32(m, name, *(uint32_t*)val); + break; + case PT_S64: + if (p->intextra && INTEXTRA_IS_SPLIT(p->intextra)) { + int64_t maj = *(int64_t*)val / p->intextra; + int64_t min = *(int64_t*)val % p->intextra; + if (min) { + snprintf(buf, sizeof(buf), "%lu.%lu", (unsigned long)maj, (unsigned long)min); + htsmsg_add_str(m, name, buf); + } else + htsmsg_add_s64(m, name, maj); } else - htsmsg_add_s64(m, name, maj); - } else - htsmsg_add_s64(m, name, *(int64_t *)val); - break; - case PT_S64_ATOMIC: - htsmsg_add_s64(m, name, atomic_get_s64((int64_t *)val)); - break; - case PT_STR: - if ((s = *(const char **)val)) - htsmsg_add_str(m, name, (optmask & PO_LOCALE) != 0 && lang ? - tvh_gettext_lang(lang, s) : s); - break; - case PT_DBL: - htsmsg_add_dbl(m, name, *(double*)val); - break; - case PT_TIME: - htsmsg_add_s64(m, name, *(time_t *)val); - break; - case PT_LANGSTR: - lang_str_serialize(*(lang_str_t **)val, m, name); - break; - case PT_PERM: - snprintf(buf, sizeof(buf), "%04o", *(uint32_t *)val); - htsmsg_add_str(m, name, buf); - break; - case PT_NONE: - break; + htsmsg_add_s64(m, name, *(int64_t*)val); + break; + case PT_S64_ATOMIC: + htsmsg_add_s64(m, name, atomic_get_s64((int64_t*)val)); + break; + case PT_STR: + if ((s = *(const char**)val)) + htsmsg_add_str(m, + name, + (optmask & PO_LOCALE) != 0 && lang ? tvh_gettext_lang(lang, s) : s); + break; + case PT_DBL: + htsmsg_add_dbl(m, name, *(double*)val); + break; + case PT_TIME: + htsmsg_add_s64(m, name, *(time_t*)val); + break; + case PT_LANGSTR: + lang_str_serialize(*(lang_str_t**)val, m, name); + break; + case PT_PERM: + snprintf(buf, sizeof(buf), "%04o", *(uint32_t*)val); + htsmsg_add_str(m, name, buf); + break; + case PT_NONE: + break; } } } @@ -365,21 +371,22 @@ prop_read_value /** * */ -void -prop_read_values - (void *obj, const property_t *pl, htsmsg_t *m, htsmsg_t *list, - int optmask, const char *lang) -{ - if(pl == NULL) +void prop_read_values(void* obj, + const property_t* pl, + htsmsg_t* m, + htsmsg_t* list, + int optmask, + const char* lang) { + if (pl == NULL) return; - if(list == NULL) { + if (list == NULL) { for (; pl->id; pl++) prop_read_value(obj, pl, m, pl->id, optmask, lang); } else { - const property_t *p; - htsmsg_field_t *f; - int b, total = 0, count = 0; + const property_t* p; + htsmsg_field_t* f; + int b, total = 0, count = 0; HTSMSG_FOREACH(f, list) { total++; @@ -395,8 +402,8 @@ prop_read_values if (total && !count) { for (; pl->id; pl++) { HTSMSG_FOREACH(f, list) - if (!strcmp(pl->id, htsmsg_field_name(f))) - break; + if (!strcmp(pl->id, htsmsg_field_name(f))) + break; if (f == NULL) prop_read_value(obj, pl, m, pl->id, optmask, lang); } @@ -407,19 +414,20 @@ prop_read_values /** * */ -static void -prop_serialize_value - (void *obj, const property_t *pl, htsmsg_t *msg, int optmask, const char *lang) -{ - htsmsg_field_t *f; - char buf[16]; - uint32_t opts; +static void prop_serialize_value(void* obj, + const property_t* pl, + htsmsg_t* msg, + int optmask, + const char* lang) { + htsmsg_field_t* f; + char buf[16]; + uint32_t opts; /* Remove parent */ // TODO: this is really horrible and inefficient! HTSMSG_FOREACH(f, msg) { - htsmsg_t *t = htsmsg_field_get_map(f); - const char *str; + htsmsg_t* t = htsmsg_field_get_map(f); + const char* str; if (t && (str = htsmsg_get_str(t, "id"))) { if (!strcmp(str, pl->id)) { htsmsg_field_destroy(msg, f); @@ -432,16 +440,16 @@ prop_serialize_value if (pl->type == PT_NONE) return; - htsmsg_t *m = htsmsg_create_map(); + htsmsg_t* m = htsmsg_create_map(); /* ID / type */ - htsmsg_add_str(m, "id", pl->id); - htsmsg_add_str(m, "type", val2str(pl->type, typetab) ?: "none"); + htsmsg_add_str(m, "id", pl->id); + htsmsg_add_str(m, "type", val2str(pl->type, typetab) ?: "none"); /* Metadata */ - htsmsg_add_str(m, "caption", tvh_gettext_lang(lang, pl->name)); + htsmsg_add_str(m, "caption", tvh_gettext_lang(lang, pl->name)); if ((optmask & PO_DOC) && pl->doc) { - char *s = pl->doc(pl, lang); + char* s = pl->doc(pl, lang); if (s) { htsmsg_add_str(m, "doc", s); free(s); @@ -530,7 +538,7 @@ prop_serialize_value /* Enum list */ if (pl->list) { - htsmsg_t *list = pl->list(obj, lang); + htsmsg_t* list = pl->list(obj, lang); if (list) htsmsg_add_msg(m, "enum", list); } @@ -565,21 +573,22 @@ prop_serialize_value /** * */ -void -prop_serialize - (void *obj, const property_t *pl, htsmsg_t *msg, htsmsg_t *list, - int optmask, const char *lang) -{ - if(pl == NULL) +void prop_serialize(void* obj, + const property_t* pl, + htsmsg_t* msg, + htsmsg_t* list, + int optmask, + const char* lang) { + if (pl == NULL) return; - if(list == NULL) { + if (list == NULL) { for (; pl->id; pl++) prop_serialize_value(obj, pl, msg, optmask, lang); } else { - const property_t *p; - htsmsg_field_t *f; - int b, total = 0, count = 0; + const property_t* p; + htsmsg_field_t* f; + int b, total = 0, count = 0; HTSMSG_FOREACH(f, list) { total++; if (!htsmsg_field_get_bool(f, &b) && b > 0) { @@ -592,8 +601,8 @@ prop_serialize if (total && !count) { for (; pl->id; pl++) { HTSMSG_FOREACH(f, list) - if (!strcmp(pl->id, htsmsg_field_name(f))) - break; + if (!strcmp(pl->id, htsmsg_field_name(f))) + break; if (f == NULL) prop_serialize_value(obj, pl, msg, optmask, lang); } @@ -604,12 +613,10 @@ prop_serialize /** * */ -char * -prop_md_doc(const char **doc, const char *lang) -{ - const char *s; - char *r = NULL; - size_t l = 0; +char* prop_md_doc(const char** doc, const char* lang) { + const char* s; + char* r = NULL; + size_t l = 0; for (; *doc; doc++) { if ((*doc)[0] == '\xff') { @@ -632,7 +639,6 @@ prop_md_doc(const char **doc, const char *lang) return r; } - /****************************************************************************** * Editor Configuration * diff --git a/src/prop.h b/src/prop.h index 373942281..2b215bcb8 100644 --- a/src/prop.h +++ b/src/prop.h @@ -39,133 +39,136 @@ typedef enum { PT_DBL, PT_TIME, PT_LANGSTR, - PT_PERM, // like PT_U32 but with the special save + PT_PERM, // like PT_U32 but with the special save } prop_type_t; /* * Property options */ -#define PO_NONE (0<<0) -#define PO_RDONLY (1<<1) // Property is read-only -#define PO_NOSAVE (1<<2) // Property is transient (not saved) -#define PO_WRONCE (1<<3) // Property is write-once (i.e. on creation) -#define PO_ADVANCED (1<<4) // Property is advanced -#define PO_EXPERT (1<<5) // Property is for experts -#define PO_NOUI (1<<6) // Property should not be presented in the user interface -#define PO_HIDDEN (1<<7) // Property column is hidden (by default) -#define PO_PHIDDEN (1<<8) // Property is permanently hidden -#define PO_USERAW (1<<9) // Only save the RAW (off) value if it exists -#define PO_SORTKEY (1<<10) // Sort using key (not display value) -#define PO_PASSWORD (1<<11) // String is a password -#define PO_DURATION (1<<12) // For PT_TIME - differentiate between duration and datetime -#define PO_HEXA (1<<13) // Hexadecimal value -#define PO_DATE (1<<14) // Show date only -#define PO_LOCALE (1<<15) // Call tvh_locale_lang on string -#define PO_LORDER (1<<16) // Manage order in lists -#define PO_MULTILINE (1<<17) // Multiline string -#define PO_PERSIST (1<<18) // Persistent value (return back on save) -#define PO_DOC (1<<19) // Use doc callback instead description if exists -#define PO_DOC_NLIST (1<<20) // Do not show list in doc -#define PO_TRIM (1<<21) // Trim whitespaces (left & right) on load +#define PO_NONE (0 << 0) +#define PO_RDONLY (1 << 1) // Property is read-only +#define PO_NOSAVE (1 << 2) // Property is transient (not saved) +#define PO_WRONCE (1 << 3) // Property is write-once (i.e. on creation) +#define PO_ADVANCED (1 << 4) // Property is advanced +#define PO_EXPERT (1 << 5) // Property is for experts +#define PO_NOUI (1 << 6) // Property should not be presented in the user interface +#define PO_HIDDEN (1 << 7) // Property column is hidden (by default) +#define PO_PHIDDEN (1 << 8) // Property is permanently hidden +#define PO_USERAW (1 << 9) // Only save the RAW (off) value if it exists +#define PO_SORTKEY (1 << 10) // Sort using key (not display value) +#define PO_PASSWORD (1 << 11) // String is a password +#define PO_DURATION (1 << 12) // For PT_TIME - differentiate between duration and datetime +#define PO_HEXA (1 << 13) // Hexadecimal value +#define PO_DATE (1 << 14) // Show date only +#define PO_LOCALE (1 << 15) // Call tvh_locale_lang on string +#define PO_LORDER (1 << 16) // Manage order in lists +#define PO_MULTILINE (1 << 17) // Multiline string +#define PO_PERSIST (1 << 18) // Persistent value (return back on save) +#define PO_DOC (1 << 19) // Use doc callback instead description if exists +#define PO_DOC_NLIST (1 << 20) // Do not show list in doc +#define PO_TRIM (1 << 21) // Trim whitespaces (left & right) on load /* * min/max/step helpers */ #define INTEXTRA_RANGE(min, max, step) \ - ((1<<31U)|(((step)&0x7fU)<<24)|(((max)&0xfffU)<<12)|((min)&0xfffU)) + ((1 << 31U) | (((step) & 0x7fU) << 24) | (((max) & 0xfffU) << 12) | ((min) & 0xfffU)) -#define INTEXTRA_IS_RANGE(e) (((e) & (1<<31U)) != 0) +#define INTEXTRA_IS_RANGE(e) (((e) & (1 << 31U)) != 0) #define INTEXTRA_IS_SPLIT(e) !INTEXTRA_IS_RANGE(e) -#define INTEXTRA_GET_STEP(e) (((e)>>24)&0x7fU) -#define INTEXTRA_GET_MAX(e) ((e)&(1<<23)?-(0x800-(((e)>>12)&0x7ff)):(((e)>>12)&0x7ff)) -#define INTEXTRA_GET_MIN(e) ((e)&(1<<11)?-(0x800-((e)&0x7ff)):((e)&0x7ff)) -#define INTEXTRA_GET_UMAX(e) (((e)>>12)&0xfff) -#define INTEXTRA_GET_UMIN(e) ((e)&0xfff) +#define INTEXTRA_GET_STEP(e) (((e) >> 24) & 0x7fU) +#define INTEXTRA_GET_MAX(e) \ + ((e) & (1 << 23) ? -(0x800 - (((e) >> 12) & 0x7ff)) : (((e) >> 12) & 0x7ff)) +#define INTEXTRA_GET_MIN(e) ((e) & (1 << 11) ? -(0x800 - ((e) & 0x7ff)) : ((e) & 0x7ff)) +#define INTEXTRA_GET_UMAX(e) (((e) >> 12) & 0xfff) +#define INTEXTRA_GET_UMIN(e) ((e) & 0xfff) /* * Property definition */ typedef struct property { - const char *id; ///< Property Key - const char *name; ///< Textual description - const char *desc; ///< Verbose description (tooltip) - prop_type_t type; ///< Type - uint8_t islist; ///< Is a list - uint8_t group; ///< Visual group ID (like ExtJS FieldSet) - size_t off; ///< Offset into object - uint32_t opts; ///< Options - uint32_t intextra; ///< intsplit: integer/remainder boundary or range: min/max/step + const char* id; ///< Property Key + const char* name; ///< Textual description + const char* desc; ///< Verbose description (tooltip) + prop_type_t type; ///< Type + uint8_t islist; ///< Is a list + uint8_t group; ///< Visual group ID (like ExtJS FieldSet) + size_t off; ///< Offset into object + uint32_t opts; ///< Options + uint32_t intextra; ///< intsplit: integer/remainder boundary or range: min/max/step /* String based processing */ - const void *(*get) (void *ptr); - int (*set) (void *ptr, const void *v); - htsmsg_t *(*list) (void *ptr, const char *lang); - char *(*rend) (void *ptr, const char *lang); - ///< Provide the rendered value for enum/list - ///< Lists should be CSV. This is used for - ///< sorting and searching in UI API + const void* (*get)(void* ptr); + int (*set)(void* ptr, const void* v); + htsmsg_t* (*list)(void* ptr, const char* lang); + char* (*rend)(void* ptr, const char* lang); + ///< Provide the rendered value for enum/list + ///< Lists should be CSV. This is used for + ///< sorting and searching in UI API /* Default (for UI) */ union { - int i; // PT_BOOL/PT_INT - const char *s; // PT_STR - uint16_t u16; // PT_U16 - uint32_t u32; // PT_U32 - int64_t s64; // PT_S64 - double d; // PT_DBL - time_t tm; // PT_TIME - htsmsg_t *(*list)(void); // islist != 0 + int i; // PT_BOOL/PT_INT + const char* s; // PT_STR + uint16_t u16; // PT_U16 + uint32_t u32; // PT_U32 + int64_t s64; // PT_S64 + double d; // PT_DBL + time_t tm; // PT_TIME + htsmsg_t* (*list)(void); // islist != 0 } def; /* Extended options */ - uint32_t (*get_opts) (void *ptr, uint32_t opts); + uint32_t (*get_opts)(void* ptr, uint32_t opts); /* Documentation callback */ - char *(*doc) ( const struct property *prop, const char *lang ); + char* (*doc)(const struct property* prop, const char* lang); /* Notification callback */ - void (*notify) (void *ptr, const char *lang); + void (*notify)(void* ptr, const char* lang); } property_t; #define PROP_SBUF_LEN 4096 -extern char prop_sbuf[PROP_SBUF_LEN]; -extern const char *prop_sbuf_ptr; -extern const char *prop_ptr; +extern char prop_sbuf[PROP_SBUF_LEN]; +extern const char* prop_sbuf_ptr; +extern const char* prop_ptr; -const property_t *prop_find(const property_t *p, const char *name); +const property_t* prop_find(const property_t* p, const char* name); -int prop_write_values - (void *obj, const property_t *pl, htsmsg_t *m, int optmask, htsmsg_t *updated); +int prop_write_values(void* obj, const property_t* pl, htsmsg_t* m, int optmask, htsmsg_t* updated); -void prop_read_values - (void *obj, const property_t *pl, htsmsg_t *m, htsmsg_t *list, - int optmask, const char *lang); +void prop_read_values(void* obj, + const property_t* pl, + htsmsg_t* m, + htsmsg_t* list, + int optmask, + const char* lang); -void prop_serialize - (void *obj, const property_t *pl, htsmsg_t *m, htsmsg_t *list, - int optmask, const char *lang); +void prop_serialize(void* obj, + const property_t* pl, + htsmsg_t* m, + htsmsg_t* list, + int optmask, + const char* lang); -static inline int64_t prop_intsplit_from_str(const char *s, int64_t intsplit) -{ +static inline int64_t prop_intsplit_from_str(const char* s, int64_t intsplit) { int64_t s64 = (int64_t)atol(s) * intsplit; if ((s = strchr(s, '.')) != NULL) s64 += (atol(s + 1) % intsplit); return s64; } -char * -prop_md_doc(const char **md, const char *lang); - -#define PROP_DOC(name) \ -extern const char *tvh_doc_##name##_property[]; \ -static char * \ -prop_doc_##name(const struct property *p, const char *lang) \ -{ return prop_md_doc(tvh_doc_##name##_property, lang); } +char* prop_md_doc(const char** md, const char* lang); +#define PROP_DOC(name) \ + extern const char* tvh_doc_##name##_property[]; \ + static char* prop_doc_##name(const struct property* p, const char* lang) { \ + return prop_md_doc(tvh_doc_##name##_property, lang); \ + } /* helpers */ -htsmsg_t *proplib_kill_list ( void *o, const char *lang ); +htsmsg_t* proplib_kill_list(void* o, const char* lang); #endif /* __TVH_PROP_H__ */ diff --git a/src/proplib.c b/src/proplib.c index 057b46181..f6a7f952b 100644 --- a/src/proplib.c +++ b/src/proplib.c @@ -25,16 +25,17 @@ #include "tvh_locale.h" #include "lang_str.h" -htsmsg_t * -proplib_kill_list ( void *o, const char *lang ) -{ +htsmsg_t* proplib_kill_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("SIGKILL"), TVH_KILL_KILL }, - { N_("SIGTERM"), TVH_KILL_TERM }, - { N_("SIGINT"), TVH_KILL_INT, }, - { N_("SIGHUP"), TVH_KILL_HUP }, - { N_("SIGUSR1"), TVH_KILL_USR1 }, - { N_("SIGUSR2"), TVH_KILL_USR2 }, + {N_("SIGKILL"), TVH_KILL_KILL}, + {N_("SIGTERM"), TVH_KILL_TERM}, + { + N_("SIGINT"), + TVH_KILL_INT, + }, + {N_("SIGHUP"), TVH_KILL_HUP}, + {N_("SIGUSR1"), TVH_KILL_USR1}, + {N_("SIGUSR2"), TVH_KILL_USR2}, }; return strtab2htsmsg(tab, 1, lang); } diff --git a/src/queue.h b/src/queue.h index 70453a515..2db7077a1 100644 --- a/src/queue.h +++ b/src/queue.h @@ -11,118 +11,121 @@ * Extra LIST-ops */ -#define LIST_LAST(headname, head, field) ({ \ - headname *r; \ - for (r = LIST_FIRST(head); \ - LIST_NEXT(r, field); \ - r = LIST_NEXT(r, field)); \ - r; \ -}) - -#define LIST_PREV(elm, headname, head, field) ({ \ - headname *r; \ - for (r = LIST_FIRST(head); \ - r && LIST_NEXT(r, field) != (elm); \ - r = LIST_NEXT(r, field)); \ - r; \ -}) - -#define LIST_ENTRY_INIT(elm, field) \ - (elm)->field.le_next = NULL, (elm)->field.le_prev = NULL - -#define LIST_SAFE_REMOVE(elm, field) \ - if ((elm)->field.le_next != NULL || (elm)->field.le_prev != NULL) { \ - LIST_REMOVE(elm, field); \ - LIST_ENTRY_INIT(elm, field); \ - } - -#define LIST_SAFE_ENTRY(elm, field) \ - ((elm)->field.le_next == NULL && (elm)->field.le_prev == NULL) - -#define LIST_MOVE(newhead, oldhead, field) do { \ - if((oldhead)->lh_first) { \ - (oldhead)->lh_first->field.le_prev = &(newhead)->lh_first; \ - } \ - (newhead)->lh_first = (oldhead)->lh_first; \ -} while (0) - -#define LIST_INSERT_SORTED(head, elm, field, cmpfunc) do { \ - if(LIST_EMPTY(head)) { \ - LIST_INSERT_HEAD(head, elm, field); \ - } else { \ - typeof(elm) _tmp; \ - LIST_FOREACH(_tmp,head,field) { \ - if(cmpfunc(elm,_tmp) <= 0) { \ - LIST_INSERT_BEFORE(_tmp,elm,field); \ - break; \ - } \ - if(!LIST_NEXT(_tmp,field)) { \ - LIST_INSERT_AFTER(_tmp,elm,field); \ - break; \ - } \ - } \ - } \ -} while(0) +#define LIST_LAST(headname, head, field) \ + ({ \ + headname* r; \ + for (r = LIST_FIRST(head); LIST_NEXT(r, field); r = LIST_NEXT(r, field)) \ + ; \ + r; \ + }) + +#define LIST_PREV(elm, headname, head, field) \ + ({ \ + headname* r; \ + for (r = LIST_FIRST(head); r && LIST_NEXT(r, field) != (elm); r = LIST_NEXT(r, field)) \ + ; \ + r; \ + }) + +#define LIST_ENTRY_INIT(elm, field) (elm)->field.le_next = NULL, (elm)->field.le_prev = NULL + +#define LIST_SAFE_REMOVE(elm, field) \ + if ((elm)->field.le_next != NULL || (elm)->field.le_prev != NULL) { \ + LIST_REMOVE(elm, field); \ + LIST_ENTRY_INIT(elm, field); \ + } + +#define LIST_SAFE_ENTRY(elm, field) ((elm)->field.le_next == NULL && (elm)->field.le_prev == NULL) + +#define LIST_MOVE(newhead, oldhead, field) \ + do { \ + if ((oldhead)->lh_first) { \ + (oldhead)->lh_first->field.le_prev = &(newhead)->lh_first; \ + } \ + (newhead)->lh_first = (oldhead)->lh_first; \ + } while (0) + +#define LIST_INSERT_SORTED(head, elm, field, cmpfunc) \ + do { \ + if (LIST_EMPTY(head)) { \ + LIST_INSERT_HEAD(head, elm, field); \ + } else { \ + typeof(elm) _tmp; \ + LIST_FOREACH (_tmp, head, field) { \ + if (cmpfunc(elm, _tmp) <= 0) { \ + LIST_INSERT_BEFORE(_tmp, elm, field); \ + break; \ + } \ + if (!LIST_NEXT(_tmp, field)) { \ + LIST_INSERT_AFTER(_tmp, elm, field); \ + break; \ + } \ + } \ + } \ + } while (0) /* * Extra TAILQ-ops */ #define TAILQ_SAFE_ENTRY(elm, field) \ - ((elm)->field.tqe_next == NULL && (elm)->field.tqe_prev == NULL) - -#define TAILQ_SAFE_REMOVE(head, elm, field) \ - if ((elm)->field.tqe_next != NULL || (elm)->field.tqe_prev != NULL) { \ - TAILQ_REMOVE(head, elm, field); \ - (elm)->field.tqe_next = NULL; \ - (elm)->field.tqe_prev = NULL; \ - } - -#define TAILQ_INSERT_SORTED(head, elm, field, cmpfunc) do { \ - if(TAILQ_FIRST(head) == NULL) { \ - TAILQ_INSERT_HEAD(head, elm, field); \ - } else { \ - typeof(elm) _tmp; \ - TAILQ_FOREACH(_tmp,head,field) { \ - if(cmpfunc(elm,_tmp) <= 0) { \ - TAILQ_INSERT_BEFORE(_tmp,elm,field); \ - break; \ - } \ - if(!TAILQ_NEXT(_tmp,field)) { \ - TAILQ_INSERT_AFTER(head,_tmp,elm,field); \ - break; \ - } \ - } \ - } \ -} while(0) - -#define TAILQ_INSERT_SORTED_R(head, headname, elm, field, cmpfunc) do { \ - if(TAILQ_FIRST(head) == NULL) { \ - TAILQ_INSERT_HEAD(head, elm, field); \ - } else { \ - typeof(elm) _tmp; \ - TAILQ_FOREACH_REVERSE(_tmp,head,headname,field) { \ - if(cmpfunc(elm,_tmp) >= 0) { \ - TAILQ_INSERT_AFTER(head,_tmp,elm,field); \ - break; \ - } \ - if(!TAILQ_PREV(_tmp,headname,field)) { \ - TAILQ_INSERT_BEFORE(_tmp,elm,field); \ - break; \ - } \ - } \ - } \ -} while(0) - -#define TAILQ_MOVE(newhead, oldhead, field) do { \ - if(TAILQ_FIRST(oldhead)) { \ - TAILQ_FIRST(oldhead)->field.tqe_prev = &(newhead)->tqh_first; \ - (newhead)->tqh_first = (oldhead)->tqh_first; \ - (newhead)->tqh_last = (oldhead)->tqh_last; \ - TAILQ_INIT(oldhead);\ - } else { \ - TAILQ_INIT(newhead);\ - }\ -} while (/*CONSTCOND*/0) - + ((elm)->field.tqe_next == NULL && (elm)->field.tqe_prev == NULL) + +#define TAILQ_SAFE_REMOVE(head, elm, field) \ + if ((elm)->field.tqe_next != NULL || (elm)->field.tqe_prev != NULL) { \ + TAILQ_REMOVE(head, elm, field); \ + (elm)->field.tqe_next = NULL; \ + (elm)->field.tqe_prev = NULL; \ + } + +#define TAILQ_INSERT_SORTED(head, elm, field, cmpfunc) \ + do { \ + if (TAILQ_FIRST(head) == NULL) { \ + TAILQ_INSERT_HEAD(head, elm, field); \ + } else { \ + typeof(elm) _tmp; \ + TAILQ_FOREACH (_tmp, head, field) { \ + if (cmpfunc(elm, _tmp) <= 0) { \ + TAILQ_INSERT_BEFORE(_tmp, elm, field); \ + break; \ + } \ + if (!TAILQ_NEXT(_tmp, field)) { \ + TAILQ_INSERT_AFTER(head, _tmp, elm, field); \ + break; \ + } \ + } \ + } \ + } while (0) + +#define TAILQ_INSERT_SORTED_R(head, headname, elm, field, cmpfunc) \ + do { \ + if (TAILQ_FIRST(head) == NULL) { \ + TAILQ_INSERT_HEAD(head, elm, field); \ + } else { \ + typeof(elm) _tmp; \ + TAILQ_FOREACH_REVERSE (_tmp, head, headname, field) { \ + if (cmpfunc(elm, _tmp) >= 0) { \ + TAILQ_INSERT_AFTER(head, _tmp, elm, field); \ + break; \ + } \ + if (!TAILQ_PREV(_tmp, headname, field)) { \ + TAILQ_INSERT_BEFORE(_tmp, elm, field); \ + break; \ + } \ + } \ + } \ + } while (0) + +#define TAILQ_MOVE(newhead, oldhead, field) \ + do { \ + if (TAILQ_FIRST(oldhead)) { \ + TAILQ_FIRST(oldhead)->field.tqe_prev = &(newhead)->tqh_first; \ + (newhead)->tqh_first = (oldhead)->tqh_first; \ + (newhead)->tqh_last = (oldhead)->tqh_last; \ + TAILQ_INIT(oldhead); \ + } else { \ + TAILQ_INIT(newhead); \ + } \ + } while (/*CONSTCOND*/ 0) + #endif /* HTSQ_H */ diff --git a/src/ratinglabels.c b/src/ratinglabels.c index 52ea4f1fa..c2c2f229e 100644 --- a/src/ratinglabels.c +++ b/src/ratinglabels.c @@ -29,30 +29,32 @@ #include "ratinglabels.h" #include "input.h" -#include "channels.h" //Needed to loop through channels when deleting RL pointers from EPG -#include "dvr/dvr.h" //Needed to check recordings for RL pointers. +#include "channels.h" //Needed to loop through channels when deleting RL pointers from EPG +#include "dvr/dvr.h" //Needed to check recordings for RL pointers. ratinglabel_tree_t ratinglabels; -void ratinglabel_init(void); -void ratinglabel_done(void); -ratinglabel_t *ratinglabel_find_from_eit(char *country, int age); -ratinglabel_t *ratinglabel_find_from_xmltv(const char *authority, const char *label); -ratinglabel_t *ratinglabel_find_from_uuid(const char *string_uuid); -const char *ratinglabel_get_icon(ratinglabel_t *rl); - -static htsmsg_t *ratinglabel_class_save(idnode_t *self, char *filename, size_t fsize); -const void *ratinglabel_class_get_icon (void *obj); -ratinglabel_t *ratinglabel_create_placeholder(int enabled, const char *country, int age, - int display_age, const char *display_label, - const char *label, const char *authority); +void ratinglabel_init(void); +void ratinglabel_done(void); +ratinglabel_t* ratinglabel_find_from_eit(char* country, int age); +ratinglabel_t* ratinglabel_find_from_xmltv(const char* authority, const char* label); +ratinglabel_t* ratinglabel_find_from_uuid(const char* string_uuid); +const char* ratinglabel_get_icon(ratinglabel_t* rl); + +static htsmsg_t* ratinglabel_class_save(idnode_t* self, char* filename, size_t fsize); +const void* ratinglabel_class_get_icon(void* obj); +ratinglabel_t* ratinglabel_create_placeholder(int enabled, + const char* country, + int age, + int display_age, + const char* display_label, + const char* label, + const char* authority); /** * */ -static int -_rl_cmp(const void *a, const void *b) -{ +static int _rl_cmp(const void* a, const void* b) { return 1; } @@ -60,36 +62,38 @@ _rl_cmp(const void *a, const void *b) Used at EPG load time to get the parentalrating object from the UUID string that is stored in the EPG database. */ -ratinglabel_t * -ratinglabel_find_from_uuid(const char *string_uuid) -{ +ratinglabel_t* ratinglabel_find_from_uuid(const char* string_uuid) { - if(string_uuid[0] == 0){ + if (string_uuid[0] == 0) { tvhtrace(LS_RATINGLABELS, "Empty UUID when matching rating label, exiting."); return NULL; } - tvh_uuid_t binary_uuid; - ratinglabel_t *rl = NULL; - ratinglabel_t *temp_rl = NULL; + tvh_uuid_t binary_uuid; + ratinglabel_t* rl = NULL; + ratinglabel_t* temp_rl = NULL; if (!uuid_set(&binary_uuid, string_uuid)) { - RB_FOREACH(temp_rl, &ratinglabels, rl_link) - { - if(!memcmp((const void *)&binary_uuid, (const void *)(temp_rl->rl_id).in_uuid.bin, UUID_BIN_SIZE)){ + RB_FOREACH (temp_rl, &ratinglabels, rl_link) { + if (!memcmp((const void*)&binary_uuid, + (const void*)(temp_rl->rl_id).in_uuid.bin, + UUID_BIN_SIZE)) { rl = temp_rl; - if(rl->rl_enabled){ - tvhdebug(LS_RATINGLABELS, "Matched UUID '%s' with rating label '%s' / '%d'.", string_uuid, rl->rl_display_label, rl->rl_display_age); + if (rl->rl_enabled) { + tvhdebug(LS_RATINGLABELS, + "Matched UUID '%s' with rating label '%s' / '%d'.", + string_uuid, + rl->rl_display_label, + rl->rl_display_age); return rl; } } - }//END FOR loop - }//END the binary conversion worked + } // END FOR loop + } // END the binary conversion worked - //To get here, either the UUID was invalid or there was no matching ENABLED ratinglabel. + // To get here, either the UUID was invalid or there was no matching ENABLED ratinglabel. return NULL; - } /* @@ -97,63 +101,53 @@ ratinglabel_find_from_uuid(const char *string_uuid) is encountered. Match the Authority+Label to a rating label and return a pointer to that object if the label in enabled, null if not. */ -ratinglabel_t * -ratinglabel_find_from_xmltv(const char *authority, const char *label){ +ratinglabel_t* ratinglabel_find_from_xmltv(const char* authority, const char* label) { - ratinglabel_t *rl = NULL; - ratinglabel_t *temp_rl = NULL; + ratinglabel_t* rl = NULL; + ratinglabel_t* temp_rl = NULL; - RB_FOREACH(temp_rl, &ratinglabels, rl_link) - { - //If both authorities are null OR both authorities match - if((!authority && !temp_rl->rl_authority) || !strcasecmp(temp_rl->rl_authority, authority)){ + RB_FOREACH (temp_rl, &ratinglabels, rl_link) { + // If both authorities are null OR both authorities match + if ((!authority && !temp_rl->rl_authority) || !strcasecmp(temp_rl->rl_authority, authority)) { - //Match 2 null labels - if(!temp_rl->rl_label && !label){ - tvherror(LS_RATINGLABELS, " matched 2 nulls."); + // Match 2 null labels + if (!temp_rl->rl_label && !label) { + tvherror(LS_RATINGLABELS, " matched 2 nulls."); + rl = temp_rl; + break; + } + + // if only 1 of the labels is null, then no match. + // This test protects strcasecmp from a null pointer + if (!temp_rl->rl_label || !label) { + // No match found + } else { + if (!strcasecmp(temp_rl->rl_label, label)) { rl = temp_rl; break; } - - //if only 1 of the labels is null, then no match. - //This test protects strcasecmp from a null pointer - if(!temp_rl->rl_label || !label){ - //No match found - } - else - { - if(!strcasecmp(temp_rl->rl_label, label)){ - rl = temp_rl; - break; - } - } } + } } - //Did we get a match? - if(rl) - { - if(!rl->rl_enabled) - { + // Did we get a match? + if (rl) { + if (!rl->rl_enabled) { tvhtrace(LS_RATINGLABELS, "Not enabled, returning NULL."); return NULL; } - } - else - { - char tmpLabel[129]; //Authority+label + } else { + char tmpLabel[129]; // Authority+label snprintf(tmpLabel, 128, "XMLTV:%s:%s", authority, label); - //The XMLTV module is holding a lock. Unlock and then relock. + // The XMLTV module is holding a lock. Unlock and then relock. tvh_mutex_unlock(&global_lock); rl = ratinglabel_create_placeholder(1, "???", 0, 0, tmpLabel, label, authority); tvh_mutex_lock(&global_lock); - } return rl; - } /* @@ -161,71 +155,74 @@ ratinglabel_find_from_xmltv(const char *authority, const char *label){ is encountered. Match the Country+Age to a rating label and return a pointer to that object if the label in enabled, null if not. */ -ratinglabel_t * -ratinglabel_find_from_eit(char *country, int age) -{ - tvhdebug(LS_RATINGLABELS, "Looking for '%s', '%d'. Count: '%d'.", country, age, ratinglabels.entries); - - ratinglabel_t *rl = NULL; - ratinglabel_t *temp_rl = NULL; - int tmpAge = 0; - - //RB_FIND was tried but it gave some false negatives - //so I decided to do things the hard way. - RB_FOREACH(temp_rl, &ratinglabels, rl_link) - { - if(temp_rl->rl_age == age){ - if(!strcasecmp(temp_rl->rl_country, country)){ - rl = temp_rl; - break; - } - } - } - - //Did we get a match? - if(rl) - { - if(!rl->rl_enabled) - { - tvhtrace(LS_RATINGLABELS, "Not enabled, returning NULL."); - return NULL; +ratinglabel_t* ratinglabel_find_from_eit(char* country, int age) { + tvhdebug(LS_RATINGLABELS, + "Looking for '%s', '%d'. Count: '%d'.", + country, + age, + ratinglabels.entries); + + ratinglabel_t* rl = NULL; + ratinglabel_t* temp_rl = NULL; + int tmpAge = 0; + + // RB_FIND was tried but it gave some false negatives + // so I decided to do things the hard way. + RB_FOREACH (temp_rl, &ratinglabels, rl_link) { + if (temp_rl->rl_age == age) { + if (!strcasecmp(temp_rl->rl_country, country)) { + rl = temp_rl; + break; } } - else - { - tvhtrace(LS_RATINGLABELS, "Not found, creating placeholder '%s' / '%d'. Count: '%d' ", country, age, ratinglabels.entries); - - char tmpLabel[17]; //DBV+Country+Age+null - - snprintf(tmpLabel, 16, "DVB:%s:%d", country, age); - - //Do the DVB age adjustment - //0x00 undefined - //0x01 to 0x0F minimum age = rating + 3 years - //0x10 to 0xFF defined by the broadcaster - tmpAge = age; - if((age < 0x10) && (age != 0x00)){ - tmpAge = age + 3; - } - - rl = ratinglabel_create_placeholder(1, country, age, tmpAge, tmpLabel, tmpLabel, "NONE"); + } + // Did we get a match? + if (rl) { + if (!rl->rl_enabled) { + tvhtrace(LS_RATINGLABELS, "Not enabled, returning NULL."); + return NULL; } + } else { + tvhtrace(LS_RATINGLABELS, + "Not found, creating placeholder '%s' / '%d'. Count: '%d' ", + country, + age, + ratinglabels.entries); + + char tmpLabel[17]; // DBV+Country+Age+null + + snprintf(tmpLabel, 16, "DVB:%s:%d", country, age); + + // Do the DVB age adjustment + // 0x00 undefined + // 0x01 to 0x0F minimum age = rating + 3 years + // 0x10 to 0xFF defined by the broadcaster + tmpAge = age; + if ((age < 0x10) && (age != 0x00)) { + tmpAge = age + 3; + } + + rl = ratinglabel_create_placeholder(1, country, age, tmpAge, tmpLabel, tmpLabel, "NONE"); + } - return rl; + return rl; } /* Create a placeholder label for newly encountered ratings. The user needs to manually provide the appropriate fields. */ -ratinglabel_t * -ratinglabel_create_placeholder(int enabled, const char *country, int age, - int display_age, const char *display_label, - const char *label, const char *authority){ +ratinglabel_t* ratinglabel_create_placeholder(int enabled, + const char* country, + int age, + int display_age, + const char* display_label, + const char* label, + const char* authority) { - ratinglabel_t *rl_new = NULL; - htsmsg_t *msg_new = htsmsg_create_map(); + ratinglabel_t* rl_new = NULL; + htsmsg_t* msg_new = htsmsg_create_map(); htsmsg_add_bool(msg_new, "enabled", enabled); htsmsg_add_s64(msg_new, "age", age); @@ -237,25 +234,26 @@ ratinglabel_create_placeholder(int enabled, const char *country, int age, tvh_mutex_lock(&global_lock); rl_new = ratinglabel_create(NULL, msg_new, NULL, NULL); - if (rl_new) - { - tvhtrace(LS_RATINGLABELS, "Success: Created placeholder '%s' / '%d' : '%s / '%s'. Count: '%d'", country, age, label, authority, ratinglabels.entries); - idnode_changed((idnode_t *)rl_new); + if (rl_new) { + tvhtrace(LS_RATINGLABELS, + "Success: Created placeholder '%s' / '%d' : '%s / '%s'. Count: '%d'", + country, + age, + label, + authority, + ratinglabels.entries); + idnode_changed((idnode_t*)rl_new); } tvh_mutex_unlock(&global_lock); return rl_new; - } - /** * Free up the memory and safely dispose of the ratinglabel object */ -static void -ratinglabel_free(ratinglabel_t *rl) -{ +static void ratinglabel_free(ratinglabel_t* rl) { idnode_save_check(&rl->rl_id, 1); idnode_unlink(&rl->rl_id); @@ -270,18 +268,16 @@ ratinglabel_free(ratinglabel_t *rl) /** * Create a reating label object */ -ratinglabel_t * -ratinglabel_create(const char *uuid, htsmsg_t *conf, - const char *name, const char *src) -{ - //Minimum fields: (country+age) or (authority+label) - //If the XMLTV has no 'system' then that function needs - //send something like 'xmltvraw' as the authority. +ratinglabel_t* +ratinglabel_create(const char* uuid, htsmsg_t* conf, const char* name, const char* src) { + // Minimum fields: (country+age) or (authority+label) + // If the XMLTV has no 'system' then that function needs + // send something like 'xmltvraw' as the authority. //'remapping' could see multiple country+age+label conbinations tvhtrace(LS_RATINGLABELS, "Creating rating label '%s'.", uuid); ratinglabel_t *rl, *rl2 = NULL; - int i; + int i; lock_assert(&global_lock); @@ -308,9 +304,9 @@ ratinglabel_create(const char *uuid, htsmsg_t *conf, return NULL; } - //Load the rating icon into the image cache if it is not already there. - if(rl){ - if(rl->rl_icon){ + // Load the rating icon into the image cache if it is not already there. + if (rl) { + if (rl->rl_icon) { (void)imagecache_get_id(rl->rl_icon); } } @@ -323,11 +319,9 @@ ratinglabel_create(const char *uuid, htsmsg_t *conf, /** * This deletes an individual ratinglabel object */ -static void -ratinglabel_destroy(ratinglabel_t *rl) -{ +static void ratinglabel_destroy(ratinglabel_t* rl) { - if (!rl){ + if (!rl) { return; } @@ -340,14 +334,12 @@ ratinglabel_destroy(ratinglabel_t *rl) /* * */ -void -ratinglabel_completed(ratinglabel_t *rl, uint32_t seen) -{ - idnode_set_t *remove; - //size_t z; +void ratinglabel_completed(ratinglabel_t* rl, uint32_t seen) { + idnode_set_t* remove; + // size_t z; - //z=0; //DUMMY - //z++; //DUMMY + // z=0; //DUMMY + // z++; //DUMMY if (!rl) return; @@ -369,70 +361,76 @@ save: * Delete a rating label object from memory and disk. * Cleanup EPG entries that use that RL object. */ -void -ratinglabel_delete(ratinglabel_t *rl) -{ +void ratinglabel_delete(ratinglabel_t* rl) { char ubuf[UUID_HEX_SIZE]; - if (rl == NULL) return; + if (rl == NULL) + return; rl->rl_enabled = 0; - channel_t *ch; - epg_broadcast_t *ebc; - dvr_entry_t *de; - int foundCount = 0; - epg_changes_t *changes = NULL; - int retVal = 0; + channel_t* ch; + epg_broadcast_t* ebc; + dvr_entry_t* de; + int foundCount = 0; + epg_changes_t* changes = NULL; + int retVal = 0; if (!rl->rl_shield) { - hts_settings_remove("epggrab/ratinglabel/%s", idnode_uuid_as_str(&rl->rl_id, ubuf)); - - tvhtrace(LS_RATINGLABELS, "Deleting rating label '%s' / '%d'.", rl->rl_display_label, rl->rl_display_age); - - //Read through all of the EPG entries and set the rating label pointer to NULL for matching labels. - //If this is not done, if an EPG entry is called that has the deleted RL, then the pointer - //will point to rubbish and TVH will most likely crash. - //Note: In order to delete the RL object, the mutex is already locked. - - CHANNEL_FOREACH(ch) { - if (ch->ch_epg_parent) continue; - RB_FOREACH(ebc, &ch->ch_epg_schedule, sched_link) { - if(ebc->rating_label == rl) - { - //Cause the entry to be flagged as changed - ebc->rating_label = NULL; //Clear the pointer to the RL object - retVal = epg_broadcast_set_age_rating(ebc, 99, changes); - retVal = epg_broadcast_set_age_rating(ebc, 0, changes); - ebc->age_rating = 0; //Clear the age rating field. - foundCount++; - }//END matching RL - }//END loop through EPG entries - }//END loop through channels - - retVal = 0; - - if (foundCount != 0 && (retVal == 0)){ - epg_updated(); - } + hts_settings_remove("epggrab/ratinglabel/%s", idnode_uuid_as_str(&rl->rl_id, ubuf)); + + tvhtrace(LS_RATINGLABELS, + "Deleting rating label '%s' / '%d'.", + rl->rl_display_label, + rl->rl_display_age); + + // Read through all of the EPG entries and set the rating label pointer to NULL for matching + // labels. If this is not done, if an EPG entry is called that has the deleted RL, then the + // pointer will point to rubbish and TVH will most likely crash. Note: In order to delete the RL + // object, the mutex is already locked. + + CHANNEL_FOREACH(ch) { + if (ch->ch_epg_parent) + continue; + RB_FOREACH (ebc, &ch->ch_epg_schedule, sched_link) { + if (ebc->rating_label == rl) { + // Cause the entry to be flagged as changed + ebc->rating_label = NULL; // Clear the pointer to the RL object + retVal = epg_broadcast_set_age_rating(ebc, 99, changes); + retVal = epg_broadcast_set_age_rating(ebc, 0, changes); + ebc->age_rating = 0; // Clear the age rating field. + foundCount++; + } // END matching RL + } // END loop through EPG entries + } // END loop through channels + + retVal = 0; + + if (foundCount != 0 && (retVal == 0)) { + epg_updated(); + } - tvhtrace(LS_RATINGLABELS, "Found '%d' EPG entries when deleting rating label.", foundCount); + tvhtrace(LS_RATINGLABELS, "Found '%d' EPG entries when deleting rating label.", foundCount); - //Now check for any upcomming recordings that use this RL and remove their RL UUID. - foundCount = 0; + // Now check for any upcomming recordings that use this RL and remove their RL UUID. + foundCount = 0; - LIST_FOREACH(de, &dvrentries, de_global_link){ - if (dvr_entry_is_upcoming(de)){ - if(de->de_rating_label == rl){ - tvhtrace(LS_RATINGLABELS, "Removing rating label for scheduled recording '%s'.", de->de_title->first->str); - de->de_rating_label = NULL; //Set the rating label UUID for this recording to null - dvr_entry_changed(de); //Save this recording. - foundCount++; - } - } + LIST_FOREACH (de, &dvrentries, de_global_link) { + if (dvr_entry_is_upcoming(de)) { + if (de->de_rating_label == rl) { + tvhtrace(LS_RATINGLABELS, + "Removing rating label for scheduled recording '%s'.", + de->de_title->first->str); + de->de_rating_label = NULL; // Set the rating label UUID for this recording to null + dvr_entry_changed(de); // Save this recording. + foundCount++; + } } + } - tvhtrace(LS_RATINGLABELS, "Found '%d' upcomming recordings when deleting rating label.", foundCount); + tvhtrace(LS_RATINGLABELS, + "Found '%d' upcomming recordings when deleting rating label.", + foundCount); - ratinglabel_destroy(rl); + ratinglabel_destroy(rl); } else { idnode_changed(&rl->rl_id); } @@ -442,21 +440,22 @@ ratinglabel_delete(ratinglabel_t *rl) * Class definition * **************************************************************************/ -static htsmsg_t * -ratinglabel_class_save(idnode_t *self, char *filename, size_t fsize) -{ - ratinglabel_t *rl = (ratinglabel_t *)self; - dvr_entry_t *de; - channel_t *ch; - epg_broadcast_t *ebc; - int foundCount = 0; - epg_changes_t *changes = NULL; - int retVal = 0; - - tvhtrace(LS_RATINGLABELS, "Saving rating label '%s' / '%d'.", rl->rl_display_label, rl->rl_display_age); - - htsmsg_t *c = htsmsg_create_map(); - char ubuf[UUID_HEX_SIZE]; +static htsmsg_t* ratinglabel_class_save(idnode_t* self, char* filename, size_t fsize) { + ratinglabel_t* rl = (ratinglabel_t*)self; + dvr_entry_t* de; + channel_t* ch; + epg_broadcast_t* ebc; + int foundCount = 0; + epg_changes_t* changes = NULL; + int retVal = 0; + + tvhtrace(LS_RATINGLABELS, + "Saving rating label '%s' / '%d'.", + rl->rl_display_label, + rl->rl_display_age); + + htsmsg_t* c = htsmsg_create_map(); + char ubuf[UUID_HEX_SIZE]; idnode_save(&rl->rl_id, c); if (filename) snprintf(filename, fsize, "epggrab/ratinglabel/%s", idnode_uuid_as_str(&rl->rl_id, ubuf)); @@ -464,29 +463,29 @@ ratinglabel_class_save(idnode_t *self, char *filename, size_t fsize) htsmsg_add_bool(c, "shield", 1); rl->rl_saveflag = 0; - //Check for EPG entries that use this RL and update the age field. + // Check for EPG entries that use this RL and update the age field. CHANNEL_FOREACH(ch) { - if (ch->ch_epg_parent) continue; - RB_FOREACH(ebc, &ch->ch_epg_schedule, sched_link) { - if(ebc->rating_label == rl) - { - //This could either be a change to the display_label or the display_age - //or perhaps event the icon, regardless, whatever the change, - //for the EPG update to be pushed out to any attached client - //if required we need to have made a change. - retVal = epg_broadcast_set_age_rating(ebc, 99, changes); - retVal = epg_broadcast_set_age_rating(ebc, rl->rl_display_age, changes); - foundCount++; - }//END match the RL - }//END loop through EPG entries for that channel - }//END loop through channels - - //This is a workaround so that I can evaluate retVal and not have the compiler warning kill my buzz. - //If the RL has changed, the EPG entry will be updated, I just need a variable to hold the return - //code from epg_broadcast_set_age_rating even though I'm not going to use it for anything. + if (ch->ch_epg_parent) + continue; + RB_FOREACH (ebc, &ch->ch_epg_schedule, sched_link) { + if (ebc->rating_label == rl) { + // This could either be a change to the display_label or the display_age + // or perhaps event the icon, regardless, whatever the change, + // for the EPG update to be pushed out to any attached client + // if required we need to have made a change. + retVal = epg_broadcast_set_age_rating(ebc, 99, changes); + retVal = epg_broadcast_set_age_rating(ebc, rl->rl_display_age, changes); + foundCount++; + } // END match the RL + } // END loop through EPG entries for that channel + } // END loop through channels + + // This is a workaround so that I can evaluate retVal and not have the compiler warning kill my + // buzz. If the RL has changed, the EPG entry will be updated, I just need a variable to hold the + // return code from epg_broadcast_set_age_rating even though I'm not going to use it for anything. retVal = 0; - if (foundCount != 0 && (retVal == 0)){ + if (foundCount != 0 && (retVal == 0)) { epg_updated(); } @@ -494,89 +493,84 @@ ratinglabel_class_save(idnode_t *self, char *filename, size_t fsize) foundCount = 0; - //Check for upcomming recordings that need their saved RL details to be updated. - LIST_FOREACH(de, &dvrentries, de_global_link){ - if (dvr_entry_is_upcoming(de)){ - if(de->de_rating_label == rl){ - tvhtrace(LS_RATINGLABELS, "Updating rating label for scheduled recording '%s', from '%s' / '%d' to '%s' / '%d'.", de->de_title->first->str, de->de_rating_label_saved, de->de_age_rating, rl->rl_display_label, rl->rl_display_age); - - //Update the recording's RL details. - de->de_rating_label_saved = strdup(rl->rl_display_label); - de->de_age_rating = rl->rl_display_age; - - //If this RL has an icon, save that, else, ensure that the recording's RL icon is empty. - if(rl->rl_icon){ - de->de_rating_icon_saved = strdup(rl->rl_icon); - } - else { - de->de_rating_icon_saved = NULL; - } + // Check for upcomming recordings that need their saved RL details to be updated. + LIST_FOREACH (de, &dvrentries, de_global_link) { + if (dvr_entry_is_upcoming(de)) { + if (de->de_rating_label == rl) { + tvhtrace(LS_RATINGLABELS, + "Updating rating label for scheduled recording '%s', from '%s' / '%d' to '%s' / '%d'.", + de->de_title->first->str, + de->de_rating_label_saved, + de->de_age_rating, + rl->rl_display_label, + rl->rl_display_age); + + // Update the recording's RL details. + de->de_rating_label_saved = strdup(rl->rl_display_label); + de->de_age_rating = rl->rl_display_age; + + // If this RL has an icon, save that, else, ensure that the recording's RL icon is empty. + if (rl->rl_icon) { + de->de_rating_icon_saved = strdup(rl->rl_icon); + } else { + de->de_rating_icon_saved = NULL; + } - dvr_entry_changed(de); //Save this recording and push it out to clients. - foundCount++; - }//END we matched the RL - }//END we got an upcomminf - }//END loop through recordings + dvr_entry_changed(de); // Save this recording and push it out to clients. + foundCount++; + } // END we matched the RL + } // END we got an upcomminf + } // END loop through recordings - tvhtrace(LS_RATINGLABELS, "Found '%d' upcomming recordings when updating rating label.", foundCount); + tvhtrace(LS_RATINGLABELS, + "Found '%d' upcomming recordings when updating rating label.", + foundCount); return c; } -static void -ratinglabel_class_delete(idnode_t *self) -{ - ratinglabel_delete((ratinglabel_t *)self); +static void ratinglabel_class_delete(idnode_t* self) { + ratinglabel_delete((ratinglabel_t*)self); } -//For compatability, return the 'display label' if the 'title' is requested -//because RLs don't have a title. +// For compatability, return the 'display label' if the 'title' is requested +// because RLs don't have a title. static void -ratinglabel_class_get_title - (idnode_t *self, const char *lang, char *dst, size_t dstsize) -{ - ratinglabel_t *rl = (ratinglabel_t *)self; +ratinglabel_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + ratinglabel_t* rl = (ratinglabel_t*)self; snprintf(dst, dstsize, "%s", rl->rl_display_label); } /* exported for others */ -htsmsg_t * -ratinglabel_class_get_list(void *o, const char *lang) -{ - htsmsg_t *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "ratinglabel/list"); +htsmsg_t* ratinglabel_class_get_list(void* o, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "ratinglabel/list"); htsmsg_add_str(m, "event", "ratinglabel"); return m; } -//Get the icon from the rating label object -const char * -ratinglabel_get_icon ( ratinglabel_t *rl ) -{ - if(rl){ +// Get the icon from the rating label object +const char* ratinglabel_get_icon(ratinglabel_t* rl) { + if (rl) { return rl->rl_icon; } return NULL; } -//This is defined as a property getter and is delivered -//via the JSON API. -const void * -ratinglabel_class_get_icon ( void *obj ) -{ +// This is defined as a property getter and is delivered +// via the JSON API. +const void* ratinglabel_class_get_icon(void* obj) { prop_ptr = ratinglabel_get_icon(obj); - if (!strempty(prop_ptr)){ - prop_ptr = imagecache_get_propstr(prop_ptr, prop_sbuf, PROP_SBUF_LEN); + if (!strempty(prop_ptr)) { + prop_ptr = imagecache_get_propstr(prop_ptr, prop_sbuf, PROP_SBUF_LEN); } return &prop_ptr; } -static void -ratinglabel_class_enabled_notify ( void *obj, const char *lang ) -{ - int a=1; - ratinglabel_t *rl = obj; +static void ratinglabel_class_enabled_notify(void* obj, const char* lang) { + int a = 1; + ratinglabel_t* rl = obj; if (rl->rl_enabled) a++; @@ -584,99 +578,93 @@ ratinglabel_class_enabled_notify ( void *obj, const char *lang ) CLASS_DOC(ratinglabel) -const idclass_t ratinglabel_class = { - .ic_class = "ratinglabel", - .ic_caption = N_("EPG Parental Rating Labels"), - .ic_doc = tvh_doc_ratinglabel_class, - .ic_event = "ratinglabel", - .ic_perm_def = ACCESS_ADMIN, - .ic_save = ratinglabel_class_save, - .ic_get_title = ratinglabel_class_get_title, - .ic_delete = ratinglabel_class_delete, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/disable the rating label."), - .def.i = 1, - .off = offsetof(ratinglabel_t, rl_enabled), - .notify = ratinglabel_class_enabled_notify, - }, - { - .type = PT_STR, - .id = "country", - .name = N_("Country"), - .desc = N_("Country recieved via OTA EPG."), - .off = offsetof(ratinglabel_t, rl_country), - }, - { - .type = PT_INT, - .id = "age", - .name = N_("Age"), - .desc = N_("Unprocessed rating 'age' received via DVB OTA EPG."), - .off = offsetof(ratinglabel_t, rl_age), - //.doc = prop_doc_ratinglabel_mapping_options, - }, - { - .type = PT_INT, - .id = "display_age", - .name = N_("Display Age"), - .desc = N_("Age to use in the EPG parental rating field."), - .off = offsetof(ratinglabel_t, rl_display_age), - //.doc = prop_doc_ratinglabel_mapping_options, - }, - { - .type = PT_STR, - .id = "display_label", - .name = N_("Display Label"), - .desc = N_("Rating label to be displayed."), - .off = offsetof(ratinglabel_t, rl_display_label), - }, - { - .type = PT_STR, - .id = "label", - .name = N_("Label"), - .desc = N_("XML 'rating' tag value to match events received via XMLTV."), - .off = offsetof(ratinglabel_t, rl_label), - }, - { - .type = PT_STR, - .id = "authority", - .name = N_("Authority"), - .desc = N_("XMLTV 'system' attribute to match events received via XMLTV."), - .off = offsetof(ratinglabel_t, rl_authority), - }, - { - .type = PT_STR, - .id = "icon", - .name = N_("Icon"), - .desc = N_("File name for this rating's icon."), - .off = offsetof(ratinglabel_t, rl_icon), - }, - { - .type = PT_STR, - .id = "icon_public_url", - .name = N_("Icon URL"), - .desc = N_("The imagecache path to the icon to use/used " - "for the rating label."), - .get = ratinglabel_class_get_icon, - .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN, - }, - {} - } -}; +const idclass_t ratinglabel_class = {.ic_class = "ratinglabel", + .ic_caption = N_("EPG Parental Rating Labels"), + .ic_doc = tvh_doc_ratinglabel_class, + .ic_event = "ratinglabel", + .ic_perm_def = ACCESS_ADMIN, + .ic_save = ratinglabel_class_save, + .ic_get_title = ratinglabel_class_get_title, + .ic_delete = ratinglabel_class_delete, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/disable the rating label."), + .def.i = 1, + .off = offsetof(ratinglabel_t, rl_enabled), + .notify = ratinglabel_class_enabled_notify, + }, + { + .type = PT_STR, + .id = "country", + .name = N_("Country"), + .desc = N_("Country recieved via OTA EPG."), + .off = offsetof(ratinglabel_t, rl_country), + }, + { + .type = PT_INT, + .id = "age", + .name = N_("Age"), + .desc = N_("Unprocessed rating 'age' received via DVB OTA EPG."), + .off = offsetof(ratinglabel_t, rl_age), + //.doc = prop_doc_ratinglabel_mapping_options, + }, + { + .type = PT_INT, + .id = "display_age", + .name = N_("Display Age"), + .desc = N_("Age to use in the EPG parental rating field."), + .off = offsetof(ratinglabel_t, rl_display_age), + //.doc = prop_doc_ratinglabel_mapping_options, + }, + { + .type = PT_STR, + .id = "display_label", + .name = N_("Display Label"), + .desc = N_("Rating label to be displayed."), + .off = offsetof(ratinglabel_t, rl_display_label), + }, + { + .type = PT_STR, + .id = "label", + .name = N_("Label"), + .desc = N_("XML 'rating' tag value to match events received via XMLTV."), + .off = offsetof(ratinglabel_t, rl_label), + }, + { + .type = PT_STR, + .id = "authority", + .name = N_("Authority"), + .desc = N_("XMLTV 'system' attribute to match events received via XMLTV."), + .off = offsetof(ratinglabel_t, rl_authority), + }, + { + .type = PT_STR, + .id = "icon", + .name = N_("Icon"), + .desc = N_("File name for this rating's icon."), + .off = offsetof(ratinglabel_t, rl_icon), + }, + { + .type = PT_STR, + .id = "icon_public_url", + .name = N_("Icon URL"), + .desc = N_("The imagecache path to the icon to use/used " + "for the rating label."), + .get = ratinglabel_class_get_icon, + .opts = PO_RDONLY | PO_NOSAVE | PO_HIDDEN, + }, + {}}}; /** * */ -void -ratinglabel_init(void) -{ +void ratinglabel_init(void) { tvhtrace(LS_RATINGLABELS, "Initialising Rating Labels"); - htsmsg_t *c, *m; - htsmsg_field_t *f; - ratinglabel_t *rl; + htsmsg_t * c, *m; + htsmsg_field_t* f; + ratinglabel_t* rl; RB_INIT(&ratinglabels); idclass_register(&ratinglabel_class); @@ -684,25 +672,27 @@ ratinglabel_init(void) /* Load */ if ((c = hts_settings_load("epggrab/ratinglabel")) != NULL) { HTSMSG_FOREACH(f, c) { - if (!(m = htsmsg_field_get_map(f))) continue; + if (!(m = htsmsg_field_get_map(f))) + continue; rl = ratinglabel_create(htsmsg_field_name(f), m, NULL, NULL); - if (rl) - { - tvhtrace(LS_RATINGLABELS, "Loaded label: '%s' / '%d', enabled: '%d', label count: '%d'", rl->rl_display_label, rl->rl_display_age, rl->rl_enabled, ratinglabels.entries); + if (rl) { + tvhtrace(LS_RATINGLABELS, + "Loaded label: '%s' / '%d', enabled: '%d', label count: '%d'", + rl->rl_display_label, + rl->rl_display_age, + rl->rl_enabled, + ratinglabels.entries); rl->rl_saveflag = 0; } } htsmsg_destroy(c); } - } -//Delete all of the ratinglabel objects. -//This appears to be called from main.c. -void -ratinglabel_done(void) -{ - ratinglabel_t *rl; +// Delete all of the ratinglabel objects. +// This appears to be called from main.c. +void ratinglabel_done(void) { + ratinglabel_t* rl; tvh_mutex_lock(&global_lock); while ((rl = RB_FIRST(&ratinglabels)) != NULL) diff --git a/src/ratinglabels.h b/src/ratinglabels.h index 50415ed73..d4ccc783a 100644 --- a/src/ratinglabels.h +++ b/src/ratinglabels.h @@ -27,30 +27,30 @@ typedef struct ratinglabel { idnode_t rl_id; RB_ENTRY(ratinglabel) rl_link; - int rl_saveflag; //} These were kept because - int rl_in_load; //} they were in the module that I copied - int rl_shield; //} and I was not sure if I could delete them - - int rl_enabled; //Can this label be matched to? - char *rl_country; //The 3 byte country code from the EIT - int rl_age; //The age value from the EIT - int rl_display_age; //The age value to actually use - char *rl_display_label; //The label to actually use - char *rl_label; //The rating label from XMLTV - char *rl_authority; //The 'system' from XMLTV - char *rl_icon; //The pretty picture + int rl_saveflag; //} These were kept because + int rl_in_load; //} they were in the module that I copied + int rl_shield; //} and I was not sure if I could delete them + + int rl_enabled; // Can this label be matched to? + char* rl_country; // The 3 byte country code from the EIT + int rl_age; // The age value from the EIT + int rl_display_age; // The age value to actually use + char* rl_display_label; // The label to actually use + char* rl_label; // The rating label from XMLTV + char* rl_authority; // The 'system' from XMLTV + char* rl_icon; // The pretty picture } ratinglabel_t; /* *** EIT Documentation parental_rating_descriptor(){ - descriptor_tag 8 uimsbf - descriptor_length 8 uimsbf - for (i=0;i */ -typedef RB_HEAD(,ratinglabel) ratinglabel_tree_t; +typedef RB_HEAD(, ratinglabel) ratinglabel_tree_t; extern ratinglabel_tree_t ratinglabels; extern const idclass_t ratinglabel_class; -htsmsg_t * ratinglabel_class_get_list(void *o, const char *lang); -const void *ratinglabel_class_get_icon (void *obj); +htsmsg_t* ratinglabel_class_get_list(void* o, const char* lang); +const void* ratinglabel_class_get_icon(void* obj); -ratinglabel_t * ratinglabel_create(const char *uuid, htsmsg_t *conf, - const char *name, const char *src); +ratinglabel_t* +ratinglabel_create(const char* uuid, htsmsg_t* conf, const char* name, const char* src); -void ratinglabel_delete(ratinglabel_t *rl); +void ratinglabel_delete(ratinglabel_t* rl); -void ratinglabel_completed(ratinglabel_t *rl, uint32_t seen); -void ratinglabel_change_comment(ratinglabel_t *rl, const char *comment, int replace); +void ratinglabel_completed(ratinglabel_t* rl, uint32_t seen); +void ratinglabel_change_comment(ratinglabel_t* rl, const char* comment, int replace); extern void ratinglabel_init(void); extern void ratinglabel_done(void); -extern ratinglabel_t *ratinglabel_find_from_eit(char *country, int age); -extern ratinglabel_t *ratinglabel_find_from_xmltv(const char *authority, const char *label); -extern ratinglabel_t *ratinglabel_find_from_uuid(const char *string_uuid); +extern ratinglabel_t* ratinglabel_find_from_eit(char* country, int age); +extern ratinglabel_t* ratinglabel_find_from_xmltv(const char* authority, const char* label); +extern ratinglabel_t* ratinglabel_find_from_uuid(const char* string_uuid); #endif /* RATINGLABEL_H_ */ diff --git a/src/redblack.h b/src/redblack.h index 864fa3437..ded59c55e 100644 --- a/src/redblack.h +++ b/src/redblack.h @@ -25,220 +25,205 @@ #ifndef REDBLACK_H_ #define REDBLACK_H_ -#define RB_TREE_NODE_RED 0 -#define RB_TREE_NODE_BLACK 1 - - -#define RB_HEAD(name, type) \ -struct name { \ - struct type *first, *last, *root; \ - int entries; \ -} - -#define RB_ENTRY(type) \ -struct { \ - struct type *left, *right, *parent; \ - int color; \ -} - -#define RB_INIT(head) \ -do { \ - (head)->first = NULL; \ - (head)->last = NULL; \ - (head)->root = NULL; \ - (head)->entries = 0; \ -} while(0) - - - -#define RB_ROTATE_LEFT(x, field, root) \ -do { \ - typeof(x) xx = x; \ - typeof(x) yy = xx->field.right; \ - \ - xx->field.right = yy->field.left; \ - if(yy->field.left != NULL) \ - yy->field.left->field.parent = xx; \ - \ - yy->field.parent = xx->field.parent; \ - \ - if(xx == root) \ - root = yy; \ - else if(xx == xx->field.parent->field.left) \ - xx->field.parent->field.left = yy; \ - else \ - xx->field.parent->field.right = yy; \ - yy->field.left = xx; \ - xx->field.parent = yy; \ -} while(0) - - -#define RB_ROTATE_RIGHT(x, field, root) \ -do { \ - typeof(x) xx = x; \ - typeof(x) yy = xx->field.left; \ - \ - xx->field.left = yy->field.right; \ - if (yy->field.right != NULL) \ - yy->field.right->field.parent = xx; \ - yy->field.parent = xx->field.parent; \ - \ - if (xx == root) \ - root = yy; \ - else if (xx == xx->field.parent->field.right) \ - xx->field.parent->field.right = yy; \ - else \ - xx->field.parent->field.left = yy; \ - yy->field.right = xx; \ - xx->field.parent = yy; \ -} while(0) - - - -#define RB_INSERT_BALANCE(x, field, root) \ -do { \ - typeof(x) y; \ - \ - x->field.color = RB_TREE_NODE_RED; \ - while (x != root && x->field.parent->field.color == RB_TREE_NODE_RED) { \ - if (x->field.parent == x->field.parent->field.parent->field.left) { \ - y = x->field.parent->field.parent->field.right; \ - if (y && y->field.color == RB_TREE_NODE_RED) { \ - x->field.parent->field.color = RB_TREE_NODE_BLACK; \ - y->field.color = RB_TREE_NODE_BLACK; \ - x->field.parent->field.parent->field.color = RB_TREE_NODE_RED; \ - x = x->field.parent->field.parent; \ - } \ - else { \ - if (x == x->field.parent->field.right) { \ - x = x->field.parent; \ - RB_ROTATE_LEFT(x, field, root); \ - } \ - x->field.parent->field.color = RB_TREE_NODE_BLACK; \ - x->field.parent->field.parent->field.color = RB_TREE_NODE_RED; \ - RB_ROTATE_RIGHT(x->field.parent->field.parent, field, root); \ - } \ - } \ - else { \ - y = x->field.parent->field.parent->field.left; \ - if (y && y->field.color == RB_TREE_NODE_RED) { \ - x->field.parent->field.color = RB_TREE_NODE_BLACK; \ - y->field.color = RB_TREE_NODE_BLACK; \ - x->field.parent->field.parent->field.color = RB_TREE_NODE_RED; \ - x = x->field.parent->field.parent; \ - } \ - else { \ - if (x == x->field.parent->field.left) { \ - x = x->field.parent; \ - RB_ROTATE_RIGHT(x, field, root); \ - } \ - x->field.parent->field.color = RB_TREE_NODE_BLACK; \ - x->field.parent->field.parent->field.color = RB_TREE_NODE_RED; \ - RB_ROTATE_LEFT(x->field.parent->field.parent, field, root); \ - } \ - } \ - } \ - root->field.color = RB_TREE_NODE_BLACK; \ -} while(0); - +#define RB_TREE_NODE_RED 0 +#define RB_TREE_NODE_BLACK 1 + +#define RB_HEAD(name, type) \ + struct name { \ + struct type *first, *last, *root; \ + int entries; \ + } + +#define RB_ENTRY(type) \ + struct { \ + struct type *left, *right, *parent; \ + int color; \ + } + +#define RB_INIT(head) \ + do { \ + (head)->first = NULL; \ + (head)->last = NULL; \ + (head)->root = NULL; \ + (head)->entries = 0; \ + } while (0) + +#define RB_ROTATE_LEFT(x, field, root) \ + do { \ + typeof(x) xx = x; \ + typeof(x) yy = xx->field.right; \ + \ + xx->field.right = yy->field.left; \ + if (yy->field.left != NULL) \ + yy->field.left->field.parent = xx; \ + \ + yy->field.parent = xx->field.parent; \ + \ + if (xx == root) \ + root = yy; \ + else if (xx == xx->field.parent->field.left) \ + xx->field.parent->field.left = yy; \ + else \ + xx->field.parent->field.right = yy; \ + yy->field.left = xx; \ + xx->field.parent = yy; \ + } while (0) + +#define RB_ROTATE_RIGHT(x, field, root) \ + do { \ + typeof(x) xx = x; \ + typeof(x) yy = xx->field.left; \ + \ + xx->field.left = yy->field.right; \ + if (yy->field.right != NULL) \ + yy->field.right->field.parent = xx; \ + yy->field.parent = xx->field.parent; \ + \ + if (xx == root) \ + root = yy; \ + else if (xx == xx->field.parent->field.right) \ + xx->field.parent->field.right = yy; \ + else \ + xx->field.parent->field.left = yy; \ + yy->field.right = xx; \ + xx->field.parent = yy; \ + } while (0) + +#define RB_INSERT_BALANCE(x, field, root) \ + do { \ + typeof(x) y; \ + \ + x->field.color = RB_TREE_NODE_RED; \ + while (x != root && x->field.parent->field.color == RB_TREE_NODE_RED) { \ + if (x->field.parent == x->field.parent->field.parent->field.left) { \ + y = x->field.parent->field.parent->field.right; \ + if (y && y->field.color == RB_TREE_NODE_RED) { \ + x->field.parent->field.color = RB_TREE_NODE_BLACK; \ + y->field.color = RB_TREE_NODE_BLACK; \ + x->field.parent->field.parent->field.color = RB_TREE_NODE_RED; \ + x = x->field.parent->field.parent; \ + } else { \ + if (x == x->field.parent->field.right) { \ + x = x->field.parent; \ + RB_ROTATE_LEFT(x, field, root); \ + } \ + x->field.parent->field.color = RB_TREE_NODE_BLACK; \ + x->field.parent->field.parent->field.color = RB_TREE_NODE_RED; \ + RB_ROTATE_RIGHT(x->field.parent->field.parent, field, root); \ + } \ + } else { \ + y = x->field.parent->field.parent->field.left; \ + if (y && y->field.color == RB_TREE_NODE_RED) { \ + x->field.parent->field.color = RB_TREE_NODE_BLACK; \ + y->field.color = RB_TREE_NODE_BLACK; \ + x->field.parent->field.parent->field.color = RB_TREE_NODE_RED; \ + x = x->field.parent->field.parent; \ + } else { \ + if (x == x->field.parent->field.left) { \ + x = x->field.parent; \ + RB_ROTATE_RIGHT(x, field, root); \ + } \ + x->field.parent->field.color = RB_TREE_NODE_BLACK; \ + x->field.parent->field.parent->field.color = RB_TREE_NODE_RED; \ + RB_ROTATE_LEFT(x->field.parent->field.parent, field, root); \ + } \ + } \ + } \ + root->field.color = RB_TREE_NODE_BLACK; \ + } while (0); /** * Insert a new node, if a collision occures the colliding node is returned */ -#define RB_INSERT_SORTED(head, skel, field, cmpfunc) \ -({ \ - int res, fromleft = 0; \ - typeof(skel) x = skel, c, parent = NULL; \ - \ - c = (head)->root; \ - while(c != NULL) { \ - res = cmpfunc(x, c); \ - if(res < 0) { \ - parent = c; \ - c = c->field.left; \ - fromleft = 1; \ - } else if(res > 0) { \ - parent = c; \ - c = c->field.right; \ - fromleft = 0; \ - } else { \ - break; \ - } \ - } \ - if(c == NULL) { \ - x->field.parent = parent; \ - x->field.left = NULL; \ - x->field.right = NULL; \ - x->field.color = RB_TREE_NODE_RED; \ - \ - if(parent) { \ - if(fromleft) \ - parent->field.left = x; \ - else \ - parent->field.right = x; \ - } else { \ - (head)->root = x; \ - } \ - (head)->entries++; \ - \ - if(x->field.parent == (head)->first && \ - (x->field.parent == NULL || x->field.parent->field.left == x)) { \ - (head)->first = x; \ - } \ - \ - if(x->field.parent == (head)->last && \ - (x->field.parent == NULL || x->field.parent->field.right == x)) { \ - (head)->last = x; \ - } \ - RB_INSERT_BALANCE(x, field, (head)->root); \ - } \ - c; \ -}) - +#define RB_INSERT_SORTED(head, skel, field, cmpfunc) \ + ({ \ + int res, fromleft = 0; \ + typeof(skel) x = skel, c, parent = NULL; \ + \ + c = (head)->root; \ + while (c != NULL) { \ + res = cmpfunc(x, c); \ + if (res < 0) { \ + parent = c; \ + c = c->field.left; \ + fromleft = 1; \ + } else if (res > 0) { \ + parent = c; \ + c = c->field.right; \ + fromleft = 0; \ + } else { \ + break; \ + } \ + } \ + if (c == NULL) { \ + x->field.parent = parent; \ + x->field.left = NULL; \ + x->field.right = NULL; \ + x->field.color = RB_TREE_NODE_RED; \ + \ + if (parent) { \ + if (fromleft) \ + parent->field.left = x; \ + else \ + parent->field.right = x; \ + } else { \ + (head)->root = x; \ + } \ + (head)->entries++; \ + \ + if (x->field.parent == (head)->first && \ + (x->field.parent == NULL || x->field.parent->field.left == x)) { \ + (head)->first = x; \ + } \ + \ + if (x->field.parent == (head)->last && \ + (x->field.parent == NULL || x->field.parent->field.right == x)) { \ + (head)->last = x; \ + } \ + RB_INSERT_BALANCE(x, field, (head)->root); \ + } \ + c; \ + }) /** * Returns next node */ -#define RB_NEXT(e, field) \ -({ \ - typeof(e) xx = e, f; \ - if (xx->field.right != NULL) { \ - xx = xx->field.right; \ - while (xx->field.left != NULL) { \ - xx = xx->field.left; \ - } \ - } \ - else { \ - do { \ - f = xx; \ - xx = xx->field.parent; \ - } while (xx && f == xx->field.right); \ - } \ - xx; \ -}) - +#define RB_NEXT(e, field) \ + ({ \ + typeof(e) xx = e, f; \ + if (xx->field.right != NULL) { \ + xx = xx->field.right; \ + while (xx->field.left != NULL) { \ + xx = xx->field.left; \ + } \ + } else { \ + do { \ + f = xx; \ + xx = xx->field.parent; \ + } while (xx && f == xx->field.right); \ + } \ + xx; \ + }) /** * Returns previous node */ -#define RB_PREV(e, field) \ -({ \ - typeof(e) xx = e, f; \ - if (xx->field.left != NULL) { \ - xx = xx->field.left; \ - while (xx->field.right != NULL) { \ - xx = xx->field.right; \ - } \ - } \ - else { \ - do { \ - f = xx; \ - xx = xx->field.parent; \ - } while (xx && f == xx->field.left); \ - } \ - xx; \ -}) - +#define RB_PREV(e, field) \ + ({ \ + typeof(e) xx = e, f; \ + if (xx->field.left != NULL) { \ + xx = xx->field.left; \ + while (xx->field.right != NULL) { \ + xx = xx->field.right; \ + } \ + } else { \ + do { \ + f = xx; \ + xx = xx->field.parent; \ + } while (xx && f == xx->field.left); \ + } \ + xx; \ + }) /** * Returns first node @@ -248,325 +233,300 @@ do { \ /** * Returns last node */ -#define RB_LAST(head) ((head)->last) +#define RB_LAST(head) ((head)->last) /** * Iterate thru all nodes */ -#define RB_FOREACH(e, head, field) \ - for(e = (head)->first; e != NULL; \ - ({ \ - if(e->field.right != NULL) { \ - e = e->field.right; \ - while(e->field.left != NULL) { \ - e = e->field.left; \ - } \ - } else { \ - typeof(e) f; \ - do { \ - f = e; \ - e = e->field.parent; \ - } while(e && f == e->field.right); \ - } \ +#define RB_FOREACH(e, head, field) \ + for (e = (head)->first; e != NULL; ({ \ + if (e->field.right != NULL) { \ + e = e->field.right; \ + while (e->field.left != NULL) { \ + e = e->field.left; \ + } \ + } else { \ + typeof(e) f; \ + do { \ + f = e; \ + e = e->field.parent; \ + } while (e && f == e->field.right); \ + } \ })) - /** * Iterate thru all nodes in reverse order */ -#define RB_FOREACH_REVERSE(e, head, field) \ - for(e = (head)->last; e != NULL; \ - ({ \ - if(e->field.left != NULL) { \ - e = e->field.left; \ - while(e->field.right != NULL) { \ - e = e->field.right; \ - } \ - } else { \ - typeof(e) f; \ - do { \ - f = e; \ - e = e->field.parent; \ - } while(e && f == e->field.left); \ - } \ +#define RB_FOREACH_REVERSE(e, head, field) \ + for (e = (head)->last; e != NULL; ({ \ + if (e->field.left != NULL) { \ + e = e->field.left; \ + while (e->field.right != NULL) { \ + e = e->field.right; \ + } \ + } else { \ + typeof(e) f; \ + do { \ + f = e; \ + e = e->field.parent; \ + } while (e && f == e->field.left); \ + } \ })) /** * Remove the given node */ -#define RB_REMOVE(head, e, field) \ -do { \ - int swapColor; \ - typeof(e) x, y, z = e, x_parent, w; \ - \ - y = z; \ - if (y == (head)->first) { \ - (head)->first = RB_NEXT(y, field); \ - } \ - if (y == (head)->last) { \ - (head)->last = RB_PREV(y, field); \ - } \ - if (y->field.left == NULL) { \ - x = y->field.right; \ - } \ - else { \ - if (y->field.right == NULL) { \ - x = y->field.left; \ - } \ - else { \ - y = y->field.right; \ - while (y->field.left != NULL) { \ - y = y->field.left; \ - } \ - x = y->field.right; \ - } \ - } \ - if (y != z) { \ - z->field.left->field.parent = y; \ - y->field.left = z->field.left; \ - if (y != z->field.right) { \ - x_parent = y->field.parent; \ - if (x != NULL) { \ - x->field.parent = y->field.parent; \ - } \ - y->field.parent->field.left = x; \ - y->field.right = z->field.right; \ - z->field.right->field.parent = y; \ - } \ - else { \ - x_parent = y; \ - } \ - if ((head)->root == z) { \ - (head)->root = y; \ - } \ - else if (z->field.parent->field.left == z) { \ - z->field.parent->field.left = y; \ - } \ - else { \ - z->field.parent->field.right = y; \ - } \ - y->field.parent = z->field.parent; \ - \ - swapColor = y->field.color; \ - y->field.color = z->field.color; \ - z->field.color = swapColor; \ - \ - y = z; \ - } \ - else { \ - x_parent = y->field.parent; \ - if (x != NULL) { \ - x->field.parent = y->field.parent; \ - } \ - if ((head)->root == z) { \ - (head)->root = x; \ - } \ - else { \ - if (z->field.parent->field.left == z) { \ - z->field.parent->field.left = x; \ - } \ - else { \ - z->field.parent->field.right = x; \ - } \ - } \ - } \ - \ - (head)->entries--; \ - \ - if (y->field.color != RB_TREE_NODE_RED) { \ - while (x != (head)->root && \ - (x == NULL || x->field.color == RB_TREE_NODE_BLACK)) { \ - if (x == x_parent->field.left) { \ - w = x_parent->field.right; \ - if (w->field.color == RB_TREE_NODE_RED) { \ - w->field.color = RB_TREE_NODE_BLACK; \ - x_parent->field.color = RB_TREE_NODE_RED; \ - RB_ROTATE_LEFT(x_parent, field, (head)->root); \ - w = x_parent->field.right; \ - } \ - if ((w->field.left == NULL || \ - w->field.left->field.color == RB_TREE_NODE_BLACK) && \ - (w->field.right == NULL || \ - w->field.right->field.color == RB_TREE_NODE_BLACK)) { \ - \ - w->field.color = RB_TREE_NODE_RED; \ - x = x_parent; \ - x_parent = x_parent->field.parent; \ - } else { \ - if (w->field.right == NULL || \ - w->field.right->field.color == RB_TREE_NODE_BLACK) { \ - \ - if (w->field.left) { \ - w->field.left->field.color = RB_TREE_NODE_BLACK; \ - } \ - w->field.color = RB_TREE_NODE_RED; \ - RB_ROTATE_RIGHT(w, field, (head)->root); \ - w = x_parent->field.right; \ - } \ - w->field.color = x_parent->field.color; \ - x_parent->field.color = RB_TREE_NODE_BLACK; \ - if (w->field.right) { \ - w->field.right->field.color = RB_TREE_NODE_BLACK; \ - } \ - RB_ROTATE_LEFT(x_parent, field, (head)->root); \ - break; \ - } \ - } \ - else { \ - w = x_parent->field.left; \ - if (w->field.color == RB_TREE_NODE_RED) { \ - w->field.color = RB_TREE_NODE_BLACK; \ - x_parent->field.color = RB_TREE_NODE_RED; \ - RB_ROTATE_RIGHT(x_parent, field, (head)->root); \ - w = x_parent->field.left; \ - } \ - if ((w->field.right == NULL || \ - w->field.right->field.color == RB_TREE_NODE_BLACK) && \ - (w->field.left == NULL || \ - w->field.left->field.color == RB_TREE_NODE_BLACK)) { \ - \ - w->field.color = RB_TREE_NODE_RED; \ - x = x_parent; \ - x_parent = x_parent->field.parent; \ - } \ - else { \ - if (w->field.left == NULL || \ - w->field.left->field.color == RB_TREE_NODE_BLACK) { \ - \ - if (w->field.right) { \ - w->field.right->field.color = RB_TREE_NODE_BLACK; \ - } \ - w->field.color = RB_TREE_NODE_RED; \ - RB_ROTATE_LEFT(w, field, (head)->root); \ - w = x_parent->field.left; \ - } \ - w->field.color = x_parent->field.color; \ - x_parent->field.color = RB_TREE_NODE_BLACK; \ - if (w->field.left) { \ - w->field.left->field.color = RB_TREE_NODE_BLACK; \ - } \ - RB_ROTATE_RIGHT(x_parent, field, (head)->root); \ - break; \ - } \ - } \ - } \ - if (x) { \ - x->field.color = RB_TREE_NODE_BLACK; \ - } \ - } \ -} while(0) - - +#define RB_REMOVE(head, e, field) \ + do { \ + int swapColor; \ + typeof(e) x, y, z = e, x_parent, w; \ + \ + y = z; \ + if (y == (head)->first) { \ + (head)->first = RB_NEXT(y, field); \ + } \ + if (y == (head)->last) { \ + (head)->last = RB_PREV(y, field); \ + } \ + if (y->field.left == NULL) { \ + x = y->field.right; \ + } else { \ + if (y->field.right == NULL) { \ + x = y->field.left; \ + } else { \ + y = y->field.right; \ + while (y->field.left != NULL) { \ + y = y->field.left; \ + } \ + x = y->field.right; \ + } \ + } \ + if (y != z) { \ + z->field.left->field.parent = y; \ + y->field.left = z->field.left; \ + if (y != z->field.right) { \ + x_parent = y->field.parent; \ + if (x != NULL) { \ + x->field.parent = y->field.parent; \ + } \ + y->field.parent->field.left = x; \ + y->field.right = z->field.right; \ + z->field.right->field.parent = y; \ + } else { \ + x_parent = y; \ + } \ + if ((head)->root == z) { \ + (head)->root = y; \ + } else if (z->field.parent->field.left == z) { \ + z->field.parent->field.left = y; \ + } else { \ + z->field.parent->field.right = y; \ + } \ + y->field.parent = z->field.parent; \ + \ + swapColor = y->field.color; \ + y->field.color = z->field.color; \ + z->field.color = swapColor; \ + \ + y = z; \ + } else { \ + x_parent = y->field.parent; \ + if (x != NULL) { \ + x->field.parent = y->field.parent; \ + } \ + if ((head)->root == z) { \ + (head)->root = x; \ + } else { \ + if (z->field.parent->field.left == z) { \ + z->field.parent->field.left = x; \ + } else { \ + z->field.parent->field.right = x; \ + } \ + } \ + } \ + \ + (head)->entries--; \ + \ + if (y->field.color != RB_TREE_NODE_RED) { \ + while (x != (head)->root && (x == NULL || x->field.color == RB_TREE_NODE_BLACK)) { \ + if (x == x_parent->field.left) { \ + w = x_parent->field.right; \ + if (w->field.color == RB_TREE_NODE_RED) { \ + w->field.color = RB_TREE_NODE_BLACK; \ + x_parent->field.color = RB_TREE_NODE_RED; \ + RB_ROTATE_LEFT(x_parent, field, (head)->root); \ + w = x_parent->field.right; \ + } \ + if ((w->field.left == NULL || w->field.left->field.color == RB_TREE_NODE_BLACK) && \ + (w->field.right == NULL || w->field.right->field.color == RB_TREE_NODE_BLACK)) { \ + \ + w->field.color = RB_TREE_NODE_RED; \ + x = x_parent; \ + x_parent = x_parent->field.parent; \ + } else { \ + if (w->field.right == NULL || w->field.right->field.color == RB_TREE_NODE_BLACK) { \ + \ + if (w->field.left) { \ + w->field.left->field.color = RB_TREE_NODE_BLACK; \ + } \ + w->field.color = RB_TREE_NODE_RED; \ + RB_ROTATE_RIGHT(w, field, (head)->root); \ + w = x_parent->field.right; \ + } \ + w->field.color = x_parent->field.color; \ + x_parent->field.color = RB_TREE_NODE_BLACK; \ + if (w->field.right) { \ + w->field.right->field.color = RB_TREE_NODE_BLACK; \ + } \ + RB_ROTATE_LEFT(x_parent, field, (head)->root); \ + break; \ + } \ + } else { \ + w = x_parent->field.left; \ + if (w->field.color == RB_TREE_NODE_RED) { \ + w->field.color = RB_TREE_NODE_BLACK; \ + x_parent->field.color = RB_TREE_NODE_RED; \ + RB_ROTATE_RIGHT(x_parent, field, (head)->root); \ + w = x_parent->field.left; \ + } \ + if ((w->field.right == NULL || w->field.right->field.color == RB_TREE_NODE_BLACK) && \ + (w->field.left == NULL || w->field.left->field.color == RB_TREE_NODE_BLACK)) { \ + \ + w->field.color = RB_TREE_NODE_RED; \ + x = x_parent; \ + x_parent = x_parent->field.parent; \ + } else { \ + if (w->field.left == NULL || w->field.left->field.color == RB_TREE_NODE_BLACK) { \ + \ + if (w->field.right) { \ + w->field.right->field.color = RB_TREE_NODE_BLACK; \ + } \ + w->field.color = RB_TREE_NODE_RED; \ + RB_ROTATE_LEFT(w, field, (head)->root); \ + w = x_parent->field.left; \ + } \ + w->field.color = x_parent->field.color; \ + x_parent->field.color = RB_TREE_NODE_BLACK; \ + if (w->field.left) { \ + w->field.left->field.color = RB_TREE_NODE_BLACK; \ + } \ + RB_ROTATE_RIGHT(x_parent, field, (head)->root); \ + break; \ + } \ + } \ + } \ + if (x) { \ + x->field.color = RB_TREE_NODE_BLACK; \ + } \ + } \ + } while (0) /** * Finds a node */ -#define RB_FIND(head, skel, field, cmpfunc) \ -({ \ - int res; \ - typeof(skel) c = (head)->root; \ - while(c != NULL) { \ - res = cmpfunc(skel, c); \ - if(res < 0) { \ - c = c->field.left; \ - } else if(res > 0) { \ - c = c->field.right; \ - } else { \ - break; \ - } \ - } \ - c; \ -}) - - +#define RB_FIND(head, skel, field, cmpfunc) \ + ({ \ + int res; \ + typeof(skel) c = (head)->root; \ + while (c != NULL) { \ + res = cmpfunc(skel, c); \ + if (res < 0) { \ + c = c->field.left; \ + } else if (res > 0) { \ + c = c->field.right; \ + } else { \ + break; \ + } \ + } \ + c; \ + }) /** * Finds first node greater than 'skel' */ -#define RB_FIND_GT(head, skel, field, cmpfunc) \ -({ \ - int res; \ - typeof(skel) c = (head)->root, x = NULL; \ - while(c != NULL) { \ - res = cmpfunc(skel, c); \ - if(res < 0) { \ - x = c; \ - c = c->field.left; \ - } else if(res > 0) { \ - c = c->field.right; \ - } else { \ - x = RB_NEXT(c, field); \ - break; \ - } \ - } \ - x; \ -}) +#define RB_FIND_GT(head, skel, field, cmpfunc) \ + ({ \ + int res; \ + typeof(skel) c = (head)->root, x = NULL; \ + while (c != NULL) { \ + res = cmpfunc(skel, c); \ + if (res < 0) { \ + x = c; \ + c = c->field.left; \ + } else if (res > 0) { \ + c = c->field.right; \ + } else { \ + x = RB_NEXT(c, field); \ + break; \ + } \ + } \ + x; \ + }) /** * Finds a node greater or equal to 'skel' */ -#define RB_FIND_GE(head, skel, field, cmpfunc) \ -({ \ - int res; \ - typeof(skel) c = (head)->root, x = NULL; \ - while(c != NULL) { \ - res = cmpfunc(skel, c); \ - if(res < 0) { \ - x = c; \ - c = c->field.left; \ - } else if(res > 0) { \ - c = c->field.right; \ - } else { \ - x = c; \ - break; \ - } \ - } \ - x; \ -}) - +#define RB_FIND_GE(head, skel, field, cmpfunc) \ + ({ \ + int res; \ + typeof(skel) c = (head)->root, x = NULL; \ + while (c != NULL) { \ + res = cmpfunc(skel, c); \ + if (res < 0) { \ + x = c; \ + c = c->field.left; \ + } else if (res > 0) { \ + c = c->field.right; \ + } else { \ + x = c; \ + break; \ + } \ + } \ + x; \ + }) /** * Finds first node lesser than 'skel' */ -#define RB_FIND_LT(head, skel, field, cmpfunc) \ -({ \ - int res; \ - typeof(skel) c = (head)->root, x = NULL; \ - while(c != NULL) { \ - res = cmpfunc(skel, c); \ - if(res < 0) { \ - c = c->field.left; \ - } else if(res > 0) { \ - x = c; \ - c = c->field.right; \ - } else { \ - x = RB_PREV(c, field); \ - break; \ - } \ - } \ - x; \ -}) +#define RB_FIND_LT(head, skel, field, cmpfunc) \ + ({ \ + int res; \ + typeof(skel) c = (head)->root, x = NULL; \ + while (c != NULL) { \ + res = cmpfunc(skel, c); \ + if (res < 0) { \ + c = c->field.left; \ + } else if (res > 0) { \ + x = c; \ + c = c->field.right; \ + } else { \ + x = RB_PREV(c, field); \ + break; \ + } \ + } \ + x; \ + }) /** * Finds a node lesser or equal to 'skel' */ -#define RB_FIND_LE(head, skel, field, cmpfunc) \ -({ \ - int res; \ - typeof(skel) c = (head)->root, x = NULL; \ - while(c != NULL) { \ - res = cmpfunc(skel, c); \ - if(res < 0) { \ - c = c->field.left; \ - } else if(res > 0) { \ - x = c; \ - c = c->field.right; \ - } else { \ - x = c; \ - break; \ - } \ - } \ - x; \ -}) +#define RB_FIND_LE(head, skel, field, cmpfunc) \ + ({ \ + int res; \ + typeof(skel) c = (head)->root, x = NULL; \ + while (c != NULL) { \ + res = cmpfunc(skel, c); \ + if (res < 0) { \ + c = c->field.left; \ + } else if (res > 0) { \ + x = c; \ + c = c->field.right; \ + } else { \ + x = c; \ + break; \ + } \ + } \ + x; \ + }) #endif /* REDBLACK_H_ */ diff --git a/src/rtsp.c b/src/rtsp.c index 6a7787910..a774b086d 100644 --- a/src/rtsp.c +++ b/src/rtsp.c @@ -26,19 +26,19 @@ /* * Utils */ -int -rtsp_send_ext( http_client_t *hc, http_cmd_t cmd, - const char *path, const char *query, - http_arg_list_t *hdr, - const char *body, size_t size ) -{ +int rtsp_send_ext(http_client_t* hc, + http_cmd_t cmd, + const char* path, + const char* query, + http_arg_list_t* hdr, + const char* body, + size_t size) { http_arg_list_t h; - size_t blen = 7 + strlen(hc->hc_host) + - (hc->hc_port != 554 ? 7 : 0) + - (path ? strlen(path) : 1) + 1; - char *buf = alloca(blen); - char buf2[64]; - char buf_body[size + 3]; + size_t blen = + 7 + strlen(hc->hc_host) + (hc->hc_port != 554 ? 7 : 0) + (path ? strlen(path) : 1) + 1; + char* buf = alloca(blen); + char buf2[64]; + char buf_body[size + 3]; if (hc->hc_rtsp_session) { if (hdr == NULL) { @@ -55,7 +55,7 @@ rtsp_send_ext( http_client_t *hc, http_cmd_t cmd, } strlcpy(buf_body, body, sizeof(buf_body)); strlcat(buf_body, "\r\n", 2); - snprintf(buf2, sizeof(buf2), "%"PRIu64, (uint64_t)(size + 2)); + snprintf(buf2, sizeof(buf2), "%" PRIu64, (uint64_t)(size + 2)); http_arg_set(hdr, "Content-Length", buf2); } @@ -65,15 +65,13 @@ rtsp_send_ext( http_client_t *hc, http_cmd_t cmd, else buf2[0] = '\0'; snprintf(buf, blen, "rtsp://%s%s%s", hc->hc_host, buf2, path ? path : "/"); - if(size > 0) + if (size > 0) return http_client_send(hc, cmd, buf, query, hdr, buf_body, size + 2); else return http_client_send(hc, cmd, buf, query, hdr, NULL, 0); } -void -rtsp_clear_session( http_client_t *hc ) -{ +void rtsp_clear_session(http_client_t* hc) { free(hc->hc_rtsp_session); free(hc->hc_rtp_dest); hc->hc_rtp_port = 0; @@ -89,11 +87,9 @@ rtsp_clear_session( http_client_t *hc ) * Options */ -int -rtsp_options_decode( http_client_t *hc ) -{ +int rtsp_options_decode(http_client_t* hc) { char *argv[32], *p; - int i, n, what = 0; + int i, n, what = 0; p = http_arg_get(&hc->hc_args, "Public"); if (p == NULL) @@ -112,11 +108,9 @@ rtsp_options_decode( http_client_t *hc ) return (hc->hc_code != 200 && what != 0x0f) ? -EIO : HTTP_CON_OK; } -int -rtsp_setup_decode( http_client_t *hc, int satip ) -{ +int rtsp_setup_decode(http_client_t* hc, int satip) { char *argv[32], *argv2[2], *p; - int i, n, j; + int i, n, j; rtsp_clear_session(hc); if (hc->hc_code != 200) @@ -158,9 +152,9 @@ rtsp_setup_decode( http_client_t *hc, int satip ) n = http_tokenize(p, argv, 32, ';'); if (n < 2) return -EIO; - hc->hc_rtp_tcp = -1; - hc->hc_rtcp_tcp = -1; - hc->hc_rtp_port = -1; + hc->hc_rtp_tcp = -1; + hc->hc_rtcp_tcp = -1; + hc->hc_rtp_port = -1; hc->hc_rtcp_port = -1; if (!strcasecmp(argv[0], "RTP/AVP/TCP")) { for (i = 1; i < n; i++) { @@ -180,9 +174,8 @@ rtsp_setup_decode( http_client_t *hc, int satip ) } } } - } else if (!strcasecmp(argv[0], "RTP/AVP") || - !strcasecmp(argv[0], "RTP/AVP/UDP") || - !strcasecmp(argv[0], "RTP/AVPF/UDP")) { + } else if (!strcasecmp(argv[0], "RTP/AVP") || !strcasecmp(argv[0], "RTP/AVP/UDP") || + !strcasecmp(argv[0], "RTP/AVPF/UDP")) { if (n < 3) return -EIO; hc->hc_rtp_multicast = strcasecmp(argv[1], "multicast") == 0; @@ -205,8 +198,7 @@ rtsp_setup_decode( http_client_t *hc, int satip ) } else { return -EIO; } - } - else if (strncmp(argv[i], "server_port=", 12) == 0) { + } else if (strncmp(argv[i], "server_port=", 12) == 0) { j = http_tokenize(argv[i] + 12, argv2, 2, '-'); if (j > 1) { hc->hc_rtcp_server_port = atoi(argv2[1]); @@ -223,11 +215,9 @@ rtsp_setup_decode( http_client_t *hc, int satip ) return HTTP_CON_OK; } -int -rtsp_play_decode( http_client_t *hc ) -{ +int rtsp_play_decode(http_client_t* hc) { char *argv[32], *p; - int n; + int n; if (hc->hc_code != 200) return -EIO; @@ -238,35 +228,43 @@ rtsp_play_decode( http_client_t *hc ) if (n < 1 || strncmp(argv[0], "npt", 3)) return -EIO; hc->hc_rtsp_stream_start = strtoumax(argv[1], NULL, 10); - p = http_arg_get(&hc->hc_args, "Scale"); + p = http_arg_get(&hc->hc_args, "Scale"); if (p == NULL) return -EIO; hc->hc_rtsp_scale = strtof(p, NULL); return 0; } -int -rtsp_setup( http_client_t *hc, - const char *path, const char *query, - const char *multicast_addr, - int rtp_port, int rtcp_port ) -{ +int rtsp_setup(http_client_t* hc, + const char* path, + const char* query, + const char* multicast_addr, + int rtp_port, + int rtcp_port) { http_arg_list_t h; - char transport[256]; + char transport[256]; if (rtcp_port < 0) { - snprintf(transport, sizeof(transport), - "RTP/AVP/TCP;interleaved=%d-%d", rtp_port, rtp_port + 1); + snprintf(transport, sizeof(transport), "RTP/AVP/TCP;interleaved=%d-%d", rtp_port, rtp_port + 1); } else if (multicast_addr) { - snprintf(transport, sizeof(transport), - "RTP/AVP;multicast;destination=%s;ttl=1;client_port=%i-%i", - multicast_addr, rtp_port, rtcp_port); - } else if(hc->hc_rtp_avpf) { - snprintf(transport, sizeof(transport), - "RTP/AVPF/UDP;unicast;client_port=%i-%i", rtp_port, rtcp_port); + snprintf(transport, + sizeof(transport), + "RTP/AVP;multicast;destination=%s;ttl=1;client_port=%i-%i", + multicast_addr, + rtp_port, + rtcp_port); + } else if (hc->hc_rtp_avpf) { + snprintf(transport, + sizeof(transport), + "RTP/AVPF/UDP;unicast;client_port=%i-%i", + rtp_port, + rtcp_port); } else { - snprintf(transport, sizeof(transport), - "RTP/AVP;unicast;client_port=%i-%i", rtp_port, rtcp_port); + snprintf(transport, + sizeof(transport), + "RTP/AVP;unicast;client_port=%i-%i", + rtp_port, + rtcp_port); } http_arg_init(&h); @@ -274,10 +272,10 @@ rtsp_setup( http_client_t *hc, return rtsp_send(hc, RTSP_CMD_SETUP, path, query, &h); } -int rtsp_describe_decode(http_client_t *hc, const char *buf, size_t len) { - const char *p; - char transport[64]; - int n, t, transport_type; +int rtsp_describe_decode(http_client_t* hc, const char* buf, size_t len) { + const char* p; + char transport[64]; + int n, t, transport_type; p = http_arg_get(&hc->hc_args, "Content-Type"); if (p == NULL || strncmp(p, "application/sdp", 15)) { @@ -289,15 +287,16 @@ int rtsp_describe_decode(http_client_t *hc, const char *buf, size_t len) { if (strncmp(p, "a=range", 7) == 0) { // Parse remote timeshift buffer info if (strncmp(p + 8, "npt=", 4) == 0) { - sscanf(p + 8, "npt=%" PRItime_t "-%" PRItime_t, &hc->hc_rtsp_range_start, + sscanf(p + 8, + "npt=%" PRItime_t "-%" PRItime_t, + &hc->hc_rtsp_range_start, &hc->hc_rtsp_range_end); } } if (strncmp(p, "m=video", 7) == 0) { // Parse and select RTP/AVPF stream if available for retransmission support if (sscanf(p, "m=video %d %s %d\n", &t, transport, &transport_type) == 3) { - tvhtrace(LS_RTSP, "describe: found transport: %d %s %d", t, transport, - transport_type); + tvhtrace(LS_RTSP, "describe: found transport: %d %s %d", t, transport, transport_type); if (strncmp(transport, "RTP/AVPF", 8) == 0) { hc->hc_rtp_avpf = 1; } @@ -307,17 +306,15 @@ int rtsp_describe_decode(http_client_t *hc, const char *buf, size_t len) { return HTTP_CON_OK; } -int -rtsp_get_parameter( http_client_t *hc, const char *parameter ) { +int rtsp_get_parameter(http_client_t* hc, const char* parameter) { http_arg_list_t hdr; http_arg_init(&hdr); http_arg_set(&hdr, "Content-Type", "text/parameters"); return rtsp_send_ext(hc, RTSP_CMD_GET_PARAMETER, NULL, NULL, &hdr, parameter, strlen(parameter)); } -int -rtsp_set_speed( http_client_t *hc, float speed ) { - char buf[64]; +int rtsp_set_speed(http_client_t* hc, float speed) { + char buf[64]; http_arg_list_t h; http_arg_init(&h); snprintf(buf, sizeof(buf), "%.2f", speed); @@ -325,9 +322,8 @@ rtsp_set_speed( http_client_t *hc, float speed ) { return rtsp_send(hc, RTSP_CMD_PLAY, NULL, NULL, &h); } -int -rtsp_set_position( http_client_t *hc, time_t position ) { - char buf[64]; +int rtsp_set_position(http_client_t* hc, time_t position) { + char buf[64]; http_arg_list_t h; http_arg_init(&h); snprintf(buf, sizeof(buf), "npt=%" PRItime_t "-", position); diff --git a/src/satip/rtp.c b/src/satip/rtp.c index a66eea01b..29fb97511 100644 --- a/src/satip/rtp.c +++ b/src/satip/rtp.c @@ -31,65 +31,63 @@ #define COMPAT_IPTOS #include "compat.h" -#define RTP_PACKETS 128 -#define RTP_PAYLOAD (7*188+12) -#define RTP_TCP_MIN_PAYLOAD (7*188+12+4) /* fit ethernet packet */ -#define RTP_TCP_MAX_PAYLOAD (348*188+12+4) /* cca 64kB */ -#define RTCP_PAYLOAD (1420) +#define RTP_PACKETS 128 +#define RTP_PAYLOAD (7 * 188 + 12) +#define RTP_TCP_MIN_PAYLOAD (7 * 188 + 12 + 4) /* fit ethernet packet */ +#define RTP_TCP_MAX_PAYLOAD (348 * 188 + 12 + 4) /* cca 64kB */ +#define RTCP_PAYLOAD (1420) -#define RTP_TCP_BUFFER_SIZE (64*1024*1024) +#define RTP_TCP_BUFFER_SIZE (64 * 1024 * 1024) #define RTP_TCP_BUFFER_ROOM (2048) typedef struct satip_rtp_table { TAILQ_ENTRY(satip_rtp_table) link; mpegts_psi_table_t tbl; - int pid; - int remove_mark; + int pid; + int remove_mark; } satip_rtp_table_t; typedef struct satip_rtp_session { TAILQ_ENTRY(satip_rtp_session) link; - pthread_t tid; + pthread_t tid; struct sockaddr_storage peer; struct sockaddr_storage peer2; - int port; - th_subscription_t *subs; - streaming_queue_t *sq; - int fd_rtp; - int fd_rtcp; - int frontend; - int source; - int allow_data; - int disable_rtcp; - dvb_mux_conf_t dmc; - mpegts_apids_t pids; + int port; + th_subscription_t* subs; + streaming_queue_t* sq; + int fd_rtp; + int fd_rtcp; + int frontend; + int source; + int allow_data; + int disable_rtcp; + dvb_mux_conf_t dmc; + mpegts_apids_t pids; TAILQ_HEAD(, satip_rtp_table) pmt_tables; - udp_multisend_t um; - struct iovec *um_iovec; - struct iovec tcp_data; - uint32_t tcp_payload; - uint32_t tcp_buffer_size; - int um_packet; - uint16_t seq; - signal_status_t sig; - int sig_lock; - tvh_mutex_t lock; - http_connection_t *hc; - sbuf_t table_data; - void (*no_data_cb)(void *opaque); - void *no_data_opaque; + udp_multisend_t um; + struct iovec* um_iovec; + struct iovec tcp_data; + uint32_t tcp_payload; + uint32_t tcp_buffer_size; + int um_packet; + uint16_t seq; + signal_status_t sig; + int sig_lock; + tvh_mutex_t lock; + http_connection_t* hc; + sbuf_t table_data; + void (*no_data_cb)(void* opaque); + void* no_data_opaque; } satip_rtp_session_t; static tvh_mutex_t satip_rtp_lock; -static pthread_t satip_rtcp_tid; -static int satip_rtcp_run; +static pthread_t satip_rtcp_tid; +static int satip_rtcp_run; static TAILQ_HEAD(, satip_rtp_session) satip_rtp_sessions; -static void -satip_rtp_pmt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) -{ - satip_rtp_session_t *rtp; - uint8_t out[1024], *ob; +static void satip_rtp_pmt_cb(mpegts_psi_table_t* mt, const uint8_t* buf, int len) { + satip_rtp_session_t* rtp; + uint8_t out[1024], *ob; // uint16_t sid, pid; int l, ol; @@ -103,21 +101,21 @@ satip_rtp_pmt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) if (l > len - 9) return; - rtp = (satip_rtp_session_t *)mt->mt_opaque; + rtp = (satip_rtp_session_t*)mt->mt_opaque; memcpy(out + ol, buf, 9); - ol += 9; /* skip common descriptors */ + ol += 9; /* skip common descriptors */ buf += 9 + l; len -= 9 + l; /* no common descriptors */ - out[7+3] &= 0xf0; - out[8+3] = 0; + out[7 + 3] &= 0xf0; + out[8 + 3] = 0; while (len >= 5) { - //pid = (buf[1] & 0x1f) << 8 | buf[2]; - l = (buf[3] & 0xf) << 8 | buf[4]; + // pid = (buf[1] & 0x1f) << 8 | buf[2]; + l = (buf[3] & 0xf) << 8 | buf[4]; if (l > len - 5) return; @@ -146,35 +144,31 @@ satip_rtp_pmt_cb(mpegts_psi_table_t *mt, const uint8_t *buf, int len) } } -static void -satip_rtp_header(satip_rtp_session_t *rtp, struct iovec *v, uint32_t off) -{ - uint8_t *data = v->iov_base; +static void satip_rtp_header(satip_rtp_session_t* rtp, struct iovec* v, uint32_t off) { + uint8_t* data = v->iov_base; uint32_t tstamp = mono2sec(mclk()) + rtp->seq; rtp->seq++; - v->iov_len = off + 12; - data[off+0] = 0x80; - data[off+1] = 33; - data[off+2] = (rtp->seq >> 8) & 0xff; - data[off+3] = rtp->seq & 0xff; - data[off+4] = (tstamp >> 24) & 0xff; - data[off+5] = (tstamp >> 16) & 0xff; - data[off+6] = (tstamp >> 8) & 0xff; - data[off+7] = tstamp & 0xff; + v->iov_len = off + 12; + data[off + 0] = 0x80; + data[off + 1] = 33; + data[off + 2] = (rtp->seq >> 8) & 0xff; + data[off + 3] = rtp->seq & 0xff; + data[off + 4] = (tstamp >> 24) & 0xff; + data[off + 5] = (tstamp >> 16) & 0xff; + data[off + 6] = (tstamp >> 8) & 0xff; + data[off + 7] = tstamp & 0xff; memset(data + off + 8, 0xa5, 4); } -static int -satip_rtp_send(satip_rtp_session_t *rtp) -{ +static int satip_rtp_send(satip_rtp_session_t* rtp) { struct iovec *v = rtp->um_iovec, *v2; - int packets, copy, len, r; + int packets, copy, len, r; if (v->iov_len == RTP_PAYLOAD) { packets = rtp->um_packet; - v2 = v + packets; - copy = 1; + v2 = v + packets; + copy = 1; if (v2->iov_len == RTP_PAYLOAD) { packets++; copy = 0; @@ -211,10 +205,9 @@ satip_rtp_send(satip_rtp_session_t *rtp) } static inline int -satip_rtp_append_data(satip_rtp_session_t *rtp, struct iovec **_v, uint8_t *data) -{ - struct iovec *v = *_v; - int r; +satip_rtp_append_data(satip_rtp_session_t* rtp, struct iovec** _v, uint8_t* data) { + struct iovec* v = *_v; + int r; assert(v->iov_len + 188 <= RTP_PAYLOAD); memcpy(v->iov_base + v->iov_len, data, 188); v->iov_len += 188; @@ -234,26 +227,26 @@ satip_rtp_append_data(satip_rtp_session_t *rtp, struct iovec **_v, uint8_t *data return 0; } -static int -satip_rtp_loop(satip_rtp_session_t *rtp, uint8_t *data, int len) -{ - int i, j, pid, last_pid = -1, r; - mpegts_apid_t *pids = rtp->pids.pids; - struct iovec *v = rtp->um_iovec + rtp->um_packet; - satip_rtp_table_t *tbl; +static int satip_rtp_loop(satip_rtp_session_t* rtp, uint8_t* data, int len) { + int i, j, pid, last_pid = -1, r; + mpegts_apid_t* pids = rtp->pids.pids; + struct iovec* v = rtp->um_iovec + rtp->um_packet; + satip_rtp_table_t* tbl; assert((len % 188) == 0); - for ( ; len >= 188 ; data += 188, len -= 188) { + for (; len >= 188; data += 188, len -= 188) { pid = ((data[1] & 0x1f) << 8) | data[2]; if (pid != last_pid && !rtp->pids.all) { for (i = 0; i < rtp->pids.count; i++) { j = pids[i].pid; - if (pid < j) break; - if (j == pid) goto found; + if (pid < j) + break; + if (j == pid) + goto found; } continue; -found: - TAILQ_FOREACH(tbl, &rtp->pmt_tables, link) + found: + TAILQ_FOREACH (tbl, &rtp->pmt_tables, link) if (tbl->pid == pid) { dvb_table_parse(&tbl->tbl, "-", data, 188, 1, 0, satip_rtp_pmt_cb); if (rtp->table_data.sb_ptr > 0) { @@ -262,7 +255,7 @@ found: if (r) break; } - sbuf_reset(&rtp->table_data, 10*188); + sbuf_reset(&rtp->table_data, 10 * 188); if (r) return r; } @@ -279,10 +272,11 @@ found: return 0; } -static int -satip_rtp_tcp_data(satip_rtp_session_t *rtp, uint8_t stream, - uint8_t *data, size_t data_len, int may_discard) -{ +static int satip_rtp_tcp_data(satip_rtp_session_t* rtp, + uint8_t stream, + uint8_t* data, + size_t data_len, + int may_discard) { assert(data_len <= 0xffff); data[0] = '$'; data[1] = stream; @@ -291,26 +285,22 @@ satip_rtp_tcp_data(satip_rtp_session_t *rtp, uint8_t stream, return http_extra_send_prealloc(rtp->hc, data, data_len, may_discard); } -static inline int -satip_rtp_flush_tcp_data(satip_rtp_session_t *rtp) -{ - struct iovec *v = &rtp->tcp_data; - int r = 0; +static inline int satip_rtp_flush_tcp_data(satip_rtp_session_t* rtp) { + struct iovec* v = &rtp->tcp_data; + int r = 0; if (v->iov_len) r = satip_rtp_tcp_data(rtp, 0, v->iov_base, v->iov_len, 1); else free(v->iov_base); v->iov_base = NULL; - v->iov_len = 0; + v->iov_len = 0; return r; } -static inline int -satip_rtp_append_tcp_data(satip_rtp_session_t *rtp, uint8_t *data, size_t len) -{ - struct iovec *v = &rtp->tcp_data; - int r = 0; +static inline int satip_rtp_append_tcp_data(satip_rtp_session_t* rtp, uint8_t* data, size_t len) { + struct iovec* v = &rtp->tcp_data; + int r = 0; if (v->iov_base == NULL) { v->iov_base = malloc(rtp->tcp_payload); @@ -324,30 +314,30 @@ satip_rtp_append_tcp_data(satip_rtp_session_t *rtp, uint8_t *data, size_t len) return r; } -static int -satip_rtp_tcp_loop(satip_rtp_session_t *rtp, uint8_t *data, int len) -{ - int i, j, pid, last_pid = -1, r; - mpegts_apid_t *pids = rtp->pids.pids; - satip_rtp_table_t *tbl; +static int satip_rtp_tcp_loop(satip_rtp_session_t* rtp, uint8_t* data, int len) { + int i, j, pid, last_pid = -1, r; + mpegts_apid_t* pids = rtp->pids.pids; + satip_rtp_table_t* tbl; assert((len % 188) == 0); - for ( ; len >= 188 ; data += 188, len -= 188) { + for (; len >= 188; data += 188, len -= 188) { pid = ((data[1] & 0x1f) << 8) | data[2]; if (pid != last_pid && !rtp->pids.all) { for (i = 0; i < rtp->pids.count; i++) { j = pids[i].pid; - if (pid < j) break; - if (j == pid) goto found; + if (pid < j) + break; + if (j == pid) + goto found; } continue; -found: - TAILQ_FOREACH(tbl, &rtp->pmt_tables, link) + found: + TAILQ_FOREACH (tbl, &rtp->pmt_tables, link) if (tbl->pid == pid) { dvb_table_parse(&tbl->tbl, "-", data, 188, 1, 0, satip_rtp_pmt_cb); if (rtp->table_data.sb_ptr) { r = satip_rtp_append_tcp_data(rtp, rtp->table_data.sb_data, rtp->table_data.sb_ptr); - sbuf_reset(&rtp->table_data, 10*188); + sbuf_reset(&rtp->table_data, 10 * 188); if (r) return -1; } @@ -364,29 +354,27 @@ found: return 0; } -static void -satip_rtp_signal_status(satip_rtp_session_t *rtp, signal_status_t *sig) -{ +static void satip_rtp_signal_status(satip_rtp_session_t* rtp, signal_status_t* sig) { tvh_mutex_lock(&rtp->lock); rtp->sig = *sig; tvh_mutex_unlock(&rtp->lock); } -static void * -satip_rtp_thread(void *aux) -{ - satip_rtp_session_t *rtp = aux; - streaming_queue_t *sq = rtp->sq; - streaming_message_t *sm; - th_subscription_t *subs = rtp->subs; - pktbuf_t *pb; - char peername[50]; - int alive = 1, fatal = 0, r; - int tcp = rtp->port == RTSP_TCP_DATA; +static void* satip_rtp_thread(void* aux) { + satip_rtp_session_t* rtp = aux; + streaming_queue_t* sq = rtp->sq; + streaming_message_t* sm; + th_subscription_t* subs = rtp->subs; + pktbuf_t* pb; + char peername[50]; + int alive = 1, fatal = 0, r; + int tcp = rtp->port == RTSP_TCP_DATA; tcp_get_str_from_ip(&rtp->peer, peername, sizeof(peername)); - tvhdebug(LS_SATIPS, "RTP streaming to %s:%d open", peername, - tcp ? ntohs(IP_PORT(rtp->peer)) : rtp->port); + tvhdebug(LS_SATIPS, + "RTP streaming to %s:%d open", + peername, + tcp ? ntohs(IP_PORT(rtp->peer)) : rtp->port); tvh_mutex_lock(&sq->sq_mutex); while (rtp->sq && !fatal) { @@ -408,43 +396,44 @@ satip_rtp_thread(void *aux) tvh_mutex_unlock(&sq->sq_mutex); switch (sm->sm_type) { - case SMT_MPEGTS: - pb = sm->sm_data; - r = pktbuf_len(pb); - subscription_add_bytes_out(subs, r); - if (r > 0) - atomic_set(&rtp->sig_lock, 1); - if (atomic_get(&rtp->allow_data)) { - tvh_mutex_lock(&rtp->lock); - if (tcp) - r = satip_rtp_tcp_loop(rtp, pktbuf_ptr(pb), r); - else - r = satip_rtp_loop(rtp, pktbuf_ptr(pb), r); - tvh_mutex_unlock(&rtp->lock); - if (r) fatal = 1; - } - break; - case SMT_SIGNAL_STATUS: - satip_rtp_signal_status(rtp, sm->sm_data); - break; - case SMT_NOSTART: - case SMT_EXIT: - if (rtp->no_data_cb) - rtp->no_data_cb(rtp->no_data_opaque); - alive = 0; - break; + case SMT_MPEGTS: + pb = sm->sm_data; + r = pktbuf_len(pb); + subscription_add_bytes_out(subs, r); + if (r > 0) + atomic_set(&rtp->sig_lock, 1); + if (atomic_get(&rtp->allow_data)) { + tvh_mutex_lock(&rtp->lock); + if (tcp) + r = satip_rtp_tcp_loop(rtp, pktbuf_ptr(pb), r); + else + r = satip_rtp_loop(rtp, pktbuf_ptr(pb), r); + tvh_mutex_unlock(&rtp->lock); + if (r) + fatal = 1; + } + break; + case SMT_SIGNAL_STATUS: + satip_rtp_signal_status(rtp, sm->sm_data); + break; + case SMT_NOSTART: + case SMT_EXIT: + if (rtp->no_data_cb) + rtp->no_data_cb(rtp->no_data_opaque); + alive = 0; + break; - case SMT_START: - case SMT_STOP: - case SMT_NOSTART_WARN: - case SMT_PACKET: - case SMT_GRACE: - case SMT_SKIP: - case SMT_SPEED: - case SMT_SERVICE_STATUS: - case SMT_TIMESHIFT_STATUS: - case SMT_DESCRAMBLE_INFO: - break; + case SMT_START: + case SMT_STOP: + case SMT_NOSTART_WARN: + case SMT_PACKET: + case SMT_GRACE: + case SMT_SKIP: + case SMT_SPEED: + case SMT_SERVICE_STATUS: + case SMT_TIMESHIFT_STATUS: + case SMT_DESCRAMBLE_INFO: + break; } streaming_msg_free(sm); @@ -452,11 +441,12 @@ satip_rtp_thread(void *aux) } tvh_mutex_unlock(&sq->sq_mutex); - tvhdebug(LS_SATIPS, "RTP streaming to %s:%d closed (%s request)%s", - peername, - tcp ? ntohs(IP_PORT(rtp->peer)) : rtp->port, - alive ? "remote" : "streaming", - fatal ? " (fatal)" : ""); + tvhdebug(LS_SATIPS, + "RTP streaming to %s:%d closed (%s request)%s", + peername, + tcp ? ntohs(IP_PORT(rtp->peer)) : rtp->port, + alive ? "remote" : "streaming", + fatal ? " (fatal)" : ""); return NULL; } @@ -464,39 +454,44 @@ satip_rtp_thread(void *aux) /* * */ -void *satip_rtp_queue(th_subscription_t *subs, - streaming_queue_t *sq, - http_connection_t *hc, - struct sockaddr_storage *peer, int port, - int fd_rtp, int fd_rtcp, - int frontend, int source, dvb_mux_conf_t *dmc, - mpegts_apids_t *pids, int allow_data, int perm_lock, - void (*no_data_cb)(void *opaque), - void *no_data_opaque) -{ - satip_rtp_session_t *rtp = calloc(1, sizeof(*rtp)); - size_t len; - socklen_t socklen; - int dscp, payload; +void* satip_rtp_queue(th_subscription_t* subs, + streaming_queue_t* sq, + http_connection_t* hc, + struct sockaddr_storage* peer, + int port, + int fd_rtp, + int fd_rtcp, + int frontend, + int source, + dvb_mux_conf_t* dmc, + mpegts_apids_t* pids, + int allow_data, + int perm_lock, + void (*no_data_cb)(void* opaque), + void* no_data_opaque) { + satip_rtp_session_t* rtp = calloc(1, sizeof(*rtp)); + size_t len; + socklen_t socklen; + int dscp, payload; if (rtp == NULL) return NULL; - rtp->peer = *peer; + rtp->peer = *peer; rtp->peer2 = *peer; if (port != RTSP_TCP_DATA) IP_PORT_SET(rtp->peer2, htons(port + 1)); - rtp->port = port; - rtp->fd_rtp = fd_rtp; - rtp->fd_rtcp = fd_rtcp; - rtp->subs = subs; - rtp->sq = sq; - rtp->hc = hc; - payload = satip_server_conf.satip_rtptcpsize * 188 + 12 + 4; - rtp->tcp_payload = MINMAX(payload, RTP_TCP_MIN_PAYLOAD, RTP_TCP_MAX_PAYLOAD); - rtp->tcp_buffer_size = 16*1024*1024; - rtp->no_data_cb = no_data_cb; - rtp->no_data_opaque = no_data_opaque; + rtp->port = port; + rtp->fd_rtp = fd_rtp; + rtp->fd_rtcp = fd_rtcp; + rtp->subs = subs; + rtp->sq = sq; + rtp->hc = hc; + payload = satip_server_conf.satip_rtptcpsize * 188 + 12 + 4; + rtp->tcp_payload = MINMAX(payload, RTP_TCP_MIN_PAYLOAD, RTP_TCP_MAX_PAYLOAD); + rtp->tcp_buffer_size = 16 * 1024 * 1024; + rtp->no_data_cb = no_data_cb; + rtp->no_data_opaque = no_data_opaque; atomic_set(&rtp->allow_data, allow_data); mpegts_pid_init(&rtp->pids); mpegts_pid_copy(&rtp->pids, pids); @@ -522,8 +517,8 @@ void *satip_rtp_queue(th_subscription_t *subs, } } rtp->frontend = frontend; - rtp->dmc = *dmc; - rtp->source = source; + rtp->dmc = *dmc; + rtp->source = source; tvh_mutex_init(&rtp->lock, NULL); dscp = config.dscp >= 0 ? config.dscp : IPTOS_DSCP_EF; @@ -532,11 +527,11 @@ void *satip_rtp_queue(th_subscription_t *subs, socket_set_dscp(rtp->fd_rtcp, dscp, NULL, 0); if (perm_lock) { - int tmp = ((satip_server_conf.satip_iptv_sig_level * 0xffff) + 0x8000) / 245; + int tmp = ((satip_server_conf.satip_iptv_sig_level * 0xffff) + 0x8000) / 245; rtp->sig.signal_scale = SIGNAL_STATUS_SCALE_RELATIVE; - rtp->sig.signal = MINMAX(tmp, 0, 0xffff); - rtp->sig.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE; - rtp->sig.snr = MAX(0xffff, (rtp->sig.signal * 3) / 2); + rtp->sig.signal = MINMAX(tmp, 0, 0xffff); + rtp->sig.snr_scale = SIGNAL_STATUS_SCALE_RELATIVE; + rtp->sig.snr = MAX(0xffff, (rtp->sig.signal * 3) / 2); } tvhtrace(LS_SATIPS, "rtp queue %p", rtp); @@ -548,9 +543,8 @@ void *satip_rtp_queue(th_subscription_t *subs, return rtp; } -void satip_rtp_allow_data(void *_rtp) -{ - satip_rtp_session_t *rtp = _rtp; +void satip_rtp_allow_data(void* _rtp) { + satip_rtp_session_t* rtp = _rtp; if (rtp == NULL) return; @@ -559,9 +553,8 @@ void satip_rtp_allow_data(void *_rtp) tvh_mutex_unlock(&satip_rtp_lock); } -void satip_rtp_update_pids(void *_rtp, mpegts_apids_t *pids) -{ - satip_rtp_session_t *rtp = _rtp; +void satip_rtp_update_pids(void* _rtp, mpegts_apids_t* pids) { + satip_rtp_session_t* rtp = _rtp; if (rtp == NULL) return; @@ -572,33 +565,37 @@ void satip_rtp_update_pids(void *_rtp, mpegts_apids_t *pids) tvh_mutex_unlock(&satip_rtp_lock); } -void satip_rtp_update_pmt_pids(void *_rtp, mpegts_apids_t *pmt_pids) -{ - satip_rtp_session_t *rtp = _rtp; - satip_rtp_table_t *tbl, *tbl_next; - int i, pid; +void satip_rtp_update_pmt_pids(void* _rtp, mpegts_apids_t* pmt_pids) { + satip_rtp_session_t* rtp = _rtp; + satip_rtp_table_t * tbl, *tbl_next; + int i, pid; if (rtp == NULL) return; tvh_mutex_lock(&satip_rtp_lock); tvh_mutex_lock(&rtp->lock); - TAILQ_FOREACH(tbl, &rtp->pmt_tables, link) + TAILQ_FOREACH (tbl, &rtp->pmt_tables, link) if (!mpegts_pid_rexists(pmt_pids, tbl->pid)) tbl->remove_mark = 1; for (i = 0; i < pmt_pids->count; i++) { pid = pmt_pids->pids[i].pid; - TAILQ_FOREACH(tbl, &rtp->pmt_tables, link) + TAILQ_FOREACH (tbl, &rtp->pmt_tables, link) if (tbl->pid == pid) break; if (!tbl) { tbl = calloc(1, sizeof(*tbl)); - dvb_table_parse_init(&tbl->tbl, "satip-pmt", LS_TBL_SATIP, pid, - DVB_PMT_BASE, DVB_PMT_MASK, rtp); + dvb_table_parse_init(&tbl->tbl, + "satip-pmt", + LS_TBL_SATIP, + pid, + DVB_PMT_BASE, + DVB_PMT_MASK, + rtp); tbl->pid = pid; TAILQ_INSERT_TAIL(&rtp->pmt_tables, tbl, link); } } - for (tbl = TAILQ_FIRST(&rtp->pmt_tables); tbl; tbl = tbl_next){ + for (tbl = TAILQ_FIRST(&rtp->pmt_tables); tbl; tbl = tbl_next) { tbl_next = TAILQ_NEXT(tbl, link); if (tbl->remove_mark) { TAILQ_REMOVE(&rtp->pmt_tables, tbl, link); @@ -609,11 +606,10 @@ void satip_rtp_update_pmt_pids(void *_rtp, mpegts_apids_t *pmt_pids) tvh_mutex_unlock(&satip_rtp_lock); } -void satip_rtp_close(void *_rtp) -{ - satip_rtp_session_t *rtp = _rtp; - satip_rtp_table_t *tbl; - streaming_queue_t *sq; +void satip_rtp_close(void* _rtp) { + satip_rtp_session_t* rtp = _rtp; + satip_rtp_table_t* tbl; + streaming_queue_t* sq; if (rtp == NULL) return; @@ -646,34 +642,30 @@ void satip_rtp_close(void *_rtp) /* * */ -static const char * -satip_rtcp_pol(int pol) -{ +static const char* satip_rtcp_pol(int pol) { switch (pol) { - case DVB_POLARISATION_HORIZONTAL: - return "h"; - case DVB_POLARISATION_VERTICAL: - return "v"; - case DVB_POLARISATION_CIRCULAR_LEFT: - return "l"; - case DVB_POLARISATION_CIRCULAR_RIGHT: - return "r"; - case DVB_POLARISATION_OFF: - return "off"; - default: - return ""; + case DVB_POLARISATION_HORIZONTAL: + return "h"; + case DVB_POLARISATION_VERTICAL: + return "v"; + case DVB_POLARISATION_CIRCULAR_LEFT: + return "l"; + case DVB_POLARISATION_CIRCULAR_RIGHT: + return "r"; + case DVB_POLARISATION_OFF: + return "off"; + default: + return ""; } } /* * */ -static const char * -satip_rtcp_fec(int fec) -{ +static const char* satip_rtcp_fec(int fec) { static char buf[16]; - char *p = buf; - const char *s; + char* p = buf; + const char* s; if (fec == DVB_FEC_AUTO || fec == DVB_FEC_NONE) return ""; @@ -683,7 +675,7 @@ satip_rtcp_fec(int fec) strlcpy(buf, s, sizeof(buf)); p = strchr(buf, '/'); while (p && *p) { - *p = *(p+1); + *p = *(p + 1); p++; } return buf; @@ -692,160 +684,278 @@ satip_rtcp_fec(int fec) /* * */ -static int -satip_status_build(satip_rtp_session_t *rtp, char *buf, int len) -{ - char pids[1400]; +static int satip_status_build(satip_rtp_session_t* rtp, char* buf, int len) { + char pids[1400]; const char *delsys, *msys, *pilot, *rolloff; const char *bw, *tmode, *gi, *plp, *t2id, *sm, *c2tft, *ds, *specinv; - int r, level = 0, lock = 0, quality = 0; + int r, level = 0, lock = 0, quality = 0; lock = atomic_get(&rtp->sig_lock); if (satip_server_conf.satip_force_sig_level > 0) { - level = MINMAX(satip_server_conf.satip_force_sig_level, 1, 240); + level = MINMAX(satip_server_conf.satip_force_sig_level, 1, 240); quality = MAX((level + 15) / 15, 15); } else { switch (rtp->sig.signal_scale) { - case SIGNAL_STATUS_SCALE_RELATIVE: - level = MINMAX((rtp->sig.signal * 245) / 0xffff, 0, 240); - break; - case SIGNAL_STATUS_SCALE_DECIBEL: - level = MINMAX((rtp->sig.signal + 90000) / 375, 0, 240); - break; - default: - level = lock ? 120 : 0; - break; + case SIGNAL_STATUS_SCALE_RELATIVE: + level = MINMAX((rtp->sig.signal * 245) / 0xffff, 0, 240); + break; + case SIGNAL_STATUS_SCALE_DECIBEL: + level = MINMAX((rtp->sig.signal + 90000) / 375, 0, 240); + break; + default: + level = lock ? 120 : 0; + break; } switch (rtp->sig.snr_scale) { - case SIGNAL_STATUS_SCALE_RELATIVE: - quality = MINMAX((rtp->sig.snr * 16) / 0xffff, 0, 15); - break; - case SIGNAL_STATUS_SCALE_DECIBEL: - quality = MINMAX(rtp->sig.snr / 2000, 0, 15); - break; - default: - quality = lock ? 10 : 0; - break; + case SIGNAL_STATUS_SCALE_RELATIVE: + quality = MINMAX((rtp->sig.snr * 16) / 0xffff, 0, 15); + break; + case SIGNAL_STATUS_SCALE_DECIBEL: + quality = MINMAX(rtp->sig.snr / 2000, 0, 15); + break; + default: + quality = lock ? 10 : 0; + break; } } mpegts_pid_dump(&rtp->pids, pids, sizeof(pids), 0, 0); switch (rtp->dmc.dmc_fe_delsys) { - case DVB_SYS_DVBS: - case DVB_SYS_DVBS2: - delsys = rtp->dmc.dmc_fe_delsys == DVB_SYS_DVBS ? "dvbs" : "dvbs2"; - switch (rtp->dmc.dmc_fe_modulation) { - case DVB_MOD_QPSK: msys = "qpsk"; break; - case DVB_MOD_PSK_8: msys = "8psk"; break; - default: msys = ""; break; - } - switch (rtp->dmc.dmc_fe_pilot) { - case DVB_PILOT_ON: pilot = "on"; break; - case DVB_PILOT_OFF: pilot = "off"; break; - default: pilot = ""; break; - } - switch (rtp->dmc.dmc_fe_rolloff) { - case DVB_ROLLOFF_20: rolloff = "20"; break; - case DVB_ROLLOFF_25: rolloff = "25"; break; - case DVB_ROLLOFF_35: rolloff = "35"; break; - default: rolloff = ""; break; - } - /* ver=.;src=;tuner=,,,,,,\ - * ,,,,,;pids=,..., - */ - r = snprintf(buf, len, - "ver=1.0;src=%d;tuner=%d,%d,%d,%d,%.f,%s,%s,%s,%s,%s,%.f,%s;pids=%s", - rtp->source, rtp->frontend, level, lock, quality, - (float)rtp->dmc.dmc_fe_freq / 1000.0, - satip_rtcp_pol(rtp->dmc.u.dmc_fe_qpsk.polarisation), - delsys, msys, pilot, rolloff, - (float)rtp->dmc.u.dmc_fe_qpsk.symbol_rate / 1000.0, - satip_rtcp_fec(rtp->dmc.u.dmc_fe_qpsk.fec_inner), - pids); - break; - case DVB_SYS_DVBT: - case DVB_SYS_DVBT2: - delsys = rtp->dmc.dmc_fe_delsys == DVB_SYS_DVBT ? "dvbt" : "dvbt2"; - switch (rtp->dmc.u.dmc_fe_ofdm.bandwidth) { - case DVB_BANDWIDTH_1_712_MHZ: bw = "1.712"; break; - case DVB_BANDWIDTH_5_MHZ: bw = "5"; break; - case DVB_BANDWIDTH_6_MHZ: bw = "6"; break; - case DVB_BANDWIDTH_7_MHZ: bw = "7"; break; - case DVB_BANDWIDTH_8_MHZ: bw = "8"; break; - case DVB_BANDWIDTH_10_MHZ: bw = "10"; break; - default: bw = ""; break; - } - switch (rtp->dmc.u.dmc_fe_ofdm.transmission_mode) { - case DVB_TRANSMISSION_MODE_1K: tmode = "1k"; break; - case DVB_TRANSMISSION_MODE_2K: tmode = "2k"; break; - case DVB_TRANSMISSION_MODE_4K: tmode = "4k"; break; - case DVB_TRANSMISSION_MODE_8K: tmode = "8k"; break; - case DVB_TRANSMISSION_MODE_16K: tmode = "16k"; break; - case DVB_TRANSMISSION_MODE_32K: tmode = "32k"; break; - default: tmode = ""; break; - } - switch (rtp->dmc.dmc_fe_modulation) { - case DVB_MOD_QAM_16: msys = "qam16"; break; - case DVB_MOD_QAM_32: msys = "qam32"; break; - case DVB_MOD_QAM_64: msys = "qam64"; break; - case DVB_MOD_QAM_128: msys = "qam128"; break; - default: msys = ""; break; - } - switch (rtp->dmc.u.dmc_fe_ofdm.guard_interval) { - case DVB_GUARD_INTERVAL_1_4: gi = "14"; break; - case DVB_GUARD_INTERVAL_1_8: gi = "18"; break; - case DVB_GUARD_INTERVAL_1_16: gi = "116"; break; - case DVB_GUARD_INTERVAL_1_32: gi = "132"; break; - case DVB_GUARD_INTERVAL_1_128: gi = "1128"; break; - case DVB_GUARD_INTERVAL_19_128: gi = "19128"; break; - case DVB_GUARD_INTERVAL_19_256: gi = "19256"; break; - default: gi = ""; break; - } - plp = ""; - t2id = ""; - sm = ""; - /* ver=1.1;tuner=,,,,,,,,,,\ - * ,,,;pids=,..., - */ - r = snprintf(buf, len, - "ver=1.1;tuner=%d,%d,%d,%d,%.f,%s,%s,%s,%s,%s,%s,%s,%s,%s;pids=%s", - rtp->frontend, level, lock, quality, - (float)rtp->dmc.dmc_fe_freq / 1000000.0, - bw, delsys, tmode, msys, gi, - satip_rtcp_fec(rtp->dmc.u.dmc_fe_ofdm.code_rate_HP), - plp, t2id, sm, pids); - break; - case DVB_SYS_DVBC_ANNEX_A: - case DVB_SYS_DVBC_ANNEX_C: - delsys = rtp->dmc.dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_A ? "dvbc" : "dvbc2"; - bw = ""; - switch (rtp->dmc.dmc_fe_modulation) { - case DVB_MOD_QAM_16: msys = "qam16"; break; - case DVB_MOD_QAM_32: msys = "qam32"; break; - case DVB_MOD_QAM_64: msys = "qam64"; break; - case DVB_MOD_QAM_128: msys = "qam128"; break; - default: msys = ""; break; - } - c2tft = ""; - ds = ""; - plp = ""; - specinv = ""; - /* ver=1.2;tuner=,,,,,,,,,,,, - * ;pids=,..., - */ - r = snprintf(buf, len, - "ver=1.1;tuner=%d,%d,%d,%d,%.f,%s,%s,%s,%.f,%s,%s,%s,%s;pids=%s", - rtp->frontend, level, lock, quality, - (float)rtp->dmc.dmc_fe_freq / 1000000.0, - bw, delsys, msys, - (float)rtp->dmc.u.dmc_fe_qam.symbol_rate / 1000.0, - c2tft, ds, plp, specinv, pids); - break; - default: - r = snprintf(buf, len, "ver=1.0;src=%d;tuner=%d,%d,%d,%d,,,,,,,,;pids=%s", - rtp->source, rtp->frontend, level, lock, quality, pids); - break; + case DVB_SYS_DVBS: + case DVB_SYS_DVBS2: + delsys = rtp->dmc.dmc_fe_delsys == DVB_SYS_DVBS ? "dvbs" : "dvbs2"; + switch (rtp->dmc.dmc_fe_modulation) { + case DVB_MOD_QPSK: + msys = "qpsk"; + break; + case DVB_MOD_PSK_8: + msys = "8psk"; + break; + default: + msys = ""; + break; + } + switch (rtp->dmc.dmc_fe_pilot) { + case DVB_PILOT_ON: + pilot = "on"; + break; + case DVB_PILOT_OFF: + pilot = "off"; + break; + default: + pilot = ""; + break; + } + switch (rtp->dmc.dmc_fe_rolloff) { + case DVB_ROLLOFF_20: + rolloff = "20"; + break; + case DVB_ROLLOFF_25: + rolloff = "25"; + break; + case DVB_ROLLOFF_35: + rolloff = "35"; + break; + default: + rolloff = ""; + break; + } + /* ver=.;src=;tuner=,,,,,,\ + * ,,,,,;pids=,..., + */ + r = snprintf(buf, + len, + "ver=1.0;src=%d;tuner=%d,%d,%d,%d,%.f,%s,%s,%s,%s,%s,%.f,%s;pids=%s", + rtp->source, + rtp->frontend, + level, + lock, + quality, + (float)rtp->dmc.dmc_fe_freq / 1000.0, + satip_rtcp_pol(rtp->dmc.u.dmc_fe_qpsk.polarisation), + delsys, + msys, + pilot, + rolloff, + (float)rtp->dmc.u.dmc_fe_qpsk.symbol_rate / 1000.0, + satip_rtcp_fec(rtp->dmc.u.dmc_fe_qpsk.fec_inner), + pids); + break; + case DVB_SYS_DVBT: + case DVB_SYS_DVBT2: + delsys = rtp->dmc.dmc_fe_delsys == DVB_SYS_DVBT ? "dvbt" : "dvbt2"; + switch (rtp->dmc.u.dmc_fe_ofdm.bandwidth) { + case DVB_BANDWIDTH_1_712_MHZ: + bw = "1.712"; + break; + case DVB_BANDWIDTH_5_MHZ: + bw = "5"; + break; + case DVB_BANDWIDTH_6_MHZ: + bw = "6"; + break; + case DVB_BANDWIDTH_7_MHZ: + bw = "7"; + break; + case DVB_BANDWIDTH_8_MHZ: + bw = "8"; + break; + case DVB_BANDWIDTH_10_MHZ: + bw = "10"; + break; + default: + bw = ""; + break; + } + switch (rtp->dmc.u.dmc_fe_ofdm.transmission_mode) { + case DVB_TRANSMISSION_MODE_1K: + tmode = "1k"; + break; + case DVB_TRANSMISSION_MODE_2K: + tmode = "2k"; + break; + case DVB_TRANSMISSION_MODE_4K: + tmode = "4k"; + break; + case DVB_TRANSMISSION_MODE_8K: + tmode = "8k"; + break; + case DVB_TRANSMISSION_MODE_16K: + tmode = "16k"; + break; + case DVB_TRANSMISSION_MODE_32K: + tmode = "32k"; + break; + default: + tmode = ""; + break; + } + switch (rtp->dmc.dmc_fe_modulation) { + case DVB_MOD_QAM_16: + msys = "qam16"; + break; + case DVB_MOD_QAM_32: + msys = "qam32"; + break; + case DVB_MOD_QAM_64: + msys = "qam64"; + break; + case DVB_MOD_QAM_128: + msys = "qam128"; + break; + default: + msys = ""; + break; + } + switch (rtp->dmc.u.dmc_fe_ofdm.guard_interval) { + case DVB_GUARD_INTERVAL_1_4: + gi = "14"; + break; + case DVB_GUARD_INTERVAL_1_8: + gi = "18"; + break; + case DVB_GUARD_INTERVAL_1_16: + gi = "116"; + break; + case DVB_GUARD_INTERVAL_1_32: + gi = "132"; + break; + case DVB_GUARD_INTERVAL_1_128: + gi = "1128"; + break; + case DVB_GUARD_INTERVAL_19_128: + gi = "19128"; + break; + case DVB_GUARD_INTERVAL_19_256: + gi = "19256"; + break; + default: + gi = ""; + break; + } + plp = ""; + t2id = ""; + sm = ""; + /* ver=1.1;tuner=,,,,,,,,,,\ + * ,,,;pids=,..., + */ + r = snprintf(buf, + len, + "ver=1.1;tuner=%d,%d,%d,%d,%.f,%s,%s,%s,%s,%s,%s,%s,%s,%s;pids=%s", + rtp->frontend, + level, + lock, + quality, + (float)rtp->dmc.dmc_fe_freq / 1000000.0, + bw, + delsys, + tmode, + msys, + gi, + satip_rtcp_fec(rtp->dmc.u.dmc_fe_ofdm.code_rate_HP), + plp, + t2id, + sm, + pids); + break; + case DVB_SYS_DVBC_ANNEX_A: + case DVB_SYS_DVBC_ANNEX_C: + delsys = rtp->dmc.dmc_fe_delsys == DVB_SYS_DVBC_ANNEX_A ? "dvbc" : "dvbc2"; + bw = ""; + switch (rtp->dmc.dmc_fe_modulation) { + case DVB_MOD_QAM_16: + msys = "qam16"; + break; + case DVB_MOD_QAM_32: + msys = "qam32"; + break; + case DVB_MOD_QAM_64: + msys = "qam64"; + break; + case DVB_MOD_QAM_128: + msys = "qam128"; + break; + default: + msys = ""; + break; + } + c2tft = ""; + ds = ""; + plp = ""; + specinv = ""; + /* ver=1.2;tuner=,,,,,,,,,,,, + * ;pids=,..., + */ + r = snprintf(buf, + len, + "ver=1.1;tuner=%d,%d,%d,%d,%.f,%s,%s,%s,%.f,%s,%s,%s,%s;pids=%s", + rtp->frontend, + level, + lock, + quality, + (float)rtp->dmc.dmc_fe_freq / 1000000.0, + bw, + delsys, + msys, + (float)rtp->dmc.u.dmc_fe_qam.symbol_rate / 1000.0, + c2tft, + ds, + plp, + specinv, + pids); + break; + default: + r = snprintf(buf, + len, + "ver=1.0;src=%d;tuner=%d,%d,%d,%d,,,,,,,,;pids=%s", + rtp->source, + rtp->frontend, + level, + lock, + quality, + pids); + break; } return r >= len ? len - 1 : r; @@ -854,10 +964,9 @@ satip_status_build(satip_rtp_session_t *rtp, char *buf, int len) /* * */ -int satip_rtp_status(void *_rtp, char *buf, int len) -{ - satip_rtp_session_t *rtp = _rtp; - int r = 0; +int satip_rtp_status(void* _rtp, char* buf, int len) { + satip_rtp_session_t* rtp = _rtp; + int r = 0; buf[0] = '\0'; if (rtp == NULL) @@ -873,11 +982,9 @@ int satip_rtp_status(void *_rtp, char *buf, int len) /* * */ -static int -satip_rtcp_build(satip_rtp_session_t *rtp, uint8_t *msg) -{ +static int satip_rtcp_build(satip_rtp_session_t* rtp, uint8_t* msg) { char buf[1500]; - int len, len2; + int len, len2; tvh_mutex_lock(&rtp->lock); len = satip_status_build(rtp, buf, sizeof(buf)); @@ -891,16 +998,16 @@ satip_rtcp_build(satip_rtp_session_t *rtp, uint8_t *msg) memcpy(msg + 16, buf, len); len += 16; - msg[0] = 0x80; - msg[1] = 204; - msg[2] = (((len - 1) / 4) >> 8) & 0xff; - msg[3] = ((len - 1) / 4) & 0xff; - msg[4] = 0; - msg[5] = 0; - msg[6] = 0; - msg[7] = 0; - msg[8] = 'S'; - msg[9] = 'E'; + msg[0] = 0x80; + msg[1] = 204; + msg[2] = (((len - 1) / 4) >> 8) & 0xff; + msg[3] = ((len - 1) / 4) & 0xff; + msg[4] = 0; + msg[5] = 0; + msg[6] = 0; + msg[7] = 0; + msg[8] = 'S'; + msg[9] = 'E'; msg[10] = 'S'; msg[11] = '1'; msg[12] = 0; @@ -914,14 +1021,12 @@ satip_rtcp_build(satip_rtp_session_t *rtp, uint8_t *msg) /* * */ -static void * -satip_rtcp_thread(void *aux) -{ - satip_rtp_session_t *rtp; - int64_t us; - uint8_t msg[RTCP_PAYLOAD+1], *msg1; - char addrbuf[50]; - int r, len, err; +static void* satip_rtcp_thread(void* aux) { + satip_rtp_session_t* rtp; + int64_t us; + uint8_t msg[RTCP_PAYLOAD + 1], *msg1; + char addrbuf[50]; + int r, len, err; tvhtrace(LS_SATIPS, "starting rtcp thread"); while (atomic_get(&satip_rtcp_run)) { @@ -934,37 +1039,49 @@ satip_rtcp_thread(void *aux) goto end; } while (us > 0); tvh_mutex_lock(&satip_rtp_lock); - TAILQ_FOREACH(rtp, &satip_rtp_sessions, link) { - if (rtp->sq == NULL || rtp->disable_rtcp) continue; + TAILQ_FOREACH (rtp, &satip_rtp_sessions, link) { + if (rtp->sq == NULL || rtp->disable_rtcp) + continue; len = satip_rtcp_build(rtp, msg); - if (len <= 0) continue; + if (len <= 0) + continue; if (tvhtrace_enabled()) { msg[len] = '\0'; tcp_get_str_from_ip(&rtp->peer2, addrbuf, sizeof(addrbuf)); - tvhtrace(LS_SATIPS, "RTCP send to %s:%d : %s", addrbuf, ntohs(IP_PORT(rtp->peer2)), msg + 16); + tvhtrace(LS_SATIPS, + "RTCP send to %s:%d : %s", + addrbuf, + ntohs(IP_PORT(rtp->peer2)), + msg + 16); } if (rtp->port == RTSP_TCP_DATA) { msg1 = malloc(len); if (msg1) { memcpy(msg1, msg, len); err = satip_rtp_tcp_data(rtp, 1, msg1, len, 0); - r = err ? -1 : 0; + r = err ? -1 : 0; } else { - r = -1; + r = -1; err = ENOMEM; } } else { - r = sendto(rtp->fd_rtcp, msg, len, 0, - (struct sockaddr*)&rtp->peer2, - rtp->peer2.ss_family == AF_INET6 ? - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); + r = sendto(rtp->fd_rtcp, + msg, + len, + 0, + (struct sockaddr*)&rtp->peer2, + rtp->peer2.ss_family == AF_INET6 ? sizeof(struct sockaddr_in6) + : sizeof(struct sockaddr_in)); err = errno; } if (r < 0) { if (err != ECONNREFUSED) { tcp_get_str_from_ip(&rtp->peer2, addrbuf, sizeof(addrbuf)); - tvhwarn(LS_SATIPS, "RTCP send to error %s:%d : %s", - addrbuf, ntohs(IP_PORT(rtp->peer2)), strerror(err)); + tvhwarn(LS_SATIPS, + "RTCP send to error %s:%d : %s", + addrbuf, + ntohs(IP_PORT(rtp->peer2)), + strerror(err)); } else { rtp->disable_rtcp = 1; } @@ -979,8 +1096,7 @@ end: /* * */ -void satip_rtp_init(int boot) -{ +void satip_rtp_init(int boot) { TAILQ_INIT(&satip_rtp_sessions); tvh_mutex_init(&satip_rtp_lock, NULL); @@ -996,8 +1112,7 @@ void satip_rtp_init(int boot) /* * */ -void satip_rtp_done(void) -{ +void satip_rtp_done(void) { assert(TAILQ_EMPTY(&satip_rtp_sessions)); if (atomic_get(&satip_rtcp_run)) { atomic_set(&satip_rtcp_run, 0); diff --git a/src/satip/rtsp.c b/src/satip/rtsp.c index 98f85724e..a1df9f2ee 100644 --- a/src/satip/rtsp.c +++ b/src/satip/rtsp.c @@ -28,8 +28,8 @@ #include #define RTSP_TIMEOUT 30 -#define RTP_BUFSIZE (256*1024) -#define RTCP_BUFSIZE (16*1024) +#define RTP_BUFSIZE (256 * 1024) +#define RTCP_BUFSIZE (16 * 1024) #define STATE_DESCRIBE 0 #define STATE_SETUP 1 @@ -37,78 +37,75 @@ typedef struct slave_subscription { LIST_ENTRY(slave_subscription) link; - mpegts_service_t *service; - th_subscription_t *ths; - profile_chain_t prch; + mpegts_service_t* service; + th_subscription_t* ths; + profile_chain_t prch; } slave_subscription_t; typedef struct session { TAILQ_ENTRY(session) link; - char *peer_ipstr; - int stream; - int frontend; - int findex; - int src; - int state; - int playing; - int weight; - int used_weight; - http_connection_t *shutdown_on_close; - http_connection_t *tcp_data; - int perm_lock; - int no_data; - uint32_t nsession; - char session[9]; - dvb_mux_conf_t dmc; - dvb_mux_conf_t dmc_tuned; - mpegts_apids_t pids; - mtimer_t timer; - mpegts_mux_t *mux; - int mux_created; - profile_chain_t prch; - th_subscription_t *subs; - int rtp_peer_port; - int rtp_udp_bound; - udp_connection_t *udp_rtp; - udp_connection_t *udp_rtcp; - void *rtp_handle; - http_connection_t *old_hc; + char* peer_ipstr; + int stream; + int frontend; + int findex; + int src; + int state; + int playing; + int weight; + int used_weight; + http_connection_t* shutdown_on_close; + http_connection_t* tcp_data; + int perm_lock; + int no_data; + uint32_t nsession; + char session[9]; + dvb_mux_conf_t dmc; + dvb_mux_conf_t dmc_tuned; + mpegts_apids_t pids; + mtimer_t timer; + mpegts_mux_t* mux; + int mux_created; + profile_chain_t prch; + th_subscription_t* subs; + int rtp_peer_port; + int rtp_udp_bound; + udp_connection_t* udp_rtp; + udp_connection_t* udp_rtcp; + void* rtp_handle; + http_connection_t* old_hc; LIST_HEAD(, slave_subscription) slaves; } session_t; static uint32_t session_number; static uint16_t stream_id; -static char *rtsp_ip = NULL; -static char *rtsp_nat_ip = NULL; -static char *rtp_src_ip = NULL; -static int rtsp_port = -1; -static int rtsp_nat_port = -1; -static int rtsp_descramble = 1; -static int rtsp_rewrite_pmt = 0; -static int rtsp_muxcnf = MUXCNF_AUTO; -static void *rtsp_server = NULL; -static TAILQ_HEAD(,session) rtsp_sessions; +static char* rtsp_ip = NULL; +static char* rtsp_nat_ip = NULL; +static char* rtp_src_ip = NULL; +static int rtsp_port = -1; +static int rtsp_nat_port = -1; +static int rtsp_descramble = 1; +static int rtsp_rewrite_pmt = 0; +static int rtsp_muxcnf = MUXCNF_AUTO; +static void* rtsp_server = NULL; +static TAILQ_HEAD(, session) rtsp_sessions; static tvh_mutex_t rtsp_lock; -static void rtsp_close_session(session_t *rs); -static void rtsp_free_session(session_t *rs); +static void rtsp_close_session(session_t* rs); +static void rtsp_free_session(session_t* rs); /* * */ -static inline int rtsp_is_nat_active(void) -{ +static inline int rtsp_is_nat_active(void) { return rtsp_nat_ip[0] != '\0'; } /* * */ -int -satip_rtsp_delsys(int fe, int *findex, const char **ftype) -{ - const char *t = NULL; - int res, i; +int satip_rtsp_delsys(int fe, int* findex, const char** ftype) { + const char* t = NULL; + int res, i; if (fe < 1) return DVB_SYS_NONE; @@ -116,63 +113,63 @@ satip_rtsp_delsys(int fe, int *findex, const char **ftype) i = satip_server_conf.satip_dvbs; if (fe <= i) { res = DVB_SYS_DVBS; - t = "DVB-S"; + t = "DVB-S"; goto result; } fe -= i; i = satip_server_conf.satip_dvbs2; if (fe <= i) { res = DVB_SYS_DVBS; - t = "DVB-S2"; + t = "DVB-S2"; goto result; } fe -= i; i = satip_server_conf.satip_dvbt; if (fe <= i) { res = DVB_SYS_DVBT; - t = "DVB-T"; + t = "DVB-T"; goto result; } fe -= i; i = satip_server_conf.satip_dvbt2; if (fe <= i) { res = DVB_SYS_DVBT; - t = "DVB-T2"; + t = "DVB-T2"; goto result; } fe -= i; i = satip_server_conf.satip_dvbc; if (fe <= i) { res = DVB_SYS_DVBC_ANNEX_A; - t = "DVB-C"; + t = "DVB-C"; goto result; } fe -= i; i = satip_server_conf.satip_dvbc2; if (fe <= i) { res = DVB_SYS_DVBC_ANNEX_A; - t = "DVB-C2"; + t = "DVB-C2"; goto result; } fe -= i; i = satip_server_conf.satip_atsc_t; if (fe <= i) { res = DVB_SYS_ATSC; - t = "ATSC-T"; + t = "ATSC-T"; goto result; } fe -= i; i = satip_server_conf.satip_atsc_c; if (fe <= i) { res = DVB_SYS_DVBC_ANNEX_B; - t = "ATSC-C"; + t = "ATSC-C"; goto result; } fe -= i; i = satip_server_conf.satip_isdb_t; if (fe <= i) { res = DVB_SYS_ISDBT; - t = "ISDB-T"; + t = "ISDB-T"; goto result; } tvh_mutex_unlock(&global_lock); @@ -188,33 +185,35 @@ result: /* * */ -static struct session * -rtsp_new_session(const char *ipstr, int delsys, uint32_t nsession, int session) -{ - struct session *rs = NULL; - int count_s = satip_server_conf.satip_max_sessions; - int count_u = satip_server_conf.satip_max_user_connections; +static struct session* +rtsp_new_session(const char* ipstr, int delsys, uint32_t nsession, int session) { + struct session* rs = NULL; + int count_s = satip_server_conf.satip_max_sessions; + int count_u = satip_server_conf.satip_max_user_connections; if (count_s > 0 || count_u > 0) - TAILQ_FOREACH(rs, &rtsp_sessions, link) { - if (--count_s == 0) { - tvhnotice(LS_SATIPS, "Max number (%i) of active RTSP sessions reached.", - satip_server_conf.satip_max_sessions); - return NULL; - } - if (strcmp(rs->peer_ipstr, ipstr) == 0 && --count_u == 0) { - tvhnotice(LS_SATIPS, "Max number (%i) of active RTSP sessions per user (IP: %s).", - satip_server_conf.satip_max_user_connections, ipstr); - return NULL; + TAILQ_FOREACH (rs, &rtsp_sessions, link) { + if (--count_s == 0) { + tvhnotice(LS_SATIPS, + "Max number (%i) of active RTSP sessions reached.", + satip_server_conf.satip_max_sessions); + return NULL; + } + if (strcmp(rs->peer_ipstr, ipstr) == 0 && --count_u == 0) { + tvhnotice(LS_SATIPS, + "Max number (%i) of active RTSP sessions per user (IP: %s).", + satip_server_conf.satip_max_user_connections, + ipstr); + return NULL; + } } - } rs = calloc(1, sizeof(*rs)); if (rs == NULL) return NULL; rs->peer_ipstr = strdup(ipstr); - rs->nsession = nsession ?: session_number; + rs->nsession = nsession ?: session_number; snprintf(rs->session, sizeof(rs->session), "%08X", session_number); if (!nsession) { session_number += 9876; @@ -229,16 +228,13 @@ rtsp_new_session(const char *ipstr, int delsys, uint32_t nsession, int session) /* * */ -static struct session * -rtsp_find_session(http_connection_t *hc, int stream) -{ +static struct session* rtsp_find_session(http_connection_t* hc, int stream) { struct session *rs, *first = NULL; if (stream <= 0) return NULL; - TAILQ_FOREACH(rs, &rtsp_sessions, link) { - if (hc->hc_session && - strcmp(rs->session, hc->hc_session) == 0 && + TAILQ_FOREACH (rs, &rtsp_sessions, link) { + if (hc->hc_session && strcmp(rs->session, hc->hc_session) == 0 && strcmp(rs->peer_ipstr, hc->hc_peer_ipstr) == 0) { if (stream == rs->stream) return rs; @@ -254,10 +250,8 @@ rtsp_find_session(http_connection_t *hc, int stream) /* * */ -static void -rtsp_session_timer_cb(void *aux) -{ - session_t *rs = aux; +static void rtsp_session_timer_cb(void* aux) { + session_t* rs = aux; tvhwarn(LS_SATIPS, "-/%s/%i: session closed (timeout)", rs->session, rs->stream); tvh_mutex_unlock(&global_lock); @@ -268,9 +262,7 @@ rtsp_session_timer_cb(void *aux) tvh_mutex_lock(&global_lock); } -static inline void -rtsp_rearm_session_timer(session_t *rs) -{ +static inline void rtsp_rearm_session_timer(session_t* rs) { if (!rs->shutdown_on_close || (rs->rtp_peer_port == RTSP_TCP_DATA)) { tvh_mutex_lock(&global_lock); mtimer_arm_rel(&rs->timer, rtsp_session_timer_cb, rs, sec2mono(RTSP_TIMEOUT)); @@ -281,11 +273,9 @@ rtsp_rearm_session_timer(session_t *rs) /* * */ -static char * -rtsp_check_urlbase(char *u) -{ +static char* rtsp_check_urlbase(char* u) { char *p, *s; - int t; + int t; if (*u == '/' || strncmp(u, "stream=", 7) == 0) return u; @@ -298,7 +288,7 @@ rtsp_check_urlbase(char *u) *p = '\0'; if ((s = strchr(u, ':')) != NULL) { *s = '\0'; - t = atoi(s + 1); + t = atoi(s + 1); if (t != rtsp_port) { if (rtsp_nat_port <= 0 || t != rtsp_nat_port) return NULL; @@ -323,23 +313,22 @@ rtsp_check_urlbase(char *u) /* * */ -static int -rtsp_parse_args(http_connection_t *hc, char *u) -{ - char *s; - int stream = 0; +static int rtsp_parse_args(http_connection_t* hc, char* u) { + char* s; + int stream = 0; if (strncmp(u, "stream=", 7) == 0) { u += 7; - for (s = u; isdigit(*s); s++); + for (s = u; isdigit(*s); s++) + ; if (*s == '\0') return atoi(u); - if (*s != '/' || *(s+1) != '\0') + if (*s != '/' || *(s + 1) != '\0') if (*s != '?') return -1; - *s = '\0'; + *s = '\0'; stream = atoi(u); - u = s + 1; + u = s + 1; } else { if (*u != '?') return -1; @@ -352,11 +341,9 @@ rtsp_parse_args(http_connection_t *hc, char *u) /* * */ -static inline const char * -rtsp_conn_ip(http_connection_t *hc, char *buf, size_t buflen, int *port) -{ - const char *used_ip = rtsp_ip; - int used_port = rtsp_port, local; +static inline const char* rtsp_conn_ip(http_connection_t* hc, char* buf, size_t buflen, int* port) { + const char* used_ip = rtsp_ip; + int used_port = rtsp_port, local; if (!rtsp_is_nat_active()) goto end; @@ -385,12 +372,9 @@ end: /* * */ -static void -rtsp_slave_add - (session_t *rs, mpegts_service_t *master, mpegts_service_t *slave) -{ - char buf[128]; - slave_subscription_t *sub = calloc(1, sizeof(*sub)); +static void rtsp_slave_add(session_t* rs, mpegts_service_t* master, mpegts_service_t* slave) { + char buf[128]; + slave_subscription_t* sub = calloc(1, sizeof(*sub)); tvh_mutex_lock(&master->s_stream_mutex); if (master->s_slaves_pids == NULL) @@ -400,40 +384,55 @@ rtsp_slave_add sub->service = slave; profile_chain_init(&sub->prch, NULL, slave, 0); snprintf(buf, sizeof(buf), "SAT>IP Slave/%s", slave->s_nicename); - sub->ths = subscription_create_from_service(&sub->prch, NULL, rs->used_weight, - buf, SUBSCRIPTION_NONE, NULL, NULL, - buf, NULL); + sub->ths = subscription_create_from_service(&sub->prch, + NULL, + rs->used_weight, + buf, + SUBSCRIPTION_NONE, + NULL, + NULL, + buf, + NULL); if (sub->ths == NULL) { - tvherror(LS_SATIPS, "%i/%s/%i: unable to subscribe service %s\n", - rs->frontend, rs->session, rs->stream, slave->s_nicename); + tvherror(LS_SATIPS, + "%i/%s/%i: unable to subscribe service %s\n", + rs->frontend, + rs->session, + rs->stream, + slave->s_nicename); profile_chain_close(&sub->prch); free(sub); master->s_unlink(master, slave); } else { LIST_INSERT_HEAD(&rs->slaves, sub, link); - tvhdebug(LS_SATIPS, "%i/%s/%i: slave service %s subscribed", - rs->frontend, rs->session, rs->stream, slave->s_nicename); + tvhdebug(LS_SATIPS, + "%i/%s/%i: slave service %s subscribed", + rs->frontend, + rs->session, + rs->stream, + slave->s_nicename); } } /* * */ -static void -rtsp_slave_remove - (session_t *rs, mpegts_service_t *master, mpegts_service_t *slave) -{ - slave_subscription_t *sub; +static void rtsp_slave_remove(session_t* rs, mpegts_service_t* master, mpegts_service_t* slave) { + slave_subscription_t* sub; if (master == NULL) return; - LIST_FOREACH(sub, &rs->slaves, link) + LIST_FOREACH (sub, &rs->slaves, link) if (sub->service == slave) break; if (sub == NULL) return; - tvhdebug(LS_SATIPS, "%i/%s/%i: slave service %s unsubscribed", - rs->frontend, rs->session, rs->stream, slave->s_nicename); + tvhdebug(LS_SATIPS, + "%i/%s/%i: slave service %s unsubscribed", + rs->frontend, + rs->session, + rs->stream, + slave->s_nicename); master->s_unlink(master, slave); if (sub->ths) subscription_unsubscribe(sub->ths, UNSUBSCRIBE_FINAL); @@ -446,10 +445,8 @@ rtsp_slave_remove /* * */ -static void -rtsp_clean(session_t *rs, int clean_mux) -{ - slave_subscription_t *sub; +static void rtsp_clean(session_t* rs, int clean_mux) { + slave_subscription_t* sub; if (rs->rtp_handle) { satip_rtp_close(rs->rtp_handle); @@ -457,8 +454,7 @@ rtsp_clean(session_t *rs, int clean_mux) } if (rs->subs) { while ((sub = LIST_FIRST(&rs->slaves)) != NULL) - rtsp_slave_remove(rs, (mpegts_service_t *)rs->subs->ths_raw_service, - sub->service); + rtsp_slave_remove(rs, (mpegts_service_t*)rs->subs->ths_raw_service, sub->service); subscription_unsubscribe(rs->subs, UNSUBSCRIBE_FINAL); rs->subs = NULL; } @@ -468,7 +464,7 @@ rtsp_clean(session_t *rs, int clean_mux) if (rs->mux && rs->mux_created && (rtsp_muxcnf != MUXCNF_KEEP || LIST_EMPTY(&rs->mux->mm_services))) rs->mux->mm_delete(rs->mux, 1); - rs->mux = NULL; + rs->mux = NULL; rs->mux_created = 0; } } @@ -476,28 +472,24 @@ rtsp_clean(session_t *rs, int clean_mux) /* * */ -static void -rtsp_no_data(void *opaque) -{ - session_t *rs = opaque; - rs->no_data = 1; +static void rtsp_no_data(void* opaque) { + session_t* rs = opaque; + rs->no_data = 1; } /* * */ -static int -rtsp_validate_service(mpegts_service_t *s, mpegts_apids_t *pids) -{ - int av = 0, enc = 0; - elementary_stream_t *st; +static int rtsp_validate_service(mpegts_service_t* s, mpegts_apids_t* pids) { + int av = 0, enc = 0; + elementary_stream_t* st; tvh_mutex_lock(&s->s_stream_mutex); if (s->s_components.set_pmt_pid <= 0 || s->s_components.set_pcr_pid <= 0) { tvh_mutex_unlock(&s->s_stream_mutex); return 0; } - TAILQ_FOREACH(st, &s->s_components.set_all, es_link) { + TAILQ_FOREACH (st, &s->s_components.set_all, es_link) { if (st->es_type == SCT_CA) enc = 1; if (st->es_pid > 0) @@ -508,22 +500,19 @@ rtsp_validate_service(mpegts_service_t *s, mpegts_apids_t *pids) tvh_mutex_unlock(&s->s_stream_mutex); if (enc == 0 || av == 0) return 0; - return pids == NULL || - mpegts_pid_wexists(pids, s->s_components.set_pmt_pid, MPS_WEIGHT_RAW); + return pids == NULL || mpegts_pid_wexists(pids, s->s_components.set_pmt_pid, MPS_WEIGHT_RAW); } /* * */ -static void -rtsp_manage_descramble(session_t *rs) -{ - idnode_set_t *found; - mpegts_service_t *s, *master; - slave_subscription_t *sub; - mpegts_apids_t pmt_pids; - size_t si; - int i, used = 0; +static void rtsp_manage_descramble(session_t* rs) { + idnode_set_t* found; + mpegts_service_t * s, *master; + slave_subscription_t* sub; + mpegts_apids_t pmt_pids; + size_t si; + int i, used = 0; if (rtsp_descramble <= 0) return; @@ -533,15 +522,15 @@ rtsp_manage_descramble(session_t *rs) if (rs->mux == NULL || rs->subs == NULL) goto end; - master = (mpegts_service_t *)rs->subs->ths_raw_service; + master = (mpegts_service_t*)rs->subs->ths_raw_service; if (rs->pids.all) { - LIST_FOREACH(s, &rs->mux->mm_services, s_dvb_mux_link) + LIST_FOREACH (s, &rs->mux->mm_services, s_dvb_mux_link) if (rtsp_validate_service(s, NULL)) idnode_set_add(found, &s->s_id, NULL, NULL); } else { for (i = 0; i < rs->pids.count; i++) { - s = mpegts_service_find_by_pid((mpegts_mux_t *)rs->mux, rs->pids.pids[i].pid); + s = mpegts_service_find_by_pid((mpegts_mux_t*)rs->mux, rs->pids.pids[i].pid); if (s != NULL && rtsp_validate_service(s, &rs->pids)) if (!idnode_set_exists(found, &s->s_id)) idnode_set_add(found, &s->s_id, NULL, NULL); @@ -550,37 +539,42 @@ rtsp_manage_descramble(session_t *rs) /* Remove already used or no-longer required services */ for (si = 0; si < master->s_slaves.is_count; si++) { - s = (mpegts_service_t *)master->s_slaves.is_array[si]; + s = (mpegts_service_t*)master->s_slaves.is_array[si]; if (idnode_set_remove(found, &s->s_id)) { used++; } else if (!idnode_set_exists(found, &s->s_id)) { rtsp_slave_remove(rs, master, s); - if(si) - si--; + if (si) + si--; } } /* Add new ones */ for (si = 0; used < rtsp_descramble && si < found->is_count; si++, used++) { - s = (mpegts_service_t *)found->is_array[si]; + s = (mpegts_service_t*)found->is_array[si]; rtsp_slave_add(rs, master, s); idnode_set_remove(found, &s->s_id); } if (si < found->is_count) - tvhwarn(LS_SATIPS, "%i/%s/%i: limit for descrambled services reached (wanted %zd allowed %d)", - rs->frontend, rs->session, rs->stream, - (used - si) + found->is_count, rtsp_descramble); - + tvhwarn(LS_SATIPS, + "%i/%s/%i: limit for descrambled services reached (wanted %zd allowed %d)", + rs->frontend, + rs->session, + rs->stream, + (used - si) + found->is_count, + rtsp_descramble); + end: idnode_set_free(found); if (rtsp_rewrite_pmt) { /* handle PMT rewrite */ mpegts_pid_init(&pmt_pids); - LIST_FOREACH(sub, &rs->slaves, link) { - if ((s = sub->service) == NULL) continue; - if (s->s_components.set_pmt_pid <= 0 || - s->s_components.set_pmt_pid >= 8191) continue; + LIST_FOREACH (sub, &rs->slaves, link) { + if ((s = sub->service) == NULL) + continue; + if (s->s_components.set_pmt_pid <= 0 || s->s_components.set_pmt_pid >= 8191) + continue; mpegts_pid_add(&pmt_pids, s->s_components.set_pmt_pid, MPS_WEIGHT_PMT); } satip_rtp_update_pmt_pids(rs->rtp_handle, &pmt_pids); @@ -591,19 +585,15 @@ end: /* * */ -static int -rtsp_start - (http_connection_t *hc, session_t *rs, char *addrbuf, - int newmux, int cmd) -{ - mpegts_network_t *mn, *mn2; - dvb_network_t *ln; - mpegts_mux_t *mux; - mpegts_service_t *svc; - dvb_mux_conf_t dmc; - slave_subscription_t *sub; - char buf[384]; - int res = HTTP_STATUS_NOT_ALLOWED, qsize = 3000000, created = 0, weight; +static int rtsp_start(http_connection_t* hc, session_t* rs, char* addrbuf, int newmux, int cmd) { + mpegts_network_t * mn, *mn2; + dvb_network_t* ln; + mpegts_mux_t* mux; + mpegts_service_t* svc; + dvb_mux_conf_t dmc; + slave_subscription_t* sub; + char buf[384]; + int res = HTTP_STATUS_NOT_ALLOWED, qsize = 3000000, created = 0, weight; tvh_mutex_lock(&global_lock); weight = satip_server_conf.satip_weight; @@ -613,17 +603,20 @@ rtsp_start if (newmux) { mux = NULL; mn2 = NULL; - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) { if (idnode_is_instance(&mn->mn_id, &dvb_network_class)) { - ln = (dvb_network_t *)mn; - if (ln->ln_type == rs->dmc.dmc_fe_type && - mn->mn_satip_source == rs->src) { - if (!mn2) mn2 = mn; - mux = (mpegts_mux_t *) - dvb_network_find_mux((dvb_network_t *)mn, &rs->dmc, - MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, 1, rtsp_muxcnf == MUXCNF_REJECT_EXACT_MATCH ); + ln = (dvb_network_t*)mn; + if (ln->ln_type == rs->dmc.dmc_fe_type && mn->mn_satip_source == rs->src) { + if (!mn2) + mn2 = mn; + mux = (mpegts_mux_t*)dvb_network_find_mux((dvb_network_t*)mn, + &rs->dmc, + MPEGTS_ONID_NONE, + MPEGTS_TSID_NONE, + 1, + rtsp_muxcnf == MUXCNF_REJECT_EXACT_MATCH); if (mux) { - dmc = ((dvb_mux_t *)mux)->lm_tuning; + dmc = ((dvb_mux_t*)mux)->lm_tuning; rs->perm_lock = 0; break; } @@ -631,121 +624,138 @@ rtsp_start } #if ENABLE_IPTV if (idnode_is_instance(&mn->mn_id, &iptv_network_class)) { - LIST_FOREACH(mux, &mn->mn_muxes, mm_network_link) { + LIST_FOREACH (mux, &mn->mn_muxes, mm_network_link) { if (rs->dmc.dmc_fe_type == DVB_TYPE_T && - deltaU32(rs->dmc.dmc_fe_freq, ((iptv_mux_t *)mux)->mm_iptv_satip_dvbt_freq) < 2000) + deltaU32(rs->dmc.dmc_fe_freq, ((iptv_mux_t*)mux)->mm_iptv_satip_dvbt_freq) < 2000) break; if (rs->dmc.dmc_fe_type == DVB_TYPE_C && - deltaU32(rs->dmc.dmc_fe_freq, ((iptv_mux_t *)mux)->mm_iptv_satip_dvbc_freq) < 2000) + deltaU32(rs->dmc.dmc_fe_freq, ((iptv_mux_t*)mux)->mm_iptv_satip_dvbc_freq) < 2000) break; if (rs->dmc.dmc_fe_type == DVB_TYPE_S && - deltaU32(rs->dmc.dmc_fe_freq, ((iptv_mux_t *)mux)->mm_iptv_satip_dvbs_freq) < 2000) + deltaU32(rs->dmc.dmc_fe_freq, ((iptv_mux_t*)mux)->mm_iptv_satip_dvbs_freq) < 2000) break; - } + } if (mux) { - dmc = rs->dmc; + dmc = rs->dmc; rs->perm_lock = 1; break; } } #endif if (idnode_is_instance(&mn->mn_id, &dvb_network_class)) { - LIST_FOREACH(mux, &mn->mn_muxes, mm_network_link) { + LIST_FOREACH (mux, &mn->mn_muxes, mm_network_link) { if (rs->dmc.dmc_fe_type == DVB_TYPE_T && - deltaU32(rs->dmc.dmc_fe_freq, ((dvb_mux_t *)mux)->mm_dvb_satip_dvbt_freq) < 2000) + deltaU32(rs->dmc.dmc_fe_freq, ((dvb_mux_t*)mux)->mm_dvb_satip_dvbt_freq) < 2000) break; if (rs->dmc.dmc_fe_type == DVB_TYPE_C && - deltaU32(rs->dmc.dmc_fe_freq, ((dvb_mux_t *)mux)->mm_dvb_satip_dvbc_freq) < 2000) + deltaU32(rs->dmc.dmc_fe_freq, ((dvb_mux_t*)mux)->mm_dvb_satip_dvbc_freq) < 2000) break; if (rs->dmc.dmc_fe_type == DVB_TYPE_S && - deltaU32(rs->dmc.dmc_fe_freq, ((dvb_mux_t *)mux)->mm_dvb_satip_dvbs_freq) < 2000) + deltaU32(rs->dmc.dmc_fe_freq, ((dvb_mux_t*)mux)->mm_dvb_satip_dvbs_freq) < 2000) break; - } + } if (mux) { - dmc = rs->dmc; + dmc = rs->dmc; rs->perm_lock = 1; break; } } } - if (mux == NULL && mn2 && - (rtsp_muxcnf == MUXCNF_AUTO || rtsp_muxcnf == MUXCNF_KEEP)) { + if (mux == NULL && mn2 && (rtsp_muxcnf == MUXCNF_AUTO || rtsp_muxcnf == MUXCNF_KEEP)) { dvb_mux_conf_str(&rs->dmc, buf, sizeof(buf)); - tvhwarn(LS_SATIPS, "%i/%s/%i: create mux %s", - rs->frontend, rs->session, rs->stream, buf); - mux = - mn2->mn_create_mux(mn2, (void *)(intptr_t)rs->nsession, - MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, - &rs->dmc, 1); + tvhwarn(LS_SATIPS, "%i/%s/%i: create mux %s", rs->frontend, rs->session, rs->stream, buf); + mux = mn2->mn_create_mux(mn2, + (void*)(intptr_t)rs->nsession, + MPEGTS_ONID_NONE, + MPEGTS_TSID_NONE, + &rs->dmc, + 1); if (mux) { - created = 1; - dmc = ((dvb_mux_t *)mux)->lm_tuning; + created = 1; + dmc = ((dvb_mux_t*)mux)->lm_tuning; rs->perm_lock = 1; } } if (mux == NULL) { dvb_mux_conf_str(&rs->dmc, buf, sizeof(buf)); - tvhwarn(LS_SATIPS, "%i/%s/%i: unable to create mux %s%s", - rs->frontend, rs->session, rs->stream, buf, - (rtsp_muxcnf == MUXCNF_REJECT || rtsp_muxcnf == MUXCNF_REJECT_EXACT_MATCH ) ? " (configuration)" : ""); + tvhwarn(LS_SATIPS, + "%i/%s/%i: unable to create mux %s%s", + rs->frontend, + rs->session, + rs->stream, + buf, + (rtsp_muxcnf == MUXCNF_REJECT || rtsp_muxcnf == MUXCNF_REJECT_EXACT_MATCH) + ? " (configuration)" + : ""); goto endclean; } if (rs->mux == mux && rs->subs) { if (rs->no_data) { dvb_mux_conf_str(&rs->dmc, buf, sizeof(buf)); - tvhwarn(LS_SATIPS, "%i/%s/%i: subscription fails because mux %s can't tune", - rs->frontend, rs->session, rs->stream, buf); + tvhwarn(LS_SATIPS, + "%i/%s/%i: subscription fails because mux %s can't tune", + rs->frontend, + rs->session, + rs->stream, + buf); goto endclean; } goto pids; } rtsp_clean(rs, 1); - rs->dmc_tuned = dmc; - rs->mux = mux; + rs->dmc_tuned = dmc; + rs->mux = mux; rs->mux_created = created; - if (profile_chain_raw_open(&rs->prch, (mpegts_mux_t *)rs->mux, qsize, 0)) + if (profile_chain_raw_open(&rs->prch, (mpegts_mux_t*)rs->mux, qsize, 0)) goto endclean; rs->used_weight = weight; - rs->subs = subscription_create_from_mux(&rs->prch, NULL, - weight, - "SAT>IP", - rs->prch.prch_flags | - SUBSCRIPTION_STREAMING, - addrbuf, http_username(hc), - http_arg_get(&hc->hc_args, "User-Agent"), - NULL); + rs->subs = subscription_create_from_mux(&rs->prch, + NULL, + weight, + "SAT>IP", + rs->prch.prch_flags | SUBSCRIPTION_STREAMING, + addrbuf, + http_username(hc), + http_arg_get(&hc->hc_args, "User-Agent"), + NULL); if (!rs->subs) goto endclean; if (!rs->pids.all && rs->pids.count == 0) mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW); } else { -pids: + pids: if (!rs->subs) goto endclean; if (!rs->pids.all && rs->pids.count == 0) mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW); - svc = (mpegts_service_t *)rs->subs->ths_raw_service; + svc = (mpegts_service_t*)rs->subs->ths_raw_service; svc->s_update_pids(svc, &rs->pids); satip_rtp_update_pids(rs->rtp_handle, &rs->pids); if (rs->used_weight != weight && weight > 0) { subscription_set_weight(rs->subs, rs->used_weight = weight); - LIST_FOREACH(sub, &rs->slaves, link) + LIST_FOREACH (sub, &rs->slaves, link) subscription_set_weight(sub->ths, weight); } } if (cmd != RTSP_CMD_DESCRIBE && rs->rtp_handle == NULL) { if (rs->mux == NULL) goto endclean; - rs->no_data = 0; - rs->rtp_handle = - satip_rtp_queue(rs->subs, &rs->prch.prch_sq, - hc, hc->hc_peer, rs->rtp_peer_port, - rs->udp_rtp ? rs->udp_rtp->fd : hc->hc_fd, - rs->udp_rtcp ? rs->udp_rtcp->fd : -1, - rs->findex, rs->src, &rs->dmc_tuned, - &rs->pids, - cmd == RTSP_CMD_PLAY || rs->playing, - rs->perm_lock, rtsp_no_data, rs); + rs->no_data = 0; + rs->rtp_handle = satip_rtp_queue(rs->subs, + &rs->prch.prch_sq, + hc, + hc->hc_peer, + rs->rtp_peer_port, + rs->udp_rtp ? rs->udp_rtp->fd : hc->hc_fd, + rs->udp_rtcp ? rs->udp_rtcp->fd : -1, + rs->findex, + rs->src, + &rs->dmc_tuned, + &rs->pids, + cmd == RTSP_CMD_PLAY || rs->playing, + rs->perm_lock, + rtsp_no_data, + rs); if (rs->rtp_handle == NULL) { res = HTTP_STATUS_INTERNAL; goto endclean; @@ -753,10 +763,10 @@ pids: rs->tcp_data = rs->udp_rtp ? NULL : hc; if (!rs->pids.all && rs->pids.count == 0) mpegts_pid_add(&rs->pids, 0, MPS_WEIGHT_RAW); - svc = (mpegts_service_t *)rs->subs->ths_raw_service; + svc = (mpegts_service_t*)rs->subs->ths_raw_service; svc->s_update_pids(svc, &rs->pids); rs->playing = cmd == RTSP_CMD_PLAY || rs->playing; - rs->state = STATE_PLAY; + rs->state = STATE_PLAY; } else if (cmd == RTSP_CMD_PLAY) { rs->playing = 1; if (rs->mux == NULL) @@ -776,104 +786,113 @@ endclean: /* * */ -static inline int -msys_to_tvh(http_connection_t *hc) -{ - static struct strtab tab[] = { - { "dvbs", DVB_SYS_DVBS }, - { "dvbs2", DVB_SYS_DVBS2 }, - { "dvbt", DVB_SYS_DVBT }, - { "dvbt2", DVB_SYS_DVBT2 }, - { "dvbc", DVB_SYS_DVBC_ANNEX_A }, - { "dvbc2", DVB_SYS_DVBC_ANNEX_C }, - { "atsc", DVB_SYS_ATSC }, - { "isdbt", DVB_SYS_ISDBT }, - { "dvbcb", DVB_SYS_DVBC_ANNEX_B } - }; - const char *s = http_arg_get_remove(&hc->hc_req_args, "msys"); +static inline int msys_to_tvh(http_connection_t* hc) { + static struct strtab tab[] = {{"dvbs", DVB_SYS_DVBS}, + {"dvbs2", DVB_SYS_DVBS2}, + {"dvbt", DVB_SYS_DVBT}, + {"dvbt2", DVB_SYS_DVBT2}, + {"dvbc", DVB_SYS_DVBC_ANNEX_A}, + {"dvbc2", DVB_SYS_DVBC_ANNEX_C}, + {"atsc", DVB_SYS_ATSC}, + {"isdbt", DVB_SYS_ISDBT}, + {"dvbcb", DVB_SYS_DVBC_ANNEX_B}}; + const char* s = http_arg_get_remove(&hc->hc_req_args, "msys"); return s && s[0] ? str2val(s, tab) : DVB_SYS_NONE; } -static inline int -pol_to_tvh(http_connection_t *hc) -{ +static inline int pol_to_tvh(http_connection_t* hc) { static struct strtab tab[] = { - { "h", DVB_POLARISATION_HORIZONTAL }, - { "v", DVB_POLARISATION_VERTICAL }, - { "l", DVB_POLARISATION_CIRCULAR_LEFT }, - { "r", DVB_POLARISATION_CIRCULAR_RIGHT }, + {"h", DVB_POLARISATION_HORIZONTAL}, + {"v", DVB_POLARISATION_VERTICAL}, + {"l", DVB_POLARISATION_CIRCULAR_LEFT}, + {"r", DVB_POLARISATION_CIRCULAR_RIGHT}, }; - const char *s = http_arg_get_remove(&hc->hc_req_args, "pol"); + const char* s = http_arg_get_remove(&hc->hc_req_args, "pol"); return s && s[0] ? str2val(s, tab) : -1; } -static int -fec_to_tvh(http_connection_t *hc) -{ +static int fec_to_tvh(http_connection_t* hc) { switch (atoi(http_arg_get_remove(&hc->hc_req_args, "fec") ?: "0")) { - case 0: return DVB_FEC_AUTO; - case 12: return DVB_FEC_1_2; - case 13: return DVB_FEC_1_3; - case 15: return DVB_FEC_1_5; - case 23: return DVB_FEC_2_3; - case 25: return DVB_FEC_2_5; - case 29: return DVB_FEC_2_9; - case 34: return DVB_FEC_3_4; - case 35: return DVB_FEC_3_5; - case 45: return DVB_FEC_4_5; - case 415: return DVB_FEC_4_15; - case 56: return DVB_FEC_5_6; - case 59: return DVB_FEC_5_9; - case 67: return DVB_FEC_6_7; - case 78: return DVB_FEC_7_8; - case 79: return DVB_FEC_7_9; - case 715: return DVB_FEC_7_15; - case 89: return DVB_FEC_8_9; - case 815: return DVB_FEC_8_15; - case 910: return DVB_FEC_9_10; - case 920: return DVB_FEC_9_20; - default: return DVB_FEC_NONE; + case 0: + return DVB_FEC_AUTO; + case 12: + return DVB_FEC_1_2; + case 13: + return DVB_FEC_1_3; + case 15: + return DVB_FEC_1_5; + case 23: + return DVB_FEC_2_3; + case 25: + return DVB_FEC_2_5; + case 29: + return DVB_FEC_2_9; + case 34: + return DVB_FEC_3_4; + case 35: + return DVB_FEC_3_5; + case 45: + return DVB_FEC_4_5; + case 415: + return DVB_FEC_4_15; + case 56: + return DVB_FEC_5_6; + case 59: + return DVB_FEC_5_9; + case 67: + return DVB_FEC_6_7; + case 78: + return DVB_FEC_7_8; + case 79: + return DVB_FEC_7_9; + case 715: + return DVB_FEC_7_15; + case 89: + return DVB_FEC_8_9; + case 815: + return DVB_FEC_8_15; + case 910: + return DVB_FEC_9_10; + case 920: + return DVB_FEC_9_20; + default: + return DVB_FEC_NONE; } } -static int -bw_to_tvh(http_connection_t *hc) -{ +static int bw_to_tvh(http_connection_t* hc) { int bw = atof(http_arg_get_remove(&hc->hc_req_args, "bw") ?: "0") * 1000; switch (bw) { - case 0: return DVB_BANDWIDTH_AUTO; - case DVB_BANDWIDTH_1_712_MHZ: - case DVB_BANDWIDTH_5_MHZ: - case DVB_BANDWIDTH_6_MHZ: - case DVB_BANDWIDTH_7_MHZ: - case DVB_BANDWIDTH_8_MHZ: - case DVB_BANDWIDTH_10_MHZ: - return bw; - default: - return DVB_BANDWIDTH_NONE; + case 0: + return DVB_BANDWIDTH_AUTO; + case DVB_BANDWIDTH_1_712_MHZ: + case DVB_BANDWIDTH_5_MHZ: + case DVB_BANDWIDTH_6_MHZ: + case DVB_BANDWIDTH_7_MHZ: + case DVB_BANDWIDTH_8_MHZ: + case DVB_BANDWIDTH_10_MHZ: + return bw; + default: + return DVB_BANDWIDTH_NONE; } } -static int -rolloff_to_tvh(http_connection_t *hc) -{ +static int rolloff_to_tvh(http_connection_t* hc) { int ro = atof(http_arg_get_remove(&hc->hc_req_args, "ro") ?: "0") * 1000; switch (ro) { - case 0: - return DVB_ROLLOFF_35; - case DVB_ROLLOFF_20: - case DVB_ROLLOFF_25: - case DVB_ROLLOFF_35: - return ro; - default: - return DVB_ROLLOFF_NONE; + case 0: + return DVB_ROLLOFF_35; + case DVB_ROLLOFF_20: + case DVB_ROLLOFF_25: + case DVB_ROLLOFF_35: + return ro; + default: + return DVB_ROLLOFF_NONE; } } -static int -pilot_to_tvh(http_connection_t *hc) -{ - const char *s = http_arg_get_remove(&hc->hc_req_args, "plts"); +static int pilot_to_tvh(http_connection_t* hc) { + const char* s = http_arg_get_remove(&hc->hc_req_args, "plts"); if (s && strcmp(s, "on") == 0) return DVB_PILOT_ON; if (s && strcmp(s, "off") == 0) @@ -883,19 +902,17 @@ pilot_to_tvh(http_connection_t *hc) return DVB_ROLLOFF_NONE; } -static int -tmode_to_tvh(http_connection_t *hc) -{ +static int tmode_to_tvh(http_connection_t* hc) { static struct strtab tab[] = { - { "auto", DVB_TRANSMISSION_MODE_AUTO }, - { "1k", DVB_TRANSMISSION_MODE_1K }, - { "2k", DVB_TRANSMISSION_MODE_2K }, - { "4k", DVB_TRANSMISSION_MODE_4K }, - { "8k", DVB_TRANSMISSION_MODE_8K }, - { "16k", DVB_TRANSMISSION_MODE_16K }, - { "32k", DVB_TRANSMISSION_MODE_32K }, + {"auto", DVB_TRANSMISSION_MODE_AUTO}, + {"1k", DVB_TRANSMISSION_MODE_1K}, + {"2k", DVB_TRANSMISSION_MODE_2K}, + {"4k", DVB_TRANSMISSION_MODE_4K}, + {"8k", DVB_TRANSMISSION_MODE_8K}, + {"16k", DVB_TRANSMISSION_MODE_16K}, + {"32k", DVB_TRANSMISSION_MODE_32K}, }; - const char *s = http_arg_get_remove(&hc->hc_req_args, "tmode"); + const char* s = http_arg_get_remove(&hc->hc_req_args, "tmode"); if (s && s[0]) { int v = str2val(s, tab); return v >= 0 ? v : DVB_TRANSMISSION_MODE_NONE; @@ -903,21 +920,19 @@ tmode_to_tvh(http_connection_t *hc) return DVB_TRANSMISSION_MODE_AUTO; } -static int -mtype_to_tvh(http_connection_t *hc) -{ +static int mtype_to_tvh(http_connection_t* hc) { static struct strtab tab[] = { - { "auto", DVB_MOD_AUTO }, - { "qpsk", DVB_MOD_QPSK }, - { "8psk", DVB_MOD_PSK_8 }, - { "16qam", DVB_MOD_QAM_16 }, - { "32qam", DVB_MOD_QAM_32 }, - { "64qam", DVB_MOD_QAM_64 }, - { "128qam", DVB_MOD_QAM_128 }, - { "256qam", DVB_MOD_QAM_256 }, - { "8vsb", DVB_MOD_VSB_8 }, + {"auto", DVB_MOD_AUTO}, + {"qpsk", DVB_MOD_QPSK}, + {"8psk", DVB_MOD_PSK_8}, + {"16qam", DVB_MOD_QAM_16}, + {"32qam", DVB_MOD_QAM_32}, + {"64qam", DVB_MOD_QAM_64}, + {"128qam", DVB_MOD_QAM_128}, + {"256qam", DVB_MOD_QAM_256}, + {"8vsb", DVB_MOD_VSB_8}, }; - const char *s = http_arg_get_remove(&hc->hc_req_args, "mtype"); + const char* s = http_arg_get_remove(&hc->hc_req_args, "mtype"); if (s && s[0]) { int v = str2val(s, tab); return v >= 0 ? v : DVB_MOD_NONE; @@ -925,27 +940,32 @@ mtype_to_tvh(http_connection_t *hc) return DVB_MOD_AUTO; } -static int -gi_to_tvh(http_connection_t *hc) -{ +static int gi_to_tvh(http_connection_t* hc) { switch (atoi(http_arg_get_remove(&hc->hc_req_args, "gi") ?: "0")) { - case 0: return DVB_GUARD_INTERVAL_AUTO; - case 14: return DVB_GUARD_INTERVAL_1_4; - case 18: return DVB_GUARD_INTERVAL_1_8; - case 116: return DVB_GUARD_INTERVAL_1_16; - case 132: return DVB_GUARD_INTERVAL_1_32; - case 1128: return DVB_GUARD_INTERVAL_1_128; - case 19128: return DVB_GUARD_INTERVAL_19_128; - case 19256: return DVB_GUARD_INTERVAL_19_256; - default: return DVB_GUARD_INTERVAL_NONE; + case 0: + return DVB_GUARD_INTERVAL_AUTO; + case 14: + return DVB_GUARD_INTERVAL_1_4; + case 18: + return DVB_GUARD_INTERVAL_1_8; + case 116: + return DVB_GUARD_INTERVAL_1_16; + case 132: + return DVB_GUARD_INTERVAL_1_32; + case 1128: + return DVB_GUARD_INTERVAL_1_128; + case 19128: + return DVB_GUARD_INTERVAL_19_128; + case 19256: + return DVB_GUARD_INTERVAL_19_256; + default: + return DVB_GUARD_INTERVAL_NONE; } } -static int -parse_pids(char *p, mpegts_apids_t *pids) -{ +static int parse_pids(char* p, mpegts_apids_t* pids) { char *x, *saveptr; - int i = 0, pid; + int i = 0, pid; mpegts_pid_reset(pids); if (p == NULL || *p == '\0') @@ -958,16 +978,16 @@ parse_pids(char *p, mpegts_apids_t *pids) if (satip_server_conf.satip_restrict_pids_all) { pids->all = 0; for (pid = 1; pid <= 2; pid++) /* CAT, TSDT */ - mpegts_pid_add(pids, pid, MPS_WEIGHT_RAW); + mpegts_pid_add(pids, pid, MPS_WEIGHT_RAW); for (pid = 0x10; pid < 0x20; pid++) /* NIT ... SIT */ - mpegts_pid_add(pids, pid, MPS_WEIGHT_RAW); + mpegts_pid_add(pids, pid, MPS_WEIGHT_RAW); mpegts_pid_add(pids, 0x1ffb, MPS_WEIGHT_RAW); /* ATSC */ } else { pids->all = 1; } } else { pids->all = 0; - pid = atoi(x); + pid = atoi(x); if (pid < 0 || pid > 8191) return -1; mpegts_pid_add(pids, pid, MPS_WEIGHT_RAW); @@ -980,13 +1000,11 @@ parse_pids(char *p, mpegts_apids_t *pids) return 0; } -static int -parse_transport(http_connection_t *hc, char *destip, size_t destip_len) -{ - const char *s = http_arg_get(&hc->hc_args, "Transport"); - const char *u; - char *x; - int a, b; +static int parse_transport(http_connection_t* hc, char* destip, size_t destip_len) { + const char* s = http_arg_get(&hc->hc_args, "Transport"); + const char* u; + char* x; + int a, b; if (!s) return -1; destip[0] = '\0'; @@ -997,29 +1015,39 @@ parse_transport(http_connection_t *hc, char *destip, size_t destip_len) if (strncmp(s, "destination=", 12) == 0) { s += 12; strlcpy(destip, s, destip_len); - for (x = destip; *x && *x != ';'; x++); + for (x = destip; *x && *x != ';'; x++) + ; *x = '\0'; - for (; *s && *s != ';'; s++); - if (*s != '\0' && *s != ';') return -1; - if (*s == ';') s++; + for (; *s && *s != ';'; s++) + ; + if (*s != '\0' && *s != ';') + return -1; + if (*s == ';') + s++; continue; } if (strncmp(s, "client_port=", 12) == 0) { - for (s += 12, u = s; isdigit(*u); u++); - if (*u != '-') return -1; + for (s += 12, u = s; isdigit(*u); u++) + ; + if (*u != '-') + return -1; a = atoi(s); - for (s = ++u; isdigit(*s); s++); - if (*s != '\0' && *s != ';') return -1; + for (s = ++u; isdigit(*s); s++) + ; + if (*s != '\0' && *s != ';') + return -1; b = atoi(u); - if (a + 1 != b) return -1; - if (*s == ';') s++; + if (a + 1 != b) + return -1; + if (*s == ';') + s++; continue; } return -1; } return a; } else if ((strncmp(s, "RTP/AVP/TCP;interleaved=0-1", 27) == 0) && - !satip_server_conf.satip_notcp_mode) { + !satip_server_conf.satip_notcp_mode) { return RTSP_TCP_DATA; } return -1; @@ -1028,28 +1056,32 @@ parse_transport(http_connection_t *hc, char *destip, size_t destip_len) /* * */ -static int -rtsp_parse_cmd - (http_connection_t *hc, int stream, int cmd, - session_t **rrs, int *valid) -{ - session_t *rs = NULL; - int errcode = HTTP_STATUS_BAD_REQUEST, r, findex = 1, has_args, weight = 0; - int delsys = DVB_SYS_NONE, msys, fe, src, freq, pol, sr; - int fec, ro, plts, bw, tmode, mtype, gi, plp, t2id, sm, c2tft, ds, specinv; - int alloc_stream_id = 0; - char *s; - const char *caller; - mpegts_apids_t pids, addpids, delpids; - dvb_mux_conf_t *dmc; - char buf[256]; - http_arg_t *arg; +static int rtsp_parse_cmd(http_connection_t* hc, int stream, int cmd, session_t** rrs, int* valid) { + session_t* rs = NULL; + int errcode = HTTP_STATUS_BAD_REQUEST, r, findex = 1, has_args, weight = 0; + int delsys = DVB_SYS_NONE, msys, fe, src, freq, pol, sr; + int fec, ro, plts, bw, tmode, mtype, gi, plp, t2id, sm, c2tft, ds, specinv; + int alloc_stream_id = 0; + char* s; + const char* caller; + mpegts_apids_t pids, addpids, delpids; + dvb_mux_conf_t* dmc; + char buf[256]; + http_arg_t* arg; switch (cmd) { - case RTSP_CMD_DESCRIBE: caller = "DESCRIBE"; break; - case RTSP_CMD_PLAY: caller = "PLAY"; break; - case RTSP_CMD_SETUP: caller = "SETUP"; break; - default: caller = NULL; break; + case RTSP_CMD_DESCRIBE: + caller = "DESCRIBE"; + break; + case RTSP_CMD_PLAY: + caller = "PLAY"; + break; + case RTSP_CMD_SETUP: + caller = "SETUP"; + break; + default: + caller = NULL; + break; } *rrs = NULL; @@ -1061,14 +1093,17 @@ rtsp_parse_cmd fe = atoi(http_arg_get_remove(&hc->hc_req_args, "fe") ?: 0); fe = satip_server_conf.satip_drop_fe ? 0 : fe; - s = http_arg_get_remove(&hc->hc_req_args, "addpids"); - if (parse_pids(s, &addpids)) goto end; + s = http_arg_get_remove(&hc->hc_req_args, "addpids"); + if (parse_pids(s, &addpids)) + goto end; s = http_arg_get_remove(&hc->hc_req_args, "delpids"); - if (parse_pids(s, &delpids)) goto end; + if (parse_pids(s, &delpids)) + goto end; s = http_arg_get_remove(&hc->hc_req_args, "pids"); - if (parse_pids(s, &pids)) goto end; - msys = msys_to_tvh(hc); - freq = atof(http_arg_get_remove(&hc->hc_req_args, "freq")) * 1000; + if (parse_pids(s, &pids)) + goto end; + msys = msys_to_tvh(hc); + freq = atof(http_arg_get_remove(&hc->hc_req_args, "freq")) * 1000; *valid = freq >= 10000; weight = atoi(http_arg_get_remove(&hc->hc_req_args, "tvhweight")); @@ -1094,17 +1129,25 @@ rtsp_parse_cmd if (cmd == RTSP_CMD_SETUP) { if (!rs) { rs = rtsp_new_session(hc->hc_peer_ipstr, msys, 0, -1); - if (rs == NULL) goto end; - if (delsys == DVB_SYS_NONE) goto end; - if (msys == DVB_SYS_NONE) goto end; - if (!(*valid)) goto end; + if (rs == NULL) + goto end; + if (delsys == DVB_SYS_NONE) + goto end; + if (msys == DVB_SYS_NONE) + goto end; + if (!(*valid)) + goto end; alloc_stream_id = 1; } else if (stream != rs->stream) { rs = rtsp_new_session(hc->hc_peer_ipstr, msys, rs->nsession, stream); - if (rs == NULL) goto end; - if (delsys == DVB_SYS_NONE) goto end; - if (msys == DVB_SYS_NONE) goto end; - if (!(*valid)) goto end; + if (rs == NULL) + goto end; + if (delsys == DVB_SYS_NONE) + goto end; + if (msys == DVB_SYS_NONE) + goto end; + if (!(*valid)) + goto end; alloc_stream_id = 1; } else { if (!has_args && rs->state == STATE_DESCRIBE) { @@ -1114,7 +1157,7 @@ rtsp_parse_cmd goto end; } rs->rtp_peer_port = r; - *valid = 1; + *valid = 1; goto ok; } } @@ -1128,7 +1171,7 @@ rtsp_parse_cmd goto end; } rs->rtp_peer_port = r; - rs->frontend = fe > 0 ? fe : 1; + rs->frontend = fe > 0 ? fe : 1; } else { if (!rs && !stream && cmd == RTSP_CMD_DESCRIBE) rs = rtsp_new_session(hc->hc_peer_ipstr, msys, 0, -1); @@ -1138,16 +1181,19 @@ rtsp_parse_cmd goto end; } if (!fe) { - fe = rs->frontend; + fe = rs->frontend; findex = rs->findex; } if (rs->frontend != fe) goto end; if (*valid) { - if (delsys == DVB_SYS_NONE) goto end; - if (msys == DVB_SYS_NONE) goto end; + if (delsys == DVB_SYS_NONE) + goto end; + if (msys == DVB_SYS_NONE) + goto end; } else { - if (!TAILQ_EMPTY(&hc->hc_req_args)) goto end; + if (!TAILQ_EMPTY(&hc->hc_req_args)) + goto end; goto play; } } @@ -1155,133 +1201,171 @@ rtsp_parse_cmd dvb_mux_conf_init(NULL, dmc = &rs->dmc, msys); mtype = mtype_to_tvh(hc); - if (mtype == DVB_MOD_NONE) goto end; + if (mtype == DVB_MOD_NONE) + goto end; - src = http_arg_get(&hc->hc_req_args, "src") ? - atoi(http_arg_get_remove(&hc->hc_req_args, "src")) : 1; - if (src < 1) goto end; + src = http_arg_get(&hc->hc_req_args, "src") ? atoi(http_arg_get_remove(&hc->hc_req_args, "src")) + : 1; + if (src < 1) + goto end; if (msys == DVB_SYS_DVBS || msys == DVB_SYS_DVBS2) { pol = pol_to_tvh(hc); - if (pol < 0) goto end; + if (pol < 0) + goto end; sr = atof(http_arg_get_remove(&hc->hc_req_args, "sr") ?: "0") * 1000; - if (sr < 1000) goto end; + if (sr < 1000) + goto end; fec = fec_to_tvh(hc); - if (fec == DVB_FEC_NONE) goto end; + if (fec == DVB_FEC_NONE) + goto end; ro = rolloff_to_tvh(hc); - if (ro == DVB_ROLLOFF_NONE || - (ro != DVB_ROLLOFF_35 && msys == DVB_SYS_DVBS)) goto end; + if (ro == DVB_ROLLOFF_NONE || (ro != DVB_ROLLOFF_35 && msys == DVB_SYS_DVBS)) + goto end; plts = pilot_to_tvh(hc); - if (plts == DVB_PILOT_NONE) goto end; - - TAILQ_FOREACH(arg, &hc->hc_req_args, link) - tvhwarn(LS_SATIPS, "%i/%s/%i: extra parameter '%s'='%s'", - rs->frontend, rs->session, rs->stream, - arg->key, arg->val); + if (plts == DVB_PILOT_NONE) + goto end; - dmc->dmc_fe_rolloff = ro; - dmc->dmc_fe_pilot = plts; + TAILQ_FOREACH (arg, &hc->hc_req_args, link) + tvhwarn(LS_SATIPS, + "%i/%s/%i: extra parameter '%s'='%s'", + rs->frontend, + rs->session, + rs->stream, + arg->key, + arg->val); + + dmc->dmc_fe_rolloff = ro; + dmc->dmc_fe_pilot = plts; dmc->u.dmc_fe_qpsk.polarisation = pol; - dmc->u.dmc_fe_qpsk.symbol_rate = sr; - dmc->u.dmc_fe_qpsk.fec_inner = fec; + dmc->u.dmc_fe_qpsk.symbol_rate = sr; + dmc->u.dmc_fe_qpsk.fec_inner = fec; } else if (msys == DVB_SYS_DVBT || msys == DVB_SYS_DVBT2) { freq *= 1000; - if (freq < 0) goto end; + if (freq < 0) + goto end; bw = bw_to_tvh(hc); - if (bw == DVB_BANDWIDTH_NONE) goto end; + if (bw == DVB_BANDWIDTH_NONE) + goto end; tmode = tmode_to_tvh(hc); - if (tmode == DVB_TRANSMISSION_MODE_NONE) goto end; + if (tmode == DVB_TRANSMISSION_MODE_NONE) + goto end; gi = gi_to_tvh(hc); - if (gi == DVB_GUARD_INTERVAL_NONE) goto end; + if (gi == DVB_GUARD_INTERVAL_NONE) + goto end; fec = fec_to_tvh(hc); - if (fec == DVB_FEC_NONE) goto end; + if (fec == DVB_FEC_NONE) + goto end; s = http_arg_get_remove(&hc->hc_req_args, "plp"); if (s && s[0]) { plp = atoi(s); - if (plp < 0 || plp > 255) goto end; + if (plp < 0 || plp > 255) + goto end; } else { plp = DVB_NO_STREAM_ID_FILTER; } t2id = atoi(http_arg_get_remove(&hc->hc_req_args, "t2id") ?: "0"); - if (t2id < 0 || t2id > 65535) goto end; + if (t2id < 0 || t2id > 65535) + goto end; sm = atoi(http_arg_get_remove(&hc->hc_req_args, "sm") ?: "0"); - if (sm < 0 || sm > 1) goto end; - - TAILQ_FOREACH(arg, &hc->hc_req_args, link) - tvhwarn(LS_SATIPS, "%i/%s/%i: extra parameter '%s'='%s'", - rs->frontend, rs->session, rs->stream, - arg->key, arg->val); - - dmc->u.dmc_fe_ofdm.bandwidth = bw; - dmc->u.dmc_fe_ofdm.code_rate_HP = fec; - dmc->u.dmc_fe_ofdm.code_rate_LP = DVB_FEC_NONE; - dmc->u.dmc_fe_ofdm.transmission_mode = tmode; - dmc->u.dmc_fe_ofdm.guard_interval = gi; + if (sm < 0 || sm > 1) + goto end; + + TAILQ_FOREACH (arg, &hc->hc_req_args, link) + tvhwarn(LS_SATIPS, + "%i/%s/%i: extra parameter '%s'='%s'", + rs->frontend, + rs->session, + rs->stream, + arg->key, + arg->val); + + dmc->u.dmc_fe_ofdm.bandwidth = bw; + dmc->u.dmc_fe_ofdm.code_rate_HP = fec; + dmc->u.dmc_fe_ofdm.code_rate_LP = DVB_FEC_NONE; + dmc->u.dmc_fe_ofdm.transmission_mode = tmode; + dmc->u.dmc_fe_ofdm.guard_interval = gi; dmc->u.dmc_fe_ofdm.hierarchy_information = DVB_HIERARCHY_AUTO; - dmc->dmc_fe_stream_id = plp; - dmc->dmc_fe_pls_code = t2id; - dmc->dmc_fe_pls_mode = sm; /* check */ + dmc->dmc_fe_stream_id = plp; + dmc->dmc_fe_pls_code = t2id; + dmc->dmc_fe_pls_mode = sm; /* check */ } else if (msys == DVB_SYS_DVBC_ANNEX_A || msys == DVB_SYS_DVBC_ANNEX_C) { freq *= 1000; - if (freq < 0) goto end; + if (freq < 0) + goto end; c2tft = atoi(http_arg_get_remove(&hc->hc_req_args, "c2tft") ?: "0"); - if (c2tft < 0 || c2tft > 2) goto end; + if (c2tft < 0 || c2tft > 2) + goto end; bw = bw_to_tvh(hc); - if (bw == DVB_BANDWIDTH_NONE) goto end; + if (bw == DVB_BANDWIDTH_NONE) + goto end; sr = atof(http_arg_get_remove(&hc->hc_req_args, "sr") ?: "0") * 1000; - if (sr < 1000) goto end; + if (sr < 1000) + goto end; ds = atoi(http_arg_get_remove(&hc->hc_req_args, "ds") ?: "0"); - if (ds < 0 || ds > 255) goto end; + if (ds < 0 || ds > 255) + goto end; s = http_arg_get_remove(&hc->hc_req_args, "plp"); if (s && s[0]) { plp = atoi(http_arg_get_remove(&hc->hc_req_args, "plp")); - if (plp < 0 || plp > 255) goto end; + if (plp < 0 || plp > 255) + goto end; } else { plp = DVB_NO_STREAM_ID_FILTER; } specinv = atoi(http_arg_get_remove(&hc->hc_req_args, "specinv") ?: "0"); - if (specinv < 0 || specinv > 1) goto end; + if (specinv < 0 || specinv > 1) + goto end; fec = fec_to_tvh(hc); - if (fec == DVB_FEC_NONE) goto end; + if (fec == DVB_FEC_NONE) + goto end; - TAILQ_FOREACH(arg, &hc->hc_req_args, link) - tvhwarn(LS_SATIPS, "%i/%s/%i: extra parameter '%s'='%s'", - rs->frontend, rs->session, rs->stream, - arg->key, arg->val); + TAILQ_FOREACH (arg, &hc->hc_req_args, link) + tvhwarn(LS_SATIPS, + "%i/%s/%i: extra parameter '%s'='%s'", + rs->frontend, + rs->session, + rs->stream, + arg->key, + arg->val); dmc->u.dmc_fe_qam.symbol_rate = sr; - dmc->u.dmc_fe_qam.fec_inner = fec; - dmc->dmc_fe_inversion = specinv; - dmc->dmc_fe_stream_id = plp; - dmc->dmc_fe_pls_code = ds; /* check */ + dmc->u.dmc_fe_qam.fec_inner = fec; + dmc->dmc_fe_inversion = specinv; + dmc->dmc_fe_stream_id = plp; + dmc->dmc_fe_pls_code = ds; /* check */ } else if (msys == DVB_SYS_ISDBT || msys == DVB_SYS_ATSC || msys == DVB_SYS_DVBC_ANNEX_B) { freq *= 1000; - if (freq < 0) goto end; - TAILQ_FOREACH(arg, &hc->hc_req_args, link) - tvhwarn(LS_SATIPS, "%i/%s/%i: extra parameter '%s'='%s'", - rs->frontend, rs->session, rs->stream, - arg->key, arg->val); + if (freq < 0) + goto end; + TAILQ_FOREACH (arg, &hc->hc_req_args, link) + tvhwarn(LS_SATIPS, + "%i/%s/%i: extra parameter '%s'='%s'", + rs->frontend, + rs->session, + rs->stream, + arg->key, + arg->val); } else { goto end; - } - dmc->dmc_fe_freq = freq; + dmc->dmc_fe_freq = freq; dmc->dmc_fe_modulation = mtype; - dmc->dmc_fe_delsys = msys; + dmc->dmc_fe_delsys = msys; rs->frontend = fe; - rs->findex = findex; - rs->src = src; + rs->findex = findex; + rs->src = src; if (weight > 0) rs->weight = weight; else if (cmd == RTSP_CMD_SETUP) @@ -1316,13 +1400,19 @@ play: if (mpegts_pid_dump(&rs->pids, buf + r, sizeof(buf) - r, 0, 0) == 0) tvh_strlcatf(buf, sizeof(buf), r, ""); - tvhdebug(LS_SATIPS, "%i/%s/%d: %s from %s:%d %s", - rs->frontend, rs->session, rs->stream, - caller, hc->hc_peer_ipstr, ntohs(IP_PORT(*hc->hc_peer)), buf); + tvhdebug(LS_SATIPS, + "%i/%s/%d: %s from %s:%d %s", + rs->frontend, + rs->session, + rs->stream, + caller, + hc->hc_peer_ipstr, + ntohs(IP_PORT(*hc->hc_peer)), + buf); ok: errcode = 0; - *rrs = rs; + *rrs = rs; end: if (rs) @@ -1336,13 +1426,11 @@ end: /* * */ -static int -rtsp_process_options(http_connection_t *hc) -{ +static int rtsp_process_options(http_connection_t* hc) { http_arg_list_t args; - char *u = tvh_strdupa(hc->hc_url); - session_t *rs; - int found; + char* u = tvh_strdupa(hc->hc_url); + session_t* rs; + int found; if (strcmp(u, "*") != 0 && (u = rtsp_check_urlbase(u)) == NULL) goto error; @@ -1350,7 +1438,7 @@ rtsp_process_options(http_connection_t *hc) if (hc->hc_session) { found = 0; tvh_mutex_lock(&rtsp_lock); - TAILQ_FOREACH(rs, &rtsp_sessions, link) + TAILQ_FOREACH (rs, &rtsp_sessions, link) if (!strcmp(rs->session, hc->hc_session)) { rtsp_rearm_session_timer(rs); found = 1; @@ -1379,27 +1467,24 @@ error: /* * */ -static void -rtsp_describe_header(session_t *rs, htsbuf_queue_t *q) -{ +static void rtsp_describe_header(session_t* rs, htsbuf_queue_t* q) { unsigned long mono = mclk(); - int dvbt, dvbc; + int dvbt, dvbc; htsbuf_append_str(q, "v=0\r\n"); - htsbuf_qprintf(q, "o=- %lu %lu IN %s %s\r\n", - rs ? (unsigned long)rs->nsession : mono - 123, - mono, - strchr(rtsp_ip, ':') ? "IP6" : "IP4", - rtsp_ip); + htsbuf_qprintf(q, + "o=- %lu %lu IN %s %s\r\n", + rs ? (unsigned long)rs->nsession : mono - 123, + mono, + strchr(rtsp_ip, ':') ? "IP6" : "IP4", + rtsp_ip); tvh_mutex_lock(&global_lock); - htsbuf_qprintf(q, "s=SatIPServer:1 %d", - satip_server_conf.satip_dvbs + - satip_server_conf.satip_dvbs2); - dvbt = satip_server_conf.satip_dvbt + - satip_server_conf.satip_dvbt2; - dvbc = satip_server_conf.satip_dvbc + - satip_server_conf.satip_dvbc2; + htsbuf_qprintf(q, + "s=SatIPServer:1 %d", + satip_server_conf.satip_dvbs + satip_server_conf.satip_dvbs2); + dvbt = satip_server_conf.satip_dvbt + satip_server_conf.satip_dvbt2; + dvbc = satip_server_conf.satip_dvbc + satip_server_conf.satip_dvbc2; if (dvbc) htsbuf_qprintf(q, " %d %d\r\n", dvbt, dvbc); else if (dvbt) @@ -1411,9 +1496,7 @@ rtsp_describe_header(session_t *rs, htsbuf_queue_t *q) htsbuf_append_str(q, "t=0 0\r\n"); } -static void -rtsp_describe_session(session_t *rs, htsbuf_queue_t *q) -{ +static void rtsp_describe_session(session_t* rs, htsbuf_queue_t* q) { char buf[4096]; if (rs->stream > 0) @@ -1437,18 +1520,16 @@ rtsp_describe_session(session_t *rs, htsbuf_queue_t *q) /* * */ -static int -rtsp_process_describe(http_connection_t *hc) -{ +static int rtsp_process_describe(http_connection_t* hc) { http_arg_list_t args; - const char *arg; - char *u = tvh_strdupa(hc->hc_url); - session_t *rs; - htsbuf_queue_t q; - char buf[96], buf1[46]; - const char *used_ip = NULL; - int r = HTTP_STATUS_BAD_REQUEST; - int stream, first = 1, valid, used_port; + const char* arg; + char* u = tvh_strdupa(hc->hc_url); + session_t* rs; + htsbuf_queue_t q; + char buf[96], buf1[46]; + const char* used_ip = NULL; + int r = HTTP_STATUS_BAD_REQUEST; + int stream, first = 1, valid, used_port; htsbuf_queue_init(&q, 0); @@ -1475,7 +1556,7 @@ rtsp_process_describe(http_connection_t *hc) } } - TAILQ_FOREACH(rs, &rtsp_sessions, link) { + TAILQ_FOREACH (rs, &rtsp_sessions, link) { if (hc->hc_session) { if (strcmp(hc->hc_session, rs->session)) continue; @@ -1483,8 +1564,7 @@ rtsp_process_describe(http_connection_t *hc) } if (stream > 0 && rs->stream != stream) continue; - if (satip_server_conf.satip_anonymize && - strcmp(hc->hc_peer_ipstr, rs->peer_ipstr)) + if (satip_server_conf.satip_anonymize && strcmp(hc->hc_peer_ipstr, rs->peer_ipstr)) continue; if (first) { rtsp_describe_header(hc->hc_session ? rs : NULL, &q); @@ -1516,8 +1596,16 @@ rtsp_process_describe(http_connection_t *hc) snprintf(buf, sizeof(buf), "rtsp://%s", used_ip); http_arg_set(&args, "Content-Base", buf); http_send_begin(hc); - http_send_header(hc, HTTP_STATUS_OK, "application/sdp", q.hq_size, - NULL, NULL, 0, NULL, NULL, &args); + http_send_header(hc, + HTTP_STATUS_OK, + "application/sdp", + q.hq_size, + NULL, + NULL, + 0, + NULL, + NULL, + &args); tcp_write_queue(hc->hc_fd, &q); http_send_end(hc); http_arg_flush(&args); @@ -1533,13 +1621,11 @@ error: /* * */ -static int -rtsp_process_play(http_connection_t *hc, int cmd) -{ - session_t *rs; - int errcode = HTTP_STATUS_BAD_REQUEST, valid = 0, i, stream, used_port; - char buf[256], buf1[46], *u = tvh_strdupa(hc->hc_url); - const char *used_ip = NULL; +static int rtsp_process_play(http_connection_t* hc, int cmd) { + session_t* rs; + int errcode = HTTP_STATUS_BAD_REQUEST, valid = 0, i, stream, used_port; + char buf[256], buf1[46], *u = tvh_strdupa(hc->hc_url); + const char* used_ip = NULL; http_arg_list_t args; http_arg_init(&args); @@ -1554,25 +1640,32 @@ rtsp_process_play(http_connection_t *hc, int cmd) errcode = rtsp_parse_cmd(hc, stream, cmd, &rs, &valid); - if (errcode) goto error; + if (errcode) + goto error; - if (cmd == RTSP_CMD_SETUP && rs->rtp_peer_port != RTSP_TCP_DATA && - !rs->rtp_udp_bound) { - if (udp_bind_double(&rs->udp_rtp, &rs->udp_rtcp, - LS_SATIPS, "rtsp", "rtcp", - (rtp_src_ip != NULL && rtp_src_ip[0] != '\0') ? rtp_src_ip : rtsp_ip, 0, NULL, - 4*1024, 4*1024, - RTP_BUFSIZE, RTCP_BUFSIZE)) { + if (cmd == RTSP_CMD_SETUP && rs->rtp_peer_port != RTSP_TCP_DATA && !rs->rtp_udp_bound) { + if (udp_bind_double(&rs->udp_rtp, + &rs->udp_rtcp, + LS_SATIPS, + "rtsp", + "rtcp", + (rtp_src_ip != NULL && rtp_src_ip[0] != '\0') ? rtp_src_ip : rtsp_ip, + 0, + NULL, + 4 * 1024, + 4 * 1024, + RTP_BUFSIZE, + RTCP_BUFSIZE)) { errcode = HTTP_STATUS_INTERNAL; goto error; } - if (udp_connect(rs->udp_rtp, "RTP", hc->hc_peer_ipstr, rs->rtp_peer_port) || + if (udp_connect(rs->udp_rtp, "RTP", hc->hc_peer_ipstr, rs->rtp_peer_port) || udp_connect(rs->udp_rtcp, "RTCP", hc->hc_peer_ipstr, rs->rtp_peer_port + 1)) { udp_close(rs->udp_rtp); rs->udp_rtp = NULL; udp_close(rs->udp_rtcp); rs->udp_rtcp = NULL; - errcode = HTTP_STATUS_INTERNAL; + errcode = HTTP_STATUS_INTERNAL; goto error; } rs->rtp_udp_bound = 1; @@ -1591,7 +1684,7 @@ rtsp_process_play(http_connection_t *hc, int cmd) if (i == RTSP_TCP_DATA) { snprintf(buf, sizeof(buf), "RTP/AVP/TCP;interleaved=0-1"); } else { - snprintf(buf, sizeof(buf), "RTP/AVP;unicast;client_port=%d-%d", i, i+1); + snprintf(buf, sizeof(buf), "RTP/AVP;unicast;client_port=%d-%d", i, i + 1); } http_arg_set(&args, "Transport", buf); snprintf(buf, sizeof(buf), "%d", rs->stream); @@ -1626,23 +1719,24 @@ end: /* * */ -static int -rtsp_process_teardown(http_connection_t *hc) -{ - char *u = tvh_strdupa(hc->hc_url); - struct session *rs = NULL; +static int rtsp_process_teardown(http_connection_t* hc) { + char* u = tvh_strdupa(hc->hc_url); + struct session* rs = NULL; http_arg_list_t args; - char session[16]; - int stream; + char session[16]; + int stream; - if ((u = rtsp_check_urlbase(u)) == NULL || - (stream = rtsp_parse_args(hc, u)) < 0) { + if ((u = rtsp_check_urlbase(u)) == NULL || (stream = rtsp_parse_args(hc, u)) < 0) { http_error(hc, HTTP_STATUS_BAD_REQUEST); return 0; } - tvhdebug(LS_SATIPS, "-/%s/%i: teardown from %s:%d", - hc->hc_session, stream, hc->hc_peer_ipstr, ntohs(IP_PORT(*hc->hc_peer))); + tvhdebug(LS_SATIPS, + "-/%s/%i: teardown from %s:%d", + hc->hc_session, + stream, + hc->hc_peer_ipstr, + ntohs(IP_PORT(*hc->hc_peer))); tvh_mutex_lock(&rtsp_lock); rs = rtsp_find_session(hc, stream); @@ -1667,31 +1761,27 @@ rtsp_process_teardown(http_connection_t *hc) /** * Process a RTSP request */ -static int -rtsp_process_request(http_connection_t *hc, htsbuf_queue_t *spill) -{ +static int rtsp_process_request(http_connection_t* hc, htsbuf_queue_t* spill) { switch (hc->hc_cmd) { - case RTSP_CMD_OPTIONS: - return rtsp_process_options(hc); - case RTSP_CMD_DESCRIBE: - return rtsp_process_describe(hc); - case RTSP_CMD_SETUP: - case RTSP_CMD_PLAY: - return rtsp_process_play(hc, hc->hc_cmd); - case RTSP_CMD_TEARDOWN: - return rtsp_process_teardown(hc); - default: - http_error(hc, HTTP_STATUS_BAD_REQUEST); - return 0; + case RTSP_CMD_OPTIONS: + return rtsp_process_options(hc); + case RTSP_CMD_DESCRIBE: + return rtsp_process_describe(hc); + case RTSP_CMD_SETUP: + case RTSP_CMD_PLAY: + return rtsp_process_play(hc, hc->hc_cmd); + case RTSP_CMD_TEARDOWN: + return rtsp_process_teardown(hc); + default: + http_error(hc, HTTP_STATUS_BAD_REQUEST); + return 0; } } /* * */ -static void -rtsp_flush_requests(http_connection_t *hc) -{ +static void rtsp_flush_requests(http_connection_t* hc) { struct session *rs, *rs_next; tvh_mutex_lock(&rtsp_lock); @@ -1703,8 +1793,8 @@ rtsp_flush_requests(http_connection_t *hc) } else if (rs->tcp_data == hc) { satip_rtp_close(rs->rtp_handle); rs->rtp_handle = NULL; - rs->tcp_data = NULL; - rs->state = STATE_SETUP; + rs->tcp_data = NULL; + rs->state = STATE_SETUP; } } tvh_mutex_unlock(&rtsp_lock); @@ -1713,15 +1803,13 @@ rtsp_flush_requests(http_connection_t *hc) /* * */ -static void -rtsp_stream_status ( void *opaque, htsmsg_t *m ) -{ - http_connection_t *hc = opaque; - char buf[128]; - const char *username; - struct session *rs = NULL; - htsmsg_t *c, *tcp = NULL, *udp = NULL; - int udpport, s32; +static void rtsp_stream_status(void* opaque, htsmsg_t* m) { + http_connection_t* hc = opaque; + char buf[128]; + const char* username; + struct session* rs = NULL; + htsmsg_t * c, *tcp = NULL, *udp = NULL; + int udpport, s32; htsmsg_add_str(m, "type", "SAT>IP"); if (hc->hc_proxy_ip) { @@ -1732,28 +1820,30 @@ rtsp_stream_status ( void *opaque, htsmsg_t *m ) if (username) htsmsg_add_str(m, "user", username); - TAILQ_FOREACH(rs, &rtsp_sessions, link) { - if (hc->hc_session && - strcmp(rs->session, hc->hc_session) == 0 && - strcmp(rs->peer_ipstr, hc->hc_peer_ipstr) == 0 && - (udpport = rs->rtp_peer_port) > 0) { + TAILQ_FOREACH (rs, &rtsp_sessions, link) { + if (hc->hc_session && strcmp(rs->session, hc->hc_session) == 0 && + strcmp(rs->peer_ipstr, hc->hc_peer_ipstr) == 0 && (udpport = rs->rtp_peer_port) > 0) { if (udpport == RTSP_TCP_DATA) { if (rs->tcp_data == hc) { s32 = htsmsg_get_s32_or_default(m, "peer_port", -1); - if (!tcp) tcp = htsmsg_create_list(); + if (!tcp) + tcp = htsmsg_create_list(); htsmsg_add_s32(tcp, NULL, s32); } } else { - if (!udp) udp = htsmsg_create_list(); + if (!udp) + udp = htsmsg_create_list(); htsmsg_add_s32(udp, NULL, udpport); - htsmsg_add_s32(udp, NULL, udpport+1); + htsmsg_add_s32(udp, NULL, udpport + 1); } } } if (tcp || udp) { c = htsmsg_create_map(); - if (tcp) htsmsg_add_msg(c, "tcp", tcp); - if (udp) htsmsg_add_msg(c, "udp", udp); + if (tcp) + htsmsg_add_msg(c, "tcp", tcp); + if (udp) + htsmsg_add_msg(c, "udp", udp); htsmsg_add_msg(m, "peer_extra_ports", c); } } @@ -1762,13 +1852,11 @@ rtsp_stream_status ( void *opaque, htsmsg_t *m ) * */ static void -rtsp_serve(int fd, void **opaque, struct sockaddr_storage *peer, - struct sockaddr_storage *self) -{ +rtsp_serve(int fd, void** opaque, struct sockaddr_storage* peer, struct sockaddr_storage* self) { http_connection_t hc; - access_t aa; - char buf[128]; - void *tcp; + access_t aa; + char buf[128]; + void* tcp; memset(&hc, 0, sizeof(http_connection_t)); *opaque = &hc; @@ -1806,20 +1894,18 @@ rtsp_serve(int fd, void **opaque, struct sockaddr_storage *peer, /* * */ -static void -rtsp_close_session(session_t *rs) -{ +static void rtsp_close_session(session_t* rs) { satip_rtp_close(rs->rtp_handle); rs->rtp_handle = NULL; - rs->playing = 0; - rs->state = STATE_DESCRIBE; + rs->playing = 0; + rs->state = STATE_DESCRIBE; udp_close(rs->udp_rtp); rs->udp_rtp = NULL; udp_close(rs->udp_rtcp); - rs->udp_rtcp = NULL; - rs->rtp_udp_bound = 0; + rs->udp_rtcp = NULL; + rs->rtp_udp_bound = 0; rs->shutdown_on_close = NULL; - rs->tcp_data = NULL; + rs->tcp_data = NULL; tvh_mutex_lock(&global_lock); mpegts_pid_reset(&rs->pids); rtsp_clean(rs, 1); @@ -1830,9 +1916,7 @@ rtsp_close_session(session_t *rs) /* * */ -static void -rtsp_free_session(session_t *rs) -{ +static void rtsp_free_session(session_t* rs) { TAILQ_REMOVE(&rtsp_sessions, rs, link); tvh_mutex_lock(&global_lock); mtimer_disarm(&rs->timer); @@ -1845,10 +1929,8 @@ rtsp_free_session(session_t *rs) /* * */ -static void -rtsp_close_sessions(void) -{ - session_t *rs; +static void rtsp_close_sessions(void) { + session_t* rs; do { tvh_mutex_lock(&rtsp_lock); rs = TAILQ_FIRST(&rtsp_sessions); @@ -1863,21 +1945,21 @@ rtsp_close_sessions(void) /* * */ -void satip_server_rtsp_init - (const char *bindaddr, int port, int descramble, int rewrite_pmt, int muxcnf, - const char *rtp_src, const char *nat_ip, int nat_port) -{ - static tcp_server_ops_t ops = { - .start = rtsp_serve, - .stop = NULL, - .cancel = http_cancel - }; - int reg = 0; - uint8_t rnd[4]; - char *s; +void satip_server_rtsp_init(const char* bindaddr, + int port, + int descramble, + int rewrite_pmt, + int muxcnf, + const char* rtp_src, + const char* nat_ip, + int nat_port) { + static tcp_server_ops_t ops = {.start = rtsp_serve, .stop = NULL, .cancel = http_cancel}; + int reg = 0; + uint8_t rnd[4]; + char* s; if (!rtsp_server) { uuid_random(rnd, sizeof(rnd)); - session_number = *(uint32_t *)rnd; + session_number = *(uint32_t*)rnd; TAILQ_INIT(&rtsp_sessions); tvh_mutex_init(&rtsp_lock, NULL); satip_rtp_init(1); @@ -1886,19 +1968,19 @@ void satip_server_rtsp_init rtsp_close_sessions(); tcp_server_delete(rtsp_server); rtsp_server = NULL; - reg = 1; + reg = 1; } - s = rtsp_ip; + s = rtsp_ip; rtsp_ip = strdup(bindaddr); free(s); - rtsp_port = port; - rtsp_descramble = descramble; + rtsp_port = port; + rtsp_descramble = descramble; rtsp_rewrite_pmt = rewrite_pmt; - rtsp_muxcnf = muxcnf; - s = rtp_src_ip; - rtp_src_ip = rtp_src ? strdup(rtp_src) : NULL; + rtsp_muxcnf = muxcnf; + s = rtp_src_ip; + rtp_src_ip = rtp_src ? strdup(rtp_src) : NULL; free(s); - s = rtsp_nat_ip; + s = rtsp_nat_ip; rtsp_nat_ip = nat_ip ? strdup(nat_ip) : NULL; free(s); rtsp_nat_port = nat_port; @@ -1908,14 +1990,12 @@ void satip_server_rtsp_init tcp_server_register(rtsp_server); } -void satip_server_rtsp_register(void) -{ +void satip_server_rtsp_register(void) { tcp_server_register(rtsp_server); satip_rtp_init(0); } -void satip_server_rtsp_done(void) -{ +void satip_server_rtsp_done(void) { tvh_mutex_lock(&global_lock); if (rtsp_server) tcp_server_delete(rtsp_server); @@ -1923,8 +2003,8 @@ void satip_server_rtsp_done(void) if (rtsp_server) rtsp_close_sessions(); tvh_mutex_lock(&global_lock); - rtsp_server = NULL; - rtsp_port = -1; + rtsp_server = NULL; + rtsp_port = -1; rtsp_nat_port = -1; free(rtsp_ip); free(rtp_src_ip); diff --git a/src/satip/server.c b/src/satip/server.c index 401fd6b63..7247958a0 100644 --- a/src/satip/server.c +++ b/src/satip/server.c @@ -27,24 +27,23 @@ #define UPNP_MAX_AGE 1800 -static char *http_server_ip; -static int http_server_port; -static int satip_server_deviceid; -static time_t satip_server_bootid; -static char *satip_server_bindaddr; -static int satip_server_rtsp_port; -static int satip_server_rtsp_port_locked; -static upnp_service_t *satips_upnp_discovery; -static tvh_mutex_t satip_server_reinit; -static int bound_port; +static char* http_server_ip; +static int http_server_port; +static int satip_server_deviceid; +static time_t satip_server_bootid; +static char* satip_server_bindaddr; +static int satip_server_rtsp_port; +static int satip_server_rtsp_port_locked; +static upnp_service_t* satips_upnp_discovery; +static tvh_mutex_t satip_server_reinit; +static int bound_port; static void satip_server_save(void); /* * */ -int satip_server_match_uuid(const char *uuid) -{ +int satip_server_match_uuid(const char* uuid) { return strcmp(uuid ?: "", satip_server_conf.satip_uuid ?: "") == 0; } @@ -53,15 +52,14 @@ int satip_server_match_uuid(const char *uuid) */ struct xml_type_xtab { - const char *id; - int *cptr; - int *count; + const char* id; + int* cptr; + int* count; }; -static int -satip_server_http_xml(http_connection_t *hc) -{ -#define MSG "\ +static int satip_server_http_xml(http_connection_t* hc) { +#define MSG \ + "\ \n\ \n\ 11\n\ @@ -112,28 +110,26 @@ satip_server_http_xml(http_connection_t *hc) \n\ \n" - char buf[sizeof(MSG) + 1024], buf2[64], purl[128]; - const char *cs; - char *devicelist = NULL; - htsbuf_queue_t q; - mpegts_network_t *mn; - int dvbt = 0, dvbs = 0, dvbc = 0, atsc = 0, isdbt = 0; - int srcs = 0, delim = 0, tuners = 0, i, satipm3u = 0; - struct xml_type_xtab *p; - http_arg_list_t args; - - struct xml_type_xtab xtab[] = { - { "DVBS", &satip_server_conf.satip_dvbs, &dvbs }, - { "DVBS2", &satip_server_conf.satip_dvbs2, &dvbs }, - { "DVBT", &satip_server_conf.satip_dvbt, &dvbt }, - { "DVBT2", &satip_server_conf.satip_dvbt2, &dvbt }, - { "DVBC", &satip_server_conf.satip_dvbc, &dvbc }, - { "DVBC2", &satip_server_conf.satip_dvbc2, &dvbc }, - { "ATSCT", &satip_server_conf.satip_atsc_t, &atsc }, - { "ATSCC", &satip_server_conf.satip_atsc_c, &atsc }, - { "ISDBT", &satip_server_conf.satip_isdb_t, &isdbt }, - {} - }; + char buf[sizeof(MSG) + 1024], buf2[64], purl[128]; + const char* cs; + char* devicelist = NULL; + htsbuf_queue_t q; + mpegts_network_t* mn; + int dvbt = 0, dvbs = 0, dvbc = 0, atsc = 0, isdbt = 0; + int srcs = 0, delim = 0, tuners = 0, i, satipm3u = 0; + struct xml_type_xtab* p; + http_arg_list_t args; + + struct xml_type_xtab xtab[] = {{"DVBS", &satip_server_conf.satip_dvbs, &dvbs}, + {"DVBS2", &satip_server_conf.satip_dvbs2, &dvbs}, + {"DVBT", &satip_server_conf.satip_dvbt, &dvbt}, + {"DVBT2", &satip_server_conf.satip_dvbt2, &dvbt}, + {"DVBC", &satip_server_conf.satip_dvbc, &dvbc}, + {"DVBC2", &satip_server_conf.satip_dvbc2, &dvbc}, + {"ATSCT", &satip_server_conf.satip_atsc_t, &atsc}, + {"ATSCC", &satip_server_conf.satip_atsc_c, &atsc}, + {"ISDBT", &satip_server_conf.satip_isdb_t, &isdbt}, + {}}; if (http_server_ip == NULL) return HTTP_STATUS_NOT_FOUND; @@ -141,7 +137,7 @@ satip_server_http_xml(http_connection_t *hc) htsbuf_queue_init(&q, 0); tvh_mutex_lock(&global_lock); - LIST_FOREACH(mn, &mpegts_network_all, mn_global_link) { + LIST_FOREACH (mn, &mpegts_network_all, mn_global_link) { if (mn->mn_satip_source == 0) continue; if (idnode_is_instance(&mn->mn_id, &dvb_network_dvbt_class)) @@ -158,15 +154,15 @@ satip_server_http_xml(http_connection_t *hc) isdbt++; #if ENABLE_IPTV else if (idnode_is_instance(&mn->mn_id, &iptv_network_class)) { - mpegts_mux_t *mm; - LIST_FOREACH(mm, &mn->mn_muxes, mm_network_link) { - if (((iptv_mux_t *)mm)->mm_iptv_satip_dvbt_freq) { + mpegts_mux_t* mm; + LIST_FOREACH (mm, &mn->mn_muxes, mm_network_link) { + if (((iptv_mux_t*)mm)->mm_iptv_satip_dvbt_freq) { dvbt++; } - if (((iptv_mux_t *)mm)->mm_iptv_satip_dvbc_freq) { + if (((iptv_mux_t*)mm)->mm_iptv_satip_dvbc_freq) { dvbc++; } - if (((iptv_mux_t *)mm)->mm_iptv_satip_dvbs_freq) { + if (((iptv_mux_t*)mm)->mm_iptv_satip_dvbs_freq) { dvbs++; } } @@ -174,11 +170,16 @@ satip_server_http_xml(http_connection_t *hc) #endif } // The SAT>IP specification only supports 1-9 tuners (1 digit)! - if (dvbt > 9) dvbt = 9; - if (dvbc > 9) dvbc = 9; - if (dvbs > 9) dvbs = 9; - if (atsc > 9) atsc = 9; - if (isdbt > 9) isdbt = 9; + if (dvbt > 9) + dvbt = 9; + if (dvbc > 9) + dvbc = 9; + if (dvbs > 9) + dvbs = 9; + if (atsc > 9) + atsc = 9; + if (isdbt > 9) + isdbt = 9; for (p = xtab; p->id; p++) { i = *p->cptr; if (i > 0) { @@ -197,14 +198,20 @@ satip_server_http_xml(http_connection_t *hc) htsbuf_queue_flush(&q); if (devicelist == NULL || devicelist[0] == '\0') { - tvhwarn(LS_SATIPS, "SAT>IP server announces an empty tuner list to a client %s (missing %s)", - hc->hc_peer_ipstr, !tuners ? "tuner settings - global config" : "network assignment"); + tvhwarn(LS_SATIPS, + "SAT>IP server announces an empty tuner list to a client %s (missing %s)", + hc->hc_peer_ipstr, + !tuners ? "tuner settings - global config" : "network assignment"); } if (satip_server_rtsp_port != 554) - snprintf(buf2, sizeof(buf2), ":%d %s", satip_server_rtsp_port, satip_server_conf.satip_uuid + 26); + snprintf(buf2, + sizeof(buf2), + ":%d %s", + satip_server_rtsp_port, + satip_server_conf.satip_uuid + 26); else - snprintf(buf2, sizeof(buf2), " %s", satip_server_conf.satip_uuid + 26); + snprintf(buf2, sizeof(buf2), " %s", satip_server_conf.satip_uuid + 26); if (!hts_settings_buildpath(buf, sizeof(buf), "satip.m3u")) satipm3u = access(buf, R_OK) == 0; @@ -217,21 +224,32 @@ satip_server_http_xml(http_connection_t *hc) } else { cs = "playlist/satip/channels"; } - snprintf(purl, sizeof(purl), - "%s/%s\n", - tvheadend_webroot ?: "", cs); + snprintf(purl, + sizeof(purl), + "%s/%s\n", + tvheadend_webroot ?: "", + cs); } - snprintf(buf, sizeof(buf), MSG, - config_get_server_name(), - buf2, tvheadend_version, - satip_server_conf.satip_uuid, - http_server_ip, http_server_port, - http_server_ip, http_server_port, - http_server_ip, http_server_port, - http_server_ip, http_server_port, - http_server_ip, http_server_port, - devicelist ?: "", purl); + snprintf(buf, + sizeof(buf), + MSG, + config_get_server_name(), + buf2, + tvheadend_version, + satip_server_conf.satip_uuid, + http_server_ip, + http_server_port, + http_server_ip, + http_server_port, + http_server_ip, + http_server_port, + http_server_ip, + http_server_port, + http_server_ip, + http_server_port, + devicelist ?: "", + purl); free(devicelist); @@ -254,9 +272,7 @@ satip_server_http_xml(http_connection_t *hc) #undef MSG } -static int -satip_server_satip_m3u(http_connection_t *hc) -{ +static int satip_server_satip_m3u(http_connection_t* hc) { char path[PATH_MAX]; if (hts_settings_buildpath(path, sizeof(path), "satip.m3u")) @@ -265,10 +281,7 @@ satip_server_satip_m3u(http_connection_t *hc) return http_serve_file(hc, path, 0, MIME_M3U, NULL, NULL, NULL, NULL); } -int -satip_server_http_page(http_connection_t *hc, - const char *remain, void *opaque) -{ +int satip_server_http_page(http_connection_t* hc, const char* remain, void* opaque) { if (remain && strcmp(remain, "desc.xml") == 0) return satip_server_http_xml(hc); if (remain && strcmp(remain, "satip.m3u") == 0) @@ -280,10 +293,9 @@ satip_server_http_page(http_connection_t *hc, * Discovery */ -static void -satips_upnp_send_byebye(void) -{ -#define MSG "\ +static void satips_upnp_send_byebye(void) { +#define MSG \ + "\ NOTIFY * HTTP/1.1\r\n\ HOST: 239.255.255.250:1900\r\n\ NT: %s\r\n\ @@ -293,9 +305,9 @@ BOOTID.UPNP.ORG: %ld\r\n\ CONFIGID.UPNP.ORG: 0\r\n\ \r\n\r\n" - int attempt; - char buf[512], buf2[50]; - const char *nt, *usn2; + int attempt; + char buf[512], buf2[50]; + const char * nt, *usn2; htsbuf_queue_t q; if (satips_upnp_discovery == NULL || satip_server_rtsp_port <= 0) @@ -305,25 +317,30 @@ CONFIGID.UPNP.ORG: 0\r\n\ for (attempt = 1; attempt <= 3; attempt++) { switch (attempt) { - case 1: - nt = "upnp:rootdevice"; - usn2 = "::upnp:rootdevice"; - break; - case 2: - snprintf(buf2, sizeof(buf2), "uuid:%s", satip_server_conf.satip_uuid); - nt = buf2; - usn2 = ""; - break; - case 3: - nt = "urn:ses-com:device:SatIPServer:1"; - usn2 = "::urn:ses-com:device:SatIPServer:1"; - break; - default: - abort(); + case 1: + nt = "upnp:rootdevice"; + usn2 = "::upnp:rootdevice"; + break; + case 2: + snprintf(buf2, sizeof(buf2), "uuid:%s", satip_server_conf.satip_uuid); + nt = buf2; + usn2 = ""; + break; + case 3: + nt = "urn:ses-com:device:SatIPServer:1"; + usn2 = "::urn:ses-com:device:SatIPServer:1"; + break; + default: + abort(); } - snprintf(buf, sizeof(buf), MSG, nt, satip_server_conf.satip_uuid, - usn2, (long)satip_server_bootid); + snprintf(buf, + sizeof(buf), + MSG, + nt, + satip_server_conf.satip_uuid, + usn2, + (long)satip_server_bootid); htsbuf_queue_init(&q, 0); htsbuf_append_str(&q, buf); @@ -333,10 +350,9 @@ CONFIGID.UPNP.ORG: 0\r\n\ #undef MSG } -static void -satips_upnp_send_announce(void) -{ -#define MSG "\ +static void satips_upnp_send_announce(void) { +#define MSG \ + "\ NOTIFY * HTTP/1.1\r\n\ HOST: 239.255.255.250:1900\r\n\ CACHE-CONTROL: max-age=%d\r\n\ @@ -349,9 +365,9 @@ BOOTID.UPNP.ORG: %ld\r\n\ CONFIGID.UPNP.ORG: 0\r\n\ DEVICEID.SES.COM: %d\r\n\r\n" - int attempt; - char buf[512], buf2[50]; - const char *nt, *usn2; + int attempt; + char buf[512], buf2[50]; + const char * nt, *usn2; htsbuf_queue_t q; if (satips_upnp_discovery == NULL || satip_server_rtsp_port <= 0) @@ -361,28 +377,36 @@ DEVICEID.SES.COM: %d\r\n\r\n" for (attempt = 1; attempt <= 3; attempt++) { switch (attempt) { - case 1: - nt = "upnp:rootdevice"; - usn2 = "::upnp:rootdevice"; - break; - case 2: - snprintf(buf2, sizeof(buf2), "uuid:%s", satip_server_conf.satip_uuid); - nt = buf2; - usn2 = ""; - break; - case 3: - nt = "urn:ses-com:device:SatIPServer:1"; - usn2 = "::urn:ses-com:device:SatIPServer:1"; - break; - default: - abort(); + case 1: + nt = "upnp:rootdevice"; + usn2 = "::upnp:rootdevice"; + break; + case 2: + snprintf(buf2, sizeof(buf2), "uuid:%s", satip_server_conf.satip_uuid); + nt = buf2; + usn2 = ""; + break; + case 3: + nt = "urn:ses-com:device:SatIPServer:1"; + usn2 = "::urn:ses-com:device:SatIPServer:1"; + break; + default: + abort(); } - snprintf(buf, sizeof(buf), MSG, UPNP_MAX_AGE, - http_server_ip, http_server_port, tvheadend_webroot ?: "", - nt, tvheadend_version, - satip_server_conf.satip_uuid, usn2, (long)satip_server_bootid, - satip_server_deviceid); + snprintf(buf, + sizeof(buf), + MSG, + UPNP_MAX_AGE, + http_server_ip, + http_server_port, + tvheadend_webroot ?: "", + nt, + tvheadend_version, + satip_server_conf.satip_uuid, + usn2, + (long)satip_server_bootid, + satip_server_deviceid); htsbuf_queue_init(&q, 0); htsbuf_append_str(&q, buf); @@ -392,11 +416,11 @@ DEVICEID.SES.COM: %d\r\n\r\n" #undef MSG } -static void -satips_upnp_send_discover_reply - (struct sockaddr_storage *dst, const char *deviceid, int from_multicast) -{ -#define MSG "\ +static void satips_upnp_send_discover_reply(struct sockaddr_storage* dst, + const char* deviceid, + int from_multicast) { +#define MSG \ + "\ HTTP/1.1 200 OK\r\n\ CACHE-CONTROL: max-age=%d\r\n\ EXT:\r\n\ @@ -407,8 +431,8 @@ USN: uuid:%s::urn:ses-com:device:SatIPServer:1\r\n\ BOOTID.UPNP.ORG: %ld\r\n\ CONFIGID.UPNP.ORG: 0\r\n" - char buf[512]; - htsbuf_queue_t q; + char buf[512]; + htsbuf_queue_t q; struct sockaddr_storage storage; if (satips_upnp_discovery == NULL || satip_server_rtsp_port <= 0) @@ -416,14 +440,24 @@ CONFIGID.UPNP.ORG: 0\r\n" if (tvhtrace_enabled()) { tcp_get_str_from_ip(dst, buf, sizeof(buf)); - tvhtrace(LS_SATIPS, "sending discover reply to %s:%d%s%s", - buf, ntohs(IP_PORT(*dst)), deviceid ? " device: " : "", deviceid ?: ""); + tvhtrace(LS_SATIPS, + "sending discover reply to %s:%d%s%s", + buf, + ntohs(IP_PORT(*dst)), + deviceid ? " device: " : "", + deviceid ?: ""); } - snprintf(buf, sizeof(buf), MSG, UPNP_MAX_AGE, - http_server_ip, http_server_port, tvheadend_webroot ?: "", - tvheadend_version, - satip_server_conf.satip_uuid, (long)satip_server_bootid); + snprintf(buf, + sizeof(buf), + MSG, + UPNP_MAX_AGE, + http_server_ip, + http_server_port, + tvheadend_webroot ?: "", + tvheadend_version, + satip_server_conf.satip_uuid, + (long)satip_server_bootid); htsbuf_queue_init(&q, 0); htsbuf_append_str(&q, buf); @@ -436,17 +470,16 @@ CONFIGID.UPNP.ORG: 0\r\n" #undef MSG } -static void -satips_upnp_discovery_received - (uint8_t *data, size_t len, udp_connection_t *conn, - struct sockaddr_storage *storage) -{ +static void satips_upnp_discovery_received(uint8_t* data, + size_t len, + udp_connection_t* conn, + struct sockaddr_storage* storage) { #define MSEARCH "M-SEARCH * HTTP/1.1" char *buf, *ptr, *saveptr; - char *argv[10]; + char* argv[10]; char *st = NULL, *man = NULL, *host = NULL, *deviceid = NULL, *searchport = NULL; - char buf2[64]; + char buf2[64]; if (satip_server_rtsp_port <= 0) return; @@ -454,15 +487,15 @@ satips_upnp_discovery_received if (len < 32 || len > 8191) return; - if (strncmp((char *)data, MSEARCH, sizeof(MSEARCH)-1)) + if (strncmp((char*)data, MSEARCH, sizeof(MSEARCH) - 1)) return; #undef MSEARCH - buf = alloca(len+1); + buf = alloca(len + 1); memcpy(buf, data, len); buf[len] = '\0'; - ptr = strtok_r(buf, "\r\n", &saveptr); + ptr = strtok_r(buf, "\r\n", &saveptr); /* Request decoder */ if (ptr) { if (http_tokenize(ptr, argv, 3, -1) != 3) @@ -522,9 +555,11 @@ satips_upnp_discovery_received if (tvhtrace_enabled()) { tcp_get_str_from_ip(storage, buf2, sizeof(buf2)); - tvhtrace(LS_SATIPS, "received %s M-SEARCH from %s:%d", - conn->multicast ? "multicast" : "unicast", - buf2, ntohs(IP_PORT(*storage))); + tvhtrace(LS_SATIPS, + "received %s M-SEARCH from %s:%d", + conn->multicast ? "multicast" : "unicast", + buf2, + ntohs(IP_PORT(*storage))); } /* Check for deviceid collision */ @@ -534,8 +569,12 @@ satips_upnp_discovery_received if (satip_server_deviceid >= 254) satip_server_deviceid = 1; tcp_get_str_from_ip(storage, buf2, sizeof(buf2)); - tvhwarn(LS_SATIPS, "received duplicate SAT>IP DeviceID %s from %s:%d, using %d", - deviceid, buf2, ntohs(IP_PORT(*storage)), satip_server_deviceid); + tvhwarn(LS_SATIPS, + "received duplicate SAT>IP DeviceID %s from %s:%d, using %d", + deviceid, + buf2, + ntohs(IP_PORT(*storage)), + satip_server_deviceid); satips_upnp_send_discover_reply(storage, deviceid, 0); satips_upnp_send_byebye(); satips_upnp_send_announce(); @@ -547,17 +586,14 @@ satips_upnp_discovery_received } } -static void -satips_upnp_discovery_destroy(upnp_service_t *upnp) -{ +static void satips_upnp_discovery_destroy(upnp_service_t* upnp) { satips_upnp_discovery = NULL; } /* * */ -static void satips_rtsp_port(int def) -{ +static void satips_rtsp_port(int def) { int rtsp_port = satip_server_rtsp_port; if (!satip_server_rtsp_port_locked) rtsp_port = satip_server_conf.satip_rtsp > 0 ? satip_server_conf.satip_rtsp : def; @@ -566,28 +602,28 @@ static void satips_rtsp_port(int def) rtsp_port = 9983; } satip_server_rtsp_port = rtsp_port; - } /* * */ -static void satip_server_info(const char *prefix, int descramble, int muxcnf) -{ - int fe, findex; - const char *ftype; +static void satip_server_info(const char* prefix, int descramble, int muxcnf) { + int fe, findex; + const char* ftype; if (satip_server_rtsp_port <= 0) { tvhinfo(LS_SATIPS, "SAT>IP Server inactive"); return; } tvhinfo(LS_SATIPS, "SAT>IP Server %sinitialized", prefix); - tvhinfo(LS_SATIPS, " HTTP %s:%d, RTSP %s:%d", - http_server_ip, http_server_port, - http_server_ip, satip_server_rtsp_port); - tvhinfo(LS_SATIPS, " descramble %d, muxcnf %d", - descramble, muxcnf); + tvhinfo(LS_SATIPS, + " HTTP %s:%d, RTSP %s:%d", + http_server_ip, + http_server_port, + http_server_ip, + satip_server_rtsp_port); + tvhinfo(LS_SATIPS, " descramble %d, muxcnf %d", descramble, muxcnf); for (fe = 1; fe <= 128; fe++) { if (satip_rtsp_delsys(fe, &findex, &ftype) == DVB_TYPE_NONE) break; @@ -599,40 +635,35 @@ static void satip_server_info(const char *prefix, int descramble, int muxcnf) * Node Simple Class */ struct satip_server_conf satip_server_conf = { - .idnode.in_class = &satip_server_class, - .satip_descramble = 1, - .satip_weight = 100, - .satip_allow_remote_weight = 1, - .satip_iptv_sig_level = 220, + .idnode.in_class = &satip_server_class, + .satip_descramble = 1, + .satip_weight = 100, + .satip_allow_remote_weight = 1, + .satip_iptv_sig_level = 220, }; -static void satip_server_class_changed(idnode_t *self) -{ +static void satip_server_class_changed(idnode_t* self) { idnode_changed(&config.idnode); satip_server_save(); } -static htsmsg_t *satip_server_class_muxcfg_list ( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("Auto"), MUXCNF_AUTO }, - { N_("Keep"), MUXCNF_KEEP }, - { N_("Reject"), MUXCNF_REJECT }, - { N_("Reject exact match"), MUXCNF_REJECT_EXACT_MATCH } - }; +static htsmsg_t* satip_server_class_muxcfg_list(void* o, const char* lang) { + static const struct strtab tab[] = {{N_("Auto"), MUXCNF_AUTO}, + {N_("Keep"), MUXCNF_KEEP}, + {N_("Reject"), MUXCNF_REJECT}, + {N_("Reject exact match"), MUXCNF_REJECT_EXACT_MATCH}}; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t *satip_server_class_rtptcpsize_list ( void *o, const char *lang ) -{ +static htsmsg_t* satip_server_class_rtptcpsize_list(void* o, const char* lang) { static const struct strtab tab[] = { - { N_("1316 bytes"), 1316/188 }, - { N_("2632 bytes"), 2632/188 }, - { N_("5264 bytes"), 5264/188 }, - { N_("7896 bytes"), 7896/188 }, - { N_("16356 bytes"), 16356/188 }, - { N_("32712 bytes"), 32712/188 }, - { N_("65424 bytes"), 65424/188 }, + {N_("1316 bytes"), 1316 / 188}, + {N_("2632 bytes"), 2632 / 188}, + {N_("5264 bytes"), 5264 / 188}, + {N_("7896 bytes"), 7896 / 188}, + {N_("16356 bytes"), 16356 / 188}, + {N_("32712 bytes"), 32712 / 188}, + {N_("65424 bytes"), 65424 / 188}, }; return strtab2htsmsg(tab, 1, lang); } @@ -641,349 +672,343 @@ CLASS_DOC(satip_server) PROP_DOC(satip_muxhandling) const idclass_t satip_server_class = { - .ic_snode = (idnode_t *)&satip_server_conf, - .ic_class = "satip_server", - .ic_caption = N_("Configuration - SAT>IP Server"), - .ic_event = "satip_server", - .ic_perm_def = ACCESS_ADMIN, - .ic_doc = tvh_doc_satip_server_class, - .ic_changed = satip_server_class_changed, - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - { - .name = N_("NAT Settings"), - .number = 2, - }, - { - .name = N_("Signal Settings"), - .number = 3, - }, - { - .name = N_("Exported Tuner(s) Settings"), - .number = 4, - }, - { - .name = N_("Miscellaneous Settings"), - .number = 5, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "satip_uuid", - .name = N_("Server UUID"), - .desc = N_("Universally unique identifier. Read only."), - .off = offsetof(struct satip_server_conf, satip_uuid), - .opts = PO_RDONLY | PO_EXPERT, - .group = 1, - }, - { - .type = PT_INT, - .id = "satip_rtsp", - .name = N_("RTSP port (554 or 9983, 0 = disable)"), - .desc = N_("Real Time Streaming Protocol (RTSP) port the " - "server should listen on (554 or 9983, 0 = " - "disable)."), - .off = offsetof(struct satip_server_conf, satip_rtsp), - .group = 1, - }, - { - .type = PT_BOOL, - .id = "satip_anonymize", - .name = N_("Anonymize"), - .desc = N_("Show only information for sessions which " - "are initiated from an IP address of the requester."), - .off = offsetof(struct satip_server_conf, satip_anonymize), - .group = 1, - }, - { - .type = PT_BOOL, - .id = "satip_noupnp", - .name = N_("Disable UPnP"), - .desc = N_("Disable UPnP discovery."), - .off = offsetof(struct satip_server_conf, satip_noupnp), - .group = 1, - }, - { - .type = PT_INT, - .id = "satip_weight", - .name = N_("Subscription weight"), - .desc = N_("The default subscription weight for each " - "subscription."), - .off = offsetof(struct satip_server_conf, satip_weight), - .opts = PO_ADVANCED, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "satip_remote_weight", - .name = N_("Accept remote subscription weight"), - .desc = N_("Accept the remote subscription weight " - "(from the SAT>IP client)."), - .off = offsetof(struct satip_server_conf, satip_allow_remote_weight), - .opts = PO_EXPERT, - .group = 1, - }, - { - .type = PT_INT, - .id = "satip_descramble", - .name = N_("Descramble services (limit per mux)"), - .desc = N_("The maximum number of services to decrypt per " - "mux."), - .off = offsetof(struct satip_server_conf, satip_descramble), - .opts = PO_ADVANCED, - .group = 1, - }, - { - .type = PT_INT, - .id = "satip_muxcnf", - .name = N_("Mux handling"), - .desc = N_("Select how Tvheadend should handle muxes. See Help " - "for details."), - .doc = prop_doc_satip_muxhandling, - .off = offsetof(struct satip_server_conf, satip_muxcnf), - .list = satip_server_class_muxcfg_list, - .opts = PO_EXPERT | PO_DOC_NLIST, - .group = 1, - }, - { - .type = PT_INT, - .id = "satip_rtptcpsize", - .name = N_("RTP over TCP payload"), - .desc = N_("Select the payload size for RTP contents used " - "in the TCP embedded data mode. Some implementations " - "like ffmpeg and VideoLAN have maximum limit 7896 " - "bytes. The recommended value for tvheadend is " - "16356 or 32712 bytes."), - .off = offsetof(struct satip_server_conf, satip_rtptcpsize), - .list = satip_server_class_rtptcpsize_list, - .group = 1, - }, - { - .type = PT_STR, - .id = "satip_nat_ip", - .name = N_("External IP (NAT)"), - .desc = N_("Enter external IP if behind Network address " - "translation (NAT). Asterisk (*) means accept all IP addresses."), - .off = offsetof(struct satip_server_conf, satip_nat_ip), - .opts = PO_EXPERT, - .group = 2, - }, - { - .type = PT_INT, - .id = "satip_nat_rtsp", - .name = N_("External RTSP port (NAT)"), - .desc = N_("Enter external PORT if behind Forwarding redirection." - "(0 = use the same local port)."), - .off = offsetof(struct satip_server_conf, satip_nat_rtsp), - .opts = PO_EXPERT, - .group = 2, - }, - { - .type = PT_BOOL, - .id = "satip_nat_name_force", - .name = N_("Force RTSP announcement of the external (NAT) ip:port"), - .desc = N_("Advertise only NAT address and port in RTSP commands," - "even for local connections."), - .off = offsetof(struct satip_server_conf, satip_nat_name_force), - .opts = PO_EXPERT, - .group = 2, - }, - { - .type = PT_STR, - .id = "satip_rtp_src_ip", - .name = N_("RTP Local bind IP address"), - .desc = N_("Bind RTP source address of the outgoing RTP packets " - "to specific local IP address " - "(empty = same IP as the listening RTSP; " - "0.0.0.0 = IP in network of default gateway; " - "or write here a valid local IP address)."), - .off = offsetof(struct satip_server_conf, satip_rtp_src_ip), - .opts = PO_EXPERT, - .group = 2, - }, - - - - { - .type = PT_U32, - .id = "satip_iptv_sig_level", - .name = N_("IPTV signal level"), - .desc = N_("Signal level for IPTV sources (0-240)."), - .off = offsetof(struct satip_server_conf, satip_iptv_sig_level), - .opts = PO_EXPERT, - .group = 3, - .def.u32 = 220, - }, - { - .type = PT_U32, - .id = "force_sig_level", - .name = N_("Force signal level"), - .desc = N_("Force signal level for all streaming (1-240, 0=do not use)."), - .off = offsetof(struct satip_server_conf, satip_force_sig_level), - .opts = PO_EXPERT, - .group = 3, - }, - { - .type = PT_INT, - .id = "satip_dvbs", - .name = N_("DVB-S"), - .desc = N_("The number of DVB-S (Satellite) tuners to export."), - .off = offsetof(struct satip_server_conf, satip_dvbs), - .group = 4, - }, - { - .type = PT_INT, - .id = "satip_dvbs2", - .name = N_("DVB-S2"), - .desc = N_("The number of DVB-S2 (Satellite) tuners to export."), - .off = offsetof(struct satip_server_conf, satip_dvbs2), - .group = 4, - }, - { - .type = PT_INT, - .id = "satip_dvbt", - .name = N_("DVB-T"), - .desc = N_("The number of DVB-T (Terresterial) tuners to export."), - .off = offsetof(struct satip_server_conf, satip_dvbt), - .group = 4, - }, - { - .type = PT_INT, - .id = "satip_dvbt2", - .name = N_("DVB-T2"), - .desc = N_("The number of DVB-T2 (Terresterial) tuners to export."), - .off = offsetof(struct satip_server_conf, satip_dvbt2), - .group = 4, - }, - { - .type = PT_INT, - .id = "satip_dvbc", - .name = N_("DVB-C"), - .desc = N_("The number of DVB-C (Cable) tuners to export."), - .off = offsetof(struct satip_server_conf, satip_dvbc), - .group = 4, - }, - { - .type = PT_INT, - .id = "satip_dvbc2", - .name = N_("DVB-C2"), - .desc = N_("The number of DVB-C2 (Cable) tuners to export."), - .off = offsetof(struct satip_server_conf, satip_dvbc2), - .group = 4, - }, - { - .type = PT_INT, - .id = "satip_atsct", - .name = N_("ATSC-T"), - .desc = N_("The number of ATSC-T (Terresterial) tuners to export."), - .off = offsetof(struct satip_server_conf, satip_atsc_t), - .group = 4, - }, - { - .type = PT_INT, - .id = "satip_atscc", - .name = N_("ATSC-C"), - .desc = N_("The number of ATSC-C (Cable/AnnexB) tuners to export."), - .off = offsetof(struct satip_server_conf, satip_atsc_c), - .group = 4, - }, - { - .type = PT_INT, - .id = "satip_isdbt", - .name = N_("ISDB-T"), - .desc = N_("The number of ISDB-T (Terresterial) tuners to export."), - .off = offsetof(struct satip_server_conf, satip_isdb_t), - .group = 4, - }, - { - .type = PT_INT, - .id = "satip_max_sessions", - .name = N_("Max Sessions"), - .desc = N_("The maximum number of active RTSP sessions " - "(if 0 no limit)."), - .off = offsetof(struct satip_server_conf, satip_max_sessions), - .opts = PO_ADVANCED, - .group = 4, - }, - { - .type = PT_INT, - .id = "satip_max_user_connections", - .name = N_("Max User connections"), - .desc = N_("The maximum concurrent RTSP connections from the " - "same IP address (if 0 no limit)."), - .off = offsetof(struct satip_server_conf, satip_max_user_connections), - .opts = PO_ADVANCED, - .group = 4, - }, - { - .type = PT_BOOL, - .id = "satip_rewrite_pmt", - .name = N_("Rewrite PMT"), - .desc = N_("Rewrite Program Map Table (PMT) packets " - "to only include information about the currently " - "streamed service."), - .off = offsetof(struct satip_server_conf, satip_rewrite_pmt), - .opts = PO_EXPERT, - .group = 5, - }, - { - .type = PT_BOOL, - .id = "satip_nom3u", - .name = N_("Disable X_SATIPM3U tag"), - .desc = N_("Do not send X_SATIPM3U information in the XML description to clients."), - .off = offsetof(struct satip_server_conf, satip_nom3u), - .opts = PO_EXPERT, - .group = 5, - }, - { - .type = PT_BOOL, - .id = "satip_notcp_mode", - .name = N_("Disable RTP/AVP/TCP support"), - .desc = N_("Remove server support for RTP/AVP/TCP transfer mode " - "(embedded data in the RTSP session)."), - .off = offsetof(struct satip_server_conf, satip_notcp_mode), - .opts = PO_EXPERT, - .group = 5, - }, - { - .type = PT_BOOL, - .id = "satip_restrict_pids_all", - .name = N_("Restrict \"pids=all\""), - .desc = N_("Replace the full Transport Stream with a range " - "0x00-0x02,0x10-0x1F,0x1FFB pids only."), - .off = offsetof(struct satip_server_conf, satip_restrict_pids_all), - .opts = PO_EXPERT, - .group = 5, - }, - { - .type = PT_BOOL, - .id = "satip_drop_fe", - .name = N_("Drop \"fe=\" parameter"), - .desc = N_("Discard the frontend parameter in RTSP requests, " - "as some clients incorrectly use it."), - .off = offsetof(struct satip_server_conf, satip_drop_fe), - .opts = PO_EXPERT, - .group = 5, - }, - {} - }, + .ic_snode = (idnode_t*)&satip_server_conf, + .ic_class = "satip_server", + .ic_caption = N_("Configuration - SAT>IP Server"), + .ic_event = "satip_server", + .ic_perm_def = ACCESS_ADMIN, + .ic_doc = tvh_doc_satip_server_class, + .ic_changed = satip_server_class_changed, + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + { + .name = N_("NAT Settings"), + .number = 2, + }, + { + .name = N_("Signal Settings"), + .number = 3, + }, + { + .name = N_("Exported Tuner(s) Settings"), + .number = 4, + }, + { + .name = N_("Miscellaneous Settings"), + .number = 5, + }, + {}}, + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "satip_uuid", + .name = N_("Server UUID"), + .desc = N_("Universally unique identifier. Read only."), + .off = offsetof(struct satip_server_conf, satip_uuid), + .opts = PO_RDONLY | PO_EXPERT, + .group = 1, + }, + { + .type = PT_INT, + .id = "satip_rtsp", + .name = N_("RTSP port (554 or 9983, 0 = disable)"), + .desc = N_("Real Time Streaming Protocol (RTSP) port the " + "server should listen on (554 or 9983, 0 = " + "disable)."), + .off = offsetof(struct satip_server_conf, satip_rtsp), + .group = 1, + }, + { + .type = PT_BOOL, + .id = "satip_anonymize", + .name = N_("Anonymize"), + .desc = N_("Show only information for sessions which " + "are initiated from an IP address of the requester."), + .off = offsetof(struct satip_server_conf, satip_anonymize), + .group = 1, + }, + { + .type = PT_BOOL, + .id = "satip_noupnp", + .name = N_("Disable UPnP"), + .desc = N_("Disable UPnP discovery."), + .off = offsetof(struct satip_server_conf, satip_noupnp), + .group = 1, + }, + { + .type = PT_INT, + .id = "satip_weight", + .name = N_("Subscription weight"), + .desc = N_("The default subscription weight for each " + "subscription."), + .off = offsetof(struct satip_server_conf, satip_weight), + .opts = PO_ADVANCED, + .group = 1, + }, + { + .type = PT_BOOL, + .id = "satip_remote_weight", + .name = N_("Accept remote subscription weight"), + .desc = N_("Accept the remote subscription weight " + "(from the SAT>IP client)."), + .off = offsetof(struct satip_server_conf, satip_allow_remote_weight), + .opts = PO_EXPERT, + .group = 1, + }, + { + .type = PT_INT, + .id = "satip_descramble", + .name = N_("Descramble services (limit per mux)"), + .desc = N_("The maximum number of services to decrypt per " + "mux."), + .off = offsetof(struct satip_server_conf, satip_descramble), + .opts = PO_ADVANCED, + .group = 1, + }, + { + .type = PT_INT, + .id = "satip_muxcnf", + .name = N_("Mux handling"), + .desc = N_("Select how Tvheadend should handle muxes. See Help " + "for details."), + .doc = prop_doc_satip_muxhandling, + .off = offsetof(struct satip_server_conf, satip_muxcnf), + .list = satip_server_class_muxcfg_list, + .opts = PO_EXPERT | PO_DOC_NLIST, + .group = 1, + }, + { + .type = PT_INT, + .id = "satip_rtptcpsize", + .name = N_("RTP over TCP payload"), + .desc = N_("Select the payload size for RTP contents used " + "in the TCP embedded data mode. Some implementations " + "like ffmpeg and VideoLAN have maximum limit 7896 " + "bytes. The recommended value for tvheadend is " + "16356 or 32712 bytes."), + .off = offsetof(struct satip_server_conf, satip_rtptcpsize), + .list = satip_server_class_rtptcpsize_list, + .group = 1, + }, + { + .type = PT_STR, + .id = "satip_nat_ip", + .name = N_("External IP (NAT)"), + .desc = N_("Enter external IP if behind Network address " + "translation (NAT). Asterisk (*) means accept all IP addresses."), + .off = offsetof(struct satip_server_conf, satip_nat_ip), + .opts = PO_EXPERT, + .group = 2, + }, + { + .type = PT_INT, + .id = "satip_nat_rtsp", + .name = N_("External RTSP port (NAT)"), + .desc = N_("Enter external PORT if behind Forwarding redirection." + "(0 = use the same local port)."), + .off = offsetof(struct satip_server_conf, satip_nat_rtsp), + .opts = PO_EXPERT, + .group = 2, + }, + { + .type = PT_BOOL, + .id = "satip_nat_name_force", + .name = N_("Force RTSP announcement of the external (NAT) ip:port"), + .desc = N_("Advertise only NAT address and port in RTSP commands," + "even for local connections."), + .off = offsetof(struct satip_server_conf, satip_nat_name_force), + .opts = PO_EXPERT, + .group = 2, + }, + { + .type = PT_STR, + .id = "satip_rtp_src_ip", + .name = N_("RTP Local bind IP address"), + .desc = N_("Bind RTP source address of the outgoing RTP packets " + "to specific local IP address " + "(empty = same IP as the listening RTSP; " + "0.0.0.0 = IP in network of default gateway; " + "or write here a valid local IP address)."), + .off = offsetof(struct satip_server_conf, satip_rtp_src_ip), + .opts = PO_EXPERT, + .group = 2, + }, + + { + .type = PT_U32, + .id = "satip_iptv_sig_level", + .name = N_("IPTV signal level"), + .desc = N_("Signal level for IPTV sources (0-240)."), + .off = offsetof(struct satip_server_conf, satip_iptv_sig_level), + .opts = PO_EXPERT, + .group = 3, + .def.u32 = 220, + }, + { + .type = PT_U32, + .id = "force_sig_level", + .name = N_("Force signal level"), + .desc = N_("Force signal level for all streaming (1-240, 0=do not use)."), + .off = offsetof(struct satip_server_conf, satip_force_sig_level), + .opts = PO_EXPERT, + .group = 3, + }, + { + .type = PT_INT, + .id = "satip_dvbs", + .name = N_("DVB-S"), + .desc = N_("The number of DVB-S (Satellite) tuners to export."), + .off = offsetof(struct satip_server_conf, satip_dvbs), + .group = 4, + }, + { + .type = PT_INT, + .id = "satip_dvbs2", + .name = N_("DVB-S2"), + .desc = N_("The number of DVB-S2 (Satellite) tuners to export."), + .off = offsetof(struct satip_server_conf, satip_dvbs2), + .group = 4, + }, + { + .type = PT_INT, + .id = "satip_dvbt", + .name = N_("DVB-T"), + .desc = N_("The number of DVB-T (Terresterial) tuners to export."), + .off = offsetof(struct satip_server_conf, satip_dvbt), + .group = 4, + }, + { + .type = PT_INT, + .id = "satip_dvbt2", + .name = N_("DVB-T2"), + .desc = N_("The number of DVB-T2 (Terresterial) tuners to export."), + .off = offsetof(struct satip_server_conf, satip_dvbt2), + .group = 4, + }, + { + .type = PT_INT, + .id = "satip_dvbc", + .name = N_("DVB-C"), + .desc = N_("The number of DVB-C (Cable) tuners to export."), + .off = offsetof(struct satip_server_conf, satip_dvbc), + .group = 4, + }, + { + .type = PT_INT, + .id = "satip_dvbc2", + .name = N_("DVB-C2"), + .desc = N_("The number of DVB-C2 (Cable) tuners to export."), + .off = offsetof(struct satip_server_conf, satip_dvbc2), + .group = 4, + }, + { + .type = PT_INT, + .id = "satip_atsct", + .name = N_("ATSC-T"), + .desc = N_("The number of ATSC-T (Terresterial) tuners to export."), + .off = offsetof(struct satip_server_conf, satip_atsc_t), + .group = 4, + }, + { + .type = PT_INT, + .id = "satip_atscc", + .name = N_("ATSC-C"), + .desc = N_("The number of ATSC-C (Cable/AnnexB) tuners to export."), + .off = offsetof(struct satip_server_conf, satip_atsc_c), + .group = 4, + }, + { + .type = PT_INT, + .id = "satip_isdbt", + .name = N_("ISDB-T"), + .desc = N_("The number of ISDB-T (Terresterial) tuners to export."), + .off = offsetof(struct satip_server_conf, satip_isdb_t), + .group = 4, + }, + { + .type = PT_INT, + .id = "satip_max_sessions", + .name = N_("Max Sessions"), + .desc = N_("The maximum number of active RTSP sessions " + "(if 0 no limit)."), + .off = offsetof(struct satip_server_conf, satip_max_sessions), + .opts = PO_ADVANCED, + .group = 4, + }, + { + .type = PT_INT, + .id = "satip_max_user_connections", + .name = N_("Max User connections"), + .desc = N_("The maximum concurrent RTSP connections from the " + "same IP address (if 0 no limit)."), + .off = offsetof(struct satip_server_conf, satip_max_user_connections), + .opts = PO_ADVANCED, + .group = 4, + }, + { + .type = PT_BOOL, + .id = "satip_rewrite_pmt", + .name = N_("Rewrite PMT"), + .desc = N_("Rewrite Program Map Table (PMT) packets " + "to only include information about the currently " + "streamed service."), + .off = offsetof(struct satip_server_conf, satip_rewrite_pmt), + .opts = PO_EXPERT, + .group = 5, + }, + { + .type = PT_BOOL, + .id = "satip_nom3u", + .name = N_("Disable X_SATIPM3U tag"), + .desc = N_("Do not send X_SATIPM3U information in the XML description to clients."), + .off = offsetof(struct satip_server_conf, satip_nom3u), + .opts = PO_EXPERT, + .group = 5, + }, + { + .type = PT_BOOL, + .id = "satip_notcp_mode", + .name = N_("Disable RTP/AVP/TCP support"), + .desc = N_("Remove server support for RTP/AVP/TCP transfer mode " + "(embedded data in the RTSP session)."), + .off = offsetof(struct satip_server_conf, satip_notcp_mode), + .opts = PO_EXPERT, + .group = 5, + }, + { + .type = PT_BOOL, + .id = "satip_restrict_pids_all", + .name = N_("Restrict \"pids=all\""), + .desc = N_("Replace the full Transport Stream with a range " + "0x00-0x02,0x10-0x1F,0x1FFB pids only."), + .off = offsetof(struct satip_server_conf, satip_restrict_pids_all), + .opts = PO_EXPERT, + .group = 5, + }, + { + .type = PT_BOOL, + .id = "satip_drop_fe", + .name = N_("Drop \"fe=\" parameter"), + .desc = N_("Discard the frontend parameter in RTSP requests, " + "as some clients incorrectly use it."), + .off = offsetof(struct satip_server_conf, satip_drop_fe), + .opts = PO_EXPERT, + .group = 5, + }, + {}}, }; /* * */ -static void satip_server_init_common(const char *prefix, int announce) -{ +static void satip_server_init_common(const char* prefix, int announce) { struct sockaddr_storage http; - char http_ip[128]; - int descramble, rewrite_pmt, muxcnf; - char *nat_ip, *rtp_src_ip; - int nat_port; + char http_ip[128]; + int descramble, rewrite_pmt, muxcnf; + char * nat_ip, *rtp_src_ip; + int nat_port; if (satip_server_rtsp_port <= 0) return; @@ -998,24 +1023,31 @@ static void satip_server_init_common(const char *prefix, int announce) return; } tcp_get_str_from_ip(&http, http_ip, sizeof(http_ip)); - http_server_ip = strdup(satip_server_bindaddr ?: http_ip); + http_server_ip = strdup(satip_server_bindaddr ?: http_ip); http_server_port = ntohs(IP_PORT(http)); } - descramble = satip_server_conf.satip_descramble; + descramble = satip_server_conf.satip_descramble; rewrite_pmt = satip_server_conf.satip_rewrite_pmt; - muxcnf = satip_server_conf.satip_muxcnf; - nat_ip = strdup(satip_server_conf.satip_nat_ip ?: ""); - nat_port = satip_server_conf.satip_nat_rtsp ?: satip_server_rtsp_port; - rtp_src_ip = strdup(satip_server_conf.satip_rtp_src_ip ?: ""); - bound_port = satip_server_rtsp_port; + muxcnf = satip_server_conf.satip_muxcnf; + nat_ip = strdup(satip_server_conf.satip_nat_ip ?: ""); + nat_port = satip_server_conf.satip_nat_rtsp ?: satip_server_rtsp_port; + rtp_src_ip = strdup(satip_server_conf.satip_rtp_src_ip ?: ""); + bound_port = satip_server_rtsp_port; if (announce) tvh_mutex_unlock(&global_lock); tvh_mutex_lock(&satip_server_reinit); - satip_server_rtsp_init(http_server_ip, satip_server_rtsp_port, descramble, rewrite_pmt, muxcnf, rtp_src_ip, nat_ip, nat_port); + satip_server_rtsp_init(http_server_ip, + satip_server_rtsp_port, + descramble, + rewrite_pmt, + muxcnf, + rtp_src_ip, + nat_ip, + nat_port); satip_server_info(prefix, descramble, muxcnf); if (announce) @@ -1033,8 +1065,7 @@ static void satip_server_init_common(const char *prefix, int announce) /* * */ -static void satip_server_save(void) -{ +static void satip_server_save(void) { if (!satip_server_rtsp_port_locked) { satips_rtsp_port(0); if (satip_server_rtsp_port > 0) { @@ -1053,51 +1084,48 @@ static void satip_server_save(void) * Initialization */ -void satip_server_boot(void) -{ +void satip_server_boot(void) { idclass_register(&satip_server_class); - satip_server_bootid = time(NULL); - satip_server_conf.satip_deviceid = 1; - satip_server_conf.satip_rtptcpsize = 7896/188; + satip_server_bootid = time(NULL); + satip_server_conf.satip_deviceid = 1; + satip_server_conf.satip_rtptcpsize = 7896 / 188; } -void satip_server_init(const char *bindaddr, int rtsp_port) -{ +void satip_server_init(const char* bindaddr, int rtsp_port) { tvh_mutex_init(&satip_server_reinit, NULL); http_server_ip = NULL; - satip_server_bindaddr = bindaddr ? strdup(bindaddr) : NULL; + satip_server_bindaddr = bindaddr ? strdup(bindaddr) : NULL; satip_server_rtsp_port_locked = rtsp_port > 0; - satip_server_rtsp_port = rtsp_port; + satip_server_rtsp_port = rtsp_port; satips_rtsp_port(rtsp_port); satip_server_init_common("", 0); } -void satip_server_register(void) -{ - char uu[UUID_HEX_SIZE + 4]; +void satip_server_register(void) { + char uu[UUID_HEX_SIZE + 4]; tvh_uuid_t u; - int save = 0; + int save = 0; if (http_server_ip == NULL) return; if (satip_server_conf.satip_rtsp != satip_server_rtsp_port) { satip_server_conf.satip_rtsp = satip_server_rtsp_port; - save = 1; + save = 1; } if (satip_server_conf.satip_weight <= 0) { satip_server_conf.satip_weight = 100; - save = 1; + save = 1; } if (satip_server_conf.satip_deviceid <= 0) { satip_server_conf.satip_deviceid = 1; - save = 1; + save = 1; } if (strempty(satip_server_conf.satip_uuid)) { @@ -1106,11 +1134,16 @@ void satip_server_register(void) tvherror(LS_SATIPS, "Unable to create UUID"); return; } - bin2hex(uu + 0, 9, u.bin, 4); uu[ 8] = '-'; - bin2hex(uu + 9, 5, u.bin + 4, 2); uu[13] = '-'; - bin2hex(uu + 14, 5, u.bin + 6, 2); uu[18] = '-'; - bin2hex(uu + 19, 5, u.bin + 8, 2); uu[23] = '-'; - bin2hex(uu + 24, 13, u.bin + 10, 6); uu[36] = 0; + bin2hex(uu + 0, 9, u.bin, 4); + uu[8] = '-'; + bin2hex(uu + 9, 5, u.bin + 4, 2); + uu[13] = '-'; + bin2hex(uu + 14, 5, u.bin + 6, 2); + uu[18] = '-'; + bin2hex(uu + 19, 5, u.bin + 8, 2); + uu[23] = '-'; + bin2hex(uu + 24, 13, u.bin + 10, 6); + uu[36] = 0; tvh_str_set(&satip_server_conf.satip_uuid, uu); save = 1; } @@ -1134,8 +1167,7 @@ void satip_server_register(void) satips_upnp_send_announce(); } -void satip_server_done(void) -{ +void satip_server_done(void) { satip_server_rtsp_done(); if (satip_server_rtsp_port > 0) satips_upnp_send_byebye(); diff --git a/src/satip/server.h b/src/satip/server.h index 03a286289..eafd155d0 100644 --- a/src/satip/server.h +++ b/src/satip/server.h @@ -38,93 +38,102 @@ struct satip_server_conf { idnode_t idnode; - int satip_deviceid; - char *satip_uuid; - int satip_rtsp; - int satip_weight; - int satip_allow_remote_weight; - int satip_descramble; - int satip_rewrite_pmt; - int satip_muxcnf; - int satip_rtptcpsize; - int satip_nom3u; - int satip_notcp_mode; - int satip_anonymize; - int satip_noupnp; - int satip_drop_fe; - int satip_restrict_pids_all; - int satip_iptv_sig_level; - int satip_force_sig_level; - int satip_dvbs; - int satip_dvbs2; - int satip_dvbt; - int satip_dvbt2; - int satip_dvbc; - int satip_dvbc2; - int satip_atsc_t; - int satip_atsc_c; - int satip_isdb_t; - int satip_max_sessions; - int satip_max_user_connections; - char *satip_nat_ip; - int satip_nat_rtsp; - int satip_nat_name_force; - char *satip_rtp_src_ip; + int satip_deviceid; + char* satip_uuid; + int satip_rtsp; + int satip_weight; + int satip_allow_remote_weight; + int satip_descramble; + int satip_rewrite_pmt; + int satip_muxcnf; + int satip_rtptcpsize; + int satip_nom3u; + int satip_notcp_mode; + int satip_anonymize; + int satip_noupnp; + int satip_drop_fe; + int satip_restrict_pids_all; + int satip_iptv_sig_level; + int satip_force_sig_level; + int satip_dvbs; + int satip_dvbs2; + int satip_dvbt; + int satip_dvbt2; + int satip_dvbc; + int satip_dvbc2; + int satip_atsc_t; + int satip_atsc_c; + int satip_isdb_t; + int satip_max_sessions; + int satip_max_user_connections; + char* satip_nat_ip; + int satip_nat_rtsp; + int satip_nat_name_force; + char* satip_rtp_src_ip; }; extern struct satip_server_conf satip_server_conf; extern const idclass_t satip_server_class; -void *satip_rtp_queue(th_subscription_t *subs, - streaming_queue_t *sq, - http_connection_t *hc, - struct sockaddr_storage *peer, int port, - int fd_rtp, int fd_rtcp, - int frontend, int source, - dvb_mux_conf_t *dmc, - mpegts_apids_t *pids, - int allow_data, int perm_lock, - void (*no_data_cb)(void *opaque), - void *no_data_opaque); -void satip_rtp_allow_data(void *_rtp); -void satip_rtp_update_pids(void *_rtp, mpegts_apids_t *pids); -void satip_rtp_update_pmt_pids(void *_rtp, mpegts_apids_t *pmt_pids); -int satip_rtp_status(void *id, char *buf, int len); -void satip_rtp_close(void *id); +void* satip_rtp_queue(th_subscription_t* subs, + streaming_queue_t* sq, + http_connection_t* hc, + struct sockaddr_storage* peer, + int port, + int fd_rtp, + int fd_rtcp, + int frontend, + int source, + dvb_mux_conf_t* dmc, + mpegts_apids_t* pids, + int allow_data, + int perm_lock, + void (*no_data_cb)(void* opaque), + void* no_data_opaque); +void satip_rtp_allow_data(void* _rtp); +void satip_rtp_update_pids(void* _rtp, mpegts_apids_t* pids); +void satip_rtp_update_pmt_pids(void* _rtp, mpegts_apids_t* pmt_pids); +int satip_rtp_status(void* id, char* buf, int len); +void satip_rtp_close(void* id); void satip_rtp_init(int boot); void satip_rtp_done(void); -int satip_rtsp_delsys(int fe, int *findex, const char **ftype); +int satip_rtsp_delsys(int fe, int* findex, const char** ftype); -void satip_server_rtsp_init(const char *bindaddr, int port, - int descramble, int rewrite_pmt, int muxcnf, - const char *rtp_src, - const char *nat_ip, int nat_port); +void satip_server_rtsp_init(const char* bindaddr, + int port, + int descramble, + int rewrite_pmt, + int muxcnf, + const char* rtp_src, + const char* nat_ip, + int nat_port); void satip_server_rtsp_register(void); void satip_server_rtsp_done(void); -int satip_server_http_page(http_connection_t *hc, - const char *remain, void *opaque); +int satip_server_http_page(http_connection_t* hc, const char* remain, void* opaque); -int satip_server_match_uuid(const char *uuid); +int satip_server_match_uuid(const char* uuid); void satip_server_boot(void); -void satip_server_init(const char *bindaddr, int rtsp_port); +void satip_server_init(const char* bindaddr, int rtsp_port); void satip_server_register(void); void satip_server_done(void); #else -static inline int satip_server_match_uuid(const char *uuid) { return 0; } +static inline int satip_server_match_uuid(const char* uuid) { + return 0; +} -static inline void satip_server_config_changed(void) { }; +static inline void satip_server_config_changed(void) {}; -static inline void satip_server_boot(void) { }; -static inline void satip_server_init(const char *bindaddr, int rtsp_port) { }; -static inline void satip_server_register(void) { }; -static inline void satip_server_done(void) { }; +static inline void satip_server_boot(void) {}; +static inline void satip_server_init(const char* bindaddr, int rtsp_port) {}; +static inline void satip_server_register(void) {}; +static inline void satip_server_done(void) {}; #endif diff --git a/src/sbuf.h b/src/sbuf.h index 2969e6c94..c31de0ad6 100644 --- a/src/sbuf.h +++ b/src/sbuf.h @@ -29,70 +29,84 @@ * Simple dynamically growing buffer */ typedef struct sbuf { - uint8_t *sb_data; + uint8_t* sb_data; int sb_ptr; int sb_size; uint16_t sb_err; uint8_t sb_bswap; } sbuf_t; +void sbuf_init(sbuf_t* sb); +void sbuf_init_fixed(sbuf_t* sb, int len); -void sbuf_init(sbuf_t *sb); -void sbuf_init_fixed(sbuf_t *sb, int len); +void sbuf_free(sbuf_t* sb); -void sbuf_free(sbuf_t *sb); +void sbuf_reset(sbuf_t* sb, int max_len); +void sbuf_reset_and_alloc(sbuf_t* sb, int len); -void sbuf_reset(sbuf_t *sb, int max_len); -void sbuf_reset_and_alloc(sbuf_t *sb, int len); - -static inline void sbuf_steal_data(sbuf_t *sb) -{ +static inline void sbuf_steal_data(sbuf_t* sb) { sb->sb_data = NULL; sb->sb_ptr = sb->sb_size = sb->sb_err = 0; } -static inline void sbuf_err(sbuf_t *sb, int errors) -{ +static inline void sbuf_err(sbuf_t* sb, int errors) { sb->sb_err += errors; } -void sbuf_alloc_(sbuf_t *sb, int len); +void sbuf_alloc_(sbuf_t* sb, int len); -static inline void sbuf_alloc(sbuf_t *sb, int len) -{ +static inline void sbuf_alloc(sbuf_t* sb, int len) { if (sb->sb_ptr + len >= sb->sb_size) sbuf_alloc_(sb, len); } -void sbuf_realloc(sbuf_t *sb, int len); +void sbuf_realloc(sbuf_t* sb, int len); -void sbuf_replace(sbuf_t *sb, sbuf_t *src); +void sbuf_replace(sbuf_t* sb, sbuf_t* src); -void sbuf_append(sbuf_t *sb, const void *data, int len); -void sbuf_append_from_sbuf(sbuf_t *sb, sbuf_t *src); +void sbuf_append(sbuf_t* sb, const void* data, int len); +void sbuf_append_from_sbuf(sbuf_t* sb, sbuf_t* src); -void sbuf_cut(sbuf_t *sb, int off); +void sbuf_cut(sbuf_t* sb, int off); -void sbuf_put_be32(sbuf_t *sb, uint32_t u32); -void sbuf_put_be16(sbuf_t *sb, uint16_t u16); -void sbuf_put_byte(sbuf_t *sb, uint8_t u8); +void sbuf_put_be32(sbuf_t* sb, uint32_t u32); +void sbuf_put_be16(sbuf_t* sb, uint16_t u16); +void sbuf_put_byte(sbuf_t* sb, uint8_t u8); -ssize_t sbuf_read(sbuf_t *sb, int fd); +ssize_t sbuf_read(sbuf_t* sb, int fd); -static inline uint8_t sbuf_peek_u8(sbuf_t *sb, int off) { return sb->sb_data[off]; } -static inline int8_t sbuf_peek_s8(sbuf_t *sb, int off) { return sb->sb_data[off]; } -uint16_t sbuf_peek_u16(sbuf_t *sb, int off); -static inline int16_t sbuf_peek_s16(sbuf_t *sb, int off) { return sbuf_peek_u16(sb, off); } -uint16_t sbuf_peek_u16le(sbuf_t *sb, int off); -static inline int16_t sbuf_peek_s16le(sbuf_t *sb, int off) { return sbuf_peek_u16le(sb, off); } -uint16_t sbuf_peek_u16be(sbuf_t *sb, int off); -static inline int16_t sbuf_peek_s16be(sbuf_t *sb, int off) { return sbuf_peek_u16be(sb, off); } -uint32_t sbuf_peek_u32(sbuf_t *sb, int off); -static inline int32_t sbuf_peek_s32(sbuf_t *sb, int off) { return sbuf_peek_u32(sb, off); } -uint32_t sbuf_peek_u32le(sbuf_t *sb, int off); -static inline int32_t sbuf_peek_s32le(sbuf_t *sb, int off) { return sbuf_peek_u32le(sb, off); } -uint32_t sbuf_peek_u32be(sbuf_t *sb, int off); -static inline int32_t sbuf_peek_s32be(sbuf_t *sb, int off) { return sbuf_peek_u32be(sb, off); } -static inline uint8_t *sbuf_peek(sbuf_t *sb, int off) { return sb->sb_data + off; } +static inline uint8_t sbuf_peek_u8(sbuf_t* sb, int off) { + return sb->sb_data[off]; +} +static inline int8_t sbuf_peek_s8(sbuf_t* sb, int off) { + return sb->sb_data[off]; +} +uint16_t sbuf_peek_u16(sbuf_t* sb, int off); +static inline int16_t sbuf_peek_s16(sbuf_t* sb, int off) { + return sbuf_peek_u16(sb, off); +} +uint16_t sbuf_peek_u16le(sbuf_t* sb, int off); +static inline int16_t sbuf_peek_s16le(sbuf_t* sb, int off) { + return sbuf_peek_u16le(sb, off); +} +uint16_t sbuf_peek_u16be(sbuf_t* sb, int off); +static inline int16_t sbuf_peek_s16be(sbuf_t* sb, int off) { + return sbuf_peek_u16be(sb, off); +} +uint32_t sbuf_peek_u32(sbuf_t* sb, int off); +static inline int32_t sbuf_peek_s32(sbuf_t* sb, int off) { + return sbuf_peek_u32(sb, off); +} +uint32_t sbuf_peek_u32le(sbuf_t* sb, int off); +static inline int32_t sbuf_peek_s32le(sbuf_t* sb, int off) { + return sbuf_peek_u32le(sb, off); +} +uint32_t sbuf_peek_u32be(sbuf_t* sb, int off); +static inline int32_t sbuf_peek_s32be(sbuf_t* sb, int off) { + return sbuf_peek_u32be(sb, off); +} +static inline uint8_t* sbuf_peek(sbuf_t* sb, int off) { + return sb->sb_data + off; +} #endif /* __TVH_SBUF_H */ diff --git a/src/service.c b/src/service.c index c65301666..dd419004a 100644 --- a/src/service.c +++ b/src/service.c @@ -36,11 +36,11 @@ #include "memoryinfo.h" #include "config.h" -static void service_data_timeout(void *aux); -static void service_class_delete(struct idnode *self); -static htsmsg_t *service_class_save(struct idnode *self, char *filename, size_t fsize); -static void service_class_load(struct idnode *self, htsmsg_t *conf); -static int service_make_nicename0(service_t *t, char *buf, size_t len, int adapter); +static void service_data_timeout(void* aux); +static void service_class_delete(struct idnode* self); +static htsmsg_t* service_class_save(struct idnode* self, char* filename, size_t fsize); +static void service_class_load(struct idnode* self, htsmsg_t* conf); +static int service_make_nicename0(service_t* t, char* buf, size_t len, int adapter); struct service_queue service_all; struct service_queue service_raw_all; @@ -48,10 +48,8 @@ struct service_queue service_raw_remove; static mtimer_t service_raw_remove_timer; -static void -service_class_notify_enabled ( void *obj, const char *lang ) -{ - service_t *t = (service_t *)obj; +static void service_class_notify_enabled(void* obj, const char* lang) { + service_t* t = (service_t*)obj; if (t->s_enabled && t->s_auto != SERVICE_AUTO_OFF) t->s_auto = SERVICE_AUTO_NORMAL; bouquet_notify_service_enabled(t); @@ -59,202 +57,166 @@ service_class_notify_enabled ( void *obj, const char *lang ) service_remove_subscriber(t, NULL, SM_CODE_SVC_NOT_ENABLED); } -static const void * -service_class_channel_get ( void *obj ) -{ - service_t *svc = obj; +static const void* service_class_channel_get(void* obj) { + service_t* svc = obj; return idnode_list_get1(&svc->s_channels); } -static char * -service_class_channel_rend ( void *obj, const char *lang ) -{ - service_t *svc = obj; +static char* service_class_channel_rend(void* obj, const char* lang) { + service_t* svc = obj; return idnode_list_get_csv1(&svc->s_channels, lang); } -static int -service_class_channel_set - ( void *obj, const void *p ) -{ - service_t *svc = obj; - return idnode_list_set1(&svc->s_id, &svc->s_channels, - &channel_class, (htsmsg_t *)p, - service_mapper_create); +static int service_class_channel_set(void* obj, const void* p) { + service_t* svc = obj; + return idnode_list_set1(&svc->s_id, + &svc->s_channels, + &channel_class, + (htsmsg_t*)p, + service_mapper_create); } -static void -service_class_get_title - ( idnode_t *self, const char *lang, char *dst, size_t dstsize ) -{ - snprintf(dst, dstsize, "%s", - service_get_full_channel_name((service_t *)self) ?: ""); +static void service_class_get_title(idnode_t* self, const char* lang, char* dst, size_t dstsize) { + snprintf(dst, dstsize, "%s", service_get_full_channel_name((service_t*)self) ?: ""); } -static const void * -service_class_encrypted_get ( void *p ) -{ +static const void* service_class_encrypted_get(void* p) { static int t; - service_t *s = p; + service_t* s = p; tvh_mutex_lock(&s->s_stream_mutex); t = service_is_encrypted(s); tvh_mutex_unlock(&s->s_stream_mutex); return &t; } -static const void * -service_class_caid_get ( void *obj ) -{ - static char buf[256], *s = buf; - service_t *svc = obj; - elementary_stream_t *st; - caid_t *c; - size_t l; +static const void* service_class_caid_get(void* obj) { + static char buf[256], *s = buf; + service_t* svc = obj; + elementary_stream_t* st; + caid_t* c; + size_t l; buf[0] = '\0'; - TAILQ_FOREACH(st, &svc->s_components.set_all, es_link) { - switch(st->es_type) { - case SCT_CA: - LIST_FOREACH(c, &st->es_caids, link) { - l = strlen(buf); - snprintf(buf + l, sizeof(buf) - l, "%s%04X:%06X", - l ? "," : "", c->caid, c->providerid); - } - break; - default: - break; + TAILQ_FOREACH (st, &svc->s_components.set_all, es_link) { + switch (st->es_type) { + case SCT_CA: + LIST_FOREACH (c, &st->es_caids, link) { + l = strlen(buf); + snprintf(buf + l, sizeof(buf) - l, "%s%04X:%06X", l ? "," : "", c->caid, c->providerid); + } + break; + default: + break; } } return &s; } -static htsmsg_t * -service_class_auto_list ( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("Auto check enabled"), 0 }, - { N_("Auto check disabled"), 1 }, - { N_("Missing In PAT/SDT"), 2 } - }; +static htsmsg_t* service_class_auto_list(void* o, const char* lang) { + static const struct strtab tab[] = {{N_("Auto check enabled"), 0}, + {N_("Auto check disabled"), 1}, + {N_("Missing In PAT/SDT"), 2}}; return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -service_type_auto_list ( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("Override disabled"), ST_UNSET }, - { N_("None"), ST_NONE }, - { N_("Radio"), ST_RADIO }, - { N_("SD TV"), ST_SDTV }, - { N_("HD TV"), ST_HDTV }, - { N_("FHD TV"), ST_FHDTV }, - { N_("UHD TV"), ST_UHDTV } - }; +static htsmsg_t* service_type_auto_list(void* o, const char* lang) { + static const struct strtab tab[] = {{N_("Override disabled"), ST_UNSET}, + {N_("None"), ST_NONE}, + {N_("Radio"), ST_RADIO}, + {N_("SD TV"), ST_SDTV}, + {N_("HD TV"), ST_HDTV}, + {N_("FHD TV"), ST_FHDTV}, + {N_("UHD TV"), ST_UHDTV}}; return strtab2htsmsg(tab, 1, lang); } PROP_DOC(servicechecking) -const idclass_t service_class = { - .ic_class = "service", - .ic_caption = N_("Service"), - .ic_event = "service", - .ic_perm_def = ACCESS_ADMIN, - .ic_delete = service_class_delete, - .ic_save = service_class_save, - .ic_load = service_class_load, - .ic_get_title = service_class_get_title, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/Disable service."), - .off = offsetof(service_t, s_enabled), - .notify = service_class_notify_enabled, - }, - { - .type = PT_INT, - .id = "auto", - .name = N_("Automatic checking"), - .desc = N_("Check for the services' presence. If the service is no " - "longer broadcast this field will change to " - "Missing In PAT/SDT."), - .doc = prop_doc_servicechecking, - .list = service_class_auto_list, - .off = offsetof(service_t, s_auto), - .opts = PO_ADVANCED | PO_DOC_NLIST, - }, - { - .type = PT_STR, - .islist = 1, - .id = "channel", - .name = N_("Channel"), - .desc = N_("The channel this service is mapped to."), - .get = service_class_channel_get, - .set = service_class_channel_set, - .list = channel_class_get_list, - .rend = service_class_channel_rend, - .opts = PO_NOSAVE - }, - { - .type = PT_INT, - .id = "priority", - .name = N_("Priority (-10..10)"), - .desc = N_("Service priority. Enter a value between -10 and " - "10. A higher value indicates a higher preference. " - "See Help for more info."), - .off = offsetof(service_t, s_prio), - .opts = PO_ADVANCED - }, - { - .type = PT_BOOL, - .id = "encrypted", - .name = N_("Encrypted"), - .desc = N_("The service's encryption status."), - .get = service_class_encrypted_get, - .opts = PO_NOSAVE | PO_RDONLY - }, - { - .type = PT_STR, - .id = "caid", - .name = N_("CAID"), - .desc = N_("The Conditional Access ID used for the service."), - .get = service_class_caid_get, - .opts = PO_NOSAVE | PO_RDONLY | PO_HIDDEN | PO_EXPERT, - }, - { - .type = PT_INT, - .id = "s_type_user", - .name = N_("Type override"), - .desc = N_("Service type override. This value will override the " - "service type provided by the stream."), - .list = service_type_auto_list, - .off = offsetof(service_t, s_type_user), - .opts = PO_ADVANCED | PO_DOC_NLIST, - }, - {} - } -}; - -const idclass_t service_raw_class = { - .ic_class = "service_raw", - .ic_caption = N_("Service raw"), - .ic_event = "service_raw", - .ic_perm_def = ACCESS_ADMIN, - .ic_delete = service_class_delete, - .ic_save = NULL, - .ic_get_title = service_class_get_title, - .ic_properties = NULL -}; +const idclass_t service_class = {.ic_class = "service", + .ic_caption = N_("Service"), + .ic_event = "service", + .ic_perm_def = ACCESS_ADMIN, + .ic_delete = service_class_delete, + .ic_save = service_class_save, + .ic_load = service_class_load, + .ic_get_title = service_class_get_title, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/Disable service."), + .off = offsetof(service_t, s_enabled), + .notify = service_class_notify_enabled, + }, + { + .type = PT_INT, + .id = "auto", + .name = N_("Automatic checking"), + .desc = N_("Check for the services' presence. If the service is no " + "longer broadcast this field will change to " + "Missing In PAT/SDT."), + .doc = prop_doc_servicechecking, + .list = service_class_auto_list, + .off = offsetof(service_t, s_auto), + .opts = PO_ADVANCED | PO_DOC_NLIST, + }, + {.type = PT_STR, + .islist = 1, + .id = "channel", + .name = N_("Channel"), + .desc = N_("The channel this service is mapped to."), + .get = service_class_channel_get, + .set = service_class_channel_set, + .list = channel_class_get_list, + .rend = service_class_channel_rend, + .opts = PO_NOSAVE}, + {.type = PT_INT, + .id = "priority", + .name = N_("Priority (-10..10)"), + .desc = N_("Service priority. Enter a value between -10 and " + "10. A higher value indicates a higher preference. " + "See Help for more info."), + .off = offsetof(service_t, s_prio), + .opts = PO_ADVANCED}, + {.type = PT_BOOL, + .id = "encrypted", + .name = N_("Encrypted"), + .desc = N_("The service's encryption status."), + .get = service_class_encrypted_get, + .opts = PO_NOSAVE | PO_RDONLY}, + { + .type = PT_STR, + .id = "caid", + .name = N_("CAID"), + .desc = N_("The Conditional Access ID used for the service."), + .get = service_class_caid_get, + .opts = PO_NOSAVE | PO_RDONLY | PO_HIDDEN | PO_EXPERT, + }, + { + .type = PT_INT, + .id = "s_type_user", + .name = N_("Type override"), + .desc = N_("Service type override. This value will override the " + "service type provided by the stream."), + .list = service_type_auto_list, + .off = offsetof(service_t, s_type_user), + .opts = PO_ADVANCED | PO_DOC_NLIST, + }, + {}}}; + +const idclass_t service_raw_class = {.ic_class = "service_raw", + .ic_caption = N_("Service raw"), + .ic_event = "service_raw", + .ic_perm_def = ACCESS_ADMIN, + .ic_delete = service_class_delete, + .ic_save = NULL, + .ic_get_title = service_class_get_title, + .ic_properties = NULL}; /** * Service lock must be held */ -void -service_stop(service_t *t) -{ +void service_stop(service_t* t) { mtimer_disarm(&t->s_receive_timer); t->s_stop_feed(t); @@ -276,7 +238,6 @@ service_stop(service_t *t) tvh_mutex_unlock(&t->s_stream_mutex); } - /** * Remove the given subscriber from the service * @@ -284,14 +245,11 @@ service_stop(service_t *t) * * Global lock must be held */ -void -service_remove_subscriber(service_t *t, th_subscription_t *s, - int reason) -{ +void service_remove_subscriber(service_t* t, th_subscription_t* s, int reason) { lock_assert(&global_lock); - th_subscription_t *s_next; + th_subscription_t* s_next; - if(s == NULL) { + if (s == NULL) { for (s = LIST_FIRST(&t->s_subscriptions); s; s = s_next) { s_next = LIST_NEXT(s, ths_service_link); if (reason == SM_CODE_SVC_NOT_ENABLED && s->ths_channel == NULL) @@ -306,10 +264,7 @@ service_remove_subscriber(service_t *t, th_subscription_t *s, /** * */ -int -service_start(service_t *t, int instance, int weight, int flags, - int timeout, int postpone) -{ +int service_start(service_t* t, int instance, int weight, int flags, int timeout, int postpone) { int r, stimeout = 10; lock_assert(&global_lock); @@ -329,7 +284,7 @@ service_start(service_t *t, int instance, int weight, int flags, descrambler_caid_changed(t); - if((r = t->s_start_feed(t, instance, weight, flags))) + if ((r = t->s_start_feed(t, instance, weight, flags))) return r; descrambler_service_start(t); @@ -345,39 +300,41 @@ service_start(service_t *t, int instance, int weight, int flags, tvh_mutex_unlock(&t->s_stream_mutex); - if(t->s_grace_period != NULL) + if (t->s_grace_period != NULL) stimeout = t->s_grace_period(t); stimeout += postpone; - t->s_timeout = timeout; + t->s_timeout = timeout; t->s_grace_delay = stimeout; if (stimeout > 0) - mtimer_arm_rel(&t->s_receive_timer, service_data_timeout, t, - sec2mono(stimeout)); + mtimer_arm_rel(&t->s_receive_timer, service_data_timeout, t, sec2mono(stimeout)); return 0; } - /** * Main entry point for starting a service based on a channel */ -service_instance_t * -service_find_instance - (service_t *s, channel_t *ch, tvh_input_t *ti, - profile_chain_t *prch, service_instance_list_t *sil, - int *error, int weight, int flags, int timeout, int postpone) -{ - idnode_list_mapping_t *ilm; - service_instance_t *si, *next; - profile_t *pro = prch ? prch->prch_pro : NULL; - int r, r1; +service_instance_t* service_find_instance(service_t* s, + channel_t* ch, + tvh_input_t* ti, + profile_chain_t* prch, + service_instance_list_t* sil, + int* error, + int weight, + int flags, + int timeout, + int postpone) { + idnode_list_mapping_t* ilm; + service_instance_t * si, *next; + profile_t* pro = prch ? prch->prch_pro : NULL; + int r, r1; lock_assert(&global_lock); /* Build list */ r = 0; if (flags & SUBSCRIPTION_SWSERVICE) { - TAILQ_FOREACH(si, sil, si_link) { + TAILQ_FOREACH (si, sil, si_link) { next = TAILQ_NEXT(si, si_link); if (next && next->si_s != si->si_s) { r++; @@ -385,10 +342,10 @@ service_find_instance } } } - TAILQ_FOREACH(si, sil, si_link) { + TAILQ_FOREACH (si, sil, si_link) { si->si_mark = 1; if (r && (flags & SUBSCRIPTION_SWSERVICE) != 0) { - TAILQ_FOREACH(next, sil, si_link) + TAILQ_FOREACH (next, sil, si_link) if (next != si && si->si_s == next->si_s && si->si_error) next->si_error = MAX(next->si_error, si->si_error); } @@ -400,11 +357,10 @@ service_find_instance *error = SM_CODE_SVC_NOT_ENABLED; return NULL; } - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - s = (service_t *)ilm->ilm_in1; + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t*)ilm->ilm_in1; if (s->s_is_enabled(s, flags)) { - if (pro == NULL || - pro->pro_svfilter == PROFILE_SVF_NONE || + if (pro == NULL || pro->pro_svfilter == PROFILE_SVF_NONE || (pro->pro_svfilter == PROFILE_SVF_SD && service_is_sdtv(s)) || (pro->pro_svfilter == PROFILE_SVF_HD && service_is_hdtv(s)) || (pro->pro_svfilter == PROFILE_SVF_FHD && service_is_fhdtv(s)) || @@ -416,29 +372,29 @@ service_find_instance } } /* find a valid instance, no error and "user" idle */ - TAILQ_FOREACH(si, sil, si_link) - if (si->si_weight < SUBSCRIPTION_PRIO_MIN && si->si_error == 0) break; + TAILQ_FOREACH (si, sil, si_link) + if (si->si_weight < SUBSCRIPTION_PRIO_MIN && si->si_error == 0) + break; /* SD->HD->FHD->UHD fallback */ - if (si == NULL && pro && - pro->pro_svfilter == PROFILE_SVF_SD) { - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - s = (service_t *)ilm->ilm_in1; + if (si == NULL && pro && pro->pro_svfilter == PROFILE_SVF_SD) { + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t*)ilm->ilm_in1; if (s->s_is_enabled(s, flags) && service_is_hdtv(s)) { r1 = s->s_enlist(s, ti, sil, flags, weight); if (r1 && r == 0) r = r1; } } - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - s = (service_t *)ilm->ilm_in1; + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t*)ilm->ilm_in1; if (s->s_is_enabled(s, flags) && service_is_fhdtv(s)) { r1 = s->s_enlist(s, ti, sil, flags, weight); if (r1 && r == 0) r = r1; } } - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - s = (service_t *)ilm->ilm_in1; + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t*)ilm->ilm_in1; if (s->s_is_enabled(s, flags) && service_is_uhdtv(s)) { r1 = s->s_enlist(s, ti, sil, flags, weight); if (r1 && r == 0) @@ -446,30 +402,30 @@ service_find_instance } } /* find a valid instance, no error and "user" idle */ - TAILQ_FOREACH(si, sil, si_link) - if (si->si_weight < SUBSCRIPTION_PRIO_MIN && si->si_error == 0) break; + TAILQ_FOREACH (si, sil, si_link) + if (si->si_weight < SUBSCRIPTION_PRIO_MIN && si->si_error == 0) + break; } /* UHD->FHD->HD->SD fallback */ - if (si == NULL && pro && - pro->pro_svfilter == PROFILE_SVF_UHD) { - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - s = (service_t *)ilm->ilm_in1; + if (si == NULL && pro && pro->pro_svfilter == PROFILE_SVF_UHD) { + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t*)ilm->ilm_in1; if (s->s_is_enabled(s, flags) && service_is_fhdtv(s)) { r1 = s->s_enlist(s, ti, sil, flags, weight); if (r1 && r == 0) r = r1; } } - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - s = (service_t *)ilm->ilm_in1; + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t*)ilm->ilm_in1; if (s->s_is_enabled(s, flags) && service_is_hdtv(s)) { r1 = s->s_enlist(s, ti, sil, flags, weight); if (r1 && r == 0) r = r1; } } - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - s = (service_t *)ilm->ilm_in1; + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t*)ilm->ilm_in1; if (s->s_is_enabled(s, flags) && service_is_sdtv(s)) { r1 = s->s_enlist(s, ti, sil, flags, weight); if (r1 && r == 0) @@ -477,13 +433,14 @@ service_find_instance } } /* find a valid instance, no error and "user" idle */ - TAILQ_FOREACH(si, sil, si_link) - if (si->si_weight < SUBSCRIPTION_PRIO_MIN && si->si_error == 0) break; + TAILQ_FOREACH (si, sil, si_link) + if (si->si_weight < SUBSCRIPTION_PRIO_MIN && si->si_error == 0) + break; } /* fallback, enlist all instances */ if (si == NULL) { - LIST_FOREACH(ilm, &ch->ch_services, ilm_in2_link) { - s = (service_t *)ilm->ilm_in1; + LIST_FOREACH (ilm, &ch->ch_services, ilm_in2_link) { + s = (service_t*)ilm->ilm_in1; if (s->s_is_enabled(s, flags)) { r1 = s->s_enlist(s, ti, sil, flags, weight); if (r1 && r == 0) @@ -491,7 +448,7 @@ service_find_instance } } } - TAILQ_FOREACH(si, sil, si_link) + TAILQ_FOREACH (si, sil, si_link) if (!si->si_error) { r = 0; break; @@ -505,9 +462,9 @@ service_find_instance } /* Clean */ - for(si = TAILQ_FIRST(sil); si != NULL; si = next) { + for (si = TAILQ_FIRST(sil); si != NULL; si = next) { next = TAILQ_NEXT(si, si_link); - if(si->si_mark) + if (si->si_mark) service_instance_destroy(sil, si); } @@ -525,16 +482,24 @@ service_find_instance } /* Debug */ - TAILQ_FOREACH(si, sil, si_link) { - const char *name = ch ? channel_get_name(ch, NULL) : NULL; - if (!name && s) name = s->s_nicename; - tvhdebug(LS_SERVICE, "%d: %s si %p %s weight %d prio %d error %d (%s)", - si->si_instance, name, si, si->si_source, si->si_weight, si->si_prio, - si->si_error, streaming_code2txt(si->si_error)); + TAILQ_FOREACH (si, sil, si_link) { + const char* name = ch ? channel_get_name(ch, NULL) : NULL; + if (!name && s) + name = s->s_nicename; + tvhdebug(LS_SERVICE, + "%d: %s si %p %s weight %d prio %d error %d (%s)", + si->si_instance, + name, + si, + si->si_source, + si->si_weight, + si->si_prio, + si->si_error, + streaming_code2txt(si->si_error)); } /* Already running? */ - TAILQ_FOREACH(si, sil, si_link) + TAILQ_FOREACH (si, sil, si_link) if (si->si_s->s_status == SERVICE_RUNNING && si->si_error == 0) { tvhtrace(LS_SERVICE, "return already running %p", si); return si; @@ -542,14 +507,14 @@ service_find_instance /* Forced, handle priority settings */ si = NULL; - TAILQ_FOREACH(next, sil, si_link) + TAILQ_FOREACH (next, sil, si_link) if (next->si_weight < 0 && next->si_error == 0) if (si == NULL || next->si_prio > si->si_prio) si = next; /* Idle */ if (!si) { - TAILQ_FOREACH_REVERSE(si, sil, service_instance_list, si_link) + TAILQ_FOREACH_REVERSE (si, sil, service_instance_list, si_link) if (si->si_weight == 0 && si->si_error == 0) break; } @@ -557,8 +522,9 @@ service_find_instance /* Bump the one with lowest weight or bigger priority */ if (!si) { next = NULL; - TAILQ_FOREACH(si, sil, si_link) { - if (si->si_error) continue; + TAILQ_FOREACH (si, sil, si_link) { + if (si->si_error) + continue; if (next == NULL) { if (si->si_weight < weight) next = si; @@ -572,7 +538,7 @@ service_find_instance } /* Failed */ - if(si == NULL) { + if (si == NULL) { if (*error < SM_CODE_NO_FREE_ADAPTER) *error = SM_CODE_NO_FREE_ADAPTER; return NULL; @@ -590,14 +556,11 @@ service_find_instance return si; } - /** * */ -void -service_unref(service_t *t) -{ - if((atomic_add(&t->s_refcount, -1)) == 1) { +void service_unref(service_t* t) { + if ((atomic_add(&t->s_refcount, -1)) == 1) { if (t->s_unref) t->s_unref(t); free(t->s_nicename); @@ -605,37 +568,30 @@ service_unref(service_t *t) } } - /** * */ -void -service_ref(service_t *t) -{ +void service_ref(service_t* t) { atomic_add(&t->s_refcount, 1); } - - /** * Destroy a service */ -void -service_destroy(service_t *t, int delconf) -{ - th_subscription_t *s; - idnode_list_mapping_t *ilm; +void service_destroy(service_t* t, int delconf) { + th_subscription_t* s; + idnode_list_mapping_t* ilm; lock_assert(&global_lock); idnode_save_check(&t->s_id, delconf); - if(t->s_delete != NULL) + if (t->s_delete != NULL) t->s_delete(t, delconf); service_mapper_remove(t); - while((s = LIST_FIRST(&t->s_subscriptions)) != NULL) + while ((s = LIST_FIRST(&t->s_subscriptions)) != NULL) subscription_unlink_service(s, SM_CODE_SOURCE_DELETED); bouquet_destroy_by_service(t, delconf); @@ -657,31 +613,28 @@ service_destroy(service_t *t, int delconf) } switch (t->s_type) { - case STYPE_RAW: - TAILQ_REMOVE(&service_raw_all, t, s_all_link); - break; - case STYPE_RAW_REMOVED: - TAILQ_REMOVE(&service_raw_remove, t, s_all_link); - break; - default: - TAILQ_REMOVE(&service_all, t, s_all_link); + case STYPE_RAW: + TAILQ_REMOVE(&service_raw_all, t, s_all_link); + break; + case STYPE_RAW_REMOVED: + TAILQ_REMOVE(&service_raw_remove, t, s_all_link); + break; + default: + TAILQ_REMOVE(&service_all, t, s_all_link); } service_unref(t); } -static void -service_remove_raw_timer_cb(void *aux) -{ - service_t *t; +static void service_remove_raw_timer_cb(void* aux) { + service_t* t; while ((t = TAILQ_FIRST(&service_raw_remove)) != NULL) service_destroy(t, 0); } -void -service_remove_raw(service_t *t) -{ - if (t == NULL) return; +void service_remove_raw(service_t* t) { + if (t == NULL) + return; assert(t->s_type == STYPE_RAW); t->s_type = STYPE_RAW_REMOVED; TAILQ_REMOVE(&service_raw_all, t, s_all_link); @@ -689,39 +642,29 @@ service_remove_raw(service_t *t) mtimer_arm_rel(&service_raw_remove_timer, service_remove_raw_timer_cb, NULL, 0); } -void -service_set_enabled(service_t *t, int enabled, int _auto) -{ +void service_set_enabled(service_t* t, int enabled, int _auto) { if (t->s_enabled != !!enabled) { t->s_enabled = !!enabled; - t->s_auto = _auto; + t->s_auto = _auto; service_class_notify_enabled(t, NULL); service_request_save(t); idnode_notify_changed(&t->s_id); } } -static int64_t -service_channel_number ( service_t *s ) -{ +static int64_t service_channel_number(service_t* s) { return 0; } -static const char * -service_channel_name ( service_t *s ) -{ +static const char* service_channel_name(service_t* s) { return NULL; } -static const char * -service_provider_name ( service_t *s ) -{ +static const char* service_provider_name(service_t* s) { return NULL; } -void -service_memoryinfo ( service_t *s, int64_t *size ) -{ +void service_memoryinfo(service_t* s, int64_t* size) { *size += sizeof(*s); *size += tvh_strlen(s->s_nicename); } @@ -729,12 +672,12 @@ service_memoryinfo ( service_t *s, int64_t *size ) /** * Create and initialize a new service struct */ -service_t * -service_create0 - ( service_t *t, int service_type, - const idclass_t *class, const char *uuid, - int source_type, htsmsg_t *conf ) -{ +service_t* service_create0(service_t* t, + int service_type, + const idclass_t* class, + const char* uuid, + int source_type, + htsmsg_t* conf) { lock_assert(&global_lock); if (idnode_insert(&t->s_id, uuid, class, 0)) { @@ -750,11 +693,11 @@ service_create0 TAILQ_INSERT_TAIL(&service_all, t, s_all_link); tvh_mutex_init(&t->s_stream_mutex, NULL); - t->s_type = service_type; - t->s_type_user = ST_UNSET; - t->s_source_type = source_type; - t->s_refcount = 1; - t->s_enabled = 1; + t->s_type = service_type; + t->s_type_user = ST_UNSET; + t->s_source_type = source_type; + t->s_refcount = 1; + t->s_enabled = 1; t->s_channel_number = service_channel_number; t->s_channel_name = service_channel_name; t->s_provider_name = service_provider_name; @@ -773,13 +716,11 @@ service_create0 /** * */ -static int -service_make_nicename0(service_t *t, char *buf, size_t len, int adapter) -{ - char buf2[16]; +static int service_make_nicename0(service_t* t, char* buf, size_t len, int adapter) { + char buf2[16]; source_info_t si; - char *service_name; - int prefidx; + char* service_name; + int prefidx; lock_assert(&t->s_stream_mutex); @@ -791,18 +732,20 @@ service_make_nicename0(service_t *t, char *buf, size_t len, int adapter) service_name = buf2; } - snprintf(buf, len, - "%s%s%s%s%s%s%s", - adapter && si.si_adapter ? si.si_adapter : "", - adapter && si.si_adapter && si.si_network ? "/" : "", - si.si_network ?: "", si.si_network && si.si_mux ? "/" : "", - si.si_mux ?: "", si.si_mux && service_name ? "/" : "", - service_name ?: ""); + snprintf(buf, + len, + "%s%s%s%s%s%s%s", + adapter && si.si_adapter ? si.si_adapter : "", + adapter && si.si_adapter && si.si_network ? "/" : "", + si.si_network ?: "", + si.si_network && si.si_mux ? "/" : "", + si.si_mux ?: "", + si.si_mux && service_name ? "/" : "", + service_name ?: ""); prefidx = (adapter && si.si_adapter ? strlen(si.si_adapter) : 0) + - (adapter && si.si_adapter && si.si_network ? 1 : 0) + - (si.si_network ? strlen(si.si_network) : 0) + - (si.si_network && si.si_mux ? 1 : 0) + - (si.si_mux ? strlen(si.si_mux) : 0); + (adapter && si.si_adapter && si.si_network ? 1 : 0) + + (si.si_network ? strlen(si.si_network) : 0) + (si.si_network && si.si_mux ? 1 : 0) + + (si.si_mux ? strlen(si.si_mux) : 0); service_source_info_free(&si); @@ -812,16 +755,14 @@ service_make_nicename0(service_t *t, char *buf, size_t len, int adapter) /** * */ -const char * -service_make_nicename(service_t *t) -{ - int prefidx; +const char* service_make_nicename(service_t* t) { + int prefidx; char buf[256]; prefidx = service_make_nicename0(t, buf, sizeof(buf), 0); free(t->s_nicename); - t->s_nicename = strdup(buf); + t->s_nicename = strdup(buf); t->s_nicename_prefidx = prefidx; elementary_set_update_nicename(&t->s_components, t->s_nicename); @@ -832,17 +773,15 @@ service_make_nicename(service_t *t) /** * */ -static void -service_data_timeout(void *aux) -{ - service_t *t = aux; - int flags = 0; +static void service_data_timeout(void* aux) { + service_t* t = aux; + int flags = 0; tvh_mutex_lock(&t->s_stream_mutex); - if(!(t->s_streaming_status & TSS_PACKETS)) + if (!(t->s_streaming_status & TSS_PACKETS)) flags |= TSS_GRACEPERIOD; - if(!(t->s_streaming_live & TSS_LIVE)) + if (!(t->s_streaming_live & TSS_LIVE)) flags |= TSS_TIMEOUT; if (flags) service_set_streaming_status_flags(t, flags); @@ -851,81 +790,71 @@ service_data_timeout(void *aux) tvh_mutex_unlock(&t->s_stream_mutex); if (t->s_timeout > 0) - mtimer_arm_rel(&t->s_receive_timer, service_data_timeout, t, - sec2mono(t->s_timeout)); + mtimer_arm_rel(&t->s_receive_timer, service_data_timeout, t, sec2mono(t->s_timeout)); } -int -service_is_sdtv(const service_t *t) -{ +int service_is_sdtv(const service_t* t) { char s_type; - if(t->s_type_user == ST_UNSET) + if (t->s_type_user == ST_UNSET) s_type = t->s_servicetype; else s_type = t->s_type_user; if (s_type == ST_SDTV) return 1; else if (s_type == ST_NONE) { - elementary_stream_t *st; - TAILQ_FOREACH(st, &t->s_components.set_all, es_link) + elementary_stream_t* st; + TAILQ_FOREACH (st, &t->s_components.set_all, es_link) if (SCT_ISVIDEO(st->es_type) && st->es_height < 720) return 1; } return 0; } -int -service_is_hdtv(const service_t *t) -{ +int service_is_hdtv(const service_t* t) { char s_type; - if(t->s_type_user == ST_UNSET) + if (t->s_type_user == ST_UNSET) s_type = t->s_servicetype; else s_type = t->s_type_user; if (s_type == ST_HDTV) return 1; else if (s_type == ST_NONE) { - elementary_stream_t *st; - TAILQ_FOREACH(st, &t->s_components.set_all, es_link) - if (SCT_ISVIDEO(st->es_type) && - st->es_height >= 720 && st->es_height < 1080) + elementary_stream_t* st; + TAILQ_FOREACH (st, &t->s_components.set_all, es_link) + if (SCT_ISVIDEO(st->es_type) && st->es_height >= 720 && st->es_height < 1080) return 1; } return 0; } -int -service_is_fhdtv(const service_t *t) -{ +int service_is_fhdtv(const service_t* t) { char s_type; - if(t->s_type_user == ST_UNSET) + if (t->s_type_user == ST_UNSET) s_type = t->s_servicetype; else s_type = t->s_type_user; if (s_type == ST_FHDTV) return 1; else if (s_type == ST_NONE) { - elementary_stream_t *st; - TAILQ_FOREACH(st, &t->s_components.set_all, es_link) + elementary_stream_t* st; + TAILQ_FOREACH (st, &t->s_components.set_all, es_link) if (SCT_ISVIDEO(st->es_type) && st->es_height >= 1080 && st->es_height < 1440) return 1; } return 0; } -int -service_is_uhdtv(const service_t *t) -{ +int service_is_uhdtv(const service_t* t) { char s_type; - if(t->s_type_user == ST_UNSET) + if (t->s_type_user == ST_UNSET) s_type = t->s_servicetype; else s_type = t->s_type_user; if (s_type == ST_UHDTV) return 1; else if (s_type == ST_NONE) { - elementary_stream_t *st; - TAILQ_FOREACH(st, &t->s_components.set_all, es_link) + elementary_stream_t* st; + TAILQ_FOREACH (st, &t->s_components.set_all, es_link) if (SCT_ISVIDEO(st->es_type) && st->es_height >= 1440) return 1; } @@ -935,20 +864,18 @@ service_is_uhdtv(const service_t *t) /** * */ -int -service_is_radio(const service_t *t) -{ - int ret = 0; +int service_is_radio(const service_t* t) { + int ret = 0; char s_type; - if(t->s_type_user == ST_UNSET) + if (t->s_type_user == ST_UNSET) s_type = t->s_servicetype; else s_type = t->s_type_user; if (s_type == ST_RADIO) return 1; else if (s_type == ST_NONE) { - elementary_stream_t *st; - TAILQ_FOREACH(st, &t->s_components.set_all, es_link) { + elementary_stream_t* st; + TAILQ_FOREACH (st, &t->s_components.set_all, es_link) { if (SCT_ISVIDEO(st->es_type)) return 0; else if (SCT_ISAUDIO(st->es_type)) @@ -961,15 +888,13 @@ service_is_radio(const service_t *t) /** * Is encrypted */ -int -service_is_encrypted(const service_t *t) -{ - elementary_stream_t *st; - if (((mpegts_service_t *)t)->s_dvb_forcecaid == 0xffff) +int service_is_encrypted(const service_t* t) { + elementary_stream_t* st; + if (((mpegts_service_t*)t)->s_dvb_forcecaid == 0xffff) return 0; - if (((mpegts_service_t *)t)->s_dvb_forcecaid) + if (((mpegts_service_t*)t)->s_dvb_forcecaid) return 1; - TAILQ_FOREACH(st, &t->s_components.set_all, es_link) + TAILQ_FOREACH (st, &t->s_components.set_all, es_link) if (st->es_type == SCT_CA) return 1; return 0; @@ -978,28 +903,26 @@ service_is_encrypted(const service_t *t) /* * String describing service type */ -const char * -service_servicetype_txt ( service_t *s ) -{ - static const char *types[] = { - "HDTV", "SDTV", "Radio", "FHDTV", "UHDTV", "Other" - }; - if (service_is_hdtv(s)) return types[0]; - if (service_is_sdtv(s)) return types[1]; - if (service_is_radio(s)) return types[2]; - if (service_is_fhdtv(s)) return types[3]; - if (service_is_uhdtv(s)) return types[4]; +const char* service_servicetype_txt(service_t* s) { + static const char* types[] = {"HDTV", "SDTV", "Radio", "FHDTV", "UHDTV", "Other"}; + if (service_is_hdtv(s)) + return types[0]; + if (service_is_sdtv(s)) + return types[1]; + if (service_is_radio(s)) + return types[2]; + if (service_is_fhdtv(s)) + return types[3]; + if (service_is_uhdtv(s)) + return types[4]; return types[5]; } - /** * */ -void -service_send_streaming_status(service_t *t) -{ - streaming_message_t *sm; +void service_send_streaming_status(service_t* t) { + streaming_message_t* sm; lock_assert(&t->s_stream_mutex); sm = streaming_msg_create_code(SMT_SERVICE_STATUS, t->s_streaming_status); @@ -1009,28 +932,27 @@ service_send_streaming_status(service_t *t) /** * */ -void -service_set_streaming_status_flags_(service_t *t, int set) -{ +void service_set_streaming_status_flags_(service_t* t, int set) { lock_assert(&t->s_stream_mutex); - if(set == t->s_streaming_status) + if (set == t->s_streaming_status) return; // Already set t->s_streaming_status = set; - tvhdebug(LS_SERVICE, "%s: Status changed to %s%s%s%s%s%s%s%s%s%s", - service_nicename(t), - set & TSS_INPUT_HARDWARE ? "[Hardware input] " : "", - set & TSS_INPUT_SERVICE ? "[Input on service] " : "", - set & TSS_MUX_PACKETS ? "[Demuxed packets] " : "", - set & TSS_PACKETS ? "[Reassembled packets] " : "", - set & TSS_NO_DESCRAMBLER ? "[No available descrambler] " : "", - set & TSS_NO_ACCESS ? "[No access] " : "", - set & TSS_CA_CHECK ? "[CA check] " : "", - set & TSS_TUNING ? "[Tuning failed] " : "", - set & TSS_GRACEPERIOD ? "[Graceperiod expired] " : "", - set & TSS_TIMEOUT ? "[Data timeout] " : ""); + tvhdebug(LS_SERVICE, + "%s: Status changed to %s%s%s%s%s%s%s%s%s%s", + service_nicename(t), + set & TSS_INPUT_HARDWARE ? "[Hardware input] " : "", + set & TSS_INPUT_SERVICE ? "[Input on service] " : "", + set & TSS_MUX_PACKETS ? "[Demuxed packets] " : "", + set & TSS_PACKETS ? "[Reassembled packets] " : "", + set & TSS_NO_DESCRAMBLER ? "[No available descrambler] " : "", + set & TSS_NO_ACCESS ? "[No access] " : "", + set & TSS_CA_CHECK ? "[CA check] " : "", + set & TSS_TUNING ? "[Tuning failed] " : "", + set & TSS_GRACEPERIOD ? "[Graceperiod expired] " : "", + set & TSS_TIMEOUT ? "[Data timeout] " : ""); service_send_streaming_status(t); } @@ -1038,10 +960,8 @@ service_set_streaming_status_flags_(service_t *t, int set) /** * */ -streaming_start_t * -service_build_streaming_start(service_t *t) -{ - streaming_start_t *ss; +streaming_start_t* service_build_streaming_start(service_t* t) { + streaming_start_t* ss; ss = elementary_stream_build_start(&t->s_components); t->s_setsourceinfo(t, &ss->ss_si); return ss; @@ -1052,17 +972,15 @@ service_build_streaming_start(service_t *t) * Happens if the stream composition changes. * (i.e. an AC3 stream disappears, etc) */ -void -service_restart_streams(service_t *t) -{ - streaming_message_t *sm; - streaming_start_t *ss; - const int had_streams = elementary_set_has_streams(&t->s_components, 1); - const int had_components = had_streams && t->s_running; +void service_restart_streams(service_t* t) { + streaming_message_t* sm; + streaming_start_t* ss; + const int had_streams = elementary_set_has_streams(&t->s_components, 1); + const int had_components = had_streams && t->s_running; elementary_set_filter_build(&t->s_components); - if(had_streams) { + if (had_streams) { if (had_components) { sm = streaming_msg_create_code(SMT_STOP, SM_CODE_SOURCE_RECONFIGURED); streaming_service_deliver(t, sm); @@ -1083,9 +1001,7 @@ service_restart_streams(service_t *t) * Happens if the stream composition changes. * (i.e. an AC3 stream disappears, etc) */ -void -service_restart(service_t *t) -{ +void service_restart(service_t* t) { tvhtrace(LS_SERVICE, "restarting service '%s'", t->s_nicename); if (t->s_type == STYPE_STD) { @@ -1106,20 +1022,24 @@ service_restart(service_t *t) * Update one elementary stream from the parser. * The update should be handled only for the live streaming. */ -void -service_update_elementary_stream(service_t *t, elementary_stream_t *src) -{ - elementary_stream_t *es; - int change = 0, restart = 0; +void service_update_elementary_stream(service_t* t, elementary_stream_t* src) { + elementary_stream_t* es; + int change = 0, restart = 0; es = elementary_stream_find(&t->s_components, src->es_pid); if (es == NULL) return; - # define _CHANGE(field) \ - if (es->field != src->field) { es->field = src->field; change++; } - # define _RESTART(field) \ - if (es->field != src->field) { es->field = src->field; restart++; } +#define _CHANGE(field) \ + if (es->field != src->field) { \ + es->field = src->field; \ + change++; \ + } +#define _RESTART(field) \ + if (es->field != src->field) { \ + es->field = src->field; \ + restart++; \ + } _CHANGE(es_frame_duration); _RESTART(es_width); @@ -1131,8 +1051,8 @@ service_update_elementary_stream(service_t *t, elementary_stream_t *src) _RESTART(es_ext_sri); _CHANGE(es_channels); - # undef _CHANGE - # undef _RESTART +#undef _CHANGE +#undef _RESTART if (change || restart) service_request_save(t); @@ -1144,22 +1064,20 @@ service_update_elementary_stream(service_t *t, elementary_stream_t *src) * */ -static tvh_mutex_t pending_save_mutex; -static tvh_cond_t pending_save_cond; +static tvh_mutex_t pending_save_mutex; +static tvh_cond_t pending_save_cond; static struct service_queue pending_save_queue; /** * */ -void -service_request_save(service_t *t) -{ +void service_request_save(service_t* t) { if (t->s_type != STYPE_STD) return; tvh_mutex_lock(&pending_save_mutex); - if(!t->s_ps_onqueue) { + if (!t->s_ps_onqueue) { t->s_ps_onqueue = 1; TAILQ_INSERT_TAIL(&pending_save_queue, t, s_ps_link); service_ref(t); @@ -1169,23 +1087,18 @@ service_request_save(service_t *t) tvh_mutex_unlock(&pending_save_mutex); } - /** * */ -static void -service_class_delete(struct idnode *self) -{ - service_destroy((service_t *)self, 1); +static void service_class_delete(struct idnode* self) { + service_destroy((service_t*)self, 1); } /** * */ -static htsmsg_t * -service_class_save(struct idnode *self, char *filename, size_t fsize) -{ - service_t *s = (service_t *)self; +static htsmsg_t* service_class_save(struct idnode* self, char* filename, size_t fsize) { + service_t* s = (service_t*)self; if (s->s_config_save) return s->s_config_save(s, filename, fsize); return NULL; @@ -1194,25 +1107,21 @@ service_class_save(struct idnode *self, char *filename, size_t fsize) /** * */ -static void -service_class_load(struct idnode *self, htsmsg_t *c) -{ - service_load((service_t *)self, c); +static void service_class_load(struct idnode* self, htsmsg_t* c) { + service_load((service_t*)self, c); } /** * */ -static void * -service_saver(void *aux) -{ - service_t *t; +static void* service_saver(void* aux) { + service_t* t; tvh_mutex_lock(&pending_save_mutex); - while(tvheadend_is_running()) { + while (tvheadend_is_running()) { - if((t = TAILQ_FIRST(&pending_save_queue)) == NULL) { + if ((t = TAILQ_FIRST(&pending_save_queue)) == NULL) { tvh_cond_wait(&pending_save_cond, &pending_save_mutex); continue; } @@ -1224,7 +1133,7 @@ service_saver(void *aux) tvh_mutex_unlock(&pending_save_mutex); tvh_mutex_lock(&global_lock); - if(t->s_status != SERVICE_ZOMBIE && t->s_config_save) + if (t->s_status != SERVICE_ZOMBIE && t->s_config_save) idnode_changed(&t->s_id); service_unref(t); @@ -1236,41 +1145,35 @@ service_saver(void *aux) return NULL; } - /** * */ pthread_t service_saver_tid; -static void services_memoryinfo_update(memoryinfo_t *my) -{ - service_t *t; - int64_t size = 0, count = 0; +static void services_memoryinfo_update(memoryinfo_t* my) { + service_t* t; + int64_t size = 0, count = 0; lock_assert(&global_lock); - TAILQ_FOREACH(t, &service_all, s_all_link) { + TAILQ_FOREACH (t, &service_all, s_all_link) { t->s_memoryinfo(t, &size); count++; } - TAILQ_FOREACH(t, &service_raw_all, s_all_link) { + TAILQ_FOREACH (t, &service_raw_all, s_all_link) { t->s_memoryinfo(t, &size); count++; } - TAILQ_FOREACH(t, &service_raw_remove, s_all_link) { + TAILQ_FOREACH (t, &service_raw_remove, s_all_link) { t->s_memoryinfo(t, &size); count++; } memoryinfo_update(my, size, count); } -static memoryinfo_t services_memoryinfo = { - .my_name = "Services", - .my_update = services_memoryinfo_update -}; +static memoryinfo_t services_memoryinfo = {.my_name = "Services", + .my_update = services_memoryinfo_update}; -void -service_init(void) -{ +void service_init(void) { memoryinfo_register(&services_memoryinfo); TAILQ_INIT(&pending_save_queue); TAILQ_INIT(&service_all); @@ -1283,10 +1186,8 @@ service_init(void) tvh_thread_create(&service_saver_tid, NULL, service_saver, NULL, "service"); } -void -service_done(void) -{ - service_t *t; +void service_done(void) { + service_t* t; tvh_mutex_lock(&pending_save_mutex); tvh_cond_signal(&pending_save_cond, 0); @@ -1303,9 +1204,7 @@ service_done(void) /** * */ -void -service_source_info_free(struct source_info *si) -{ +void service_source_info_free(struct source_info* si) { free(si->si_adapter); free(si->si_network); free(si->si_network_type); @@ -1315,12 +1214,11 @@ service_source_info_free(struct source_info *si) free(si->si_satpos); } - -void -service_source_info_copy(source_info_t *dst, const source_info_t *src) -{ +void service_source_info_copy(source_info_t* dst, const source_info_t* src) { *dst = *src; -#define COPY(x) if (src->si_##x) dst->si_##x = strdup(src->si_##x) +#define COPY(x) \ + if (src->si_##x) \ + dst->si_##x = strdup(src->si_##x) COPY(adapter); COPY(network); COPY(network_type); @@ -1331,100 +1229,84 @@ service_source_info_copy(source_info_t *dst, const source_info_t *src) #undef COPY } - /** * */ -const char * -service_nicename(service_t *t) -{ +const char* service_nicename(service_t* t) { return t->s_nicename; } -const char * -service_adapter_nicename(service_t *t, char *buf, size_t len) -{ +const char* service_adapter_nicename(service_t* t, char* buf, size_t len) { tvh_mutex_lock(&t->s_stream_mutex); service_make_nicename0(t, buf, len, 1); tvh_mutex_unlock(&t->s_stream_mutex); return buf; } -const char * -service_tss2text(int flags) -{ - if(flags & TSS_NO_ACCESS) +const char* service_tss2text(int flags) { + if (flags & TSS_NO_ACCESS) return "No access"; - if(flags & TSS_TUNING) + if (flags & TSS_TUNING) return "Tuning failed"; - if(flags & TSS_NO_DESCRAMBLER) + if (flags & TSS_NO_DESCRAMBLER) return "No descrambler"; - if(flags & TSS_PACKETS) + if (flags & TSS_PACKETS) return "Got valid packets"; - if(flags & TSS_MUX_PACKETS) + if (flags & TSS_MUX_PACKETS) return "Got multiplexed packets but could not decode further"; - if(flags & TSS_INPUT_SERVICE) + if (flags & TSS_INPUT_SERVICE) return "Got packets for this service but could not decode further"; - if(flags & TSS_INPUT_HARDWARE) + if (flags & TSS_INPUT_HARDWARE) return "Sensed input from hardware but nothing for the service"; - if(flags & TSS_GRACEPERIOD) + if (flags & TSS_GRACEPERIOD) return "No input detected"; - if(flags & TSS_TIMEOUT) + if (flags & TSS_TIMEOUT) return "Data timeout"; return "No status"; } - /** * */ -int -tss2errcode(int tss) -{ - if(tss & TSS_NO_DESCRAMBLER) +int tss2errcode(int tss) { + if (tss & TSS_NO_DESCRAMBLER) return SM_CODE_NO_DESCRAMBLER; - if(tss & TSS_NO_ACCESS) + if (tss & TSS_NO_ACCESS) return SM_CODE_NO_ACCESS; - if(tss & TSS_TUNING) + if (tss & TSS_TUNING) return SM_CODE_TUNING_FAILED; - if(tss & (TSS_GRACEPERIOD|TSS_TIMEOUT)) + if (tss & (TSS_GRACEPERIOD | TSS_TIMEOUT)) return SM_CODE_NO_INPUT; return SM_CODE_OK; } - /** * */ -void -service_refresh_channel(service_t *t) -{ - idnode_list_mapping_t *ilm; - LIST_FOREACH(ilm, &t->s_channels, ilm_in1_link) { - htsp_channel_update((channel_t *)ilm->ilm_in2); +void service_refresh_channel(service_t* t) { + idnode_list_mapping_t* ilm; + LIST_FOREACH (ilm, &t->s_channels, ilm_in1_link) { + htsp_channel_update((channel_t*)ilm->ilm_in2); } } - /** * Priority Then Weight */ -static int -si_cmp(const service_instance_t *a, const service_instance_t *b) -{ +static int si_cmp(const service_instance_t* a, const service_instance_t* b) { int r; r = a->si_prio - b->si_prio; @@ -1436,28 +1318,29 @@ si_cmp(const service_instance_t *a, const service_instance_t *b) /** * */ -service_instance_t * -service_instance_add(service_instance_list_t *sil, - struct service *s, int instance, - const char *source, int prio, int weight) -{ - service_instance_t *si; +service_instance_t* service_instance_add(service_instance_list_t* sil, + struct service* s, + int instance, + const char* source, + int prio, + int weight) { + service_instance_t* si; prio += 10 + MAX(-10, MIN(10, s->s_prio)); /* Existing */ - TAILQ_FOREACH(si, sil, si_link) - if(si->si_s == s && si->si_instance == instance) + TAILQ_FOREACH (si, sil, si_link) + if (si->si_s == s && si->si_instance == instance) break; - if(si == NULL) { - si = calloc(1, sizeof(service_instance_t)); + if (si == NULL) { + si = calloc(1, sizeof(service_instance_t)); si->si_s = s; service_ref(s); si->si_instance = instance; } else { si->si_mark = 0; - if(si->si_prio == prio && si->si_weight == weight) + if (si->si_prio == prio && si->si_weight == weight) return si; TAILQ_REMOVE(sil, si, si_link); } @@ -1471,10 +1354,7 @@ service_instance_add(service_instance_list_t *sil, /** * */ -void -service_instance_destroy - (service_instance_list_t *sil, service_instance_t *si) -{ +void service_instance_destroy(service_instance_list_t* sil, service_instance_t* si) { TAILQ_REMOVE(sil, si, si_link); service_unref(si->si_s); free(si); @@ -1483,36 +1363,32 @@ service_instance_destroy /** * */ -void -service_instance_list_clear(service_instance_list_t *sil) -{ +void service_instance_list_clear(service_instance_list_t* sil) { lock_assert(&global_lock); - service_instance_t *si; - while((si = TAILQ_FIRST(sil)) != NULL) + service_instance_t* si; + while ((si = TAILQ_FIRST(sil)) != NULL) service_instance_destroy(sil, si); } /* * Get name for channel from service */ -const char * -service_get_channel_name ( service_t *s ) -{ - const char *r = NULL; - if (s->s_channel_name) r = s->s_channel_name(s); - if (!r) r = s->s_nicename; +const char* service_get_channel_name(service_t* s) { + const char* r = NULL; + if (s->s_channel_name) + r = s->s_channel_name(s); + if (!r) + r = s->s_nicename; return r; } /* * Get full name for channel from service */ -const char * -service_get_full_channel_name ( service_t *s ) -{ +const char* service_get_full_channel_name(service_t* s) { static char buf[256]; - const char *r = NULL; + const char* r = NULL; int len; if (s->s_channel_name) @@ -1535,63 +1411,57 @@ service_get_full_channel_name ( service_t *s ) /* * Get number for service */ -int64_t -service_get_channel_number ( service_t *s ) -{ - if (s->s_channel_number) return s->s_channel_number(s); +int64_t service_get_channel_number(service_t* s) { + if (s->s_channel_number) + return s->s_channel_number(s); return 0; } /* * Get source identificator for service */ -const char * -service_get_source ( service_t *s ) -{ - if (s->s_source) return s->s_source(s); +const char* service_get_source(service_t* s) { + if (s->s_source) + return s->s_source(s); return NULL; } /* * Get name for channel from service */ -const char * -service_get_channel_icon ( service_t *s ) -{ - const char *r = NULL; - if (s->s_channel_icon) r = s->s_channel_icon(s); +const char* service_get_channel_icon(service_t* s) { + const char* r = NULL; + if (s->s_channel_icon) + r = s->s_channel_icon(s); return r; } /* * Get EPG ID for channel from service */ -const char * -service_get_channel_epgid ( service_t *s ) -{ - if (s->s_channel_epgid) return s->s_channel_epgid(s); +const char* service_get_channel_epgid(service_t* s) { + if (s->s_channel_epgid) + return s->s_channel_epgid(s); return NULL; } /* * */ -void -service_mapped(service_t *s) -{ - if (s->s_mapped) s->s_mapped(s); +void service_mapped(service_t* s) { + if (s->s_mapped) + s->s_mapped(s); } /* * list of known service types */ -htsmsg_t *servicetype_list ( void ) -{ - htsmsg_t *ret;//, *e; - //int i; +htsmsg_t* servicetype_list(void) { + htsmsg_t* ret; //, *e; + // int i; ret = htsmsg_create_list(); #ifdef TODO_FIX_THIS - for (i = 0; i < sizeof(stypetab) / sizeof(stypetab[0]); i++ ) { + for (i = 0; i < sizeof(stypetab) / sizeof(stypetab[0]); i++) { e = htsmsg_create_map(); htsmsg_add_u32(e, "val", stypetab[i].val); htsmsg_add_str(e, "str", stypetab[i].str); @@ -1601,10 +1471,9 @@ htsmsg_t *servicetype_list ( void ) return ret; } -void service_save ( service_t *t, htsmsg_t *m ) -{ - elementary_stream_t *st; - htsmsg_t *list, *sub, *hbbtv; +void service_save(service_t* t, htsmsg_t* m) { + elementary_stream_t* st; + htsmsg_t * list, *sub, *hbbtv; idnode_save(&t->s_id, m); @@ -1615,7 +1484,7 @@ void service_save ( service_t *t, htsmsg_t *m ) tvh_mutex_lock(&t->s_stream_mutex); list = htsmsg_create_list(); - TAILQ_FOREACH(st, &t->s_components.set_all, es_link) { + TAILQ_FOREACH (st, &t->s_components.set_all, es_link) { if (st->es_type == SCT_PCR) continue; @@ -1626,7 +1495,7 @@ void service_save ( service_t *t, htsmsg_t *m ) htsmsg_add_str(sub, "type", streaming_component_type2txt(st->es_type)); htsmsg_add_u32(sub, "position", st->es_position); - if(st->es_lang[0]) + if (st->es_lang[0]) htsmsg_add_str(sub, "language", st->es_lang); if (SCT_ISAUDIO(st->es_type)) { @@ -1635,14 +1504,14 @@ void service_save ( service_t *t, htsmsg_t *m ) htsmsg_add_u32(sub, "audio_version", st->es_audio_version); } - if(st->es_type == SCT_CA) { - caid_t *c; - htsmsg_t *v = htsmsg_create_list(); - LIST_FOREACH(c, &st->es_caids, link) { - htsmsg_t *caid = htsmsg_create_map(); + if (st->es_type == SCT_CA) { + caid_t* c; + htsmsg_t* v = htsmsg_create_list(); + LIST_FOREACH (c, &st->es_caids, link) { + htsmsg_t* caid = htsmsg_create_map(); htsmsg_add_u32(caid, "caid", c->caid); - if(c->providerid) + if (c->providerid) htsmsg_add_u32(caid, "providerid", c->providerid); htsmsg_add_msg(v, NULL, caid); } @@ -1650,20 +1519,20 @@ void service_save ( service_t *t, htsmsg_t *m ) htsmsg_add_msg(sub, "caidlist", v); } - if(st->es_type == SCT_DVBSUB) { + if (st->es_type == SCT_DVBSUB) { htsmsg_add_u32(sub, "compositionid", st->es_composition_id); htsmsg_add_u32(sub, "ancillartyid", st->es_ancillary_id); } - if(st->es_type == SCT_TEXTSUB) + if (st->es_type == SCT_TEXTSUB) htsmsg_add_u32(sub, "parentpid", st->es_parent_pid); - if(SCT_ISVIDEO(st->es_type)) { - if(st->es_width) - htsmsg_add_u32(sub, "width", st->es_width); - if(st->es_height) - htsmsg_add_u32(sub, "height", st->es_height); - if(st->es_frame_duration) + if (SCT_ISVIDEO(st->es_type)) { + if (st->es_width) + htsmsg_add_u32(sub, "width", st->es_width); + if (st->es_height) + htsmsg_add_u32(sub, "height", st->es_height); + if (st->es_frame_duration) htsmsg_add_u32(sub, "duration", st->es_frame_duration); } @@ -1682,11 +1551,9 @@ void service_save ( service_t *t, htsmsg_t *m ) /** * */ -void -service_remove_unseen(const char *type, int days) -{ +void service_remove_unseen(const char* type, int days) { service_t *s, *sn; - time_t before = gclk() - MAX(days, 5) * 24 * 3600; + time_t before = gclk() - MAX(days, 5) * 24 * 3600; lock_assert(&global_lock); for (s = TAILQ_FIRST(&service_all); s; s = sn) { @@ -1699,33 +1566,29 @@ service_remove_unseen(const char *type, int days) /** * */ -static void -add_caid(elementary_stream_t *st, uint16_t caid, uint32_t providerid) -{ - caid_t *c = malloc(sizeof(caid_t)); - c->caid = caid; +static void add_caid(elementary_stream_t* st, uint16_t caid, uint32_t providerid) { + caid_t* c = malloc(sizeof(caid_t)); + c->caid = caid; c->providerid = providerid; - c->pid = 0; - c->use = 1; - c->filter = 0; - c->delete_me = 0; + c->pid = 0; + c->use = 1; + c->filter = 0; + c->delete_me = 0; LIST_INSERT_HEAD(&st->es_caids, c, link); } /** * */ -static void -load_legacy_caid(htsmsg_t *c, elementary_stream_t *st) -{ - uint32_t a, b; - const char *v; +static void load_legacy_caid(htsmsg_t* c, elementary_stream_t* st) { + uint32_t a, b; + const char* v; - if(htsmsg_get_u32(c, "caproviderid", &b)) + if (htsmsg_get_u32(c, "caproviderid", &b)) b = 0; - if(htsmsg_get_u32(c, "caidnum", &a)) { - if((v = htsmsg_get_str(c, "caid")) != NULL) { + if (htsmsg_get_u32(c, "caidnum", &a)) { + if ((v = htsmsg_get_str(c, "caid")) != NULL) { a = name2caid(v); } else { return; @@ -1738,51 +1601,48 @@ load_legacy_caid(htsmsg_t *c, elementary_stream_t *st) /** * */ -static void -load_caid(htsmsg_t *m, elementary_stream_t *st) -{ - htsmsg_field_t *f; - htsmsg_t *c, *v = htsmsg_get_list(m, "caidlist"); - uint32_t a, b; - - if(v == NULL) +static void load_caid(htsmsg_t* m, elementary_stream_t* st) { + htsmsg_field_t* f; + htsmsg_t * c, *v = htsmsg_get_list(m, "caidlist"); + uint32_t a, b; + + if (v == NULL) return; HTSMSG_FOREACH(f, v) { - if((c = htsmsg_get_map_by_field(f)) == NULL) + if ((c = htsmsg_get_map_by_field(f)) == NULL) continue; - if(htsmsg_get_u32(c, "caid", &a)) + if (htsmsg_get_u32(c, "caid", &a)) continue; - if(htsmsg_get_u32(c, "providerid", &b)) + if (htsmsg_get_u32(c, "providerid", &b)) b = 0; add_caid(st, a, b); } } -void service_load ( service_t *t, htsmsg_t *c ) -{ - htsmsg_t *m, *hbbtv; - htsmsg_field_t *f; - int32_t s32; - uint32_t u32, pid, pid2; - elementary_stream_t *st; +void service_load(service_t* t, htsmsg_t* c) { + htsmsg_t * m, *hbbtv; + htsmsg_field_t* f; + int32_t s32; + uint32_t u32, pid, pid2; + elementary_stream_t* st; streaming_component_type_t type; - const char *v; - int shared_pcr = 0; + const char* v; + int shared_pcr = 0; idnode_load(&t->s_id, c); tvh_mutex_lock(&t->s_stream_mutex); - if(!htsmsg_get_s32(c, "verified", &s32)) + if (!htsmsg_get_s32(c, "verified", &s32)) t->s_verified = s32; else t->s_verified = 1; - if(!htsmsg_get_u32(c, "pcr", &u32)) + if (!htsmsg_get_u32(c, "pcr", &u32)) t->s_components.set_pcr_pid = u32; - if(!htsmsg_get_u32(c, "pmt", &u32)) + if (!htsmsg_get_u32(c, "pmt", &u32)) t->s_components.set_pmt_pid = u32; if (config.hbbtv) { @@ -1798,69 +1658,68 @@ void service_load ( service_t *t, htsmsg_t *c ) m = htsmsg_get_list(c, "stream"); if (m) { HTSMSG_FOREACH(f, m) { - if((c = htsmsg_get_map_by_field(f)) == NULL) + if ((c = htsmsg_get_map_by_field(f)) == NULL) continue; - if((v = htsmsg_get_str(c, "type")) == NULL) + if ((v = htsmsg_get_str(c, "type")) == NULL) continue; type = streaming_component_txt2type(v); - if(type == -1 || type == SCT_PCR) + if (type == -1 || type == SCT_PCR) continue; - if(htsmsg_get_u32(c, "pid", &pid)) + if (htsmsg_get_u32(c, "pid", &pid)) continue; pid2 = t->s_components.set_pcr_pid; - if(pid > 0 && pid2 > 0 && pid == pid2) + if (pid > 0 && pid2 > 0 && pid == pid2) shared_pcr = 1; st = elementary_stream_create(&t->s_components, pid, type); - if((v = htsmsg_get_str(c, "language")) != NULL) + if ((v = htsmsg_get_str(c, "language")) != NULL) strlcpy(st->es_lang, lang_code_get(v), 4); if (SCT_ISAUDIO(type)) { - if(!htsmsg_get_u32(c, "audio_type", &u32)) + if (!htsmsg_get_u32(c, "audio_type", &u32)) st->es_audio_type = u32; - if(!htsmsg_get_u32(c, "audio_version", &u32)) + if (!htsmsg_get_u32(c, "audio_version", &u32)) st->es_audio_version = u32; } - if(!htsmsg_get_u32(c, "position", &u32)) + if (!htsmsg_get_u32(c, "position", &u32)) st->es_position = u32; load_legacy_caid(c, st); load_caid(c, st); - if(type == SCT_DVBSUB) { - if(!htsmsg_get_u32(c, "compositionid", &u32)) - st->es_composition_id = u32; + if (type == SCT_DVBSUB) { + if (!htsmsg_get_u32(c, "compositionid", &u32)) + st->es_composition_id = u32; - if(!htsmsg_get_u32(c, "ancillartyid", &u32)) - st->es_ancillary_id = u32; + if (!htsmsg_get_u32(c, "ancillartyid", &u32)) + st->es_ancillary_id = u32; } - if(type == SCT_TEXTSUB) { - if(!htsmsg_get_u32(c, "parentpid", &u32)) - st->es_parent_pid = u32; + if (type == SCT_TEXTSUB) { + if (!htsmsg_get_u32(c, "parentpid", &u32)) + st->es_parent_pid = u32; } - if(SCT_ISVIDEO(type)) { - if(!htsmsg_get_u32(c, "width", &u32)) - st->es_width = u32; + if (SCT_ISVIDEO(type)) { + if (!htsmsg_get_u32(c, "width", &u32)) + st->es_width = u32; - if(!htsmsg_get_u32(c, "height", &u32)) - st->es_height = u32; + if (!htsmsg_get_u32(c, "height", &u32)) + st->es_height = u32; - if(!htsmsg_get_u32(c, "duration", &u32)) + if (!htsmsg_get_u32(c, "duration", &u32)) st->es_frame_duration = u32; } } } if (!shared_pcr) - elementary_stream_type_modify(&t->s_components, - t->s_components.set_pcr_pid, SCT_PCR); + elementary_stream_type_modify(&t->s_components, t->s_components.set_pcr_pid, SCT_PCR); else elementary_stream_type_destroy(&t->s_components, SCT_PCR); elementary_set_sort_streams(&t->s_components); diff --git a/src/service.h b/src/service.h index d4833848f..1b328ea66 100644 --- a/src/service.h +++ b/src/service.h @@ -60,59 +60,56 @@ TAILQ_HEAD(service_queue, service); typedef struct service_instance { TAILQ_ENTRY(service_instance) si_link; - struct service *si_s; /* A reference is held */ - - int si_prio; /* Priority (higher value has more weight) */ - int si_instance; /* Discriminator when having multiple adapters, etc */ - int si_error; /* Set if subscription layer deem this cand - * to be broken. We typically set this if we - * have not seen any demuxed packets after - * the grace period has expired. - * The actual value is current time - */ + struct service* si_s; /* A reference is held */ + + int si_prio; /* Priority (higher value has more weight) */ + int si_instance; /* Discriminator when having multiple adapters, etc */ + int si_error; /* Set if subscription layer deem this cand + * to be broken. We typically set this if we + * have not seen any demuxed packets after + * the grace period has expired. + * The actual value is current time + */ time_t si_error_time; - int si_weight; /* Highest weight that holds this cand */ - int si_mark; /* For mark & sweep */ + int si_weight; /* Highest weight that holds this cand */ + int si_mark; /* For mark & sweep */ char si_source[128]; } service_instance_t; - /** * */ -service_instance_t *service_instance_add(service_instance_list_t *sil, - struct service *s, - int instance, - const char *source, - int prio, - int weight); +service_instance_t* service_instance_add(service_instance_list_t* sil, + struct service* s, + int instance, + const char* source, + int prio, + int weight); -void service_instance_destroy - (service_instance_list_t *sil, service_instance_t *si); +void service_instance_destroy(service_instance_list_t* sil, service_instance_t* si); -void service_instance_list_clear(service_instance_list_t *sil); +void service_instance_list_clear(service_instance_list_t* sil); /** * */ typedef struct service_lcn { LIST_ENTRY(service_lcn) sl_link; - void *sl_bouquet; - uint64_t sl_lcn; - uint8_t sl_seen; + void* sl_bouquet; + uint64_t sl_lcn; + uint8_t sl_seen; } service_lcn_t; - /** * */ -#define SERVICE_AUTO_NORMAL 0 -#define SERVICE_AUTO_OFF 1 -#define SERVICE_AUTO_PAT_MISSING 2 +#define SERVICE_AUTO_NORMAL 0 +#define SERVICE_AUTO_OFF 1 +#define SERVICE_AUTO_PAT_MISSING 2 -#define SERVICE_PMT_AUTO 0xffff +#define SERVICE_PMT_AUTO 0xffff /** * @@ -134,11 +131,11 @@ typedef struct service { SERVICE_RUNNING, /** - * Destroyed, but pointer is till valid. - * This would be the case if transport_destroy() did not actually free + * Destroyed, but pointer is till valid. + * This would be the case if transport_destroy() did not actually free * the transport because there are references held to it. * - * Reference counts can be used so that code can hold a pointer to + * Reference counts can be used so that code can hold a pointer to * a transport without having the global lock. * * Note: No fields in the transport may be accessed without the @@ -147,27 +144,23 @@ typedef struct service { * just drop the refcount and pretend that the transport never * was there in the first place. */ - SERVICE_ZOMBIE, + SERVICE_ZOMBIE, } s_status; /** * Refcount, operated using atomic.h ops. - */ + */ int s_refcount; /** * Service type, standard or raw (for mux or partial mux streaming) */ - enum { - STYPE_STD, - STYPE_RAW, - STYPE_RAW_REMOVED - } s_type; + enum { STYPE_STD, STYPE_RAW, STYPE_RAW_REMOVED } s_type; /** * Source type is used to determine if an output requesting * MPEG-TS can shortcut all the parsing and remuxing. - */ + */ enum { S_MPEG_TS, S_MPEG_PS, @@ -179,7 +172,7 @@ typedef struct service { */ enum { ST_UNSET = -1, - ST_NONE = 0, + ST_NONE = 0, ST_OTHER, ST_SDTV, ST_HDTV, @@ -188,7 +181,7 @@ typedef struct service { ST_RADIO } s_servicetype; -// TODO: should this really be here? + // TODO: should this really be here? /** * Set if transport is enabled (the default). If disabled it should @@ -196,7 +189,7 @@ typedef struct service { * subscription scheduling. */ int s_enabled; - int s_verified; // In PMT and valid streams + int s_verified; // In PMT and valid streams int s_auto; int s_prio; int s_type_user; @@ -206,59 +199,62 @@ typedef struct service { LIST_HEAD(, th_subscription) s_subscriptions; - int (*s_is_enabled)(struct service *t, int flags); + int (*s_is_enabled)(struct service* t, int flags); - int (*s_enlist)(struct service *s, struct tvh_input *ti, - service_instance_list_t *sil, int flags, int weight); + int (*s_enlist)(struct service* s, + struct tvh_input* ti, + service_instance_list_t* sil, + int flags, + int weight); - int (*s_start_feed)(struct service *s, int instance, int weight, int flags); + int (*s_start_feed)(struct service* s, int instance, int weight, int flags); - void (*s_refresh_feed)(struct service *t); + void (*s_refresh_feed)(struct service* t); - void (*s_stop_feed)(struct service *t); + void (*s_stop_feed)(struct service* t); - htsmsg_t *(*s_config_save)(struct service *t, char *filename, size_t fsize); + htsmsg_t* (*s_config_save)(struct service* t, char* filename, size_t fsize); - void (*s_setsourceinfo)(struct service *t, struct source_info *si); + void (*s_setsourceinfo)(struct service* t, struct source_info* si); - int (*s_grace_period)(struct service *t); + int (*s_grace_period)(struct service* t); - void (*s_delete)(struct service *t, int delconf); + void (*s_delete)(struct service* t, int delconf); - void (*s_unref)(struct service *t); + void (*s_unref)(struct service* t); - struct mpegts_apids *(*s_pid_list)(struct service *t); + struct mpegts_apids* (*s_pid_list)(struct service* t); - int (*s_satip_source)(struct service *t); + int (*s_satip_source)(struct service* t); - void (*s_memoryinfo)(struct service *t, int64_t *size); + void (*s_memoryinfo)(struct service* t, int64_t* size); - int (*s_unseen)(struct service *t, const char *type, time_t before); + int (*s_unseen)(struct service* t, const char* type, time_t before); /** * Channel info */ - int64_t (*s_channel_number) (struct service *); - const char *(*s_channel_name) (struct service *); - const char *(*s_source) (struct service *); - const char *(*s_channel_epgid) (struct service *); - htsmsg_t *(*s_channel_tags) (struct service *); - const char *(*s_provider_name) (struct service *); - const char *(*s_channel_icon) (struct service *); - void (*s_mapped) (struct service *); + int64_t (*s_channel_number)(struct service*); + const char* (*s_channel_name)(struct service*); + const char* (*s_source)(struct service*); + const char* (*s_channel_epgid)(struct service*); + htsmsg_t* (*s_channel_tags)(struct service*); + const char* (*s_provider_name)(struct service*); + const char* (*s_channel_icon)(struct service*); + void (*s_mapped)(struct service*); /** * Name usable for displaying to user */ - char *s_nicename; + char* s_nicename; int s_nicename_prefidx; /** * Teletext... */ commercial_advice_t s_tt_commercial_advice; - time_t s_tt_clock; /* Network clock as determined by teletext decoder */ - + time_t s_tt_clock; /* Network clock as determined by teletext decoder */ + /** * Channel mapping */ @@ -294,7 +290,6 @@ typedef struct service { int s_grace_delay; int64_t s_start_time; - /********************************************************* * * Streaming part of transport @@ -302,7 +297,7 @@ typedef struct service { * All access to fields below this must be protected with * s_stream_mutex held. * - * Note: Code holding s_stream_mutex should _never_ + * Note: Code holding s_stream_mutex should _never_ * acquire global_lock while already holding s_stream_mutex. * */ @@ -316,26 +311,24 @@ typedef struct service { /** * - */ + */ int s_streaming_status; // Progress -#define TSS_INPUT_HARDWARE 0x00000001 -#define TSS_INPUT_SERVICE 0x00000002 -#define TSS_MUX_PACKETS 0x00000004 -#define TSS_PACKETS 0x00000008 -#define TSS_NO_ACCESS 0x00000010 -#define TSS_CA_CHECK 0x00000020 - +#define TSS_INPUT_HARDWARE 0x00000001 +#define TSS_INPUT_SERVICE 0x00000002 +#define TSS_MUX_PACKETS 0x00000004 +#define TSS_PACKETS 0x00000008 +#define TSS_NO_ACCESS 0x00000010 +#define TSS_CA_CHECK 0x00000020 // Errors -#define TSS_GRACEPERIOD 0x00010000 -#define TSS_NO_DESCRAMBLER 0x00020000 -#define TSS_TIMEOUT 0x00040000 -#define TSS_TUNING 0x00080000 - -#define TSS_ERRORS 0xffff0000 +#define TSS_GRACEPERIOD 0x00010000 +#define TSS_NO_DESCRAMBLER 0x00020000 +#define TSS_TIMEOUT 0x00040000 +#define TSS_TUNING 0x00080000 +#define TSS_ERRORS 0xffff0000 /** * @@ -345,28 +338,28 @@ typedef struct service { int s_pending_restart; // Live status -#define TSS_LIVE 0x01 +#define TSS_LIVE 0x01 /** * For simple streaming sources (such as video4linux) keeping * track of the video and audio stream is convenient. */ #ifdef MOVE_TO_V4L - elementary_stream_t *s_video; - elementary_stream_t *s_audio; + elementary_stream_t* s_video; + elementary_stream_t* s_audio; #endif - + /** * Descrambling support */ - uint16_t s_dvb_forcecaid; + uint16_t s_dvb_forcecaid; struct th_descrambler_list s_descramblers; - uint8_t s_scrambled_seen; - uint8_t s_scrambled_pass; - th_descrambler_runtime_t *s_descramble; - void *s_descrambler; /* last active descrambler */ - struct descramble_info *s_descramble_info; + uint8_t s_scrambled_seen; + uint8_t s_scrambled_pass; + th_descrambler_runtime_t* s_descramble; + void* s_descrambler; /* last active descrambler */ + struct descramble_info* s_descramble_info; /** * Set of all and filtered components. @@ -383,147 +376,148 @@ typedef struct service { /* * Local channel numbers per bouquet */ - LIST_HEAD(,service_lcn) s_lcns; + LIST_HEAD(, service_lcn) s_lcns; /* * HBBTV */ - htsmsg_t *s_hbbtv; + htsmsg_t* s_hbbtv; } service_t; - void service_init(void); void service_done(void); +int service_start(service_t* t, int instance, int weight, int flags, int timeout, int postpone); +void service_stop(service_t* t); -int service_start(service_t *t, int instance, int weight, int flags, - int timeout, int postpone); -void service_stop(service_t *t); - -service_t *service_create0(service_t *t, int service_type, const idclass_t *idc, - const char *uuid, int source_type, htsmsg_t *conf); +service_t* service_create0(service_t* t, + int service_type, + const idclass_t* idc, + const char* uuid, + int source_type, + htsmsg_t* conf); -#define service_create(t, y, c, u, s, m)\ +#define service_create(t, y, c, u, s, m) \ (struct t*)service_create0(calloc(1, sizeof(struct t), y, &t##_class, c, u, s, m) -void service_unref(service_t *t); +void service_unref(service_t* t); -void service_ref(service_t *t); +void service_ref(service_t* t); -static inline service_t *service_find_by_uuid(const char *uuid) - { return idnode_find(uuid, &service_class, NULL); } -static inline service_t *service_find_by_uuid0(tvh_uuid_t *uuid) - { return idnode_find0(uuid, &service_class, NULL); } - -service_instance_t *service_find_instance(struct service *s, - struct channel *ch, - struct tvh_input *source, - struct profile_chain *prch, - service_instance_list_t *sil, - int *error, int weight, - int flags, int timeout, - int postpone); +static inline service_t* service_find_by_uuid(const char* uuid) { + return idnode_find(uuid, &service_class, NULL); +} +static inline service_t* service_find_by_uuid0(tvh_uuid_t* uuid) { + return idnode_find0(uuid, &service_class, NULL); +} -void service_settings_write(service_t *t); +service_instance_t* service_find_instance(struct service* s, + struct channel* ch, + struct tvh_input* source, + struct profile_chain* prch, + service_instance_list_t* sil, + int* error, + int weight, + int flags, + int timeout, + int postpone); -const char *service_servicetype_txt(service_t *t); +void service_settings_write(service_t* t); -static inline uint16_t service_id16(void *t) - { return ((service_t *)t)->s_components.set_service_id; } +const char* service_servicetype_txt(service_t* t); -int service_is_sdtv(const service_t *t); -int service_is_uhdtv(const service_t *t); -int service_is_fhdtv(const service_t *t); -int service_is_hdtv(const service_t *t); -int service_is_radio(const service_t *t); -static inline int service_is_tv( const service_t *s) - { return service_is_hdtv(s) || service_is_sdtv(s) || service_is_uhdtv(s) || service_is_fhdtv(s); } -static inline int service_is_other(const service_t *t) - { return !service_is_tv(t) && !service_is_radio(t); } +static inline uint16_t service_id16(void* t) { + return ((service_t*)t)->s_components.set_service_id; +} -int service_is_encrypted ( const service_t *t ); +int service_is_sdtv(const service_t* t); +int service_is_uhdtv(const service_t* t); +int service_is_fhdtv(const service_t* t); +int service_is_hdtv(const service_t* t); +int service_is_radio(const service_t* t); +static inline int service_is_tv(const service_t* s) { + return service_is_hdtv(s) || service_is_sdtv(s) || service_is_uhdtv(s) || service_is_fhdtv(s); +} +static inline int service_is_other(const service_t* t) { + return !service_is_tv(t) && !service_is_radio(t); +} -void service_set_enabled ( service_t *t, int enabled, int _auto ); +int service_is_encrypted(const service_t* t); -void service_destroy(service_t *t, int delconf); +void service_set_enabled(service_t* t, int enabled, int _auto); -void service_remove_raw(service_t *); +void service_destroy(service_t* t, int delconf); -void service_remove_subscriber(service_t *t, struct th_subscription *s, - int reason); +void service_remove_raw(service_t*); +void service_remove_subscriber(service_t* t, struct th_subscription* s, int reason); -void service_send_streaming_status(service_t *t); +void service_send_streaming_status(service_t* t); -void service_set_streaming_status_flags_(service_t *t, int flag); +void service_set_streaming_status_flags_(service_t* t, int flag); -static inline void -service_set_streaming_status_flags(service_t *t, int flag) -{ +static inline void service_set_streaming_status_flags(service_t* t, int flag) { int n = t->s_streaming_status; if ((n & flag) != flag) service_set_streaming_status_flags_(t, n | flag); } -static inline void -service_reset_streaming_status_flags(service_t *t, int flag) -{ +static inline void service_reset_streaming_status_flags(service_t* t, int flag) { int n = t->s_streaming_status; if ((n & flag) != 0) service_set_streaming_status_flags_(t, n & ~flag); } -streaming_start_t *service_build_streaming_start(service_t *t); +streaming_start_t* service_build_streaming_start(service_t* t); -void service_restart(service_t *t); +void service_restart(service_t* t); -void service_restart_streams(service_t *t); +void service_restart_streams(service_t* t); -void service_request_save(service_t *t); +void service_request_save(service_t* t); -void service_update_elementary_stream(service_t *t, elementary_stream_t *src); +void service_update_elementary_stream(service_t* t, elementary_stream_t* src); -void service_source_info_free(source_info_t *si); +void service_source_info_free(source_info_t* si); -void service_source_info_copy(source_info_t *dst, const source_info_t *src); +void service_source_info_copy(source_info_t* dst, const source_info_t* src); -const char *service_make_nicename(service_t *t); +const char* service_make_nicename(service_t* t); -const char *service_nicename(service_t *t); +const char* service_nicename(service_t* t); -const char *service_adapter_nicename(service_t *t, char *buf, size_t len); +const char* service_adapter_nicename(service_t* t, char* buf, size_t len); -const char *service_tss2text(int flags); +const char* service_tss2text(int flags); -static inline int service_tss_is_error(int flags) -{ +static inline int service_tss_is_error(int flags) { return flags & TSS_ERRORS ? 1 : 0; } -void service_refresh_channel(service_t *t); +void service_refresh_channel(service_t* t); int tss2errcode(int tss); -htsmsg_t *servicetype_list (void); +htsmsg_t* servicetype_list(void); -void service_load ( service_t *s, htsmsg_t *c ); +void service_load(service_t* s, htsmsg_t* c); -void service_save ( service_t *s, htsmsg_t *c ); +void service_save(service_t* s, htsmsg_t* c); -void service_remove_unseen(const char *type, int days); +void service_remove_unseen(const char* type, int days); -void sort_elementary_streams(service_t *t); +void sort_elementary_streams(service_t* t); -const char *service_get_channel_name (service_t *s); -const char *service_get_full_channel_name (service_t *s); -int64_t service_get_channel_number (service_t *s); -const char *service_get_source (service_t *s); -const char *service_get_channel_icon (service_t *s); -const char *service_get_channel_epgid (service_t *s); +const char* service_get_channel_name(service_t* s); +const char* service_get_full_channel_name(service_t* s); +int64_t service_get_channel_number(service_t* s); +const char* service_get_source(service_t* s); +const char* service_get_channel_icon(service_t* s); +const char* service_get_channel_epgid(service_t* s); -void service_memoryinfo (service_t *s, int64_t *size); +void service_memoryinfo(service_t* s, int64_t* size); -void service_mapped (service_t *s); +void service_mapped(service_t* s); #endif // SERVICE_H__ diff --git a/src/service_mapper.c b/src/service_mapper.c index ee37a54fc..efb77aaff 100644 --- a/src/service_mapper.c +++ b/src/service_mapper.c @@ -30,65 +30,69 @@ typedef struct service_mapper_item { TAILQ_ENTRY(service_mapper_item) link; - service_t *s; + service_t* s; service_mapper_conf_t conf; } service_mapper_item_t; -static service_mapper_status_t service_mapper_stat; +static service_mapper_status_t service_mapper_stat; static tvh_cond_t service_mapper_cond; static TAILQ_HEAD(, service_mapper_item) service_mapper_queue; -service_mapper_t service_mapper_conf; +service_mapper_t service_mapper_conf; -static void *service_mapper_thread ( void *p ); +static void* service_mapper_thread(void* p); /* * Get status */ -service_mapper_status_t -service_mapper_status ( void ) -{ +service_mapper_status_t service_mapper_status(void) { return service_mapper_stat; } /* * Start a new mapping */ -void -service_mapper_start ( const service_mapper_conf_t *conf, htsmsg_t *uuids ) -{ - int e, tr, qd = 0; - service_mapper_item_t *smi; - service_t *s; - char ubuf[UUID_HEX_SIZE]; +void service_mapper_start(const service_mapper_conf_t* conf, htsmsg_t* uuids) { + int e, tr, qd = 0; + service_mapper_item_t* smi; + service_t* s; + char ubuf[UUID_HEX_SIZE]; /* Reset stat counters */ if (TAILQ_EMPTY(&service_mapper_queue)) service_mapper_reset_stats(); /* Check each service */ - TAILQ_FOREACH(s, &service_all, s_all_link) { + TAILQ_FOREACH (s, &service_all, s_all_link) { if (uuids) { - htsmsg_field_t *f; - const char *str; - const char *uuid = idnode_uuid_as_str(&s->s_id, ubuf); + htsmsg_field_t* f; + const char* str; + const char* uuid = idnode_uuid_as_str(&s->s_id, ubuf); HTSMSG_FOREACH(f, uuids) { - if (!(str = htsmsg_field_get_str(f))) continue; - if (!strcmp(str, uuid)) break; + if (!(str = htsmsg_field_get_str(f))) + continue; + if (!strcmp(str, uuid)) + break; } - if (!f) continue; + if (!f) + continue; } - tvhtrace(LS_SERVICE_MAPPER, "check service %s (%s)", - s->s_nicename, idnode_uuid_as_str(&s->s_id, ubuf)); + tvhtrace(LS_SERVICE_MAPPER, + "check service %s (%s)", + s->s_nicename, + idnode_uuid_as_str(&s->s_id, ubuf)); /* Already mapped (or in progress) */ - if (s->s_sm_onqueue) continue; - if (LIST_FIRST(&s->s_channels)) continue; + if (s->s_sm_onqueue) + continue; + if (LIST_FIRST(&s->s_channels)) + continue; tvhtrace(LS_SERVICE_MAPPER, " not mapped"); service_mapper_stat.total++; service_mapper_stat.ignore++; /* Disabled */ - if (!s->s_is_enabled(s, 0)) continue; + if (!s->s_is_enabled(s, 0)) + continue; tvhtrace(LS_SERVICE_MAPPER, " enabled"); /* Get service info */ @@ -98,44 +102,45 @@ service_mapper_start ( const service_mapper_conf_t *conf, htsmsg_t *uuids ) tvh_mutex_unlock(&s->s_stream_mutex); /* Skip non-TV / Radio */ - if (!tr) continue; + if (!tr) + continue; tvhtrace(LS_SERVICE_MAPPER, " radio or tv"); /* Skip encrypted */ - if (!conf->encrypted && e) continue; + if (!conf->encrypted && e) + continue; service_mapper_stat.ignore--; - + /* Queue */ if (conf->check_availability) { tvhtrace(LS_SERVICE_MAPPER, " queue for checking"); - qd = 1; - smi = malloc(sizeof(*smi)); - smi->s = s; + qd = 1; + smi = malloc(sizeof(*smi)); + smi->s = s; smi->conf = *conf; TAILQ_INSERT_TAIL(&service_mapper_queue, smi, link); s->s_sm_onqueue = 1; - - /* Process */ + + /* Process */ } else { tvhtrace(LS_SERVICE_MAPPER, " process"); service_mapper_process(conf, s, NULL); } } - + /* Notify */ api_service_mapper_notify(); /* Signal */ - if (qd) tvh_cond_signal(&service_mapper_cond, 0); + if (qd) + tvh_cond_signal(&service_mapper_cond, 0); } /* * Stop everything */ -void -service_mapper_stop ( void ) -{ - service_mapper_item_t *smi; +void service_mapper_stop(void) { + service_mapper_item_t* smi; while ((smi = TAILQ_FIRST(&service_mapper_queue))) { service_mapper_stat.total--; TAILQ_REMOVE(&service_mapper_queue, smi, link); @@ -149,14 +154,13 @@ service_mapper_stop ( void ) /* * Remove service */ -void -service_mapper_remove ( service_t *s ) -{ - service_mapper_item_t *smi; +void service_mapper_remove(service_t* s) { + service_mapper_item_t* smi; if (s->s_sm_onqueue) { - TAILQ_FOREACH(smi, &service_mapper_queue, link) - if (smi->s == s) break; + TAILQ_FOREACH (smi, &service_mapper_queue, link) + if (smi->s == s) + break; assert(smi); TAILQ_REMOVE(&service_mapper_queue, smi, link); free(smi); @@ -170,14 +174,10 @@ service_mapper_remove ( service_t *s ) /* * Link service and channel */ -int -service_mapper_link ( service_t *s, channel_t *c, void *origin ) -{ - idnode_list_mapping_t *ilm; - - ilm = idnode_list_link(&s->s_id, &s->s_channels, - &c->ch_id, &c->ch_services, - origin, 2); +int service_mapper_link(service_t* s, channel_t* c, void* origin) { + idnode_list_mapping_t* ilm; + + ilm = idnode_list_link(&s->s_id, &s->s_channels, &c->ch_id, &c->ch_services, origin, 2); if (ilm) { service_mapped(s); return 1; @@ -185,24 +185,19 @@ service_mapper_link ( service_t *s, channel_t *c, void *origin ) return 0; } -int -service_mapper_create ( idnode_t *s, idnode_t *c, void *origin ) -{ - return service_mapper_link((service_t *)s, (channel_t *)c, origin); +int service_mapper_create(idnode_t* s, idnode_t* c, void* origin) { + return service_mapper_link((service_t*)s, (channel_t*)c, origin); } /* - * Process a service + * Process a service */ -channel_t * -service_mapper_process - ( const service_mapper_conf_t *conf, service_t *s, bouquet_t *bq ) -{ - channel_t *chn = NULL; - const char *name, *tagname; - char *tidy_name = NULL; - htsmsg_field_t *f; - htsmsg_t *m; +channel_t* service_mapper_process(const service_mapper_conf_t* conf, service_t* s, bouquet_t* bq) { + channel_t* chn = NULL; + const char * name, *tagname; + char* tidy_name = NULL; + htsmsg_field_t* f; + htsmsg_t* m; /* Ignore */ if (s->s_status == SERVICE_ZOMBIE) { @@ -229,23 +224,25 @@ service_mapper_process // 5 HD\0 len=4, HD at pos 2 (4-2) // 4HD\0 len=3, HD at pos 1 (3-2) // 4\0 len=1 - if (name[len-2] == 'H' && name[len-1] == 'D') { + if (name[len - 2] == 'H' && name[len - 1] == 'D') { /* Ends in HD but does it end in UHD/FHD? */ tidy_name = tvh_strdupa(name); - if (len > 3 && (name[len-3] == 'U' || name[len-3] == 'F')) - tidy_name[len-3] = 0; + if (len > 3 && (name[len - 3] == 'U' || name[len - 3] == 'F')) + tidy_name[len - 3] = 0; else - tidy_name[len-2] = 0; + tidy_name[len - 2] = 0; len = strlen(tidy_name); /* Strip any trailing space such as '5 HD' should become * '5' not '5 '. */ - if (len && isspace(tidy_name[len-1])) - tidy_name[len-1] = 0; + if (len && isspace(tidy_name[len - 1])) + tidy_name[len - 1] = 0; tvhdebug(bq ? LS_BOUQUET : LS_SERVICE_MAPPER, - "%s: generated tidy_name [%s] from [%s]", - s->s_nicename, tidy_name, name); + "%s: generated tidy_name [%s] from [%s]", + s->s_nicename, + tidy_name, + name); /* Assign tidy_name so we use it for rest of function */ name = tidy_name; @@ -270,13 +267,13 @@ service_mapper_process * but we'll safety-check here. */ if (!chn || (bq && chn->ch_bouquet != bq)) { - chn = channel_create(NULL, NULL, NULL); + chn = channel_create(NULL, NULL, NULL); chn->ch_bouquet = bq; } - + /* Map */ if (chn) { - const char *prov; + const char* prov; service_mapper_link(s, chn, chn); /* We have to set tidy name here (not in channel_create) because @@ -318,8 +315,8 @@ service_mapper_process /* Custom tags */ if (s->s_channel_tags && (m = s->s_channel_tags(s)) != NULL) HTSMSG_FOREACH(f, m) - if ((tagname = htsmsg_field_get_str(f)) != NULL) - channel_tag_map(channel_tag_find_by_name(tagname, 1), chn, chn); + if ((tagname = htsmsg_field_get_str(f)) != NULL) + channel_tag_map(channel_tag_find_by_name(tagname, 1), chn, chn); /* Provider */ if (conf->provider_tags) @@ -352,27 +349,25 @@ exit: /** * */ -static void * -service_mapper_thread ( void *aux ) -{ - service_t *s; - service_mapper_item_t *smi; - profile_chain_t prch; - th_subscription_t *sub; - int run, working = 0, r; - streaming_queue_t *sq; - streaming_message_t *sm; - const char *err = NULL; - uint64_t timeout, timeout_other; +static void* service_mapper_thread(void* aux) { + service_t* s; + service_mapper_item_t* smi; + profile_chain_t prch; + th_subscription_t* sub; + int run, working = 0, r; + streaming_queue_t* sq; + streaming_message_t* sm; + const char* err = NULL; + uint64_t timeout, timeout_other; profile_chain_init(&prch, NULL, NULL, 1); prch.prch_st = &prch.prch_sq.sq_st; - sq = &prch.prch_sq; + sq = &prch.prch_sq; tvh_mutex_lock(&global_lock); while (tvheadend_is_running()) { - + /* Wait for work */ while (!(smi = TAILQ_FIRST(&service_mapper_queue))) { if (working) { @@ -396,11 +391,15 @@ service_mapper_thread ( void *aux ) /* Subscribe */ tvhinfo(LS_SERVICE_MAPPER, "checking %s", s->s_nicename); prch.prch_id = s; - sub = subscription_create_from_service(&prch, NULL, - SUBSCRIPTION_PRIO_MAPPER, - "service_mapper", - SUBSCRIPTION_PACKET, - NULL, NULL, "service_mapper", NULL); + sub = subscription_create_from_service(&prch, + NULL, + SUBSCRIPTION_PRIO_MAPPER, + "service_mapper", + SUBSCRIPTION_PACKET, + NULL, + NULL, + "service_mapper", + NULL); /* Failed */ if (!sub) { @@ -415,10 +414,10 @@ service_mapper_thread ( void *aux ) tvh_mutex_unlock(&global_lock); /* Wait */ - run = 1; - timeout = mclk() + sec2mono(30); + run = 1; + timeout = mclk() + sec2mono(30); timeout_other = mclk() + sec2mono(5); - while(tvheadend_is_running() && run) { + while (tvheadend_is_running() && run) { if (timeout < mclk()) { run = 0; @@ -439,7 +438,7 @@ service_mapper_thread ( void *aux ) /* Wait for message */ tvh_mutex_lock(&sq->sq_mutex); - while((sm = TAILQ_FIRST(&sq->sq_queue)) == NULL) { + while ((sm = TAILQ_FIRST(&sq->sq_queue)) == NULL) { tvh_cond_wait(&sq->sq_cond, &sq->sq_mutex); if (!tvheadend_is_running()) break; @@ -451,26 +450,26 @@ service_mapper_thread ( void *aux ) break; switch (sm->sm_type) { - case SMT_GRACE: - timeout += sec2mono(sm->sm_code); - timeout_other = sec2mono(sm->sm_code); - break; - case SMT_PACKET: - run = 0; - err = NULL; - break; - case SMT_SERVICE_STATUS: - if(sm->sm_code & TSS_ERRORS) { + case SMT_GRACE: + timeout += sec2mono(sm->sm_code); + timeout_other = sec2mono(sm->sm_code); + break; + case SMT_PACKET: run = 0; - err = service_tss2text(sm->sm_code); - } - break; - case SMT_NOSTART: - run = 0; - err = streaming_code2txt(sm->sm_code); - break; - default: - break; + err = NULL; + break; + case SMT_SERVICE_STATUS: + if (sm->sm_code & TSS_ERRORS) { + run = 0; + err = service_tss2text(sm->sm_code); + } + break; + case SMT_NOSTART: + run = 0; + err = streaming_code2txt(sm->sm_code); + break; + default: + break; } streaming_msg_free(sm); @@ -481,11 +480,11 @@ service_mapper_thread ( void *aux ) tvh_mutex_lock(&sq->sq_mutex); streaming_queue_clear(&sq->sq_queue); tvh_mutex_unlock(&sq->sq_mutex); - + tvh_mutex_lock(&global_lock); subscription_unsubscribe(sub, UNSUBSCRIBE_FINAL); - if(err) { + if (err) { tvhinfo(LS_SERVICE_MAPPER, "%s: failed [reason: %s]", s->s_nicename, err); service_mapper_stat.fail++; } else @@ -501,9 +500,7 @@ service_mapper_thread ( void *aux ) return NULL; } -void -service_mapper_reset_stats (void) -{ +void service_mapper_reset_stats(void) { service_mapper_stat.total = 0; service_mapper_stat.ok = 0; service_mapper_stat.ignore = 0; @@ -514,10 +511,8 @@ service_mapper_reset_stats (void) /* * Save settings */ -static htsmsg_t * -service_mapper_conf_class_save ( idnode_t *self, char *filename, size_t fsize ) -{ - htsmsg_t *m; +static htsmsg_t* service_mapper_conf_class_save(idnode_t* self, char* filename, size_t fsize) { + htsmsg_t* m; m = htsmsg_create_map(); idnode_save(&service_mapper_conf.idnode, m); @@ -536,33 +531,25 @@ service_mapper_conf_class_save ( idnode_t *self, char *filename, size_t fsize ) * Class */ -static const void * -service_mapper_services_get ( void *obj ) -{ +static const void* service_mapper_services_get(void* obj) { return NULL; } -static char * -service_mapper_services_rend ( void *obj, const char *lang ) -{ +static char* service_mapper_services_rend(void* obj, const char* lang) { return strdup(""); } -static int -service_mapper_services_set ( void *obj, const void *p ) -{ - service_mapper_t *sm = obj; +static int service_mapper_services_set(void* obj, const void* p) { + service_mapper_t* sm = obj; htsmsg_destroy(sm->services); - sm->services = htsmsg_copy((htsmsg_t *)p); + sm->services = htsmsg_copy((htsmsg_t*)p); return 1; } -static htsmsg_t * -service_mapper_services_enum ( void *obj, const char *lang ) -{ +static htsmsg_t* service_mapper_services_enum(void* obj, const char* lang) { htsmsg_t *e, *m = htsmsg_create_map(); - htsmsg_add_str(m, "type", "api"); - htsmsg_add_str(m, "uri", "service/list"); + htsmsg_add_str(m, "type", "api"); + htsmsg_add_str(m, "uri", "service/list"); htsmsg_add_str(m, "event", "service"); e = htsmsg_create_map(); htsmsg_add_bool(e, "enum", 1); @@ -572,103 +559,89 @@ service_mapper_services_enum ( void *obj, const char *lang ) CLASS_DOC(service_mapper) -static const idclass_t service_mapper_conf_class = { - .ic_snode = &service_mapper_conf.idnode, - .ic_class = "service_mapper", - .ic_caption = N_("Service Mapping (Map services to channels)"), - .ic_doc = tvh_doc_service_mapper_class, - .ic_event = "service_mapper", - .ic_perm_def = ACCESS_ADMIN, - .ic_save = service_mapper_conf_class_save, - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .islist = 1, - .id = "services", - .name = N_("Services"), - .desc = N_("Select/Selected services to map."), - .get = service_mapper_services_get, - .set = service_mapper_services_set, - .list = service_mapper_services_enum, - .rend = service_mapper_services_rend - }, - { - .type = PT_BOOL, - .id = "check_availability", - .name = N_("Check availability"), - .desc = N_("Check services for availability. If enabled, " - "services that are not currently broadcasting (or " - "can't be decrypted) will be ignored. Leave disabled " - "if you want Tvheadend to also map offline services."), - .off = offsetof(service_mapper_t, d.check_availability), - .opts = PO_ADVANCED - }, - { - .type = PT_BOOL, - .id = "encrypted", - .name = N_("Map encrypted services"), - .desc = N_("Ignore encryption flag, include encrypted services " - "anyway."), - .off = offsetof(service_mapper_t, d.encrypted), - }, - { - .type = PT_BOOL, - .id = "merge_same_name", - .name = N_("Merge same name"), - .desc = N_("Merge services with the same name into one channel."), - .off = offsetof(service_mapper_t, d.merge_same_name), - }, - { - .type = PT_BOOL, - .id = "merge_same_name_fuzzy", - .name = N_("Use fuzzy mapping if merging same name"), - .desc = N_("If merge same name is enabled then " - "merge services with the same name into one channel but " - "using fuzzy logic such as ignoring whitespace, case and " - "some channel suffixes such as HD. So 'Channel 5+1', " - "'Channel 5 +1', 'Channel 5+1HD' and 'Channel 5 +1HD' would " - "all merge in to the same channel. The exact name chosen " - "depends on the order the channels are mapped."), - .off = offsetof(service_mapper_t, d.merge_same_name_fuzzy), - }, - { - .type = PT_BOOL, - .id = "tidy_channel_name", - .name = N_("Tidy the channel name such as removing trailing HD text"), - .desc = N_("Some broadcasters distinguish channels by appending " - "descriptors such as 'HD'. This option strips those " - "so 'Channel 4 HD' would be named 'Channel 4'. " - "Note that xmltv settings may try and match by channel name " - "so changing a channel name may require manual xmltv mapping."), - .off = offsetof(service_mapper_t, d.tidy_channel_name), - }, - { - .type = PT_BOOL, - .id = "type_tags", - .name = N_("Create type-based tags"), - .desc = N_("Create SDTV/HDTV/Radio tags."), - .off = offsetof(service_mapper_t, d.type_tags), - .opts = PO_ADVANCED - }, - { - .type = PT_BOOL, - .id = "provider_tags", - .name = N_("Create provider name tags"), - .desc = N_("Create a provider name tag."), - .off = offsetof(service_mapper_t, d.provider_tags), - .opts = PO_ADVANCED - }, - { - .type = PT_BOOL, - .id = "network_tags", - .name = N_("Create network name tags"), - .desc = N_("Create network name tags (set by provider)."), - .off = offsetof(service_mapper_t, d.network_tags), - .opts = PO_ADVANCED - }, - {} - } -}; +static const idclass_t service_mapper_conf_class = {.ic_snode = &service_mapper_conf.idnode, + .ic_class = "service_mapper", + .ic_caption = N_("Service Mapping (Map services to channels)"), + .ic_doc = tvh_doc_service_mapper_class, + .ic_event = "service_mapper", + .ic_perm_def = ACCESS_ADMIN, + .ic_save = service_mapper_conf_class_save, + .ic_properties = (const property_t[]){{.type = PT_STR, + .islist = 1, + .id = "services", + .name = N_("Services"), + .desc = N_("Select/Selected services to map."), + .get = service_mapper_services_get, + .set = service_mapper_services_set, + .list = service_mapper_services_enum, + .rend = service_mapper_services_rend}, + {.type = PT_BOOL, + .id = "check_availability", + .name = N_("Check availability"), + .desc = N_("Check services for availability. If enabled, " + "services that are not currently broadcasting (or " + "can't be decrypted) will be ignored. Leave disabled " + "if you want Tvheadend to also map offline services."), + .off = offsetof(service_mapper_t, d.check_availability), + .opts = PO_ADVANCED}, + { + .type = PT_BOOL, + .id = "encrypted", + .name = N_("Map encrypted services"), + .desc = N_("Ignore encryption flag, include encrypted services " + "anyway."), + .off = offsetof(service_mapper_t, d.encrypted), + }, + { + .type = PT_BOOL, + .id = "merge_same_name", + .name = N_("Merge same name"), + .desc = N_("Merge services with the same name into one channel."), + .off = offsetof(service_mapper_t, d.merge_same_name), + }, + { + .type = PT_BOOL, + .id = "merge_same_name_fuzzy", + .name = N_("Use fuzzy mapping if merging same name"), + .desc = N_("If merge same name is enabled then " + "merge services with the same name into one channel but " + "using fuzzy logic such as ignoring whitespace, case and " + "some channel suffixes such as HD. So 'Channel 5+1', " + "'Channel 5 +1', 'Channel 5+1HD' and 'Channel 5 +1HD' would " + "all merge in to the same channel. The exact name chosen " + "depends on the order the channels are mapped."), + .off = offsetof(service_mapper_t, d.merge_same_name_fuzzy), + }, + { + .type = PT_BOOL, + .id = "tidy_channel_name", + .name = N_("Tidy the channel name such as removing trailing HD text"), + .desc = N_("Some broadcasters distinguish channels by appending " + "descriptors such as 'HD'. This option strips those " + "so 'Channel 4 HD' would be named 'Channel 4'. " + "Note that xmltv settings may try and match by channel name " + "so changing a channel name may require manual xmltv mapping."), + .off = offsetof(service_mapper_t, d.tidy_channel_name), + }, + {.type = PT_BOOL, + .id = "type_tags", + .name = N_("Create type-based tags"), + .desc = N_("Create SDTV/HDTV/Radio tags."), + .off = offsetof(service_mapper_t, d.type_tags), + .opts = PO_ADVANCED}, + {.type = PT_BOOL, + .id = "provider_tags", + .name = N_("Create provider name tags"), + .desc = N_("Create a provider name tag."), + .off = offsetof(service_mapper_t, d.provider_tags), + .opts = PO_ADVANCED}, + {.type = PT_BOOL, + .id = "network_tags", + .name = N_("Create network name tags"), + .desc = N_("Create network name tags (set by provider)."), + .off = offsetof(service_mapper_t, d.network_tags), + .opts = PO_ADVANCED}, + {}}}; /* * @@ -676,9 +649,8 @@ static const idclass_t service_mapper_conf_class = { pthread_t service_mapper_tid; -void service_mapper_init ( void ) -{ - htsmsg_t *m; +void service_mapper_init(void) { + htsmsg_t* m; TAILQ_INIT(&service_mapper_queue); idclass_register(&service_mapper_conf_class); @@ -688,8 +660,8 @@ void service_mapper_init ( void ) /* Defaults */ memset(&service_mapper_conf, 0, sizeof(service_mapper_conf)); service_mapper_conf.idnode.in_class = &service_mapper_conf_class; - service_mapper_conf.d.type_tags = 1; - service_mapper_conf.d.encrypted = 1; + service_mapper_conf.d.type_tags = 1; + service_mapper_conf.d.encrypted = 1; /* Load settings */ if ((m = hts_settings_load("service_mapper/config"))) { @@ -698,9 +670,7 @@ void service_mapper_init ( void ) } } - -void service_mapper_done ( void ) -{ +void service_mapper_done(void) { tvh_cond_signal(&service_mapper_cond, 0); pthread_join(service_mapper_tid, NULL); htsmsg_destroy(service_mapper_conf.services); diff --git a/src/service_mapper.h b/src/service_mapper.h index 64166253b..0b4c01a4a 100644 --- a/src/service_mapper.h +++ b/src/service_mapper.h @@ -21,61 +21,60 @@ struct bouquet; -typedef struct service_mapper_conf -{ - int check_availability; ///< Check service is receivable - int encrypted; ///< Include encrypted services - int merge_same_name; ///< Merge entries with the same name - int merge_same_name_fuzzy; ///< Merge entries with the same name with fuzzy matching (ignore case, etc) - int tidy_channel_name; ///< Tidy channel name by removing trailing HD/UHD. - int type_tags; ///< Create tags based on the service type (SDTV/HDTV/Radio) - int provider_tags; ///< Create tags based on provider name - int network_tags; ///< Create tags based on network name (useful for multi adapter equipments) +typedef struct service_mapper_conf { + int check_availability; ///< Check service is receivable + int encrypted; ///< Include encrypted services + int merge_same_name; ///< Merge entries with the same name + int merge_same_name_fuzzy; ///< Merge entries with the same name with fuzzy matching (ignore case, + ///< etc) + int tidy_channel_name; ///< Tidy channel name by removing trailing HD/UHD. + int type_tags; ///< Create tags based on the service type (SDTV/HDTV/Radio) + int provider_tags; ///< Create tags based on provider name + int network_tags; ///< Create tags based on network name (useful for multi adapter equipments) } service_mapper_conf_t; typedef struct service_mapper { - idnode_t idnode; + idnode_t idnode; service_mapper_conf_t d; - htsmsg_t *services; + htsmsg_t* services; } service_mapper_t; -typedef struct service_mapper_status -{ - int total; - int ok; - int fail; - int ignore; - service_t *active; +typedef struct service_mapper_status { + int total; + int ok; + int fail; + int ignore; + service_t* active; } service_mapper_status_t; extern service_mapper_t service_mapper_conf; -void service_mapper_init ( void ); -void service_mapper_done ( void ); +void service_mapper_init(void); +void service_mapper_done(void); // Start service mapper -void service_mapper_start ( const service_mapper_conf_t *conf, htsmsg_t *uuids ); +void service_mapper_start(const service_mapper_conf_t* conf, htsmsg_t* uuids); // Stop pending services (remove from Q) -void service_mapper_stop ( void ); +void service_mapper_stop(void); // Remove service (deleted?) from Q -void service_mapper_remove ( struct service *t ); +void service_mapper_remove(struct service* t); // Get current Q size -service_mapper_status_t service_mapper_status ( void ); +service_mapper_status_t service_mapper_status(void); // Link service to channel -int service_mapper_link ( struct service *s, struct channel *c, void *origin ); +int service_mapper_link(struct service* s, struct channel* c, void* origin); // Create new link -int service_mapper_create ( idnode_t *s, idnode_t *c, void *origin ); +int service_mapper_create(idnode_t* s, idnode_t* c, void* origin); // Process one service -struct channel *service_mapper_process - ( const service_mapper_conf_t *conf, struct service *s, struct bouquet *bq ); +struct channel* +service_mapper_process(const service_mapper_conf_t* conf, struct service* s, struct bouquet* bq); // Resets the stat counters -void service_mapper_reset_stats ( void ); +void service_mapper_reset_stats(void); #endif /* __TVH_SERVICE_MAPPER_H__ */ diff --git a/src/settings.c b/src/settings.c index da98a249a..62360fa1e 100644 --- a/src/settings.c +++ b/src/settings.c @@ -37,23 +37,19 @@ #include "../vendor/xdg-user-dirs/xdg-user-dir-lookup.c" -static char *settingspath = NULL; +static char* settingspath = NULL; /** * */ -const char * -hts_settings_get_root(void) -{ +const char* hts_settings_get_root(void) { return settingspath; } /** * */ -void -hts_settings_init(const char *confpath) -{ +void hts_settings_init(const char* confpath) { if (confpath) settingspath = realpath(confpath, NULL); } @@ -61,22 +57,19 @@ hts_settings_init(const char *confpath) /** * */ -void -hts_settings_done(void) -{ +void hts_settings_done(void) { free(settingspath); } /** * */ -int -hts_settings_makedirs ( const char *inpath ) -{ - size_t x = strlen(inpath) - 1; - char *path = alloca(x + 2); +int hts_settings_makedirs(const char* inpath) { + size_t x = strlen(inpath) - 1; + char* path = alloca(x + 2); - if (path == NULL) return -1; + if (path == NULL) + return -1; strcpy(path, inpath); while (x) { @@ -92,12 +85,13 @@ hts_settings_makedirs ( const char *inpath ) /** * */ -static void -_hts_settings_buildpath - (char *dst, size_t dstsize, const char *fmt, va_list ap, const char *prefix) -{ - char tmp[PATH_MAX]; - char *n = dst; +static void _hts_settings_buildpath(char* dst, + size_t dstsize, + const char* fmt, + va_list ap, + const char* prefix) { + char tmp[PATH_MAX]; + char* n = dst; vsnprintf(tmp, sizeof(tmp), fmt, ap); if (*tmp != '/' && prefix) @@ -105,17 +99,14 @@ _hts_settings_buildpath else strlcpy(dst, tmp, dstsize); - while(*n) { - if(*n == ':' || *n == '?' || *n == '*' || *n > 127 || *n < 32) + while (*n) { + if (*n == ':' || *n == '?' || *n == '*' || *n > 127 || *n < 32) *n = '_'; n++; } } -int -hts_settings_buildpath - (char *dst, size_t dstsize, const char *fmt, ...) -{ +int hts_settings_buildpath(char* dst, size_t dstsize, const char* fmt, ...) { va_list va; if (!settingspath) return 1; @@ -128,18 +119,16 @@ hts_settings_buildpath /** * */ -void -hts_settings_save(htsmsg_t *record, const char *pathfmt, ...) -{ - char path[PATH_MAX]; - char tmppath[PATH_MAX + 4]; - int fd; - va_list ap; +void hts_settings_save(htsmsg_t* record, const char* pathfmt, ...) { + char path[PATH_MAX]; + char tmppath[PATH_MAX + 4]; + int fd; + va_list ap; htsbuf_queue_t hq; - htsbuf_data_t *hd; - int ok, r, pack; + htsbuf_data_t* hd; + int ok, r, pack; - if(settingspath == NULL) + if (settingspath == NULL) return; /* Clean the path */ @@ -148,23 +137,22 @@ hts_settings_save(htsmsg_t *record, const char *pathfmt, ...) va_end(ap); /* Create directories */ - if (hts_settings_makedirs(path)) return; + if (hts_settings_makedirs(path)) + return; tvhdebug(LS_SETTINGS, "saving to %s", path); /* Create tmp file */ snprintf(tmppath, sizeof(tmppath), "%s.tmp", path); - if((fd = tvh_open(tmppath, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR)) < 0) { - tvhalert(LS_SETTINGS, "Unable to create \"%s\" - %s", - tmppath, strerror(errno)); + if ((fd = tvh_open(tmppath, O_CREAT | O_TRUNC | O_RDWR, S_IRUSR | S_IWUSR)) < 0) { + tvhalert(LS_SETTINGS, "Unable to create \"%s\" - %s", tmppath, strerror(errno)); return; } /* Store data */ #if ENABLE_ZLIB pack = strstr(path, "/muxes/") != NULL && /* ugly, redesign API */ - strstr(path, "/networks/") != NULL && - strstr(path, "/input/") != NULL; + strstr(path, "/networks/") != NULL && strstr(path, "/input/") != NULL; #else pack = 0; #endif @@ -173,19 +161,18 @@ hts_settings_save(htsmsg_t *record, const char *pathfmt, ...) if (!pack) { htsbuf_queue_init(&hq, 0); htsmsg_json_serialize(record, &hq, 1); - TAILQ_FOREACH(hd, &hq.hq_q, hd_link) - if(tvh_write(fd, hd->hd_data + hd->hd_data_off, hd->hd_data_len)) { - tvhalert(LS_SETTINGS, "Failed to write file \"%s\" - %s", - tmppath, strerror(errno)); + TAILQ_FOREACH (hd, &hq.hq_q, hd_link) + if (tvh_write(fd, hd->hd_data + hd->hd_data_off, hd->hd_data_len)) { + tvhalert(LS_SETTINGS, "Failed to write file \"%s\" - %s", tmppath, strerror(errno)); ok = 0; break; } htsbuf_queue_flush(&hq); } else { #if ENABLE_ZLIB - void *msgdata = NULL; + void* msgdata = NULL; size_t msglen; - r = htsmsg_binary2_serialize0(record, &msgdata, &msglen, 2*1024*1024); + r = htsmsg_binary2_serialize0(record, &msgdata, &msglen, 2 * 1024 * 1024); if (!r && msglen >= 4) { r = tvh_gzip_deflate_fd_header(fd, msgdata, msglen, NULL, 3, "01"); if (r) @@ -199,17 +186,20 @@ hts_settings_save(htsmsg_t *record, const char *pathfmt, ...) close(fd); /* Move */ - if(ok) { + if (ok) { r = rename(tmppath, path); if (r && errno == EISDIR) { rmtree(path); r = rename(tmppath, path); } if (r) - tvhalert(LS_SETTINGS, "Unable to rename file \"%s\" to \"%s\" - %s", - tmppath, path, strerror(errno)); - - /* Delete tmp */ + tvhalert(LS_SETTINGS, + "Unable to rename file \"%s\" to \"%s\" - %s", + tmppath, + path, + strerror(errno)); + + /* Delete tmp */ } else unlink(tmppath); } @@ -217,34 +207,33 @@ hts_settings_save(htsmsg_t *record, const char *pathfmt, ...) /** * */ -static htsmsg_t * -hts_settings_load_one(const char *filename) -{ - ssize_t n, size; - char *mem; - fb_file *fp; - htsmsg_t *r = NULL; +static htsmsg_t* hts_settings_load_one(const char* filename) { + ssize_t n, size; + char* mem; + fb_file* fp; + htsmsg_t* r = NULL; /* Open */ - if (!(fp = fb_open(filename, 1, 0))) return NULL; + if (!(fp = fb_open(filename, 1, 0))) + return NULL; size = fb_size(fp); /* Load data */ - mem = malloc(size+1); - n = fb_read(fp, mem, size); - if (n >= 0) mem[n] = 0; + mem = malloc(size + 1); + n = fb_read(fp, mem, size); + if (n >= 0) + mem[n] = 0; /* Decode */ - if(n == size) { - if (size > 12 && memcmp(mem, "\xff\xffGZIP0", 7) == 0 && - (mem[7] == '0' || mem[7] == '1')) { + if (n == size) { + if (size > 12 && memcmp(mem, "\xff\xffGZIP0", 7) == 0 && (mem[7] == '0' || mem[7] == '1')) { #if ENABLE_ZLIB uint32_t orig = (mem[8] << 24) | (mem[9] << 16) | (mem[10] << 8) | mem[11]; - if (orig > 10*1024*1024U) { + if (orig > 10 * 1024 * 1024U) { tvhalert(LS_SETTINGS, "too big gzip for %s", filename); r = NULL; } else if (orig > 0) { - uint8_t *unpacked = tvh_gzip_inflate((uint8_t *)mem + 12, size - 12, orig); + uint8_t* unpacked = tvh_gzip_inflate((uint8_t*)mem + 12, size - 12, orig); if (unpacked) { if (mem[7] == '1') { r = htsmsg_binary2_deserialize0(unpacked, orig, NULL); @@ -270,48 +259,46 @@ hts_settings_load_one(const char *filename) /** * */ -static htsmsg_t * -hts_settings_load_path(const char *fullpath, int depth) -{ - char child[PATH_MAX]; - const char *name; +static htsmsg_t* hts_settings_load_path(const char* fullpath, int depth) { + char child[PATH_MAX]; + const char* name; struct filebundle_stat st; - fb_dirent **namelist, *d; - htsmsg_t *r, *c; - int n, i; + fb_dirent ** namelist, *d; + htsmsg_t * r, *c; + int n, i; /* Invalid */ - if (fb_stat(fullpath, &st)) return NULL; + if (fb_stat(fullpath, &st)) + return NULL; /* Directory */ if (st.is_dir) { /* Get file list */ - if((n = fb_scandir(fullpath, &namelist)) < 0) + if ((n = fb_scandir(fullpath, &namelist)) < 0) return NULL; /* Read files */ r = htsmsg_create_map(); - for(i = 0; i < n; i++) { - d = namelist[i]; + for (i = 0; i < n; i++) { + d = namelist[i]; name = d->name; - if(name[0] != '.' && name[0] && name[strlen(name)-1] != '~') { + if (name[0] != '.' && name[0] && name[strlen(name) - 1] != '~') { snprintf(child, sizeof(child), "%s/%s", fullpath, d->name); - if(d->type == FB_DIR && depth > 0) { + if (d->type == FB_DIR && depth > 0) { c = hts_settings_load_path(child, depth - 1); } else { c = hts_settings_load_one(child); } - if(c != NULL) + if (c != NULL) htsmsg_add_msg(r, d->name, c); - } free(d); } free(namelist); - /* File */ + /* File */ } else { r = hts_settings_load_one(fullpath); } @@ -322,23 +309,19 @@ hts_settings_load_path(const char *fullpath, int depth) /** * */ -static htsmsg_t * -hts_settings_vload(const char *pathfmt, va_list ap, int depth) -{ - htsmsg_t *ret = NULL; - char fullpath[PATH_MAX]; - va_list ap2; +static htsmsg_t* hts_settings_vload(const char* pathfmt, va_list ap, int depth) { + htsmsg_t* ret = NULL; + char fullpath[PATH_MAX]; + va_list ap2; va_copy(ap2, ap); /* Try normal path */ - _hts_settings_buildpath(fullpath, sizeof(fullpath), - pathfmt, ap, settingspath); + _hts_settings_buildpath(fullpath, sizeof(fullpath), pathfmt, ap, settingspath); ret = hts_settings_load_path(fullpath, depth); /* Try bundle path */ if (!ret && *pathfmt != '/') { - _hts_settings_buildpath(fullpath, sizeof(fullpath), - pathfmt, ap2, "data/conf"); + _hts_settings_buildpath(fullpath, sizeof(fullpath), pathfmt, ap2, "data/conf"); ret = hts_settings_load_path(fullpath, depth); } @@ -347,30 +330,24 @@ hts_settings_vload(const char *pathfmt, va_list ap, int depth) return ret; } - /** * */ -htsmsg_t * -hts_settings_load(const char *pathfmt, ...) -{ +htsmsg_t* hts_settings_load(const char* pathfmt, ...) { va_list ap; va_start(ap, pathfmt); - htsmsg_t *r = hts_settings_vload(pathfmt, ap, 0); + htsmsg_t* r = hts_settings_vload(pathfmt, ap, 0); va_end(ap); return r; } - /** * */ -htsmsg_t * -hts_settings_load_r(int depth, const char *pathfmt, ...) -{ +htsmsg_t* hts_settings_load_r(int depth, const char* pathfmt, ...) { va_list ap; va_start(ap, pathfmt); - htsmsg_t *r = hts_settings_vload(pathfmt, ap, depth); + htsmsg_t* r = hts_settings_vload(pathfmt, ap, depth); va_end(ap); return r; } @@ -378,23 +355,21 @@ hts_settings_load_r(int depth, const char *pathfmt, ...) /** * */ -void -hts_settings_remove(const char *pathfmt, ...) -{ - char fullpath[PATH_MAX]; - va_list ap; +void hts_settings_remove(const char* pathfmt, ...) { + char fullpath[PATH_MAX]; + va_list ap; struct stat st; va_start(ap, pathfmt); - _hts_settings_buildpath(fullpath, sizeof(fullpath), - pathfmt, ap, settingspath); + _hts_settings_buildpath(fullpath, sizeof(fullpath), pathfmt, ap, settingspath); va_end(ap); if (stat(fullpath, &st) == 0) { if (S_ISDIR(st.st_mode)) rmtree(fullpath); else { unlink(fullpath); - while (rmdir(dirname(fullpath)) == 0); + while (rmdir(dirname(fullpath)) == 0) + ; } } } @@ -402,11 +377,9 @@ hts_settings_remove(const char *pathfmt, ...) /** * */ -int -hts_settings_open_file(int flags, const char *pathfmt, ...) -{ - char path[PATH_MAX]; - int _flags; +int hts_settings_open_file(int flags, const char* pathfmt, ...) { + char path[PATH_MAX]; + int _flags; va_list ap; /* Build path */ @@ -416,7 +389,8 @@ hts_settings_open_file(int flags, const char *pathfmt, ...) /* Create directories */ if (flags & HTS_SETTINGS_OPEN_WRITE) - if (hts_settings_makedirs(path)) return -1; + if (hts_settings_makedirs(path)) + return -1; /* Open file */ _flags = (flags & HTS_SETTINGS_OPEN_WRITE) ? O_CREAT | O_TRUNC | O_WRONLY : O_RDONLY; @@ -430,11 +404,9 @@ hts_settings_open_file(int flags, const char *pathfmt, ...) /* * Check if a path exists */ -int -hts_settings_exists ( const char *pathfmt, ... ) -{ - va_list ap; - char path[PATH_MAX]; +int hts_settings_exists(const char* pathfmt, ...) { + va_list ap; + char path[PATH_MAX]; struct stat st; /* Build path */ @@ -448,14 +420,10 @@ hts_settings_exists ( const char *pathfmt, ... ) /* * XDG user directory support */ -char * -hts_settings_get_xdg_dir_lookup (const char *name) -{ - return xdg_user_dir_lookup (name); +char* hts_settings_get_xdg_dir_lookup(const char* name) { + return xdg_user_dir_lookup(name); } -char * -hts_settings_get_xdg_dir_with_fallback (const char *name, const char *fallback) -{ - return xdg_user_dir_lookup_with_fallback (name, fallback); +char* hts_settings_get_xdg_dir_with_fallback(const char* name, const char* fallback) { + return xdg_user_dir_lookup_with_fallback(name, fallback); } diff --git a/src/settings.h b/src/settings.h index bf8524628..77aeadad7 100644 --- a/src/settings.h +++ b/src/settings.h @@ -23,32 +23,32 @@ #include "htsmsg.h" -#define HTS_SETTINGS_OPEN_WRITE (1<<0) -#define HTS_SETTINGS_OPEN_DIRECT (1<<1) +#define HTS_SETTINGS_OPEN_WRITE (1 << 0) +#define HTS_SETTINGS_OPEN_DIRECT (1 << 1) -void hts_settings_init(const char *confpath); +void hts_settings_init(const char* confpath); void hts_settings_done(void); -void hts_settings_save(htsmsg_t *record, const char *pathfmt, ...); +void hts_settings_save(htsmsg_t* record, const char* pathfmt, ...); -htsmsg_t *hts_settings_load(const char *pathfmt, ...); +htsmsg_t* hts_settings_load(const char* pathfmt, ...); -htsmsg_t *hts_settings_load_r(int depth, const char *pathfmt, ...); +htsmsg_t* hts_settings_load_r(int depth, const char* pathfmt, ...); -void hts_settings_remove(const char *pathfmt, ...); +void hts_settings_remove(const char* pathfmt, ...); -const char *hts_settings_get_root(void); +const char* hts_settings_get_root(void); -int hts_settings_open_file(int flags, const char *pathfmt, ...); +int hts_settings_open_file(int flags, const char* pathfmt, ...); -int hts_settings_buildpath(char *dst, size_t dstsize, const char *pathfmt, ...); +int hts_settings_buildpath(char* dst, size_t dstsize, const char* pathfmt, ...); -int hts_settings_makedirs ( const char *path ); +int hts_settings_makedirs(const char* path); -int hts_settings_exists ( const char *pathfmt, ... ); +int hts_settings_exists(const char* pathfmt, ...); -char *hts_settings_get_xdg_dir_lookup (const char *name); -char *hts_settings_get_xdg_dir_with_fallback (const char *name, const char *fallback); +char* hts_settings_get_xdg_dir_lookup(const char* name); +char* hts_settings_get_xdg_dir_with_fallback(const char* name, const char* fallback); #endif /* HTSSETTINGS_H__ */ diff --git a/src/spawn.c b/src/spawn.c index 89b65402c..e595e6348 100644 --- a/src/spawn.c +++ b/src/spawn.c @@ -39,14 +39,14 @@ #define WIFCONTINUED(s) ((s) == 0xffff) #endif -extern char **environ; +extern char** environ; tvh_mutex_t spawn_mutex = TVH_THREAD_MUTEX_INITIALIZER; static LIST_HEAD(, spawn) spawns; -static char *spawn_info_buf = NULL; -static char *spawn_error_buf = NULL; +static char* spawn_info_buf = NULL; +static char* spawn_error_buf = NULL; static th_pipe_t spawn_pipe_info; static th_pipe_t spawn_pipe_error; @@ -57,9 +57,9 @@ static int spawn_pipe_running; typedef struct spawn { LIST_ENTRY(spawn) link; - pid_t pid; - const char *name; - int64_t killed; + pid_t pid; + const char* name; + int64_t killed; } spawn_t; static void spawn_reaper(void); @@ -69,22 +69,20 @@ static void spawn_reaper(void); */ #define SPAWN_PIPE_READ_SIZE 4096 -static void -spawn_pipe_read( th_pipe_t *p, char **_buf, int level ) -{ - char *buf = *_buf, *s; +static void spawn_pipe_read(th_pipe_t* p, char** _buf, int level) { + char * buf = *_buf, *s; size_t len; - int r; + int r; if (buf == NULL) { - buf = malloc(SPAWN_PIPE_READ_SIZE); - buf[0] = '\0'; + buf = malloc(SPAWN_PIPE_READ_SIZE); + buf[0] = '\0'; buf[SPAWN_PIPE_READ_SIZE - 1] = 0; - *_buf = buf; + *_buf = buf; } while (1) { len = strlen(buf); - r = read(p->rd, buf + len, SPAWN_PIPE_READ_SIZE - 1 - len); + r = read(p->rd, buf + len, SPAWN_PIPE_READ_SIZE - 1 - len); if (r < 1) { if (errno == EAGAIN) break; @@ -112,15 +110,13 @@ spawn_pipe_read( th_pipe_t *p, char **_buf, int level ) } } -static void * -spawn_pipe_thread(void *aux) -{ +static void* spawn_pipe_thread(void* aux) { tvhpoll_event_t ev[2]; - tvhpoll_t *efd = tvhpoll_create(2); - int nfds; + tvhpoll_t* efd = tvhpoll_create(2); + int nfds; - tvhpoll_event(ev+0, spawn_pipe_info.rd, TVHPOLL_IN, &spawn_pipe_info); - tvhpoll_event(ev+1, spawn_pipe_error.rd, TVHPOLL_IN, &spawn_pipe_error); + tvhpoll_event(ev + 0, spawn_pipe_info.rd, TVHPOLL_IN, &spawn_pipe_info); + tvhpoll_event(ev + 1, spawn_pipe_error.rd, TVHPOLL_IN, &spawn_pipe_error); tvhpoll_add(efd, ev, 2); while (atomic_get(&spawn_pipe_running)) { @@ -132,18 +128,15 @@ spawn_pipe_thread(void *aux) spawn_pipe_read(&spawn_pipe_error, &spawn_error_buf, LOG_ERR); } spawn_reaper(); - } tvhpoll_destroy(efd); return NULL; } -static void -spawn_pipe_write( th_pipe_t *p, const char *fmt, va_list ap ) -{ +static void spawn_pipe_write(th_pipe_t* p, const char* fmt, va_list ap) { char buf[512], *s = buf; - int r; + int r; vsnprintf(buf, sizeof(buf), fmt, ap); while (*s) { @@ -161,9 +154,7 @@ spawn_pipe_write( th_pipe_t *p, const char *fmt, va_list ap ) } } -void -spawn_info( const char *fmt, ... ) -{ +void spawn_info(const char* fmt, ...) { va_list ap; va_start(ap, fmt); @@ -171,9 +162,7 @@ spawn_info( const char *fmt, ... ) va_end(ap); } -void -spawn_error( const char *fmt, ... ) -{ +void spawn_error(const char* fmt, ...) { va_list ap; va_start(ap, fmt); @@ -184,34 +173,39 @@ spawn_error( const char *fmt, ... ) /* * Search PATH for executable */ -int -find_exec ( const char *name, char *out, size_t len ) -{ - int ret = 0; - char bin[512]; - char *path, *tmp, *tmp2 = NULL; - DIR *dir; - struct dirent *de; - struct stat st; +int find_exec(const char* name, char* out, size_t len) { + int ret = 0; + char bin[512]; + char * path, *tmp, *tmp2 = NULL; + DIR* dir; + struct dirent* de; + struct stat st; if (name[0] == '/') { - if (lstat(name, &st)) return 0; - if (!S_ISREG(st.st_mode) || !(st.st_mode & S_IEXEC)) return 0; + if (lstat(name, &st)) + return 0; + if (!S_ISREG(st.st_mode) || !(st.st_mode & S_IEXEC)) + return 0; strlcpy(out, name, len); return 1; } - if (!(path = getenv("PATH"))) return 0; + if (!(path = getenv("PATH"))) + return 0; path = strdup(path); tmp = strtok_r(path, ":", &tmp2); while (tmp && !ret) { if ((dir = opendir(tmp))) { while ((de = readdir(dir))) { - if (strstr(de->d_name, name) != de->d_name) continue; + if (strstr(de->d_name, name) != de->d_name) + continue; snprintf(bin, sizeof(bin), "%s/%s", tmp, de->d_name); - if (lstat(bin, &st)) continue; - if (!S_ISREG(st.st_mode) || !(st.st_mode & S_IEXEC)) continue; + if (lstat(bin, &st)) + continue; + if (!S_ISREG(st.st_mode) || !(st.st_mode & S_IEXEC)) + continue; strlcpy(out, bin, len); ret = 1; - if(strcmp(de->d_name, name) == 0) break; // Exact match, it won't get any better + if (strcmp(de->d_name, name) == 0) + break; // Exact match, it won't get any better } closedir(dir); } @@ -224,27 +218,25 @@ find_exec ( const char *name, char *out, size_t len ) /** * Reap one child */ -int -spawn_reap(pid_t wpid, char *stxt, size_t stxtlen) -{ - pid_t pid; - int status, res; - spawn_t *s; +int spawn_reap(pid_t wpid, char* stxt, size_t stxtlen) { + pid_t pid; + int status, res; + spawn_t* s; pid = waitpid(wpid, &status, WNOHANG); - if(pid < 0 && ERRNO_AGAIN(errno)) + if (pid < 0 && ERRNO_AGAIN(errno)) return -EAGAIN; - if(pid < 0) + if (pid < 0) return -errno; - if(pid < 1) { + if (pid < 1) { if (wpid > 0 && pid != wpid) return -EAGAIN; return 0; } tvh_mutex_lock(&spawn_mutex); - LIST_FOREACH(s, &spawns, link) - if(s->pid == pid) + LIST_FOREACH (s, &spawns, link) + if (s->pid == pid) break; res = -EIO; @@ -254,10 +246,12 @@ spawn_reap(pid_t wpid, char *stxt, size_t stxtlen) snprintf(stxt, stxtlen, "exited, status=%d", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { if (stxt) - snprintf(stxt, stxtlen, "killed by signal %d, " - "stopped by signal %d", - WTERMSIG(status), - WSTOPSIG(status)); + snprintf(stxt, + stxtlen, + "killed by signal %d, " + "stopped by signal %d", + WTERMSIG(status), + WSTOPSIG(status)); } else if (WIFCONTINUED(status)) { if (stxt) snprintf(stxt, stxtlen, "continued"); @@ -266,9 +260,9 @@ spawn_reap(pid_t wpid, char *stxt, size_t stxtlen) snprintf(stxt, stxtlen, "unknown status"); } - if(s != NULL) { + if (s != NULL) { LIST_REMOVE(s, link); - free((void *)s->name); + free((void*)s->name); free(s); } tvh_mutex_unlock(&spawn_mutex); @@ -278,11 +272,9 @@ spawn_reap(pid_t wpid, char *stxt, size_t stxtlen) /** * The reaper is called once a second to finish of any pending spawns */ -static void -spawn_reaper(void) -{ - int r; - spawn_t *s; +static void spawn_reaper(void) { + int r; + spawn_t* s; do { r = spawn_reap(-1, NULL, 0); @@ -294,7 +286,7 @@ spawn_reaper(void) /* forced kill for expired PIDs */ tvh_mutex_lock(&spawn_mutex); - LIST_FOREACH(s, &spawns, link) + LIST_FOREACH (s, &spawns, link) if (s->killed && s->killed < mclk()) { /* kill the whole process group */ r = kill(-(s->pid), SIGKILL); @@ -307,18 +299,16 @@ spawn_reaper(void) /** * Kill the pid (only if waiting) */ -int -spawn_kill(pid_t pid, int sig, int timeout) -{ - int r = -ESRCH; - spawn_t *s; +int spawn_kill(pid_t pid, int sig, int timeout) { + int r = -ESRCH; + spawn_t* s; if (pid > 0) { spawn_reaper(); tvh_mutex_lock(&spawn_mutex); - LIST_FOREACH(s, &spawns, link) - if(s->pid == pid) + LIST_FOREACH (s, &spawns, link) + if (s->pid == pid) break; if (s) { if (!s->killed) @@ -339,39 +329,34 @@ spawn_kill(pid_t pid, int sig, int timeout) /** * Enqueue a spawn on the pending spawn list */ -static spawn_t * -spawn_enq(const char *name, int pid) -{ - spawn_t *s = calloc(1, sizeof(spawn_t)); - s->name = strdup(name); - s->pid = pid; +static spawn_t* spawn_enq(const char* name, int pid) { + spawn_t* s = calloc(1, sizeof(spawn_t)); + s->name = strdup(name); + s->pid = pid; tvh_mutex_lock(&spawn_mutex); LIST_INSERT_HEAD(&spawns, s, link); tvh_mutex_unlock(&spawn_mutex); return s; } - /** * */ -int -spawn_parse_args(char ***argv, int argc, const char *cmd, const char **replace) -{ - char *s, *f, *p, *a; - const char **r; - int i = 0, l, eow; +int spawn_parse_args(char*** argv, int argc, const char* cmd, const char** replace) { + char * s, *f, *p, *a; + const char** r; + int i = 0, l, eow; if (!argv || !cmd) return -1; - s = tvh_strdupa(cmd); - *argv = calloc(argc, sizeof(char *)); + s = tvh_strdupa(cmd); + *argv = calloc(argc, sizeof(char*)); while (*s && i < argc - 1) { while (*s == ' ') s++; - f = s; + f = s; eow = 0; while (*s) { if (*s == '\\') { @@ -414,14 +399,14 @@ spawn_parse_args(char ***argv, int argc, const char *cmd, const char **replace) } if (f != s) { if (*s) { - *(char *)s = '\0'; + *(char*)s = '\0'; s++; } for (r = replace; r && *r; r += 2) { p = strstr(f, *r); if (p) { - l = strlen(*r); - a = malloc(strlen(f) + strlen(r[1]) + 1); + l = strlen(*r); + a = malloc(strlen(f) + strlen(r[1]) + 1); *p = '\0'; strcpy(a, f); strcat(a, r[1]); @@ -442,10 +427,8 @@ spawn_parse_args(char ***argv, int argc, const char *cmd, const char **replace) /** * */ -void -spawn_free_args(char **argv) -{ - char **a = argv; +void spawn_free_args(char** argv) { + char** a = argv; for (; *a; a++) free(*a); free(argv); @@ -454,41 +437,48 @@ spawn_free_args(char **argv) /** * Execute the given program and return its standard output as file-descriptor (pipe). */ -int -spawn_and_give_stdout(const char *prog, char *argv[], char *envp[], - int *rd, pid_t *pid, int redir_stderr) -{ - pid_t p; - int fd[2], f, i; - char bin[256]; - const char *local_argv[2] = { NULL, NULL }; - char **e, **e0, **e2, **e3, *p1, *p2; +int spawn_and_give_stdout(const char* prog, + char* argv[], + char* envp[], + int* rd, + pid_t* pid, + int redir_stderr) { + pid_t p; + int fd[2], f, i; + char bin[256]; + const char* local_argv[2] = {NULL, NULL}; + char ** e, **e0, **e2, **e3, *p1, *p2; if (*prog != '/' && *prog != '.') { - if (!find_exec(prog, bin, sizeof(bin))) return -1; + if (!find_exec(prog, bin, sizeof(bin))) + return -1; prog = bin; } - if (!argv) argv = (void *)local_argv; + if (!argv) + argv = (void*)local_argv; if (!argv[0]) { - if (argv != (void *)local_argv) { - for (i = 1, e = argv + 1; *e; i++, e++); - i = (i + 1) * sizeof(char *); + if (argv != (void*)local_argv) { + for (i = 1, e = argv + 1; *e; i++, e++) + ; + i = (i + 1) * sizeof(char*); e = alloca(i); memcpy(e, argv, i); argv = e; } - argv[0] = (char *)prog; + argv[0] = (char*)prog; } if (!envp || !envp[0]) { e = environ; } else { - for (i = 0, e2 = environ; *e2; i++, e2++); - for (f = 0, e2 = envp; *e2; f++, e2++); - e = alloca((i + f + 1) * sizeof(char *)); - memcpy(e, environ, i * sizeof(char *)); - e0 = e + i; + for (i = 0, e2 = environ; *e2; i++, e2++) + ; + for (f = 0, e2 = envp; *e2; f++, e2++) + ; + e = alloca((i + f + 1) * sizeof(char*)); + memcpy(e, environ, i * sizeof(char*)); + e0 = e + i; *e0 = NULL; for (e2 = envp; *e2; e2++) { for (e3 = e; *e3; e3++) { @@ -501,7 +491,7 @@ spawn_and_give_stdout(const char *prog, char *argv[], char *envp[], } if (!*e3) { *e0++ = *e2; - *e0 = NULL; + *e0 = NULL; } } *e0 = NULL; @@ -509,30 +499,31 @@ spawn_and_give_stdout(const char *prog, char *argv[], char *envp[], tvh_mutex_lock(&fork_lock); - if(pipe(fd) == -1) { + if (pipe(fd) == -1) { tvh_mutex_unlock(&fork_lock); return -1; } p = fork(); - if(p == -1) { + if (p == -1) { tvh_mutex_unlock(&fork_lock); close(fd[0]); close(fd[1]); - tvherror(LS_SPAWN, "Unable to fork() for \"%s\" -- %s", - prog, strerror(errno)); + tvherror(LS_SPAWN, "Unable to fork() for \"%s\" -- %s", prog, strerror(errno)); return -1; } - if(p == 0) { - struct dirent *selfd_ent; - DIR *selfd; + if (p == 0) { + struct dirent* selfd_ent; + DIR* selfd; f = open("/dev/null", O_RDWR); - if(f == -1) { + if (f == -1) { spawn_error("pid %d cannot open /dev/null for redirect %s -- %s", - getpid(), prog, strerror(errno)); + getpid(), + prog, + strerror(errno)); exit(1); } @@ -561,18 +552,19 @@ spawn_and_give_stdout(const char *prog, char *argv[], char *envp[], } closedir(selfd); } else { - int maxfd = sysconf(_SC_OPEN_MAX);; + int maxfd = sysconf(_SC_OPEN_MAX); + ; spawn_error("unable to open '/dev/fd', falling back to closing all %d" - "This may take a long time!", maxfd); + "This may take a long time!", + maxfd); for (f = 3; f < maxfd; f++) close(f); } execve(prog, argv, e); - spawn_error("pid %d cannot execute %s -- %s\n", - getpid(), prog, strerror(errno)); + spawn_error("pid %d cannot execute %s -- %s\n", getpid(), prog, strerror(errno)); exit(1); } @@ -598,41 +590,49 @@ spawn_and_give_stdout(const char *prog, char *argv[], char *envp[], * Execute the given program and return its standard input as file-descriptor (pipe). * The standard output file-decriptor (od) must be valid, too. */ -int -spawn_with_passthrough(const char *prog, char *argv[], char *envp[], - int od, int *wd, pid_t *pid, int redir_stderr) -{ - pid_t p; - int fd[2], f, i, maxfd; - char bin[256]; - const char *local_argv[2] = { NULL, NULL }; - char **e, **e0, **e2, **e3, *p1, *p2; +int spawn_with_passthrough(const char* prog, + char* argv[], + char* envp[], + int od, + int* wd, + pid_t* pid, + int redir_stderr) { + pid_t p; + int fd[2], f, i, maxfd; + char bin[256]; + const char* local_argv[2] = {NULL, NULL}; + char ** e, **e0, **e2, **e3, *p1, *p2; if (*prog != '/' && *prog != '.') { - if (!find_exec(prog, bin, sizeof(bin))) return -1; + if (!find_exec(prog, bin, sizeof(bin))) + return -1; prog = bin; } - if (!argv) argv = (void *)local_argv; + if (!argv) + argv = (void*)local_argv; if (!argv[0]) { - if (argv != (void *)local_argv) { - for (i = 1, e = argv + 1; *e; i++, e++); - i = (i + 1) * sizeof(char *); + if (argv != (void*)local_argv) { + for (i = 1, e = argv + 1; *e; i++, e++) + ; + i = (i + 1) * sizeof(char*); e = alloca(i); memcpy(e, argv, i); argv = e; } - argv[0] = (char *)prog; + argv[0] = (char*)prog; } if (!envp || !envp[0]) { e = environ; } else { - for (i = 0, e2 = environ; *e2; i++, e2++); - for (f = 0, e2 = envp; *e2; f++, e2++); - e = alloca((i + f + 1) * sizeof(char *)); - memcpy(e, environ, i * sizeof(char *)); - e0 = e + i; + for (i = 0, e2 = environ; *e2; i++, e2++) + ; + for (f = 0, e2 = envp; *e2; f++, e2++) + ; + e = alloca((i + f + 1) * sizeof(char*)); + memcpy(e, environ, i * sizeof(char*)); + e0 = e + i; *e0 = NULL; for (e2 = envp; *e2; e2++) { for (e3 = e; *e3; e3++) { @@ -645,7 +645,7 @@ spawn_with_passthrough(const char *prog, char *argv[], char *envp[], } if (!*e3) { *e0++ = *e2; - *e0 = NULL; + *e0 = NULL; } } *e0 = NULL; @@ -655,7 +655,7 @@ spawn_with_passthrough(const char *prog, char *argv[], char *envp[], tvh_mutex_lock(&fork_lock); - if(pipe(fd) == -1) { + if (pipe(fd) == -1) { tvh_mutex_unlock(&fork_lock); // do not pass the local variable outside if (argv[0] == bin) @@ -665,26 +665,27 @@ spawn_with_passthrough(const char *prog, char *argv[], char *envp[], p = fork(); - if(p == -1) { + if (p == -1) { tvh_mutex_unlock(&fork_lock); close(fd[0]); close(fd[1]); - tvherror(LS_SPAWN, "Unable to fork() for \"%s\" -- %s", - prog, strerror(errno)); + tvherror(LS_SPAWN, "Unable to fork() for \"%s\" -- %s", prog, strerror(errno)); // do not pass the local variable outside if (argv[0] == bin) argv[0] = NULL; return -1; } - if(p == 0) { + if (p == 0) { if (redir_stderr) { f = spawn_pipe_error.wr; } else { f = open("/dev/null", O_RDWR); - if(f == -1) { + if (f == -1) { spawn_error("pid %d cannot open /dev/null for redirect %s -- %s", - getpid(), prog, strerror(errno)); + getpid(), + prog, + strerror(errno)); exit(1); } } @@ -707,8 +708,7 @@ spawn_with_passthrough(const char *prog, char *argv[], char *envp[], close(f); execve(prog, argv, e); - spawn_error("pid %d cannot execute %s -- %s\n", - getpid(), prog, strerror(errno)); + spawn_error("pid %d cannot execute %s -- %s\n", getpid(), prog, strerror(errno)); exit(1); } @@ -735,23 +735,24 @@ spawn_with_passthrough(const char *prog, char *argv[], char *envp[], /** * Execute the given program with arguments - * + * * *outp will point to the allocated buffer */ -int -spawnv(const char *prog, char *argv[], pid_t *pid, int redir_stdout, int redir_stderr) -{ - pid_t p, f, maxfd; - char bin[256]; - const char *local_argv[2] = { NULL, NULL }; +int spawnv(const char* prog, char* argv[], pid_t* pid, int redir_stdout, int redir_stderr) { + pid_t p, f, maxfd; + char bin[256]; + const char* local_argv[2] = {NULL, NULL}; if (*prog != '/' && *prog != '.') { - if (!find_exec(prog, bin, sizeof(bin))) return -1; + if (!find_exec(prog, bin, sizeof(bin))) + return -1; prog = bin; } - if(!argv) argv = (void *)local_argv; - if (!argv[0]) argv[0] = (char*)prog; + if (!argv) + argv = (void*)local_argv; + if (!argv[0]) + argv[0] = (char*)prog; maxfd = sysconf(_SC_OPEN_MAX); @@ -759,21 +760,22 @@ spawnv(const char *prog, char *argv[], pid_t *pid, int redir_stdout, int redir_s p = fork(); - if(p == -1) { + if (p == -1) { tvh_mutex_unlock(&fork_lock); - tvherror(LS_SPAWN, "Unable to fork() for \"%s\" -- %s", - prog, strerror(errno)); + tvherror(LS_SPAWN, "Unable to fork() for \"%s\" -- %s", prog, strerror(errno)); // do not pass the local variable outside if (argv[0] == bin) argv[0] = NULL; return -1; } - if(p == 0) { + if (p == 0) { f = open("/dev/null", O_RDWR); - if(f == -1) { + if (f == -1) { spawn_error("pid %d cannot open /dev/null for redirect %s -- %s", - getpid(), prog, strerror(errno)); + getpid(), + prog, + strerror(errno)); exit(1); } @@ -793,8 +795,7 @@ spawnv(const char *prog, char *argv[], pid_t *pid, int redir_stdout, int redir_s close(f); execve(prog, argv, environ); - spawn_error("pid %d cannot execute %s -- %s\n", - getpid(), prog, strerror(errno)); + spawn_error("pid %d cannot execute %s -- %s\n", getpid(), prog, strerror(errno)); close(1); exit(1); } @@ -821,17 +822,15 @@ spawnv(const char *prog, char *argv[], pid_t *pid, int redir_stdout, int redir_s /* * */ -void spawn_init(void) -{ +void spawn_init(void) { tvh_pipe(O_NONBLOCK, &spawn_pipe_info); tvh_pipe(O_NONBLOCK, &spawn_pipe_error); atomic_set(&spawn_pipe_running, 1); pthread_create(&spawn_pipe_tid, NULL, spawn_pipe_thread, NULL); } -void spawn_done(void) -{ - spawn_t *s; +void spawn_done(void) { + spawn_t* s; atomic_set(&spawn_pipe_running, 0); tvh_thread_kill(spawn_pipe_tid, SIGTERM); @@ -842,7 +841,7 @@ void spawn_done(void) free(spawn_info_buf); while ((s = LIST_FIRST(&spawns)) != NULL) { LIST_REMOVE(s, link); - free((char *)s->name); + free((char*)s->name); free(s); } } diff --git a/src/spawn.h b/src/spawn.h index 12c0b2ec8..7e7a71d9e 100644 --- a/src/spawn.h +++ b/src/spawn.h @@ -19,25 +19,34 @@ #ifndef SPAWN_H #define SPAWN_H -void spawn_info ( const char *fmt, ... ); +void spawn_info(const char* fmt, ...); -void spawn_error ( const char *fmt, ... ); +void spawn_error(const char* fmt, ...); -int find_exec ( const char *name, char *out, size_t len ); +int find_exec(const char* name, char* out, size_t len); -int spawn_parse_args(char ***argv, int argc, const char *cmd, const char **replace); +int spawn_parse_args(char*** argv, int argc, const char* cmd, const char** replace); -void spawn_free_args(char **argv); +void spawn_free_args(char** argv); -int spawn_and_give_stdout(const char *prog, char *argv[], char *envp[], - int *rd, pid_t *pid, int redir_stderr); +int spawn_and_give_stdout(const char* prog, + char* argv[], + char* envp[], + int* rd, + pid_t* pid, + int redir_stderr); -int spawn_with_passthrough(const char *prog, char *argv[], char *envp[], - int od, int *wd, pid_t *pid, int redir_stderr); +int spawn_with_passthrough(const char* prog, + char* argv[], + char* envp[], + int od, + int* wd, + pid_t* pid, + int redir_stderr); -int spawnv(const char *prog, char *argv[], pid_t *pid, int redir_stdout, int redir_stderr); +int spawnv(const char* prog, char* argv[], pid_t* pid, int redir_stdout, int redir_stderr); -int spawn_reap(pid_t pid, char *stxt, size_t stxtlen); +int spawn_reap(pid_t pid, char* stxt, size_t stxtlen); int spawn_kill(pid_t pid, int sig, int timeout); diff --git a/src/streaming.c b/src/streaming.c index 54f48b9ec..055442f3c 100644 --- a/src/streaming.c +++ b/src/streaming.c @@ -26,40 +26,36 @@ #include "service.h" #include "timeshift.h" -static memoryinfo_t streaming_msg_memoryinfo = { .my_name = "Streaming message" }; +static memoryinfo_t streaming_msg_memoryinfo = {.my_name = "Streaming message"}; -void -streaming_pad_init(streaming_pad_t *sp) -{ +void streaming_pad_init(streaming_pad_t* sp) { LIST_INIT(&sp->sp_targets); - sp->sp_ntargets = 0; + sp->sp_ntargets = 0; sp->sp_reject_filter = ~0; } /** * */ -void -streaming_target_init(streaming_target_t *st, streaming_ops_t *ops, - void *opaque, int reject_filter) -{ - st->st_ops = *ops; - st->st_opaque = opaque; +void streaming_target_init(streaming_target_t* st, + streaming_ops_t* ops, + void* opaque, + int reject_filter) { + st->st_ops = *ops; + st->st_opaque = opaque; st->st_reject_filter = reject_filter; } /** * */ -static size_t -streaming_message_data_size(streaming_message_t *sm) -{ +static size_t streaming_message_data_size(streaming_message_t* sm) { if (sm->sm_type == SMT_PACKET) { - th_pkt_t *pkt = sm->sm_data; + th_pkt_t* pkt = sm->sm_data; if (pkt && pkt->pkt_payload) return pktbuf_len(pkt->pkt_payload); } else if (sm->sm_type == SMT_MPEGTS) { - pktbuf_t *pkt_payload = sm->sm_data; + pktbuf_t* pkt_payload = sm->sm_data; if (pkt_payload) return pktbuf_len(pkt_payload); } @@ -69,10 +65,8 @@ streaming_message_data_size(streaming_message_t *sm) /** * */ -static void -streaming_queue_deliver(void *opauqe, streaming_message_t *sm) -{ - streaming_queue_t *sq = opauqe; +static void streaming_queue_deliver(void* opauqe, streaming_message_t* sm) { + streaming_queue_t* sq = opauqe; tvh_mutex_lock(&sq->sq_mutex); @@ -91,12 +85,10 @@ streaming_queue_deliver(void *opauqe, streaming_message_t *sm) /** * */ -static htsmsg_t * -streaming_queue_info(void *opaque, htsmsg_t *list) -{ - streaming_queue_t *sq = opaque; - size_t size; - char buf[256]; +static htsmsg_t* streaming_queue_info(void* opaque, htsmsg_t* list) { + streaming_queue_t* sq = opaque; + size_t size; + char buf[256]; tvh_mutex_lock(&sq->sq_mutex); size = sq->sq_size; tvh_mutex_unlock(&sq->sq_mutex); @@ -108,9 +100,7 @@ streaming_queue_info(void *opaque, htsmsg_t *list) /** * */ -void -streaming_queue_remove(streaming_queue_t *sq, streaming_message_t *sm) -{ +void streaming_queue_remove(streaming_queue_t* sq, streaming_message_t* sm) { sq->sq_size -= streaming_message_data_size(sm); TAILQ_REMOVE(&sq->sq_queue, sm, sm_link); } @@ -118,13 +108,8 @@ streaming_queue_remove(streaming_queue_t *sq, streaming_message_t *sm) /** * */ -void -streaming_queue_init(streaming_queue_t *sq, int reject_filter, size_t maxsize) -{ - static streaming_ops_t ops = { - .st_cb = streaming_queue_deliver, - .st_info = streaming_queue_info - }; +void streaming_queue_init(streaming_queue_t* sq, int reject_filter, size_t maxsize) { + static streaming_ops_t ops = {.st_cb = streaming_queue_deliver, .st_info = streaming_queue_info}; streaming_target_init(&sq->sq_st, &ops, sq, reject_filter); @@ -133,15 +118,13 @@ streaming_queue_init(streaming_queue_t *sq, int reject_filter, size_t maxsize) TAILQ_INIT(&sq->sq_queue); sq->sq_maxsize = maxsize; - sq->sq_size = 0; + sq->sq_size = 0; } /** * */ -void -streaming_queue_deinit(streaming_queue_t *sq) -{ +void streaming_queue_deinit(streaming_queue_t* sq) { sq->sq_size = 0; streaming_queue_clear(&sq->sq_queue); tvh_mutex_destroy(&sq->sq_mutex); @@ -151,12 +134,10 @@ streaming_queue_deinit(streaming_queue_t *sq) /** * */ -void -streaming_queue_clear(struct streaming_message_queue *q) -{ - streaming_message_t *sm; +void streaming_queue_clear(struct streaming_message_queue* q) { + streaming_message_t* sm; - while((sm = TAILQ_FIRST(q)) != NULL) { + while ((sm = TAILQ_FIRST(q)) != NULL) { TAILQ_REMOVE(q, sm, sm_link); streaming_msg_free(sm); } @@ -165,22 +146,17 @@ streaming_queue_clear(struct streaming_message_queue *q) /** * */ -void -streaming_target_connect(streaming_pad_t *sp, streaming_target_t *st) -{ +void streaming_target_connect(streaming_pad_t* sp, streaming_target_t* st) { sp->sp_ntargets++; st->st_pad = sp; LIST_INSERT_HEAD(&sp->sp_targets, st, st_link); sp->sp_reject_filter &= st->st_reject_filter; } - /** * */ -void -streaming_target_disconnect(streaming_pad_t *sp, streaming_target_t *st) -{ +void streaming_target_disconnect(streaming_pad_t* sp, streaming_target_t* st) { int filter; sp->sp_ntargets--; @@ -189,154 +165,135 @@ streaming_target_disconnect(streaming_pad_t *sp, streaming_target_t *st) LIST_REMOVE(st, st_link); filter = ~0; - LIST_FOREACH(st, &sp->sp_targets, st_link) + LIST_FOREACH (st, &sp->sp_targets, st_link) filter &= st->st_reject_filter; sp->sp_reject_filter = filter; } - /** * */ -streaming_message_t * -streaming_msg_create(streaming_message_type_t type) -{ - streaming_message_t *sm = malloc(sizeof(streaming_message_t)); +streaming_message_t* streaming_msg_create(streaming_message_type_t type) { + streaming_message_t* sm = malloc(sizeof(streaming_message_t)); memoryinfo_alloc(&streaming_msg_memoryinfo, sizeof(*sm)); sm->sm_type = type; #if ENABLE_TIMESHIFT sm->sm_time = 0; - sm->sm_s = NULL; + sm->sm_s = NULL; #endif return sm; } - /** * */ -streaming_message_t * -streaming_msg_create_pkt(th_pkt_t *pkt) -{ - streaming_message_t *sm = streaming_msg_create(SMT_PACKET); - sm->sm_data = pkt; +streaming_message_t* streaming_msg_create_pkt(th_pkt_t* pkt) { + streaming_message_t* sm = streaming_msg_create(SMT_PACKET); + sm->sm_data = pkt; pkt_ref_inc(pkt); return sm; } - /** * */ -streaming_message_t * -streaming_msg_create_data(streaming_message_type_t type, void *data) -{ - streaming_message_t *sm = streaming_msg_create(type); - sm->sm_data = data; +streaming_message_t* streaming_msg_create_data(streaming_message_type_t type, void* data) { + streaming_message_t* sm = streaming_msg_create(type); + sm->sm_data = data; return sm; } - /** * */ -streaming_message_t * -streaming_msg_create_code(streaming_message_type_t type, int code) -{ - streaming_message_t *sm = streaming_msg_create(type); - sm->sm_code = code; +streaming_message_t* streaming_msg_create_code(streaming_message_type_t type, int code) { + streaming_message_t* sm = streaming_msg_create(type); + sm->sm_code = code; return sm; } - - /** * */ -streaming_message_t * -streaming_msg_clone(streaming_message_t *src) -{ - streaming_message_t *dst = malloc(sizeof(streaming_message_t)); - streaming_start_t *ss; +streaming_message_t* streaming_msg_clone(streaming_message_t* src) { + streaming_message_t* dst = malloc(sizeof(streaming_message_t)); + streaming_start_t* ss; memoryinfo_alloc(&streaming_msg_memoryinfo, sizeof(*dst)); - dst->sm_type = src->sm_type; + dst->sm_type = src->sm_type; #if ENABLE_TIMESHIFT - dst->sm_time = src->sm_time; - dst->sm_s = src->sm_s; + dst->sm_time = src->sm_time; + dst->sm_s = src->sm_s; #endif - switch(src->sm_type) { - - case SMT_PACKET: - pkt_ref_inc(src->sm_data); - dst->sm_data = src->sm_data; - break; - - case SMT_START: - ss = dst->sm_data = src->sm_data; - streaming_start_ref(ss); - break; - - case SMT_SKIP: - dst->sm_data = malloc(sizeof(streaming_skip_t)); - memcpy(dst->sm_data, src->sm_data, sizeof(streaming_skip_t)); - break; - - case SMT_SIGNAL_STATUS: - dst->sm_data = malloc(sizeof(signal_status_t)); - memcpy(dst->sm_data, src->sm_data, sizeof(signal_status_t)); - break; - - case SMT_DESCRAMBLE_INFO: - dst->sm_data = malloc(sizeof(descramble_info_t)); - memcpy(dst->sm_data, src->sm_data, sizeof(descramble_info_t)); - break; - - case SMT_TIMESHIFT_STATUS: - dst->sm_data = malloc(sizeof(timeshift_status_t)); - memcpy(dst->sm_data, src->sm_data, sizeof(timeshift_status_t)); - break; - - case SMT_GRACE: - case SMT_SPEED: - case SMT_STOP: - case SMT_SERVICE_STATUS: - case SMT_NOSTART: - case SMT_NOSTART_WARN: - dst->sm_code = src->sm_code; - break; - - case SMT_EXIT: - break; - - case SMT_MPEGTS: - pktbuf_ref_inc(src->sm_data); - dst->sm_data = src->sm_data; - break; - - default: - abort(); + switch (src->sm_type) { + + case SMT_PACKET: + pkt_ref_inc(src->sm_data); + dst->sm_data = src->sm_data; + break; + + case SMT_START: + ss = dst->sm_data = src->sm_data; + streaming_start_ref(ss); + break; + + case SMT_SKIP: + dst->sm_data = malloc(sizeof(streaming_skip_t)); + memcpy(dst->sm_data, src->sm_data, sizeof(streaming_skip_t)); + break; + + case SMT_SIGNAL_STATUS: + dst->sm_data = malloc(sizeof(signal_status_t)); + memcpy(dst->sm_data, src->sm_data, sizeof(signal_status_t)); + break; + + case SMT_DESCRAMBLE_INFO: + dst->sm_data = malloc(sizeof(descramble_info_t)); + memcpy(dst->sm_data, src->sm_data, sizeof(descramble_info_t)); + break; + + case SMT_TIMESHIFT_STATUS: + dst->sm_data = malloc(sizeof(timeshift_status_t)); + memcpy(dst->sm_data, src->sm_data, sizeof(timeshift_status_t)); + break; + + case SMT_GRACE: + case SMT_SPEED: + case SMT_STOP: + case SMT_SERVICE_STATUS: + case SMT_NOSTART: + case SMT_NOSTART_WARN: + dst->sm_code = src->sm_code; + break; + + case SMT_EXIT: + break; + + case SMT_MPEGTS: + pktbuf_ref_inc(src->sm_data); + dst->sm_data = src->sm_data; + break; + + default: + abort(); } return dst; } - /** * */ -void -streaming_start_unref(streaming_start_t *ss) -{ +void streaming_start_unref(streaming_start_t* ss) { int i; - if((atomic_add(&ss->ss_refcount, -1)) != 1) + if ((atomic_add(&ss->ss_refcount, -1)) != 1) return; service_source_info_free(&ss->ss_si); - for(i = 0; i < ss->ss_num_components; i++) - if(ss->ss_components[i].ssc_gh) + for (i = 0; i < ss->ss_num_components; i++) + if (ss->ss_components[i].ssc_gh) pktbuf_ref_dec(ss->ss_components[i].ssc_gh); free(ss); } @@ -344,48 +301,46 @@ streaming_start_unref(streaming_start_t *ss) /** * */ -void -streaming_msg_free(streaming_message_t *sm) -{ +void streaming_msg_free(streaming_message_t* sm) { if (!sm) return; - switch(sm->sm_type) { - case SMT_PACKET: - if(sm->sm_data) - pkt_ref_dec(sm->sm_data); - break; - - case SMT_START: - if(sm->sm_data) - streaming_start_unref(sm->sm_data); - break; - - case SMT_GRACE: - case SMT_STOP: - case SMT_EXIT: - case SMT_SERVICE_STATUS: - case SMT_NOSTART: - case SMT_NOSTART_WARN: - case SMT_SPEED: - break; - - case SMT_SKIP: - case SMT_SIGNAL_STATUS: - case SMT_DESCRAMBLE_INFO: + switch (sm->sm_type) { + case SMT_PACKET: + if (sm->sm_data) + pkt_ref_dec(sm->sm_data); + break; + + case SMT_START: + if (sm->sm_data) + streaming_start_unref(sm->sm_data); + break; + + case SMT_GRACE: + case SMT_STOP: + case SMT_EXIT: + case SMT_SERVICE_STATUS: + case SMT_NOSTART: + case SMT_NOSTART_WARN: + case SMT_SPEED: + break; + + case SMT_SKIP: + case SMT_SIGNAL_STATUS: + case SMT_DESCRAMBLE_INFO: #if ENABLE_TIMESHIFT - case SMT_TIMESHIFT_STATUS: + case SMT_TIMESHIFT_STATUS: #endif - free(sm->sm_data); - break; + free(sm->sm_data); + break; - case SMT_MPEGTS: - if(sm->sm_data) - pktbuf_ref_dec(sm->sm_data); - break; + case SMT_MPEGTS: + if (sm->sm_data) + pktbuf_ref_dec(sm->sm_data); + break; - default: - abort(); + default: + abort(); } memoryinfo_free(&streaming_msg_memoryinfo, sizeof(*sm)); free(sm); @@ -394,9 +349,7 @@ streaming_msg_free(streaming_message_t *sm) /** * */ -void -streaming_target_deliver2(streaming_target_t *st, streaming_message_t *sm) -{ +void streaming_target_deliver2(streaming_target_t* st, streaming_message_t* sm) { if (st->st_reject_filter & SMT_TO_MASK(sm->sm_type)) streaming_msg_free(sm); else @@ -406,9 +359,7 @@ streaming_target_deliver2(streaming_target_t *st, streaming_message_t *sm) /** * */ -void -streaming_pad_deliver(streaming_pad_t *sp, streaming_message_t *sm) -{ +void streaming_pad_deliver(streaming_pad_t* sp, streaming_message_t* sm) { streaming_target_t *st, *next, *run = NULL; for (st = LIST_FIRST(&sp->sp_targets); st; st = next) { @@ -429,9 +380,7 @@ streaming_pad_deliver(streaming_pad_t *sp, streaming_message_t *sm) /** * */ -void -streaming_service_deliver(service_t *t, streaming_message_t *sm) -{ +void streaming_service_deliver(service_t* t, streaming_message_t* sm) { if (atomic_set(&t->s_pending_restart, 0)) service_restart_streams(t); sm->sm_s = t; @@ -441,102 +390,97 @@ streaming_service_deliver(service_t *t, streaming_message_t *sm) /** * */ -const char * -streaming_code2txt(int code) -{ +const char* streaming_code2txt(int code) { static __thread char ret[64]; - switch(code) { - case SM_CODE_OK: - return N_("OK"); - case SM_CODE_FORCE_OK: - return N_("Forced OK"); - - case SM_CODE_SOURCE_RECONFIGURED: - return N_("Source reconfigured"); - case SM_CODE_BAD_SOURCE: - return N_("Source quality is bad"); - case SM_CODE_SOURCE_DELETED: - return N_("Source deleted"); - case SM_CODE_SUBSCRIPTION_OVERRIDDEN: - return N_("Subscription overridden"); - case SM_CODE_INVALID_TARGET: - return N_("Invalid target"); - case SM_CODE_USER_ACCESS: - return N_("User access error"); - case SM_CODE_USER_LIMIT: - return N_("User limit reached"); - case SM_CODE_WEAK_STREAM: - return N_("Weak stream"); - case SM_CODE_USER_REQUEST: - return N_("User request"); - case SM_CODE_PREVIOUSLY_RECORDED: - return N_("Previously recorded"); - - case SM_CODE_NO_FREE_ADAPTER: - return N_("No free adapter"); - case SM_CODE_MUX_NOT_ENABLED: - return N_("Mux not enabled"); - case SM_CODE_NOT_FREE: - return N_("Adapter in use by another subscription"); - case SM_CODE_TUNING_FAILED: - return N_("Tuning failed"); - case SM_CODE_SVC_NOT_ENABLED: - return N_("No service enabled"); - case SM_CODE_BAD_SIGNAL: - return N_("Signal quality too poor"); - case SM_CODE_NO_SOURCE: - return N_("No source available"); - case SM_CODE_NO_SERVICE: - return N_("No service assigned to channel"); - case SM_CODE_NO_ADAPTERS: - return N_("No assigned adapters"); - case SM_CODE_INVALID_SERVICE: - return N_("Invalid service"); - case SM_CODE_CHN_NOT_ENABLED: - return N_("No channel enabled"); - case SM_CODE_DATA_TIMEOUT: - return N_("No A/V data received"); - case SM_CODE_OTHER_SERVICE: - return N_("Other service without A/V streams"); - - case SM_CODE_ABORTED: - return N_("Aborted by user"); - - case SM_CODE_NO_DESCRAMBLER: - return N_("No descrambler"); - case SM_CODE_NO_ACCESS: - return N_("No access"); - case SM_CODE_NO_INPUT: - return N_("No input detected"); - case SM_CODE_NO_SPACE: - return N_("Not enough disk space"); - - default: - snprintf(ret, sizeof(ret), _("Unknown reason (%i)"), code); - return ret; + switch (code) { + case SM_CODE_OK: + return N_("OK"); + case SM_CODE_FORCE_OK: + return N_("Forced OK"); + + case SM_CODE_SOURCE_RECONFIGURED: + return N_("Source reconfigured"); + case SM_CODE_BAD_SOURCE: + return N_("Source quality is bad"); + case SM_CODE_SOURCE_DELETED: + return N_("Source deleted"); + case SM_CODE_SUBSCRIPTION_OVERRIDDEN: + return N_("Subscription overridden"); + case SM_CODE_INVALID_TARGET: + return N_("Invalid target"); + case SM_CODE_USER_ACCESS: + return N_("User access error"); + case SM_CODE_USER_LIMIT: + return N_("User limit reached"); + case SM_CODE_WEAK_STREAM: + return N_("Weak stream"); + case SM_CODE_USER_REQUEST: + return N_("User request"); + case SM_CODE_PREVIOUSLY_RECORDED: + return N_("Previously recorded"); + + case SM_CODE_NO_FREE_ADAPTER: + return N_("No free adapter"); + case SM_CODE_MUX_NOT_ENABLED: + return N_("Mux not enabled"); + case SM_CODE_NOT_FREE: + return N_("Adapter in use by another subscription"); + case SM_CODE_TUNING_FAILED: + return N_("Tuning failed"); + case SM_CODE_SVC_NOT_ENABLED: + return N_("No service enabled"); + case SM_CODE_BAD_SIGNAL: + return N_("Signal quality too poor"); + case SM_CODE_NO_SOURCE: + return N_("No source available"); + case SM_CODE_NO_SERVICE: + return N_("No service assigned to channel"); + case SM_CODE_NO_ADAPTERS: + return N_("No assigned adapters"); + case SM_CODE_INVALID_SERVICE: + return N_("Invalid service"); + case SM_CODE_CHN_NOT_ENABLED: + return N_("No channel enabled"); + case SM_CODE_DATA_TIMEOUT: + return N_("No A/V data received"); + case SM_CODE_OTHER_SERVICE: + return N_("Other service without A/V streams"); + + case SM_CODE_ABORTED: + return N_("Aborted by user"); + + case SM_CODE_NO_DESCRAMBLER: + return N_("No descrambler"); + case SM_CODE_NO_ACCESS: + return N_("No access"); + case SM_CODE_NO_INPUT: + return N_("No input detected"); + case SM_CODE_NO_SPACE: + return N_("Not enough disk space"); + + default: + snprintf(ret, sizeof(ret), _("Unknown reason (%i)"), code); + return ret; } } - /** * */ -streaming_start_t * -streaming_start_copy(const streaming_start_t *src) -{ - int i; - size_t siz = sizeof(streaming_start_t) + - sizeof(streaming_start_component_t) * src->ss_num_components; +streaming_start_t* streaming_start_copy(const streaming_start_t* src) { + int i; + size_t siz = + sizeof(streaming_start_t) + sizeof(streaming_start_component_t) * src->ss_num_components; - streaming_start_t *dst = malloc(siz); + streaming_start_t* dst = malloc(siz); memcpy(dst, src, siz); service_source_info_copy(&dst->ss_si, &src->ss_si); - for(i = 0; i < dst->ss_num_components; i++) { - streaming_start_component_t *ssc = &dst->ss_components[i]; - if(ssc->ssc_gh != NULL) + for (i = 0; i < dst->ss_num_components; i++) { + streaming_start_component_t* ssc = &dst->ss_components[i]; + if (ssc->ssc_gh != NULL) pktbuf_ref_inc(ssc->ssc_gh); } @@ -544,17 +488,15 @@ streaming_start_copy(const streaming_start_t *src) return dst; } - /** * */ -streaming_start_component_t * -streaming_start_component_find_by_index(streaming_start_t *ss, int idx) -{ - streaming_start_component_t *ssc; - int i; - for(i = 0, ssc = ss->ss_components; i < ss->ss_num_components; i++, ssc++) - if(ssc->es_index == idx) +streaming_start_component_t* streaming_start_component_find_by_index(streaming_start_t* ss, + int idx) { + streaming_start_component_t* ssc; + int i; + for (i = 0, ssc = ss->ss_components; i < ss->ss_num_components; i++, ssc++) + if (ssc->es_index == idx) return ssc; return NULL; } @@ -563,88 +505,84 @@ streaming_start_component_find_by_index(streaming_start_t *ss, int idx) * */ static struct strtab streamtypetab[] = { - { "NONE", SCT_NONE }, - { "UNKNOWN", SCT_UNKNOWN }, - { "RAW", SCT_RAW }, - { "PCR", SCT_PCR }, - { "CAT", SCT_CAT }, - { "CA", SCT_CA }, - { "HBBTV", SCT_HBBTV }, - { "RDS", SCT_RDS }, - { "MPEG2VIDEO", SCT_MPEG2VIDEO }, - { "MPEG2AUDIO", SCT_MPEG2AUDIO }, - { "H264", SCT_H264 }, - { "AC3", SCT_AC3 }, - { "TELETEXT", SCT_TELETEXT }, - { "DVBSUB", SCT_DVBSUB }, - { "AAC-LATM", SCT_AAC }, - { "MPEGTS", SCT_MPEGTS }, - { "TEXTSUB", SCT_TEXTSUB }, - { "EAC3", SCT_EAC3 }, - { "AAC", SCT_MP4A }, - { "VP8", SCT_VP8 }, - { "VORBIS", SCT_VORBIS }, - { "HEVC", SCT_HEVC }, - { "VP9", SCT_VP9 }, - { "THEORA", SCT_THEORA }, - { "OPUS", SCT_OPUS }, - { "FLAC", SCT_FLAC }, - { "AC-4", SCT_AC4 }, + {"NONE", SCT_NONE}, + {"UNKNOWN", SCT_UNKNOWN}, + {"RAW", SCT_RAW}, + {"PCR", SCT_PCR}, + {"CAT", SCT_CAT}, + {"CA", SCT_CA}, + {"HBBTV", SCT_HBBTV}, + {"RDS", SCT_RDS}, + {"MPEG2VIDEO", SCT_MPEG2VIDEO}, + {"MPEG2AUDIO", SCT_MPEG2AUDIO}, + {"H264", SCT_H264}, + {"AC3", SCT_AC3}, + {"TELETEXT", SCT_TELETEXT}, + {"DVBSUB", SCT_DVBSUB}, + {"AAC-LATM", SCT_AAC}, + {"MPEGTS", SCT_MPEGTS}, + {"TEXTSUB", SCT_TEXTSUB}, + {"EAC3", SCT_EAC3}, + {"AAC", SCT_MP4A}, + {"VP8", SCT_VP8}, + {"VORBIS", SCT_VORBIS}, + {"HEVC", SCT_HEVC}, + {"VP9", SCT_VP9}, + {"THEORA", SCT_THEORA}, + {"OPUS", SCT_OPUS}, + {"FLAC", SCT_FLAC}, + {"AC-4", SCT_AC4}, }; /** * */ -const char * -streaming_component_type2txt(streaming_component_type_t s) -{ +const char* streaming_component_type2txt(streaming_component_type_t s) { return val2str(s, streamtypetab) ?: "INVALID"; } -streaming_component_type_t -streaming_component_txt2type(const char *s) -{ +streaming_component_type_t streaming_component_txt2type(const char* s) { return s ? str2val(s, streamtypetab) : SCT_UNKNOWN; } -const char * -streaming_component_audio_type2desc(int audio_type) -{ +const char* streaming_component_audio_type2desc(int audio_type) { /* From ISO 13818-1 - ISO 639 language descriptor */ - switch(audio_type) { - case 0: return ""; /* "Undefined" in the standard, but used for normal audio */ - case 1: return N_("Clean effects"); - case 2: return N_("Hearing impaired"); - case 3: return N_("Visually impaired commentary/audio description"); + switch (audio_type) { + case 0: + return ""; /* "Undefined" in the standard, but used for normal audio */ + case 1: + return N_("Clean effects"); + case 2: + return N_("Hearing impaired"); + case 3: + return N_("Visually impaired commentary/audio description"); } return N_("Reserved"); } static struct strtab signal_statetab[] = { - { "GOOD", SIGNAL_GOOD }, - { "BAD", SIGNAL_BAD }, - { "FAINT", SIGNAL_FAINT }, - { "NONE", SIGNAL_NONE }, + {"GOOD", SIGNAL_GOOD}, + {"BAD", SIGNAL_BAD}, + {"FAINT", SIGNAL_FAINT}, + {"NONE", SIGNAL_NONE}, }; -const char *signal2str(signal_state_t st) -{ - const char *r = val2str(st, signal_statetab); - if (!r) r = "UNKNOWN"; +const char* signal2str(signal_state_t st) { + const char* r = val2str(st, signal_statetab); + if (!r) + r = "UNKNOWN"; return r; } /* * */ -void streaming_init(void) -{ +void streaming_init(void) { memoryinfo_register(&streaming_msg_memoryinfo); } -void streaming_done(void) -{ +void streaming_done(void) { tvh_mutex_lock(&global_lock); memoryinfo_unregister(&streaming_msg_memoryinfo); tvh_mutex_unlock(&global_lock); diff --git a/src/streaming.h b/src/streaming.h index c90034358..29c7cefdf 100644 --- a/src/streaming.h +++ b/src/streaming.h @@ -30,21 +30,21 @@ struct service; /** * */ -typedef enum commercial_advice commercial_advice_t; -typedef enum signal_status_scale signal_status_scale_t; -typedef struct signal_status signal_status_t; -typedef struct descramble_info descramble_info_t; -typedef struct timeshift_status timeshift_status_t; -typedef struct streaming_skip streaming_skip_t; -typedef struct streaming_pad streaming_pad_t; -typedef enum streaming_message_type streaming_message_type_t; -typedef enum signal_state signal_state_t; -typedef struct streaming_message streaming_message_t; -typedef struct streaming_ops streaming_ops_t; -typedef struct streaming_queue streaming_queue_t; -typedef struct source_info source_info_t; +typedef enum commercial_advice commercial_advice_t; +typedef enum signal_status_scale signal_status_scale_t; +typedef struct signal_status signal_status_t; +typedef struct descramble_info descramble_info_t; +typedef struct timeshift_status timeshift_status_t; +typedef struct streaming_skip streaming_skip_t; +typedef struct streaming_pad streaming_pad_t; +typedef enum streaming_message_type streaming_message_type_t; +typedef enum signal_state signal_state_t; +typedef struct streaming_message streaming_message_t; +typedef struct streaming_ops streaming_ops_t; +typedef struct streaming_queue streaming_queue_t; +typedef struct source_info source_info_t; typedef struct streaming_start_component streaming_start_component_t; -typedef struct streaming_start streaming_start_t; +typedef struct streaming_start streaming_start_t; /** * @@ -74,17 +74,17 @@ enum signal_status_scale { * The signal status of a tuner */ struct signal_status { - const char *status_text; /* adapter status text */ - int snr; /* signal/noise ratio */ + const char* status_text; /* adapter status text */ + int snr; /* signal/noise ratio */ signal_status_scale_t snr_scale; - int signal; /* signal strength */ + int signal; /* signal strength */ signal_status_scale_t signal_scale; - int ber; /* bit error rate */ - int unc; /* uncorrected blocks */ - int ec_bit; /* error bit count */ - int tc_bit; /* total bit count */ - int ec_block; /* error block count */ - int tc_block; /* total block count */ + int ber; /* bit error rate */ + int unc; /* uncorrected blocks */ + int ec_bit; /* error bit count */ + int tc_bit; /* total bit count */ + int ec_block; /* error block count */ + int tc_block; /* total block count */ }; /** @@ -96,17 +96,16 @@ struct descramble_info { uint32_t provid; uint32_t ecmtime; uint16_t hops; - char cardsystem[128]; - char reader [128]; - char from [128]; - char protocol [128]; + char cardsystem[128]; + char reader[128]; + char from[128]; + char protocol[128]; }; /** * */ -struct timeshift_status -{ +struct timeshift_status { int full; int64_t shift; int64_t pts_start; @@ -116,8 +115,7 @@ struct timeshift_status /** * Streaming skip */ -struct streaming_skip -{ +struct streaming_skip { enum { SMT_SKIP_ERROR, SMT_SKIP_REL_TIME, @@ -135,7 +133,6 @@ struct streaming_skip #endif }; - /** * A streaming pad generates data. * It has one or more streaming targets attached to it. @@ -150,8 +147,8 @@ struct streaming_skip */ struct streaming_pad { struct streaming_target_list sp_targets; - int sp_ntargets; - int sp_reject_filter; + int sp_ntargets; + int sp_reject_filter; }; /** @@ -261,58 +258,51 @@ enum streaming_message_type { /** * Streaming codes */ -#define SM_CODE_OK 0 - -#define SM_CODE_UNDEFINED_ERROR 1 - -#define SM_CODE_FORCE_OK 10 - -#define SM_CODE_SOURCE_RECONFIGURED 100 -#define SM_CODE_BAD_SOURCE 101 -#define SM_CODE_SOURCE_DELETED 102 -#define SM_CODE_SUBSCRIPTION_OVERRIDDEN 103 -#define SM_CODE_INVALID_TARGET 104 -#define SM_CODE_USER_ACCESS 105 -#define SM_CODE_USER_LIMIT 106 -#define SM_CODE_WEAK_STREAM 107 -#define SM_CODE_USER_REQUEST 108 -#define SM_CODE_PREVIOUSLY_RECORDED 109 - -#define SM_CODE_NO_FREE_ADAPTER 200 -#define SM_CODE_MUX_NOT_ENABLED 201 -#define SM_CODE_NOT_FREE 202 -#define SM_CODE_TUNING_FAILED 203 -#define SM_CODE_SVC_NOT_ENABLED 204 -#define SM_CODE_BAD_SIGNAL 205 -#define SM_CODE_NO_SOURCE 206 -#define SM_CODE_NO_SERVICE 207 -#define SM_CODE_NO_VALID_ADAPTER 208 -#define SM_CODE_NO_ADAPTERS 209 -#define SM_CODE_INVALID_SERVICE 210 -#define SM_CODE_CHN_NOT_ENABLED 211 -#define SM_CODE_DATA_TIMEOUT 212 -#define SM_CODE_OTHER_SERVICE 213 - -#define SM_CODE_ABORTED 300 - -#define SM_CODE_NO_DESCRAMBLER 400 -#define SM_CODE_NO_ACCESS 401 -#define SM_CODE_NO_INPUT 402 -#define SM_CODE_NO_SPACE 403 +#define SM_CODE_OK 0 + +#define SM_CODE_UNDEFINED_ERROR 1 + +#define SM_CODE_FORCE_OK 10 + +#define SM_CODE_SOURCE_RECONFIGURED 100 +#define SM_CODE_BAD_SOURCE 101 +#define SM_CODE_SOURCE_DELETED 102 +#define SM_CODE_SUBSCRIPTION_OVERRIDDEN 103 +#define SM_CODE_INVALID_TARGET 104 +#define SM_CODE_USER_ACCESS 105 +#define SM_CODE_USER_LIMIT 106 +#define SM_CODE_WEAK_STREAM 107 +#define SM_CODE_USER_REQUEST 108 +#define SM_CODE_PREVIOUSLY_RECORDED 109 + +#define SM_CODE_NO_FREE_ADAPTER 200 +#define SM_CODE_MUX_NOT_ENABLED 201 +#define SM_CODE_NOT_FREE 202 +#define SM_CODE_TUNING_FAILED 203 +#define SM_CODE_SVC_NOT_ENABLED 204 +#define SM_CODE_BAD_SIGNAL 205 +#define SM_CODE_NO_SOURCE 206 +#define SM_CODE_NO_SERVICE 207 +#define SM_CODE_NO_VALID_ADAPTER 208 +#define SM_CODE_NO_ADAPTERS 209 +#define SM_CODE_INVALID_SERVICE 210 +#define SM_CODE_CHN_NOT_ENABLED 211 +#define SM_CODE_DATA_TIMEOUT 212 +#define SM_CODE_OTHER_SERVICE 213 + +#define SM_CODE_ABORTED 300 + +#define SM_CODE_NO_DESCRAMBLER 400 +#define SM_CODE_NO_ACCESS 401 +#define SM_CODE_NO_INPUT 402 +#define SM_CODE_NO_SPACE 403 /** * Signal */ -enum signal_state -{ - SIGNAL_UNKNOWN, - SIGNAL_GOOD, - SIGNAL_BAD, - SIGNAL_FAINT, - SIGNAL_NONE -}; +enum signal_state { SIGNAL_UNKNOWN, SIGNAL_GOOD, SIGNAL_BAD, SIGNAL_FAINT, SIGNAL_NONE }; -const char * signal2str ( signal_state_t st ); +const char* signal2str(signal_state_t st); /** * Streaming messages are sent from the pad to its receivers @@ -320,32 +310,32 @@ const char * signal2str ( signal_state_t st ); struct streaming_message { TAILQ_ENTRY(streaming_message) sm_link; streaming_message_type_t sm_type; - service_t *sm_s; + service_t* sm_s; #if ENABLE_TIMESHIFT int64_t sm_time; #endif union { - void *sm_data; - int sm_code; + void* sm_data; + int sm_code; }; }; /** * A streaming target receives data. */ -typedef void (st_callback_t)(void *opaque, streaming_message_t *sm); +typedef void(st_callback_t)(void* opaque, streaming_message_t* sm); struct streaming_ops { - st_callback_t *st_cb; - htsmsg_t *(*st_info)(void *opaque, htsmsg_t *list); + st_callback_t* st_cb; + htsmsg_t* (*st_info)(void* opaque, htsmsg_t* list); }; typedef struct streaming_target { LIST_ENTRY(streaming_target) st_link; - streaming_pad_t *st_pad; /* Source we are linked to */ - streaming_ops_t st_ops; - void *st_opaque; - int st_reject_filter; + streaming_pad_t* st_pad; /* Source we are linked to */ + streaming_ops_t st_ops; + void* st_opaque; + int st_reject_filter; } streaming_target_t; /** @@ -355,20 +345,19 @@ struct streaming_queue { streaming_target_t sq_st; - tvh_mutex_t sq_mutex; /* Protects sp_queue */ - tvh_cond_t sq_cond; /* Condvar for signalling new packets */ + tvh_mutex_t sq_mutex; /* Protects sp_queue */ + tvh_cond_t sq_cond; /* Condvar for signalling new packets */ - size_t sq_maxsize; /* Max queue size (bytes) */ - size_t sq_size; /* Actual queue size (bytes) - only data */ + size_t sq_maxsize; /* Max queue size (bytes) */ + size_t sq_size; /* Actual queue size (bytes) - only data */ struct streaming_message_queue sq_queue; - }; -streaming_component_type_t streaming_component_txt2type(const char *str); -const char *streaming_component_type2txt(streaming_component_type_t s); -streaming_component_type_t streaming_component_txt2type(const char *s); -const char *streaming_component_audio_type2desc(int audio_type); +streaming_component_type_t streaming_component_txt2type(const char* str); +const char* streaming_component_type2txt(streaming_component_type_t s); +streaming_component_type_t streaming_component_txt2type(const char* s); +const char* streaming_component_audio_type2desc(int audio_type); /** * Source information @@ -377,16 +366,16 @@ struct source_info { tvh_uuid_t si_adapter_uuid; tvh_uuid_t si_network_uuid; tvh_uuid_t si_mux_uuid; - char *si_adapter; - char *si_network; - char *si_network_type; - char *si_satpos; - char *si_mux; - char *si_provider; - char *si_service; - int si_type; - uint16_t si_tsid; - uint16_t si_onid; + char* si_adapter; + char* si_network; + char* si_network_type; + char* si_satpos; + char* si_mux; + char* si_provider; + char* si_service; + int si_type; + uint16_t si_tsid; + uint16_t si_onid; }; /** @@ -397,10 +386,9 @@ struct streaming_start_component { uint8_t ssc_disabled; uint8_t ssc_muxer_disabled; - - pktbuf_t *ssc_gh; -}; + pktbuf_t* ssc_gh; +}; struct streaming_start { int ss_refcount; @@ -414,73 +402,68 @@ struct streaming_start { uint16_t ss_service_id; streaming_start_component_t ss_components[0]; - }; /** * */ -void streaming_pad_init(streaming_pad_t *sp); +void streaming_pad_init(streaming_pad_t* sp); -void streaming_target_init(streaming_target_t *st, - streaming_ops_t *ops, void *opaque, - int reject_filter); +void streaming_target_init(streaming_target_t* st, + streaming_ops_t* ops, + void* opaque, + int reject_filter); -void streaming_queue_init - (streaming_queue_t *sq, int reject_filter, size_t maxsize); +void streaming_queue_init(streaming_queue_t* sq, int reject_filter, size_t maxsize); -void streaming_queue_clear(struct streaming_message_queue *q); +void streaming_queue_clear(struct streaming_message_queue* q); -void streaming_queue_deinit(streaming_queue_t *sq); +void streaming_queue_deinit(streaming_queue_t* sq); -void streaming_queue_remove(streaming_queue_t *sq, streaming_message_t *sm); +void streaming_queue_remove(streaming_queue_t* sq, streaming_message_t* sm); -void streaming_target_connect(streaming_pad_t *sp, streaming_target_t *st); +void streaming_target_connect(streaming_pad_t* sp, streaming_target_t* st); -void streaming_target_disconnect(streaming_pad_t *sp, streaming_target_t *st); +void streaming_target_disconnect(streaming_pad_t* sp, streaming_target_t* st); -void streaming_pad_deliver(streaming_pad_t *sp, streaming_message_t *sm); +void streaming_pad_deliver(streaming_pad_t* sp, streaming_message_t* sm); -void streaming_service_deliver(struct service *t, streaming_message_t *sm); +void streaming_service_deliver(struct service* t, streaming_message_t* sm); -void streaming_msg_free(streaming_message_t *sm); +void streaming_msg_free(streaming_message_t* sm); -streaming_message_t *streaming_msg_clone(streaming_message_t *src); +streaming_message_t* streaming_msg_clone(streaming_message_t* src); -streaming_message_t *streaming_msg_create(streaming_message_type_t type); +streaming_message_t* streaming_msg_create(streaming_message_type_t type); -streaming_message_t *streaming_msg_create_data(streaming_message_type_t type, - void *data); +streaming_message_t* streaming_msg_create_data(streaming_message_type_t type, void* data); -streaming_message_t *streaming_msg_create_code(streaming_message_type_t type, - int code); +streaming_message_t* streaming_msg_create_code(streaming_message_type_t type, int code); -streaming_message_t *streaming_msg_create_pkt(th_pkt_t *pkt); +streaming_message_t* streaming_msg_create_pkt(th_pkt_t* pkt); -static inline void -streaming_target_deliver(streaming_target_t *st, streaming_message_t *sm) - { st->st_ops.st_cb(st->st_opaque, sm); } +static inline void streaming_target_deliver(streaming_target_t* st, streaming_message_t* sm) { + st->st_ops.st_cb(st->st_opaque, sm); +} -void streaming_target_deliver2(streaming_target_t *st, streaming_message_t *sm); +void streaming_target_deliver2(streaming_target_t* st, streaming_message_t* sm); -static inline void streaming_start_ref(streaming_start_t *ss) -{ +static inline void streaming_start_ref(streaming_start_t* ss) { atomic_add(&ss->ss_refcount, 1); } -void streaming_start_unref(streaming_start_t *ss); +void streaming_start_unref(streaming_start_t* ss); -streaming_start_t *streaming_start_copy(const streaming_start_t *src); +streaming_start_t* streaming_start_copy(const streaming_start_t* src); -static inline int -streaming_pad_probe_type(streaming_pad_t *sp, streaming_message_type_t smt) -{ +static inline int streaming_pad_probe_type(streaming_pad_t* sp, streaming_message_type_t smt) { return (sp->sp_reject_filter & SMT_TO_MASK(smt)) == 0; } -const char *streaming_code2txt(int code); +const char* streaming_code2txt(int code); -streaming_start_component_t *streaming_start_component_find_by_index(streaming_start_t *ss, int idx); +streaming_start_component_t* streaming_start_component_find_by_index(streaming_start_t* ss, + int idx); void streaming_init(void); void streaming_done(void); diff --git a/src/string_list.c b/src/string_list.c index cfe0fa034..2dd3a383b 100644 --- a/src/string_list.c +++ b/src/string_list.c @@ -23,26 +23,21 @@ #include "htsmsg.h" /// Sorted string list helper functions. -void -string_list_init(string_list_t *l) -{ +void string_list_init(string_list_t* l) { RB_INIT(l); } -string_list_t * -string_list_create(void) -{ - string_list_t *ret = calloc(1, sizeof(string_list_t)); +string_list_t* string_list_create(void) { + string_list_t* ret = calloc(1, sizeof(string_list_t)); string_list_init(ret); return ret; } -void -string_list_destroy(string_list_t *l) -{ - if (!l) return; +void string_list_destroy(string_list_t* l) { + if (!l) + return; - string_list_item_t *item; + string_list_item_t* item; while ((item = RB_FIRST(l))) { RB_REMOVE(l, item, h_link); free(item); @@ -50,12 +45,11 @@ string_list_destroy(string_list_t *l) free(l); } -char * -string_list_remove_first(string_list_t *l) -{ - char *ret = NULL; - if (!l) return NULL; - string_list_item_t *item = RB_FIRST(l); +char* string_list_remove_first(string_list_t* l) { + char* ret = NULL; + if (!l) + return NULL; + string_list_item_t* item = RB_FIRST(l); if (!item) return NULL; ret = strdup(item->id); @@ -64,18 +58,15 @@ string_list_remove_first(string_list_t *l) return ret; } -static inline int -string_list_item_cmp(const void *a, const void *b) -{ +static inline int string_list_item_cmp(const void* a, const void* b) { return strcmp(((const string_list_item_t*)a)->id, ((const string_list_item_t*)b)->id); } -void -string_list_insert(string_list_t *l, const char *id) -{ - if (!id) return; +void string_list_insert(string_list_t* l, const char* id) { + if (!id) + return; - string_list_item_t *item = calloc(1, sizeof(string_list_item_t) + strlen(id) + 1); + string_list_item_t* item = calloc(1, sizeof(string_list_item_t) + strlen(id) + 1); strcpy(item->id, id); if (RB_INSERT_SORTED(l, item, h_link, string_list_item_cmp)) { /* Duplicate, so not inserted. */ @@ -83,12 +74,11 @@ string_list_insert(string_list_t *l, const char *id) } } -void -string_list_insert_lowercase(string_list_t *l, const char *id) -{ +void string_list_insert_lowercase(string_list_t* l, const char* id) { char *s, *p; - if (!id) return; + if (!id) + return; s = alloca(strlen(id) + 1); for (p = s; *id; id++, p++) *p = tolower(*id); @@ -96,29 +86,26 @@ string_list_insert_lowercase(string_list_t *l, const char *id) string_list_insert(l, s); } -htsmsg_t * -string_list_to_htsmsg(const string_list_t *l) -{ - htsmsg_t *ret; - string_list_item_t *item; +htsmsg_t* string_list_to_htsmsg(const string_list_t* l) { + htsmsg_t* ret; + string_list_item_t* item; if (!RB_FIRST(l)) return NULL; ret = htsmsg_create_list(); - RB_FOREACH(item, l, h_link) + RB_FOREACH (item, l, h_link) htsmsg_add_str(ret, NULL, item->id); return ret; } -string_list_t * -htsmsg_to_string_list(const htsmsg_t *m) -{ - string_list_t *ret = NULL; - htsmsg_field_t *f; +string_list_t* htsmsg_to_string_list(const htsmsg_t* m) { + string_list_t* ret = NULL; + htsmsg_field_t* f; HTSMSG_FOREACH(f, m) { if (f->hmf_type == HMF_STR) { - const char *str = f->hmf_str; + const char* str = f->hmf_str; if (str && *str) { - if (!ret) ret = string_list_create(); + if (!ret) + ret = string_list_create(); string_list_insert(ret, str); } } @@ -126,49 +113,45 @@ htsmsg_to_string_list(const htsmsg_t *m) return ret; } -void -string_list_serialize(const string_list_t *l, htsmsg_t *m, const char *f) -{ - if (!l) return; +void string_list_serialize(const string_list_t* l, htsmsg_t* m, const char* f) { + if (!l) + return; - htsmsg_t *msg = string_list_to_htsmsg(l); + htsmsg_t* msg = string_list_to_htsmsg(l); if (msg) htsmsg_add_msg(m, f, msg); } -string_list_t * -string_list_deserialize(const htsmsg_t *m, const char *n) -{ - htsmsg_t *sub = htsmsg_get_list(m, n); - if (!sub) return NULL; +string_list_t* string_list_deserialize(const htsmsg_t* m, const char* n) { + htsmsg_t* sub = htsmsg_get_list(m, n); + if (!sub) + return NULL; return htsmsg_to_string_list(sub); } -char * -string_list_2_csv(const string_list_t *l, char delim, int human) -{ - if (!l) return NULL; +char* string_list_2_csv(const string_list_t* l, char delim, int human) { + if (!l) + return NULL; - htsmsg_t *msg = string_list_to_htsmsg(l); - if (!msg) return NULL; + htsmsg_t* msg = string_list_to_htsmsg(l); + if (!msg) + return NULL; - char *ret = htsmsg_list_2_csv(msg, delim, human); + char* ret = htsmsg_list_2_csv(msg, delim, human); htsmsg_destroy(msg); return ret; } -int -string_list_cmp(const string_list_t *m1, const string_list_t *m2) -{ +int string_list_cmp(const string_list_t* m1, const string_list_t* m2) { /* Algorithm based on htsmsg_cmp */ if (m1 == NULL && m2 == NULL) return 0; if (m1 == NULL || m2 == NULL) return 1; - string_list_item_t *i1; - string_list_item_t *i2 = RB_FIRST(m2); - RB_FOREACH(i1, m1, h_link) { + string_list_item_t* i1; + string_list_item_t* i2 = RB_FIRST(m2); + RB_FOREACH (i1, m1, h_link) { if (i2 == NULL) return 1; const int cmp = strcmp(i1->id, i2->id); @@ -185,28 +168,25 @@ string_list_cmp(const string_list_t *m1, const string_list_t *m2) return 0; } -string_list_t * -string_list_copy(const string_list_t *src) -{ - if (!src) return NULL; - string_list_t *ret = string_list_create(); - string_list_item_t *item; - RB_FOREACH(item, src, h_link) +string_list_t* string_list_copy(const string_list_t* src) { + if (!src) + return NULL; + string_list_t* ret = string_list_create(); + string_list_item_t* item; + RB_FOREACH (item, src, h_link) string_list_insert(ret, item->id); return ret; } -int -string_list_contains_string(const string_list_t *src, const char *find) -{ +int string_list_contains_string(const string_list_t* src, const char* find) { if (find == NULL) return 0; - string_list_item_t *skel = alloca(sizeof(*skel) + strlen(find) + 1); + string_list_item_t* skel = alloca(sizeof(*skel) + strlen(find) + 1); strcpy(skel->id, find); - string_list_item_t *item = RB_FIND(src, skel, h_link, string_list_item_cmp); + string_list_item_t* item = RB_FIND(src, skel, h_link, string_list_item_cmp); /* Can't just return item due to compiler settings preventing ptr to * int conversion */ diff --git a/src/string_list.h b/src/string_list.h index e60ead66e..943bd03db 100644 --- a/src/string_list.h +++ b/src/string_list.h @@ -47,42 +47,38 @@ typedef struct string_list_item string_list_item_t; typedef RB_HEAD(string_list, string_list_item) string_list_t; /// Initialize the memory used by the list. -void string_list_init(string_list_t *l); +void string_list_init(string_list_t* l); /// Dynamically allocate and initialize a list. -string_list_t *string_list_create(void); +string_list_t* string_list_create(void); /// Free up the memory used by the list. -void string_list_destroy(string_list_t *l); +void string_list_destroy(string_list_t* l); /// Insert a copy of id in to the sorted string list. -void string_list_insert(string_list_t *l, const char *id); +void string_list_insert(string_list_t* l, const char* id); /// Insert a copy of lowercase id in to the sorted string list. -void string_list_insert_lowercase(string_list_t *l, const char *id); +void string_list_insert_lowercase(string_list_t* l, const char* id); /// Remove the first entry from the list and return ownership to the /// caller. -char *string_list_remove_first(string_list_t *l) - __attribute__((warn_unused_result)); +char* string_list_remove_first(string_list_t* l) __attribute__((warn_unused_result)); /// Conversion function from sorted string list to an htsmsg. /// @return NULL if empty. -struct htsmsg *string_list_to_htsmsg(const string_list_t *l) +struct htsmsg* string_list_to_htsmsg(const string_list_t* l) __attribute__((warn_unused_result)); +string_list_t* htsmsg_to_string_list(const struct htsmsg* m) __attribute__((warn_unused_result)); +void string_list_serialize(const string_list_t* l, struct htsmsg* m, const char* f); +string_list_t* string_list_deserialize(const struct htsmsg* m, const char* f) __attribute__((warn_unused_result)); -string_list_t *htsmsg_to_string_list(const struct htsmsg *m) +char* string_list_2_csv(const string_list_t* l, char delim, int human) __attribute__((warn_unused_result)); -void string_list_serialize(const string_list_t *l, struct htsmsg *m, const char *f); -string_list_t *string_list_deserialize(const struct htsmsg *m, const char *f) - __attribute__((warn_unused_result)); -char *string_list_2_csv(const string_list_t *l, char delim, int human) - __attribute__((warn_unused_result)); -int string_list_cmp(const string_list_t *m1, const string_list_t *m2) +int string_list_cmp(const string_list_t* m1, const string_list_t* m2) __attribute__((warn_unused_result)); /// Deep clone (shares no pointers, so have to string_list_destroy both. -string_list_t *string_list_copy(const string_list_t *src) - __attribute__((warn_unused_result)); +string_list_t* string_list_copy(const string_list_t* src) __attribute__((warn_unused_result)); /// Searching -int string_list_contains_string(const string_list_t *src, const char *find); +int string_list_contains_string(const string_list_t* src, const char* find); #endif diff --git a/src/subscriptions.c b/src/subscriptions.c index 08f490e1d..9bb0d4184 100644 --- a/src/subscriptions.c +++ b/src/subscriptions.c @@ -39,26 +39,20 @@ static int subscription_postpone; * */ static void subscription_reschedule(void); -static void subscription_unsubscribe_cb(void *aux); +static void subscription_unsubscribe_cb(void* aux); /** * */ -static inline int -shortid(th_subscription_t *s) -{ +static inline int shortid(th_subscription_t* s) { return s->ths_id & 0xffff; } -static inline void -subsetstate(th_subscription_t *s, ths_state_t state) -{ +static inline void subsetstate(th_subscription_t* s, ths_state_t state) { atomic_set(&s->ths_state, state); } -static inline ths_state_t -subgetstate(th_subscription_t *s) -{ +static inline ths_state_t subgetstate(th_subscription_t* s) { return atomic_get(&s->ths_state); } @@ -69,11 +63,9 @@ subgetstate(th_subscription_t *s) /** * The service is producing output. */ -static void -subscription_link_service(th_subscription_t *s, service_t *t) -{ - streaming_message_t *sm; - streaming_start_t *ss; +static void subscription_link_service(th_subscription_t* s, service_t* t) { + streaming_message_t* sm; + streaming_start_t* ss; subsetstate(s, SUBSCRIPTION_TESTING_SERVICE); s->ths_service = t; @@ -85,14 +77,13 @@ subscription_link_service(th_subscription_t *s, service_t *t) LIST_INSERT_HEAD(&t->s_subscriptions, s, ths_service_link); - tvhtrace(LS_SUBSCRIPTION, "%04X: linking sub %p to svc %p type %i", - shortid(s), s, t, t->s_type); + tvhtrace(LS_SUBSCRIPTION, "%04X: linking sub %p to svc %p type %i", shortid(s), s, t, t->s_type); tvh_mutex_lock(&t->s_stream_mutex); - if(elementary_set_has_streams(&t->s_components, 1) || t->s_type != STYPE_STD) { + if (elementary_set_has_streams(&t->s_components, 1) || t->s_type != STYPE_STD) { streaming_msg_free(s->ths_start_message); - ss = service_build_streaming_start(t); + ss = service_build_streaming_start(t); s->ths_start_message = streaming_msg_create_data(SMT_START, ss); } @@ -102,18 +93,17 @@ subscription_link_service(th_subscription_t *s, service_t *t) sm = streaming_msg_create_code(SMT_GRACE, s->ths_postpone + t->s_grace_delay); streaming_service_deliver(t, sm); - if(s->ths_start_message != NULL && t->s_streaming_status & TSS_PACKETS) { + if (s->ths_start_message != NULL && t->s_streaming_status & TSS_PACKETS) { subsetstate(s, SUBSCRIPTION_GOT_SERVICE); // Send a START message to the subscription client streaming_target_deliver(s->ths_output, s->ths_start_message); s->ths_start_message = NULL; - t->s_running = 1; + t->s_running = 1; // Send status report - sm = streaming_msg_create_code(SMT_SERVICE_STATUS, - t->s_streaming_status); + sm = streaming_msg_create_code(SMT_SERVICE_STATUS, t->s_streaming_status); streaming_target_deliver(s->ths_output, sm); } @@ -123,21 +113,20 @@ subscription_link_service(th_subscription_t *s, service_t *t) /** * Called from service code */ -static int -subscription_unlink_service0(th_subscription_t *s, int reason, int resched) -{ - streaming_message_t *sm; - service_t *t = s->ths_service; +static int subscription_unlink_service0(th_subscription_t* s, int reason, int resched) { + streaming_message_t* sm; + service_t* t = s->ths_service; /* Ignore - not actually linked */ - if (!s->ths_current_instance) goto stop; + if (!s->ths_current_instance) + goto stop; s->ths_current_instance = NULL; tvh_mutex_lock(&t->s_stream_mutex); streaming_target_disconnect(&t->s_streaming_pad, &s->ths_input); - if(!resched && t->s_running) { + if (!resched && t->s_running) { // Send a STOP message to the subscription client sm = streaming_msg_create_code(SMT_STOP, reason); streaming_target_deliver(s->ths_output, sm); @@ -160,14 +149,12 @@ subscription_unlink_service0(th_subscription_t *s, int reason, int resched) mtimer_arm_rel(&s->ths_remove_timer, subscription_unsubscribe_cb, s, 0); stop: - if(resched || LIST_FIRST(&t->s_subscriptions) == NULL) + if (resched || LIST_FIRST(&t->s_subscriptions) == NULL) service_stop(t); return 1; } -void -subscription_unlink_service(th_subscription_t *s, int reason) -{ +void subscription_unlink_service(th_subscription_t* s, int reason) { subscription_unlink_service0(s, reason, 0); } @@ -178,37 +165,40 @@ subscription_unlink_service(th_subscription_t *s, int reason) /** * */ -static int -subscription_sort(th_subscription_t *a, th_subscription_t *b) -{ +static int subscription_sort(th_subscription_t* a, th_subscription_t* b) { return b->ths_weight - a->ths_weight; } -static void -subscription_show_none(th_subscription_t *s) -{ - char buf[256]; +static void subscription_show_none(th_subscription_t* s) { + char buf[256]; size_t l = 0; - tvh_strlcatf(buf, sizeof(buf), l, - "No input source available for subscription \"%s\"", - s->ths_title); + tvh_strlcatf(buf, + sizeof(buf), + l, + "No input source available for subscription \"%s\"", + s->ths_title); if (s->ths_channel) - tvh_strlcatf(buf, sizeof(buf), l, " to channel \"%s\"", - s->ths_channel ? - channel_get_name(s->ths_channel, channel_blank_name) : "none"); + tvh_strlcatf(buf, + sizeof(buf), + l, + " to channel \"%s\"", + s->ths_channel ? channel_get_name(s->ths_channel, channel_blank_name) : "none"); #if ENABLE_MPEGTS else if (s->ths_raw_service) { - mpegts_service_t *ms = (mpegts_service_t *)s->ths_raw_service; + mpegts_service_t* ms = (mpegts_service_t*)s->ths_raw_service; tvh_strlcatf(buf, sizeof(buf), l, " to mux \"%s\"", ms->s_dvb_mux->mm_nicename); } #endif else { - tvh_strlcatf(buf, sizeof(buf), l, " to service \"%s\"", - s->ths_service ? s->ths_service->s_nicename : "none"); + tvh_strlcatf(buf, + sizeof(buf), + l, + " to service \"%s\"", + s->ths_service ? s->ths_service->s_nicename : "none"); #if ENABLE_MPEGTS if (idnode_is_instance(&s->ths_service->s_id, &mpegts_service_class)) { - mpegts_service_t *ms = (mpegts_service_t *)s->ths_service; + mpegts_service_t* ms = (mpegts_service_t*)s->ths_service; tvh_strlcatf(buf, sizeof(buf), l, " in mux \"%s\"", ms->s_dvb_mux->mm_nicename); } #endif @@ -216,28 +206,31 @@ subscription_show_none(th_subscription_t *s) tvhnotice(LS_SUBSCRIPTION, "%04X: %s", shortid(s), buf); } -static void -subscription_show_info(th_subscription_t *s) -{ - char buf[512]; +static void subscription_show_info(th_subscription_t* s) { + char buf[512]; source_info_t si; - size_t l = 0; - int mux = 0, service = 0; + size_t l = 0; + int mux = 0, service = 0; s->ths_service->s_setsourceinfo(s->ths_service, &si); tvh_strlcatf(buf, sizeof(buf), l, "\"%s\" subscribing", s->ths_title); if (s->ths_channel) { - tvh_strlcatf(buf, sizeof(buf), l, " on channel \"%s\"", - s->ths_channel ? - channel_get_name(s->ths_channel, channel_blank_name) : "none"); + tvh_strlcatf(buf, + sizeof(buf), + l, + " on channel \"%s\"", + s->ths_channel ? channel_get_name(s->ths_channel, channel_blank_name) : "none"); #if ENABLE_MPEGTS } else if (s->ths_raw_service && si.si_mux) { tvh_strlcatf(buf, sizeof(buf), l, " to mux \"%s\"", si.si_mux); mux = 1; #endif } else { - tvh_strlcatf(buf, sizeof(buf), l, " to service \"%s\"", - s->ths_service ? s->ths_service->s_nicename : "none"); + tvh_strlcatf(buf, + sizeof(buf), + l, + " to service \"%s\"", + s->ths_service ? s->ths_service->s_nicename : "none"); service = 1; } tvh_strlcatf(buf, sizeof(buf), l, ", weight: %d", s->ths_weight); @@ -253,8 +246,7 @@ subscription_show_info(th_subscription_t *s) tvh_strlcatf(buf, sizeof(buf), l, ", service: \"%s\"", si.si_service); if (s->ths_prch && s->ths_prch->prch_pro) - tvh_strlcatf(buf, sizeof(buf), l, ", profile=\"%s\"", - profile_get_name(s->ths_prch->prch_pro)); + tvh_strlcatf(buf, sizeof(buf), l, ", profile=\"%s\"", profile_get_name(s->ths_prch->prch_pro)); if (s->ths_hostname) tvh_strlcatf(buf, sizeof(buf), l, ", hostname=\"%s\"", s->ths_hostname); @@ -267,15 +259,15 @@ subscription_show_info(th_subscription_t *s) service_source_info_free(&si); if (tvhtrace_enabled()) { - htsmsg_t *list = htsmsg_create_list(); - htsmsg_field_t *f; - const char *x; - int i = 1; + htsmsg_t* list = htsmsg_create_list(); + htsmsg_field_t* f; + const char* x; + int i = 1; s->ths_input.st_ops.st_info(s->ths_input.st_opaque, list); HTSMSG_FOREACH(f, list) - if ((x = htsmsg_field_get_str(f)) != NULL) { - tvhtrace(LS_SUBSCRIPTION, "%04X: chain %02d: %s", shortid(s), i++, x); - } + if ((x = htsmsg_field_get_str(f)) != NULL) { + tvhtrace(LS_SUBSCRIPTION, "%04X: chain %02d: %s", shortid(s), i++, x); + } htsmsg_destroy(list); } } @@ -283,20 +275,16 @@ subscription_show_info(th_subscription_t *s) /** * */ -static void -subscription_reschedule_cb(void *aux) -{ +static void subscription_reschedule_cb(void* aux) { subscription_reschedule(); } /** * */ -static void -subscription_ca_check_cb(void *aux) -{ - th_subscription_t *s = aux; - service_t *t = s->ths_service; +static void subscription_ca_check_cb(void* aux) { + th_subscription_t* s = aux; + service_t* t = s->ths_service; if (t == NULL) return; @@ -311,34 +299,38 @@ subscription_ca_check_cb(void *aux) /** * */ -void -subscription_delayed_reschedule(int64_t mono) -{ - mtimer_arm_rel(&subscription_reschedule_timer, - subscription_reschedule_cb, NULL, mono); +void subscription_delayed_reschedule(int64_t mono) { + mtimer_arm_rel(&subscription_reschedule_timer, subscription_reschedule_cb, NULL, mono); } /** * */ -static service_instance_t * -subscription_start_instance - (th_subscription_t *s, int *error) -{ - service_instance_t *si; +static service_instance_t* subscription_start_instance(th_subscription_t* s, int* error) { + service_instance_t* si; if (s->ths_channel) - tvhtrace(LS_SUBSCRIPTION, "%04X: find service for %s weight %d", - shortid(s), channel_get_name(s->ths_channel, channel_blank_name), s->ths_weight); + tvhtrace(LS_SUBSCRIPTION, + "%04X: find service for %s weight %d", + shortid(s), + channel_get_name(s->ths_channel, channel_blank_name), + s->ths_weight); else - tvhtrace(LS_SUBSCRIPTION, "%04X: find instance for %s weight %d", - shortid(s), s->ths_service->s_nicename, s->ths_weight); - si = service_find_instance(s->ths_service, s->ths_channel, - s->ths_source, s->ths_prch, - &s->ths_instances, error, s->ths_weight, - s->ths_flags, s->ths_timeout, - mclk() > s->ths_postpone_end ? - 0 : mono2sec(s->ths_postpone_end - mclk())); + tvhtrace(LS_SUBSCRIPTION, + "%04X: find instance for %s weight %d", + shortid(s), + s->ths_service->s_nicename, + s->ths_weight); + si = service_find_instance(s->ths_service, + s->ths_channel, + s->ths_source, + s->ths_prch, + &s->ths_instances, + error, + s->ths_weight, + s->ths_flags, + s->ths_timeout, + mclk() > s->ths_postpone_end ? 0 : mono2sec(s->ths_postpone_end - mclk())); if (si && (s->ths_flags & SUBSCRIPTION_CONTACCESS) == 0) mtimer_arm_rel(&s->ths_ca_check_timer, subscription_ca_check_cb, s, s->ths_ca_timeout); return s->ths_current_instance = si; @@ -347,23 +339,23 @@ subscription_start_instance /** * */ -static void -subscription_reschedule(void) -{ - static int reenter = 0; - th_subscription_t *s; - service_t *t; - service_instance_t *si; - streaming_message_t *sm; - int error, postpone = INT_MAX, postpone2; +static void subscription_reschedule(void) { + static int reenter = 0; + th_subscription_t* s; + service_t* t; + service_instance_t* si; + streaming_message_t* sm; + int error, postpone = INT_MAX, postpone2; assert(reenter == 0); reenter = 1; lock_assert(&global_lock); - LIST_FOREACH(s, &subscriptions, ths_global_link) { - if (!s->ths_service && !s->ths_channel) continue; - if (s->ths_flags & SUBSCRIPTION_ONESHOT) continue; + LIST_FOREACH (s, &subscriptions, ths_global_link) { + if (!s->ths_service && !s->ths_channel) + continue; + if (s->ths_flags & SUBSCRIPTION_ONESHOT) + continue; /* Postpone the tuner decision */ /* Leave some time to wakeup tuners through DBus or so */ @@ -377,18 +369,20 @@ subscription_reschedule(void) } t = s->ths_service; - if(t != NULL && s->ths_current_instance != NULL) { + if (t != NULL && s->ths_current_instance != NULL) { /* Already got a service */ - if(subgetstate(s) != SUBSCRIPTION_BAD_SERVICE) - continue; /* And it is not bad, so we're happy */ + if (subgetstate(s) != SUBSCRIPTION_BAD_SERVICE) + continue; /* And it is not bad, so we're happy */ - tvhwarn(LS_SUBSCRIPTION, "%04X: service instance is bad, reason: %s", - shortid(s), streaming_code2txt(s->ths_testing_error)); + tvhwarn(LS_SUBSCRIPTION, + "%04X: service instance is bad, reason: %s", + shortid(s), + streaming_code2txt(s->ths_testing_error)); tvh_mutex_lock(&t->s_stream_mutex); t->s_streaming_status = 0; - t->s_status = SERVICE_IDLE; + t->s_status = SERVICE_IDLE; tvh_mutex_unlock(&t->s_stream_mutex); si = s->ths_current_instance; @@ -405,13 +399,12 @@ subscription_reschedule(void) s->ths_last_error = 0; } - error = s->ths_testing_error; - si = subscription_start_instance(s, &error); + error = s->ths_testing_error; + si = subscription_start_instance(s, &error); s->ths_current_instance = si; - if(si == NULL) { - if (s->ths_last_error != error || - s->ths_last_find + sec2mono(2) >= mclk() || + if (si == NULL) { + if (s->ths_last_error != error || s->ths_last_find + sec2mono(2) >= mclk() || error == SM_CODE_TUNING_FAILED) { tvhtrace(LS_SUBSCRIPTION, "%04X: instance not available, retrying", shortid(s)); if (s->ths_last_error != error) @@ -421,12 +414,16 @@ subscription_reschedule(void) } if (s->ths_flags & SUBSCRIPTION_RESTART) { if (s->ths_channel) - tvhwarn(LS_SUBSCRIPTION, "%04X: restarting channel %s", - shortid(s), channel_get_name(s->ths_channel, channel_blank_name)); + tvhwarn(LS_SUBSCRIPTION, + "%04X: restarting channel %s", + shortid(s), + channel_get_name(s->ths_channel, channel_blank_name)); else - tvhwarn(LS_SUBSCRIPTION, "%04X: restarting service %s", - shortid(s), s->ths_service->s_nicename); - s->ths_testing_error = 0; + tvhwarn(LS_SUBSCRIPTION, + "%04X: restarting service %s", + shortid(s), + s->ths_service->s_nicename); + s->ths_testing_error = 0; s->ths_current_instance = NULL; service_instance_list_clear(&s->ths_instances); sm = streaming_msg_create_code(SMT_NOSTART_WARN, error); @@ -456,9 +453,7 @@ subscription_reschedule(void) /** * */ -void -subscription_set_weight(th_subscription_t *s, unsigned int weight) -{ +void subscription_set_weight(th_subscription_t* s, unsigned int weight) { lock_assert(&global_lock); s->ths_weight = weight; } @@ -466,23 +461,21 @@ subscription_set_weight(th_subscription_t *s, unsigned int weight) /** * */ -static int64_t -subscription_set_postpone(void *aux, const char *path, int64_t postpone) -{ - th_subscription_t *s; - int64_t now = mclk(); - int64_t postpone2; +static int64_t subscription_set_postpone(void* aux, const char* path, int64_t postpone) { + th_subscription_t* s; + int64_t now = mclk(); + int64_t postpone2; if (strcmp(path, "/set")) return -1; /* some limits that make sense */ - postpone = MINMAX(postpone, 0, 120); + postpone = MINMAX(postpone, 0, 120); postpone2 = sec2mono(postpone); tvh_mutex_lock(&global_lock); if (subscription_postpone != postpone) { subscription_postpone = postpone; - tvhinfo(LS_SUBSCRIPTION, "postpone set to %"PRId64" seconds", postpone); - LIST_FOREACH(s, &subscriptions, ths_global_link) { + tvhinfo(LS_SUBSCRIPTION, "postpone set to %" PRId64 " seconds", postpone); + LIST_FOREACH (s, &subscriptions, ths_global_link) { s->ths_postpone = postpone; if (s->ths_postpone_end > now && s->ths_postpone_end - now > postpone2) s->ths_postpone_end = now + postpone2; @@ -502,10 +495,8 @@ subscription_set_postpone(void *aux, const char *path, int64_t postpone) * * These require no data, though expect to receive the stop command */ -static void -subscription_input_null(void *opaque, streaming_message_t *sm) -{ - th_subscription_t *s = opaque; +static void subscription_input_null(void* opaque, streaming_message_t* sm) { + th_subscription_t* s = opaque; if (sm->sm_type == SMT_STOP && subgetstate(s) != SUBSCRIPTION_ZOMBIE) { LIST_INSERT_HEAD(&subscriptions_remove, s, ths_remove_link); subscription_delayed_reschedule(0); @@ -514,34 +505,28 @@ subscription_input_null(void *opaque, streaming_message_t *sm) streaming_msg_free(sm); } -static htsmsg_t * -subscription_input_null_info(void *opaque, htsmsg_t *list) -{ +static htsmsg_t* subscription_input_null_info(void* opaque, htsmsg_t* list) { htsmsg_add_str(list, NULL, "null input"); return list; } -static streaming_ops_t subscription_input_null_ops = { - .st_cb = subscription_input_null, - .st_info = subscription_input_null_info -}; +static streaming_ops_t subscription_input_null_ops = {.st_cb = subscription_input_null, + .st_info = subscription_input_null_info}; /** * */ -static void -subscription_input_direct(void *opauqe, streaming_message_t *sm) -{ - th_subscription_t *s = opauqe; +static void subscription_input_direct(void* opauqe, streaming_message_t* sm) { + th_subscription_t* s = opauqe; /* Log data and errors */ - if(sm->sm_type == SMT_PACKET) { - th_pkt_t *pkt = sm->sm_data; + if (sm->sm_type == SMT_PACKET) { + th_pkt_t* pkt = sm->sm_data; atomic_add(&s->ths_total_err, pkt->pkt_err); if (pkt->pkt_payload) subscription_add_bytes_in(s, pktbuf_len(pkt->pkt_payload)); - } else if(sm->sm_type == SMT_MPEGTS) { - pktbuf_t *pb = sm->sm_data; + } else if (sm->sm_type == SMT_MPEGTS) { + pktbuf_t* pb = sm->sm_data; atomic_add(&s->ths_total_err, pb->pb_err); subscription_add_bytes_in(s, pktbuf_len(pb)); } @@ -550,50 +535,42 @@ subscription_input_direct(void *opauqe, streaming_message_t *sm) streaming_target_deliver(s->ths_output, sm); } -static htsmsg_t * -subscription_input_direct_info(void *opaque, htsmsg_t *list) -{ +static htsmsg_t* subscription_input_direct_info(void* opaque, htsmsg_t* list) { htsmsg_add_str(list, NULL, "direct input"); return list; } -static streaming_ops_t subscription_input_direct_ops = { - .st_cb = subscription_input_direct, - .st_info = subscription_input_direct_info -}; +static streaming_ops_t subscription_input_direct_ops = {.st_cb = subscription_input_direct, + .st_info = subscription_input_direct_info}; /** * This callback is invoked when we receive data and status updates from * the currently bound service */ -static void -subscription_input(void *opaque, streaming_message_t *sm) -{ - int error; - th_subscription_t *s = opaque; +static void subscription_input(void* opaque, streaming_message_t* sm) { + int error; + th_subscription_t* s = opaque; - if(subgetstate(s) == SUBSCRIPTION_TESTING_SERVICE) { + if (subgetstate(s) == SUBSCRIPTION_TESTING_SERVICE) { // We are just testing if this service is good - if(sm->sm_type == SMT_GRACE) { + if (sm->sm_type == SMT_GRACE) { streaming_target_deliver(s->ths_output, sm); return; } - if(sm->sm_type == SMT_START) { + if (sm->sm_type == SMT_START) { streaming_msg_free(s->ths_start_message); s->ths_start_message = sm; return; } - if(sm->sm_type == SMT_SERVICE_STATUS && - (sm->sm_code & (TSS_ERRORS|TSS_CA_CHECK))) { + if (sm->sm_type == SMT_SERVICE_STATUS && (sm->sm_code & (TSS_ERRORS | TSS_CA_CHECK))) { // No, mark our subscription as bad_service // the scheduler will take care of things error = tss2errcode(sm->sm_code); if (error != SM_CODE_OK) - if (error != SM_CODE_NO_ACCESS || - (s->ths_flags & SUBSCRIPTION_CONTACCESS) == 0) { + if (error != SM_CODE_NO_ACCESS || (s->ths_flags & SUBSCRIPTION_CONTACCESS) == 0) { if (error > s->ths_testing_error) s->ths_testing_error = error; subsetstate(s, SUBSCRIPTION_BAD_SERVICE); @@ -602,9 +579,8 @@ subscription_input(void *opaque, streaming_message_t *sm) } } - if(sm->sm_type == SMT_SERVICE_STATUS && - (sm->sm_code & TSS_PACKETS)) { - if(s->ths_start_message != NULL) { + if (sm->sm_type == SMT_SERVICE_STATUS && (sm->sm_code & TSS_PACKETS)) { + if (s->ths_start_message != NULL) { streaming_target_deliver(s->ths_output, s->ths_start_message); s->ths_start_message = NULL; if (s->ths_service) @@ -614,17 +590,16 @@ subscription_input(void *opaque, streaming_message_t *sm) } } - if(subgetstate(s) != SUBSCRIPTION_GOT_SERVICE) { + if (subgetstate(s) != SUBSCRIPTION_GOT_SERVICE) { streaming_msg_free(sm); return; } if (sm->sm_type == SMT_SERVICE_STATUS && - (sm->sm_code & (TSS_TUNING|TSS_TIMEOUT|TSS_NO_DESCRAMBLER|TSS_CA_CHECK))) { + (sm->sm_code & (TSS_TUNING | TSS_TIMEOUT | TSS_NO_DESCRAMBLER | TSS_CA_CHECK))) { error = tss2errcode(sm->sm_code); if (error != SM_CODE_OK) - if (error != SM_CODE_NO_ACCESS || - (s->ths_flags & SUBSCRIPTION_CONTACCESS) == 0) { + if (error != SM_CODE_NO_ACCESS || (s->ths_flags & SUBSCRIPTION_CONTACCESS) == 0) { if (error > s->ths_testing_error) s->ths_testing_error = error; s->ths_state = SUBSCRIPTION_BAD_SERVICE; @@ -635,20 +610,15 @@ subscription_input(void *opaque, streaming_message_t *sm) subscription_input_direct(s, sm); } -static htsmsg_t * -subscription_input_info(void *opaque, htsmsg_t *list) -{ - th_subscription_t *s = opaque; - streaming_target_t *st = s->ths_output; +static htsmsg_t* subscription_input_info(void* opaque, htsmsg_t* list) { + th_subscription_t* s = opaque; + streaming_target_t* st = s->ths_output; htsmsg_add_str(list, NULL, "input"); return st->st_ops.st_info(st->st_opaque, list); } -static streaming_ops_t subscription_input_ops = { - .st_cb = subscription_input, - .st_info = subscription_input_info -}; - +static streaming_ops_t subscription_input_ops = {.st_cb = subscription_input, + .st_info = subscription_input_info}; /* ************************************************************************** * Destroy subscriptions @@ -657,19 +627,15 @@ static streaming_ops_t subscription_input_ops = { /** * Delete */ -static void -subscription_unsubscribe_cb(void *aux) -{ - subscription_unsubscribe((th_subscription_t *)aux, UNSUBSCRIBE_FINAL); +static void subscription_unsubscribe_cb(void* aux) { + subscription_unsubscribe((th_subscription_t*)aux, UNSUBSCRIBE_FINAL); } -static void -subscription_destroy(th_subscription_t *s) -{ +static void subscription_destroy(th_subscription_t* s) { streaming_msg_free(s->ths_start_message); - if(s->ths_output->st_ops.st_cb == subscription_input_null) - free(s->ths_output); + if (s->ths_output->st_ops.st_cb == subscription_input_null) + free(s->ths_output); free(s->ths_title); free(s->ths_hostname); @@ -677,16 +643,13 @@ subscription_destroy(th_subscription_t *s) free(s->ths_client); free(s->ths_dvrfile); free(s); - } -void -subscription_unsubscribe(th_subscription_t *s, int flags) -{ - service_t *t; - char buf[512]; - size_t l = 0; - service_t *raw; +void subscription_unsubscribe(th_subscription_t* s, int flags) { + service_t* t; + char buf[512]; + size_t l = 0; + service_t* raw; if (s == NULL) return; @@ -717,8 +680,12 @@ subscription_unsubscribe(th_subscription_t *s, int flags) if (s->ths_channel != NULL) { LIST_REMOVE(s, ths_channel_link); - tvh_strlcatf(buf, sizeof(buf), l, "\"%s\" unsubscribing from \"%s\"", - s->ths_title, channel_get_name(s->ths_channel, channel_blank_name)); + tvh_strlcatf(buf, + sizeof(buf), + l, + "\"%s\" unsubscribing from \"%s\"", + s->ths_title, + channel_get_name(s->ths_channel, channel_blank_name)); } else { tvh_strlcatf(buf, sizeof(buf), l, "\"%s\" unsubscribing", s->ths_title); } @@ -730,7 +697,10 @@ subscription_unsubscribe(th_subscription_t *s, int flags) if (s->ths_client) tvh_strlcatf(buf, sizeof(buf), l, ", client=\"%s\"", s->ths_client); tvhlog((flags & UNSUBSCRIBE_QUIET) != 0 ? LOG_TRACE : LOG_INFO, - LS_SUBSCRIPTION, "%04X: %s", shortid(s), buf); + LS_SUBSCRIPTION, + "%04X: %s", + shortid(s), + buf); if (t) service_remove_subscriber(t, s, SM_CODE_OK); @@ -745,8 +715,7 @@ subscription_unsubscribe(th_subscription_t *s, int flags) s->ths_parser = NULL; } - if ((flags & UNSUBSCRIBE_FINAL) != 0 || - (s->ths_flags & SUBSCRIPTION_ONESHOT) != 0) + if ((flags & UNSUBSCRIBE_FINAL) != 0 || (s->ths_flags & SUBSCRIPTION_ONESHOT) != 0) subscription_destroy(s); subscription_delayed_reschedule(0); @@ -760,20 +729,23 @@ subscription_unsubscribe(th_subscription_t *s, int flags) /* * Generic handler for all susbcription creation */ -th_subscription_t * -subscription_create - (profile_chain_t *prch, int weight, const char *name, - int flags, streaming_ops_t *ops, const char *hostname, - const char *username, const char *client) -{ - th_subscription_t *s = calloc(1, sizeof(th_subscription_t)); - profile_t *pro = prch ? prch->prch_pro : NULL; - streaming_target_t *st = prch ? prch->prch_st : NULL; - static int tally; +th_subscription_t* subscription_create(profile_chain_t* prch, + int weight, + const char* name, + int flags, + streaming_ops_t* ops, + const char* hostname, + const char* username, + const char* client) { + th_subscription_t* s = calloc(1, sizeof(th_subscription_t)); + profile_t* pro = prch ? prch->prch_pro : NULL; + streaming_target_t* st = prch ? prch->prch_st : NULL; + static int tally; TAILQ_INIT(&s->ths_instances); - if (!ops) ops = &subscription_input_direct_ops; + if (!ops) + ops = &subscription_input_direct_ops; if (!st) { st = calloc(1, sizeof(streaming_target_t)); streaming_target_init(st, &subscription_input_null_ops, s, 0); @@ -781,17 +753,17 @@ subscription_create streaming_target_init(&s->ths_input, ops, s, 0); - s->ths_prch = prch && prch->prch_st ? prch : NULL; - s->ths_title = strdup(name); - s->ths_hostname = hostname ? strdup(hostname) : NULL; - s->ths_username = username ? strdup(username) : NULL; - s->ths_client = client ? strdup(client) : NULL; - s->ths_output = st; - s->ths_flags = flags; - s->ths_timeout = pro ? pro->pro_timeout : 0; - s->ths_ca_timeout = sec2mono(2); - s->ths_postpone = subscription_postpone; - s->ths_postpone_end = mclk() + sec2mono(s->ths_postpone); + s->ths_prch = prch && prch->prch_st ? prch : NULL; + s->ths_title = strdup(name); + s->ths_hostname = hostname ? strdup(hostname) : NULL; + s->ths_username = username ? strdup(username) : NULL; + s->ths_client = client ? strdup(client) : NULL; + s->ths_output = st; + s->ths_flags = flags; + s->ths_timeout = pro ? pro->pro_timeout : 0; + s->ths_ca_timeout = sec2mono(2); + s->ths_postpone = subscription_postpone; + s->ths_postpone_end = mclk() + sec2mono(s->ths_postpone); atomic_set(&s->ths_total_err, 0); if (s->ths_prch) @@ -825,22 +797,20 @@ subscription_create /** * */ -static th_subscription_t * -subscription_create_from_channel_or_service(profile_chain_t *prch, - tvh_input_t *ti, - unsigned int weight, - const char *name, - int flags, - const char *hostname, - const char *username, - const char *client, - int *error, - service_t *service) -{ - th_subscription_t *s; - service_instance_t *si; - channel_t *ch = NULL; - int _error; +static th_subscription_t* subscription_create_from_channel_or_service(profile_chain_t* prch, + tvh_input_t* ti, + unsigned int weight, + const char* name, + int flags, + const char* hostname, + const char* username, + const char* client, + int* error, + service_t* service) { + th_subscription_t* s; + service_instance_t* si; + channel_t* ch = NULL; + int _error; assert(prch); assert(prch->prch_id); @@ -852,16 +822,30 @@ subscription_create_from_channel_or_service(profile_chain_t *prch, if (!service) ch = prch->prch_id; - s = subscription_create(prch, weight, name, flags, &subscription_input_ops, - hostname, username, client); + s = subscription_create(prch, + weight, + name, + flags, + &subscription_input_ops, + hostname, + username, + client); if (tvhtrace_enabled()) { - const char *pro_name = prch->prch_pro ? profile_get_name(prch->prch_pro) : ""; + const char* pro_name = prch->prch_pro ? profile_get_name(prch->prch_pro) : ""; if (ch) - tvhtrace(LS_SUBSCRIPTION, "%04X: creating subscription for %s weight %d using profile %s", - shortid(s), channel_get_name(ch, channel_blank_name), weight, pro_name); + tvhtrace(LS_SUBSCRIPTION, + "%04X: creating subscription for %s weight %d using profile %s", + shortid(s), + channel_get_name(ch, channel_blank_name), + weight, + pro_name); else - tvhtrace(LS_SUBSCRIPTION, "%04X: creating subscription for service %s weight %d using profile %s", - shortid(s), service->s_nicename, weight, pro_name); + tvhtrace(LS_SUBSCRIPTION, + "%04X: creating subscription for service %s weight %d using profile %s", + shortid(s), + service->s_nicename, + weight, + pro_name); } s->ths_channel = ch; s->ths_service = service; @@ -871,7 +855,7 @@ subscription_create_from_channel_or_service(profile_chain_t *prch, #if ENABLE_MPEGTS if (service && service->s_type == STYPE_RAW) { - mpegts_mux_t *mm = prch->prch_id; + mpegts_mux_t* mm = prch->prch_id; s->ths_raw_service = service; LIST_INSERT_HEAD(&mm->mm_raw_subs, s, ths_mux_link); } @@ -890,93 +874,104 @@ subscription_create_from_channel_or_service(profile_chain_t *prch, return s; } -th_subscription_t * -subscription_create_from_channel(profile_chain_t *prch, - tvh_input_t *ti, - unsigned int weight, - const char *name, - int flags, - const char *hostname, - const char *username, - const char *client, - int *error) -{ +th_subscription_t* subscription_create_from_channel(profile_chain_t* prch, + tvh_input_t* ti, + unsigned int weight, + const char* name, + int flags, + const char* hostname, + const char* username, + const char* client, + int* error) { assert(flags == SUBSCRIPTION_NONE || prch->prch_st); - return subscription_create_from_channel_or_service - (prch, ti, weight, name, flags, hostname, username, client, - error, NULL); + return subscription_create_from_channel_or_service(prch, + ti, + weight, + name, + flags, + hostname, + username, + client, + error, + NULL); } /** * */ -th_subscription_t * -subscription_create_from_service(profile_chain_t *prch, - tvh_input_t *ti, - unsigned int weight, - const char *name, - int flags, - const char *hostname, - const char *username, - const char *client, - int *error) -{ +th_subscription_t* subscription_create_from_service(profile_chain_t* prch, + tvh_input_t* ti, + unsigned int weight, + const char* name, + int flags, + const char* hostname, + const char* username, + const char* client, + int* error) { assert(flags == SUBSCRIPTION_NONE || prch->prch_st); - return subscription_create_from_channel_or_service - (prch, ti, weight, name, flags, hostname, username, client, - error, prch->prch_id); + return subscription_create_from_channel_or_service(prch, + ti, + weight, + name, + flags, + hostname, + username, + client, + error, + prch->prch_id); } /** * */ #if ENABLE_MPEGTS -th_subscription_t * -subscription_create_from_mux(profile_chain_t *prch, - tvh_input_t *ti, - unsigned int weight, - const char *name, - int flags, - const char *hostname, - const char *username, - const char *client, - int *error) -{ - mpegts_mux_t *mm = prch->prch_id; - mpegts_service_t *s = mpegts_service_create_raw(mm); +th_subscription_t* subscription_create_from_mux(profile_chain_t* prch, + tvh_input_t* ti, + unsigned int weight, + const char* name, + int flags, + const char* hostname, + const char* username, + const char* client, + int* error) { + mpegts_mux_t* mm = prch->prch_id; + mpegts_service_t* s = mpegts_service_create_raw(mm); if (!s) return NULL; - return subscription_create_from_channel_or_service - (prch, ti, weight, name, flags, hostname, username, client, - error, (service_t *)s); + return subscription_create_from_channel_or_service(prch, + ti, + weight, + name, + flags, + hostname, + username, + client, + error, + (service_t*)s); } #endif /** * */ -th_subscription_t * -subscription_create_from_file(const char *name, - const char *charset, - const char *filename, - const char *hostname, - const char *username, - const char *client) -{ - th_subscription_t *ts; - char *str, *url; - - ts = subscription_create(NULL, 1, name, - SUBSCRIPTION_NONE, NULL, - hostname, username, client); +th_subscription_t* subscription_create_from_file(const char* name, + const char* charset, + const char* filename, + const char* hostname, + const char* username, + const char* client) { + th_subscription_t* ts; + char * str, *url; + + ts = subscription_create(NULL, 1, name, SUBSCRIPTION_NONE, NULL, hostname, username, client); if (ts == NULL) return NULL; str = intlconv_to_utf8safestr(charset, filename, strlen(filename) * 3); if (str == NULL) - str = intlconv_to_utf8safestr(intlconv_charset_id("ASCII", 1, 1), - filename, strlen(filename) * 3); + str = + intlconv_to_utf8safestr(intlconv_charset_id("ASCII", 1, 1), filename, strlen(filename) * 3); if (str == NULL) str = strdup("error"); url = malloc(strlen(str) + 7 + 1); @@ -996,38 +991,36 @@ static mtimer_t subscription_status_timer; /* * Serialize info about subscription */ -htsmsg_t * -subscription_create_msg(th_subscription_t *s, const char *lang) -{ - htsmsg_t *m = htsmsg_create_map(); - descramble_info_t *di; - service_t *t; - profile_t *pro; - char buf[284]; - const char *state; - htsmsg_t *l; - mpegts_apids_t *pids = NULL; +htsmsg_t* subscription_create_msg(th_subscription_t* s, const char* lang) { + htsmsg_t* m = htsmsg_create_map(); + descramble_info_t* di; + service_t* t; + profile_t* pro; + char buf[284]; + const char* state; + htsmsg_t* l; + mpegts_apids_t* pids = NULL; htsmsg_add_u32(m, "id", s->ths_id); htsmsg_add_u32(m, "start", s->ths_start); htsmsg_add_u32(m, "errors", atomic_get(&s->ths_total_err)); - switch(subgetstate(s)) { - default: - state = N_("Idle"); - break; - - case SUBSCRIPTION_TESTING_SERVICE: - state = N_("Testing"); - break; - - case SUBSCRIPTION_GOT_SERVICE: - state = N_("Running"); - break; - - case SUBSCRIPTION_BAD_SERVICE: - state = N_("Bad"); - break; + switch (subgetstate(s)) { + default: + state = N_("Idle"); + break; + + case SUBSCRIPTION_TESTING_SERVICE: + state = N_("Testing"); + break; + + case SUBSCRIPTION_GOT_SERVICE: + state = N_("Running"); + break; + + case SUBSCRIPTION_BAD_SERVICE: + state = N_("Bad"); + break; } htsmsg_add_str(m, "state", lang ? tvh_gettext_lang(lang, state) : state); @@ -1043,10 +1036,12 @@ subscription_create_msg(th_subscription_t *s, const char *lang) if (s->ths_title != NULL) htsmsg_add_str(m, "title", s->ths_title); - + if (s->ths_channel != NULL) - htsmsg_add_str(m, "channel", channel_get_name(s->ths_channel, tvh_gettext_lang(lang, channel_blank_name))); - + htsmsg_add_str(m, + "channel", + channel_get_name(s->ths_channel, tvh_gettext_lang(lang, channel_blank_name))); + if ((t = s->ths_service) != NULL) { htsmsg_add_str(m, "service", service_adapter_nicename(t, buf, sizeof(buf))); @@ -1055,9 +1050,15 @@ subscription_create_msg(th_subscription_t *s, const char *lang) if (di->caid == 0 && di->ecmtime == 0) { snprintf(buf, sizeof(buf), N_("Failed")); } else { - snprintf(buf, sizeof(buf), "%04X:%06X(%ums)-%s%s%s", - di->caid, di->provid, di->ecmtime, di->from, - di->reader[0] ? "/" : "", di->reader); + snprintf(buf, + sizeof(buf), + "%04X:%06X(%ums)-%s%s%s", + di->caid, + di->provid, + di->ecmtime, + di->from, + di->reader[0] ? "/" : "", + di->reader); } htsmsg_add_str(m, "descramble", buf); } @@ -1083,8 +1084,7 @@ subscription_create_msg(th_subscription_t *s, const char *lang) if (s->ths_prch != NULL) { pro = s->ths_prch->prch_pro; if (pro) - htsmsg_add_str(m, "profile", - idnode_get_title(&pro->pro_id, lang, buf, sizeof(buf))); + htsmsg_add_str(m, "profile", idnode_get_title(&pro->pro_id, lang, buf, sizeof(buf))); } } else if (s->ths_dvrfile != NULL) { @@ -1102,27 +1102,24 @@ subscription_create_msg(th_subscription_t *s, const char *lang) /** * Check status (bandwidth, errors, etc.) */ -static void -subscription_status_callback ( void *p ) -{ - th_subscription_t *s; - int64_t count = 0; - static int64_t old_count = -1; +static void subscription_status_callback(void* p) { + th_subscription_t* s; + int64_t count = 0; + static int64_t old_count = -1; - mtimer_arm_rel(&subscription_status_timer, - subscription_status_callback, NULL, sec2mono(1)); + mtimer_arm_rel(&subscription_status_timer, subscription_status_callback, NULL, sec2mono(1)); - LIST_FOREACH(s, &subscriptions, ths_global_link) { + LIST_FOREACH (s, &subscriptions, ths_global_link) { /* Store the difference between total bytes from the last round */ - uint64_t in_curr = atomic_get_u64(&s->ths_total_bytes_in); - uint64_t in_prev = atomic_exchange_u64(&s->ths_total_bytes_in_prev, in_curr); + uint64_t in_curr = atomic_get_u64(&s->ths_total_bytes_in); + uint64_t in_prev = atomic_exchange_u64(&s->ths_total_bytes_in_prev, in_curr); uint64_t out_curr = atomic_get_u64(&s->ths_total_bytes_out); uint64_t out_prev = atomic_exchange_u64(&s->ths_total_bytes_out_prev, out_curr); atomic_set(&s->ths_bytes_in_avg, (int)(in_curr - in_prev)); atomic_set(&s->ths_bytes_out_avg, (int)(out_curr - out_prev)); - htsmsg_t *m = subscription_create_msg(s, NULL); + htsmsg_t* m = subscription_create_msg(s, NULL); htsmsg_add_u32(m, "updateEntry", 1); notify_by_msg("subscriptions", m, 1, NOTIFY_REWRITE_SUBSCRIPTIONS); count++; @@ -1136,9 +1133,7 @@ subscription_status_callback ( void *p ) /** * Initialise subsystem */ -void -subscription_init(void) -{ +void subscription_init(void) { subscription_status_callback(NULL); dbus_register_rpc_s64("postpone", NULL, subscription_set_postpone); } @@ -1146,9 +1141,7 @@ subscription_init(void) /** * Shutdown subsystem */ -void -subscription_done(void) -{ +void subscription_done(void) { tvh_mutex_lock(&global_lock); mtimer_disarm(&subscription_status_timer); /* clear remaining subscriptions */ @@ -1164,26 +1157,22 @@ subscription_done(void) /** * Update incoming byte count */ -void subscription_add_bytes_in(th_subscription_t *s, size_t in) -{ +void subscription_add_bytes_in(th_subscription_t* s, size_t in) { atomic_add_u64(&s->ths_total_bytes_in, in); } /** * Update outgoing byte count */ -void subscription_add_bytes_out(th_subscription_t *s, size_t out) -{ +void subscription_add_bytes_out(th_subscription_t* s, size_t out) { atomic_add_u64(&s->ths_total_bytes_out, out); } /** * Change weight */ -void -subscription_change_weight(th_subscription_t *s, int weight) -{ - if(s->ths_weight == weight) +void subscription_change_weight(th_subscription_t* s, int weight) { + if (s->ths_weight == weight) return; LIST_REMOVE(s, ths_global_link); @@ -1201,13 +1190,12 @@ subscription_change_weight(th_subscription_t *s, int weight) /** * Set speed */ -void -subscription_set_speed ( th_subscription_t *s, int speed ) -{ - streaming_message_t *sm; - service_t *t = s->ths_service; +void subscription_set_speed(th_subscription_t* s, int speed) { + streaming_message_t* sm; + service_t* t = s->ths_service; - if (!t) return; + if (!t) + return; tvh_mutex_lock(&t->s_stream_mutex); @@ -1221,17 +1209,16 @@ subscription_set_speed ( th_subscription_t *s, int speed ) /** * Set skip */ -void -subscription_set_skip ( th_subscription_t *s, const streaming_skip_t *skip ) -{ - streaming_message_t *sm; - service_t *t = s->ths_service; +void subscription_set_skip(th_subscription_t* s, const streaming_skip_t* skip) { + streaming_message_t* sm; + service_t* t = s->ths_service; - if (!t) return; + if (!t) + return; tvh_mutex_lock(&t->s_stream_mutex); - sm = streaming_msg_create(SMT_SKIP); + sm = streaming_msg_create(SMT_SKIP); sm->sm_data = malloc(sizeof(streaming_skip_t)); memcpy(sm->sm_data, skip, sizeof(streaming_skip_t)); @@ -1247,47 +1234,37 @@ subscription_set_skip ( th_subscription_t *s, const streaming_skip_t *skip ) /** * */ -static void -dummy_callback(void *opauqe, streaming_message_t *sm) -{ - switch(sm->sm_type) { - case SMT_START: - fprintf(stderr, "dummysubscription START\n"); - break; - case SMT_STOP: - fprintf(stderr, "dummysubscription STOP\n"); - break; - - case SMT_SERVICE_STATUS: - fprintf(stderr, "dummsubscription: %x\n", sm->sm_code); - break; - default: - break; +static void dummy_callback(void* opauqe, streaming_message_t* sm) { + switch (sm->sm_type) { + case SMT_START: + fprintf(stderr, "dummysubscription START\n"); + break; + case SMT_STOP: + fprintf(stderr, "dummysubscription STOP\n"); + break; + + case SMT_SERVICE_STATUS: + fprintf(stderr, "dummsubscription: %x\n", sm->sm_code); + break; + default: + break; } streaming_msg_free(sm); } -static htsmsg_t * -dummy_info(void *opaque, htsmsg_t *list) -{ +static htsmsg_t* dummy_info(void* opaque, htsmsg_t* list) { htsmsg_add_str(list, NULL, "null input"); return list; } -static streaming_ops_t dummy_ops = { - .st_cb = dummy_callback, - .st_info = dummy_info -}; - +static streaming_ops_t dummy_ops = {.st_cb = dummy_callback, .st_info = dummy_info}; static mtimer_t dummy_sub_timer; /** * */ -static void -dummy_retry(void *opaque) -{ +static void dummy_retry(void* opaque) { subscription_dummy_join(opaque, 0); free(opaque); } @@ -1295,30 +1272,27 @@ dummy_retry(void *opaque) /** * */ -void -subscription_dummy_join(const char *id, int first) -{ - service_t *t = service_find_by_uuid(id); - profile_chain_t *prch; - streaming_target_t *st; - th_subscription_t *s; - - if(first) { +void subscription_dummy_join(const char* id, int first) { + service_t* t = service_find_by_uuid(id); + profile_chain_t* prch; + streaming_target_t* st; + th_subscription_t* s; + + if (first) { mtimer_arm_rel(&dummy_sub_timer, dummy_retry, strdup(id), sec2mono(2)); return; } - if(t == NULL) { - tvherror(LS_SUBSCRIPTION, - "Unable to dummy join %s, service not found, retrying...", id); + if (t == NULL) { + tvherror(LS_SUBSCRIPTION, "Unable to dummy join %s, service not found, retrying...", id); mtimer_arm_rel(&dummy_sub_timer, dummy_retry, strdup(id), sec2mono(1)); return; } - prch = calloc(1, sizeof(*prch)); + prch = calloc(1, sizeof(*prch)); prch->prch_id = t; - st = calloc(1, sizeof(*st)); + st = calloc(1, sizeof(*st)); streaming_target_init(st, &dummy_ops, NULL, 0); prch->prch_st = st; s = subscription_create_from_service(prch, NULL, 1, "dummy", 0, NULL, NULL, "dummy", NULL); diff --git a/src/subscriptions.h b/src/subscriptions.h index 1416f3747..6615e72d6 100644 --- a/src/subscriptions.h +++ b/src/subscriptions.h @@ -25,38 +25,38 @@ struct profile_chain; extern struct th_subscription_list subscriptions; -#define SUBSCRIPTION_NONE 0x000 -#define SUBSCRIPTION_MPEGTS 0x001 -#define SUBSCRIPTION_PACKET 0x002 -#define SUBSCRIPTION_TYPE_MASK 0x00f -#define SUBSCRIPTION_STREAMING 0x010 -#define SUBSCRIPTION_RESTART 0x020 -#define SUBSCRIPTION_CONTACCESS 0x040 -#define SUBSCRIPTION_ONESHOT 0x080 -#define SUBSCRIPTION_TABLES 0x100 -#define SUBSCRIPTION_MINIMAL 0x200 -#define SUBSCRIPTION_NODESCR 0x400 ///< no decramble -#define SUBSCRIPTION_EMM 0x800 ///< add EMM PIDs for no descramble subscription +#define SUBSCRIPTION_NONE 0x000 +#define SUBSCRIPTION_MPEGTS 0x001 +#define SUBSCRIPTION_PACKET 0x002 +#define SUBSCRIPTION_TYPE_MASK 0x00f +#define SUBSCRIPTION_STREAMING 0x010 +#define SUBSCRIPTION_RESTART 0x020 +#define SUBSCRIPTION_CONTACCESS 0x040 +#define SUBSCRIPTION_ONESHOT 0x080 +#define SUBSCRIPTION_TABLES 0x100 +#define SUBSCRIPTION_MINIMAL 0x200 +#define SUBSCRIPTION_NODESCR 0x400 ///< no decramble +#define SUBSCRIPTION_EMM 0x800 ///< add EMM PIDs for no descramble subscription #define SUBSCRIPTION_INITSCAN 0x1000 ///< for mux subscriptions #define SUBSCRIPTION_IDLESCAN 0x2000 ///< for mux subscriptions #define SUBSCRIPTION_USERSCAN 0x4000 ///< for mux subscriptions #define SUBSCRIPTION_EPG 0x8000 ///< for mux subscriptions -#define SUBSCRIPTION_HTSP 0x10000 -#define SUBSCRIPTION_SWSERVICE 0x20000 +#define SUBSCRIPTION_HTSP 0x10000 +#define SUBSCRIPTION_SWSERVICE 0x20000 /* Some internal priorities */ -#define SUBSCRIPTION_PRIO_KEEP 1 ///< Keep input rolling -#define SUBSCRIPTION_PRIO_SCAN_IDLE 2 ///< Idle scanning -#define SUBSCRIPTION_PRIO_SCAN_SCHED 3 ///< Scheduled scan -#define SUBSCRIPTION_PRIO_EPG 4 ///< EPG scanner -#define SUBSCRIPTION_PRIO_SCAN_INIT 5 ///< Initial scan -#define SUBSCRIPTION_PRIO_SCAN_USER 6 ///< User defined scan -#define SUBSCRIPTION_PRIO_MAPPER 7 ///< Channel mapper +#define SUBSCRIPTION_PRIO_KEEP 1 ///< Keep input rolling +#define SUBSCRIPTION_PRIO_SCAN_IDLE 2 ///< Idle scanning +#define SUBSCRIPTION_PRIO_SCAN_SCHED 3 ///< Scheduled scan +#define SUBSCRIPTION_PRIO_EPG 4 ///< EPG scanner +#define SUBSCRIPTION_PRIO_SCAN_INIT 5 ///< Initial scan +#define SUBSCRIPTION_PRIO_SCAN_USER 6 ///< User defined scan +#define SUBSCRIPTION_PRIO_MAPPER 7 ///< Channel mapper #define SUBSCRIPTION_PRIO_MIN 10 ///< User defined / Normal levels /* Unsubscribe flags */ -#define UNSUBSCRIBE_QUIET 0x01 -#define UNSUBSCRIBE_FINAL 0x02 +#define UNSUBSCRIBE_QUIET 0x01 +#define UNSUBSCRIBE_FINAL 0x02 /* States */ typedef enum { @@ -70,11 +70,11 @@ typedef enum { typedef struct th_subscription { int ths_id; - + LIST_ENTRY(th_subscription) ths_global_link; LIST_ENTRY(th_subscription) ths_remove_link; - struct profile_chain *ths_prch; + struct profile_chain* ths_prch; int ths_weight; @@ -86,50 +86,51 @@ typedef struct th_subscription { mtimer_t ths_ca_check_timer; LIST_ENTRY(th_subscription) ths_channel_link; - struct channel *ths_channel; /* May be NULL if channel has been - destroyed during the - subscription */ + struct channel* ths_channel; /* May be NULL if channel has been + destroyed during the + subscription */ LIST_ENTRY(th_subscription) ths_service_link; - struct service *ths_service; /* if NULL, ths_service_link - is not linked */ + struct service* ths_service; /* if NULL, ths_service_link + is not linked */ - struct tvh_input *ths_source; /* if NULL, all sources are allowed */ + struct tvh_input* ths_source; /* if NULL, all sources are allowed */ - char *ths_title; /* display title */ - time_t ths_start; /* time when subscription started */ - int ths_total_err; /* total errors during entire subscription */ - uint64_t ths_total_bytes_in; /* total bytes since the subscription started */ - uint64_t ths_total_bytes_out; /* total bytes since the subscription started */ + char* ths_title; /* display title */ + time_t ths_start; /* time when subscription started */ + int ths_total_err; /* total errors during entire subscription */ + uint64_t ths_total_bytes_in; /* total bytes since the subscription started */ + uint64_t ths_total_bytes_out; /* total bytes since the subscription started */ uint64_t ths_total_bytes_in_prev; /* total bytes since the subscription started, minus 1 second */ - uint64_t ths_total_bytes_out_prev; /* total bytes since the subscription started, minus 1 second */ - int ths_bytes_in_avg; /* Average bytes in per second */ - int ths_bytes_out_avg; /* Average bytes out per second */ + uint64_t + ths_total_bytes_out_prev; /* total bytes since the subscription started, minus 1 second */ + int ths_bytes_in_avg; /* Average bytes in per second */ + int ths_bytes_out_avg; /* Average bytes out per second */ streaming_target_t ths_input; - streaming_target_t *ths_output; - streaming_target_t *ths_parser; + streaming_target_t* ths_output; + streaming_target_t* ths_parser; int ths_flags; int ths_timeout; int ths_ca_timeout; int64_t ths_last_find; - int ths_last_error; + int ths_last_error; - streaming_message_t *ths_start_message; + streaming_message_t* ths_start_message; - char *ths_hostname; - char *ths_username; - char *ths_client; - char *ths_dvrfile; + char* ths_hostname; + char* ths_username; + char* ths_client; + char* ths_dvrfile; /** * This is the list of service candidates we have */ - service_instance_list_t ths_instances; - struct service_instance *ths_current_instance; + service_instance_list_t ths_instances; + struct service_instance* ths_current_instance; /** * Postpone @@ -141,7 +142,7 @@ typedef struct th_subscription { * MPEG-TS mux chain */ #if ENABLE_MPEGTS - service_t *ths_raw_service; + service_t* ths_raw_service; LIST_ENTRY(th_subscription) ths_mux_link; #endif @@ -156,87 +157,82 @@ void subscription_init(void); void subscription_done(void); -void subscription_unsubscribe(th_subscription_t *s, int flags); +void subscription_unsubscribe(th_subscription_t* s, int flags); -void subscription_set_weight(th_subscription_t *s, unsigned int weight); +void subscription_set_weight(th_subscription_t* s, unsigned int weight); void subscription_delayed_reschedule(int64_t mono); -th_subscription_t * -subscription_create_from_channel(struct profile_chain *prch, - struct tvh_input *ti, - unsigned int weight, - const char *name, - int flags, - const char *hostname, - const char *username, - const char *client, - int *error); - - -th_subscription_t * -subscription_create_from_service(struct profile_chain *prch, - struct tvh_input *ti, - unsigned int weight, - const char *name, - int flags, - const char *hostname, - const char *username, - const char *client, - int *error); +th_subscription_t* subscription_create_from_channel(struct profile_chain* prch, + struct tvh_input* ti, + unsigned int weight, + const char* name, + int flags, + const char* hostname, + const char* username, + const char* client, + int* error); + +th_subscription_t* subscription_create_from_service(struct profile_chain* prch, + struct tvh_input* ti, + unsigned int weight, + const char* name, + int flags, + const char* hostname, + const char* username, + const char* client, + int* error); #if ENABLE_MPEGTS struct tvh_input; -th_subscription_t * -subscription_create_from_mux(struct profile_chain *prch, - struct tvh_input *ti, - unsigned int weight, - const char *name, - int flags, - const char *hostname, - const char *username, - const char *client, - int *error); +th_subscription_t* subscription_create_from_mux(struct profile_chain* prch, + struct tvh_input* ti, + unsigned int weight, + const char* name, + int flags, + const char* hostname, + const char* username, + const char* client, + int* error); #endif -th_subscription_t * -subscription_create_from_file(const char *name, - const char *charset, - const char *filename, - const char *hostname, - const char *username, - const char *client); - -th_subscription_t *subscription_create(struct profile_chain *prch, - int weight, const char *name, - int flags, streaming_ops_t *ops, - const char *hostname, - const char *username, - const char *client); +th_subscription_t* subscription_create_from_file(const char* name, + const char* charset, + const char* filename, + const char* hostname, + const char* username, + const char* client); +th_subscription_t* subscription_create(struct profile_chain* prch, + int weight, + const char* name, + int flags, + streaming_ops_t* ops, + const char* hostname, + const char* username, + const char* client); -void subscription_change_weight(th_subscription_t *s, int weight); +void subscription_change_weight(th_subscription_t* s, int weight); -void subscription_set_speed - (th_subscription_t *s, int32_t speed ); +void subscription_set_speed(th_subscription_t* s, int32_t speed); -void subscription_set_skip - (th_subscription_t *s, const streaming_skip_t *skip); +void subscription_set_skip(th_subscription_t* s, const streaming_skip_t* skip); -void subscription_stop(th_subscription_t *s); +void subscription_stop(th_subscription_t* s); -void subscription_unlink_service(th_subscription_t *s, int reason); +void subscription_unlink_service(th_subscription_t* s, int reason); -void subscription_dummy_join(const char *id, int first); +void subscription_dummy_join(const char* id, int first); -void subscription_add_bytes_in(th_subscription_t *s, size_t in); +void subscription_add_bytes_in(th_subscription_t* s, size_t in); -void subscription_add_bytes_out(th_subscription_t *s, size_t out); +void subscription_add_bytes_out(th_subscription_t* s, size_t out); -static inline int subscriptions_active(void) - { return LIST_FIRST(&subscriptions) != NULL; } +static inline int subscriptions_active(void) { + return LIST_FIRST(&subscriptions) != NULL; +} struct htsmsg; -struct htsmsg *subscription_create_msg(th_subscription_t *s, const char *lang); +struct htsmsg* subscription_create_msg(th_subscription_t* s, const char* lang); #endif /* SUBSCRIPTIONS_H */ diff --git a/src/tcp.c b/src/tcp.c index 8ff558730..bd5d0a69d 100644 --- a/src/tcp.c +++ b/src/tcp.c @@ -41,16 +41,14 @@ #include #endif -int tcp_preferred_address_family = AF_INET; -int tcp_server_running; +int tcp_preferred_address_family = AF_INET; +int tcp_server_running; th_pipe_t tcp_server_pipe; /** * */ -int -socket_set_dscp(int sockfd, uint32_t dscp, char *errbuf, size_t errbufsize) -{ +int socket_set_dscp(int sockfd, uint32_t dscp, char* errbuf, size_t errbufsize) { int r, v; v = dscp & IPTOS_DSCP_MASK; @@ -66,14 +64,12 @@ socket_set_dscp(int sockfd, uint32_t dscp, char *errbuf, size_t errbufsize) /** * */ -int -ip_check_is_local_address - (const struct sockaddr_storage *peer, const struct sockaddr_storage *local, - struct sockaddr_storage *used_local) -{ - struct ifaddrs *iflist, *ifdev = NULL; +int ip_check_is_local_address(const struct sockaddr_storage* peer, + const struct sockaddr_storage* local, + struct sockaddr_storage* used_local) { + struct ifaddrs * iflist, *ifdev = NULL; struct sockaddr_storage *ifaddr, *ifnetmask; - int any_address, ret; + int any_address, ret; // Note: Not all platforms have getifaddrs() // See http://docs.freeswitch.org/switch__utils_8c_source.html @@ -89,11 +85,14 @@ ip_check_is_local_address any_address = ip_check_is_any(local); for (ifdev = iflist, ret = 0; ifdev && ret == 0; ifdev = ifdev->ifa_next) { - ifaddr = (struct sockaddr_storage *)(ifdev->ifa_addr); - ifnetmask = (struct sockaddr_storage *)(ifdev->ifa_netmask); - if (!ifaddr || !ifnetmask) continue; - if (ifaddr->ss_family != local->ss_family) continue; - if (!any_address && !ip_check_equal(ifaddr, local)) continue; + ifaddr = (struct sockaddr_storage*)(ifdev->ifa_addr); + ifnetmask = (struct sockaddr_storage*)(ifdev->ifa_netmask); + if (!ifaddr || !ifnetmask) + continue; + if (ifaddr->ss_family != local->ss_family) + continue; + if (!any_address && !ip_check_equal(ifaddr, local)) + continue; ret = !!ip_check_in_network(ifaddr, ifnetmask, peer); if (ret) { if (used_local) @@ -108,15 +107,17 @@ ip_check_is_local_address /** * */ -int -tcp_connect(const char *hostname, int port, const char *bindaddr, - char *errbuf, size_t errbufsize, int timeout) -{ - int fd = -1, r, res, err; - struct addrinfo *ai, *rai = NULL, hints; +int tcp_connect(const char* hostname, + int port, + const char* bindaddr, + char* errbuf, + size_t errbufsize, + int timeout) { + int fd = -1, r, res, err; + struct addrinfo * ai, *rai = NULL, hints; struct sockaddr_storage bindip; - char portstr[6]; - socklen_t errlen = sizeof(err); + char portstr[6]; + socklen_t errlen = sizeof(err); errbuf[0] = '\0'; @@ -132,7 +133,7 @@ tcp_connect(const char *hostname, int port, const char *bindaddr, snprintf(portstr, 6, "%u", port); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; - res = getaddrinfo(hostname, portstr, &hints, &ai); + res = getaddrinfo(hostname, portstr, &hints, &ai); if (res != 0) { snprintf(errbuf, errbufsize, "%s", gai_strerror(res)); return -1; @@ -158,9 +159,8 @@ again: } fd = tvh_socket(rai->ai_family, SOCK_STREAM, 0); - if(fd < 0) { - snprintf(errbuf, errbufsize, "Unable to create socket: %s", - strerror(errno)); + if (fd < 0) { + snprintf(errbuf, errbufsize, "Unable to create socket: %s", strerror(errno)); goto again; } @@ -170,24 +170,27 @@ again: fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_NONBLOCK); if (bindip.ss_family != AF_UNSPEC) { - if (bind(fd, (struct sockaddr *)&bindip, IP_IN_ADDRLEN(bindip)) < 0) { - snprintf(errbuf, errbufsize, "Cannot bind to IPv%s addr '%s:%i': %s", - bindip.ss_family == AF_INET6 ? "6" : "4", - bindaddr, htons(IP_PORT(bindip)), - strerror(errno)); + if (bind(fd, (struct sockaddr*)&bindip, IP_IN_ADDRLEN(bindip)) < 0) { + snprintf(errbuf, + errbufsize, + "Cannot bind to IPv%s addr '%s:%i': %s", + bindip.ss_family == AF_INET6 ? "6" : "4", + bindaddr, + htons(IP_PORT(bindip)), + strerror(errno)); goto error; } } r = connect(fd, rai->ai_addr, rai->ai_addrlen); - if(r < 0) { + if (r < 0) { /* timeout < 0 - do not wait at all */ - if(errno == EINPROGRESS && timeout < 0) { + if (errno == EINPROGRESS && timeout < 0) { err = 0; - } else if(errno == EINPROGRESS) { + } else if (errno == EINPROGRESS) { tvhpoll_event_t ev; - tvhpoll_t *efd; + tvhpoll_t* efd; efd = tvhpoll_create(1); tvhpoll_add1(efd, fd, TVHPOLL_OUT, &fd); @@ -206,22 +209,22 @@ again: r = tvhpoll_wait(efd, &ev, 1, timeout * 1000); if (r > 0) break; - + if (r == 0) { /* Timeout */ snprintf(errbuf, errbufsize, "Connection attempt to '%s' timed out", hostname); tvhpoll_destroy(efd); goto again; } - + if (!ERRNO_AGAIN(errno)) { snprintf(errbuf, errbufsize, "poll() error: %s", strerror(errno)); tvhpoll_destroy(efd); goto error; } } - + tvhpoll_destroy(efd); - getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&err, &errlen); + getsockopt(fd, SOL_SOCKET, SO_ERROR, (void*)&err, &errlen); } else { err = errno; } @@ -229,16 +232,16 @@ again: err = 0; } - if(err != 0) { + if (err != 0) { snprintf(errbuf, errbufsize, "%s", strerror(err)); goto again; } - + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_NONBLOCK); /* Set the keep-alive active */ err = 1; - setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&err, errlen); + setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void*)&err, errlen); freeaddrinfo(ai); return fd; @@ -250,18 +253,15 @@ error: return -1; } - /** * */ -int -tcp_write_queue(int fd, htsbuf_queue_t *q) -{ - htsbuf_data_t *hd; - int l, r = 0; - void *p; - - while((hd = TAILQ_FIRST(&q->hq_q)) != NULL) { +int tcp_write_queue(int fd, htsbuf_queue_t* q) { + htsbuf_data_t* hd; + int l, r = 0; + void* p; + + while ((hd = TAILQ_FIRST(&q->hq_q)) != NULL) { if (!r) { l = hd->hd_data_len - hd->hd_data_off; p = hd->hd_data + hd->hd_data_off; @@ -273,43 +273,40 @@ tcp_write_queue(int fd, htsbuf_queue_t *q) return r; } - /** * */ -static int -tcp_fill_htsbuf_from_fd(int fd, htsbuf_queue_t *hq) -{ - htsbuf_data_t *hd = TAILQ_LAST(&hq->hq_q, htsbuf_data_queue); - int c, r; +static int tcp_fill_htsbuf_from_fd(int fd, htsbuf_queue_t* hq) { + htsbuf_data_t* hd = TAILQ_LAST(&hq->hq_q, htsbuf_data_queue); + int c, r; - if(hd != NULL) { + if (hd != NULL) { /* Fill out any previous buffer */ c = hd->hd_data_size - hd->hd_data_len; - if(c > 0) { + if (c > 0) { do { r = read(fd, hd->hd_data + hd->hd_data_len, c); } while (r < 0 && ERRNO_AGAIN(errno)); - if(r < 1) - return -1; + if (r < 1) + return -1; hd->hd_data_len += r; hq->hq_size += r; return 0; } } - + hd = malloc(sizeof(htsbuf_data_t)); - + hd->hd_data_size = 1000; - hd->hd_data = malloc(hd->hd_data_size); + hd->hd_data = malloc(hd->hd_data_size); do { r = read(fd, hd->hd_data, hd->hd_data_size); } while (r < 0 && ERRNO_AGAIN(errno)); - if(r < 1) { + if (r < 1) { free(hd->hd_data); free(hd); return -1; @@ -321,50 +318,43 @@ tcp_fill_htsbuf_from_fd(int fd, htsbuf_queue_t *hq) return 0; } - /** * */ -char * -tcp_read_line(int fd, htsbuf_queue_t *spill) -{ - int len; - char *buf; +char* tcp_read_line(int fd, htsbuf_queue_t* spill) { + int len; + char* buf; do { len = htsbuf_find(spill, 0xa); - if(len == -1) { - if(tcp_fill_htsbuf_from_fd(fd, spill) < 0) + if (len == -1) { + if (tcp_fill_htsbuf_from_fd(fd, spill) < 0) return NULL; } } while (len == -1); - buf = malloc(len+1); - + buf = malloc(len + 1); + htsbuf_read(spill, buf, len); buf[len] = 0; - while(len > 0 && buf[len - 1] < 32) + while (len > 0 && buf[len - 1] < 32) buf[--len] = 0; htsbuf_drop(spill, 1); /* Drop the \n */ return buf; } - - /** * */ -int -tcp_read_data(int fd, char *buf, const size_t bufsize, htsbuf_queue_t *spill) -{ +int tcp_read_data(int fd, char* buf, const size_t bufsize, htsbuf_queue_t* spill) { int x, tot = htsbuf_read(spill, buf, bufsize); - if(tot == bufsize) + if (tot == bufsize) return 0; x = recv(fd, buf + tot, bufsize - tot, MSG_WAITALL); - if(x != bufsize - tot) + if (x != bufsize - tot) return -1; return 0; @@ -373,40 +363,35 @@ tcp_read_data(int fd, char *buf, const size_t bufsize, htsbuf_queue_t *spill) /** * */ -int -tcp_read(int fd, void *buf, size_t len) -{ +int tcp_read(int fd, void* buf, size_t len) { int x = recv(fd, buf, len, MSG_WAITALL); - if(x == -1) + if (x == -1) return errno; - if(x != len) + if (x != len) return ECONNRESET; return 0; - } /** * */ -int -tcp_read_timeout(int fd, void *buf, size_t len, int timeout) -{ - int x, tot = 0; +int tcp_read_timeout(int fd, void* buf, size_t len, int timeout) { + int x, tot = 0; struct pollfd fds; assert(timeout > 0); - fds.fd = fd; - fds.events = POLLIN; + fds.fd = fd; + fds.events = POLLIN; fds.revents = 0; - while(tot != len) { + while (tot != len) { x = poll(&fds, 1, timeout); - if(x == 0) + if (x == 0) return ETIMEDOUT; - if(x == -1) { + if (x == -1) { if (!tvheadend_is_running()) return ECONNRESET; if (ERRNO_AGAIN(errno)) @@ -415,29 +400,26 @@ tcp_read_timeout(int fd, void *buf, size_t len, int timeout) } x = recv(fd, buf + tot, len - tot, MSG_DONTWAIT); - if(x == -1) { - if(ERRNO_AGAIN(errno)) + if (x == -1) { + if (ERRNO_AGAIN(errno)) continue; return errno; } - if(x == 0) + if (x == 0) return ECONNRESET; tot += x; } return 0; - } /** * */ -int -tcp_socket_dead(int fd) -{ - int err = 0; +int tcp_socket_dead(int fd) { + int err = 0; socklen_t errlen = sizeof(err); if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &err, &errlen)) @@ -457,14 +439,11 @@ tcp_socket_dead(int fd) /** * */ -char * -tcp_get_str_from_ip(const struct sockaddr_storage *sa, char *dst, size_t maxlen) -{ +char* tcp_get_str_from_ip(const struct sockaddr_storage* sa, char* dst, size_t maxlen) { if (sa == NULL || dst == NULL) return NULL; - switch(sa->ss_family) - { + switch (sa->ss_family) { case AF_INET: inet_ntop(AF_INET, &(((struct sockaddr_in*)sa)->sin_addr), dst, maxlen); break; @@ -482,9 +461,7 @@ tcp_get_str_from_ip(const struct sockaddr_storage *sa, char *dst, size_t maxlen) /** * */ -struct sockaddr_storage * -tcp_get_ip_from_str(const char *src, struct sockaddr_storage *sa) -{ +struct sockaddr_storage* tcp_get_ip_from_str(const char* src, struct sockaddr_storage* sa) { if (sa == NULL || src == NULL) return NULL; @@ -506,54 +483,52 @@ tcp_get_ip_from_str(const char *src, struct sockaddr_storage *sa) /** * */ -static tvhpoll_t *tcp_server_poll; -static uint32_t tcp_server_launch_id; +static tvhpoll_t* tcp_server_poll; +static uint32_t tcp_server_launch_id; typedef struct tcp_server { - int serverfd; + int serverfd; struct sockaddr_storage bound; - tcp_server_ops_t ops; - void *opaque; + tcp_server_ops_t ops; + void* opaque; LIST_ENTRY(tcp_server) link; } tcp_server_t; typedef struct tcp_server_launch { - pthread_t tid; - uint32_t id; - int fd; - int streaming; + pthread_t tid; + uint32_t id; + int fd; + int streaming; tcp_server_ops_t ops; - void *opaque; - char *representative; - void (*status) (void *opaque, htsmsg_t *m); + void* opaque; + char* representative; + void (*status)(void* opaque, htsmsg_t* m); struct sockaddr_storage peer; struct sockaddr_storage self; - time_t started; + time_t started; LIST_ENTRY(tcp_server_launch) link; LIST_ENTRY(tcp_server_launch) alink; LIST_ENTRY(tcp_server_launch) jlink; } tcp_server_launch_t; -static LIST_HEAD(, tcp_server) tcp_server_delete_list = { 0 }; -static LIST_HEAD(, tcp_server_launch) tcp_server_launches = { 0 }; -static LIST_HEAD(, tcp_server_launch) tcp_server_active = { 0 }; -static LIST_HEAD(, tcp_server_launch) tcp_server_join = { 0 }; +static LIST_HEAD(, tcp_server) tcp_server_delete_list = {0}; +static LIST_HEAD(, tcp_server_launch) tcp_server_launches = {0}; +static LIST_HEAD(, tcp_server_launch) tcp_server_active = {0}; +static LIST_HEAD(, tcp_server_launch) tcp_server_join = {0}; /** * */ -uint32_t -tcp_connection_count(access_t *aa) -{ - tcp_server_launch_t *tsl; - uint32_t used = 0; +uint32_t tcp_connection_count(access_t* aa) { + tcp_server_launch_t* tsl; + uint32_t used = 0; lock_assert(&global_lock); if (aa == NULL) return 0; - LIST_FOREACH(tsl, &tcp_server_active, alink) + LIST_FOREACH (tsl, &tcp_server_active, alink) if (!strcmp(aa->aa_representative ?: "", tsl->representative ?: "")) used++; return used; @@ -562,14 +537,14 @@ tcp_connection_count(access_t *aa) /** * */ -void * -tcp_connection_launch - (int fd, int streaming, void (*status) (void *opaque, htsmsg_t *m), access_t *aa) -{ +void* tcp_connection_launch(int fd, + int streaming, + void (*status)(void* opaque, htsmsg_t* m), + access_t* aa) { tcp_server_launch_t *tsl, *res; - uint32_t sused, used2; - int64_t started = mclk(); - int c1, c2; + uint32_t sused, used2; + int64_t started = mclk(); + int c1, c2; lock_assert(&global_lock); @@ -579,9 +554,9 @@ tcp_connection_launch return NULL; try_again: - res = NULL; + res = NULL; sused = 0; - LIST_FOREACH(tsl, &tcp_server_active, alink) { + LIST_FOREACH (tsl, &tcp_server_active, alink) { if (tsl->fd == fd) { res = tsl; if (!aa->aa_conn_limit && !aa->aa_conn_limit_streaming) @@ -603,11 +578,15 @@ try_again: if (c1 && c2) { if (started + sec2mono(5) < mclk()) { - tvherror(LS_TCP, "multiple connections are not allowed for user '%s' from '%s' " - "(limit %u, streaming limit %u, active streaming %u, DVR %u)", - aa->aa_username ?: "", aa->aa_representative ?: "", - aa->aa_conn_limit, aa->aa_conn_limit_streaming, - sused, used2); + tvherror(LS_TCP, + "multiple connections are not allowed for user '%s' from '%s' " + "(limit %u, streaming limit %u, active streaming %u, DVR %u)", + aa->aa_username ?: "", + aa->aa_representative ?: "", + aa->aa_conn_limit, + aa->aa_conn_limit_streaming, + sused, + used2); return NULL; } tvh_mutex_unlock(&global_lock); @@ -620,8 +599,8 @@ try_again: } res->representative = aa->aa_representative ? strdup(aa->aa_representative) : NULL; - res->status = status; - res->streaming = streaming; + res->status = status; + res->streaming = streaming; LIST_INSERT_HEAD(&tcp_server_launches, res, link); notify_reload("connections"); return res; @@ -630,10 +609,8 @@ try_again: /** * */ -void -tcp_connection_land(void *tcp_id) -{ - tcp_server_launch_t *tsl = tcp_id; +void tcp_connection_land(void* tcp_id) { + tcp_server_launch_t* tsl = tcp_id; lock_assert(&global_lock); @@ -650,14 +627,12 @@ tcp_connection_land(void *tcp_id) /** * */ -void -tcp_connection_cancel(uint32_t id) -{ - tcp_server_launch_t *tsl; +void tcp_connection_cancel(uint32_t id) { + tcp_server_launch_t* tsl; lock_assert(&global_lock); - LIST_FOREACH(tsl, &tcp_server_active, alink) + LIST_FOREACH (tsl, &tcp_server_active, alink) if (tsl->id == id) { if (tsl->ops.cancel) tsl->ops.cancel(tsl->opaque); @@ -668,14 +643,12 @@ tcp_connection_cancel(uint32_t id) /** * */ -void -tcp_connection_cancel_all(void) -{ - tcp_server_launch_t *tsl; +void tcp_connection_cancel_all(void) { + tcp_server_launch_t* tsl; lock_assert(&global_lock); - LIST_FOREACH(tsl, &tcp_server_active, alink) + LIST_FOREACH (tsl, &tcp_server_active, alink) if (tsl->ops.cancel) tsl->ops.cancel(tsl->opaque); } @@ -683,17 +656,15 @@ tcp_connection_cancel_all(void) /* * */ -static void * -tcp_server_start(void *aux) -{ - tcp_server_launch_t *tsl = aux; - struct timeval to; - int val; - char c = 'J'; +static void* tcp_server_start(void* aux) { + tcp_server_launch_t* tsl = aux; + struct timeval to; + int val; + char c = 'J'; val = 1; setsockopt(tsl->fd, SOL_SOCKET, SO_KEEPALIVE, &val, sizeof(val)); - + #ifdef TCP_KEEPIDLE val = 30; setsockopt(tsl->fd, IPPROTO_TCP, TCP_KEEPIDLE, &val, sizeof(val)); @@ -713,18 +684,20 @@ tcp_server_start(void *aux) setsockopt(tsl->fd, IPPROTO_TCP, TCP_NODELAY, &val, sizeof(val)); to.tv_sec = 30; - to.tv_usec = 0; + to.tv_usec = 0; setsockopt(tsl->fd, SOL_SOCKET, SO_SNDTIMEO, &to, sizeof(to)); /* Start */ time(&tsl->started); tvh_mutex_lock(&global_lock); tsl->id = ++tcp_server_launch_id; - if (!tsl->id) tsl->id = ++tcp_server_launch_id; + if (!tsl->id) + tsl->id = ++tcp_server_launch_id; tsl->ops.start(tsl->fd, &tsl->opaque, &tsl->peer, &tsl->self); /* Stop */ - if (tsl->ops.stop) tsl->ops.stop(tsl->opaque); + if (tsl->ops.stop) + tsl->ops.stop(tsl->opaque); LIST_REMOVE(tsl, alink); LIST_INSERT_HEAD(&tcp_server_join, tsl, jlink); tvh_mutex_unlock(&global_lock); @@ -733,35 +706,33 @@ tcp_server_start(void *aux) return NULL; } - /** * */ -static void * -tcp_server_loop(void *aux) -{ - int r; - tvhpoll_event_t ev; - tcp_server_t *ts; - tcp_server_launch_t *tsl; - socklen_t slen; - char c; - - while(atomic_get(&tcp_server_running)) { +static void* tcp_server_loop(void* aux) { + int r; + tvhpoll_event_t ev; + tcp_server_t* ts; + tcp_server_launch_t* tsl; + socklen_t slen; + char c; + + while (atomic_get(&tcp_server_running)) { r = tvhpoll_wait(tcp_server_poll, &ev, 1, -1); - if(r < 0) { + if (r < 0) { if (ERRNO_AGAIN(errno)) continue; tvherror(LS_TCP, "tcp_server_loop: tvhpoll_wait: %s", strerror(errno)); continue; } - if (r == 0) continue; + if (r == 0) + continue; if (ev.ptr == &tcp_server_pipe) { r = read(tcp_server_pipe.rd, &c, 1); if (r > 0) { -next: + next: tvh_mutex_lock(&global_lock); while ((tsl = LIST_FIRST(&tcp_server_join)) != NULL) { LIST_REMOVE(tsl, jlink); @@ -781,31 +752,30 @@ next: ts = ev.ptr; - if(ev.events & TVHPOLL_HUP) { + if (ev.events & TVHPOLL_HUP) { close(ts->serverfd); free(ts); continue; - } + } - if(ev.events & TVHPOLL_IN) { - tsl = malloc(sizeof(tcp_server_launch_t)); + if (ev.events & TVHPOLL_IN) { + tsl = malloc(sizeof(tcp_server_launch_t)); tsl->ops = ts->ops; tsl->opaque = ts->opaque; tsl->status = NULL; tsl->representative = NULL; - slen = sizeof(struct sockaddr_storage); + slen = sizeof(struct sockaddr_storage); - tsl->fd = accept(ts->serverfd, - (struct sockaddr *)&tsl->peer, &slen); - if(tsl->fd == -1) { - perror("accept"); - free(tsl); - sleep(1); - continue; + tsl->fd = accept(ts->serverfd, (struct sockaddr*)&tsl->peer, &slen); + if (tsl->fd == -1) { + perror("accept"); + free(tsl); + sleep(1); + continue; } slen = sizeof(struct sockaddr_storage); - if(getsockname(tsl->fd, (struct sockaddr *)&tsl->self, &slen)) { + if (getsockname(tsl->fd, (struct sockaddr*)&tsl->self, &slen)) { close(tsl->fd); free(tsl); continue; @@ -821,62 +791,65 @@ next: return NULL; } - - /** * */ #if ENABLE_LIBSYSTEMD_DAEMON -static void *tcp_server_create_new +static void* tcp_server_create_new #else -void *tcp_server_create +void* tcp_server_create #endif - (int subsystem, const char *name, const char *bindaddr, - int port, tcp_server_ops_t *ops, void *opaque) -{ - int fd, x; - tcp_server_t *ts; - struct addrinfo hints, *res, *ressave, *use = NULL; + (int subsystem, + const char* name, + const char* bindaddr, + int port, + tcp_server_ops_t* ops, + void* opaque) { + int fd, x; + tcp_server_t* ts; + struct addrinfo hints, *res, *ressave, *use = NULL; struct sockaddr_storage bound; - char port_buf[6], buf[50]; - int one = 1; - int zero = 0; + char port_buf[6], buf[50]; + int one = 1; + int zero = 0; snprintf(port_buf, 6, "%d", port); memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV; if (bindaddr != NULL) - hints.ai_flags |= AI_NUMERICHOST; - hints.ai_family = AF_UNSPEC; + hints.ai_flags |= AI_NUMERICHOST; + hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; x = getaddrinfo(bindaddr, port_buf, &hints, &res); - if(x != 0) { - tvherror(LS_TCP, "getaddrinfo: %s: %s", bindaddr != NULL ? bindaddr : "*", - x == EAI_SYSTEM ? strerror(errno) : gai_strerror(x)); + if (x != 0) { + tvherror(LS_TCP, + "getaddrinfo: %s: %s", + bindaddr != NULL ? bindaddr : "*", + x == EAI_SYSTEM ? strerror(errno) : gai_strerror(x)); return NULL; } ressave = res; - while(res) { - if(res->ai_family == tcp_preferred_address_family) { + while (res) { + if (res->ai_family == tcp_preferred_address_family) { use = res; break; - } else if(use == NULL) { + } else if (use == NULL) { use = res; } res = res->ai_next; } fd = tvh_socket(use->ai_family, use->ai_socktype, use->ai_protocol); - if(fd == -1) { + if (fd == -1) { freeaddrinfo(ressave); return NULL; } - if(use->ai_family == AF_INET6) + if (use->ai_family == AF_INET6) setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &zero, sizeof(int)); setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(int)); @@ -884,12 +857,11 @@ void *tcp_server_create assert(use->ai_addrlen <= sizeof(bound)); memset(&bound, 0, sizeof(bound)); memcpy(&bound, use->ai_addr, use->ai_addrlen); - + x = bind(fd, use->ai_addr, use->ai_addrlen); freeaddrinfo(ressave); - if(x != 0) - { + if (x != 0) { tvherror(LS_TCP, "bind: %s:%i: %s", bindaddr != NULL ? bindaddr : "*", port, strerror(errno)); close(fd); return NULL; @@ -897,11 +869,11 @@ void *tcp_server_create listen(fd, 511); - ts = malloc(sizeof(tcp_server_t)); + ts = malloc(sizeof(tcp_server_t)); ts->serverfd = fd; - ts->bound = bound; - ts->ops = *ops; - ts->opaque = opaque; + ts->bound = bound; + ts->ops = *ops; + ts->opaque = opaque; tcp_get_str_from_ip(&bound, buf, sizeof(buf)); tvhinfo(subsystem, "Starting %s server %s:%d", name, buf, htons(IP_PORT(bound))); @@ -913,48 +885,48 @@ void *tcp_server_create /** * */ -void * -tcp_server_create - (int subsystem, const char *name, const char *bindaddr, - int port, tcp_server_ops_t *ops, void *opaque) -{ - int sd_fds_num, i, fd; +void* tcp_server_create(int subsystem, + const char* name, + const char* bindaddr, + int port, + tcp_server_ops_t* ops, + void* opaque) { + int sd_fds_num, i, fd; struct sockaddr_storage bound; - tcp_server_t *ts; - struct in_addr addr4; - struct in6_addr addr6; - char buf[50]; - int found = 0; + tcp_server_t* ts; + struct in_addr addr4; + struct in6_addr addr6; + char buf[50]; + int found = 0; sd_fds_num = sd_listen_fds(0); inet_pton(AF_INET, bindaddr ?: "0.0.0.0", &addr4); inet_pton(AF_INET6, bindaddr ?: "::", &addr6); for (i = 0; i < sd_fds_num && !found; i++) { - struct sockaddr_in *s_addr4; - struct sockaddr_in6 *s_addr6; - socklen_t s_len; + struct sockaddr_in* s_addr4; + struct sockaddr_in6* s_addr6; + socklen_t s_len; /* Check which of the systemd-managed descriptors * corresponds to the requested server (if any) */ fd = SD_LISTEN_FDS_START + i; memset(&bound, 0, sizeof(bound)); s_len = sizeof(bound); - if (getsockname(fd, (struct sockaddr *) &bound, &s_len) != 0) { + if (getsockname(fd, (struct sockaddr*)&bound, &s_len) != 0) { tvherror(LS_TCP, "getsockname failed: %s", strerror(errno)); continue; } switch (bound.ss_family) { case AF_INET: - s_addr4 = (struct sockaddr_in *) &bound; - if (addr4.s_addr == s_addr4->sin_addr.s_addr - && htons(port) == s_addr4->sin_port) + s_addr4 = (struct sockaddr_in*)&bound; + if (addr4.s_addr == s_addr4->sin_addr.s_addr && htons(port) == s_addr4->sin_port) found = 1; break; case AF_INET6: - s_addr6 = (struct sockaddr_in6 *) &bound; - if (memcmp(addr6.s6_addr, s_addr6->sin6_addr.s6_addr, 16) == 0 - && htons(port) == s_addr6->sin6_port) + s_addr6 = (struct sockaddr_in6*)&bound; + if (memcmp(addr6.s6_addr, s_addr6->sin6_addr.s6_addr, 16) == 0 && + htons(port) == s_addr6->sin6_port) found = 1; break; default: @@ -964,11 +936,11 @@ tcp_server_create if (found) { /* use the systemd provided socket */ - ts = malloc(sizeof(tcp_server_t)); + ts = malloc(sizeof(tcp_server_t)); ts->serverfd = fd; - ts->bound = bound; - ts->ops = *ops; - ts->opaque = opaque; + ts->bound = bound; + ts->ops = *ops; + ts->opaque = opaque; tcp_get_str_from_ip(&bound, buf, sizeof(buf)); tvhinfo(subsystem, "Starting %s server %s:%d (systemd)", name, buf, htons(IP_PORT(bound))); } else { @@ -984,9 +956,8 @@ tcp_server_create /** * */ -void tcp_server_register(void *server) -{ - tcp_server_t *ts = server; +void tcp_server_register(void* server) { + tcp_server_t* ts = server; if (ts == NULL) return; @@ -997,11 +968,9 @@ void tcp_server_register(void *server) /** * */ -void -tcp_server_delete(void *server) -{ - tcp_server_t *ts = server; - char c = 'D'; +void tcp_server_delete(void* server) { + tcp_server_t* ts = server; + char c = 'D'; if (server == NULL) return; @@ -1016,21 +985,20 @@ tcp_server_delete(void *server) /** * */ -int -tcp_default_ip_addr ( struct sockaddr_storage *deflt, int family ) -{ +int tcp_default_ip_addr(struct sockaddr_storage* deflt, int family) { struct sockaddr_storage ss; - socklen_t ss_len; - int sock; + socklen_t ss_len; + int sock; memset(&ss, 0, sizeof(ss)); ss.ss_family = family == PF_UNSPEC ? tcp_preferred_address_family : family; if (inet_pton(ss.ss_family, - ss.ss_family == AF_INET ? - /* Google name servers */ - "8.8.8.8" : "2001:4860:4860::8888", - IP_IN_ADDR(ss)) <= 0) + ss.ss_family == AF_INET ? + /* Google name servers */ + "8.8.8.8" + : "2001:4860:4860::8888", + IP_IN_ADDR(ss)) <= 0) return -1; IP_PORT_SET(ss, htons(53)); @@ -1039,13 +1007,13 @@ tcp_default_ip_addr ( struct sockaddr_storage *deflt, int family ) if (sock < 0) return -1; - if (connect(sock, (struct sockaddr *)&ss, IP_IN_ADDRLEN(ss)) < 0) { + if (connect(sock, (struct sockaddr*)&ss, IP_IN_ADDRLEN(ss)) < 0) { close(sock); return -1; } ss_len = sizeof(ss); - if (getsockname(sock, (struct sockaddr *)&ss, &ss_len) < 0) { + if (getsockname(sock, (struct sockaddr*)&ss, &ss_len) < 0) { close(sock); return -1; } @@ -1065,12 +1033,10 @@ tcp_default_ip_addr ( struct sockaddr_storage *deflt, int family ) /** * */ -int -tcp_server_bound ( void *server, struct sockaddr_storage *bound, int family ) -{ - tcp_server_t *ts = server; - int i, len, port; - uint8_t *ptr; +int tcp_server_bound(void* server, struct sockaddr_storage* bound, int family) { + tcp_server_t* ts = server; + int i, len, port; + uint8_t* ptr; if (server == NULL) { memset(bound, 0, sizeof(*bound)); @@ -1078,7 +1044,7 @@ tcp_server_bound ( void *server, struct sockaddr_storage *bound, int family ) } len = IP_IN_ADDRLEN(ts->bound); - ptr = (uint8_t *)IP_IN_ADDR(ts->bound); + ptr = (uint8_t*)IP_IN_ADDR(ts->bound); for (i = 0; i < len; i++) if (ptr[0]) break; @@ -1101,17 +1067,16 @@ tcp_server_bound ( void *server, struct sockaddr_storage *bound, int family ) /** * */ -int -tcp_server_onall ( void *server ) -{ - tcp_server_t *ts = server; - int i, len; - uint8_t *ptr; +int tcp_server_onall(void* server) { + tcp_server_t* ts = server; + int i, len; + uint8_t* ptr; - if (server == NULL) return 0; + if (server == NULL) + return 0; len = IP_IN_ADDRLEN(ts->bound); - ptr = (uint8_t *)IP_IN_ADDR(ts->bound); + ptr = (uint8_t*)IP_IN_ADDR(ts->bound); for (i = 0; i < len; i++) if (ptr[0]) break; @@ -1121,19 +1086,18 @@ tcp_server_onall ( void *server ) /* * Connections status */ -htsmsg_t * -tcp_server_connections ( void ) -{ - tcp_server_launch_t *tsl; +htsmsg_t* tcp_server_connections(void) { + tcp_server_launch_t* tsl; lock_assert(&global_lock); htsmsg_t *l, *e, *m; - char buf[128]; - int c = 0; - + char buf[128]; + int c = 0; + /* Build list */ l = htsmsg_create_list(); - LIST_FOREACH(tsl, &tcp_server_launches, link) { - if (!tsl->status) continue; + LIST_FOREACH (tsl, &tcp_server_launches, link) { + if (!tsl->status) + continue; c++; e = htsmsg_create_map(); htsmsg_add_u32(e, "id", tsl->id); @@ -1161,16 +1125,12 @@ tcp_server_connections ( void ) */ pthread_t tcp_server_tid; -void -tcp_server_preinit(int opt_ipv6) -{ - if(opt_ipv6) +void tcp_server_preinit(int opt_ipv6) { + if (opt_ipv6) tcp_preferred_address_family = AF_INET6; } -void -tcp_server_init(void) -{ +void tcp_server_init(void) { tvh_pipe(O_NONBLOCK, &tcp_server_pipe); tcp_server_poll = tvhpoll_create(10); @@ -1180,19 +1140,17 @@ tcp_server_init(void) tvh_thread_create(&tcp_server_tid, NULL, tcp_server_loop, NULL, "tcp-loop"); } -void -tcp_server_done(void) -{ - tcp_server_t *ts; - tcp_server_launch_t *tsl; - char c = 'E'; - int64_t t; +void tcp_server_done(void) { + tcp_server_t* ts; + tcp_server_launch_t* tsl; + char c = 'E'; + int64_t t; atomic_set(&tcp_server_running, 0); tvh_write(tcp_server_pipe.wr, &c, 1); tvh_mutex_lock(&global_lock); - LIST_FOREACH(tsl, &tcp_server_active, alink) { + LIST_FOREACH (tsl, &tcp_server_active, alink) { if (tsl->ops.cancel) tsl->ops.cancel(tsl->opaque); if (tsl->fd >= 0) @@ -1204,7 +1162,7 @@ tcp_server_done(void) pthread_join(tcp_server_tid, NULL); tvh_pipe_close(&tcp_server_pipe); tvhpoll_destroy(tcp_server_poll); - + tvh_mutex_lock(&global_lock); t = mclk(); while (LIST_FIRST(&tcp_server_active) != NULL) { diff --git a/src/tcp.h b/src/tcp.h index 5d32b8926..2a60b349e 100644 --- a/src/tcp.h +++ b/src/tcp.h @@ -26,34 +26,29 @@ #include #endif -#define IP_AS_V4(storage, f) ((struct sockaddr_in *)(storage))->sin_##f -#define IP_AS_V6(storage, f) ((struct sockaddr_in6 *)(storage))->sin6_##f -#define IP_IN_ADDR(storage) \ - ((storage).ss_family == AF_INET6 ? \ - &((struct sockaddr_in6 *)&(storage))->sin6_addr : \ - (void *)&((struct sockaddr_in *)&(storage))->sin_addr) +#define IP_AS_V4(storage, f) ((struct sockaddr_in*)(storage))->sin_##f +#define IP_AS_V6(storage, f) ((struct sockaddr_in6*)(storage))->sin6_##f +#define IP_IN_ADDR(storage) \ + ((storage).ss_family == AF_INET6 ? &((struct sockaddr_in6*)&(storage))->sin6_addr \ + : (void*)&((struct sockaddr_in*)&(storage))->sin_addr) #define IP_IN_ADDRLEN(storage) \ - ((storage).ss_family == AF_INET6 ? \ - sizeof(struct sockaddr_in6) : \ - sizeof(struct sockaddr_in)) -#define IP_PORT(storage) \ - ((storage).ss_family == AF_INET6 ? \ - ((struct sockaddr_in6 *)&(storage))->sin6_port : \ - ((struct sockaddr_in *)&(storage))->sin_port) -#define IP_PORT_SET(storage, port) \ - do { \ - if ((storage).ss_family == AF_INET6) \ - ((struct sockaddr_in6 *)&(storage))->sin6_port = (port); else \ - ((struct sockaddr_in *)&(storage))->sin_port = (port); \ + ((storage).ss_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)) +#define IP_PORT(storage) \ + ((storage).ss_family == AF_INET6 ? ((struct sockaddr_in6*)&(storage))->sin6_port \ + : ((struct sockaddr_in*)&(storage))->sin_port) +#define IP_PORT_SET(storage, port) \ + do { \ + if ((storage).ss_family == AF_INET6) \ + ((struct sockaddr_in6*)&(storage))->sin6_port = (port); \ + else \ + ((struct sockaddr_in*)&(storage))->sin_port = (port); \ } while (0) -typedef struct tcp_server_ops -{ - void (*start) (int fd, void **opaque, - struct sockaddr_storage *peer, - struct sockaddr_storage *self); - void (*stop) (void *opaque); - void (*cancel) (void *opaque); +typedef struct tcp_server_ops { + void ( + *start)(int fd, void** opaque, struct sockaddr_storage* peer, struct sockaddr_storage* self); + void (*stop)(void* opaque); + void (*cancel)(void* opaque); } tcp_server_ops_t; extern int tcp_preferred_address_family; @@ -62,107 +57,129 @@ void tcp_server_preinit(int opt_ipv6); void tcp_server_init(void); void tcp_server_done(void); -static inline int ip_check_equal_v4 - (const struct sockaddr_storage *a, const struct sockaddr_storage *b) - { return IP_AS_V4(a, addr).s_addr == IP_AS_V4(b, addr).s_addr; } +static inline int ip_check_equal_v4(const struct sockaddr_storage* a, + const struct sockaddr_storage* b) { + return IP_AS_V4(a, addr).s_addr == IP_AS_V4(b, addr).s_addr; +} + +static inline int ip_check_equal_v6(const struct sockaddr_storage* a, + const struct sockaddr_storage* b) { + return memcmp(IP_AS_V6(a, addr).s6_addr, + IP_AS_V6(b, addr).s6_addr, + sizeof(IP_AS_V6(a, addr).s6_addr)) == 0; +} -static inline int ip_check_equal_v6 - (const struct sockaddr_storage *a, const struct sockaddr_storage *b) - { return memcmp(IP_AS_V6(a, addr).s6_addr, IP_AS_V6(b, addr).s6_addr, sizeof(IP_AS_V6(a, addr).s6_addr)) == 0; } +static inline int ip_check_equal(const struct sockaddr_storage* a, + const struct sockaddr_storage* b) { + return a->ss_family == b->ss_family && a->ss_family == AF_INET + ? ip_check_equal_v4(a, b) + : (a->ss_family == AF_INET6 ? ip_check_equal_v6(a, b) : 0); +} -static inline int ip_check_equal - (const struct sockaddr_storage *a, const struct sockaddr_storage *b) - { return a->ss_family == b->ss_family && - a->ss_family == AF_INET ? ip_check_equal_v4(a, b) : - (a->ss_family == AF_INET6 ? ip_check_equal_v6(a, b) : 0); } +static inline int ip_check_in_network_v4(const struct sockaddr_storage* network, + const struct sockaddr_storage* mask, + const struct sockaddr_storage* address) { + return (IP_AS_V4(address, addr).s_addr & IP_AS_V4(mask, addr).s_addr) == + (IP_AS_V4(network, addr).s_addr & IP_AS_V4(mask, addr).s_addr); +} -static inline int ip_check_in_network_v4(const struct sockaddr_storage *network, - const struct sockaddr_storage *mask, - const struct sockaddr_storage *address) - { return (IP_AS_V4(address, addr).s_addr & IP_AS_V4(mask, addr).s_addr) == - (IP_AS_V4(network, addr).s_addr & IP_AS_V4(mask, addr).s_addr); } +static inline int ip_check_in_network_v6(const struct sockaddr_storage* network, + const struct sockaddr_storage* mask, + const struct sockaddr_storage* address) { + short i; + for (i = 0; i < sizeof(IP_AS_V6(address, addr).s6_addr); ++i) + if (((IP_AS_V6(address, addr).s6_addr)[i] & (IP_AS_V6(mask, addr).s6_addr)[i]) != + ((IP_AS_V6(network, addr).s6_addr)[i] & (IP_AS_V6(mask, addr).s6_addr)[i])) + return 0; + return 1; +} -static inline int ip_check_in_network_v6(const struct sockaddr_storage *network, - const struct sockaddr_storage *mask, - const struct sockaddr_storage *address) - { - short i; - for (i = 0; i < sizeof(IP_AS_V6(address, addr).s6_addr); ++i) - if (((IP_AS_V6(address, addr).s6_addr)[i] & (IP_AS_V6(mask, addr).s6_addr)[i]) != ((IP_AS_V6(network, addr).s6_addr)[i] & (IP_AS_V6(mask, addr).s6_addr)[i])) - return 0; - return 1; - } +static inline int ip_check_in_network(const struct sockaddr_storage* network, + const struct sockaddr_storage* mask, + const struct sockaddr_storage* address) { + return address->ss_family == AF_INET + ? ip_check_in_network_v4(network, mask, address) + : (address->ss_family == AF_INET6 ? ip_check_in_network_v6(network, mask, address) : 0); +} -static inline int ip_check_in_network(const struct sockaddr_storage *network, - const struct sockaddr_storage *mask, - const struct sockaddr_storage *address) - { return address->ss_family == AF_INET ? ip_check_in_network_v4(network, mask, address) : - (address->ss_family == AF_INET6 ? ip_check_in_network_v6(network, mask, address) : 0); } +static inline int ip_check_is_any_v4(const struct sockaddr_storage* address) { + return IP_AS_V4(address, addr).s_addr == INADDR_ANY; +} -static inline int ip_check_is_any_v4(const struct sockaddr_storage *address) - { return IP_AS_V4(address, addr).s_addr == INADDR_ANY; } +static inline int ip_check_is_any_v6(const struct sockaddr_storage* address) { + return memcmp(IP_AS_V6(address, addr).s6_addr, + in6addr_any.s6_addr, + sizeof(in6addr_any.s6_addr)) == 0; +} -static inline int ip_check_is_any_v6(const struct sockaddr_storage *address) - { return memcmp(IP_AS_V6(address, addr).s6_addr, in6addr_any.s6_addr, sizeof(in6addr_any.s6_addr)) == 0; } +static inline int ip_check_is_any(const struct sockaddr_storage* address) { + return address->ss_family == AF_INET + ? ip_check_is_any_v4(address) + : (address->ss_family == AF_INET6 ? ip_check_is_any_v6(address) : 0); +} -static inline int ip_check_is_any(const struct sockaddr_storage *address) - { return address->ss_family == AF_INET ? ip_check_is_any_v4(address) : - (address->ss_family == AF_INET6 ? ip_check_is_any_v6(address) : 0); } +int ip_check_is_local_address(const struct sockaddr_storage* peer, + const struct sockaddr_storage* local, + struct sockaddr_storage* used_local); -int ip_check_is_local_address(const struct sockaddr_storage *peer, - const struct sockaddr_storage *local, - struct sockaddr_storage *used_local); +int socket_set_dscp(int sockfd, uint32_t dscp, char* errbuf, size_t errbufsize); -int socket_set_dscp(int sockfd, uint32_t dscp, char *errbuf, size_t errbufsize); +int tcp_connect(const char* hostname, + int port, + const char* bindaddr, + char* errbuf, + size_t errbufsize, + int timeout); -int tcp_connect(const char *hostname, int port, const char *bindaddr, - char *errbuf, size_t errbufsize, int timeout); +typedef void(tcp_server_callback_t)(int fd, + void* opaque, + struct sockaddr_storage* peer, + struct sockaddr_storage* self); -typedef void (tcp_server_callback_t)(int fd, void *opaque, - struct sockaddr_storage *peer, - struct sockaddr_storage *self); +void* tcp_server_create(int subsystem, + const char* name, + const char* bindaddr, + int port, + tcp_server_ops_t* ops, + void* opaque); -void *tcp_server_create(int subsystem, const char *name, - const char *bindaddr, int port, - tcp_server_ops_t *ops, void *opaque); +void tcp_server_register(void* server); -void tcp_server_register(void *server); +void tcp_server_delete(void* server); -void tcp_server_delete(void *server); +int tcp_default_ip_addr(struct sockaddr_storage* deflt, int family); -int tcp_default_ip_addr(struct sockaddr_storage *deflt, int family); +int tcp_server_bound(void* server, struct sockaddr_storage* bound, int family); -int tcp_server_bound(void *server, struct sockaddr_storage *bound, int family); +int tcp_server_onall(void* server); -int tcp_server_onall(void *server); +int tcp_read(int fd, void* buf, size_t len); -int tcp_read(int fd, void *buf, size_t len); +char* tcp_read_line(int fd, htsbuf_queue_t* spill); -char *tcp_read_line(int fd, htsbuf_queue_t *spill); +int tcp_read_data(int fd, char* buf, const size_t bufsize, htsbuf_queue_t* spill); + +int tcp_write_queue(int fd, htsbuf_queue_t* q); -int tcp_read_data(int fd, char *buf, const size_t bufsize, - htsbuf_queue_t *spill); +int tcp_read_timeout(int fd, void* buf, size_t len, int timeout); + +char* tcp_get_str_from_ip(const struct sockaddr_storage* sa, char* dst, size_t maxlen); -int tcp_write_queue(int fd, htsbuf_queue_t *q); - -int tcp_read_timeout(int fd, void *buf, size_t len, int timeout); - -char *tcp_get_str_from_ip(const struct sockaddr_storage *sa, char *dst, size_t maxlen); - -struct sockaddr_storage *tcp_get_ip_from_str(const char *str, struct sockaddr_storage *sa); +struct sockaddr_storage* tcp_get_ip_from_str(const char* str, struct sockaddr_storage* sa); int tcp_socket_dead(int fd); struct access; -uint32_t tcp_connection_count(struct access *aa); -void *tcp_connection_launch(int fd, int streaming, - void (*status) (void *opaque, htsmsg_t *m), - struct access *aa); -void tcp_connection_land(void *tcp_id); -void tcp_connection_cancel(uint32_t id); -void tcp_connection_cancel_all(void); +uint32_t tcp_connection_count(struct access* aa); +void* tcp_connection_launch(int fd, + int streaming, + void (*status)(void* opaque, htsmsg_t* m), + struct access* aa); +void tcp_connection_land(void* tcp_id); +void tcp_connection_cancel(uint32_t id); +void tcp_connection_cancel_all(void); -htsmsg_t *tcp_server_connections ( void ); +htsmsg_t* tcp_server_connections(void); #endif /* TCP_H_ */ diff --git a/src/test.c b/src/test.c index 4c5191bb0..c5cd50fe5 100644 --- a/src/test.c +++ b/src/test.c @@ -1,59 +1,47 @@ #include "test.h" -const idclass_t obj_a_class = { - .ic_class = "obj_a", - .ic_caption = N_("Object A"), - .ic_properties = (const property_t[]){ - { PROPDEF1("int1", "Integer 1", PT_INT, obj_a_t, a_int1) }, - { PROPDEF1("bool1", "Boolean 1", PT_BOOL, obj_a_t, a_bool1) }, - { PROPDEF1("str1", "String 1", PT_STR, obj_a_t, a_str1) }, - } -}; - -static void obj_b_save ( idnode_t *self ); - -const idclass_t obj_b_class = { - .ic_super = &obj_a_class, - .ic_class = "obj_b", - .ic_caption = N_("Object B"), - .ic_save = obj_b_save, - .ic_properties = (const property_t[]){ - { PROPDEF1("int2", "Integer 2", PT_INT, obj_b_t, b_int2) }, - { PROPDEF1("bool2", "Boolean 2", PT_BOOL, obj_b_t, b_bool2) }, - { PROPDEF1("str2", "String 2", PT_STR, obj_b_t, b_str2) }, - } -}; - -static void -obj_a_func1 ( void *self ) -{ - obj_a_t *a = self; +const idclass_t obj_a_class = {.ic_class = "obj_a", + .ic_caption = N_("Object A"), + .ic_properties = (const property_t[]){ + {PROPDEF1("int1", "Integer 1", PT_INT, obj_a_t, a_int1)}, + {PROPDEF1("bool1", "Boolean 1", PT_BOOL, obj_a_t, a_bool1)}, + {PROPDEF1("str1", "String 1", PT_STR, obj_a_t, a_str1)}, + }}; + +static void obj_b_save(idnode_t* self); + +const idclass_t obj_b_class = {.ic_super = &obj_a_class, + .ic_class = "obj_b", + .ic_caption = N_("Object B"), + .ic_save = obj_b_save, + .ic_properties = (const property_t[]){ + {PROPDEF1("int2", "Integer 2", PT_INT, obj_b_t, b_int2)}, + {PROPDEF1("bool2", "Boolean 2", PT_BOOL, obj_b_t, b_bool2)}, + {PROPDEF1("str2", "String 2", PT_STR, obj_b_t, b_str2)}, + }}; + +static void obj_a_func1(void* self) { + obj_a_t* a = self; printf("a->a_int1 = %d\n", a->a_int1); } -static obj_a_t * -obj_a_create1 ( size_t alloc, const idclass_t *class, const char *uuid ) -{ - obj_a_t *a = idnode_create(alloc, class, uuid); +static obj_a_t* obj_a_create1(size_t alloc, const idclass_t* class, const char* uuid) { + obj_a_t* a = idnode_create(alloc, class, uuid); a->a_func1 = obj_a_func1; return a; } -#define obj_a_create(type, uuid)\ +#define obj_a_create(type, uuid) \ (struct type*)obj_a_create1(sizeof(struct type), &type##_class, uuid) -static void -obj_b_func1 ( void *self ) -{ - obj_b_t *b = self; +static void obj_b_func1(void* self) { + obj_b_t* b = self; printf("b->a_int1 = %d\n", b->a_int1); printf("b->b_int2 = %d\n", b->b_int2); } -obj_b_t * -obj_b_create ( const char *uuid ) -{ - obj_b_t *b = obj_a_create(obj_b, uuid); +obj_b_t* obj_b_create(const char* uuid) { + obj_b_t* b = obj_a_create(obj_b, uuid); b->a_func1 = obj_b_func1; b->a_bool1 = 0; b->b_bool2 = 1; @@ -64,12 +52,10 @@ obj_b_create ( const char *uuid ) return b; } -void obj_b_save ( idnode_t *self ) -{ +void obj_b_save(idnode_t* self) { idnode_save(self, "test"); } -void obj_b_load_all ( void ) -{ - idnode_load_all("test", (void*(*)(const char*))obj_b_create); +void obj_b_load_all(void) { + idnode_load_all("test", (void* (*)(const char*))obj_b_create); } diff --git a/src/test.h b/src/test.h index 463aa17d6..d4ce280ad 100644 --- a/src/test.h +++ b/src/test.h @@ -3,30 +3,28 @@ #include /* Parent */ -typedef struct obj_a -{ +typedef struct obj_a { idnode_t a_id; - + uint32_t a_int1; int a_bool1; - char *a_str1; + char* a_str1; - void (*a_func1) (void *a); + void (*a_func1)(void* a); } obj_a_t; extern const idclass_t obj_a_class; /* Child */ -typedef struct obj_b -{ +typedef struct obj_b { obj_a_t; uint32_t b_int2; int b_bool2; - char *b_str2; + char* b_str2; } obj_b_t; -obj_b_t *obj_b_create ( const char *uuid ); -void obj_b_load_all ( void ); +obj_b_t* obj_b_create(const char* uuid); +void obj_b_load_all(void); diff --git a/src/timeshift.c b/src/timeshift.c index be5655318..24fb94b39 100644 --- a/src/timeshift.c +++ b/src/timeshift.c @@ -38,35 +38,32 @@ static int timeshift_index = 0; struct timeshift_conf timeshift_conf; -memoryinfo_t timeshift_memoryinfo = { .my_name = "Timeshift" }; -memoryinfo_t timeshift_memoryinfo_ram = { .my_name = "Timeshift RAM buffer" }; +memoryinfo_t timeshift_memoryinfo = {.my_name = "Timeshift"}; +memoryinfo_t timeshift_memoryinfo_ram = {.my_name = "Timeshift RAM buffer"}; /* * Packet log */ -void -timeshift_packet_log0 - ( const char *source, timeshift_t *ts, streaming_message_t *sm ) -{ - th_pkt_t *pkt = sm->sm_data; +void timeshift_packet_log0(const char* source, timeshift_t* ts, streaming_message_t* sm) { + th_pkt_t* pkt = sm->sm_data; tvhtrace(LS_TIMESHIFT, - "ts %d pkt %s - stream %d type %c pts %10"PRId64 - " dts %10"PRId64" dur %10d len %6zu time %14"PRId64, - ts->id, source, - pkt->pkt_componentindex, - SCT_ISVIDEO(pkt->pkt_type) ? pkt_frametype_to_char(pkt->v.pkt_frametype) : '-', - ts_rescale(pkt->pkt_pts, 1000000), - ts_rescale(pkt->pkt_dts, 1000000), - pkt->pkt_duration, - pktbuf_len(pkt->pkt_payload), - sm->sm_time); + "ts %d pkt %s - stream %d type %c pts %10" PRId64 " dts %10" PRId64 + " dur %10d len %6zu time %14" PRId64, + ts->id, + source, + pkt->pkt_componentindex, + SCT_ISVIDEO(pkt->pkt_type) ? pkt_frametype_to_char(pkt->v.pkt_frametype) : '-', + ts_rescale(pkt->pkt_pts, 1000000), + ts_rescale(pkt->pkt_dts, 1000000), + pkt->pkt_duration, + pktbuf_len(pkt->pkt_payload), + sm->sm_time); } /* * Safe values for RAM configuration */ -static void timeshift_fixup ( void ) -{ +static void timeshift_fixup(void) { if (timeshift_conf.ram_only) timeshift_conf.max_size = timeshift_conf.ram_size; } @@ -74,9 +71,8 @@ static void timeshift_fixup ( void ) /* * Intialise global file manager */ -void timeshift_init ( void ) -{ - htsmsg_t *m; +void timeshift_init(void) { + htsmsg_t* m; memoryinfo_register(×hift_memoryinfo); memoryinfo_register(×hift_memoryinfo_ram); @@ -86,8 +82,8 @@ void timeshift_init ( void ) /* Defaults */ memset(×hift_conf, 0, sizeof(timeshift_conf)); timeshift_conf.idnode.in_class = ×hift_conf_class; - timeshift_conf.max_period = 60; // Hr (60mins) - timeshift_conf.max_size = 10000 * (size_t)1048576; // 10G + timeshift_conf.max_period = 60; // Hr (60mins) + timeshift_conf.max_size = 10000 * (size_t)1048576; // 10G idclass_register(×hift_conf_class); @@ -102,8 +98,7 @@ void timeshift_init ( void ) /* * Terminate global file manager */ -void timeshift_term ( void ) -{ +void timeshift_term(void) { timeshift_filemgr_term(); free(timeshift_conf.path); timeshift_conf.path = NULL; @@ -115,19 +110,15 @@ void timeshift_term ( void ) /* * Changed settings */ -static void -timeshift_conf_class_changed ( idnode_t *self ) -{ +static void timeshift_conf_class_changed(idnode_t* self) { timeshift_fixup(); } /* * Save settings */ -static htsmsg_t * -timeshift_conf_class_save ( idnode_t *self, char *filename, size_t fsize ) -{ - htsmsg_t *m = htsmsg_create_map(); +static htsmsg_t* timeshift_conf_class_save(idnode_t* self, char* filename, size_t fsize) { + htsmsg_t* m = htsmsg_create_map(); idnode_save(×hift_conf.idnode, m); if (filename) snprintf(filename, fsize, "timeshift/config"); @@ -137,18 +128,14 @@ timeshift_conf_class_save ( idnode_t *self, char *filename, size_t fsize ) /* * Class */ -static const void * -timeshift_conf_class_max_size_get ( void *o ) -{ +static const void* timeshift_conf_class_max_size_get(void* o) { static uint64_t r; r = timeshift_conf.max_size / 1048576LL; return &r; } -static int -timeshift_conf_class_max_size_set ( void *o, const void *v ) -{ - uint64_t u64 = *(uint64_t *)v * 1048576LL; +static int timeshift_conf_class_max_size_set(void* o, const void* v) { + uint64_t u64 = *(uint64_t*)v * 1048576LL; if (u64 != timeshift_conf.max_size) { timeshift_conf.max_size = u64; return 1; @@ -156,18 +143,14 @@ timeshift_conf_class_max_size_set ( void *o, const void *v ) return 0; } -static const void * -timeshift_conf_class_ram_size_get ( void *o ) -{ +static const void* timeshift_conf_class_ram_size_get(void* o) { static uint64_t r; r = timeshift_conf.ram_size / 1048576LL; return &r; } -static int -timeshift_conf_class_ram_size_set ( void *o, const void *v ) -{ - uint64_t u64 = *(uint64_t *)v * 1048576LL; +static int timeshift_conf_class_ram_size_set(void* o, const void* v) { + uint64_t u64 = *(uint64_t*)v * 1048576LL; timeshift_conf.ram_segment_size = u64 / 10; if (u64 != timeshift_conf.ram_size) { timeshift_conf.ram_size = u64; @@ -178,140 +161,134 @@ timeshift_conf_class_ram_size_set ( void *o, const void *v ) CLASS_DOC(timeshift) -const idclass_t timeshift_conf_class = { - .ic_snode = ×hift_conf.idnode, - .ic_class = "timeshift", - .ic_caption = N_("Timeshift"), - .ic_doc = tvh_doc_timeshift_class, - .ic_event = "timeshift", - .ic_perm_def = ACCESS_ADMIN, - .ic_changed = timeshift_conf_class_changed, - .ic_save = timeshift_conf_class_save, - .ic_properties = (const property_t[]){ - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Enable/Disable timeshift."), - .off = offsetof(timeshift_conf_t, enabled), - }, - { - .type = PT_BOOL, - .id = "ondemand", - .name = N_("On-demand (no first rewind)"), - .desc = N_("Only activate timeshift when the client makes the first " - "rewind, fast-forward or pause request. Note, " - "because there is no buffer on the first request " - "rewinding is not possible at that point."), - .off = offsetof(timeshift_conf_t, ondemand), - .opts = PO_EXPERT, - }, - { - .type = PT_STR, - .id = "path", - .name = N_("Storage path"), - .desc = N_("Path to where the timeshift data will be stored. " - "If nothing is specified this will default to " - "CONF_DIR/timeshift/buffer."), - .off = offsetof(timeshift_conf_t, path), - .opts = PO_ADVANCED, - }, - { - .type = PT_U32, - .id = "max_period", - .name = N_("Maximum period (mins)"), - .desc = N_("The maximum time period that will be buffered for " - "any given (client) subscription."), - .off = offsetof(timeshift_conf_t, max_period), - }, - { - .type = PT_BOOL, - .id = "unlimited_period", - .name = N_("Unlimited time"), - .desc = N_("Allow the timeshift buffer to grow unbounded until " - "your storage media runs out of space. Warning, " - "enabling this option may cause your system to slow " - "down or crash completely!"), - .off = offsetof(timeshift_conf_t, unlimited_period), - .opts = PO_EXPERT, - }, - { - .type = PT_S64, - .id = "max_size", - .name = N_("Maximum size (MB)"), - .desc = N_("The maximum combined size of all timeshift buffers. " - "If you specify an unlimited period it's highly " - "recommended you specify a value here."), - .set = timeshift_conf_class_max_size_set, - .get = timeshift_conf_class_max_size_get, - .opts = PO_ADVANCED, - }, - { - .type = PT_S64, - .id = "ram_size", - .name = N_("Maximum RAM size (MB)"), - .desc = N_("The maximum RAM (system memory) size for timeshift " - "buffers. When free RAM buffers are available they " - "are used for timeshift data in preference to using " - "storage."), - .set = timeshift_conf_class_ram_size_set, - .get = timeshift_conf_class_ram_size_get, - .opts = PO_ADVANCED, - }, - { - .type = PT_BOOL, - .id = "unlimited_size", - .name = N_("Unlimited size"), - .desc = N_("Allow the combined size of all timeshift buffers to " - "potentially grow unbounded until your storage media " - "runs out of space."), - .off = offsetof(timeshift_conf_t, unlimited_size), - .opts = PO_EXPERT, - }, - { - .type = PT_BOOL, - .id = "ram_only", - .name = N_("RAM only"), - .desc = N_("Keep timeshift buffers in RAM only. " - "With this option enabled, the amount of rewind time " - "is limited by how much RAM TVHeadend is allowed."), - .off = offsetof(timeshift_conf_t, ram_only), - .opts = PO_ADVANCED, - }, - { - .type = PT_BOOL, - .id = "ram_fit", - .name = N_("Fit to RAM (cut rewind)"), - .desc = N_("With \"RAM only\" enabled, and when \"Maximum RAM " - "size\" is reached, remove the oldest segment in the " - "buffer instead of replacing it completely. Note, " - "this may reduce the amount of rewind time."), - .off = offsetof(timeshift_conf_t, ram_fit), - .opts = PO_EXPERT, - }, - { - .type = PT_BOOL, - .id = "teletext", - .name = N_("Include teletext"), - .desc = N_("Include teletext in the timeshift buffer. Enabling " - "this may cause issues with some services where the " - "teletext DTS is invalid."), - .off = offsetof(timeshift_conf_t, teletext), - .opts = PO_EXPERT, - }, - {} - } -}; +const idclass_t timeshift_conf_class = {.ic_snode = ×hift_conf.idnode, + .ic_class = "timeshift", + .ic_caption = N_("Timeshift"), + .ic_doc = tvh_doc_timeshift_class, + .ic_event = "timeshift", + .ic_perm_def = ACCESS_ADMIN, + .ic_changed = timeshift_conf_class_changed, + .ic_save = timeshift_conf_class_save, + .ic_properties = (const property_t[]){{ + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Enable/Disable timeshift."), + .off = offsetof(timeshift_conf_t, enabled), + }, + { + .type = PT_BOOL, + .id = "ondemand", + .name = N_("On-demand (no first rewind)"), + .desc = N_("Only activate timeshift when the client makes the first " + "rewind, fast-forward or pause request. Note, " + "because there is no buffer on the first request " + "rewinding is not possible at that point."), + .off = offsetof(timeshift_conf_t, ondemand), + .opts = PO_EXPERT, + }, + { + .type = PT_STR, + .id = "path", + .name = N_("Storage path"), + .desc = N_("Path to where the timeshift data will be stored. " + "If nothing is specified this will default to " + "CONF_DIR/timeshift/buffer."), + .off = offsetof(timeshift_conf_t, path), + .opts = PO_ADVANCED, + }, + { + .type = PT_U32, + .id = "max_period", + .name = N_("Maximum period (mins)"), + .desc = N_("The maximum time period that will be buffered for " + "any given (client) subscription."), + .off = offsetof(timeshift_conf_t, max_period), + }, + { + .type = PT_BOOL, + .id = "unlimited_period", + .name = N_("Unlimited time"), + .desc = N_("Allow the timeshift buffer to grow unbounded until " + "your storage media runs out of space. Warning, " + "enabling this option may cause your system to slow " + "down or crash completely!"), + .off = offsetof(timeshift_conf_t, unlimited_period), + .opts = PO_EXPERT, + }, + { + .type = PT_S64, + .id = "max_size", + .name = N_("Maximum size (MB)"), + .desc = N_("The maximum combined size of all timeshift buffers. " + "If you specify an unlimited period it's highly " + "recommended you specify a value here."), + .set = timeshift_conf_class_max_size_set, + .get = timeshift_conf_class_max_size_get, + .opts = PO_ADVANCED, + }, + { + .type = PT_S64, + .id = "ram_size", + .name = N_("Maximum RAM size (MB)"), + .desc = N_("The maximum RAM (system memory) size for timeshift " + "buffers. When free RAM buffers are available they " + "are used for timeshift data in preference to using " + "storage."), + .set = timeshift_conf_class_ram_size_set, + .get = timeshift_conf_class_ram_size_get, + .opts = PO_ADVANCED, + }, + { + .type = PT_BOOL, + .id = "unlimited_size", + .name = N_("Unlimited size"), + .desc = N_("Allow the combined size of all timeshift buffers to " + "potentially grow unbounded until your storage media " + "runs out of space."), + .off = offsetof(timeshift_conf_t, unlimited_size), + .opts = PO_EXPERT, + }, + { + .type = PT_BOOL, + .id = "ram_only", + .name = N_("RAM only"), + .desc = N_("Keep timeshift buffers in RAM only. " + "With this option enabled, the amount of rewind time " + "is limited by how much RAM TVHeadend is allowed."), + .off = offsetof(timeshift_conf_t, ram_only), + .opts = PO_ADVANCED, + }, + { + .type = PT_BOOL, + .id = "ram_fit", + .name = N_("Fit to RAM (cut rewind)"), + .desc = N_("With \"RAM only\" enabled, and when \"Maximum RAM " + "size\" is reached, remove the oldest segment in the " + "buffer instead of replacing it completely. Note, " + "this may reduce the amount of rewind time."), + .off = offsetof(timeshift_conf_t, ram_fit), + .opts = PO_EXPERT, + }, + { + .type = PT_BOOL, + .id = "teletext", + .name = N_("Include teletext"), + .desc = N_("Include teletext in the timeshift buffer. Enabling " + "this may cause issues with some services where the " + "teletext DTS is invalid."), + .off = offsetof(timeshift_conf_t, teletext), + .opts = PO_EXPERT, + }, + {}}}; /* * Process a packet */ -static int -timeshift_packet( timeshift_t *ts, streaming_message_t *sm ) -{ - th_pkt_t *pkt = sm->sm_data; - int64_t time; +static int timeshift_packet(timeshift_t* ts, streaming_message_t* sm) { + th_pkt_t* pkt = sm->sm_data; + int64_t time; if (pkt->pkt_pts != PTS_UNSET) { /* avoid to update last_wr_time for TELETEXT packets */ @@ -330,12 +307,10 @@ timeshift_packet( timeshift_t *ts, streaming_message_t *sm ) /* * Receive data */ -static void timeshift_input - ( void *opaque, streaming_message_t *sm ) -{ - int type = sm->sm_type; - timeshift_t *ts = opaque; - th_pkt_t *pkt, *pkt2; +static void timeshift_input(void* opaque, streaming_message_t* sm) { + int type = sm->sm_type; + timeshift_t* ts = opaque; + th_pkt_t * pkt, *pkt2; if (ts->exit) return; @@ -351,17 +326,18 @@ static void timeshift_input /* Change PTS/DTS offsets */ if (ts->packet_mode && ts->start_pts && type == SMT_PACKET) { - pkt = sm->sm_data; + pkt = sm->sm_data; pkt2 = pkt_copy_shallow(pkt); pkt_ref_dec(pkt); sm->sm_data = pkt2; - if (pkt2->pkt_pts != PTS_UNSET) pkt2->pkt_pts += ts->start_pts; - if (pkt2->pkt_dts != PTS_UNSET) pkt2->pkt_dts += ts->start_pts; + if (pkt2->pkt_pts != PTS_UNSET) + pkt2->pkt_pts += ts->start_pts; + if (pkt2->pkt_dts != PTS_UNSET) + pkt2->pkt_dts += ts->start_pts; } /* Check for exit */ - else if (type == SMT_EXIT || - (type == SMT_STOP && sm->sm_code != SM_CODE_SOURCE_RECONFIGURED)) + else if (type == SMT_EXIT || (type == SMT_STOP && sm->sm_code != SM_CODE_SOURCE_RECONFIGURED)) ts->exit = 1; else if (type == SMT_MPEGTS) @@ -375,7 +351,7 @@ static void timeshift_input } else { if (ts->ref_time == 0) { ts->ref_time = getfastmonoclock(); - sm->sm_time = 0; + sm->sm_time = 0; } else { sm->sm_time = getfastmonoclock() - ts->ref_time; } @@ -383,33 +359,26 @@ static void timeshift_input streaming_target_deliver2(&ts->wr_queue.sq_st, sm); /* Exit/Stop */ -_exit: + _exit: if (ts->exit) timeshift_write_exit(ts->rd_pipe.wr); } } -static htsmsg_t * -timeshift_input_info(void *opaque, htsmsg_t *list) -{ +static htsmsg_t* timeshift_input_info(void* opaque, htsmsg_t* list) { htsmsg_add_str(list, NULL, "wtimeshift input"); return list; } -static streaming_ops_t timeshift_input_ops = { - .st_cb = timeshift_input, - .st_info = timeshift_input_info -}; - +static streaming_ops_t timeshift_input_ops = {.st_cb = timeshift_input, + .st_info = timeshift_input_info}; /** * */ -void -timeshift_destroy(streaming_target_t *pad) -{ - timeshift_t *ts = (timeshift_t*)pad; - streaming_message_t *sm; +void timeshift_destroy(streaming_target_t* pad) { + timeshift_t* ts = (timeshift_t*)pad; + streaming_message_t* sm; /* Must hold global lock */ lock_assert(&global_lock); @@ -453,10 +422,8 @@ timeshift_destroy(streaming_target_t *pad) * max_period of buffer in seconds (0 = unlimited) * max_size of buffer in bytes (0 = unlimited) */ -streaming_target_t *timeshift_create - (streaming_target_t *out, time_t max_time) -{ - timeshift_t *ts = calloc(1, sizeof(timeshift_t)); +streaming_target_t* timeshift_create(streaming_target_t* out, time_t max_time) { + timeshift_t* ts = calloc(1, sizeof(timeshift_t)); memoryinfo_alloc(×hift_memoryinfo, sizeof(timeshift_t)); @@ -465,24 +432,24 @@ streaming_target_t *timeshift_create /* Setup structure */ TAILQ_INIT(&ts->files); - ts->output = out; - ts->path = NULL; - ts->max_time = max_time; - ts->state = TS_LIVE; - ts->exit = 0; - ts->full = 0; - ts->vididx = -1; - ts->id = timeshift_index; - ts->ondemand = timeshift_conf.ondemand; - ts->dobuf = ts->ondemand ? 0 : 1; - ts->packet_mode= 1; - ts->last_wr_time = 0; - ts->buf_time = 0; - ts->start_pts = 0; - ts->ref_time = 0; - ts->seek.file = NULL; - ts->seek.frame = NULL; - ts->ram_segments = 0; + ts->output = out; + ts->path = NULL; + ts->max_time = max_time; + ts->state = TS_LIVE; + ts->exit = 0; + ts->full = 0; + ts->vididx = -1; + ts->id = timeshift_index; + ts->ondemand = timeshift_conf.ondemand; + ts->dobuf = ts->ondemand ? 0 : 1; + ts->packet_mode = 1; + ts->last_wr_time = 0; + ts->buf_time = 0; + ts->start_pts = 0; + ts->ref_time = 0; + ts->seek.file = NULL; + ts->seek.frame = NULL; + ts->ram_segments = 0; ts->file_segments = 0; tvh_mutex_init(&ts->state_mutex, NULL); diff --git a/src/timeshift.h b/src/timeshift.h index a97621cb5..bc2822bb8 100644 --- a/src/timeshift.h +++ b/src/timeshift.h @@ -24,35 +24,34 @@ #include "memoryinfo.h" typedef struct timeshift_conf { - idnode_t idnode; - int enabled; - int ondemand; - char *path; - int unlimited_period; - uint32_t max_period; - int unlimited_size; - uint64_t max_size; - uint64_t total_size; - uint64_t ram_size; - uint64_t ram_segment_size; - uint64_t total_ram_size; - int ram_only; - int ram_fit; - int teletext; + idnode_t idnode; + int enabled; + int ondemand; + char* path; + int unlimited_period; + uint32_t max_period; + int unlimited_size; + uint64_t max_size; + uint64_t total_size; + uint64_t ram_size; + uint64_t ram_segment_size; + uint64_t total_ram_size; + int ram_only; + int ram_fit; + int teletext; } timeshift_conf_t; extern struct timeshift_conf timeshift_conf; -extern const idclass_t timeshift_conf_class; +extern const idclass_t timeshift_conf_class; extern memoryinfo_t timeshift_memoryinfo; extern memoryinfo_t timeshift_memoryinfo_ram; -void timeshift_init ( void ); -void timeshift_term ( void ); +void timeshift_init(void); +void timeshift_term(void); -streaming_target_t *timeshift_create - (streaming_target_t *out, time_t max_period); +streaming_target_t* timeshift_create(streaming_target_t* out, time_t max_period); -void timeshift_destroy(streaming_target_t *pad); +void timeshift_destroy(streaming_target_t* pad); #endif /* __TVH_TIMESHIFT_H__ */ diff --git a/src/timeshift/private.h b/src/timeshift/private.h index c6a5609f2..6b1629eee 100644 --- a/src/timeshift/private.h +++ b/src/timeshift/private.h @@ -19,72 +19,70 @@ #ifndef __TVH_TIMESHIFT_PRIVATE_H__ #define __TVH_TIMESHIFT_PRIVATE_H__ -#define TIMESHIFT_PLAY_BUF 1000000 //< us to buffer in TX -#define TIMESHIFT_FILE_PERIOD 60 //< number of secs in each buffer file -#define TIMESHIFT_BACKLOG_MAX 16 //< maximum elementary streams +#define TIMESHIFT_PLAY_BUF 1000000 //< us to buffer in TX +#define TIMESHIFT_FILE_PERIOD 60 //< number of secs in each buffer file +#define TIMESHIFT_BACKLOG_MAX 16 //< maximum elementary streams /** * Indexes of import data in the stream */ -typedef struct timeshift_index_iframe -{ - off_t pos; ///< Position in the file - int64_t time; ///< Packet time - TAILQ_ENTRY(timeshift_index_iframe) link; ///< List entry +typedef struct timeshift_index_iframe { + off_t pos; ///< Position in the file + int64_t time; ///< Packet time + TAILQ_ENTRY(timeshift_index_iframe) link; ///< List entry } timeshift_index_iframe_t; -typedef TAILQ_HEAD(timeshift_index_iframe_list,timeshift_index_iframe) timeshift_index_iframe_list_t; +typedef TAILQ_HEAD(timeshift_index_iframe_list, + timeshift_index_iframe) timeshift_index_iframe_list_t; /** * Indexes of import data in the stream */ -typedef struct timeshift_index_data -{ - off_t pos; ///< Position in the file - streaming_message_t *data; ///< Associated data - TAILQ_ENTRY(timeshift_index_data) link; ///< List entry +typedef struct timeshift_index_data { + off_t pos; ///< Position in the file + streaming_message_t* data; ///< Associated data + TAILQ_ENTRY(timeshift_index_data) link; ///< List entry } timeshift_index_data_t; -typedef TAILQ_HEAD(timeshift_index_data_list,timeshift_index_data) timeshift_index_data_list_t; +typedef TAILQ_HEAD(timeshift_index_data_list, timeshift_index_data) timeshift_index_data_list_t; /** * Timeshift file */ -typedef struct timeshift_file -{ - int wfd; ///< Write descriptor - int rfd; ///< Read descriptor - char *path; ///< Full path to file +typedef struct timeshift_file { + int wfd; ///< Write descriptor + int rfd; ///< Read descriptor + char* path; ///< Full path to file - int64_t time; ///< Files coarse timestamp - size_t size; ///< Current file size; - int64_t last; ///< Latest timestamp - off_t woff; ///< Write offset - off_t roff; ///< Read offset + int64_t time; ///< Files coarse timestamp + size_t size; ///< Current file size; + int64_t last; ///< Latest timestamp + off_t woff; ///< Write offset + off_t roff; ///< Read offset - uint8_t *ram; ///< RAM area - int64_t ram_size; ///< RAM area size in bytes + uint8_t* ram; ///< RAM area + int64_t ram_size; ///< RAM area size in bytes - uint8_t bad; ///< File is broken + uint8_t bad; ///< File is broken - int refcount; ///< Reader ref count + int refcount; ///< Reader ref count - timeshift_index_iframe_list_t iframes; ///< I-frame indexing - timeshift_index_data_list_t sstart; ///< Stream start messages + timeshift_index_iframe_list_t iframes; ///< I-frame indexing + timeshift_index_data_list_t sstart; ///< Stream start messages - TAILQ_ENTRY(timeshift_file) link; ///< List entry + TAILQ_ENTRY(timeshift_file) link; ///< List entry - tvh_mutex_t ram_lock; ///< Mutex for the ram array access + tvh_mutex_t ram_lock; ///< Mutex for the ram array access } timeshift_file_t; -typedef TAILQ_HEAD(timeshift_file_list,timeshift_file) timeshift_file_list_t; +typedef TAILQ_HEAD(timeshift_file_list, timeshift_file) timeshift_file_list_t; /** * */ typedef struct timeshift_seek { - timeshift_file_t *file; - timeshift_index_iframe_t *frame; + timeshift_file_t* file; + timeshift_index_iframe_t* frame; } timeshift_seek_t; /** @@ -92,50 +90,50 @@ typedef struct timeshift_seek { */ typedef struct timeshift { // Note: input MUST BE FIRST in struct - streaming_target_t input; ///< Input source - streaming_target_t *output; ///< Output dest - - int id; ///< Reference number - char *path; ///< Directory containing buffer - time_t max_time; ///< Maximum period to shift - int ondemand; ///< Whether this is an on-demand timeshift - int packet_mode;///< Packet mode (otherwise MPEG-TS data mode) - int dobuf; ///< Buffer packets (store) - int64_t last_wr_time;///< Last write time in us (PTS conversion) - int64_t start_pts; ///< Start time for packets (PTS) - int64_t ref_time; ///< Start time in us (monoclock) - int64_t buf_time; ///< Last buffered time in us (PTS conversion) - int backlog_max;///< Maximum component index in backlog + streaming_target_t input; ///< Input source + streaming_target_t* output; ///< Output dest + + int id; ///< Reference number + char* path; ///< Directory containing buffer + time_t max_time; ///< Maximum period to shift + int ondemand; ///< Whether this is an on-demand timeshift + int packet_mode; ///< Packet mode (otherwise MPEG-TS data mode) + int dobuf; ///< Buffer packets (store) + int64_t last_wr_time; ///< Last write time in us (PTS conversion) + int64_t start_pts; ///< Start time for packets (PTS) + int64_t ref_time; ///< Start time in us (monoclock) + int64_t buf_time; ///< Last buffered time in us (PTS conversion) + int backlog_max; ///< Maximum component index in backlog enum { TS_EXIT, TS_LIVE, TS_PAUSE, TS_PLAY, - } state; ///< Play state - tvh_mutex_t state_mutex; ///< Protect state changes - uint8_t exit; ///< Exit from the main input thread - uint8_t full; ///< Buffer is full + } state; ///< Play state + tvh_mutex_t state_mutex; ///< Protect state changes + uint8_t exit; ///< Exit from the main input thread + uint8_t full; ///< Buffer is full - timeshift_seek_t seek; ///< Seek into buffered data - - streaming_queue_t wr_queue; ///< Writer queue - pthread_t wr_thread; ///< Writer thread + timeshift_seek_t seek; ///< Seek into buffered data - pthread_t rd_thread; ///< Reader thread - th_pipe_t rd_pipe; ///< Message passing to reader + streaming_queue_t wr_queue; ///< Writer queue + pthread_t wr_thread; ///< Writer thread - timeshift_file_list_t files; ///< List of files + pthread_t rd_thread; ///< Reader thread + th_pipe_t rd_pipe; ///< Message passing to reader - int ram_segments; ///< Count of segments in RAM - int file_segments; ///< Count of segments in files + timeshift_file_list_t files; ///< List of files - int vididx; ///< Index of (current) video stream - int audidx; ///< Index of (current) audio stream - - uint8_t audio_packet_counter; ///< Counter for audio packets in audio-only streams + int ram_segments; ///< Count of segments in RAM + int file_segments; ///< Count of segments in files - streaming_start_t *smt_start; ///< Streaming start info + int vididx; ///< Index of (current) video stream + int audidx; ///< Index of (current) audio stream + + uint8_t audio_packet_counter; ///< Counter for audio packets in audio-only streams + + streaming_start_t* smt_start; ///< Streaming start info } timeshift_t; @@ -145,12 +143,10 @@ typedef struct timeshift { extern uint64_t timeshift_total_size; extern uint64_t timeshift_total_ram_size; -void timeshift_packet_log0 - ( const char *prefix, timeshift_t *ts, streaming_message_t *sm ); +void timeshift_packet_log0(const char* prefix, timeshift_t* ts, streaming_message_t* sm); -static inline void timeshift_packet_log - ( const char *prefix, timeshift_t *ts, streaming_message_t *sm ) -{ +static inline void +timeshift_packet_log(const char* prefix, timeshift_t* ts, streaming_message_t* sm) { if (sm->sm_type == SMT_PACKET && tvhtrace_enabled()) timeshift_packet_log0(prefix, ts, sm); } @@ -158,76 +154,69 @@ static inline void timeshift_packet_log /* * Write functions */ -ssize_t timeshift_write_start ( timeshift_file_t *tsf, int64_t time, streaming_start_t *ss ); -ssize_t timeshift_write_sigstat ( timeshift_file_t *tsf, int64_t time, signal_status_t *ss ); -ssize_t timeshift_write_packet ( timeshift_file_t *tsf, int64_t time, th_pkt_t *pkt ); -ssize_t timeshift_write_mpegts ( timeshift_file_t *tsf, int64_t time, void *data ); -ssize_t timeshift_write_skip ( int fd, streaming_skip_t *skip ); -ssize_t timeshift_write_speed ( int fd, int speed ); -ssize_t timeshift_write_stop ( int fd, int code ); -ssize_t timeshift_write_exit ( int fd ); -ssize_t timeshift_write_eof ( timeshift_file_t *tsf ); +ssize_t timeshift_write_start(timeshift_file_t* tsf, int64_t time, streaming_start_t* ss); +ssize_t timeshift_write_sigstat(timeshift_file_t* tsf, int64_t time, signal_status_t* ss); +ssize_t timeshift_write_packet(timeshift_file_t* tsf, int64_t time, th_pkt_t* pkt); +ssize_t timeshift_write_mpegts(timeshift_file_t* tsf, int64_t time, void* data); +ssize_t timeshift_write_skip(int fd, streaming_skip_t* skip); +ssize_t timeshift_write_speed(int fd, int speed); +ssize_t timeshift_write_stop(int fd, int code); +ssize_t timeshift_write_exit(int fd); +ssize_t timeshift_write_eof(timeshift_file_t* tsf); /* * Threads */ -void *timeshift_reader ( void *p ); -void *timeshift_writer ( void *p ); +void* timeshift_reader(void* p); +void* timeshift_writer(void* p); /* * File management */ -void timeshift_filemgr_init ( void ); -void timeshift_filemgr_term ( void ); -int timeshift_filemgr_makedirs ( int ts_index, char *buf, size_t len ); +void timeshift_filemgr_init(void); +void timeshift_filemgr_term(void); +int timeshift_filemgr_makedirs(int ts_index, char* buf, size_t len); -static inline void timeshift_file_get0 ( timeshift_file_t *tsf ) -{ +static inline void timeshift_file_get0(timeshift_file_t* tsf) { if (tsf) tsf->refcount++; } -#define timeshift_file_get(tsf) ({ \ - timeshift_file_get0(tsf); \ - /* tvhtrace("timeshift", "file get %p refcount %d fcn %s:%d", \ - tsf, tsf ? tsf->refcount : -1, __FUNCTION__, __LINE__); */ \ - tsf; \ -}) +#define timeshift_file_get(tsf) \ + ({ \ + timeshift_file_get0(tsf); \ + /* tvhtrace("timeshift", "file get %p refcount %d fcn %s:%d", \ + tsf, tsf ? tsf->refcount : -1, __FUNCTION__, __LINE__); */ \ + tsf; \ + }) -static inline void timeshift_file_put0 ( timeshift_file_t *tsf ) -{ +static inline void timeshift_file_put0(timeshift_file_t* tsf) { if (tsf) { assert(tsf->refcount > 0); tsf->refcount--; } } -#define timeshift_file_put(tsf) ({ \ - /* tvhtrace("timeshift", "file put %p refcount %d fcn %s:%d", \ - tsf, tsf ? (tsf->refcount - 1) : -1, __FUNCTION__, __LINE__); */ \ - timeshift_file_put0(tsf); \ - tsf; \ -}) - -timeshift_file_t *timeshift_filemgr_get - ( timeshift_t *ts, int64_t start_time ); -timeshift_file_t *timeshift_filemgr_oldest - ( timeshift_t *ts ); -timeshift_file_t *timeshift_filemgr_newest - ( timeshift_t *ts ); -timeshift_file_t *timeshift_filemgr_prev - ( timeshift_file_t *ts, int *end, int keep ); -timeshift_file_t *timeshift_filemgr_next - ( timeshift_file_t *ts, int *end, int keep ); -void timeshift_filemgr_remove - ( timeshift_t *ts, timeshift_file_t *tsf, int force ); -void timeshift_filemgr_flush ( timeshift_t *ts, timeshift_file_t *end ); -void timeshift_filemgr_close ( timeshift_file_t *tsf ); - -void timeshift_filemgr_dump0 ( timeshift_t *ts ); - -static inline void timeshift_filemgr_dump ( timeshift_t *ts ) -{ +#define timeshift_file_put(tsf) \ + ({ \ + /* tvhtrace("timeshift", "file put %p refcount %d fcn %s:%d", \ + tsf, tsf ? (tsf->refcount - 1) : -1, __FUNCTION__, __LINE__); */ \ + timeshift_file_put0(tsf); \ + tsf; \ + }) + +timeshift_file_t* timeshift_filemgr_get(timeshift_t* ts, int64_t start_time); +timeshift_file_t* timeshift_filemgr_oldest(timeshift_t* ts); +timeshift_file_t* timeshift_filemgr_newest(timeshift_t* ts); +timeshift_file_t* timeshift_filemgr_prev(timeshift_file_t* ts, int* end, int keep); +timeshift_file_t* timeshift_filemgr_next(timeshift_file_t* ts, int* end, int keep); +void timeshift_filemgr_remove(timeshift_t* ts, timeshift_file_t* tsf, int force); +void timeshift_filemgr_flush(timeshift_t* ts, timeshift_file_t* end); +void timeshift_filemgr_close(timeshift_file_t* tsf); + +void timeshift_filemgr_dump0(timeshift_t* ts); + +static inline void timeshift_filemgr_dump(timeshift_t* ts) { if (tvhtrace_enabled()) timeshift_filemgr_dump0(ts); } diff --git a/src/timeshift/timeshift_filemgr.c b/src/timeshift/timeshift_filemgr.c index e82e2cf33..73a2b1776 100644 --- a/src/timeshift/timeshift_filemgr.c +++ b/src/timeshift/timeshift_filemgr.c @@ -29,23 +29,22 @@ static int timeshift_reaper_run; static timeshift_file_list_t timeshift_reaper_list; static pthread_t timeshift_reaper_thread; -static tvh_mutex_t timeshift_reaper_lock; +static tvh_mutex_t timeshift_reaper_lock; static tvh_cond_t timeshift_reaper_cond; -uint64_t timeshift_total_size; -uint64_t timeshift_total_ram_size; +uint64_t timeshift_total_size; +uint64_t timeshift_total_ram_size; /* ************************************************************************** * File reaper thread * *************************************************************************/ -static void* timeshift_reaper_callback ( void *p ) -{ - char *dpath; - timeshift_file_t *tsf; - timeshift_index_iframe_t *ti; - timeshift_index_data_t *tid; - streaming_message_t *sm; +static void* timeshift_reaper_callback(void* p) { + char* dpath; + timeshift_file_t* tsf; + timeshift_index_iframe_t* ti; + timeshift_index_data_t* tid; + streaming_message_t* sm; tvh_mutex_lock(×hift_reaper_lock); while (timeshift_reaper_run) { @@ -68,8 +67,10 @@ static void* timeshift_reaper_callback ( void *p ) if (errno != ENOTEMPTY) tvherror(LS_TIMESHIFT, "failed to remove %s [e=%s]", dpath, strerror(errno)); } else { - tvhtrace(LS_TIMESHIFT, "remove RAM segment (time %"PRId64", size %"PRId64")", - tsf->time, (int64_t)tsf->size); + tvhtrace(LS_TIMESHIFT, + "remove RAM segment (time %" PRId64 ", size %" PRId64 ")", + tsf->time, + (int64_t)tsf->size); } /* Free memory */ @@ -98,8 +99,7 @@ static void* timeshift_reaper_callback ( void *p ) return NULL; } -static void timeshift_reaper_remove ( timeshift_file_t *tsf ) -{ +static void timeshift_reaper_remove(timeshift_file_t* tsf) { if (tvhtrace_enabled()) { if (tsf->path) tvhtrace(LS_TIMESHIFT, "queue file for removal %s", tsf->path); @@ -116,18 +116,23 @@ static void timeshift_reaper_remove ( timeshift_file_t *tsf ) * File Handling * *************************************************************************/ -void -timeshift_filemgr_dump0 ( timeshift_t *ts ) -{ - timeshift_file_t *tsf; +void timeshift_filemgr_dump0(timeshift_t* ts) { + timeshift_file_t* tsf; if (TAILQ_EMPTY(&ts->files)) { tvhtrace(LS_TIMESHIFT, "ts %d file dump - EMPTY", ts->id); return; } - TAILQ_FOREACH(tsf, &ts->files, link) { - tvhtrace(LS_TIMESHIFT, "ts %d (full=%d) file dump tsf %p time %4"PRId64" last %10"PRId64" bad %d refcnt %d", - ts->id, ts->full, tsf, tsf->time, tsf->last, tsf->bad, tsf->refcount); + TAILQ_FOREACH (tsf, &ts->files, link) { + tvhtrace(LS_TIMESHIFT, + "ts %d (full=%d) file dump tsf %p time %4" PRId64 " last %10" PRId64 " bad %d refcnt %d", + ts->id, + ts->full, + tsf, + tsf->time, + tsf->last, + tsf->bad, + tsf->refcount); } } @@ -136,10 +141,8 @@ timeshift_filemgr_dump0 ( timeshift_t *ts ) * * TODO: should this be fixed on startup? */ -static int -timeshift_filemgr_get_root ( char *buf, size_t len ) -{ - const char *path = timeshift_conf.path; +static int timeshift_filemgr_get_root(char* buf, size_t len) { + const char* path = timeshift_conf.path; if (!path || !*path) { return hts_settings_buildpath(buf, len, "timeshift/buffer"); } else { @@ -151,21 +154,19 @@ timeshift_filemgr_get_root ( char *buf, size_t len ) /* * Create timeshift directories (for a given instance) */ -int timeshift_filemgr_makedirs ( int index, char *buf, size_t len ) -{ +int timeshift_filemgr_makedirs(int index, char* buf, size_t len) { if (timeshift_filemgr_get_root(buf, len)) return 1; - snprintf(buf+strlen(buf), len-strlen(buf), "/%d", index); + snprintf(buf + strlen(buf), len - strlen(buf), "/%d", index); return makedirs(LS_TIMESHIFT, buf, 0700, 0, -1, -1); } /* * Close file */ -void timeshift_filemgr_close ( timeshift_file_t *tsf ) -{ - uint8_t *ram; - ssize_t r = timeshift_write_eof(tsf); +void timeshift_filemgr_close(timeshift_file_t* tsf) { + uint8_t* ram; + ssize_t r = timeshift_write_eof(tsf); if (r > 0) { tsf->size += r; atomic_add_u64(×hift_total_size, r); @@ -177,7 +178,7 @@ void timeshift_filemgr_close ( timeshift_file_t *tsf ) ram = realloc(tsf->ram, tsf->woff); if (ram) { memoryinfo_append(×hift_memoryinfo_ram, tsf->ram_size - tsf->woff); - tsf->ram = ram; + tsf->ram = ram; tsf->ram_size = tsf->woff; } } @@ -189,18 +190,24 @@ void timeshift_filemgr_close ( timeshift_file_t *tsf ) /* * Remove file */ -void timeshift_filemgr_remove - ( timeshift_t *ts, timeshift_file_t *tsf, int force ) -{ +void timeshift_filemgr_remove(timeshift_t* ts, timeshift_file_t* tsf, int force) { if (tsf->wfd >= 0) close(tsf->wfd); assert(tsf->rfd < 0); if (tvhtrace_enabled()) { if (tsf->path) - tvhdebug(LS_TIMESHIFT, "ts %d remove %s (size %"PRId64")", ts->id, tsf->path, (int64_t)tsf->size); + tvhdebug(LS_TIMESHIFT, + "ts %d remove %s (size %" PRId64 ")", + ts->id, + tsf->path, + (int64_t)tsf->size); else - tvhdebug(LS_TIMESHIFT, "ts %d RAM segment remove time %"PRId64" (size %"PRId64", alloc size %"PRId64")", - ts->id, tsf->time, (int64_t)tsf->size, (int64_t)tsf->ram_size); + tvhdebug(LS_TIMESHIFT, + "ts %d RAM segment remove time %" PRId64 " (size %" PRId64 ", alloc size %" PRId64 ")", + ts->id, + tsf->time, + (int64_t)tsf->size, + (int64_t)tsf->ram_size); } TAILQ_REMOVE(&ts->files, tsf, link); if (tsf->path) { @@ -219,11 +226,11 @@ void timeshift_filemgr_remove /* * Flush all files */ -void timeshift_filemgr_flush ( timeshift_t *ts, timeshift_file_t *end ) -{ - timeshift_file_t *tsf; +void timeshift_filemgr_flush(timeshift_t* ts, timeshift_file_t* end) { + timeshift_file_t* tsf; while ((tsf = TAILQ_FIRST(&ts->files))) { - if (tsf == end) break; + if (tsf == end) + break; timeshift_filemgr_remove(ts, tsf, 1); } } @@ -231,17 +238,15 @@ void timeshift_filemgr_flush ( timeshift_t *ts, timeshift_file_t *end ) /* * */ -static timeshift_file_t * timeshift_filemgr_file_init - ( timeshift_t *ts, int64_t start_time ) -{ - timeshift_file_t *tsf; +static timeshift_file_t* timeshift_filemgr_file_init(timeshift_t* ts, int64_t start_time) { + timeshift_file_t* tsf; tsf = calloc(1, sizeof(timeshift_file_t)); memoryinfo_alloc(×hift_memoryinfo, sizeof(*tsf)); - tsf->time = mono2sec(start_time) / TIMESHIFT_FILE_PERIOD; - tsf->last = start_time; - tsf->wfd = -1; - tsf->rfd = -1; + tsf->time = mono2sec(start_time) / TIMESHIFT_FILE_PERIOD; + tsf->last = start_time; + tsf->wfd = -1; + tsf->rfd = -1; TAILQ_INIT(&tsf->iframes); TAILQ_INIT(&tsf->sstart); TAILQ_INSERT_TAIL(&ts->files, tsf, link); @@ -252,14 +257,13 @@ static timeshift_file_t * timeshift_filemgr_file_init /* * Get current / new file */ -timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time ) -{ - int fd; - timeshift_file_t *tsf_tl, *tsf_hd, *tsf_tmp; - timeshift_index_data_t *ti; - streaming_message_t *sm; - char path[PATH_MAX]; - int64_t time; +timeshift_file_t* timeshift_filemgr_get(timeshift_t* ts, int64_t start_time) { + int fd; + timeshift_file_t * tsf_tl, *tsf_hd, *tsf_tmp; + timeshift_index_data_t* ti; + streaming_message_t* sm; + char path[PATH_MAX]; + int64_t time; /* Return last file */ if (start_time < 0) @@ -271,7 +275,7 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time ) /* Store to file */ tsf_tl = TAILQ_LAST(&ts->files, timeshift_file_list); - time = mono2sec(start_time) / TIMESHIFT_FILE_PERIOD; + time = mono2sec(start_time) / TIMESHIFT_FILE_PERIOD; if (!tsf_tl || tsf_tl->time < time || (tsf_tl->ram && tsf_tl->woff >= timeshift_conf.ram_segment_size)) { tsf_hd = TAILQ_FIRST(&ts->files); @@ -281,10 +285,9 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time ) timeshift_filemgr_close(tsf_tl); /* Check period */ - if (!timeshift_conf.unlimited_period && - ts->max_time && tsf_hd && tsf_tl) { + if (!timeshift_conf.unlimited_period && ts->max_time && tsf_hd && tsf_tl) { time_t d = (tsf_tl->time - tsf_hd->time) * TIMESHIFT_FILE_PERIOD; - if (d > (ts->max_time+5)) { + if (d > (ts->max_time + 5)) { if (!tsf_hd->refcount) { timeshift_filemgr_remove(ts, tsf_hd, 0); tsf_hd = NULL; @@ -303,7 +306,7 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time ) if (tsf_hd && !tsf_hd->refcount) { timeshift_filemgr_remove(ts, tsf_hd, 0); - /* Full */ + /* Full */ } else { tvhdebug(LS_TIMESHIFT, "ts %d buffer full", ts->id); ts->full = 1; @@ -314,38 +317,47 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time ) tsf_tmp = NULL; if (!ts->full) { - tvhtrace(LS_TIMESHIFT, "ts %d RAM total %"PRId64" requested %"PRId64" segment %"PRId64, - ts->id, atomic_pre_add_u64(×hift_total_ram_size, 0), - timeshift_conf.ram_size, timeshift_conf.ram_segment_size); + tvhtrace(LS_TIMESHIFT, + "ts %d RAM total %" PRId64 " requested %" PRId64 " segment %" PRId64, + ts->id, + atomic_pre_add_u64(×hift_total_ram_size, 0), + timeshift_conf.ram_size, + timeshift_conf.ram_segment_size); while (1) { - if (timeshift_conf.ram_size >= 8*1024*1024 && + if (timeshift_conf.ram_size >= 8 * 1024 * 1024 && atomic_pre_add_u64(×hift_total_ram_size, 0) < - timeshift_conf.ram_size + (timeshift_conf.ram_segment_size / 2)) { - tsf_tmp = timeshift_filemgr_file_init(ts, start_time); - tsf_tmp->ram_size = MIN(16*1024*1024, timeshift_conf.ram_segment_size); - tsf_tmp->ram = malloc(tsf_tmp->ram_size); + timeshift_conf.ram_size + (timeshift_conf.ram_segment_size / 2)) { + tsf_tmp = timeshift_filemgr_file_init(ts, start_time); + tsf_tmp->ram_size = MIN(16 * 1024 * 1024, timeshift_conf.ram_segment_size); + tsf_tmp->ram = malloc(tsf_tmp->ram_size); if (!tsf_tmp->ram) { free(tsf_tmp); tsf_tmp = NULL; } else { - tvhtrace(LS_TIMESHIFT, "ts %d create RAM segment with %"PRId64" bytes (time %"PRId64")", - ts->id, tsf_tmp->ram_size, start_time); + tvhtrace(LS_TIMESHIFT, + "ts %d create RAM segment with %" PRId64 " bytes (time %" PRId64 ")", + ts->id, + tsf_tmp->ram_size, + start_time); ts->ram_segments++; memoryinfo_alloc(×hift_memoryinfo_ram, tsf_tmp->ram_size); } break; } else { tsf_hd = TAILQ_FIRST(&ts->files); - if (timeshift_conf.ram_fit && tsf_hd && !tsf_hd->refcount && - tsf_hd->ram && ts->file_segments == 0) { - tvhtrace(LS_TIMESHIFT, "ts %d remove RAM segment %"PRId64" (fit)", ts->id, tsf_hd->time); + if (timeshift_conf.ram_fit && tsf_hd && !tsf_hd->refcount && tsf_hd->ram && + ts->file_segments == 0) { + tvhtrace(LS_TIMESHIFT, + "ts %d remove RAM segment %" PRId64 " (fit)", + ts->id, + tsf_hd->time); timeshift_filemgr_remove(ts, tsf_hd, 0); } else { break; } } } - + if (!tsf_tmp && !timeshift_conf.ram_only) { /* Create directories */ if (!ts->path) { @@ -355,11 +367,11 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time ) } /* Create File */ - snprintf(path, sizeof(path), "%s/tvh-%"PRId64, ts->path, start_time); + snprintf(path, sizeof(path), "%s/tvh-%" PRId64, ts->path, start_time); tvhtrace(LS_TIMESHIFT, "ts %d create file %s", ts->id, path); if ((fd = tvh_open(path, O_WRONLY | O_CREAT, 0600)) > 0) { - tsf_tmp = timeshift_filemgr_file_init(ts, start_time); - tsf_tmp->wfd = fd; + tsf_tmp = timeshift_filemgr_file_init(ts, start_time); + tsf_tmp->wfd = fd; tsf_tmp->path = strdup(path); ts->file_segments++; } @@ -368,9 +380,11 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time ) if (tsf_tmp && tsf_tl) { /* Copy across last start message */ if ((ti = TAILQ_LAST(&tsf_tl->sstart, timeshift_index_data_list)) || ts->smt_start) { - tvhtrace(LS_TIMESHIFT, "ts %d copy smt_start to new file%s", - ts->id, ti ? " (from last file)" : ""); - timeshift_index_data_t *ti2 = calloc(1, sizeof(timeshift_index_data_t)); + tvhtrace(LS_TIMESHIFT, + "ts %d copy smt_start to new file%s", + ts->id, + ti ? " (from last file)" : ""); + timeshift_index_data_t* ti2 = calloc(1, sizeof(timeshift_index_data_t)); if (ti) { memoryinfo_alloc(×hift_memoryinfo, sizeof(timeshift_index_data_t)); sm = streaming_msg_clone(ti->data); @@ -391,22 +405,22 @@ timeshift_file_t *timeshift_filemgr_get ( timeshift_t *ts, int64_t start_time ) return timeshift_file_get(tsf_tl); } -timeshift_file_t *timeshift_filemgr_next - ( timeshift_file_t *tsf, int *end, int keep ) -{ - timeshift_file_t *nxt = TAILQ_NEXT(tsf, link); - if (!nxt && end) *end = 1; - if (!nxt && keep) return tsf; +timeshift_file_t* timeshift_filemgr_next(timeshift_file_t* tsf, int* end, int keep) { + timeshift_file_t* nxt = TAILQ_NEXT(tsf, link); + if (!nxt && end) + *end = 1; + if (!nxt && keep) + return tsf; timeshift_file_put(tsf); return timeshift_file_get(nxt); } -timeshift_file_t *timeshift_filemgr_prev - ( timeshift_file_t *tsf, int *end, int keep ) -{ - timeshift_file_t *prev = TAILQ_PREV(tsf, timeshift_file_list, link); - if (!prev && end) *end = 1; - if (!prev && keep) return tsf; +timeshift_file_t* timeshift_filemgr_prev(timeshift_file_t* tsf, int* end, int keep) { + timeshift_file_t* prev = TAILQ_PREV(tsf, timeshift_file_list, link); + if (!prev && end) + *end = 1; + if (!prev && keep) + return tsf; timeshift_file_put(tsf); return timeshift_file_get(prev); } @@ -414,18 +428,16 @@ timeshift_file_t *timeshift_filemgr_prev /* * Get the oldest file */ -timeshift_file_t *timeshift_filemgr_oldest ( timeshift_t *ts ) -{ - timeshift_file_t *tsf = TAILQ_FIRST(&ts->files); +timeshift_file_t* timeshift_filemgr_oldest(timeshift_t* ts) { + timeshift_file_t* tsf = TAILQ_FIRST(&ts->files); return timeshift_file_get(tsf); } /* * Get the newest file */ -timeshift_file_t *timeshift_filemgr_newest ( timeshift_t *ts ) -{ - timeshift_file_t *tsf = TAILQ_LAST(&ts->files, timeshift_file_list); +timeshift_file_t* timeshift_filemgr_newest(timeshift_t* ts) { + timeshift_file_t* tsf = TAILQ_LAST(&ts->files, timeshift_file_list); return timeshift_file_get(tsf); } @@ -436,16 +448,15 @@ timeshift_file_t *timeshift_filemgr_newest ( timeshift_t *ts ) /* * Initialise global structures */ -void timeshift_filemgr_init ( void ) -{ +void timeshift_filemgr_init(void) { char path[512]; /* Try to remove any rubbish left from last run */ - if(!timeshift_filemgr_get_root(path, sizeof(path))) + if (!timeshift_filemgr_get_root(path, sizeof(path))) rmtree(path); /* Size processing */ - timeshift_total_size = 0; + timeshift_total_size = 0; timeshift_conf.ram_size = 0; /* Start the reaper thread */ @@ -453,15 +464,13 @@ void timeshift_filemgr_init ( void ) tvh_mutex_init(×hift_reaper_lock, NULL); tvh_cond_init(×hift_reaper_cond, 1); TAILQ_INIT(×hift_reaper_list); - tvh_thread_create(×hift_reaper_thread, NULL, - timeshift_reaper_callback, NULL, "tshift-reap"); + tvh_thread_create(×hift_reaper_thread, NULL, timeshift_reaper_callback, NULL, "tshift-reap"); } /* * Terminate */ -void timeshift_filemgr_term ( void ) -{ +void timeshift_filemgr_term(void) { char path[512]; /* Wait for thread */ diff --git a/src/timeshift/timeshift_reader.c b/src/timeshift/timeshift_reader.c index 6339a9485..0a9677f3e 100644 --- a/src/timeshift/timeshift_reader.c +++ b/src/timeshift/timeshift_reader.c @@ -41,18 +41,15 @@ * Buffered position handling * *************************************************************************/ -static timeshift_seek_t *_seek_reset ( timeshift_seek_t *seek ) -{ - timeshift_file_t *tsf = seek->file; - seek->file = NULL; - seek->frame = NULL; +static timeshift_seek_t* _seek_reset(timeshift_seek_t* seek) { + timeshift_file_t* tsf = seek->file; + seek->file = NULL; + seek->frame = NULL; timeshift_file_put(tsf); return seek; } -static timeshift_seek_t *_seek_set_file - ( timeshift_seek_t *seek, timeshift_file_t *tsf, off_t roff ) -{ +static timeshift_seek_t* _seek_set_file(timeshift_seek_t* seek, timeshift_file_t* tsf, off_t roff) { seek->file = tsf; seek->frame = NULL; if (tsf) @@ -60,8 +57,7 @@ static timeshift_seek_t *_seek_set_file return seek; } -static timeshift_seek_t *_read_close ( timeshift_seek_t *seek ) -{ +static timeshift_seek_t* _read_close(timeshift_seek_t* seek) { if (seek->file && seek->file->rfd >= 0) { close(seek->file->rfd); seek->file->rfd = -1; @@ -73,14 +69,15 @@ static timeshift_seek_t *_read_close ( timeshift_seek_t *seek ) * File Reading * *************************************************************************/ -static ssize_t _read_buf ( timeshift_file_t *tsf, int fd, void *buf, size_t size ) -{ +static ssize_t _read_buf(timeshift_file_t* tsf, int fd, void* buf, size_t size) { ssize_t r; - size_t ret; + size_t ret; if (tsf && tsf->ram) { - if (tsf->roff == tsf->woff) return 0; - if (tsf->roff + size > tsf->woff) return -1; + if (tsf->roff == tsf->woff) + return 0; + if (tsf->roff + size > tsf->woff) + return -1; tvh_mutex_lock(&tsf->ram_lock); memcpy(buf, tsf->ram + tsf->roff, size); tsf->roff += size; @@ -110,15 +107,16 @@ static ssize_t _read_buf ( timeshift_file_t *tsf, int fd, void *buf, size_t size } } -static ssize_t _read_pktbuf ( timeshift_file_t *tsf, int fd, pktbuf_t **pktbuf ) -{ +static ssize_t _read_pktbuf(timeshift_file_t* tsf, int fd, pktbuf_t** pktbuf) { ssize_t r, cnt = 0; - size_t sz; + size_t sz; /* Size */ r = _read_buf(tsf, fd, &sz, sizeof(sz)); - if (r < 0) return -1; - if (r != sizeof(sz)) return 0; + if (r < 0) + return -1; + if (r != sizeof(sz)) + return 0; cnt += r; /* Empty And Sanity Check */ @@ -129,7 +127,7 @@ static ssize_t _read_pktbuf ( timeshift_file_t *tsf, int fd, pktbuf_t **pktbuf ) /* Data */ *pktbuf = pktbuf_alloc(NULL, sz); - r = _read_buf(tsf, fd, pktbuf_ptr(*pktbuf), sz); + r = _read_buf(tsf, fd, pktbuf_ptr(*pktbuf), sz); if (r != sz) { pktbuf_destroy(*pktbuf); *pktbuf = NULL; @@ -140,27 +138,28 @@ static ssize_t _read_pktbuf ( timeshift_file_t *tsf, int fd, pktbuf_t **pktbuf ) return cnt; } - -static ssize_t _read_msg ( timeshift_file_t *tsf, int fd, streaming_message_t **sm ) -{ - ssize_t r, cnt = 0; - size_t sz; +static ssize_t _read_msg(timeshift_file_t* tsf, int fd, streaming_message_t** sm) { + ssize_t r, cnt = 0; + size_t sz; streaming_message_type_t type; - int64_t time; - void *data; - int code; + int64_t time; + void* data; + int code; /* Clear */ *sm = NULL; /* Size */ r = _read_buf(tsf, fd, &sz, sizeof(sz)); - if (r < 0) return -1; - if (r != sizeof(sz)) return 0; + if (r < 0) + return -1; + if (r != sizeof(sz)) + return 0; cnt += r; /* EOF */ - if (sz == 0) return cnt; + if (sz == 0) + return cnt; /* Wrong data size */ if (sz > 1024 * 1024) { @@ -170,14 +169,18 @@ static ssize_t _read_msg ( timeshift_file_t *tsf, int fd, streaming_message_t ** /* Type */ r = _read_buf(tsf, fd, &type, sizeof(type)); - if (r < 0) return -1; - if (r != sizeof(type)) return 0; + if (r < 0) + return -1; + if (r != sizeof(type)) + return 0; cnt += r; /* Time */ r = _read_buf(tsf, fd, &time, sizeof(time)); - if (r < 0) return -1; - if (r != sizeof(time)) return 0; + if (r < 0) + return -1; + if (r != sizeof(time)) + return 0; cnt += r; /* Adjust size */ @@ -200,10 +203,12 @@ static ssize_t _read_msg ( timeshift_file_t *tsf, int fd, streaming_message_t ** case SMT_STOP: case SMT_EXIT: case SMT_SPEED: - if (sz != sizeof(code)) return -1; + if (sz != sizeof(code)) + return -1; r = _read_buf(tsf, fd, &code, sz); if (r != sz) { - if (r < 0) return -1; + if (r < 0) + return -1; return 0; } *sm = streaming_msg_create_code(type, code); @@ -215,24 +220,25 @@ static ssize_t _read_msg ( timeshift_file_t *tsf, int fd, streaming_message_t ** case SMT_MPEGTS: case SMT_PACKET: data = malloc(sz); - r = _read_buf(tsf, fd, data, sz); + r = _read_buf(tsf, fd, data, sz); if (r != sz) { free(data); - if (r < 0) return -1; + if (r < 0) + return -1; return 0; } if (type == SMT_PACKET) { - th_pkt_t *pkt = data; - pkt->pkt_payload = pkt->pkt_meta = NULL; - pkt->pkt_refcount = 0; - *sm = streaming_msg_create_pkt(pkt); - r = _read_pktbuf(tsf, fd, &pkt->pkt_meta); + th_pkt_t* pkt = data; + pkt->pkt_payload = pkt->pkt_meta = NULL; + pkt->pkt_refcount = 0; + *sm = streaming_msg_create_pkt(pkt); + r = _read_pktbuf(tsf, fd, &pkt->pkt_meta); if (r < 0) { streaming_msg_free(*sm); return r; } cnt += r; - r = _read_pktbuf(tsf, fd, &pkt->pkt_payload); + r = _read_pktbuf(tsf, fd, &pkt->pkt_payload); if (r < 0) { streaming_msg_free(*sm); return r; @@ -256,31 +262,30 @@ static ssize_t _read_msg ( timeshift_file_t *tsf, int fd, streaming_message_t ** * Utilities * *************************************************************************/ -static int64_t _timeshift_first_time - ( timeshift_t *ts, int *active ) -{ - int64_t ret = 0; - int end; - timeshift_index_iframe_t *tsi = NULL; - timeshift_file_t *tsf = timeshift_filemgr_oldest(ts); +static int64_t _timeshift_first_time(timeshift_t* ts, int* active) { + int64_t ret = 0; + int end; + timeshift_index_iframe_t* tsi = NULL; + timeshift_file_t* tsf = timeshift_filemgr_oldest(ts); while (tsf && !tsi) { if (!(tsi = TAILQ_FIRST(&tsf->iframes))) tsf = timeshift_filemgr_next(tsf, &end, 0); } if (tsi) { *active = 1; - ret = tsi->time; + ret = tsi->time; } timeshift_file_put(tsf); return ret; } -static int _timeshift_skip - ( timeshift_t *ts, int64_t req_time, int64_t cur_time, - timeshift_seek_t *seek, timeshift_seek_t *nseek ) -{ - timeshift_index_iframe_t *tsi = seek->frame; - timeshift_file_t *tsf = seek->file, *tsf_last; +static int _timeshift_skip(timeshift_t* ts, + int64_t req_time, + int64_t cur_time, + timeshift_seek_t* seek, + timeshift_seek_t* nseek) { + timeshift_index_iframe_t* tsi = seek->frame; + timeshift_file_t * tsf = seek->file, *tsf_last; int64_t sec = mono2sec(req_time) / TIMESHIFT_FILE_PERIOD; int back = (req_time < cur_time) ? 1 : 0; int end = 0; @@ -289,13 +294,11 @@ static int _timeshift_skip if (!tsi) { while (tsf && !end) { if (back) { - if ((tsf->time <= sec) && - (tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list))) + if ((tsf->time <= sec) && (tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list))) break; tsf = timeshift_filemgr_prev(tsf, &end, 1); } else { - if ((tsf->time >= sec) && - (tsi = TAILQ_FIRST(&tsf->iframes))) + if ((tsf->time >= sec) && (tsi = TAILQ_FIRST(&tsf->iframes))) break; tsf = timeshift_filemgr_next(tsf, &end, 0); } @@ -331,7 +334,7 @@ static int _timeshift_skip timeshift_file_put(tsf); if (back) { tsf = tsf_last = timeshift_filemgr_oldest(ts); - tsi = NULL; + tsi = NULL; while (tsf && !tsi) { tsf_last = tsf; if (!(tsi = TAILQ_FIRST(&tsf->iframes))) @@ -342,7 +345,7 @@ static int _timeshift_skip end = -1; } else { tsf = tsf_last = timeshift_filemgr_newest(ts); - tsi = NULL; + tsi = NULL; while (tsf && !tsi) { tsf_last = tsf; if (!(tsi = TAILQ_LAST(&tsf->iframes, timeshift_index_iframe_list))) @@ -363,23 +366,19 @@ static int _timeshift_skip /* * */ -static int _timeshift_do_skip - ( timeshift_t *ts, int64_t req_time, int64_t last_time, - timeshift_seek_t *seek ) -{ +static int +_timeshift_do_skip(timeshift_t* ts, int64_t req_time, int64_t last_time, timeshift_seek_t* seek) { timeshift_seek_t nseek; - int end; + int end; - tvhdebug(LS_TIMESHIFT, "ts %d skip to %"PRId64" from %"PRId64, - ts->id, req_time, last_time); + tvhdebug(LS_TIMESHIFT, "ts %d skip to %" PRId64 " from %" PRId64, ts->id, req_time, last_time); timeshift_file_get(seek->file); /* Find */ end = _timeshift_skip(ts, req_time, last_time, seek, &nseek); if (nseek.frame) - tvhdebug(LS_TIMESHIFT, "ts %d skip found pkt @ %"PRId64, - ts->id, nseek.frame->time); + tvhdebug(LS_TIMESHIFT, "ts %d skip found pkt @ %" PRId64, ts->id, nseek.frame->time); /* File changed (close) */ if (nseek.file != seek->file) @@ -394,24 +393,23 @@ static int _timeshift_do_skip nseek.file->roff = nseek.frame->pos; else nseek.file->roff = req_time > last_time ? nseek.file->size : 0; - tvhtrace(LS_TIMESHIFT, "do skip seek->file %p roff %"PRId64, - nseek.file, (int64_t)nseek.file->roff); + tvhtrace(LS_TIMESHIFT, + "do skip seek->file %p roff %" PRId64, + nseek.file, + (int64_t)nseek.file->roff); } return end; } - /* * Output packet */ -static int _timeshift_read - ( timeshift_t *ts, timeshift_seek_t *seek, - streaming_message_t **sm, int *wait ) -{ - timeshift_file_t *tsf = seek->file; - ssize_t r; - off_t off = 0; +static int +_timeshift_read(timeshift_t* ts, timeshift_seek_t* seek, streaming_message_t** sm, int* wait) { + timeshift_file_t* tsf = seek->file; + ssize_t r; + off_t off = 0; *sm = NULL; @@ -426,27 +424,43 @@ static int _timeshift_read } if (tsf->rfd >= 0) if ((off = lseek(tsf->rfd, tsf->roff, SEEK_SET)) != tsf->roff) - tvherror(LS_TIMESHIFT, "ts %d seek to %s failed (off %"PRId64" != %"PRId64"): %s", - ts->id, tsf->path, (int64_t)tsf->roff, (int64_t)off, strerror(errno)); + tvherror(LS_TIMESHIFT, + "ts %d seek to %s failed (off %" PRId64 " != %" PRId64 "): %s", + ts->id, + tsf->path, + (int64_t)tsf->roff, + (int64_t)off, + strerror(errno)); /* Read msg */ r = _read_msg(tsf, -1, sm); if (r < 0) { - streaming_message_t *e = streaming_msg_create_code(SMT_STOP, SM_CODE_UNDEFINED_ERROR); + streaming_message_t* e = streaming_msg_create_code(SMT_STOP, SM_CODE_UNDEFINED_ERROR); streaming_target_deliver2(ts->output, e); - tvhtrace(LS_TIMESHIFT, "ts %d seek to %jd (woff %jd) (fd %i)", ts->id, (intmax_t)off, (intmax_t)tsf->woff, tsf->rfd); + tvhtrace(LS_TIMESHIFT, + "ts %d seek to %jd (woff %jd) (fd %i)", + ts->id, + (intmax_t)off, + (intmax_t)tsf->woff, + tsf->rfd); tvherror(LS_TIMESHIFT, "ts %d could not read buffer", ts->id); return -1; } - tvhtrace(LS_TIMESHIFT, "ts %d seek to %jd (fd %i) read msg %p/%"PRId64" (%"PRId64")", - ts->id, (intmax_t)off, tsf->rfd, *sm, *sm ? (*sm)->sm_time : -1, (int64_t)r); + tvhtrace(LS_TIMESHIFT, + "ts %d seek to %jd (fd %i) read msg %p/%" PRId64 " (%" PRId64 ")", + ts->id, + (intmax_t)off, + tsf->rfd, + *sm, + *sm ? (*sm)->sm_time : -1, + (int64_t)r); /* Special case - EOF */ if (r <= sizeof(size_t) || tsf->roff > tsf->size || *sm == NULL) { timeshift_file_get(seek->file); /* _read_close decreases file reference */ _read_close(seek); _seek_set_file(seek, timeshift_filemgr_next(tsf, NULL, 0), 0); - *wait = 0; + *wait = 0; tvhtrace(LS_TIMESHIFT, "ts %d eof, seek->file %p (prev %p)", ts->id, seek->file, tsf); timeshift_filemgr_dump(ts); } @@ -457,15 +471,14 @@ static int _timeshift_read /* * Flush all data to live */ -static int _timeshift_flush_to_live - ( timeshift_t *ts, timeshift_seek_t *seek, int *wait ) -{ - streaming_message_t *sm; +static int _timeshift_flush_to_live(timeshift_t* ts, timeshift_seek_t* seek, int* wait) { + streaming_message_t* sm; while (seek->file) { if (_timeshift_read(ts, seek, &sm, wait) == -1) return -1; - if (!sm) break; + if (!sm) + break; timeshift_packet_log("ouf", ts, sm); streaming_target_deliver2(ts->output, sm); } @@ -475,10 +488,9 @@ static int _timeshift_flush_to_live /* * Send the status message */ -static void timeshift_fill_status - ( timeshift_t *ts, timeshift_status_t *status, int64_t current_time ) -{ - int active = 0; +static void +timeshift_fill_status(timeshift_t* ts, timeshift_status_t* status, int64_t current_time) { + int active = 0; int64_t start, end; start = _timeshift_first_time(ts, &active); @@ -492,24 +504,26 @@ static void timeshift_fill_status current_time = end; } status->full = ts->full; - tvhtrace(LS_TIMESHIFT, "ts %d status start %"PRId64" end %"PRId64 - " current %"PRId64" state %d", - ts->id, start, end, current_time, ts->state); + tvhtrace(LS_TIMESHIFT, + "ts %d status start %" PRId64 " end %" PRId64 " current %" PRId64 " state %d", + ts->id, + start, + end, + current_time, + ts->state); status->shift = ts_rescale_inv(end - current_time, 1000000); if (active) { status->pts_start = ts_rescale_inv(start, 1000000); - status->pts_end = ts_rescale_inv(end, 1000000); + status->pts_end = ts_rescale_inv(end, 1000000); } else { status->pts_start = PTS_UNSET; status->pts_end = PTS_UNSET; } } -static void timeshift_status - ( timeshift_t *ts, int64_t current_time ) -{ - streaming_message_t *tsm; - timeshift_status_t *status; +static void timeshift_status(timeshift_t* ts, int64_t current_time) { + streaming_message_t* tsm; + timeshift_status_t* status; status = calloc(1, sizeof(timeshift_status_t)); timeshift_fill_status(ts, status, current_time); @@ -521,24 +535,22 @@ static void timeshift_status * Thread * *************************************************************************/ - /* * Timeshift thread */ -void *timeshift_reader ( void *p ) -{ - timeshift_t *ts = p; - int nfds, end, run = 1, wait = -1, state; - timeshift_seek_t *seek = &ts->seek; - timeshift_file_t *tmp_file; - int cur_speed = 100, keyframe_mode = 0; - int64_t mono_now, mono_play_time = 0, mono_last_status = 0; - int64_t deliver, deliver0, pause_time = 0, last_time = 0, skip_time = 0; - int64_t i64; +void* timeshift_reader(void* p) { + timeshift_t* ts = p; + int nfds, end, run = 1, wait = -1, state; + timeshift_seek_t* seek = &ts->seek; + timeshift_file_t* tmp_file; + int cur_speed = 100, keyframe_mode = 0; + int64_t mono_now, mono_play_time = 0, mono_last_status = 0; + int64_t deliver, deliver0, pause_time = 0, last_time = 0, skip_time = 0; + int64_t i64; streaming_message_t *sm = NULL, *ctrl = NULL; - streaming_skip_t *skip = NULL; - tvhpoll_t *pd; - tvhpoll_event_t ev = { 0 }; + streaming_skip_t* skip = NULL; + tvhpoll_t* pd; + tvhpoll_event_t ev = {0}; pd = tvhpoll_create(1); tvhpoll_add1(pd, ts->rd_pipe.rd, TVHPOLL_IN, NULL); @@ -552,14 +564,14 @@ void *timeshift_reader ( void *p ) wait = 1000; /* Wait for data */ - if(wait) + if (wait) nfds = tvhpoll_wait(pd, &ev, 1, wait); else nfds = 0; - wait = -1; - end = 0; - skip = NULL; - mono_now = getfastmonoclock(); + wait = -1; + end = 0; + skip = NULL; + mono_now = getfastmonoclock(); /* Control */ tvh_mutex_lock(&ts->state_mutex); @@ -573,14 +585,16 @@ void *timeshift_reader ( void *p ) streaming_msg_free(ctrl); ctrl = NULL; - /* Speed */ + /* Speed */ } else if (ctrl->sm_type == SMT_SPEED) { int speed = ctrl->sm_code; int keyframe; /* Bound it */ - if (speed > 3200) speed = 3200; - if (speed < -3200) speed = -3200; + if (speed > 3200) + speed = 3200; + if (speed < -3200) + speed = -3200; /* Ignore negative */ if (!ts->dobuf && (speed < 0)) @@ -598,7 +612,7 @@ void *timeshift_reader ( void *p ) tvhdebug(LS_TIMESHIFT, "ts %d reject 1x+ in live mode", ts->id); speed = 100; - /* Set position */ + /* Set position */ } else { tvhdebug(LS_TIMESHIFT, "ts %d enter timeshift mode", ts->id); ts->dobuf = 1; @@ -616,14 +630,14 @@ void *timeshift_reader ( void *p ) pause_time = seek->file->last; last_time = pause_time; } else { - pause_time = i64; - last_time = pause_time; + pause_time = i64; + last_time = pause_time; } } } /* Check keyframe mode */ - keyframe = (speed < 0) || (speed > 400); + keyframe = (speed < 0) || (speed > 400); if (keyframe != keyframe_mode) { tvhdebug(LS_TIMESHIFT, "using keyframe mode? %s", keyframe ? "yes" : "no"); keyframe_mode = keyframe; @@ -638,8 +652,10 @@ void *timeshift_reader ( void *p ) } if ((ts->state == TS_PLAY && state != TS_PLAY) || (speed != cur_speed)) { mono_play_time = mono_now; - tvhtrace(LS_TIMESHIFT, "update play time TS_LIVE - %"PRId64" play buffer from %"PRId64, - mono_now, pause_time); + tvhtrace(LS_TIMESHIFT, + "update play time TS_LIVE - %" PRId64 " play buffer from %" PRId64, + mono_now, + pause_time); if (speed != cur_speed) pause_time = last_time; } else if (ts->state == TS_PAUSE && state != TS_PAUSE) { @@ -654,7 +670,7 @@ void *timeshift_reader ( void *p ) streaming_target_deliver2(ts->output, ctrl); ctrl = NULL; - /* Skip/Seek */ + /* Skip/Seek */ } else if (ctrl->sm_type == SMT_SKIP) { skip = ctrl->sm_data; switch (skip->type) { @@ -684,7 +700,11 @@ void *timeshift_reader ( void *p ) /* Convert */ skip_time = ts_rescale(skip->time, 1000000); - tvhdebug(LS_TIMESHIFT, "ts %d skip %"PRId64" requested %"PRId64, ts->id, skip_time, skip->time); + tvhdebug(LS_TIMESHIFT, + "ts %d skip %" PRId64 " requested %" PRId64, + ts->id, + skip_time, + skip->time); /* Live playback (stage1) */ if (ts->state == TS_LIVE) { @@ -698,14 +718,14 @@ void *timeshift_reader ( void *p ) seek->file->roff = seek->file->size; last_time = seek->file->last; } else { - last_time = ts->buf_time; + last_time = ts->buf_time; } } /* May have failed */ if (skip->type == SMT_SKIP_REL_TIME) skip_time += last_time; - tvhdebug(LS_TIMESHIFT, "ts %d skip time %"PRId64, ts->id, skip_time); + tvhdebug(LS_TIMESHIFT, "ts %d skip time %" PRId64, ts->id, skip_time); /* Live (stage2) */ if (ts->state == TS_LIVE) { @@ -723,15 +743,21 @@ void *timeshift_reader ( void *p ) if (skip) { /* seek */ seek->frame = NULL; - end = _timeshift_do_skip(ts, skip_time, last_time, seek); + end = _timeshift_do_skip(ts, skip_time, last_time, seek); if (seek->frame) { pause_time = seek->frame->time; - tvhtrace(LS_TIMESHIFT, "ts %d skip - play buffer from %"PRId64" last_time %"PRId64, - ts->id, pause_time, last_time); + tvhtrace(LS_TIMESHIFT, + "ts %d skip - play buffer from %" PRId64 " last_time %" PRId64, + ts->id, + pause_time, + last_time); /* Adjust time */ if (mono_play_time != mono_now) - tvhtrace(LS_TIMESHIFT, "ts %d update play time skip - %"PRId64, ts->id, mono_now); + tvhtrace(LS_TIMESHIFT, + "ts %d update play time skip - %" PRId64, + ts->id, + mono_now); mono_play_time = mono_now; /* Clear existing packet */ @@ -757,7 +783,7 @@ void *timeshift_reader ( void *p ) ctrl = NULL; } - /* Ignore */ + /* Ignore */ } else { streaming_msg_free(ctrl); ctrl = NULL; @@ -765,7 +791,6 @@ void *timeshift_reader ( void *p ) } } - /* Done */ if (!run || !seek->file || ((ts->state != TS_PLAY && !skip))) { if (mono_now >= (mono_last_status + sec2mono(1))) { @@ -778,10 +803,15 @@ void *timeshift_reader ( void *p ) /* Calculate delivery time */ deliver0 = (mono_now - mono_play_time) + TIMESHIFT_PLAY_BUF; - deliver = (deliver0 * cur_speed) / 100; - deliver = (deliver + pause_time); - tvhtrace(LS_TIMESHIFT, "speed %d now %"PRId64" play_time %"PRId64" deliver %"PRId64" deliver0 %"PRId64, - cur_speed, mono_now, mono_play_time, deliver, deliver0); + deliver = (deliver0 * cur_speed) / 100; + deliver = (deliver + pause_time); + tvhtrace(LS_TIMESHIFT, + "speed %d now %" PRId64 " play_time %" PRId64 " deliver %" PRId64 " deliver0 %" PRId64, + cur_speed, + mono_now, + mono_play_time, + deliver, + deliver0); /* Determine next packet */ if (!sm) { @@ -818,7 +848,7 @@ void *timeshift_reader ( void *p ) /* Status message */ skip->time = ts_rescale_inv(sm->sm_time, 1000000); skip->type = SMT_SKIP_ABS_TIME; - tvhdebug(LS_TIMESHIFT, "ts %d skip to pts %"PRId64" ok", ts->id, sm->sm_time); + tvhdebug(LS_TIMESHIFT, "ts %d skip to pts %" PRId64 " ok", ts->id, sm->sm_time); /* Update timeshift status */ timeshift_fill_status(ts, &skip->timeshift, sm->sm_time); mono_last_status = mono_now; @@ -835,8 +865,9 @@ void *timeshift_reader ( void *p ) ctrl = NULL; /* Deliver */ - if (sm && (skip || - (((cur_speed < 0) && (sm->sm_time >= deliver)) || + if (sm && + (skip || + (((cur_speed < 0) && (sm->sm_time >= deliver)) || ((cur_speed > 0) && (sm->sm_time <= deliver))))) { last_time = sm->sm_time; @@ -844,8 +875,8 @@ void *timeshift_reader ( void *p ) timeshift_status(ts, last_time); timeshift_packet_log("out", ts, sm); streaming_target_deliver2(ts->output, sm); - sm = NULL; - wait = 0; + sm = NULL; + wait = 0; } else if (sm) { @@ -853,10 +884,15 @@ void *timeshift_reader ( void *p ) wait = (sm->sm_time - deliver) / 1000; else wait = (deliver - sm->sm_time) / 1000; - if (wait == 0) wait = 1; - tvhtrace(LS_TIMESHIFT, "ts %d wait %d speed %d sm_time %"PRId64" deliver %"PRId64, - ts->id, wait, cur_speed, sm->sm_time, deliver); - + if (wait == 0) + wait = 1; + tvhtrace(LS_TIMESHIFT, + "ts %d wait %d speed %d sm_time %" PRId64 " deliver %" PRId64, + ts->id, + wait, + cur_speed, + sm->sm_time, + deliver); } /* Periodic timeshift status */ @@ -874,7 +910,7 @@ void *timeshift_reader ( void *p ) cur_speed = 100; ctrl = streaming_msg_create_code(SMT_SPEED, cur_speed); streaming_target_deliver2(ts->output, ctrl); - ctrl = NULL; + ctrl = NULL; tvhtrace(LS_TIMESHIFT, "reader - set TS_LIVE"); /* Flush timeshift buffer to live */ @@ -888,7 +924,7 @@ void *timeshift_reader ( void *p ) /* Close file (if open) */ _read_close(seek); - /* Pause */ + /* Pause */ } else { if (cur_speed <= 0) { cur_speed = 0; @@ -901,17 +937,20 @@ void *timeshift_reader ( void *p ) ts->state = TS_PLAY; ts->dobuf = 1; if (mono_play_time != mono_now) - tvhtrace(LS_TIMESHIFT, "update play time (pause) - %"PRId64, mono_now); + tvhtrace(LS_TIMESHIFT, "update play time (pause) - %" PRId64, mono_now); mono_play_time = mono_now; } } - tvhdebug(LS_TIMESHIFT, "ts %d sob speed %d last time %"PRId64, ts->id, cur_speed, last_time); + tvhdebug(LS_TIMESHIFT, + "ts %d sob speed %d last time %" PRId64, + ts->id, + cur_speed, + last_time); pause_time = last_time; ctrl = streaming_msg_create_code(SMT_SPEED, cur_speed); streaming_target_deliver2(ts->output, ctrl); - ctrl = NULL; + ctrl = NULL; } - } tvh_mutex_unlock(&ts->state_mutex); @@ -920,8 +959,10 @@ void *timeshift_reader ( void *p ) /* Cleanup */ tvhpoll_destroy(pd); _read_close(seek); - if (sm) streaming_msg_free(sm); - if (ctrl) streaming_msg_free(ctrl); + if (sm) + streaming_msg_free(sm); + if (ctrl) + streaming_msg_free(ctrl); tvhtrace(LS_TIMESHIFT, "ts %d exit reader thread", ts->id); return NULL; diff --git a/src/timeshift/timeshift_writer.c b/src/timeshift/timeshift_writer.c index 9c6591c37..f5818f069 100644 --- a/src/timeshift/timeshift_writer.c +++ b/src/timeshift/timeshift_writer.c @@ -36,13 +36,11 @@ /* * Write data (retry on EAGAIN) */ -static ssize_t _write_fd - ( int fd, const void *buf, size_t count ) -{ +static ssize_t _write_fd(int fd, const void* buf, size_t count) { ssize_t r; size_t n = 0; - while ( n < count ) { - r = write(fd, buf+n, count-n); + while (n < count) { + r = write(fd, buf + n, count - n); if (r == -1) { if (ERRNO_AGAIN(errno)) continue; @@ -54,19 +52,17 @@ static ssize_t _write_fd return count == n ? n : -1; } -static ssize_t _write - ( timeshift_file_t *tsf, const void *buf, size_t count ) -{ - uint8_t *ram; - size_t alloc; - ssize_t ret; +static ssize_t _write(timeshift_file_t* tsf, const void* buf, size_t count) { + uint8_t* ram; + size_t alloc; + ssize_t ret; if (tsf->ram) { tvh_mutex_lock(&tsf->ram_lock); if (tsf->ram_size < tsf->woff + count) { if (tsf->ram_size >= timeshift_conf.ram_segment_size) - alloc = MAX(count, 64*1024); + alloc = MAX(count, 64 * 1024); else - alloc = MAX(count, 4*1024*1024); + alloc = MAX(count, 4 * 1024 * 1024); ram = realloc(tsf->ram, tsf->ram_size + alloc); if (ram == NULL) { tvhwarn(LS_TIMESHIFT, "RAM timeshift memalloc failed"); @@ -91,45 +87,52 @@ static ssize_t _write /* * Write message */ -static ssize_t _write_msg - ( timeshift_file_t *tsf, streaming_message_type_t type, int64_t time, - const void *buf, size_t len ) -{ - size_t len2 = len + sizeof(type) + sizeof(time); +static ssize_t _write_msg(timeshift_file_t* tsf, + streaming_message_type_t type, + int64_t time, + const void* buf, + size_t len) { + size_t len2 = len + sizeof(type) + sizeof(time); ssize_t err, ret; ret = err = _write(tsf, &len2, sizeof(len2)); - if (err < 0) return err; + if (err < 0) + return err; err = _write(tsf, &type, sizeof(type)); - if (err < 0) return err; + if (err < 0) + return err; ret += err; err = _write(tsf, &time, sizeof(time)); - if (err < 0) return err; + if (err < 0) + return err; ret += err; if (len) { err = _write(tsf, buf, len); - if (err < 0) return err; + if (err < 0) + return err; ret += err; } return ret; } -static ssize_t _write_msg_fd - ( int fd, streaming_message_type_t type, int64_t time, - const void *buf, size_t len ) -{ - size_t len2 = len + sizeof(type) + sizeof(time); +static ssize_t +_write_msg_fd(int fd, streaming_message_type_t type, int64_t time, const void* buf, size_t len) { + size_t len2 = len + sizeof(type) + sizeof(time); ssize_t err, ret; ret = err = _write_fd(fd, &len2, sizeof(len2)); - if (err < 0) return err; + if (err < 0) + return err; err = _write_fd(fd, &type, sizeof(type)); - if (err < 0) return err; + if (err < 0) + return err; ret += err; err = _write_fd(fd, &time, sizeof(time)); - if (err < 0) return err; + if (err < 0) + return err; ret += err; if (len) { err = _write_fd(fd, buf, len); - if (err < 0) return err; + if (err < 0) + return err; ret += err; } return ret; @@ -138,18 +141,19 @@ static ssize_t _write_msg_fd /* * Write packet buffer */ -static int _write_pktbuf ( timeshift_file_t *tsf, pktbuf_t *pktbuf ) -{ +static int _write_pktbuf(timeshift_file_t* tsf, pktbuf_t* pktbuf) { ssize_t ret, err; if (pktbuf) { ret = err = _write(tsf, &pktbuf->pb_size, sizeof(pktbuf->pb_size)); - if (err < 0) return err; + if (err < 0) + return err; err = _write(tsf, pktbuf_ptr(pktbuf), pktbuf_len(pktbuf)); - if (err < 0) return err; + if (err < 0) + return err; ret += err; } else { size_t sz = 0; - ret = _write(tsf, &sz, sizeof(sz)); + ret = _write(tsf, &sz, sizeof(sz)); } return ret; } @@ -157,26 +161,25 @@ static int _write_pktbuf ( timeshift_file_t *tsf, pktbuf_t *pktbuf ) /* * Write signal status */ -ssize_t timeshift_write_sigstat - ( timeshift_file_t *tsf, int64_t time, signal_status_t *sigstat ) -{ - return _write_msg(tsf, SMT_SIGNAL_STATUS, time, sigstat, - sizeof(signal_status_t)); +ssize_t timeshift_write_sigstat(timeshift_file_t* tsf, int64_t time, signal_status_t* sigstat) { + return _write_msg(tsf, SMT_SIGNAL_STATUS, time, sigstat, sizeof(signal_status_t)); } /* * Write packet */ -ssize_t timeshift_write_packet ( timeshift_file_t *tsf, int64_t time, th_pkt_t *pkt ) -{ +ssize_t timeshift_write_packet(timeshift_file_t* tsf, int64_t time, th_pkt_t* pkt) { ssize_t ret = 0, err; ret = err = _write_msg(tsf, SMT_PACKET, time, pkt, sizeof(th_pkt_t)); - if (err <= 0) return err; + if (err <= 0) + return err; err = _write_pktbuf(tsf, pkt->pkt_meta); - if (err <= 0) return err; + if (err <= 0) + return err; ret += err; err = _write_pktbuf(tsf, pkt->pkt_payload); - if (err <= 0) return err; + if (err <= 0) + return err; ret += err; return ret; } @@ -184,40 +187,35 @@ ssize_t timeshift_write_packet ( timeshift_file_t *tsf, int64_t time, th_pkt_t * /* * Write MPEGTS data */ -ssize_t timeshift_write_mpegts ( timeshift_file_t *tsf, int64_t time, void *data ) -{ +ssize_t timeshift_write_mpegts(timeshift_file_t* tsf, int64_t time, void* data) { return _write_msg(tsf, SMT_MPEGTS, time, data, 188); } /* * Write skip message */ -ssize_t timeshift_write_skip ( int fd, streaming_skip_t *skip ) -{ +ssize_t timeshift_write_skip(int fd, streaming_skip_t* skip) { return _write_msg_fd(fd, SMT_SKIP, 0, skip, sizeof(streaming_skip_t)); } /* * Write speed message */ -ssize_t timeshift_write_speed ( int fd, int speed ) -{ +ssize_t timeshift_write_speed(int fd, int speed) { return _write_msg_fd(fd, SMT_SPEED, 0, &speed, sizeof(speed)); } /* * Stop */ -ssize_t timeshift_write_stop ( int fd, int code ) -{ +ssize_t timeshift_write_stop(int fd, int code) { return _write_msg_fd(fd, SMT_STOP, 0, &code, sizeof(code)); } /* * Exit */ -ssize_t timeshift_write_exit ( int fd ) -{ +ssize_t timeshift_write_exit(int fd) { int code = 0; return _write_msg_fd(fd, SMT_EXIT, 0, &code, sizeof(code)); } @@ -225,8 +223,7 @@ ssize_t timeshift_write_exit ( int fd ) /* * Write end of file (special internal message) */ -ssize_t timeshift_write_eof ( timeshift_file_t *tsf ) -{ +ssize_t timeshift_write_eof(timeshift_file_t* tsf) { size_t sz = 0; return _write(tsf, &sz, sizeof(sz)); } @@ -234,8 +231,7 @@ ssize_t timeshift_write_eof ( timeshift_file_t *tsf ) /* * Update smt_start */ -static void _update_smt_start ( timeshift_t *ts, streaming_start_t *ss ) -{ +static void _update_smt_start(timeshift_t* ts, streaming_start_t* ss) { int i; if (ts->smt_start) @@ -263,9 +259,8 @@ static void _update_smt_start ( timeshift_t *ts, streaming_start_t *ss ) /* * Stream start handling */ -static void _handle_sstart ( timeshift_t *ts, timeshift_file_t *tsf, streaming_message_t *sm ) -{ - timeshift_index_data_t *ti = calloc(1, sizeof(timeshift_index_data_t)); +static void _handle_sstart(timeshift_t* ts, timeshift_file_t* tsf, streaming_message_t* sm) { + timeshift_index_data_t* ti = calloc(1, sizeof(timeshift_index_data_t)); memoryinfo_alloc(×hift_memoryinfo, sizeof(*ti)); ti->pos = tsf->size; @@ -276,24 +271,23 @@ static void _handle_sstart ( timeshift_t *ts, timeshift_file_t *tsf, streaming_m /* * Index i-frames and every 100th audio frame */ -static void add_frame_to_index ( timeshift_t *ts, timeshift_file_t *tsf, streaming_message_t *sm ) -{ - th_pkt_t *pkt = sm->sm_data; +static void add_frame_to_index(timeshift_t* ts, timeshift_file_t* tsf, streaming_message_t* sm) { + th_pkt_t* pkt = sm->sm_data; /* Index video iframes or audio frames for audio-only streams*/ if ((pkt->pkt_componentindex == ts->vididx && pkt->v.pkt_frametype == PKT_I_FRAME) || (ts->vididx == -1 && pkt->pkt_componentindex == ts->audidx)) { - if(ts->vididx != -1 || ts->audio_packet_counter > 100) { - timeshift_index_iframe_t *ti = calloc(1, sizeof(timeshift_index_iframe_t)); + if (ts->vididx != -1 || ts->audio_packet_counter > 100) { + timeshift_index_iframe_t* ti = calloc(1, sizeof(timeshift_index_iframe_t)); memoryinfo_alloc(×hift_memoryinfo, sizeof(*ti)); ti->pos = tsf->size; ti->time = sm->sm_time; TAILQ_INSERT_TAIL(&tsf->iframes, ti, link); - if(ts->vididx == -1) + if (ts->vididx == -1) ts->audio_packet_counter = 0; } - if(ts->vididx == -1) + if (ts->vididx == -1) ts->audio_packet_counter++; } } @@ -302,9 +296,8 @@ static void add_frame_to_index ( timeshift_t *ts, timeshift_file_t *tsf, streami * Thread * *************************************************************************/ -static inline ssize_t _process_msg0 - ( timeshift_t *ts, timeshift_file_t *tsf, streaming_message_t *sm ) -{ +static inline ssize_t +_process_msg0(timeshift_t* ts, timeshift_file_t* tsf, streaming_message_t* sm) { ssize_t err; if (sm->sm_type == SMT_START) { @@ -319,14 +312,13 @@ static inline ssize_t _process_msg0 } } else if (sm->sm_type == SMT_MPEGTS) { err = timeshift_write_mpegts(tsf, sm->sm_time, sm->sm_data); - } - else { + } else { err = 0; } /* OK */ if (err > 0) { - tsf->last = sm->sm_time; + tsf->last = sm->sm_time; tsf->size += err; atomic_add_u64(×hift_total_size, err); if (tsf->ram) @@ -335,19 +327,18 @@ static inline ssize_t _process_msg0 return err; } -static void _process_msg - ( timeshift_t *ts, streaming_message_t *sm, int *run ) -{ - int err, teletext = 0; - timeshift_file_t *tsf; - th_pkt_t *pkt; +static void _process_msg(timeshift_t* ts, streaming_message_t* sm, int* run) { + int err, teletext = 0; + timeshift_file_t* tsf; + th_pkt_t* pkt; /* Process */ switch (sm->sm_type) { /* Terminate */ case SMT_EXIT: - if (run) *run = 0; + if (run) + *run = 0; break; case SMT_STOP: if (sm->sm_code != SM_CODE_SOURCE_RECONFIGURED && run) @@ -371,7 +362,7 @@ static void _process_msg /* Store */ case SMT_PACKET: if (timeshift_conf.teletext && sm->sm_type == SMT_PACKET) { - pkt = sm->sm_data; + pkt = sm->sm_data; teletext = pkt->pkt_type == SCT_TELETEXT; } /* fall thru */ @@ -387,7 +378,7 @@ static void _process_msg timeshift_packet_log("liv", ts, sm); } if (sm->sm_type == SMT_START) - _update_smt_start(ts, (streaming_start_t *)sm->sm_data); + _update_smt_start(ts, (streaming_start_t*)sm->sm_data); /* do buffering, but without teletext packets */ if (ts->dobuf && !teletext) { if ((tsf = timeshift_filemgr_get(ts, sm->sm_time)) != NULL) { @@ -420,12 +411,11 @@ live: tvh_mutex_unlock(&ts->state_mutex); } -void *timeshift_writer ( void *aux ) -{ - int run = 1; - timeshift_t *ts = aux; - streaming_queue_t *sq = &ts->wr_queue; - streaming_message_t *sm; +void* timeshift_writer(void* aux) { + int run = 1; + timeshift_t* ts = aux; + streaming_queue_t* sq = &ts->wr_queue; + streaming_message_t* sm; tvh_mutex_lock(&sq->sq_mutex); diff --git a/src/tprofile.c b/src/tprofile.c index 5d9aeaacb..ece190746 100644 --- a/src/tprofile.c +++ b/src/tprofile.c @@ -22,14 +22,13 @@ #include "clock.h" #include "tprofile.h" -int tprofile_running; +int tprofile_running; static tvh_mutex_t tprofile_mutex; static tvh_mutex_t qprofile_mutex; static LIST_HEAD(, tprofile) tprofile_all; static LIST_HEAD(, qprofile) qprofile_all; -void tprofile_init1(tprofile_t *tprof, const char *name) -{ +void tprofile_init1(tprofile_t* tprof, const char* name) { memset(tprof, 0, sizeof(*tprof)); tprof->name = strdup(name); tvh_mutex_lock(&tprofile_mutex); @@ -37,39 +36,34 @@ void tprofile_init1(tprofile_t *tprof, const char *name) tvh_mutex_unlock(&tprofile_mutex); } -static void tprofile_time_done(tprofile_time_t *tpt) -{ +static void tprofile_time_done(tprofile_time_t* tpt) { free(tpt->id); } -static void tprofile_avg_done(tprofile_avg_t *tpa) -{ -} +static void tprofile_avg_done(tprofile_avg_t* tpa) {} -static void tprofile_destroy(tprofile_t *tprof) -{ +static void tprofile_destroy(tprofile_t* tprof) { free(tprof->name); free(tprof->start_id); tprofile_time_done(&tprof->tmax); tprofile_avg_done(&tprof->tavg); } -void tprofile_done1(tprofile_t *tprof) -{ - tprofile_t *fin = malloc(sizeof(*fin)); +void tprofile_done1(tprofile_t* tprof) { + tprofile_t* fin = malloc(sizeof(*fin)); tvh_mutex_lock(&tprofile_mutex); LIST_REMOVE(tprof, link); if (fin) { - *fin = *tprof; + *fin = *tprof; fin->changed = fin->finish = 1; LIST_INSERT_HEAD(&tprofile_all, fin, link); } tvh_mutex_unlock(&tprofile_mutex); - if (!fin) tprofile_destroy(tprof); + if (!fin) + tprofile_destroy(tprof); } -void tprofile_start1(tprofile_t *tprof, const char *id) -{ +void tprofile_start1(tprofile_t* tprof, const char* id) { tvh_mutex_lock(&tprofile_mutex); assert(tprof->start == 0); tprof->start = getfastmonoclock(); @@ -83,23 +77,18 @@ void tprofile_start1(tprofile_t *tprof, const char *id) tvh_mutex_unlock(&tprofile_mutex); } -static void -tprofile_time_replace(tprofile_time_t *tpt, const char *id, uint64_t t) -{ +static void tprofile_time_replace(tprofile_time_t* tpt, const char* id, uint64_t t) { free(tpt->id); tpt->id = strdup(id); - tpt->t = t; + tpt->t = t; } -static void -tprofile_avg_update(tprofile_avg_t *tpa, uint64_t val) -{ +static void tprofile_avg_update(tprofile_avg_t* tpa, uint64_t val) { tpa->avg = (tpa->avg * tpa->count + val) / (tpa->count + 1); tpa->count++; } -void tprofile_finish1(tprofile_t *tprof) -{ +void tprofile_finish1(tprofile_t* tprof) { if (tprof->start) { uint64_t mono, diff; tvh_mutex_lock(&tprofile_mutex); @@ -110,14 +99,13 @@ void tprofile_finish1(tprofile_t *tprof) tprofile_avg_update(&tprof->tavg, diff); free(tprof->start_id); tprof->start_id = NULL; - tprof->start = 0; - tprof->changed = 1; + tprof->start = 0; + tprof->changed = 1; tvh_mutex_unlock(&tprofile_mutex); } } -void tprofile_queue_init1(qprofile_t *qprof, const char *name) -{ +void tprofile_queue_init1(qprofile_t* qprof, const char* name) { memset(qprof, 0, sizeof(*qprof)); qprof->name = strdup(name); tvh_mutex_lock(&qprofile_mutex); @@ -125,55 +113,46 @@ void tprofile_queue_init1(qprofile_t *qprof, const char *name) tvh_mutex_unlock(&qprofile_mutex); } -static void qprofile_time_done(qprofile_time_t *qpt) -{ +static void qprofile_time_done(qprofile_time_t* qpt) { free(qpt->id); } -static void qprofile_avg_done(tprofile_avg_t *tpa) -{ -} +static void qprofile_avg_done(tprofile_avg_t* tpa) {} -static void qprofile_destroy(qprofile_t *qprof) -{ +static void qprofile_destroy(qprofile_t* qprof) { free(qprof->name); qprofile_time_done(&qprof->qmax); qprofile_avg_done(&qprof->qavg); } -void tprofile_queue_done1(qprofile_t *qprof) -{ - qprofile_t *fin = malloc(sizeof(*fin)); +void tprofile_queue_done1(qprofile_t* qprof) { + qprofile_t* fin = malloc(sizeof(*fin)); tvh_mutex_lock(&qprofile_mutex); LIST_REMOVE(qprof, link); if (fin) { - *fin = *qprof; + *fin = *qprof; fin->changed = fin->finish = 1; LIST_INSERT_HEAD(&qprofile_all, fin, link); } tvh_mutex_unlock(&qprofile_mutex); - if (!fin) qprofile_destroy(qprof); + if (!fin) + qprofile_destroy(qprof); } -static void -qprofile_time_replace(qprofile_time_t *qpt, const char *id, uint64_t t, uint64_t pos) -{ +static void qprofile_time_replace(qprofile_time_t* qpt, const char* id, uint64_t t, uint64_t pos) { free(qpt->id); - qpt->id = strdup(id); - qpt->t = t; + qpt->id = strdup(id); + qpt->t = t; qpt->pos = pos; } -static inline void -qprofile_avg_update(qprofile_avg_t *tpa, uint64_t val) -{ - tprofile_avg_update((tprofile_avg_t *)tpa, val); +static inline void qprofile_avg_update(qprofile_avg_t* tpa, uint64_t val) { + tprofile_avg_update((tprofile_avg_t*)tpa, val); } #include -void tprofile_queue_set1(qprofile_t *qprof, const char *id, uint64_t pos) -{ +void tprofile_queue_set1(qprofile_t* qprof, const char* id, uint64_t pos) { uint64_t mono; tvh_mutex_lock(&qprofile_mutex); mono = getfastmonoclock(); @@ -184,35 +163,35 @@ void tprofile_queue_set1(qprofile_t *qprof, const char *id, uint64_t pos) tvh_mutex_unlock(&qprofile_mutex); } -void tprofile_queue_add1(qprofile_t *qprof, const char *id, uint64_t count) -{ +void tprofile_queue_add1(qprofile_t* qprof, const char* id, uint64_t count) { tvh_mutex_lock(&qprofile_mutex); qprof->qsum += count; tvh_mutex_unlock(&qprofile_mutex); } -void tprofile_queue_drop1(qprofile_t *qprof, const char *id, uint64_t count) -{ +void tprofile_queue_drop1(qprofile_t* qprof, const char* id, uint64_t count) { tvh_mutex_lock(&qprofile_mutex); qprof->qdrop += count; qprof->qdropcnt++; tvh_mutex_unlock(&qprofile_mutex); } -static void tprofile_log_tstats(void) -{ +static void tprofile_log_tstats(void) { tprofile_t *tprof, *tprof_next; tvh_mutex_lock(&tprofile_mutex); for (tprof = LIST_FIRST(&tprofile_all); tprof; tprof = tprof_next) { tprof_next = LIST_NEXT(tprof, link); - if (tprof->changed == 0) continue; - tvhtrace(LS_TPROF, "%s: max/avg/cnt=%"PRIu64"ms/%"PRIu64"ms/%"PRIu64" (max=%s)%s", - tprof->name, - mono2ms(tprof->tmax.t), - mono2ms(tprof->tavg.avg), tprof->tavg.count, - tprof->tmax.id ?: "?", - tprof->finish ? " destroyed" : ""); + if (tprof->changed == 0) + continue; + tvhtrace(LS_TPROF, + "%s: max/avg/cnt=%" PRIu64 "ms/%" PRIu64 "ms/%" PRIu64 " (max=%s)%s", + tprof->name, + mono2ms(tprof->tmax.t), + mono2ms(tprof->tavg.avg), + tprof->tavg.count, + tprof->tmax.id ?: "?", + tprof->finish ? " destroyed" : ""); if (tprof->finish) { LIST_REMOVE(tprof, link); tprofile_destroy(tprof); @@ -224,28 +203,32 @@ static void tprofile_log_tstats(void) tvh_mutex_unlock(&tprofile_mutex); } -static void qprofile_log_qstats(void) -{ +static void qprofile_log_qstats(void) { qprofile_t *qprof, *qprof_next; - uint64_t mono, diff; + uint64_t mono, diff; tvh_mutex_lock(&qprofile_mutex); mono = getfastmonoclock(); for (qprof = LIST_FIRST(&qprofile_all); qprof; qprof = qprof_next) { qprof_next = LIST_NEXT(qprof, link); - if (qprof->changed == 0) continue; + if (qprof->changed == 0) + continue; diff = qprof->tstamp ? mono - qprof->tstamp : 1; - if (diff == 0) diff = 1; - tvhtrace(LS_QPROF, "%s: max/avg/cnt/drop/dropcnt=%" - PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64"/%"PRIu64 - " (max=%s -%"PRId64"sec) BW=%"PRId64"%s", - qprof->name, - qprof->qmax.pos, - qprof->qavg.avg, qprof->qavg.count, - qprof->qdrop, qprof->qdropcnt, - qprof->qmax.id, mono2sec(mono - qprof->qmax.t), - sec2mono(qprof->qsum) / diff, - qprof->finish ? " destroyed" : ""); + if (diff == 0) + diff = 1; + tvhtrace(LS_QPROF, + "%s: max/avg/cnt/drop/dropcnt=%" PRIu64 "/%" PRIu64 "/%" PRIu64 "/%" PRIu64 "/%" PRIu64 + " (max=%s -%" PRId64 "sec) BW=%" PRId64 "%s", + qprof->name, + qprof->qmax.pos, + qprof->qavg.avg, + qprof->qavg.count, + qprof->qdrop, + qprof->qdropcnt, + qprof->qmax.id, + mono2sec(mono - qprof->qmax.t), + sec2mono(qprof->qsum) / diff, + qprof->finish ? " destroyed" : ""); if (qprof->finish) { LIST_REMOVE(qprof, link); qprofile_destroy(qprof); @@ -253,32 +236,28 @@ static void qprofile_log_qstats(void) continue; } qprof->changed = 0; - qprof->qsum = 0; - qprof->tstamp = mono; + qprof->qsum = 0; + qprof->tstamp = mono; } tvh_mutex_unlock(&qprofile_mutex); } -void tprofile_log_stats1(void) -{ +void tprofile_log_stats1(void) { tprofile_log_tstats(); qprofile_log_qstats(); } -char *tprofile_get_json_stats(void) -{ +char* tprofile_get_json_stats(void) { return NULL; } -void tprofile_module_init(int enable) -{ +void tprofile_module_init(int enable) { tprofile_running = enable; tvh_mutex_init(&tprofile_mutex, NULL); tvh_mutex_init(&qprofile_mutex, NULL); } -void tprofile_module_done(void) -{ +void tprofile_module_done(void) { tprofile_log_stats1(); /* destroy all items in the finish state */ assert(LIST_FIRST(&tprofile_all) == NULL); assert(LIST_FIRST(&qprofile_all) == NULL); diff --git a/src/tprofile.h b/src/tprofile.h index ddfba6e9a..672f3549c 100644 --- a/src/tprofile.h +++ b/src/tprofile.h @@ -19,16 +19,16 @@ #ifndef __TVH_TPROFILE_H__ #define __TVH_TPROFILE_H__ -#define STRINGIFY(s) # s -#define SRCLINEID() SRCLINEID2(__FILE__, __LINE__) -#define SRCLINEID2(f,l) f ":" STRINGIFY(l) +#define STRINGIFY(s) #s +#define SRCLINEID() SRCLINEID2(__FILE__, __LINE__) +#define SRCLINEID2(f, l) f ":" STRINGIFY(l) -typedef struct tprofile_avg tprofile_avg_t; +typedef struct tprofile_avg tprofile_avg_t; typedef struct tprofile_time tprofile_time_t; -typedef struct tprofile tprofile_t; -typedef struct tprofile_avg qprofile_avg_t; +typedef struct tprofile tprofile_t; +typedef struct tprofile_avg qprofile_avg_t; typedef struct qprofile_time qprofile_time_t; -typedef struct qprofile qprofile_t; +typedef struct qprofile qprofile_t; struct tprofile_avg { uint64_t count; @@ -37,79 +37,99 @@ struct tprofile_avg { struct tprofile_time { uint64_t t; - char *id; + char* id; }; struct tprofile { LIST_ENTRY(tprofile) link; - char *name; + char* name; tprofile_time_t tmax; - tprofile_avg_t tavg; - uint64_t start; - char *start_id; - uint8_t changed; - uint8_t finish; + tprofile_avg_t tavg; + uint64_t start; + char* start_id; + uint8_t changed; + uint8_t finish; }; struct qprofile_time { uint64_t t; uint64_t pos; - char *id; + char* id; }; struct qprofile { LIST_ENTRY(qprofile) link; - char *name; - uint64_t qpos; + char* name; + uint64_t qpos; qprofile_time_t qmax; - tprofile_avg_t qavg; - uint64_t qsum; - uint64_t qdrop; - uint64_t qdropcnt; - uint64_t tstamp; - uint8_t changed; - uint8_t finish; + tprofile_avg_t qavg; + uint64_t qsum; + uint64_t qdrop; + uint64_t qdropcnt; + uint64_t tstamp; + uint8_t changed; + uint8_t finish; }; extern int tprofile_running; -void tprofile_init1(tprofile_t *tprof, const char *name); -void tprofile_done1(tprofile_t *tprof); -void tprofile_start1(tprofile_t *tprof, const char *id); -void tprofile_finish1(tprofile_t *tprof); - -static inline void tprofile_init(tprofile_t *tprof, const char *name) - { if (tprofile_running) tprofile_init1(tprof, name); } -static inline void tprofile_done(tprofile_t *tprof) - { if (tprofile_running) tprofile_done1(tprof); } -static inline void tprofile_start(tprofile_t *tprof, const char *id) - { if (tprofile_running) tprofile_start1(tprof, id); } -static inline void tprofile_finish(tprofile_t *tprof) - { if (tprofile_running) tprofile_finish1(tprof); } - -void tprofile_queue_init1(qprofile_t *qprof, const char *name); -void tprofile_queue_done1(qprofile_t *qprof); -void tprofile_queue_set1(qprofile_t *qprof, const char *id, uint64_t pos); -void tprofile_queue_add1(qprofile_t *qprof, const char *id, uint64_t pos); -void tprofile_queue_drop1(qprofile_t *qprof, const char *id, uint64_t pos); - -static inline void tprofile_queue_init(qprofile_t *qprof, const char *name) - { if (tprofile_running) tprofile_queue_init1(qprof, name); } -static inline void tprofile_queue_done(qprofile_t *qprof) - { if (tprofile_running) tprofile_queue_done1(qprof); } -static inline void tprofile_queue_set(qprofile_t *qprof, const char *id, uint64_t pos) - { if (tprofile_running) tprofile_queue_set1(qprof, id, pos); } -static inline void tprofile_queue_add(qprofile_t *qprof, const char *id, uint64_t pos) - { if (tprofile_running) tprofile_queue_add1(qprof, id, pos); } -static inline void tprofile_queue_drop(qprofile_t *qprof, const char *id, uint64_t pos) - { if (tprofile_running) tprofile_queue_drop1(qprof, id, pos); } +void tprofile_init1(tprofile_t* tprof, const char* name); +void tprofile_done1(tprofile_t* tprof); +void tprofile_start1(tprofile_t* tprof, const char* id); +void tprofile_finish1(tprofile_t* tprof); + +static inline void tprofile_init(tprofile_t* tprof, const char* name) { + if (tprofile_running) + tprofile_init1(tprof, name); +} +static inline void tprofile_done(tprofile_t* tprof) { + if (tprofile_running) + tprofile_done1(tprof); +} +static inline void tprofile_start(tprofile_t* tprof, const char* id) { + if (tprofile_running) + tprofile_start1(tprof, id); +} +static inline void tprofile_finish(tprofile_t* tprof) { + if (tprofile_running) + tprofile_finish1(tprof); +} + +void tprofile_queue_init1(qprofile_t* qprof, const char* name); +void tprofile_queue_done1(qprofile_t* qprof); +void tprofile_queue_set1(qprofile_t* qprof, const char* id, uint64_t pos); +void tprofile_queue_add1(qprofile_t* qprof, const char* id, uint64_t pos); +void tprofile_queue_drop1(qprofile_t* qprof, const char* id, uint64_t pos); + +static inline void tprofile_queue_init(qprofile_t* qprof, const char* name) { + if (tprofile_running) + tprofile_queue_init1(qprof, name); +} +static inline void tprofile_queue_done(qprofile_t* qprof) { + if (tprofile_running) + tprofile_queue_done1(qprof); +} +static inline void tprofile_queue_set(qprofile_t* qprof, const char* id, uint64_t pos) { + if (tprofile_running) + tprofile_queue_set1(qprof, id, pos); +} +static inline void tprofile_queue_add(qprofile_t* qprof, const char* id, uint64_t pos) { + if (tprofile_running) + tprofile_queue_add1(qprof, id, pos); +} +static inline void tprofile_queue_drop(qprofile_t* qprof, const char* id, uint64_t pos) { + if (tprofile_running) + tprofile_queue_drop1(qprof, id, pos); +} void tprofile_log_stats1(void); -static inline void tprofile_log_stats(void) - { if (tprofile_running) tprofile_log_stats1(); } +static inline void tprofile_log_stats(void) { + if (tprofile_running) + tprofile_log_stats1(); +} -char *tprofile_get_json_stats(void); +char* tprofile_get_json_stats(void); void tprofile_module_init(int enable); void tprofile_module_done(void); diff --git a/src/transcoding/codec.h b/src/transcoding/codec.h index dd41c84f8..f7fb00542 100644 --- a/src/transcoding/codec.h +++ b/src/transcoding/codec.h @@ -17,7 +17,6 @@ * along with this program. If not, see . */ - #ifndef TVH_TRANSCODING_CODEC_H__ #define TVH_TRANSCODING_CODEC_H__ @@ -32,156 +31,120 @@ #include - #define tvh_ssc_t streaming_start_component_t #define tvh_sct_t streaming_component_type_t -typedef struct tvh_codec TVHCodec; +typedef struct tvh_codec TVHCodec; typedef struct tvh_codec_profile TVHCodecProfile; /* codec_profile_class ====================================================== */ -typedef int (*codec_profile_setup_meth) (TVHCodecProfile *, tvh_ssc_t *); -typedef int (*codec_profile_is_copy_meth) (TVHCodecProfile *, tvh_ssc_t *); -typedef int (*codec_profile_open_meth) (TVHCodecProfile *, AVDictionary **); +typedef int (*codec_profile_setup_meth)(TVHCodecProfile*, tvh_ssc_t*); +typedef int (*codec_profile_is_copy_meth)(TVHCodecProfile*, tvh_ssc_t*); +typedef int (*codec_profile_open_meth)(TVHCodecProfile*, AVDictionary**); typedef struct { - idclass_t idclass; - codec_profile_setup_meth setup; - codec_profile_is_copy_meth is_copy; - codec_profile_open_meth open; + idclass_t idclass; + codec_profile_setup_meth setup; + codec_profile_is_copy_meth is_copy; + codec_profile_open_meth open; } codec_profile_class_t; - /* TVHCodec ================================================================= */ struct tvh_codec { - const char *name; - size_t size; - const codec_profile_class_t *idclass; - const AVCodec *codec; - const AVProfile *profiles; - int (*profile_init)(TVHCodecProfile *, htsmsg_t *conf); - void (*profile_destroy)(TVHCodecProfile *); - SLIST_ENTRY(tvh_codec) link; + const char* name; + size_t size; + const codec_profile_class_t* idclass; + const AVCodec* codec; + const AVProfile* profiles; + int (*profile_init)(TVHCodecProfile*, htsmsg_t* conf); + void (*profile_destroy)(TVHCodecProfile*); + SLIST_ENTRY(tvh_codec) link; }; SLIST_HEAD(TVHCodecs, tvh_codec); extern struct TVHCodecs tvh_codecs; -const idclass_t * -tvh_codec_get_class(TVHCodec *self); - -const char * -tvh_codec_get_name(TVHCodec *self); +const idclass_t* tvh_codec_get_class(TVHCodec* self); -const char * -tvh_codec_get_title(TVHCodec *self); +const char* tvh_codec_get_name(TVHCodec* self); +const char* tvh_codec_get_title(TVHCodec* self); /* TVHCodecProfile ========================================================== */ extern const codec_profile_class_t codec_profile_class; struct tvh_codec_profile { - idnode_t idnode; - TVHCodec *codec; - char *name; - char *description; - char *codec_name; - double bit_rate; - double qscale; - int profile; - int low_power; - int filter_hw_denoise; - int filter_hw_sharpness; - char *device; // for hardware acceleration - LIST_ENTRY(tvh_codec_profile) link; + idnode_t idnode; + TVHCodec* codec; + char* name; + char* description; + char* codec_name; + double bit_rate; + double qscale; + int profile; + int low_power; + int filter_hw_denoise; + int filter_hw_sharpness; + char* device; // for hardware acceleration + LIST_ENTRY(tvh_codec_profile) link; }; LIST_HEAD(TVHCodecProfiles, tvh_codec_profile); extern struct TVHCodecProfiles tvh_codec_profiles; -int -tvh_codec_profile_create(htsmsg_t *conf, const char *uuid, int save); +int tvh_codec_profile_create(htsmsg_t* conf, const char* uuid, int save); -const char * -tvh_codec_profile_get_status(TVHCodecProfile *self); +const char* tvh_codec_profile_get_status(TVHCodecProfile* self); -const char * -tvh_codec_profile_get_name(TVHCodecProfile *self); +const char* tvh_codec_profile_get_name(TVHCodecProfile* self); -const char * -tvh_codec_profile_get_title(TVHCodecProfile *self); - -const AVCodec * -tvh_codec_profile_get_avcodec(TVHCodecProfile *self); +const char* tvh_codec_profile_get_title(TVHCodecProfile* self); +const AVCodec* tvh_codec_profile_get_avcodec(TVHCodecProfile* self); /* transcode api */ -int -tvh_codec_profile_is_copy(TVHCodecProfile *self, tvh_ssc_t *ssc); // XXX: not too sure... - -int -tvh_codec_profile_open(TVHCodecProfile *self, AVDictionary **opts); +int tvh_codec_profile_is_copy(TVHCodecProfile* self, tvh_ssc_t* ssc); // XXX: not too sure... +int tvh_codec_profile_open(TVHCodecProfile* self, AVDictionary** opts); /* video */ -int -tvh_codec_profile_video_init(TVHCodecProfile *_self, htsmsg_t *conf); +int tvh_codec_profile_video_init(TVHCodecProfile* _self, htsmsg_t* conf); -void -tvh_codec_profile_video_destroy(TVHCodecProfile *_self); +void tvh_codec_profile_video_destroy(TVHCodecProfile* _self); -int -tvh_codec_profile_video_get_hwaccel(TVHCodecProfile *self); - -const enum AVPixelFormat * -tvh_codec_profile_video_get_pix_fmts(TVHCodecProfile *self); +int tvh_codec_profile_video_get_hwaccel(TVHCodecProfile* self); +const enum AVPixelFormat* tvh_codec_profile_video_get_pix_fmts(TVHCodecProfile* self); /* audio */ -int -tvh_codec_profile_audio_init(TVHCodecProfile *_self, htsmsg_t *conf); - -void -tvh_codec_profile_audio_destroy(TVHCodecProfile *_self); +int tvh_codec_profile_audio_init(TVHCodecProfile* _self, htsmsg_t* conf); -const enum AVSampleFormat * -tvh_codec_profile_audio_get_sample_fmts(TVHCodecProfile *self); +void tvh_codec_profile_audio_destroy(TVHCodecProfile* _self); -const int * -tvh_codec_profile_audio_get_sample_rates(TVHCodecProfile *self); +const enum AVSampleFormat* tvh_codec_profile_audio_get_sample_fmts(TVHCodecProfile* self); -const uint64_t * -tvh_codec_profile_audio_get_channel_layouts(TVHCodecProfile *self); +const int* tvh_codec_profile_audio_get_sample_rates(TVHCodecProfile* self); +const uint64_t* tvh_codec_profile_audio_get_channel_layouts(TVHCodecProfile* self); /* module level ============================================================= */ -TVHCodecProfile * -codec_find_profile(const char *name); +TVHCodecProfile* codec_find_profile(const char* name); -htsmsg_t * -codec_get_profiles_list(enum AVMediaType media_type); +htsmsg_t* codec_get_profiles_list(enum AVMediaType media_type); -void -codec_init(void); +void codec_init(void); -void -codec_done(void); +void codec_done(void); #else -static inline void -codec_init(void) -{ -} +static inline void codec_init(void) {} -static inline void -codec_done(void) -{ -} +static inline void codec_done(void) {} #endif diff --git a/src/transcoding/codec/codec.c b/src/transcoding/codec/codec.c index 631d36207..b256b41b2 100644 --- a/src/transcoding/codec/codec.c +++ b/src/transcoding/codec/codec.c @@ -17,13 +17,10 @@ * along with this program. If not, see . */ - #include "internals.h" - struct TVHCodecs tvh_codecs; - /* encoders ================================================================= */ extern TVHCodec tvh_codec_mpeg2video; @@ -75,240 +72,188 @@ extern TVHCodec tvh_codec_nvenc_hevc; extern TVHCodec tvh_codec_omx_h264; #endif - /* AVCodec ================================================================== */ -static enum AVMediaType -codec_get_type(const AVCodec *self) -{ - return self->type; +static enum AVMediaType codec_get_type(const AVCodec* self) { + return self->type; } - -static const char * -codec_get_type_string(const AVCodec *self) -{ - return av_get_media_type_string(self->type); +static const char* codec_get_type_string(const AVCodec* self) { + return av_get_media_type_string(self->type); } +const char* codec_get_title(const AVCodec* self) { + static __thread char codec_title[TVH_TITLE_LEN]; -const char * -codec_get_title(const AVCodec *self) -{ - static __thread char codec_title[TVH_TITLE_LEN]; - - memset(codec_title, 0, sizeof(codec_title)); - if ( - str_snprintf(codec_title, sizeof(codec_title), - self->long_name ? "%s: %s%s" : "%s%s%s", - self->name, self->long_name ? self->long_name : "", - (self->capabilities & AV_CODEC_CAP_EXPERIMENTAL) ? " (Experimental)" : "") - ) { - return NULL; - } - return codec_title; + memset(codec_title, 0, sizeof(codec_title)); + if (str_snprintf(codec_title, + sizeof(codec_title), + self->long_name ? "%s: %s%s" : "%s%s%s", + self->name, + self->long_name ? self->long_name : "", + (self->capabilities & AV_CODEC_CAP_EXPERIMENTAL) ? " (Experimental)" : "")) { + return NULL; + } + return codec_title; } - /* TVHCodec ================================================================= */ -static void -tvh_codec_video_init(TVHVideoCodec *self, const AVCodec *codec) -{ - if (!self->pix_fmts) { - self->pix_fmts = codec->pix_fmts; - } +static void tvh_codec_video_init(TVHVideoCodec* self, const AVCodec* codec) { + if (!self->pix_fmts) { + self->pix_fmts = codec->pix_fmts; + } } -static void -tvh_codec_audio_init(TVHAudioCodec *self, const AVCodec *codec) -{ - static int default_sample_rates[] = { - 44100, 48000, 96000, 192000, 0 - }; - - if (!self->sample_fmts) { - self->sample_fmts = codec->sample_fmts; - } - if (!self->sample_rates) { - self->sample_rates = codec->supported_samplerates; - if (!self->sample_rates) - self->sample_rates = default_sample_rates; - } - if (!self->channel_layouts) { - self->channel_layouts = codec->channel_layouts; - } +static void tvh_codec_audio_init(TVHAudioCodec* self, const AVCodec* codec) { + static int default_sample_rates[] = {44100, 48000, 96000, 192000, 0}; + + if (!self->sample_fmts) { + self->sample_fmts = codec->sample_fmts; + } + if (!self->sample_rates) { + self->sample_rates = codec->supported_samplerates; + if (!self->sample_rates) + self->sample_rates = default_sample_rates; + } + if (!self->channel_layouts) { + self->channel_layouts = codec->channel_layouts; + } } - -static void -tvh_codec_init(TVHCodec *self, const AVCodec *codec) -{ - if (!self->profiles) { - self->profiles = codec->profiles; - } - switch (codec->type) { - case AVMEDIA_TYPE_VIDEO: - tvh_codec_video_init((TVHVideoCodec *)self, codec); - break; - case AVMEDIA_TYPE_AUDIO: - tvh_codec_audio_init((TVHAudioCodec *)self, codec); - break; - default: - break; - } +static void tvh_codec_init(TVHCodec* self, const AVCodec* codec) { + if (!self->profiles) { + self->profiles = codec->profiles; + } + switch (codec->type) { + case AVMEDIA_TYPE_VIDEO: + tvh_codec_video_init((TVHVideoCodec*)self, codec); + break; + case AVMEDIA_TYPE_AUDIO: + tvh_codec_audio_init((TVHAudioCodec*)self, codec); + break; + default: + break; + } } - -static void -tvh_codec_register(TVHCodec *self) -{ - static const size_t min_size = sizeof(TVHCodecProfile); - const AVCodec *codec = NULL; - - if (tvh_str_default(self->name, NULL) == NULL || - self->size < min_size || !self->idclass) { - tvherror(LS_CODEC, "incomplete/wrong definition for '%s' codec", - self->name ? self->name : ""); - return; - } - - if ((codec = avcodec_find_encoder_by_name(self->name)) && - !(codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { - tvh_codec_init(self, codec); - self->codec = codec; // enabled - } - idclass_register((idclass_t *)self->idclass); - SLIST_INSERT_HEAD(&tvh_codecs, self, link); - tvhinfo(LS_CODEC, "'%s' encoder registered", self->name); +static void tvh_codec_register(TVHCodec* self) { + static const size_t min_size = sizeof(TVHCodecProfile); + const AVCodec* codec = NULL; + + if (tvh_str_default(self->name, NULL) == NULL || self->size < min_size || !self->idclass) { + tvherror(LS_CODEC, + "incomplete/wrong definition for '%s' codec", + self->name ? self->name : ""); + return; + } + + if ((codec = avcodec_find_encoder_by_name(self->name)) && + !(codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE)) { + tvh_codec_init(self, codec); + self->codec = codec; // enabled + } + idclass_register((idclass_t*)self->idclass); + SLIST_INSERT_HEAD(&tvh_codecs, self, link); + tvhinfo(LS_CODEC, "'%s' encoder registered", self->name); } - /* exposed */ -const idclass_t * -tvh_codec_get_class(TVHCodec *self) -{ - return (idclass_t *)self->idclass; +const idclass_t* tvh_codec_get_class(TVHCodec* self) { + return (idclass_t*)self->idclass; } - -const char * -tvh_codec_get_name(TVHCodec *self) -{ - return self->name; +const char* tvh_codec_get_name(TVHCodec* self) { + return self->name; } - -const char * -tvh_codec_get_title(TVHCodec *self) -{ - return self->codec ? codec_get_title(self->codec) : self->name; +const char* tvh_codec_get_title(TVHCodec* self) { + return self->codec ? codec_get_title(self->codec) : self->name; } - -enum AVMediaType -tvh_codec_get_type(TVHCodec *self) -{ - return self->codec ? codec_get_type(self->codec) : AVMEDIA_TYPE_UNKNOWN; +enum AVMediaType tvh_codec_get_type(TVHCodec* self) { + return self->codec ? codec_get_type(self->codec) : AVMEDIA_TYPE_UNKNOWN; } - -const char * -tvh_codec_get_type_string(TVHCodec *self) -{ - return self->codec ? codec_get_type_string(self->codec) : ""; +const char* tvh_codec_get_type_string(TVHCodec* self) { + return self->codec ? codec_get_type_string(self->codec) : ""; } - -const AVCodec * -tvh_codec_get_codec(TVHCodec *self) -{ - return self->codec; +const AVCodec* tvh_codec_get_codec(TVHCodec* self) { + return self->codec; } - -int -tvh_codec_is_enabled(TVHCodec *self) -{ - return self->codec ? 1 : 0; +int tvh_codec_is_enabled(TVHCodec* self) { + return self->codec ? 1 : 0; } +TVHCodec* tvh_codec_find(const char* name) { + TVHCodec* codec = NULL; -TVHCodec * -tvh_codec_find(const char *name) -{ - TVHCodec *codec = NULL; - - SLIST_FOREACH(codec, &tvh_codecs, link) { - if (!strcmp(codec->name, name)) { - return codec; - } + SLIST_FOREACH (codec, &tvh_codecs, link) { + if (!strcmp(codec->name, name)) { + return codec; } - return NULL; + } + return NULL; } - -void -tvh_codecs_register() -{ - SLIST_INIT(&tvh_codecs); - tvh_codec_register(&tvh_codec_mpeg2video); - tvh_codec_register(&tvh_codec_mp2); - tvh_codec_register(&tvh_codec_aac); - tvh_codec_register(&tvh_codec_vorbis); - tvh_codec_register(&tvh_codec_flac); +void tvh_codecs_register() { + SLIST_INIT(&tvh_codecs); + tvh_codec_register(&tvh_codec_mpeg2video); + tvh_codec_register(&tvh_codec_mp2); + tvh_codec_register(&tvh_codec_aac); + tvh_codec_register(&tvh_codec_vorbis); + tvh_codec_register(&tvh_codec_flac); #if ENABLE_LIBX264 - tvh_codec_register(&tvh_codec_libx264); + tvh_codec_register(&tvh_codec_libx264); #endif #if ENABLE_LIBX265 - tvh_codec_register(&tvh_codec_libx265); + tvh_codec_register(&tvh_codec_libx265); #endif #if ENABLE_LIBVPX - tvh_codec_register(&tvh_codec_libvpx_vp8); - tvh_codec_register(&tvh_codec_libvpx_vp9); + tvh_codec_register(&tvh_codec_libvpx_vp8); + tvh_codec_register(&tvh_codec_libvpx_vp9); #endif #if ENABLE_LIBTHEORA - tvh_codec_register(&tvh_codec_libtheora); + tvh_codec_register(&tvh_codec_libtheora); #endif #if ENABLE_LIBVORBIS - tvh_codec_register(&tvh_codec_libvorbis); + tvh_codec_register(&tvh_codec_libvorbis); #endif #if ENABLE_LIBFDKAAC - tvh_codec_register(&tvh_codec_libfdk_aac); + tvh_codec_register(&tvh_codec_libfdk_aac); #endif #if ENABLE_LIBOPUS - tvh_codec_register(&tvh_codec_libopus); + tvh_codec_register(&tvh_codec_libopus); #endif #if ENABLE_VAAPI - tvh_codec_register(&tvh_codec_vaapi_h264); - tvh_codec_register(&tvh_codec_vaapi_hevc); - tvh_codec_register(&tvh_codec_vaapi_vp8); - tvh_codec_register(&tvh_codec_vaapi_vp9); + tvh_codec_register(&tvh_codec_vaapi_h264); + tvh_codec_register(&tvh_codec_vaapi_hevc); + tvh_codec_register(&tvh_codec_vaapi_vp8); + tvh_codec_register(&tvh_codec_vaapi_vp9); #endif #if ENABLE_NVENC - tvh_codec_register(&tvh_codec_nvenc_h264); - tvh_codec_register(&tvh_codec_nvenc_hevc); + tvh_codec_register(&tvh_codec_nvenc_h264); + tvh_codec_register(&tvh_codec_nvenc_hevc); #endif #if ENABLE_OMX - tvh_codec_register(&tvh_codec_omx_h264); + tvh_codec_register(&tvh_codec_omx_h264); #endif } - -void -tvh_codecs_forget() -{ - tvhinfo(LS_CODEC, "forgetting codecs"); - while (!SLIST_EMPTY(&tvh_codecs)) { - SLIST_REMOVE_HEAD(&tvh_codecs, link); - } +void tvh_codecs_forget() { + tvhinfo(LS_CODEC, "forgetting codecs"); + while (!SLIST_EMPTY(&tvh_codecs)) { + SLIST_REMOVE_HEAD(&tvh_codecs, link); + } } diff --git a/src/transcoding/codec/codecs/aac.c b/src/transcoding/codec/codecs/aac.c index 4c51736e2..d5665a7c9 100644 --- a/src/transcoding/codec/codecs/aac.c +++ b/src/transcoding/codec/codecs/aac.c @@ -17,81 +17,65 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" - /* aac ====================================================================== */ static const AVProfile aac_profiles[] = { - { FF_PROFILE_AAC_MAIN, "Main" }, - { FF_PROFILE_AAC_LOW, "LC" }, - { FF_PROFILE_AAC_LTP, "LTP" }, - { FF_PROFILE_UNKNOWN }, + {FF_PROFILE_AAC_MAIN, "Main"}, + {FF_PROFILE_AAC_LOW, "LC"}, + {FF_PROFILE_AAC_LTP, "LTP"}, + {FF_PROFILE_UNKNOWN}, }; // see aac_chan_configs in ffmpeg-3.0.2/libavcodec/aacenctab.h -static const uint64_t aac_channel_layouts[] = { - AV_CH_LAYOUT_MONO, +static const uint64_t aac_channel_layouts[] = {AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND, AV_CH_LAYOUT_4POINT0, AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_5POINT1_BACK, AV_CH_LAYOUT_7POINT1_WIDE_BACK, - 0 -}; - + 0}; typedef struct { - TVHAudioCodecProfile; - char *coder; + TVHAudioCodecProfile; + char* coder; } tvh_codec_profile_aac_t; - -static int -tvh_codec_profile_aac_open(tvh_codec_profile_aac_t *self, AVDictionary **opts) -{ - // bit_rate or global_quality - if (self->bit_rate) { - AV_DICT_SET_BIT_RATE(opts, self->bit_rate); - } - else { - AV_DICT_SET_GLOBAL_QUALITY(opts, self->qscale, 1); - } - AV_DICT_SET(opts, "aac_coder", self->coder, 0); - return 0; +static int tvh_codec_profile_aac_open(tvh_codec_profile_aac_t* self, AVDictionary** opts) { + // bit_rate or global_quality + if (self->bit_rate) { + AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + } else { + AV_DICT_SET_GLOBAL_QUALITY(opts, self->qscale, 1); + } + AV_DICT_SET(opts, "aac_coder", self->coder, 0); + return 0; } - -static htsmsg_t * -codec_profile_aac_class_coder_list(void *obj, const char *lang) -{ - static const struct strtab_str tab[] = { - {N_("anmr: ANMR method (Not currently recommended)"), "anmr"}, - {N_("twoloop: Two loop searching method"), "twoloop"}, - {N_("fast: Constant quantizer (Not recommended)"), "fast"} - }; - return strtab2htsmsg_str(tab, 1, lang); +static htsmsg_t* codec_profile_aac_class_coder_list(void* obj, const char* lang) { + static const struct strtab_str tab[] = { + {N_("anmr: ANMR method (Not currently recommended)"), "anmr"}, + {N_("twoloop: Two loop searching method"), "twoloop"}, + {N_("fast: Constant quantizer (Not recommended)"), "fast"}}; + return strtab2htsmsg_str(tab, 1, lang); } - static const codec_profile_class_t codec_profile_aac_class = { - { - .ic_super = (idclass_t *)&codec_profile_audio_class, + {.ic_super = (idclass_t*)&codec_profile_audio_class, .ic_class = "codec_profile_aac", .ic_caption = N_("aac"), - .ic_properties = (const property_t[]){ - { - .type = PT_DBL, - .id = "bit_rate", - .name = N_("Bitrate (kb/s) (0=auto)"), - .desc = N_("Constant bitrate (CBR) mode."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, bit_rate), - .def.d = 0, - }, + .ic_properties = (const property_t[]){{ + .type = PT_DBL, + .id = "bit_rate", + .name = N_("Bitrate (kb/s) (0=auto)"), + .desc = N_("Constant bitrate (CBR) mode."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, bit_rate), + .def.d = 0, + }, { .type = PT_DBL, .id = "qscale", @@ -115,22 +99,16 @@ static const codec_profile_class_t codec_profile_aac_class = { .list = codec_profile_aac_class_coder_list, .def.s = "twoloop", }, - {} - } - }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_aac_open, }; - -static void -tvh_codec_profile_aac_destroy(TVHCodecProfile *_self) -{ - tvh_codec_profile_aac_t *self = (tvh_codec_profile_aac_t *)_self; - tvh_codec_profile_audio_destroy(_self); - free(self->coder); +static void tvh_codec_profile_aac_destroy(TVHCodecProfile* _self) { + tvh_codec_profile_aac_t* self = (tvh_codec_profile_aac_t*)_self; + tvh_codec_profile_audio_destroy(_self); + free(self->coder); } - TVHAudioCodec tvh_codec_aac = { .name = "aac", .size = sizeof(tvh_codec_profile_aac_t), diff --git a/src/transcoding/codec/codecs/flac.c b/src/transcoding/codec/codecs/flac.c index de0ad78a6..376898cc2 100644 --- a/src/transcoding/codec/codecs/flac.c +++ b/src/transcoding/codec/codecs/flac.c @@ -17,15 +17,12 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" - /* flac ====================================================================== */ // see flac_channel_layouts ffmpeg-3.4/libavcodec/flac.c & flacenc.c -static const uint64_t flac_channel_layouts[] = { - AV_CH_LAYOUT_MONO, +static const uint64_t flac_channel_layouts[] = {AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND, AV_CH_LAYOUT_QUAD, @@ -33,57 +30,46 @@ static const uint64_t flac_channel_layouts[] = { AV_CH_LAYOUT_5POINT0_BACK, AV_CH_LAYOUT_5POINT1, AV_CH_LAYOUT_5POINT1_BACK, - 0 -}; - + 0}; typedef struct { - TVHAudioCodecProfile; - int compression_level; + TVHAudioCodecProfile; + int compression_level; } tvh_codec_profile_flac_t; - -static int -tvh_codec_profile_flac_open(tvh_codec_profile_flac_t *self, AVDictionary **opts) -{ - AV_DICT_SET_INT(opts, "compression_level", self->compression_level, 0); - return 0; +static int tvh_codec_profile_flac_open(tvh_codec_profile_flac_t* self, AVDictionary** opts) { + AV_DICT_SET_INT(opts, "compression_level", self->compression_level, 0); + return 0; } static const codec_profile_class_t codec_profile_flac_class = { - { - .ic_super = (idclass_t *)&codec_profile_audio_class, - .ic_class = "codec_profile_flac", - .ic_caption = N_("flac"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "complevel", - .name = N_("Compression level"), - .desc = N_("Compression level (0-12), -1 means ffmpeg default"), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_flac_t, compression_level), - .intextra = INTEXTRA_RANGE(-1, 12, 1), - .def.i = -1, - }, - {} - } - }, + {.ic_super = (idclass_t*)&codec_profile_audio_class, + .ic_class = "codec_profile_flac", + .ic_caption = N_("flac"), + .ic_properties = + (const property_t[]){ + { + .type = PT_INT, + .id = "complevel", + .name = N_("Compression level"), + .desc = N_("Compression level (0-12), -1 means ffmpeg default"), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_flac_t, compression_level), + .intextra = INTEXTRA_RANGE(-1, 12, 1), + .def.i = -1, + }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_flac_open, }; +static int tvh_codec_profile_flac_init(TVHCodecProfile* _self, htsmsg_t* conf) { + tvh_codec_profile_flac_t* self = (tvh_codec_profile_flac_t*)_self; -static int -tvh_codec_profile_flac_init(TVHCodecProfile *_self, htsmsg_t *conf) -{ - tvh_codec_profile_flac_t *self = (tvh_codec_profile_flac_t *)_self; - - self->compression_level = -1; - return tvh_codec_profile_audio_init(_self, conf); + self->compression_level = -1; + return tvh_codec_profile_audio_init(_self, conf); } - TVHAudioCodec tvh_codec_flac = { .name = "flac", .size = sizeof(tvh_codec_profile_flac_t), diff --git a/src/transcoding/codec/codecs/libs/libfdk_aac.c b/src/transcoding/codec/codecs/libs/libfdk_aac.c index 6aeeb43d2..4a48793eb 100644 --- a/src/transcoding/codec/codecs/libs/libfdk_aac.c +++ b/src/transcoding/codec/codecs/libs/libfdk_aac.c @@ -17,69 +17,55 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" - /* libfdk_aac =============================================================== */ typedef struct { - TVHAudioCodecProfile; - int vbr; - int afterburner; - int eld_sbr; - int signaling; + TVHAudioCodecProfile; + int vbr; + int afterburner; + int eld_sbr; + int signaling; } tvh_codec_profile_libfdk_aac_t; - -static int -tvh_codec_profile_libfdk_aac_open(tvh_codec_profile_libfdk_aac_t *self, - AVDictionary **opts) -{ - AV_DICT_SET_FLAGS_GLOBAL_HEADER(opts); - // bit_rate or vbr - if (self->bit_rate) { - AV_DICT_SET_BIT_RATE(opts, self->bit_rate); - } - else { - AV_DICT_SET_INT(opts, "vbr", self->vbr ? self->vbr : 3, 0); - } - AV_DICT_SET_INT(opts, "afterburner", self->afterburner, 0); - AV_DICT_SET_INT(opts, "eld_sbr", self->eld_sbr, 0); - AV_DICT_SET_INT(opts, "signaling", self->signaling, 0); - return 0; +static int tvh_codec_profile_libfdk_aac_open(tvh_codec_profile_libfdk_aac_t* self, + AVDictionary** opts) { + AV_DICT_SET_FLAGS_GLOBAL_HEADER(opts); + // bit_rate or vbr + if (self->bit_rate) { + AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + } else { + AV_DICT_SET_INT(opts, "vbr", self->vbr ? self->vbr : 3, 0); + } + AV_DICT_SET_INT(opts, "afterburner", self->afterburner, 0); + AV_DICT_SET_INT(opts, "eld_sbr", self->eld_sbr, 0); + AV_DICT_SET_INT(opts, "signaling", self->signaling, 0); + return 0; } - -static htsmsg_t * -codec_profile_libfdk_aac_class_signaling_list(void *obj, const char *lang) -{ - static const struct strtab tab[] = { - {N_("default"), -1}, - {N_("implicit: Implicit backwards compatible signaling"), 0}, - {N_("explicit_sbr: Explicit SBR, implicit PS signaling"), 1}, - {N_("explicit_hierarchical: Explicit hierarchical signaling"), 2} - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* codec_profile_libfdk_aac_class_signaling_list(void* obj, const char* lang) { + static const struct strtab tab[] = {{N_("default"), -1}, + {N_("implicit: Implicit backwards compatible signaling"), 0}, + {N_("explicit_sbr: Explicit SBR, implicit PS signaling"), 1}, + {N_("explicit_hierarchical: Explicit hierarchical signaling"), 2}}; + return strtab2htsmsg(tab, 1, lang); } - static const codec_profile_class_t codec_profile_libfdk_aac_class = { - { - .ic_super = (idclass_t *)&codec_profile_audio_class, + {.ic_super = (idclass_t*)&codec_profile_audio_class, .ic_class = "codec_profile_libfdk_aac", .ic_caption = N_("libfdk_aac"), - .ic_properties = (const property_t[]){ - { - .type = PT_DBL, - .id = "bit_rate", - .name = N_("Bitrate (kb/s) (0=auto)"), - .desc = N_("Constant bitrate (CBR) mode."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, bit_rate), - .def.d = 0, - }, + .ic_properties = (const property_t[]){{ + .type = PT_DBL, + .id = "bit_rate", + .name = N_("Bitrate (kb/s) (0=auto)"), + .desc = N_("Constant bitrate (CBR) mode."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, bit_rate), + .def.d = 0, + }, { .type = PT_INT, .id = "vbr", @@ -125,17 +111,14 @@ static const codec_profile_class_t codec_profile_libfdk_aac_class = { .list = codec_profile_libfdk_aac_class_signaling_list, .def.i = -1, }, - {} - } - }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_libfdk_aac_open, }; - TVHAudioCodec tvh_codec_libfdk_aac = { - .name = "libfdk_aac", - .size = sizeof(tvh_codec_profile_libfdk_aac_t), - .idclass = &codec_profile_libfdk_aac_class, - .profile_init = tvh_codec_profile_audio_init, + .name = "libfdk_aac", + .size = sizeof(tvh_codec_profile_libfdk_aac_t), + .idclass = &codec_profile_libfdk_aac_class, + .profile_init = tvh_codec_profile_audio_init, .profile_destroy = tvh_codec_profile_audio_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/libopus.c b/src/transcoding/codec/codecs/libs/libopus.c index 0efdca617..dd9836d45 100644 --- a/src/transcoding/codec/codecs/libs/libopus.c +++ b/src/transcoding/codec/codecs/libs/libopus.c @@ -17,74 +17,57 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" #include - /* libopus ================================================================== */ typedef struct { - TVHAudioCodecProfile; - int vbr; - int application; - int complexity; + TVHAudioCodecProfile; + int vbr; + int application; + int complexity; } tvh_codec_profile_libopus_t; - -static int -tvh_codec_profile_libopus_open(tvh_codec_profile_libopus_t *self, - AVDictionary **opts) -{ - AV_DICT_SET_BIT_RATE(opts, self->bit_rate); - AV_DICT_SET_INT(opts, "vbr", self->vbr, 0); - AV_DICT_SET_INT(opts, "application", self->application, 0); - AV_DICT_SET_INT(opts, "compression_level", self->complexity, 0); - return 0; +static int tvh_codec_profile_libopus_open(tvh_codec_profile_libopus_t* self, AVDictionary** opts) { + AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + AV_DICT_SET_INT(opts, "vbr", self->vbr, 0); + AV_DICT_SET_INT(opts, "application", self->application, 0); + AV_DICT_SET_INT(opts, "compression_level", self->complexity, 0); + return 0; } - -static htsmsg_t * -codec_profile_libopus_class_vbr_list(void *obj, const char *lang) -{ - static const struct strtab tab[] = { - {N_("off: Use constant bit rate"), 0}, - {N_("on: Use variable bit rate"), 1}, - {N_("constrained: Use constrained VBR"), 2} - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* codec_profile_libopus_class_vbr_list(void* obj, const char* lang) { + static const struct strtab tab[] = {{N_("off: Use constant bit rate"), 0}, + {N_("on: Use variable bit rate"), 1}, + {N_("constrained: Use constrained VBR"), 2}}; + return strtab2htsmsg(tab, 1, lang); } - -static htsmsg_t * -codec_profile_libopus_class_application_list(void *obj, const char *lang) -{ - static const struct strtab tab[] = { - {N_("voip: Favor improved speech intelligibility"), OPUS_APPLICATION_VOIP}, - {N_("audio: Favor faithfulness to the input"), OPUS_APPLICATION_AUDIO}, - {N_("lowdelay: Restrict to only the lowest delay modes"), OPUS_APPLICATION_RESTRICTED_LOWDELAY} - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* codec_profile_libopus_class_application_list(void* obj, const char* lang) { + static const struct strtab tab[] = { + {N_("voip: Favor improved speech intelligibility"), OPUS_APPLICATION_VOIP}, + {N_("audio: Favor faithfulness to the input"), OPUS_APPLICATION_AUDIO}, + {N_("lowdelay: Restrict to only the lowest delay modes"), + OPUS_APPLICATION_RESTRICTED_LOWDELAY}}; + return strtab2htsmsg(tab, 1, lang); } - static const codec_profile_class_t codec_profile_libopus_class = { - { - .ic_super = (idclass_t *)&codec_profile_audio_class, + {.ic_super = (idclass_t*)&codec_profile_audio_class, .ic_class = "codec_profile_libopus", .ic_caption = N_("libopus"), - .ic_properties = (const property_t[]){ - { - .type = PT_DBL, - .id = "bit_rate", - .name = N_("Bitrate (kb/s) (0=auto)"), - .desc = N_("Constant bitrate (CBR) mode."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, bit_rate), - .def.d = 0, - }, + .ic_properties = (const property_t[]){{ + .type = PT_DBL, + .id = "bit_rate", + .name = N_("Bitrate (kb/s) (0=auto)"), + .desc = N_("Constant bitrate (CBR) mode."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, bit_rate), + .def.d = 0, + }, { .type = PT_INT, .id = "vbr", @@ -122,17 +105,14 @@ static const codec_profile_class_t codec_profile_libopus_class = { .intextra = INTEXTRA_RANGE(0, 10, 1), .def.i = 10, }, - {} - } - }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_libopus_open, }; - TVHAudioCodec tvh_codec_libopus = { - .name = "libopus", - .size = sizeof(tvh_codec_profile_libopus_t), - .idclass = &codec_profile_libopus_class, - .profile_init = tvh_codec_profile_audio_init, + .name = "libopus", + .size = sizeof(tvh_codec_profile_libopus_t), + .idclass = &codec_profile_libopus_class, + .profile_init = tvh_codec_profile_audio_init, .profile_destroy = tvh_codec_profile_audio_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/libtheora.c b/src/transcoding/codec/codecs/libs/libtheora.c index cc64ed0af..3453745a9 100644 --- a/src/transcoding/codec/codecs/libs/libtheora.c +++ b/src/transcoding/codec/codecs/libs/libtheora.c @@ -17,42 +17,34 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" - /* libtheora ================================================================ */ -static int -tvh_codec_profile_libtheora_open(TVHCodecProfile *self, AVDictionary **opts) -{ - // bit_rate or global_quality - if (self->bit_rate) { - AV_DICT_SET_BIT_RATE(opts, self->bit_rate); - } - else { - AV_DICT_SET_GLOBAL_QUALITY(opts, self->qscale, 6); - } - return 0; +static int tvh_codec_profile_libtheora_open(TVHCodecProfile* self, AVDictionary** opts) { + // bit_rate or global_quality + if (self->bit_rate) { + AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + } else { + AV_DICT_SET_GLOBAL_QUALITY(opts, self->qscale, 6); + } + return 0; } - static const codec_profile_class_t codec_profile_libtheora_class = { - { - .ic_super = (idclass_t *)&codec_profile_video_class, + {.ic_super = (idclass_t*)&codec_profile_video_class, .ic_class = "codec_profile_libtheora", .ic_caption = N_("libtheora"), - .ic_properties = (const property_t[]){ - { - .type = PT_DBL, - .id = "bit_rate", - .name = N_("Bitrate (kb/s) (0=auto)"), - .desc = N_("Constant bitrate (CBR) mode."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, bit_rate), - .def.d = 0, - }, + .ic_properties = (const property_t[]){{ + .type = PT_DBL, + .id = "bit_rate", + .name = N_("Bitrate (kb/s) (0=auto)"), + .desc = N_("Constant bitrate (CBR) mode."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, bit_rate), + .def.d = 0, + }, { .type = PT_DBL, .id = "qscale", @@ -64,17 +56,14 @@ static const codec_profile_class_t codec_profile_libtheora_class = { .intextra = INTEXTRA_RANGE(0, 10, 1), .def.d = 0, }, - {} - } - }, + {}}}, .open = tvh_codec_profile_libtheora_open, }; - TVHVideoCodec tvh_codec_libtheora = { - .name = "libtheora", - .size = sizeof(TVHVideoCodecProfile), - .idclass = &codec_profile_libtheora_class, - .profile_init = tvh_codec_profile_video_init, + .name = "libtheora", + .size = sizeof(TVHVideoCodecProfile), + .idclass = &codec_profile_libtheora_class, + .profile_init = tvh_codec_profile_video_init, .profile_destroy = tvh_codec_profile_video_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/libvorbis.c b/src/transcoding/codec/codecs/libs/libvorbis.c index 230f52009..a8f619d52 100644 --- a/src/transcoding/codec/codecs/libs/libvorbis.c +++ b/src/transcoding/codec/codecs/libs/libvorbis.c @@ -17,15 +17,12 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" - /* libvorbis ================================================================ */ // see libvorbis_setup() in ffmpeg-3.0.2/libavcodec/libvorbisenc.c -static const uint64_t libvorbis_channel_layouts[] = { - AV_CH_LAYOUT_MONO, +static const uint64_t libvorbis_channel_layouts[] = {AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_SURROUND, AV_CH_LAYOUT_2_2, @@ -36,42 +33,34 @@ static const uint64_t libvorbis_channel_layouts[] = { AV_CH_LAYOUT_5POINT1_BACK, AV_CH_LAYOUT_6POINT1, AV_CH_LAYOUT_7POINT1, - //AV_CH_LAYOUT_HEXADECAGONAL, - //AV_CH_LAYOUT_STEREO_DOWNMIX, - 0 -}; + // AV_CH_LAYOUT_HEXADECAGONAL, + // AV_CH_LAYOUT_STEREO_DOWNMIX, + 0}; - -static int -tvh_codec_profile_libvorbis_open(TVHCodecProfile *self, AVDictionary **opts) -{ - // bit_rate or global_quality - if (self->bit_rate) { - AV_DICT_SET_BIT_RATE(opts, self->bit_rate); - } - else { - AV_DICT_SET_GLOBAL_QUALITY(opts, self->qscale, 5); - } - return 0; +static int tvh_codec_profile_libvorbis_open(TVHCodecProfile* self, AVDictionary** opts) { + // bit_rate or global_quality + if (self->bit_rate) { + AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + } else { + AV_DICT_SET_GLOBAL_QUALITY(opts, self->qscale, 5); + } + return 0; } - static const codec_profile_class_t codec_profile_libvorbis_class = { - { - .ic_super = (idclass_t *)&codec_profile_audio_class, + {.ic_super = (idclass_t*)&codec_profile_audio_class, .ic_class = "codec_profile_libvorbis", .ic_caption = N_("libvorbis"), - .ic_properties = (const property_t[]){ - { - .type = PT_DBL, - .id = "bit_rate", - .name = N_("Bitrate (kb/s) (0=auto)"), - .desc = N_("Average bitrate (ABR) mode."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, bit_rate), - .def.d = 0, - }, + .ic_properties = (const property_t[]){{ + .type = PT_DBL, + .id = "bit_rate", + .name = N_("Bitrate (kb/s) (0=auto)"), + .desc = N_("Average bitrate (ABR) mode."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, bit_rate), + .def.d = 0, + }, { .type = PT_DBL, .id = "qscale", @@ -83,13 +72,10 @@ static const codec_profile_class_t codec_profile_libvorbis_class = { .intextra = INTEXTRA_RANGE(0, 10, 1), .def.d = 0, }, - {} - } - }, + {}}}, .open = tvh_codec_profile_libvorbis_open, }; - TVHAudioCodec tvh_codec_libvorbis = { .name = "libvorbis", .size = sizeof(TVHAudioCodecProfile), diff --git a/src/transcoding/codec/codecs/libs/libvpx.c b/src/transcoding/codec/codecs/libs/libvpx.c index ee9445f3c..849004dd7 100644 --- a/src/transcoding/codec/codecs/libs/libvpx.c +++ b/src/transcoding/codec/codecs/libs/libvpx.c @@ -17,78 +17,58 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" #include - /* libvpx =================================================================== */ typedef struct { - TVHVideoCodecProfile; - int deadline; - int cpu_used; - int tune; + TVHVideoCodecProfile; + int deadline; + int cpu_used; + int tune; } tvh_codec_profile_libvpx_t; - -static int -tvh_codec_profile_libvpx_open(tvh_codec_profile_libvpx_t *self, - AVDictionary **opts) -{ - AV_DICT_SET_TVH_REQUIRE_META(opts, 0); - AV_DICT_SET_BIT_RATE(opts, self->bit_rate ? self->bit_rate : 2560); - if (self->crf) { - AV_DICT_SET_CRF(opts, self->crf, 10); - } - AV_DICT_SET_INT(opts, "deadline", self->deadline, 0); - AV_DICT_SET_INT(opts, "cpu-used", self->cpu_used, 0); - AV_DICT_SET_INT(opts, "tune", self->tune, 0); - AV_DICT_SET_INT(opts, "threads", 0, 0); - return 0; +static int tvh_codec_profile_libvpx_open(tvh_codec_profile_libvpx_t* self, AVDictionary** opts) { + AV_DICT_SET_TVH_REQUIRE_META(opts, 0); + AV_DICT_SET_BIT_RATE(opts, self->bit_rate ? self->bit_rate : 2560); + if (self->crf) { + AV_DICT_SET_CRF(opts, self->crf, 10); + } + AV_DICT_SET_INT(opts, "deadline", self->deadline, 0); + AV_DICT_SET_INT(opts, "cpu-used", self->cpu_used, 0); + AV_DICT_SET_INT(opts, "tune", self->tune, 0); + AV_DICT_SET_INT(opts, "threads", 0, 0); + return 0; } - -static htsmsg_t * -codec_profile_libvpx_class_deadline_list(void *obj, const char *lang) -{ - static const struct strtab tab[] = { - {N_("best"), VPX_DL_BEST_QUALITY}, - {N_("good"), VPX_DL_GOOD_QUALITY}, - {N_("realtime"), VPX_DL_REALTIME} - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* codec_profile_libvpx_class_deadline_list(void* obj, const char* lang) { + static const struct strtab tab[] = {{N_("best"), VPX_DL_BEST_QUALITY}, + {N_("good"), VPX_DL_GOOD_QUALITY}, + {N_("realtime"), VPX_DL_REALTIME}}; + return strtab2htsmsg(tab, 1, lang); } - -static htsmsg_t * -codec_profile_libvpx_class_tune_list(void *obj, const char *lang) -{ - static const struct strtab tab[] = { - {N_("psnr"), VP8_TUNE_PSNR}, - {N_("ssim"), VP8_TUNE_SSIM} - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* codec_profile_libvpx_class_tune_list(void* obj, const char* lang) { + static const struct strtab tab[] = {{N_("psnr"), VP8_TUNE_PSNR}, {N_("ssim"), VP8_TUNE_SSIM}}; + return strtab2htsmsg(tab, 1, lang); } - static const codec_profile_class_t codec_profile_libvpx_class = { - { - .ic_super = (idclass_t *)&codec_profile_video_class, + {.ic_super = (idclass_t*)&codec_profile_video_class, .ic_class = "codec_profile_libvpx", .ic_caption = N_("libvpx"), - .ic_properties = (const property_t[]){ - { - .type = PT_DBL, - .id = "bit_rate", - .name = N_("Bitrate (kb/s) (0=auto)"), - .desc = N_("Constant bitrate (CBR) mode."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, bit_rate), - .def.d = 0, - }, + .ic_properties = (const property_t[]){{ + .type = PT_DBL, + .id = "bit_rate", + .name = N_("Bitrate (kb/s) (0=auto)"), + .desc = N_("Constant bitrate (CBR) mode."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, bit_rate), + .def.d = 0, + }, { .type = PT_INT, .id = "crf", @@ -136,30 +116,26 @@ static const codec_profile_class_t codec_profile_libvpx_class = { .list = codec_profile_libvpx_class_tune_list, .def.i = VP8_TUNE_PSNR, }, - {} - } - }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_libvpx_open, }; - /* libvpx_vp8 =============================================================== */ TVHVideoCodec tvh_codec_libvpx_vp8 = { - .name = "libvpx", - .size = sizeof(tvh_codec_profile_libvpx_t), - .idclass = &codec_profile_libvpx_class, - .profile_init = tvh_codec_profile_video_init, + .name = "libvpx", + .size = sizeof(tvh_codec_profile_libvpx_t), + .idclass = &codec_profile_libvpx_class, + .profile_init = tvh_codec_profile_video_init, .profile_destroy = tvh_codec_profile_video_destroy, }; - /* libvpx_vp9 =============================================================== */ TVHVideoCodec tvh_codec_libvpx_vp9 = { - .name = "libvpx-vp9", - .size = sizeof(tvh_codec_profile_libvpx_t), - .idclass = &codec_profile_libvpx_class, - .profile_init = tvh_codec_profile_video_init, + .name = "libvpx-vp9", + .size = sizeof(tvh_codec_profile_libvpx_t), + .idclass = &codec_profile_libvpx_class, + .profile_init = tvh_codec_profile_video_init, .profile_destroy = tvh_codec_profile_video_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/libx26x.c b/src/transcoding/codec/codecs/libs/libx26x.c index 088b11e70..9ef72157f 100644 --- a/src/transcoding/codec/codecs/libs/libx26x.c +++ b/src/transcoding/codec/codecs/libs/libx26x.c @@ -17,69 +17,57 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" - /* utils ==================================================================== */ -static htsmsg_t * -strlist2htsmsg(const char * const *values) -{ - htsmsg_t *list = NULL, *map = NULL; - int i; - const char *value = NULL; - - if ((list = htsmsg_create_list())) { - for (i = 0; (value = values[i]); i++) { - if (!(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - break; - } - ADD_STR_VAL(list, map, value); - } +static htsmsg_t* strlist2htsmsg(const char* const* values) { + htsmsg_t * list = NULL, *map = NULL; + int i; + const char* value = NULL; + + if ((list = htsmsg_create_list())) { + for (i = 0; (value = values[i]); i++) { + if (!(map = htsmsg_create_map())) { + htsmsg_destroy(list); + list = NULL; + break; + } + ADD_STR_VAL(list, map, value); } - return list; + } + return list; } - /* libx26x ================================================================== */ typedef struct { - TVHVideoCodecProfile; - char *preset; - char *tune; - char *params; + TVHVideoCodecProfile; + char* preset; + char* tune; + char* params; } tvh_codec_profile_libx26x_t; - -static int -tvh_codec_profile_libx26x_open(tvh_codec_profile_libx26x_t *self, - AVDictionary **opts) -{ - AV_DICT_SET(opts, "preset", self->preset, 0); - AV_DICT_SET(opts, "tune", self->tune, 0); - return 0; +static int tvh_codec_profile_libx26x_open(tvh_codec_profile_libx26x_t* self, AVDictionary** opts) { + AV_DICT_SET(opts, "preset", self->preset, 0); + AV_DICT_SET(opts, "tune", self->tune, 0); + return 0; } - static const codec_profile_class_t codec_profile_libx26x_class = { - { - .ic_super = (idclass_t *)&codec_profile_video_class, + {.ic_super = (idclass_t*)&codec_profile_video_class, .ic_class = "codec_profile_libx26x", .ic_caption = N_("libx26x"), - .ic_properties = (const property_t[]){ - { - .type = PT_DBL, - .id = "bit_rate", - .name = N_("Bitrate (kb/s) (0=auto)"), - .desc = N_("Average bitrate (ABR) mode."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, bit_rate), - .def.d = 0, - }, + .ic_properties = (const property_t[]){{ + .type = PT_DBL, + .id = "bit_rate", + .name = N_("Bitrate (kb/s) (0=auto)"), + .desc = N_("Average bitrate (ABR) mode."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, bit_rate), + .def.d = 0, + }, { .type = PT_INT, .id = "crf", @@ -91,24 +79,18 @@ static const codec_profile_class_t codec_profile_libx26x_class = { .intextra = INTEXTRA_RANGE(0, 51, 1), .def.i = 0, }, - {} - } - }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_libx26x_open, }; - -static void -tvh_codec_profile_libx265_destroy(TVHCodecProfile *_self) -{ - tvh_codec_profile_libx26x_t *self = (tvh_codec_profile_libx26x_t *)_self; - tvh_codec_profile_video_destroy(_self); - free(self->preset); - free(self->tune); - free(self->params); +static void tvh_codec_profile_libx265_destroy(TVHCodecProfile* _self) { + tvh_codec_profile_libx26x_t* self = (tvh_codec_profile_libx26x_t*)_self; + tvh_codec_profile_video_destroy(_self); + free(self->preset); + free(self->tune); + free(self->params); } - /* libx264 ================================================================== */ #if ENABLE_LIBX264 @@ -116,201 +98,168 @@ tvh_codec_profile_libx265_destroy(TVHCodecProfile *_self) #include static const AVProfile libx264_profiles[] = { - { FF_PROFILE_H264_BASELINE, "Baseline" }, - { FF_PROFILE_H264_MAIN, "Main" }, - { FF_PROFILE_H264_HIGH, "High" }, - { FF_PROFILE_H264_HIGH_10, "High 10" }, - { FF_PROFILE_H264_HIGH_422, "High 4:2:2" }, - { FF_PROFILE_H264_HIGH_444, "High 4:4:4" }, - { FF_PROFILE_UNKNOWN }, + {FF_PROFILE_H264_BASELINE, "Baseline"}, + {FF_PROFILE_H264_MAIN, "Main"}, + {FF_PROFILE_H264_HIGH, "High"}, + {FF_PROFILE_H264_HIGH_10, "High 10"}, + {FF_PROFILE_H264_HIGH_422, "High 4:2:2"}, + {FF_PROFILE_H264_HIGH_444, "High 4:4:4"}, + {FF_PROFILE_UNKNOWN}, }; - -static int -tvh_codec_profile_libx264_open(tvh_codec_profile_libx26x_t *self, - AVDictionary **opts) -{ - // bit_rate or crf - if (self->bit_rate) { - AV_DICT_SET_BIT_RATE(opts, self->bit_rate); - } - else { - AV_DICT_SET_CRF(opts, self->crf, 15); - } - // params - if (self->params && strlen(self->params)) { - AV_DICT_SET(opts, "x264-params", self->params, 0); - } - return 0; +static int tvh_codec_profile_libx264_open(tvh_codec_profile_libx26x_t* self, AVDictionary** opts) { + // bit_rate or crf + if (self->bit_rate) { + AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + } else { + AV_DICT_SET_CRF(opts, self->crf, 15); + } + // params + if (self->params && strlen(self->params)) { + AV_DICT_SET(opts, "x264-params", self->params, 0); + } + return 0; } - -static htsmsg_t * -codec_profile_libx264_class_preset_list(void *obj, const char *lang) -{ - return strlist2htsmsg(x264_preset_names); +static htsmsg_t* codec_profile_libx264_class_preset_list(void* obj, const char* lang) { + return strlist2htsmsg(x264_preset_names); } - -static htsmsg_t * -codec_profile_libx264_class_tune_list(void *obj, const char *lang) -{ - return strlist2htsmsg(x264_tune_names); +static htsmsg_t* codec_profile_libx264_class_tune_list(void* obj, const char* lang) { + return strlist2htsmsg(x264_tune_names); } - static const codec_profile_class_t codec_profile_libx264_class = { - { - .ic_super = (idclass_t *)&codec_profile_libx26x_class, - .ic_class = "codec_profile_libx264", - .ic_caption = N_("libx264"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "preset", - .name = N_("Preset"), - .desc = N_("Set the encoding preset (cf. x264 --fullhelp)."), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_libx26x_t, preset), - .list = codec_profile_libx264_class_preset_list, - .def.s = "faster", - }, - { - .type = PT_STR, - .id = "tune", - .name = N_("Tune"), - .desc = N_("Tune the encoding params (cf. x264 --fullhelp)."), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_libx26x_t, tune), - .list = codec_profile_libx264_class_tune_list, - .def.s = "zerolatency", - }, - { - .type = PT_STR, - .id = "params", - .name = N_("Parameters"), - .desc = N_("Override the configuration using a ':' separated " - "list of key=value parameters."), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_libx26x_t, params), - }, - {} - } - }, + {.ic_super = (idclass_t*)&codec_profile_libx26x_class, + .ic_class = "codec_profile_libx264", + .ic_caption = N_("libx264"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "preset", + .name = N_("Preset"), + .desc = N_("Set the encoding preset (cf. x264 --fullhelp)."), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_libx26x_t, preset), + .list = codec_profile_libx264_class_preset_list, + .def.s = "faster", + }, + { + .type = PT_STR, + .id = "tune", + .name = N_("Tune"), + .desc = N_("Tune the encoding params (cf. x264 --fullhelp)."), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_libx26x_t, tune), + .list = codec_profile_libx264_class_tune_list, + .def.s = "zerolatency", + }, + { + .type = PT_STR, + .id = "params", + .name = N_("Parameters"), + .desc = N_("Override the configuration using a ':' separated " + "list of key=value parameters."), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_libx26x_t, params), + }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_libx264_open, }; - TVHVideoCodec tvh_codec_libx264 = { - .name = "libx264", - .size = sizeof(tvh_codec_profile_libx26x_t), - .idclass = &codec_profile_libx264_class, - .profiles = libx264_profiles, + .name = "libx264", + .size = sizeof(tvh_codec_profile_libx26x_t), + .idclass = &codec_profile_libx264_class, + .profiles = libx264_profiles, .profile_destroy = tvh_codec_profile_libx265_destroy, }; #endif - /* libx265 ================================================================== */ #if ENABLE_LIBX265 #include - -static int -tvh_codec_profile_libx265_open(tvh_codec_profile_libx26x_t *self, - AVDictionary **opts) -{ - // bit_rate or crf - if (self->bit_rate) { - AV_DICT_SET_BIT_RATE(opts, self->bit_rate); - } - else { - AV_DICT_SET_CRF(opts, self->crf, 18); - } - // params - if (self->params && strlen(self->params)) { - AV_DICT_SET(opts, "x265-params", self->params, 0); - } - return 0; +static int tvh_codec_profile_libx265_open(tvh_codec_profile_libx26x_t* self, AVDictionary** opts) { + // bit_rate or crf + if (self->bit_rate) { + AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + } else { + AV_DICT_SET_CRF(opts, self->crf, 18); + } + // params + if (self->params && strlen(self->params)) { + AV_DICT_SET(opts, "x265-params", self->params, 0); + } + return 0; } - -static htsmsg_t * -codec_profile_libx265_class_preset_list(void *obj, const char *lang) -{ - return strlist2htsmsg(x265_preset_names); +static htsmsg_t* codec_profile_libx265_class_preset_list(void* obj, const char* lang) { + return strlist2htsmsg(x265_preset_names); } - -static htsmsg_t * -codec_profile_libx265_class_tune_list(void *obj, const char *lang) -{ - return strlist2htsmsg(x265_tune_names); +static htsmsg_t* codec_profile_libx265_class_tune_list(void* obj, const char* lang) { + return strlist2htsmsg(x265_tune_names); } - static const codec_profile_class_t codec_profile_libx265_class = { - { - .ic_super = (idclass_t *)&codec_profile_libx26x_class, - .ic_class = "codec_profile_libx265", - .ic_caption = N_("libx265"), - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "preset", - .name = N_("Preset"), - .desc = N_("set the x265 preset."), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_libx26x_t, preset), - .list = codec_profile_libx265_class_preset_list, - .def.s = "superfast", - }, - { - .type = PT_STR, - .id = "tune", - .name = N_("Tune"), - .desc = N_("set the x265 tune parameter."), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_libx26x_t, tune), - .list = codec_profile_libx265_class_tune_list, - .def.s = "fastdecode", - }, - { - .type = PT_STR, - .id = "params", - .name = N_("Parameters"), - .desc = N_("Override the configuration using a ':' separated " - "list of key=value parameters."), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_libx26x_t, params), - }, - {} - } - }, + {.ic_super = (idclass_t*)&codec_profile_libx26x_class, + .ic_class = "codec_profile_libx265", + .ic_caption = N_("libx265"), + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "preset", + .name = N_("Preset"), + .desc = N_("set the x265 preset."), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_libx26x_t, preset), + .list = codec_profile_libx265_class_preset_list, + .def.s = "superfast", + }, + { + .type = PT_STR, + .id = "tune", + .name = N_("Tune"), + .desc = N_("set the x265 tune parameter."), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_libx26x_t, tune), + .list = codec_profile_libx265_class_tune_list, + .def.s = "fastdecode", + }, + { + .type = PT_STR, + .id = "params", + .name = N_("Parameters"), + .desc = N_("Override the configuration using a ':' separated " + "list of key=value parameters."), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_libx26x_t, params), + }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_libx265_open, }; - TVHVideoCodec tvh_codec_libx265 = { - .name = "libx265", - .size = sizeof(tvh_codec_profile_libx26x_t), - .idclass = &codec_profile_libx265_class, - .profile_init = tvh_codec_profile_video_init, + .name = "libx265", + .size = sizeof(tvh_codec_profile_libx26x_t), + .idclass = &codec_profile_libx265_class, + .profile_init = tvh_codec_profile_video_init, .profile_destroy = tvh_codec_profile_libx265_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/nvenc.c b/src/transcoding/codec/codecs/libs/nvenc.c index 6defe7077..9271cdc4c 100644 --- a/src/transcoding/codec/codecs/libs/nvenc.c +++ b/src/transcoding/codec/codecs/libs/nvenc.c @@ -17,381 +17,351 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" #include #include -#define PRESET_DEFAULT 0 -#define PRESET_SLOW 1 -#define PRESET_MEDIUM 2 -#define PRESET_FAST 3 -#define PRESET_HP 4 -#define PRESET_HQ 5 -#define PRESET_BD 6 -#define PRESET_LOW_LATENCY_DEFAULT 7 -#define PRESET_LOW_LATENCY_HQ 8 -#define PRESET_LOW_LATENCY_HP 9 -#define PRESET_LOSSLESS_DEFAULT 10 -#define PRESET_LOSSLESS_HP 11 - -#define NV_ENC_PARAMS_RC_AUTO 0 -#define NV_ENC_PARAMS_RC_CONSTQP 1 -#define NV_ENC_PARAMS_RC_VBR 2 -#define NV_ENC_PARAMS_RC_CBR 3 -#define NV_ENC_PARAMS_RC_CBR_LD_HQ 8 -#define NV_ENC_PARAMS_RC_CBR_HQ 16 -#define NV_ENC_PARAMS_RC_VBR_HQ 32 - -#define NV_ENC_H264_PROFILE_BASELINE 0 -#define NV_ENC_H264_PROFILE_MAIN 1 -#define NV_ENC_H264_PROFILE_HIGH 2 -#define NV_ENC_H264_PROFILE_HIGH_444P 3 - -#define NV_ENC_HEVC_PROFILE_MAIN 0 -#define NV_ENC_HEVC_PROFILE_MAIN_10 1 -#define NV_ENC_HEVC_PROFILE_REXT 2 - -#define NV_ENC_PROFILE_UNKNOWN FF_PROFILE_UNKNOWN - -#define NV_ENC_LEVEL_AUTOSELECT 0 - -#define NV_ENC_LEVEL_H264_1 10 -#define NV_ENC_LEVEL_H264_1b 9 -#define NV_ENC_LEVEL_H264_11 11 -#define NV_ENC_LEVEL_H264_12 12 -#define NV_ENC_LEVEL_H264_13 13 -#define NV_ENC_LEVEL_H264_2 20 -#define NV_ENC_LEVEL_H264_21 21 -#define NV_ENC_LEVEL_H264_22 22 -#define NV_ENC_LEVEL_H264_3 30 -#define NV_ENC_LEVEL_H264_31 31 -#define NV_ENC_LEVEL_H264_32 32 -#define NV_ENC_LEVEL_H264_4 40 -#define NV_ENC_LEVEL_H264_41 41 -#define NV_ENC_LEVEL_H264_42 42 -#define NV_ENC_LEVEL_H264_5 50 -#define NV_ENC_LEVEL_H264_51 51 -#define NV_ENC_LEVEL_H264_6 60 -#define NV_ENC_LEVEL_H264_61 61 -#define NV_ENC_LEVEL_H264_62 62 - -#define NV_ENC_LEVEL_HEVC_1 30 -#define NV_ENC_LEVEL_HEVC_2 60 -#define NV_ENC_LEVEL_HEVC_21 63 -#define NV_ENC_LEVEL_HEVC_3 90 -#define NV_ENC_LEVEL_HEVC_31 93 -#define NV_ENC_LEVEL_HEVC_4 120 -#define NV_ENC_LEVEL_HEVC_41 123 -#define NV_ENC_LEVEL_HEVC_5 150 -#define NV_ENC_LEVEL_HEVC_51 153 -#define NV_ENC_LEVEL_HEVC_52 156 -#define NV_ENC_LEVEL_HEVC_6 180 -#define NV_ENC_LEVEL_HEVC_61 183 -#define NV_ENC_LEVEL_HEVC_62 186 - -#define AV_DICT_SET_CQ(d, v, a) \ - AV_DICT_SET_INT((d), "cq", (v) ? (v) : (a), AV_DICT_DONT_OVERWRITE) - +#define PRESET_DEFAULT 0 +#define PRESET_SLOW 1 +#define PRESET_MEDIUM 2 +#define PRESET_FAST 3 +#define PRESET_HP 4 +#define PRESET_HQ 5 +#define PRESET_BD 6 +#define PRESET_LOW_LATENCY_DEFAULT 7 +#define PRESET_LOW_LATENCY_HQ 8 +#define PRESET_LOW_LATENCY_HP 9 +#define PRESET_LOSSLESS_DEFAULT 10 +#define PRESET_LOSSLESS_HP 11 + +#define NV_ENC_PARAMS_RC_AUTO 0 +#define NV_ENC_PARAMS_RC_CONSTQP 1 +#define NV_ENC_PARAMS_RC_VBR 2 +#define NV_ENC_PARAMS_RC_CBR 3 +#define NV_ENC_PARAMS_RC_CBR_LD_HQ 8 +#define NV_ENC_PARAMS_RC_CBR_HQ 16 +#define NV_ENC_PARAMS_RC_VBR_HQ 32 + +#define NV_ENC_H264_PROFILE_BASELINE 0 +#define NV_ENC_H264_PROFILE_MAIN 1 +#define NV_ENC_H264_PROFILE_HIGH 2 +#define NV_ENC_H264_PROFILE_HIGH_444P 3 + +#define NV_ENC_HEVC_PROFILE_MAIN 0 +#define NV_ENC_HEVC_PROFILE_MAIN_10 1 +#define NV_ENC_HEVC_PROFILE_REXT 2 + +#define NV_ENC_PROFILE_UNKNOWN FF_PROFILE_UNKNOWN + +#define NV_ENC_LEVEL_AUTOSELECT 0 + +#define NV_ENC_LEVEL_H264_1 10 +#define NV_ENC_LEVEL_H264_1b 9 +#define NV_ENC_LEVEL_H264_11 11 +#define NV_ENC_LEVEL_H264_12 12 +#define NV_ENC_LEVEL_H264_13 13 +#define NV_ENC_LEVEL_H264_2 20 +#define NV_ENC_LEVEL_H264_21 21 +#define NV_ENC_LEVEL_H264_22 22 +#define NV_ENC_LEVEL_H264_3 30 +#define NV_ENC_LEVEL_H264_31 31 +#define NV_ENC_LEVEL_H264_32 32 +#define NV_ENC_LEVEL_H264_4 40 +#define NV_ENC_LEVEL_H264_41 41 +#define NV_ENC_LEVEL_H264_42 42 +#define NV_ENC_LEVEL_H264_5 50 +#define NV_ENC_LEVEL_H264_51 51 +#define NV_ENC_LEVEL_H264_6 60 +#define NV_ENC_LEVEL_H264_61 61 +#define NV_ENC_LEVEL_H264_62 62 + +#define NV_ENC_LEVEL_HEVC_1 30 +#define NV_ENC_LEVEL_HEVC_2 60 +#define NV_ENC_LEVEL_HEVC_21 63 +#define NV_ENC_LEVEL_HEVC_3 90 +#define NV_ENC_LEVEL_HEVC_31 93 +#define NV_ENC_LEVEL_HEVC_4 120 +#define NV_ENC_LEVEL_HEVC_41 123 +#define NV_ENC_LEVEL_HEVC_5 150 +#define NV_ENC_LEVEL_HEVC_51 153 +#define NV_ENC_LEVEL_HEVC_52 156 +#define NV_ENC_LEVEL_HEVC_6 180 +#define NV_ENC_LEVEL_HEVC_61 183 +#define NV_ENC_LEVEL_HEVC_62 186 + +#define AV_DICT_SET_CQ(d, v, a) AV_DICT_SET_INT((d), "cq", (v) ? (v) : (a), AV_DICT_DONT_OVERWRITE) /* nvenc ==================================================================== */ typedef struct { - TVHVideoCodecProfile; - int nvenc_profile; - int devicenum; - int preset; - int rc; - int level; - int quality; + TVHVideoCodecProfile; + int nvenc_profile; + int devicenum; + int preset; + int rc; + int level; + int quality; } tvh_codec_profile_nvenc_t; -static int -tvh_codec_profile_nvenc_open(tvh_codec_profile_nvenc_t *self, - AVDictionary **opts) -{ - static const struct strtab presettab[] = { - {"default", PRESET_DEFAULT}, - {"slow", PRESET_SLOW}, - {"medium", PRESET_MEDIUM}, - {"fast", PRESET_FAST}, - {"hp", PRESET_HP}, - {"hq", PRESET_HQ}, - {"bd", PRESET_BD}, - {"ll", PRESET_LOW_LATENCY_DEFAULT}, - {"llhq", PRESET_LOW_LATENCY_HQ}, - {"llhp", PRESET_LOW_LATENCY_HP}, - {"lossless", PRESET_LOSSLESS_DEFAULT}, - {"losslesshp", PRESET_LOSSLESS_HP}, - }; - static const struct strtab rctab[] = { - {"constqp", NV_ENC_PARAMS_RC_CONSTQP}, - {"vbr", NV_ENC_PARAMS_RC_VBR}, - {"cbr", NV_ENC_PARAMS_RC_CBR}, - {"cbr_ld_hq", NV_ENC_PARAMS_RC_CBR_LD_HQ}, - {"cbr_hq", NV_ENC_PARAMS_RC_CBR_HQ}, - {"vbr_hq", NV_ENC_PARAMS_RC_VBR_HQ}, - }; - const char *s; - - AV_DICT_SET_INT(opts, "gpu", MINMAX(self->devicenum, 0, 15), 0); - if (self->preset != PRESET_DEFAULT && - (s = val2str(self->profile, presettab)) != NULL) { - AV_DICT_SET(opts, "preset", s, 0); - } - if (self->rc != NV_ENC_PARAMS_RC_AUTO && - (s = val2str(self->rc, rctab)) != NULL) { - AV_DICT_SET(opts, "rc", s, 0); - } - if (self->bit_rate) { - AV_DICT_SET_BIT_RATE(opts, self->bit_rate); - } - AV_DICT_SET_INT(opts, "quality", self->quality, 0); - return 0; +static int tvh_codec_profile_nvenc_open(tvh_codec_profile_nvenc_t* self, AVDictionary** opts) { + static const struct strtab presettab[] = { + {"default", PRESET_DEFAULT}, + {"slow", PRESET_SLOW}, + {"medium", PRESET_MEDIUM}, + {"fast", PRESET_FAST}, + {"hp", PRESET_HP}, + {"hq", PRESET_HQ}, + {"bd", PRESET_BD}, + {"ll", PRESET_LOW_LATENCY_DEFAULT}, + {"llhq", PRESET_LOW_LATENCY_HQ}, + {"llhp", PRESET_LOW_LATENCY_HP}, + {"lossless", PRESET_LOSSLESS_DEFAULT}, + {"losslesshp", PRESET_LOSSLESS_HP}, + }; + static const struct strtab rctab[] = { + {"constqp", NV_ENC_PARAMS_RC_CONSTQP}, + {"vbr", NV_ENC_PARAMS_RC_VBR}, + {"cbr", NV_ENC_PARAMS_RC_CBR}, + {"cbr_ld_hq", NV_ENC_PARAMS_RC_CBR_LD_HQ}, + {"cbr_hq", NV_ENC_PARAMS_RC_CBR_HQ}, + {"vbr_hq", NV_ENC_PARAMS_RC_VBR_HQ}, + }; + const char* s; + + AV_DICT_SET_INT(opts, "gpu", MINMAX(self->devicenum, 0, 15), 0); + if (self->preset != PRESET_DEFAULT && (s = val2str(self->profile, presettab)) != NULL) { + AV_DICT_SET(opts, "preset", s, 0); + } + if (self->rc != NV_ENC_PARAMS_RC_AUTO && (s = val2str(self->rc, rctab)) != NULL) { + AV_DICT_SET(opts, "rc", s, 0); + } + if (self->bit_rate) { + AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + } + AV_DICT_SET_INT(opts, "quality", self->quality, 0); + return 0; } -static htsmsg_t * -codec_profile_nvenc_class_profile_list(void *obj, const char *lang) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return tvh_codec_get_list(codec, profiles); +static htsmsg_t* codec_profile_nvenc_class_profile_list(void* obj, const char* lang) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return tvh_codec_get_list(codec, profiles); } -static htsmsg_t * -codec_profile_nvenc_class_preset_list(void *obj, const char *lang) -{ - static const struct strtab tab[] = { - {N_("Default"), PRESET_DEFAULT}, - {N_("Slow"), PRESET_SLOW}, - {N_("Medium"), PRESET_MEDIUM}, - {N_("Fast"), PRESET_FAST}, - {N_("HP"), PRESET_HP}, - {N_("HQ"), PRESET_HQ}, - {N_("BD"), PRESET_BD}, - {N_("Low latency"), PRESET_LOW_LATENCY_DEFAULT}, - {N_("Low latency HQ"), PRESET_LOW_LATENCY_HQ}, - {N_("Low latency HP"), PRESET_LOW_LATENCY_HP}, - {N_("Lossless"), PRESET_LOSSLESS_DEFAULT}, - {N_("Lossless HP"), PRESET_LOSSLESS_HP}, - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* codec_profile_nvenc_class_preset_list(void* obj, const char* lang) { + static const struct strtab tab[] = { + {N_("Default"), PRESET_DEFAULT}, + {N_("Slow"), PRESET_SLOW}, + {N_("Medium"), PRESET_MEDIUM}, + {N_("Fast"), PRESET_FAST}, + {N_("HP"), PRESET_HP}, + {N_("HQ"), PRESET_HQ}, + {N_("BD"), PRESET_BD}, + {N_("Low latency"), PRESET_LOW_LATENCY_DEFAULT}, + {N_("Low latency HQ"), PRESET_LOW_LATENCY_HQ}, + {N_("Low latency HP"), PRESET_LOW_LATENCY_HP}, + {N_("Lossless"), PRESET_LOSSLESS_DEFAULT}, + {N_("Lossless HP"), PRESET_LOSSLESS_HP}, + }; + return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -codec_profile_nvenc_class_rc_list(void *obj, const char *lang) -{ - static const struct strtab tab[] = { - {N_("Auto"), NV_ENC_PARAMS_RC_AUTO}, - {N_("Constant QP mode"), NV_ENC_PARAMS_RC_CONSTQP}, - {N_("VBR mode"), NV_ENC_PARAMS_RC_VBR}, - {N_("CBR mode"), NV_ENC_PARAMS_RC_CBR}, - {N_("CBR LD HQ"), NV_ENC_PARAMS_RC_CBR_LD_HQ}, - {N_("CBR High Quality"), NV_ENC_PARAMS_RC_CBR_HQ}, - {N_("VBR High Quality"), NV_ENC_PARAMS_RC_VBR_HQ}, - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* codec_profile_nvenc_class_rc_list(void* obj, const char* lang) { + static const struct strtab tab[] = { + {N_("Auto"), NV_ENC_PARAMS_RC_AUTO}, + {N_("Constant QP mode"), NV_ENC_PARAMS_RC_CONSTQP}, + {N_("VBR mode"), NV_ENC_PARAMS_RC_VBR}, + {N_("CBR mode"), NV_ENC_PARAMS_RC_CBR}, + {N_("CBR LD HQ"), NV_ENC_PARAMS_RC_CBR_LD_HQ}, + {N_("CBR High Quality"), NV_ENC_PARAMS_RC_CBR_HQ}, + {N_("VBR High Quality"), NV_ENC_PARAMS_RC_VBR_HQ}, + }; + return strtab2htsmsg(tab, 1, lang); } static const codec_profile_class_t codec_profile_nvenc_class = { - { - .ic_super = (idclass_t *)&codec_profile_video_class, - .ic_class = "codec_profile_nvenc", - .ic_caption = N_("nvenc"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "devicenum", - .name = N_("GPU number"), - .group = 3, - .desc = N_("GPU number (starts with zero)."), - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_nvenc_t, devicenum), - }, - { - .type = PT_INT, - .id = "profile", - .name = N_("Profile"), - .desc = N_("Profile."), - .group = 4, - .opts = PO_ADVANCED | PO_PHIDDEN, - .get_opts = codec_profile_class_profile_get_opts, - .off = offsetof(tvh_codec_profile_nvenc_t, nvenc_profile), - .list = codec_profile_nvenc_class_profile_list, - .def.i = NV_ENC_PROFILE_UNKNOWN, - }, - { - .type = PT_INT, - .id = "preset", - .name = N_("Preset"), - .group = 3, - .desc = N_("Override the preset rate control."), - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_nvenc_t, preset), - .list = codec_profile_nvenc_class_preset_list, - .def.i = PRESET_DEFAULT, - }, - { - .type = PT_DBL, - .id = "bit_rate", - .name = N_("Bitrate (kb/s) (0=auto)"), - .desc = N_("Target bitrate."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, bit_rate), - .def.d = 0, - }, - { - .type = PT_INT, - .id = "quality", - .name = N_("Quality (0=auto)"), - .desc = N_("Set encode quality (trades off against speed, " - "higher is faster) [0-51]."), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_nvenc_t, quality), - .intextra = INTEXTRA_RANGE(0, 51, 1), - .def.i = 0, - }, - { - .type = PT_INT, - .id = "rc", - .name = N_("Rate control"), - .group = 3, - .desc = N_("Override the preset rate control."), - .opts = PO_EXPERT, - .off = offsetof(tvh_codec_profile_nvenc_t, rc), - .list = codec_profile_nvenc_class_rc_list, - .def.i = NV_ENC_PARAMS_RC_AUTO, - }, - {} - } - }, + {.ic_super = (idclass_t*)&codec_profile_video_class, + .ic_class = "codec_profile_nvenc", + .ic_caption = N_("nvenc"), + .ic_properties = + (const property_t[]){{ + .type = PT_INT, + .id = "devicenum", + .name = N_("GPU number"), + .group = 3, + .desc = N_("GPU number (starts with zero)."), + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_nvenc_t, devicenum), + }, + { + .type = PT_INT, + .id = "profile", + .name = N_("Profile"), + .desc = N_("Profile."), + .group = 4, + .opts = PO_ADVANCED | PO_PHIDDEN, + .get_opts = codec_profile_class_profile_get_opts, + .off = offsetof(tvh_codec_profile_nvenc_t, nvenc_profile), + .list = codec_profile_nvenc_class_profile_list, + .def.i = NV_ENC_PROFILE_UNKNOWN, + }, + { + .type = PT_INT, + .id = "preset", + .name = N_("Preset"), + .group = 3, + .desc = N_("Override the preset rate control."), + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_nvenc_t, preset), + .list = codec_profile_nvenc_class_preset_list, + .def.i = PRESET_DEFAULT, + }, + { + .type = PT_DBL, + .id = "bit_rate", + .name = N_("Bitrate (kb/s) (0=auto)"), + .desc = N_("Target bitrate."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, bit_rate), + .def.d = 0, + }, + { + .type = PT_INT, + .id = "quality", + .name = N_("Quality (0=auto)"), + .desc = N_("Set encode quality (trades off against speed, " + "higher is faster) [0-51]."), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_nvenc_t, quality), + .intextra = INTEXTRA_RANGE(0, 51, 1), + .def.i = 0, + }, + { + .type = PT_INT, + .id = "rc", + .name = N_("Rate control"), + .group = 3, + .desc = N_("Override the preset rate control."), + .opts = PO_EXPERT, + .off = offsetof(tvh_codec_profile_nvenc_t, rc), + .list = codec_profile_nvenc_class_rc_list, + .def.i = NV_ENC_PARAMS_RC_AUTO, + }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_nvenc_open, }; - /* h264_nvenc =============================================================== */ - static const AVProfile nvenc_h264_profiles[] = { - { NV_ENC_H264_PROFILE_BASELINE, "Baseline" }, - { NV_ENC_H264_PROFILE_MAIN, "Main" }, - { NV_ENC_H264_PROFILE_HIGH, "High" }, - { NV_ENC_H264_PROFILE_HIGH_444P, "High 444P" }, - { NV_ENC_PROFILE_UNKNOWN }, + {NV_ENC_H264_PROFILE_BASELINE, "Baseline"}, + {NV_ENC_H264_PROFILE_MAIN, "Main"}, + {NV_ENC_H264_PROFILE_HIGH, "High"}, + {NV_ENC_H264_PROFILE_HIGH_444P, "High 444P"}, + {NV_ENC_PROFILE_UNKNOWN}, }; -static int -tvh_codec_profile_nvenc_h264_open(tvh_codec_profile_nvenc_t *self, - AVDictionary **opts) -{ - static const struct strtab profiletab[] = { - {"baseline", NV_ENC_H264_PROFILE_BASELINE}, - {"main", NV_ENC_H264_PROFILE_MAIN}, - {"high", NV_ENC_H264_PROFILE_HIGH}, - {"high444p", NV_ENC_H264_PROFILE_HIGH_444P}, - }; - - static const struct strtab leveltab[] = { - {"Auto", NV_ENC_LEVEL_AUTOSELECT}, - {"1.0", NV_ENC_LEVEL_H264_1}, - {"1.0b", NV_ENC_LEVEL_H264_1b}, - {"1.1", NV_ENC_LEVEL_H264_11}, - {"1.2", NV_ENC_LEVEL_H264_12}, - {"1.3", NV_ENC_LEVEL_H264_13}, - {"2.0", NV_ENC_LEVEL_H264_2}, - {"2.1", NV_ENC_LEVEL_H264_21}, - {"2.2", NV_ENC_LEVEL_H264_22}, - {"3.0", NV_ENC_LEVEL_H264_3}, - {"3.1", NV_ENC_LEVEL_H264_31}, - {"3.2", NV_ENC_LEVEL_H264_32}, - {"4.0", NV_ENC_LEVEL_H264_4}, - {"4.1", NV_ENC_LEVEL_H264_41}, - {"4.2", NV_ENC_LEVEL_H264_42}, - {"5.0", NV_ENC_LEVEL_H264_5}, - {"5.1", NV_ENC_LEVEL_H264_51}, - {"6.0", NV_ENC_LEVEL_H264_6}, - {"6.1", NV_ENC_LEVEL_H264_61}, - {"6.2", NV_ENC_LEVEL_H264_62}, - }; - - const char *s; - - if (self->level != NV_ENC_LEVEL_AUTOSELECT && - (s = val2str(self->level, leveltab)) != NULL) { - AV_DICT_SET(opts, "level", s, 0); - } - - if (self->nvenc_profile != NV_ENC_PROFILE_UNKNOWN && - (s = val2str(self->nvenc_profile, profiletab)) != NULL) { - AV_DICT_SET(opts, "profile", s, 0); - } - - // ------ Set Defaults --------- - AV_DICT_SET_INT(opts, "qmin", -1, 0); - AV_DICT_SET_INT(opts, "qmax", -1, 0); - AV_DICT_SET_INT(opts, "qdiff", -1, 0); - AV_DICT_SET_INT(opts, "qblur", -1, 0); - AV_DICT_SET_INT(opts, "qcomp", -1, 0); - AV_DICT_SET_INT(opts, "g", 250, 0); - AV_DICT_SET_INT(opts, "bf", 0, 0); - AV_DICT_SET_INT(opts, "refs", 0, 0); - return 0; +static int tvh_codec_profile_nvenc_h264_open(tvh_codec_profile_nvenc_t* self, AVDictionary** opts) { + static const struct strtab profiletab[] = { + {"baseline", NV_ENC_H264_PROFILE_BASELINE}, + {"main", NV_ENC_H264_PROFILE_MAIN}, + {"high", NV_ENC_H264_PROFILE_HIGH}, + {"high444p", NV_ENC_H264_PROFILE_HIGH_444P}, + }; + + static const struct strtab leveltab[] = { + {"Auto", NV_ENC_LEVEL_AUTOSELECT}, + {"1.0", NV_ENC_LEVEL_H264_1}, + {"1.0b", NV_ENC_LEVEL_H264_1b}, + {"1.1", NV_ENC_LEVEL_H264_11}, + {"1.2", NV_ENC_LEVEL_H264_12}, + {"1.3", NV_ENC_LEVEL_H264_13}, + {"2.0", NV_ENC_LEVEL_H264_2}, + {"2.1", NV_ENC_LEVEL_H264_21}, + {"2.2", NV_ENC_LEVEL_H264_22}, + {"3.0", NV_ENC_LEVEL_H264_3}, + {"3.1", NV_ENC_LEVEL_H264_31}, + {"3.2", NV_ENC_LEVEL_H264_32}, + {"4.0", NV_ENC_LEVEL_H264_4}, + {"4.1", NV_ENC_LEVEL_H264_41}, + {"4.2", NV_ENC_LEVEL_H264_42}, + {"5.0", NV_ENC_LEVEL_H264_5}, + {"5.1", NV_ENC_LEVEL_H264_51}, + {"6.0", NV_ENC_LEVEL_H264_6}, + {"6.1", NV_ENC_LEVEL_H264_61}, + {"6.2", NV_ENC_LEVEL_H264_62}, + }; + + const char* s; + + if (self->level != NV_ENC_LEVEL_AUTOSELECT && (s = val2str(self->level, leveltab)) != NULL) { + AV_DICT_SET(opts, "level", s, 0); + } + + if (self->nvenc_profile != NV_ENC_PROFILE_UNKNOWN && + (s = val2str(self->nvenc_profile, profiletab)) != NULL) { + AV_DICT_SET(opts, "profile", s, 0); + } + + // ------ Set Defaults --------- + AV_DICT_SET_INT(opts, "qmin", -1, 0); + AV_DICT_SET_INT(opts, "qmax", -1, 0); + AV_DICT_SET_INT(opts, "qdiff", -1, 0); + AV_DICT_SET_INT(opts, "qblur", -1, 0); + AV_DICT_SET_INT(opts, "qcomp", -1, 0); + AV_DICT_SET_INT(opts, "g", 250, 0); + AV_DICT_SET_INT(opts, "bf", 0, 0); + AV_DICT_SET_INT(opts, "refs", 0, 0); + return 0; } -static htsmsg_t * -codec_profile_nvenc_class_level_list_h264(void *obj, const char *lang) -{ - static const struct strtab tab[] = { - {N_("Auto"), NV_ENC_LEVEL_AUTOSELECT}, - {N_("1.0"), NV_ENC_LEVEL_H264_1}, - {N_("1.0b"), NV_ENC_LEVEL_H264_1b}, - {N_("1.1"), NV_ENC_LEVEL_H264_11}, - {N_("1.2"), NV_ENC_LEVEL_H264_12}, - {N_("1.3"), NV_ENC_LEVEL_H264_13}, - {N_("2.0"), NV_ENC_LEVEL_H264_2}, - {N_("2.1"), NV_ENC_LEVEL_H264_21}, - {N_("2.2"), NV_ENC_LEVEL_H264_22}, - {N_("3.0"), NV_ENC_LEVEL_H264_3}, - {N_("3.1"), NV_ENC_LEVEL_H264_31}, - {N_("3.2"), NV_ENC_LEVEL_H264_32}, - {N_("4.0"), NV_ENC_LEVEL_H264_4}, - {N_("4.1"), NV_ENC_LEVEL_H264_41}, - {N_("4.2"), NV_ENC_LEVEL_H264_42}, - {N_("5.0"), NV_ENC_LEVEL_H264_5}, - {N_("5.1"), NV_ENC_LEVEL_H264_51}, - {N_("6.0"), NV_ENC_LEVEL_H264_6}, - {N_("6.1"), NV_ENC_LEVEL_H264_61}, - {N_("6.2"), NV_ENC_LEVEL_H264_62}, - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* codec_profile_nvenc_class_level_list_h264(void* obj, const char* lang) { + static const struct strtab tab[] = { + {N_("Auto"), NV_ENC_LEVEL_AUTOSELECT}, + {N_("1.0"), NV_ENC_LEVEL_H264_1}, + {N_("1.0b"), NV_ENC_LEVEL_H264_1b}, + {N_("1.1"), NV_ENC_LEVEL_H264_11}, + {N_("1.2"), NV_ENC_LEVEL_H264_12}, + {N_("1.3"), NV_ENC_LEVEL_H264_13}, + {N_("2.0"), NV_ENC_LEVEL_H264_2}, + {N_("2.1"), NV_ENC_LEVEL_H264_21}, + {N_("2.2"), NV_ENC_LEVEL_H264_22}, + {N_("3.0"), NV_ENC_LEVEL_H264_3}, + {N_("3.1"), NV_ENC_LEVEL_H264_31}, + {N_("3.2"), NV_ENC_LEVEL_H264_32}, + {N_("4.0"), NV_ENC_LEVEL_H264_4}, + {N_("4.1"), NV_ENC_LEVEL_H264_41}, + {N_("4.2"), NV_ENC_LEVEL_H264_42}, + {N_("5.0"), NV_ENC_LEVEL_H264_5}, + {N_("5.1"), NV_ENC_LEVEL_H264_51}, + {N_("6.0"), NV_ENC_LEVEL_H264_6}, + {N_("6.1"), NV_ENC_LEVEL_H264_61}, + {N_("6.2"), NV_ENC_LEVEL_H264_62}, + }; + return strtab2htsmsg(tab, 1, lang); } static const codec_profile_class_t codec_profile_nvenc_h264_class = { - { - .ic_super = (idclass_t *)&codec_profile_nvenc_class, + {.ic_super = (idclass_t*)&codec_profile_nvenc_class, .ic_class = "codec_profile_nvenc_h264", .ic_caption = N_("nvenc_h264"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "level", - .name = N_("Level"), - .group = 4, - .desc = N_("Override the preset level."), - .opts = PO_EXPERT, - .off = offsetof(tvh_codec_profile_nvenc_t, level), - .list = codec_profile_nvenc_class_level_list_h264, - .def.i = NV_ENC_LEVEL_AUTOSELECT, - }, - {} - } - }, + .ic_properties = (const property_t[]){{ + .type = PT_INT, + .id = "level", + .name = N_("Level"), + .group = 4, + .desc = N_("Override the preset level."), + .opts = PO_EXPERT, + .off = offsetof(tvh_codec_profile_nvenc_t, level), + .list = codec_profile_nvenc_class_level_list_h264, + .def.i = NV_ENC_LEVEL_AUTOSELECT, + }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_nvenc_h264_open, }; - TVHVideoCodec tvh_codec_nvenc_h264 = { .name = "h264_nvenc", .size = sizeof(tvh_codec_profile_nvenc_t), @@ -399,117 +369,106 @@ TVHVideoCodec tvh_codec_nvenc_h264 = { .profiles = nvenc_h264_profiles, }; - /* hevc_nvenc =============================================================== */ static const AVProfile nvenc_hevc_profiles[] = { - { NV_ENC_HEVC_PROFILE_MAIN, "Main" }, - { NV_ENC_HEVC_PROFILE_MAIN_10, "Main 10" }, - { NV_ENC_HEVC_PROFILE_REXT, "Rext" }, - { NV_ENC_PROFILE_UNKNOWN }, + {NV_ENC_HEVC_PROFILE_MAIN, "Main"}, + {NV_ENC_HEVC_PROFILE_MAIN_10, "Main 10"}, + {NV_ENC_HEVC_PROFILE_REXT, "Rext"}, + {NV_ENC_PROFILE_UNKNOWN}, }; -static int -tvh_codec_profile_nvenc_hevc_open(tvh_codec_profile_nvenc_t *self, - AVDictionary **opts) -{ - static const struct strtab profiletab[] = { - {"main", NV_ENC_HEVC_PROFILE_MAIN}, - {"main10", NV_ENC_HEVC_PROFILE_MAIN_10}, - {"rext", NV_ENC_HEVC_PROFILE_REXT}, - }; - - static const struct strtab leveltab[] = { - {"Auto", NV_ENC_LEVEL_AUTOSELECT}, - {"1.0", NV_ENC_LEVEL_HEVC_1}, - {"2.0", NV_ENC_LEVEL_HEVC_2}, - {"2.1", NV_ENC_LEVEL_HEVC_21}, - {"3.0", NV_ENC_LEVEL_HEVC_3}, - {"3.1", NV_ENC_LEVEL_HEVC_31}, - {"4.0", NV_ENC_LEVEL_HEVC_4}, - {"4.1", NV_ENC_LEVEL_HEVC_41}, - {"5.0", NV_ENC_LEVEL_HEVC_5}, - {"5.1", NV_ENC_LEVEL_HEVC_51}, - {"5.2", NV_ENC_LEVEL_HEVC_52}, - {"6.0", NV_ENC_LEVEL_HEVC_6}, - {"6.1", NV_ENC_LEVEL_HEVC_61}, - {"6.2", NV_ENC_LEVEL_HEVC_62}, - }; - - const char *s; - - if (self->level != NV_ENC_LEVEL_AUTOSELECT && - (s = val2str(self->level, leveltab)) != NULL) { - AV_DICT_SET(opts, "level", s, 0); - } - - if (self->nvenc_profile != NV_ENC_PROFILE_UNKNOWN && - (s = val2str(self->nvenc_profile, profiletab)) != NULL) { - AV_DICT_SET(opts, "profile", s, 0); - } - - // ------ Set Defaults --------- - AV_DICT_SET_INT(opts, "qmin", -1, 0); - AV_DICT_SET_INT(opts, "qmax", -1, 0); - AV_DICT_SET_INT(opts, "qdiff", -1, 0); - AV_DICT_SET_INT(opts, "qblur", -1, 0); - AV_DICT_SET_INT(opts, "qcomp", -1, 0); - AV_DICT_SET_INT(opts, "g", 250, 0); - AV_DICT_SET_INT(opts, "bf", 0, 0); - AV_DICT_SET_INT(opts, "refs", 0, 0); - return 0; +static int tvh_codec_profile_nvenc_hevc_open(tvh_codec_profile_nvenc_t* self, AVDictionary** opts) { + static const struct strtab profiletab[] = { + {"main", NV_ENC_HEVC_PROFILE_MAIN}, + {"main10", NV_ENC_HEVC_PROFILE_MAIN_10}, + {"rext", NV_ENC_HEVC_PROFILE_REXT}, + }; + + static const struct strtab leveltab[] = { + {"Auto", NV_ENC_LEVEL_AUTOSELECT}, + {"1.0", NV_ENC_LEVEL_HEVC_1}, + {"2.0", NV_ENC_LEVEL_HEVC_2}, + {"2.1", NV_ENC_LEVEL_HEVC_21}, + {"3.0", NV_ENC_LEVEL_HEVC_3}, + {"3.1", NV_ENC_LEVEL_HEVC_31}, + {"4.0", NV_ENC_LEVEL_HEVC_4}, + {"4.1", NV_ENC_LEVEL_HEVC_41}, + {"5.0", NV_ENC_LEVEL_HEVC_5}, + {"5.1", NV_ENC_LEVEL_HEVC_51}, + {"5.2", NV_ENC_LEVEL_HEVC_52}, + {"6.0", NV_ENC_LEVEL_HEVC_6}, + {"6.1", NV_ENC_LEVEL_HEVC_61}, + {"6.2", NV_ENC_LEVEL_HEVC_62}, + }; + + const char* s; + + if (self->level != NV_ENC_LEVEL_AUTOSELECT && (s = val2str(self->level, leveltab)) != NULL) { + AV_DICT_SET(opts, "level", s, 0); + } + + if (self->nvenc_profile != NV_ENC_PROFILE_UNKNOWN && + (s = val2str(self->nvenc_profile, profiletab)) != NULL) { + AV_DICT_SET(opts, "profile", s, 0); + } + + // ------ Set Defaults --------- + AV_DICT_SET_INT(opts, "qmin", -1, 0); + AV_DICT_SET_INT(opts, "qmax", -1, 0); + AV_DICT_SET_INT(opts, "qdiff", -1, 0); + AV_DICT_SET_INT(opts, "qblur", -1, 0); + AV_DICT_SET_INT(opts, "qcomp", -1, 0); + AV_DICT_SET_INT(opts, "g", 250, 0); + AV_DICT_SET_INT(opts, "bf", 0, 0); + AV_DICT_SET_INT(opts, "refs", 0, 0); + return 0; } -static htsmsg_t * -codec_profile_nvenc_class_level_list_hevc(void *obj, const char *lang) -{ - static const struct strtab tab[] = { - {N_("Auto"), NV_ENC_LEVEL_AUTOSELECT}, - {N_("1.0"), NV_ENC_LEVEL_HEVC_1}, - {N_("2.0"), NV_ENC_LEVEL_HEVC_2}, - {N_("2.1"), NV_ENC_LEVEL_HEVC_21}, - {N_("3.0"), NV_ENC_LEVEL_HEVC_3}, - {N_("3.1"), NV_ENC_LEVEL_HEVC_31}, - {N_("4.0"), NV_ENC_LEVEL_HEVC_4}, - {N_("4.1"), NV_ENC_LEVEL_HEVC_41}, - {N_("5.0"), NV_ENC_LEVEL_HEVC_5}, - {N_("5.1"), NV_ENC_LEVEL_HEVC_51}, - {N_("5.2"), NV_ENC_LEVEL_HEVC_52}, - {N_("6.0"), NV_ENC_LEVEL_HEVC_6}, - {N_("6.1"), NV_ENC_LEVEL_HEVC_61}, - {N_("6.2"), NV_ENC_LEVEL_HEVC_62}, - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* codec_profile_nvenc_class_level_list_hevc(void* obj, const char* lang) { + static const struct strtab tab[] = { + {N_("Auto"), NV_ENC_LEVEL_AUTOSELECT}, + {N_("1.0"), NV_ENC_LEVEL_HEVC_1}, + {N_("2.0"), NV_ENC_LEVEL_HEVC_2}, + {N_("2.1"), NV_ENC_LEVEL_HEVC_21}, + {N_("3.0"), NV_ENC_LEVEL_HEVC_3}, + {N_("3.1"), NV_ENC_LEVEL_HEVC_31}, + {N_("4.0"), NV_ENC_LEVEL_HEVC_4}, + {N_("4.1"), NV_ENC_LEVEL_HEVC_41}, + {N_("5.0"), NV_ENC_LEVEL_HEVC_5}, + {N_("5.1"), NV_ENC_LEVEL_HEVC_51}, + {N_("5.2"), NV_ENC_LEVEL_HEVC_52}, + {N_("6.0"), NV_ENC_LEVEL_HEVC_6}, + {N_("6.1"), NV_ENC_LEVEL_HEVC_61}, + {N_("6.2"), NV_ENC_LEVEL_HEVC_62}, + }; + return strtab2htsmsg(tab, 1, lang); } static const codec_profile_class_t codec_profile_nvenc_hevc_class = { - { - .ic_super = (idclass_t *)&codec_profile_nvenc_class, + {.ic_super = (idclass_t*)&codec_profile_nvenc_class, .ic_class = "codec_profile_nvenc_hevc", .ic_caption = N_("nvenc_hevc"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "level", - .name = N_("Level"), - .group = 4, - .desc = N_("Override the preset level."), - .opts = PO_EXPERT, - .off = offsetof(tvh_codec_profile_nvenc_t, level), - .list = codec_profile_nvenc_class_level_list_hevc, - .def.i = NV_ENC_LEVEL_AUTOSELECT, - }, - {} - } - }, + .ic_properties = (const property_t[]){{ + .type = PT_INT, + .id = "level", + .name = N_("Level"), + .group = 4, + .desc = N_("Override the preset level."), + .opts = PO_EXPERT, + .off = offsetof(tvh_codec_profile_nvenc_t, level), + .list = codec_profile_nvenc_class_level_list_hevc, + .def.i = NV_ENC_LEVEL_AUTOSELECT, + }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_nvenc_hevc_open, }; TVHVideoCodec tvh_codec_nvenc_hevc = { - .name = "hevc_nvenc", - .size = sizeof(tvh_codec_profile_nvenc_t), - .idclass = &codec_profile_nvenc_hevc_class, - .profiles = nvenc_hevc_profiles, - .profile_init = tvh_codec_profile_video_init, + .name = "hevc_nvenc", + .size = sizeof(tvh_codec_profile_nvenc_t), + .idclass = &codec_profile_nvenc_hevc_class, + .profiles = nvenc_hevc_profiles, + .profile_init = tvh_codec_profile_video_init, .profile_destroy = tvh_codec_profile_video_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/omx.c b/src/transcoding/codec/codecs/libs/omx.c index 916fcddbb..dfd8af3ae 100644 --- a/src/transcoding/codec/codecs/libs/omx.c +++ b/src/transcoding/codec/codecs/libs/omx.c @@ -17,55 +17,47 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" - /* omx ====================================================================== */ typedef struct { - TVHVideoCodecProfile; - char *libname; - char *libprefix; - int zerocopy; + TVHVideoCodecProfile; + char* libname; + char* libprefix; + int zerocopy; } tvh_codec_profile_omx_t; - -static int -tvh_codec_profile_omx_open(tvh_codec_profile_omx_t *self, AVDictionary **opts) -{ - AV_DICT_SET_FLAGS_GLOBAL_HEADER(opts); - // bit_rate - if (self->bit_rate) { - AV_DICT_SET_BIT_RATE(opts, self->bit_rate); - } - if (self->libname && strlen(self->libname)) { - AV_DICT_SET(opts, "omx_libname", self->libname, 0); - } - if (self->libprefix && strlen(self->libprefix)) { - AV_DICT_SET(opts, "omx_libprefix", self->libprefix, 0); - } - AV_DICT_SET_INT(opts, "zerocopy", self->zerocopy, 0); - return 0; +static int tvh_codec_profile_omx_open(tvh_codec_profile_omx_t* self, AVDictionary** opts) { + AV_DICT_SET_FLAGS_GLOBAL_HEADER(opts); + // bit_rate + if (self->bit_rate) { + AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + } + if (self->libname && strlen(self->libname)) { + AV_DICT_SET(opts, "omx_libname", self->libname, 0); + } + if (self->libprefix && strlen(self->libprefix)) { + AV_DICT_SET(opts, "omx_libprefix", self->libprefix, 0); + } + AV_DICT_SET_INT(opts, "zerocopy", self->zerocopy, 0); + return 0; } - static const codec_profile_class_t codec_profile_omx_class = { - { - .ic_super = (idclass_t *)&codec_profile_video_class, - .ic_class = "codec_profile_omx", - .ic_caption = N_("omx_h264"), - .ic_properties = (const property_t[]){ - { - .type = PT_DBL, - .id = "bit_rate", - .name = N_("Bitrate (kb/s) (0=auto)"), - .desc = N_("Constant bitrate (CBR) mode."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, bit_rate), - .def.d = 0, - }, + {.ic_super = (idclass_t*)&codec_profile_video_class, + .ic_class = "codec_profile_omx", + .ic_caption = N_("omx_h264"), + .ic_properties = (const property_t[]){{ + .type = PT_DBL, + .id = "bit_rate", + .name = N_("Bitrate (kb/s) (0=auto)"), + .desc = N_("Constant bitrate (CBR) mode."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, bit_rate), + .def.d = 0, + }, { .type = PT_STR, .id = "omx_libname", @@ -97,28 +89,23 @@ static const codec_profile_class_t codec_profile_omx_class = { .off = offsetof(tvh_codec_profile_omx_t, zerocopy), .def.i = 0, }, - {} - } - }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_omx_open, }; - /* h264_omx ================================================================= */ -static void -tvh_codec_profile_omx_destroy(TVHCodecProfile *_self) -{ - tvh_codec_profile_omx_t *self = (tvh_codec_profile_omx_t *)_self; - tvh_codec_profile_video_destroy(_self); - free(self->libname); - free(self->libprefix); +static void tvh_codec_profile_omx_destroy(TVHCodecProfile* _self) { + tvh_codec_profile_omx_t* self = (tvh_codec_profile_omx_t*)_self; + tvh_codec_profile_video_destroy(_self); + free(self->libname); + free(self->libprefix); } TVHVideoCodec tvh_codec_omx_h264 = { - .name = "h264_omx", - .size = sizeof(tvh_codec_profile_omx_t), - .idclass = &codec_profile_omx_class, - .profile_init = tvh_codec_profile_video_init, + .name = "h264_omx", + .size = sizeof(tvh_codec_profile_omx_t), + .idclass = &codec_profile_omx_class, + .profile_init = tvh_codec_profile_video_init, .profile_destroy = tvh_codec_profile_omx_destroy, }; diff --git a/src/transcoding/codec/codecs/libs/vaapi.c b/src/transcoding/codec/codecs/libs/vaapi.c index 5cd7ca339..5cbcfcb3e 100644 --- a/src/transcoding/codec/codecs/libs/vaapi.c +++ b/src/transcoding/codec/codecs/libs/vaapi.c @@ -17,7 +17,6 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" #include #include @@ -26,173 +25,163 @@ #include "htsmsg.h" /* defines */ -#define VAAPI_ENC_PLATFORM_UNCONSTRAINED 0 -#define VAAPI_ENC_PLATFORM_INTEL 1 -#define VAAPI_ENC_PLATFORM_AMD 2 +#define VAAPI_ENC_PLATFORM_UNCONSTRAINED 0 +#define VAAPI_ENC_PLATFORM_INTEL 1 +#define VAAPI_ENC_PLATFORM_AMD 2 -#define VAAPI_ENC_PARAMS_RC_SKIP -1 -#define VAAPI_ENC_PARAMS_RC_AUTO 0 -#define VAAPI_ENC_PARAMS_RC_CONSTQP 1 -#define VAAPI_ENC_PARAMS_RC_CBR 2 -#define VAAPI_ENC_PARAMS_RC_VBR 3 -#define VAAPI_ENC_PARAMS_RC_ICQ 4 -#define VAAPI_ENC_PARAMS_RC_QVBR 5 -#define VAAPI_ENC_PARAMS_RC_AVBR 6 +#define VAAPI_ENC_PARAMS_RC_SKIP -1 +#define VAAPI_ENC_PARAMS_RC_AUTO 0 +#define VAAPI_ENC_PARAMS_RC_CONSTQP 1 +#define VAAPI_ENC_PARAMS_RC_CBR 2 +#define VAAPI_ENC_PARAMS_RC_VBR 3 +#define VAAPI_ENC_PARAMS_RC_ICQ 4 +#define VAAPI_ENC_PARAMS_RC_QVBR 5 +#define VAAPI_ENC_PARAMS_RC_AVBR 6 -#define VAAPI_ENC_LEVEL_H264_SKIP -100 -#define VAAPI_ENC_LEVEL_H264_1 10 -#define VAAPI_ENC_LEVEL_H264_11 11 -#define VAAPI_ENC_LEVEL_H264_12 12 -#define VAAPI_ENC_LEVEL_H264_13 13 -#define VAAPI_ENC_LEVEL_H264_2 20 -#define VAAPI_ENC_LEVEL_H264_21 21 -#define VAAPI_ENC_LEVEL_H264_22 22 -#define VAAPI_ENC_LEVEL_H264_3 30 -#define VAAPI_ENC_LEVEL_H264_31 31 -#define VAAPI_ENC_LEVEL_H264_32 32 -#define VAAPI_ENC_LEVEL_H264_4 40 -#define VAAPI_ENC_LEVEL_H264_41 41 -#define VAAPI_ENC_LEVEL_H264_42 42 -#define VAAPI_ENC_LEVEL_H264_5 50 -#define VAAPI_ENC_LEVEL_H264_51 51 -#define VAAPI_ENC_LEVEL_H264_52 52 -#define VAAPI_ENC_LEVEL_H264_6 60 -#define VAAPI_ENC_LEVEL_H264_61 61 -#define VAAPI_ENC_LEVEL_H264_62 62 +#define VAAPI_ENC_LEVEL_H264_SKIP -100 +#define VAAPI_ENC_LEVEL_H264_1 10 +#define VAAPI_ENC_LEVEL_H264_11 11 +#define VAAPI_ENC_LEVEL_H264_12 12 +#define VAAPI_ENC_LEVEL_H264_13 13 +#define VAAPI_ENC_LEVEL_H264_2 20 +#define VAAPI_ENC_LEVEL_H264_21 21 +#define VAAPI_ENC_LEVEL_H264_22 22 +#define VAAPI_ENC_LEVEL_H264_3 30 +#define VAAPI_ENC_LEVEL_H264_31 31 +#define VAAPI_ENC_LEVEL_H264_32 32 +#define VAAPI_ENC_LEVEL_H264_4 40 +#define VAAPI_ENC_LEVEL_H264_41 41 +#define VAAPI_ENC_LEVEL_H264_42 42 +#define VAAPI_ENC_LEVEL_H264_5 50 +#define VAAPI_ENC_LEVEL_H264_51 51 +#define VAAPI_ENC_LEVEL_H264_52 52 +#define VAAPI_ENC_LEVEL_H264_6 60 +#define VAAPI_ENC_LEVEL_H264_61 61 +#define VAAPI_ENC_LEVEL_H264_62 62 -#define VAAPI_ENC_HEVC_TIER_SKIP -1 -#define VAAPI_ENC_HEVC_TIER_MAIN 0 -#define VAAPI_ENC_HEVC_TIER_HIGH 1 +#define VAAPI_ENC_HEVC_TIER_SKIP -1 +#define VAAPI_ENC_HEVC_TIER_MAIN 0 +#define VAAPI_ENC_HEVC_TIER_HIGH 1 -#define VAAPI_ENC_LEVEL_HEVC_SKIP -100 -#define VAAPI_ENC_LEVEL_HEVC_1 30 -#define VAAPI_ENC_LEVEL_HEVC_2 60 -#define VAAPI_ENC_LEVEL_HEVC_21 63 -#define VAAPI_ENC_LEVEL_HEVC_3 90 -#define VAAPI_ENC_LEVEL_HEVC_31 93 -#define VAAPI_ENC_LEVEL_HEVC_4 120 -#define VAAPI_ENC_LEVEL_HEVC_41 123 -#define VAAPI_ENC_LEVEL_HEVC_5 150 -#define VAAPI_ENC_LEVEL_HEVC_51 153 -#define VAAPI_ENC_LEVEL_HEVC_52 156 -#define VAAPI_ENC_LEVEL_HEVC_6 180 -#define VAAPI_ENC_LEVEL_HEVC_61 183 -#define VAAPI_ENC_LEVEL_HEVC_62 186 +#define VAAPI_ENC_LEVEL_HEVC_SKIP -100 +#define VAAPI_ENC_LEVEL_HEVC_1 30 +#define VAAPI_ENC_LEVEL_HEVC_2 60 +#define VAAPI_ENC_LEVEL_HEVC_21 63 +#define VAAPI_ENC_LEVEL_HEVC_3 90 +#define VAAPI_ENC_LEVEL_HEVC_31 93 +#define VAAPI_ENC_LEVEL_HEVC_4 120 +#define VAAPI_ENC_LEVEL_HEVC_41 123 +#define VAAPI_ENC_LEVEL_HEVC_5 150 +#define VAAPI_ENC_LEVEL_HEVC_51 153 +#define VAAPI_ENC_LEVEL_HEVC_52 156 +#define VAAPI_ENC_LEVEL_HEVC_6 180 +#define VAAPI_ENC_LEVEL_HEVC_61 183 +#define VAAPI_ENC_LEVEL_HEVC_62 186 /* hts ==================================================================== */ -static htsmsg_t * -platform_get_list( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("Unconstrained"), VAAPI_ENC_PLATFORM_UNCONSTRAINED }, - { N_("Intel"), VAAPI_ENC_PLATFORM_INTEL }, - { N_("AMD"), VAAPI_ENC_PLATFORM_AMD }, - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* platform_get_list(void* o, const char* lang) { + static const struct strtab tab[] = { + {N_("Unconstrained"), VAAPI_ENC_PLATFORM_UNCONSTRAINED}, + {N_("Intel"), VAAPI_ENC_PLATFORM_INTEL}, + {N_("AMD"), VAAPI_ENC_PLATFORM_AMD}, + }; + return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -rc_mode_get_list( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("skip"), VAAPI_ENC_PARAMS_RC_SKIP }, - { N_("auto"), VAAPI_ENC_PARAMS_RC_AUTO }, - { N_("CQP"), VAAPI_ENC_PARAMS_RC_CONSTQP }, - { N_("CBR"), VAAPI_ENC_PARAMS_RC_CBR }, - { N_("VBR"), VAAPI_ENC_PARAMS_RC_VBR }, - { N_("ICQ"), VAAPI_ENC_PARAMS_RC_ICQ }, - { N_("QVBR"), VAAPI_ENC_PARAMS_RC_QVBR }, - { N_("AVBR"), VAAPI_ENC_PARAMS_RC_AVBR }, - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* rc_mode_get_list(void* o, const char* lang) { + static const struct strtab tab[] = { + {N_("skip"), VAAPI_ENC_PARAMS_RC_SKIP}, + {N_("auto"), VAAPI_ENC_PARAMS_RC_AUTO}, + {N_("CQP"), VAAPI_ENC_PARAMS_RC_CONSTQP}, + {N_("CBR"), VAAPI_ENC_PARAMS_RC_CBR}, + {N_("VBR"), VAAPI_ENC_PARAMS_RC_VBR}, + {N_("ICQ"), VAAPI_ENC_PARAMS_RC_ICQ}, + {N_("QVBR"), VAAPI_ENC_PARAMS_RC_QVBR}, + {N_("AVBR"), VAAPI_ENC_PARAMS_RC_AVBR}, + }; + return strtab2htsmsg(tab, 1, lang); } // h264 -static htsmsg_t * -h264_level_get_list( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("skip"), VAAPI_ENC_LEVEL_H264_SKIP }, - { N_("1"), VAAPI_ENC_LEVEL_H264_1 }, - { N_("1.1"), VAAPI_ENC_LEVEL_H264_11 }, - { N_("1.2"), VAAPI_ENC_LEVEL_H264_12 }, - { N_("1.3"), VAAPI_ENC_LEVEL_H264_13 }, - { N_("2"), VAAPI_ENC_LEVEL_H264_2 }, - { N_("2.1"), VAAPI_ENC_LEVEL_H264_21 }, - { N_("2.2"), VAAPI_ENC_LEVEL_H264_22 }, - { N_("3"), VAAPI_ENC_LEVEL_H264_3 }, - { N_("3.1"), VAAPI_ENC_LEVEL_H264_31 }, - { N_("3.2"), VAAPI_ENC_LEVEL_H264_32 }, - { N_("4"), VAAPI_ENC_LEVEL_H264_4 }, - { N_("4.1"), VAAPI_ENC_LEVEL_H264_41 }, - { N_("4.2"), VAAPI_ENC_LEVEL_H264_42 }, - { N_("5"), VAAPI_ENC_LEVEL_H264_5 }, - { N_("5.1"), VAAPI_ENC_LEVEL_H264_51 }, - { N_("5.2"), VAAPI_ENC_LEVEL_H264_52 }, - { N_("6"), VAAPI_ENC_LEVEL_H264_6 }, - { N_("6.1"), VAAPI_ENC_LEVEL_H264_61 }, - { N_("6.2"), VAAPI_ENC_LEVEL_H264_62 }, - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* h264_level_get_list(void* o, const char* lang) { + static const struct strtab tab[] = { + {N_("skip"), VAAPI_ENC_LEVEL_H264_SKIP}, + {N_("1"), VAAPI_ENC_LEVEL_H264_1}, + {N_("1.1"), VAAPI_ENC_LEVEL_H264_11}, + {N_("1.2"), VAAPI_ENC_LEVEL_H264_12}, + {N_("1.3"), VAAPI_ENC_LEVEL_H264_13}, + {N_("2"), VAAPI_ENC_LEVEL_H264_2}, + {N_("2.1"), VAAPI_ENC_LEVEL_H264_21}, + {N_("2.2"), VAAPI_ENC_LEVEL_H264_22}, + {N_("3"), VAAPI_ENC_LEVEL_H264_3}, + {N_("3.1"), VAAPI_ENC_LEVEL_H264_31}, + {N_("3.2"), VAAPI_ENC_LEVEL_H264_32}, + {N_("4"), VAAPI_ENC_LEVEL_H264_4}, + {N_("4.1"), VAAPI_ENC_LEVEL_H264_41}, + {N_("4.2"), VAAPI_ENC_LEVEL_H264_42}, + {N_("5"), VAAPI_ENC_LEVEL_H264_5}, + {N_("5.1"), VAAPI_ENC_LEVEL_H264_51}, + {N_("5.2"), VAAPI_ENC_LEVEL_H264_52}, + {N_("6"), VAAPI_ENC_LEVEL_H264_6}, + {N_("6.1"), VAAPI_ENC_LEVEL_H264_61}, + {N_("6.2"), VAAPI_ENC_LEVEL_H264_62}, + }; + return strtab2htsmsg(tab, 1, lang); } -// hevc +// hevc -static htsmsg_t * -hevc_tier_get_list( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("skip"), VAAPI_ENC_HEVC_TIER_SKIP }, - { N_("main"), VAAPI_ENC_HEVC_TIER_MAIN }, - { N_("high"), VAAPI_ENC_HEVC_TIER_HIGH }, - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* hevc_tier_get_list(void* o, const char* lang) { + static const struct strtab tab[] = { + {N_("skip"), VAAPI_ENC_HEVC_TIER_SKIP}, + {N_("main"), VAAPI_ENC_HEVC_TIER_MAIN}, + {N_("high"), VAAPI_ENC_HEVC_TIER_HIGH}, + }; + return strtab2htsmsg(tab, 1, lang); } -static htsmsg_t * -hevc_level_get_list( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("skip"), VAAPI_ENC_LEVEL_HEVC_SKIP }, - { N_("1"), VAAPI_ENC_LEVEL_HEVC_1 }, - { N_("2"), VAAPI_ENC_LEVEL_HEVC_2 }, - { N_("2.1"), VAAPI_ENC_LEVEL_HEVC_21 }, - { N_("3"), VAAPI_ENC_LEVEL_HEVC_3 }, - { N_("3.1"), VAAPI_ENC_LEVEL_HEVC_31 }, - { N_("4"), VAAPI_ENC_LEVEL_HEVC_4 }, - { N_("4.1"), VAAPI_ENC_LEVEL_HEVC_41 }, - { N_("5"), VAAPI_ENC_LEVEL_HEVC_5 }, - { N_("5.1"), VAAPI_ENC_LEVEL_HEVC_51 }, - { N_("5.2"), VAAPI_ENC_LEVEL_HEVC_52 }, - { N_("6"), VAAPI_ENC_LEVEL_HEVC_6 }, - { N_("6.1"), VAAPI_ENC_LEVEL_HEVC_61 }, - { N_("6.2"), VAAPI_ENC_LEVEL_HEVC_62 }, - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* hevc_level_get_list(void* o, const char* lang) { + static const struct strtab tab[] = { + {N_("skip"), VAAPI_ENC_LEVEL_HEVC_SKIP}, + {N_("1"), VAAPI_ENC_LEVEL_HEVC_1}, + {N_("2"), VAAPI_ENC_LEVEL_HEVC_2}, + {N_("2.1"), VAAPI_ENC_LEVEL_HEVC_21}, + {N_("3"), VAAPI_ENC_LEVEL_HEVC_3}, + {N_("3.1"), VAAPI_ENC_LEVEL_HEVC_31}, + {N_("4"), VAAPI_ENC_LEVEL_HEVC_4}, + {N_("4.1"), VAAPI_ENC_LEVEL_HEVC_41}, + {N_("5"), VAAPI_ENC_LEVEL_HEVC_5}, + {N_("5.1"), VAAPI_ENC_LEVEL_HEVC_51}, + {N_("5.2"), VAAPI_ENC_LEVEL_HEVC_52}, + {N_("6"), VAAPI_ENC_LEVEL_HEVC_6}, + {N_("6.1"), VAAPI_ENC_LEVEL_HEVC_61}, + {N_("6.2"), VAAPI_ENC_LEVEL_HEVC_62}, + }; + return strtab2htsmsg(tab, 1, lang); } /* vaapi ==================================================================== */ typedef struct { - TVHVideoCodecProfile; - int qp; - int quality; - int async_depth; - int desired_b_depth; - double max_bit_rate; - double bit_rate_scale_factor; - int platform; - int loop_filter_level; - int loop_filter_sharpness; - double buff_factor; - int rc_mode; - int tier; - int level; - int qmin; - int qmax; - int super_frame; + TVHVideoCodecProfile; + int qp; + int quality; + int async_depth; + int desired_b_depth; + double max_bit_rate; + double bit_rate_scale_factor; + int platform; + int loop_filter_level; + int loop_filter_sharpness; + double buff_factor; + int rc_mode; + int tier; + int level; + int qmin; + int qmax; + int super_frame; } tvh_codec_profile_vaapi_t; #if defined(__linux__) @@ -201,1371 +190,1403 @@ typedef struct { #else #include #include -typedef size_t __kernel_size_t; +typedef size_t __kernel_size_t; #endif typedef struct drm_version { - int version_major; /**< Major version */ - int version_minor; /**< Minor version */ - int version_patchlevel; /**< Patch level */ - __kernel_size_t name_len; /**< Length of name buffer */ - char *name; /**< Name of driver */ - __kernel_size_t date_len; /**< Length of date buffer */ - char *date; /**< User-space buffer to hold date */ - __kernel_size_t desc_len; /**< Length of desc buffer */ - char *desc; /**< User-space buffer to hold desc */ + int version_major; /**< Major version */ + int version_minor; /**< Minor version */ + int version_patchlevel; /**< Patch level */ + __kernel_size_t name_len; /**< Length of name buffer */ + char* name; /**< Name of driver */ + __kernel_size_t date_len; /**< Length of date buffer */ + char* date; /**< User-space buffer to hold date */ + __kernel_size_t desc_len; /**< Length of desc buffer */ + char* desc; /**< User-space buffer to hold desc */ } drm_version_t; #define DRM_IOCTL_VERSION _IOWR('d', 0x00, struct drm_version) +static int probe_vaapi_device(const char* device, char* name, size_t namelen) { + drm_version_t dv; + char dname[128]; + int fd; -static int -probe_vaapi_device(const char *device, char *name, size_t namelen) -{ - drm_version_t dv; - char dname[128]; - int fd; - - if ((fd = open(device, O_RDWR)) < 0) - return -1; - memset(&dv, 0, sizeof(dv)); - memset(dname, 0, sizeof(dname)); - dv.name = dname; - dv.name_len = sizeof(dname)-1; - if (ioctl(fd, DRM_IOCTL_VERSION, &dv) < 0) { - close(fd); - return -1; - } - snprintf(name, namelen, "%s v%d.%d.%d (%s)", - dv.name, dv.version_major, dv.version_minor, - dv.version_patchlevel, device); + if ((fd = open(device, O_RDWR)) < 0) + return -1; + memset(&dv, 0, sizeof(dv)); + memset(dname, 0, sizeof(dname)); + dv.name = dname; + dv.name_len = sizeof(dname) - 1; + if (ioctl(fd, DRM_IOCTL_VERSION, &dv) < 0) { close(fd); - return 0; + return -1; + } + snprintf(name, + namelen, + "%s v%d.%d.%d (%s)", + dv.name, + dv.version_major, + dv.version_minor, + dv.version_patchlevel, + device); + close(fd); + return 0; } -static htsmsg_t * -tvh_codec_profile_vaapi_device_list(void *obj, const char *lang) -{ - static const char *renderD_fmt = "/dev/dri/renderD%d"; - static const char *card_fmt = "/dev/dri/card%d"; - htsmsg_t *result = htsmsg_create_list(); - char device[PATH_MAX]; - char name[128]; - int i, dev_num; +static htsmsg_t* tvh_codec_profile_vaapi_device_list(void* obj, const char* lang) { + static const char* renderD_fmt = "/dev/dri/renderD%d"; + static const char* card_fmt = "/dev/dri/card%d"; + htsmsg_t* result = htsmsg_create_list(); + char device[PATH_MAX]; + char name[128]; + int i, dev_num; - for (i = 0; i < 32; i++) { - dev_num = i + 128; - snprintf(device, sizeof(device), renderD_fmt, dev_num); - if (probe_vaapi_device(device, name, sizeof(name)) == 0) - htsmsg_add_msg(result, NULL, htsmsg_create_key_val(device, name)); - } - for (i = 0; i < 32; i++) { - dev_num = i + 128; - snprintf(device, sizeof(device), card_fmt, dev_num); - if (probe_vaapi_device(device, name, sizeof(name)) == 0) - htsmsg_add_msg(result, NULL, htsmsg_create_key_val(device, name)); - } - return result; + for (i = 0; i < 32; i++) { + dev_num = i + 128; + snprintf(device, sizeof(device), renderD_fmt, dev_num); + if (probe_vaapi_device(device, name, sizeof(name)) == 0) + htsmsg_add_msg(result, NULL, htsmsg_create_key_val(device, name)); + } + for (i = 0; i < 32; i++) { + dev_num = i + 128; + snprintf(device, sizeof(device), card_fmt, dev_num); + if (probe_vaapi_device(device, name, sizeof(name)) == 0) + htsmsg_add_msg(result, NULL, htsmsg_create_key_val(device, name)); + } + return result; } -static int -tvh_codec_profile_vaapi_open(tvh_codec_profile_vaapi_t *self, - AVDictionary **opts) -{ - // pix_fmt - AV_DICT_SET_PIX_FMT(opts, self->pix_fmt, AV_PIX_FMT_VAAPI); - return 0; +static int tvh_codec_profile_vaapi_open(tvh_codec_profile_vaapi_t* self, AVDictionary** opts) { + // pix_fmt + AV_DICT_SET_PIX_FMT(opts, self->pix_fmt, AV_PIX_FMT_VAAPI); + return 0; } // NOTE: // the names below are used in codec.js (/src/webui/static/app/codec.js) static const codec_profile_class_t codec_profile_vaapi_class = { - { - .ic_super = (idclass_t *)&codec_profile_video_class, - .ic_class = "codec_profile_vaapi", - .ic_caption = N_("vaapi"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "platform", // Don't change - .name = N_("Platform"), - .desc = N_("Select platform"), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, platform), - .list = platform_get_list, - .def.i = VAAPI_ENC_PLATFORM_UNCONSTRAINED, - }, - { - .type = PT_STR, - .id = "device", // Don't change - .name = N_("Device name"), - .desc = N_("Device name (e.g. /dev/dri/renderD128)."), - .group = 3, - .off = offsetof(tvh_codec_profile_vaapi_t, device), - .list = tvh_codec_profile_vaapi_device_list, - }, - { - .type = PT_BOOL, - .id = "low_power", // Don't change - .name = N_("Low Power"), - .desc = N_("Set low power mode.[if disabled will not send parameter to libav, if enabled codec will disable B frames]"), - .group = 3, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, low_power), - .def.i = 0, - }, - { - .type = PT_INT, - .id = "async_depth", // Don't change - .name = N_("Maximum processing parallelism"), - .desc = N_("Set maximum process in parallel (0=skip, 2=default).[driver must implement vaSyncBuffer function]"), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, async_depth), - .intextra = INTEXTRA_RANGE(0, 64, 1), - .def.i = 2, - }, - { - .type = PT_INT, - .id = "desired_b_depth", // Don't change - .name = N_("Maximum B-frame"), - .desc = N_("Maximum B-frame reference depth (from 1 to 3) (default 1)"), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, desired_b_depth), - .intextra = INTEXTRA_RANGE(0, 3, 1), - .def.i = 1, - }, - { - .type = PT_INT, - .id = "rc_mode", // Don't change - .name = N_("Rate control mode"), - .desc = N_("Set rate control mode"), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, rc_mode), - .list = rc_mode_get_list, - .def.i = VAAPI_ENC_PARAMS_RC_AUTO, - }, - { - .type = PT_INT, - .id = "qp", // Don't change - .name = N_("Constant QP"), - .group = 3, - .desc = N_("Fixed QP of P frames (from 0 to 52, 0=skip).[if disabled will not send paramter to libav]"), - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, qp), - .intextra = INTEXTRA_RANGE(0, 52, 1), - .def.i = 0, - }, - { - .type = PT_INT, - .id = "qmin", // Don't change - .name = N_("Minimum QP"), - .group = 5, - .desc = N_("Minimum QP of P frames (from 0 to 52, 0=skip)"), - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, qmin), - .intextra = INTEXTRA_RANGE(0, 52, 1), - .def.i = 0, - }, - { - .type = PT_INT, - .id = "qmax", // Don't change - .name = N_("Maximum QP"), - .group = 5, - .desc = N_("Maximum QP of P frames (from 0 to 52, 0=skip)"), - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, qmax), - .intextra = INTEXTRA_RANGE(0, 52, 1), - .def.i = 0, - }, - { - .type = PT_DBL, - .id = "bit_rate", // Don't change - .name = N_("Bitrate (kb/s)"), - .desc = N_("Target bitrate (0=skip).[if disabled will not send paramter to libav]"), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, bit_rate), - .def.d = 0, - }, - { - .type = PT_DBL, - .id = "max_bit_rate", // Don't change - .name = N_("Max bitrate (kb/s)"), - .desc = N_("Maximum bitrate (0=skip).[if disabled will not send paramter to libav]"), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, max_bit_rate), - .def.d = 0, - }, - { - .type = PT_DBL, - .id = "buff_factor", // Don't change - .name = N_("Buffer size factor"), - .desc = N_("Size of transcoding buffer (buffer=bitrate*2048*factor). Good factor is 3."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, buff_factor), - .def.d = 3, - }, - { - .type = PT_DBL, - .id = "bit_rate_scale_factor", // Don't change - .name = N_("Bitrate scale factor"), - .desc = N_("Bitrate & Max bitrate scaler with resolution (0=no scale; 1=proportional_change). Relative to 480."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, bit_rate_scale_factor), - .def.d = 0, - }, - { - .type = PT_INT, - .id = "hw_denoise", // Don't change - .name = N_("Denoise"), - .group = 2, - .desc = N_("Denoise only available with Hardware Acceleration (from 0 to 64, 0=skip, 0 default)"), - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, filter_hw_denoise), - .intextra = INTEXTRA_RANGE(0, 64, 1), - .def.i = 0, - }, - { - .type = PT_INT, - .id = "hw_sharpness", // Don't change - .name = N_("Sharpness"), - .group = 2, - .desc = N_("Sharpness only available with Hardware Acceleration (from 0 to 64, 0=skip, 44 default)"), - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, filter_hw_sharpness), - .intextra = INTEXTRA_RANGE(0, 64, 1), - .def.i = 44, - }, - {} - } - }, + {.ic_super = (idclass_t*)&codec_profile_video_class, + .ic_class = "codec_profile_vaapi", + .ic_caption = N_("vaapi"), + .ic_properties = + (const property_t[]){{ + .type = PT_INT, + .id = "platform", // Don't change + .name = N_("Platform"), + .desc = N_("Select platform"), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, platform), + .list = platform_get_list, + .def.i = VAAPI_ENC_PLATFORM_UNCONSTRAINED, + }, + { + .type = PT_STR, + .id = "device", // Don't change + .name = N_("Device name"), + .desc = N_("Device name (e.g. /dev/dri/renderD128)."), + .group = 3, + .off = offsetof(tvh_codec_profile_vaapi_t, device), + .list = tvh_codec_profile_vaapi_device_list, + }, + { + .type = PT_BOOL, + .id = "low_power", // Don't change + .name = N_("Low Power"), + .desc = N_("Set low power mode.[if disabled will not send parameter to libav, " + "if enabled codec will disable B frames]"), + .group = 3, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, low_power), + .def.i = 0, + }, + { + .type = PT_INT, + .id = "async_depth", // Don't change + .name = N_("Maximum processing parallelism"), + .desc = N_("Set maximum process in parallel (0=skip, 2=default).[driver must " + "implement vaSyncBuffer function]"), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, async_depth), + .intextra = INTEXTRA_RANGE(0, 64, 1), + .def.i = 2, + }, + { + .type = PT_INT, + .id = "desired_b_depth", // Don't change + .name = N_("Maximum B-frame"), + .desc = N_("Maximum B-frame reference depth (from 1 to 3) (default 1)"), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, desired_b_depth), + .intextra = INTEXTRA_RANGE(0, 3, 1), + .def.i = 1, + }, + { + .type = PT_INT, + .id = "rc_mode", // Don't change + .name = N_("Rate control mode"), + .desc = N_("Set rate control mode"), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, rc_mode), + .list = rc_mode_get_list, + .def.i = VAAPI_ENC_PARAMS_RC_AUTO, + }, + { + .type = PT_INT, + .id = "qp", // Don't change + .name = N_("Constant QP"), + .group = 3, + .desc = N_("Fixed QP of P frames (from 0 to 52, 0=skip).[if disabled will not " + "send paramter to libav]"), + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, qp), + .intextra = INTEXTRA_RANGE(0, 52, 1), + .def.i = 0, + }, + { + .type = PT_INT, + .id = "qmin", // Don't change + .name = N_("Minimum QP"), + .group = 5, + .desc = N_("Minimum QP of P frames (from 0 to 52, 0=skip)"), + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, qmin), + .intextra = INTEXTRA_RANGE(0, 52, 1), + .def.i = 0, + }, + { + .type = PT_INT, + .id = "qmax", // Don't change + .name = N_("Maximum QP"), + .group = 5, + .desc = N_("Maximum QP of P frames (from 0 to 52, 0=skip)"), + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, qmax), + .intextra = INTEXTRA_RANGE(0, 52, 1), + .def.i = 0, + }, + { + .type = PT_DBL, + .id = "bit_rate", // Don't change + .name = N_("Bitrate (kb/s)"), + .desc = + N_("Target bitrate (0=skip).[if disabled will not send paramter to libav]"), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, bit_rate), + .def.d = 0, + }, + { + .type = PT_DBL, + .id = "max_bit_rate", // Don't change + .name = N_("Max bitrate (kb/s)"), + .desc = N_( + "Maximum bitrate (0=skip).[if disabled will not send paramter to libav]"), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, max_bit_rate), + .def.d = 0, + }, + { + .type = PT_DBL, + .id = "buff_factor", // Don't change + .name = N_("Buffer size factor"), + .desc = N_("Size of transcoding buffer (buffer=bitrate*2048*factor). Good " + "factor is 3."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, buff_factor), + .def.d = 3, + }, + { + .type = PT_DBL, + .id = "bit_rate_scale_factor", // Don't change + .name = N_("Bitrate scale factor"), + .desc = N_("Bitrate & Max bitrate scaler with resolution (0=no scale; " + "1=proportional_change). Relative to 480."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, bit_rate_scale_factor), + .def.d = 0, + }, + { + .type = PT_INT, + .id = "hw_denoise", // Don't change + .name = N_("Denoise"), + .group = 2, + .desc = N_("Denoise only available with Hardware Acceleration (from 0 to 64, " + "0=skip, 0 default)"), + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, filter_hw_denoise), + .intextra = INTEXTRA_RANGE(0, 64, 1), + .def.i = 0, + }, + { + .type = PT_INT, + .id = "hw_sharpness", // Don't change + .name = N_("Sharpness"), + .group = 2, + .desc = N_("Sharpness only available with Hardware Acceleration (from 0 to 64, " + "0=skip, 44 default)"), + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, filter_hw_sharpness), + .intextra = INTEXTRA_RANGE(0, 64, 1), + .def.i = 44, + }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_vaapi_open, }; - /* h264_vaapi =============================================================== */ static const AVProfile vaapi_h264_profiles[] = { - { FF_PROFILE_H264_CONSTRAINED_BASELINE, "Constrained Baseline" }, - { FF_PROFILE_H264_MAIN, "Main" }, - { FF_PROFILE_H264_HIGH, "High" }, - { FF_PROFILE_UNKNOWN }, + {FF_PROFILE_H264_CONSTRAINED_BASELINE, "Constrained Baseline"}, + {FF_PROFILE_H264_MAIN, "Main"}, + {FF_PROFILE_H264_HIGH, "High"}, + {FF_PROFILE_UNKNOWN}, }; -static int -tvh_codec_profile_vaapi_h264_open(tvh_codec_profile_vaapi_t *self, - AVDictionary **opts) -{ - // to avoid issues we have this check: - if (self->buff_factor <= 0) { - self->buff_factor = 3; - } - int int_bitrate = (int)((double)(self->bit_rate) * 1024.0 * (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); - int int_buffer_size = (int)((double)(self->bit_rate) * 2048.0 * self->buff_factor * (1.0 + self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480)); - int int_max_bitrate = (int)((double)(self->max_bit_rate) * 1024.0 * (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); - tvhinfo(LS_VAAPI, "Bitrate = %d kbps; Buffer size = %d kbps; Max bitrate = %d kbps", int_bitrate / 1024, int_buffer_size / 1024, int_max_bitrate / 1024); - // https://wiki.libav.org/Hardware/vaapi - // https://blog.wmspanel.com/2017/03/vaapi-libva-support-nimble-streamer.html - // to find available parameters use: - // ffmpeg -hide_banner -h encoder=h264_vaapi - // h264_vaapi AVOptions: - // -low_power E..V....... Use low-power encoding mode (only available on some platforms; may not support all encoding features) (default false) - // -idr_interval E..V....... Distance (in I-frames) between IDR frames (from 0 to INT_MAX) (default 0) - // -b_depth E..V....... Maximum B-frame reference depth (from 1 to INT_MAX) (default 1) - // -rc_mode E..V....... Set rate control mode (from 0 to 6) (default auto) - // auto 0 E..V....... Choose mode automatically based on other parameters - // CQP 1 E..V....... Constant-quality - // CBR 2 E..V....... Constant-bitrate - // VBR 3 E..V....... Variable-bitrate - // ICQ 4 E..V....... Intelligent constant-quality - // QVBR 5 E..V....... Quality-defined variable-bitrate - // AVBR 6 E..V....... Average variable-bitrate - // -qp E..V....... Constant QP (for P-frames; scaled by qfactor/qoffset for I/B) (from 0 to 52) (default 0) - // -quality E..V....... Set encode quality (trades off against speed, higher is faster) (from -1 to INT_MAX) (default -1) - // -coder E..V....... Entropy coder type (from 0 to 1) (default cabac) - // cavlc 0 E..V....... - // cabac 1 E..V....... - // vlc 0 E..V....... - // ac 1 E..V....... - // -aud E..V....... Include AUD (default false) - // -sei E..V....... Set SEI to include (default identifier+timing+recovery_point) - // identifier E..V....... Include encoder version identifier - // timing E..V....... Include timing parameters (buffering_period and pic_timing) - // recovery_point E..V....... Include recovery points where appropriate - // -profile E..V....... Set profile (profile_idc and constraint_set*_flag) (from -99 to 65535) (default -99) - // constrained_baseline 578 E..V....... - // main 77 E..V....... - // high 100 E..V....... - // -level E..V....... Set level (level_idc) (from -99 to 255) (default -99) - // 1 10 E..V....... - // 1.1 11 E..V....... - // 1.2 12 E..V....... - // 1.3 13 E..V....... - // 2 20 E..V....... - // 2.1 21 E..V....... - // 2.2 22 E..V....... - // 3 30 E..V....... - // 3.1 31 E..V....... - // 3.2 32 E..V....... - // 4 40 E..V....... - // 4.1 41 E..V....... - // 4.2 42 E..V....... - // 5 50 E..V....... - // 5.1 51 E..V....... - // 5.2 52 E..V....... - // 6 60 E..V....... - // 6.1 61 E..V....... - // 6.2 62 E..V....... - if (self->rc_mode >= 0) { - AV_DICT_SET_INT(opts, "rc_mode", self->rc_mode, AV_DICT_DONT_OVERWRITE); - } - switch (self->platform) { +static int tvh_codec_profile_vaapi_h264_open(tvh_codec_profile_vaapi_t* self, AVDictionary** opts) { + // to avoid issues we have this check: + if (self->buff_factor <= 0) { + self->buff_factor = 3; + } + int int_bitrate = (int)((double)(self->bit_rate) * 1024.0 * + (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); + int int_buffer_size = (int)((double)(self->bit_rate) * 2048.0 * self->buff_factor * + (1.0 + self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480)); + int int_max_bitrate = (int)((double)(self->max_bit_rate) * 1024.0 * + (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); + tvhinfo(LS_VAAPI, + "Bitrate = %d kbps; Buffer size = %d kbps; Max bitrate = %d kbps", + int_bitrate / 1024, + int_buffer_size / 1024, + int_max_bitrate / 1024); + // https://wiki.libav.org/Hardware/vaapi + // https://blog.wmspanel.com/2017/03/vaapi-libva-support-nimble-streamer.html + // to find available parameters use: + // ffmpeg -hide_banner -h encoder=h264_vaapi + // h264_vaapi AVOptions: + // -low_power E..V....... Use low-power encoding mode (only available on some + // platforms; may not support all encoding features) (default false) -idr_interval + // E..V....... Distance (in I-frames) between IDR frames (from 0 to INT_MAX) (default 0) -b_depth + // E..V....... Maximum B-frame reference depth (from 1 to INT_MAX) (default 1) + // -rc_mode E..V....... Set rate control mode (from 0 to 6) (default auto) + // auto 0 E..V....... Choose mode automatically based on other parameters + // CQP 1 E..V....... Constant-quality + // CBR 2 E..V....... Constant-bitrate + // VBR 3 E..V....... Variable-bitrate + // ICQ 4 E..V....... Intelligent constant-quality + // QVBR 5 E..V....... Quality-defined variable-bitrate + // AVBR 6 E..V....... Average variable-bitrate + // -qp E..V....... Constant QP (for P-frames; scaled by + // qfactor/qoffset for I/B) (from 0 to 52) (default 0) -quality E..V....... + // Set encode quality (trades off against speed, higher is faster) (from -1 to INT_MAX) (default + // -1) -coder E..V....... Entropy coder type (from 0 to 1) (default + // cabac) + // cavlc 0 E..V....... + // cabac 1 E..V....... + // vlc 0 E..V....... + // ac 1 E..V....... + // -aud E..V....... Include AUD (default false) + // -sei E..V....... Set SEI to include (default + // identifier+timing+recovery_point) + // identifier E..V....... Include encoder version identifier + // timing E..V....... Include timing parameters (buffering_period and + // pic_timing) recovery_point E..V....... Include recovery points where + // appropriate + // -profile E..V....... Set profile (profile_idc and constraint_set*_flag) + // (from -99 to 65535) (default -99) + // constrained_baseline 578 E..V....... + // main 77 E..V....... + // high 100 E..V....... + // -level E..V....... Set level (level_idc) (from -99 to 255) (default + // -99) + // 1 10 E..V....... + // 1.1 11 E..V....... + // 1.2 12 E..V....... + // 1.3 13 E..V....... + // 2 20 E..V....... + // 2.1 21 E..V....... + // 2.2 22 E..V....... + // 3 30 E..V....... + // 3.1 31 E..V....... + // 3.2 32 E..V....... + // 4 40 E..V....... + // 4.1 41 E..V....... + // 4.2 42 E..V....... + // 5 50 E..V....... + // 5.1 51 E..V....... + // 5.2 52 E..V....... + // 6 60 E..V....... + // 6.1 61 E..V....... + // 6.2 62 E..V....... + if (self->rc_mode >= 0) { + AV_DICT_SET_INT(opts, "rc_mode", self->rc_mode, AV_DICT_DONT_OVERWRITE); + } + switch (self->platform) { + case 0: + // Uncontrained --> will allow any combination of parameters (valid or invalid) + // this mode is usefull fur future platform and for debugging. + if ((self->low_power == 0) && (self->desired_b_depth)) { + AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + // max_b_frames + AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + if (self->quality >= 0) { + AV_DICT_SET_INT(opts, "quality", self->quality, AV_DICT_DONT_OVERWRITE); + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->level != -100) { + AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + case 1: + // Intel + if ((self->low_power == 0) && (self->desired_b_depth)) { + AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + // max_b_frames + AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + } + switch (self->rc_mode) { + case -1: + // same like 0 but is not sending 'rc_mode' case 0: - // Uncontrained --> will allow any combination of parameters (valid or invalid) - // this mode is usefull fur future platform and for debugging. - if ((self->low_power == 0) && (self->desired_b_depth)) { - AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - // max_b_frames - AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - if (self->quality >= 0) { - AV_DICT_SET_INT(opts, "quality", self->quality, AV_DICT_DONT_OVERWRITE); - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->level != -100) { - AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; + // for auto --> let the driver decide as requested by documentation + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; case 1: - // Intel - if ((self->low_power == 0) && (self->desired_b_depth)) { - AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - // max_b_frames - AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - } - switch (self->rc_mode) { - case -1: - // same like 0 but is not sending 'rc_mode' - case 0: - // for auto --> let the driver decide as requested by documentation - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 1: - case 4: - // for constant quality: CQP and ICQ we use qp - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 2: - // for constant bitrate: CBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - break; - case 3: - // for variable bitrate: VBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - break; - case 5: - // for variable bitrate: QVBR we use bitrate + qp - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 6: - // for variable bitrate: AVBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - break; - } - if (self->quality >= 0) { - AV_DICT_SET_INT(opts, "quality", self->quality, AV_DICT_DONT_OVERWRITE); - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->level != -100) { - AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; + case 4: + // for constant quality: CQP and ICQ we use qp + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; case 2: - // AMD --> will allow any combination of parameters - // I am unable to confirm this platform because I don't have the HW - // Is only going to override bf to 0 (as highlited by the previous implementation) - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - AV_DICT_SET_INT(opts, "bf", 0, 0); - if (self->quality >= 0) { - AV_DICT_SET_INT(opts, "quality", self->quality, AV_DICT_DONT_OVERWRITE); - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->level != -100) { - AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; - } - // force keyframe every 3 sec. - AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); - return 0; + // for constant bitrate: CBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + break; + case 3: + // for variable bitrate: VBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + break; + case 5: + // for variable bitrate: QVBR we use bitrate + qp + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; + case 6: + // for variable bitrate: AVBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + break; + } + if (self->quality >= 0) { + AV_DICT_SET_INT(opts, "quality", self->quality, AV_DICT_DONT_OVERWRITE); + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->level != -100) { + AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + case 2: + // AMD --> will allow any combination of parameters + // I am unable to confirm this platform because I don't have the HW + // Is only going to override bf to 0 (as highlited by the previous implementation) + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + AV_DICT_SET_INT(opts, "bf", 0, 0); + if (self->quality >= 0) { + AV_DICT_SET_INT(opts, "quality", self->quality, AV_DICT_DONT_OVERWRITE); + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->level != -100) { + AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + } + // force keyframe every 3 sec. + AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); + return 0; } // NOTE: // the names below are used in codec.js (/src/webui/static/app/codec.js) static const codec_profile_class_t codec_profile_vaapi_h264_class = { - { - .ic_super = (idclass_t *)&codec_profile_vaapi_class, - .ic_class = "codec_profile_vaapi_h264", - .ic_caption = N_("vaapi_h264"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "quality", // Don't change - .name = N_("Quality"), - .desc = N_("Set encode quality (trades off against speed, " - "higher is faster) [-1=skip 0-7]."), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, quality), - .intextra = INTEXTRA_RANGE(-1, 7, 1), - .def.i = 0, - }, - { - .type = PT_INT, - .id = "level", // Don't change - .name = N_("Level"), - .desc = N_("Set level (level_idc)"), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, level), - .list = h264_level_get_list, - .def.i = VAAPI_ENC_LEVEL_H264_3, - }, - {} - } - }, + {.ic_super = (idclass_t*)&codec_profile_vaapi_class, + .ic_class = "codec_profile_vaapi_h264", + .ic_caption = N_("vaapi_h264"), + .ic_properties = + (const property_t[]){{ + .type = PT_INT, + .id = "quality", // Don't change + .name = N_("Quality"), + .desc = N_("Set encode quality (trades off against speed, " + "higher is faster) [-1=skip 0-7]."), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, quality), + .intextra = INTEXTRA_RANGE(-1, 7, 1), + .def.i = 0, + }, + { + .type = PT_INT, + .id = "level", // Don't change + .name = N_("Level"), + .desc = N_("Set level (level_idc)"), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, level), + .list = h264_level_get_list, + .def.i = VAAPI_ENC_LEVEL_H264_3, + }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_vaapi_h264_open, }; - TVHVideoCodec tvh_codec_vaapi_h264 = { - .name = "h264_vaapi", - .size = sizeof(tvh_codec_profile_vaapi_t), - .idclass = &codec_profile_vaapi_h264_class, - .profiles = vaapi_h264_profiles, - .profile_init = tvh_codec_profile_video_init, + .name = "h264_vaapi", + .size = sizeof(tvh_codec_profile_vaapi_t), + .idclass = &codec_profile_vaapi_h264_class, + .profiles = vaapi_h264_profiles, + .profile_init = tvh_codec_profile_video_init, .profile_destroy = tvh_codec_profile_video_destroy, }; - /* hevc_vaapi =============================================================== */ static const AVProfile vaapi_hevc_profiles[] = { - { FF_PROFILE_HEVC_MAIN, "Main" }, - { FF_PROFILE_HEVC_MAIN_10, "Main 10" }, - { FF_PROFILE_HEVC_REXT, "Rext" }, - { FF_PROFILE_UNKNOWN }, + {FF_PROFILE_HEVC_MAIN, "Main"}, + {FF_PROFILE_HEVC_MAIN_10, "Main 10"}, + {FF_PROFILE_HEVC_REXT, "Rext"}, + {FF_PROFILE_UNKNOWN}, }; -static int -tvh_codec_profile_vaapi_hevc_open(tvh_codec_profile_vaapi_t *self, - AVDictionary **opts) -{ - // to avoid issues we have this check: - if (self->buff_factor <= 0) { - self->buff_factor = 3; - } - int int_bitrate = (int)((double)(self->bit_rate) * 1024.0 * (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); - int int_buffer_size = (int)((double)(self->bit_rate) * 2048.0 * self->buff_factor * (1.0 + self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480)); - int int_max_bitrate = (int)((double)(self->max_bit_rate) * 1024.0 * (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); - tvhinfo(LS_VAAPI, "Bitrate = %d kbps; Buffer size = %d kbps; Max bitrate = %d kbps", int_bitrate / 1024, int_buffer_size / 1024, int_max_bitrate / 1024); - // https://wiki.libav.org/Hardware/vaapi - // to find available parameters use: - // ffmpeg -hide_banner -h encoder=hevc_vaapi - // h265_vaapi AVOptions: - // -low_power E..V....... Use low-power encoding mode (only available on some platforms; may not support all encoding features) (default false) - // -idr_interval E..V....... Distance (in I-frames) between IDR frames (from 0 to INT_MAX) (default 0) - // -b_depth E..V....... Maximum B-frame reference depth (from 1 to INT_MAX) (default 1) - // -rc_mode E..V....... Set rate control mode (from 0 to 6) (default auto) - // auto 0 E..V....... Choose mode automatically based on other parameters - // CQP 1 E..V....... Constant-quality - // CBR 2 E..V....... Constant-bitrate - // VBR 3 E..V....... Variable-bitrate - // ICQ 4 E..V....... Intelligent constant-quality - // QVBR 5 E..V....... Quality-defined variable-bitrate - // AVBR 6 E..V....... Average variable-bitrate - // -qp E..V....... Constant QP (for P-frames; scaled by qfactor/qoffset for I/B) (from 0 to 52) (default 0) - // -aud E..V....... Include AUD (default false) - // -profile E..V....... Set profile (general_profile_idc) (from -99 to 255) (default -99) - // main 1 E..V....... - // main10 2 E..V....... - // rext 4 E..V....... - // -tier E..V....... Set tier (general_tier_flag) (from 0 to 1) (default main) - // main 0 E..V....... - // high 1 E..V....... - // -level E..V....... Set level (general_level_idc) (from -99 to 255) (default -99) - // 1 30 E..V....... - // 2 60 E..V....... - // 2.1 63 E..V....... - // 3 90 E..V....... - // 3.1 93 E..V....... - // 4 120 E..V....... - // 4.1 123 E..V....... - // 5 150 E..V....... - // 5.1 153 E..V....... - // 5.2 156 E..V....... - // 6 180 E..V....... - // 6.1 183 E..V....... - // 6.2 186 E..V....... - // -sei E..V....... Set SEI to include (default hdr) - // hdr E..V....... Include HDR metadata for mastering display colour volume and content light level information - // -tiles E..V....... Tile columns x rows +static int tvh_codec_profile_vaapi_hevc_open(tvh_codec_profile_vaapi_t* self, AVDictionary** opts) { + // to avoid issues we have this check: + if (self->buff_factor <= 0) { + self->buff_factor = 3; + } + int int_bitrate = (int)((double)(self->bit_rate) * 1024.0 * + (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); + int int_buffer_size = (int)((double)(self->bit_rate) * 2048.0 * self->buff_factor * + (1.0 + self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480)); + int int_max_bitrate = (int)((double)(self->max_bit_rate) * 1024.0 * + (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); + tvhinfo(LS_VAAPI, + "Bitrate = %d kbps; Buffer size = %d kbps; Max bitrate = %d kbps", + int_bitrate / 1024, + int_buffer_size / 1024, + int_max_bitrate / 1024); + // https://wiki.libav.org/Hardware/vaapi + // to find available parameters use: + // ffmpeg -hide_banner -h encoder=hevc_vaapi + // h265_vaapi AVOptions: + // -low_power E..V....... Use low-power encoding mode (only available on some + // platforms; may not support all encoding features) (default false) -idr_interval + // E..V....... Distance (in I-frames) between IDR frames (from 0 to INT_MAX) (default 0) -b_depth + // E..V....... Maximum B-frame reference depth (from 1 to INT_MAX) (default 1) + // -rc_mode E..V....... Set rate control mode (from 0 to 6) (default auto) + // auto 0 E..V....... Choose mode automatically based on other parameters + // CQP 1 E..V....... Constant-quality + // CBR 2 E..V....... Constant-bitrate + // VBR 3 E..V....... Variable-bitrate + // ICQ 4 E..V....... Intelligent constant-quality + // QVBR 5 E..V....... Quality-defined variable-bitrate + // AVBR 6 E..V....... Average variable-bitrate + // -qp E..V....... Constant QP (for P-frames; scaled by + // qfactor/qoffset for I/B) (from 0 to 52) (default 0) -aud E..V....... + // Include AUD (default false) -profile E..V....... Set profile + // (general_profile_idc) (from -99 to 255) (default -99) + // main 1 E..V....... + // main10 2 E..V....... + // rext 4 E..V....... + // -tier E..V....... Set tier (general_tier_flag) (from 0 to 1) (default + // main) + // main 0 E..V....... + // high 1 E..V....... + // -level E..V....... Set level (general_level_idc) (from -99 to 255) + // (default -99) + // 1 30 E..V....... + // 2 60 E..V....... + // 2.1 63 E..V....... + // 3 90 E..V....... + // 3.1 93 E..V....... + // 4 120 E..V....... + // 4.1 123 E..V....... + // 5 150 E..V....... + // 5.1 153 E..V....... + // 5.2 156 E..V....... + // 6 180 E..V....... + // 6.1 183 E..V....... + // 6.2 186 E..V....... + // -sei E..V....... Set SEI to include (default hdr) + // hdr E..V....... Include HDR metadata for mastering display colour + // volume and content light level information + // -tiles E..V....... Tile columns x rows - if (self->rc_mode >= 0) { - AV_DICT_SET_INT(opts, "rc_mode", self->rc_mode, AV_DICT_DONT_OVERWRITE); - } - switch (self->platform) { + if (self->rc_mode >= 0) { + AV_DICT_SET_INT(opts, "rc_mode", self->rc_mode, AV_DICT_DONT_OVERWRITE); + } + switch (self->platform) { + case 0: + // Unconstrained --> will allow any combination of parameters (valid or invalid) + // this mode is usefull fur future platform and for debugging. + if ((self->low_power == 0) && (self->desired_b_depth)) { + AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + // max_b_frames + AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + if (self->tier >= 0) { + AV_DICT_SET_INT(opts, "tier", self->tier, AV_DICT_DONT_OVERWRITE); + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->level != -100) { + AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + case 1: + // Intel + if ((self->low_power == 0) && (self->desired_b_depth)) { + AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + // max_b_frames + AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + } + switch (self->rc_mode) { + case -1: + // same like 0 but is not sending 'rc_mode' case 0: - // Unconstrained --> will allow any combination of parameters (valid or invalid) - // this mode is usefull fur future platform and for debugging. - if ((self->low_power == 0) && (self->desired_b_depth)) { - AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - // max_b_frames - AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - if (self->tier >= 0) { - AV_DICT_SET_INT(opts, "tier", self->tier, AV_DICT_DONT_OVERWRITE); - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->level != -100) { - AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; + // for auto --> let the driver decide as requested by documentation + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; case 1: - // Intel - if ((self->low_power == 0) && (self->desired_b_depth)) { - AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - // max_b_frames - AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - } - switch (self->rc_mode) { - case -1: - // same like 0 but is not sending 'rc_mode' - case 0: - // for auto --> let the driver decide as requested by documentation - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 1: - case 4: - // for constant quality: CQP and ICQ we use qp - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 2: - // for constant bitrate: CBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - break; - case 3: - // for variable bitrate: VBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - break; - case 5: - // for variable bitrate: QVBR we use bitrate + qp - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 6: - // for variable bitrate: AVBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - break; - } - if (self->tier >= 0) { - AV_DICT_SET_INT(opts, "tier", self->tier, AV_DICT_DONT_OVERWRITE); - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->level != -100) { - AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; + case 4: + // for constant quality: CQP and ICQ we use qp + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; case 2: - // AMD --> will allow any combination of parameters - // I am unable to confirm this platform because I don't have the HW - // Is only going to override bf to 0 (as highlited by the previous implementation) - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - AV_DICT_SET_INT(opts, "bf", 0, 0); - if (self->tier >= 0) { - AV_DICT_SET_INT(opts, "tier", self->tier, AV_DICT_DONT_OVERWRITE); - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->level != -100) { - AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; - } - // force keyframe every 3 sec. - AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); - return 0; + // for constant bitrate: CBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + break; + case 3: + // for variable bitrate: VBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + break; + case 5: + // for variable bitrate: QVBR we use bitrate + qp + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; + case 6: + // for variable bitrate: AVBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + break; + } + if (self->tier >= 0) { + AV_DICT_SET_INT(opts, "tier", self->tier, AV_DICT_DONT_OVERWRITE); + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->level != -100) { + AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + case 2: + // AMD --> will allow any combination of parameters + // I am unable to confirm this platform because I don't have the HW + // Is only going to override bf to 0 (as highlited by the previous implementation) + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + AV_DICT_SET_INT(opts, "bf", 0, 0); + if (self->tier >= 0) { + AV_DICT_SET_INT(opts, "tier", self->tier, AV_DICT_DONT_OVERWRITE); + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->level != -100) { + AV_DICT_SET_INT(opts, "level", self->level, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + } + // force keyframe every 3 sec. + AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); + return 0; } - static const codec_profile_class_t codec_profile_vaapi_hevc_class = { - { - .ic_super = (idclass_t *)&codec_profile_vaapi_class, - .ic_class = "codec_profile_vaapi_hevc", - .ic_caption = N_("vaapi_hevc"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "tier", // Don't change - .name = N_("Tier"), - .desc = N_("Set tier (general_tier_flag) (from 0 to 1) (default main)"), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, tier), - .list = hevc_tier_get_list, - .def.i = 0, - }, - { - .type = PT_INT, - .id = "level", // Don't change - .name = N_("Level"), - .desc = N_("Set level (general_level_idc)"), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, level), - .list = hevc_level_get_list, - .def.i = VAAPI_ENC_LEVEL_HEVC_3, - }, - {} - } - }, + {.ic_super = (idclass_t*)&codec_profile_vaapi_class, + .ic_class = "codec_profile_vaapi_hevc", + .ic_caption = N_("vaapi_hevc"), + .ic_properties = + (const property_t[]){ + { + .type = PT_INT, + .id = "tier", // Don't change + .name = N_("Tier"), + .desc = N_("Set tier (general_tier_flag) (from 0 to 1) (default main)"), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, tier), + .list = hevc_tier_get_list, + .def.i = 0, + }, + { + .type = PT_INT, + .id = "level", // Don't change + .name = N_("Level"), + .desc = N_("Set level (general_level_idc)"), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, level), + .list = hevc_level_get_list, + .def.i = VAAPI_ENC_LEVEL_HEVC_3, + }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_vaapi_hevc_open, }; - TVHVideoCodec tvh_codec_vaapi_hevc = { - .name = "hevc_vaapi", - .size = sizeof(tvh_codec_profile_vaapi_t), - .idclass = &codec_profile_vaapi_hevc_class, - .profiles = vaapi_hevc_profiles, - .profile_init = tvh_codec_profile_video_init, + .name = "hevc_vaapi", + .size = sizeof(tvh_codec_profile_vaapi_t), + .idclass = &codec_profile_vaapi_hevc_class, + .profiles = vaapi_hevc_profiles, + .profile_init = tvh_codec_profile_video_init, .profile_destroy = tvh_codec_profile_video_destroy, }; - /* vp8_vaapi =============================================================== */ static const AVProfile vaapi_vp8_profiles[] = { - { FF_PROFILE_UNKNOWN }, + {FF_PROFILE_UNKNOWN}, }; -static int -tvh_codec_profile_vaapi_vp8_open(tvh_codec_profile_vaapi_t *self, - AVDictionary **opts) -{ - // to avoid issues we have this check: - if (self->buff_factor <= 0) { - self->buff_factor = 3; - } - int int_bitrate = (int)((double)(self->bit_rate) * 1024.0 * (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); - int int_buffer_size = (int)((double)(self->bit_rate) * 2048.0 * self->buff_factor * (1.0 + self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480)); - int int_max_bitrate = (int)((double)(self->max_bit_rate) * 1024.0 * (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); - tvhinfo(LS_VAAPI, "Bitrate = %d kbps; Buffer size = %d kbps; Max bitrate = %d kbps", int_bitrate / 1024, int_buffer_size / 1024, int_max_bitrate / 1024); - // https://wiki.libav.org/Hardware/vaapi - // to find available parameters use: - // ffmpeg -hide_banner -h encoder=vp8_vaapi - // vp8_vaapi AVOptions: - // -low_power E..V....... Use low-power encoding mode (only available on some platforms; may not support all encoding features) (default false) - // -idr_interval E..V....... Distance (in I-frames) between IDR frames (from 0 to INT_MAX) (default 0) - // -b_depth E..V....... Maximum B-frame reference depth (from 1 to INT_MAX) (default 1) - // -rc_mode E..V....... Set rate control mode (from 0 to 6) (default auto) - // auto 0 E..V....... Choose mode automatically based on other parameters - // CQP 1 E..V....... Constant-quality - // CBR 2 E..V....... Constant-bitrate - // VBR 3 E..V....... Variable-bitrate - // ICQ 4 E..V....... Intelligent constant-quality - // QVBR 5 E..V....... Quality-defined variable-bitrate - // AVBR 6 E..V....... Average variable-bitrate - // -loop_filter_level E..V....... Loop filter level (from 0 to 63) (default 16) - // -loop_filter_sharpness E..V....... Loop filter sharpness (from 0 to 15) (default 4) +static int tvh_codec_profile_vaapi_vp8_open(tvh_codec_profile_vaapi_t* self, AVDictionary** opts) { + // to avoid issues we have this check: + if (self->buff_factor <= 0) { + self->buff_factor = 3; + } + int int_bitrate = (int)((double)(self->bit_rate) * 1024.0 * + (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); + int int_buffer_size = (int)((double)(self->bit_rate) * 2048.0 * self->buff_factor * + (1.0 + self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480)); + int int_max_bitrate = (int)((double)(self->max_bit_rate) * 1024.0 * + (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); + tvhinfo(LS_VAAPI, + "Bitrate = %d kbps; Buffer size = %d kbps; Max bitrate = %d kbps", + int_bitrate / 1024, + int_buffer_size / 1024, + int_max_bitrate / 1024); + // https://wiki.libav.org/Hardware/vaapi + // to find available parameters use: + // ffmpeg -hide_banner -h encoder=vp8_vaapi + // vp8_vaapi AVOptions: + // -low_power E..V....... Use low-power encoding mode (only available on some + // platforms; may not support all encoding features) (default false) -idr_interval + // E..V....... Distance (in I-frames) between IDR frames (from 0 to INT_MAX) (default 0) -b_depth + // E..V....... Maximum B-frame reference depth (from 1 to INT_MAX) (default 1) + // -rc_mode E..V....... Set rate control mode (from 0 to 6) (default auto) + // auto 0 E..V....... Choose mode automatically based on other parameters + // CQP 1 E..V....... Constant-quality + // CBR 2 E..V....... Constant-bitrate + // VBR 3 E..V....... Variable-bitrate + // ICQ 4 E..V....... Intelligent constant-quality + // QVBR 5 E..V....... Quality-defined variable-bitrate + // AVBR 6 E..V....... Average variable-bitrate + // -loop_filter_level E..V....... Loop filter level (from 0 to 63) (default 16) + // -loop_filter_sharpness E..V....... Loop filter sharpness (from 0 to 15) (default + // 4) - if (self->rc_mode >= 0) { - AV_DICT_SET_INT(opts, "rc_mode", self->rc_mode, AV_DICT_DONT_OVERWRITE); - } - switch (self->platform) { + if (self->rc_mode >= 0) { + AV_DICT_SET_INT(opts, "rc_mode", self->rc_mode, AV_DICT_DONT_OVERWRITE); + } + switch (self->platform) { + case 0: + // Unconstrained --> will allow any combination of parameters (valid or invalid) + // this mode is usefull fur future platform and for debugging. + if ((self->low_power == 0) && (self->desired_b_depth)) { + AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + // max_b_frames + AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + if (self->quality >= 0) { + AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_level >= 0) { + AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_sharpness >= 0) { + AV_DICT_SET_INT(opts, + "loop_filter_sharpness", + self->loop_filter_sharpness, + AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + case 1: + // Intel + if ((self->low_power == 0) && (self->desired_b_depth)) { + AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + // max_b_frames + AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->quality >= 0) { + AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); + } + switch (self->rc_mode) { + case -1: + // same like 0 but is not sending 'rc_mode' case 0: - // Unconstrained --> will allow any combination of parameters (valid or invalid) - // this mode is usefull fur future platform and for debugging. - if ((self->low_power == 0) && (self->desired_b_depth)) { - AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - // max_b_frames - AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - if (self->quality >= 0) { - AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_level >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_sharpness >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_sharpness", self->loop_filter_sharpness, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; + // for auto --> let the driver decide as requested by documentation + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; case 1: - // Intel - if ((self->low_power == 0) && (self->desired_b_depth)) { - AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - // max_b_frames - AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->quality >= 0) { - AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); - } - switch (self->rc_mode) { - case -1: - // same like 0 but is not sending 'rc_mode' - case 0: - // for auto --> let the driver decide as requested by documentation - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 1: - case 4: - // for constant quality: CQP we use qp - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 2: - // for constant bitrate: CBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - break; - case 3: - // for variable bitrate: VBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - break; - case 5: - // for variable bitrate: QVBR we use bitrate + qp - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 6: - // for variable bitrate: AVBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - break; - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_level >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_sharpness >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_sharpness", self->loop_filter_sharpness, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; + case 4: + // for constant quality: CQP we use qp + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; case 2: - // AMD --> will allow any combination of parameters - // I am unable to confirm this platform because I don't have the HW - // Is only going to override bf to 0 (as highlited by the previous implementation) - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - AV_DICT_SET_INT(opts, "bf", 0, 0); - if (self->quality >= 0) { - AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_level >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_sharpness >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_sharpness", self->loop_filter_sharpness, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; - } - // force keyframe every 3 sec. - AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); - return 0; + // for constant bitrate: CBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + break; + case 3: + // for variable bitrate: VBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + break; + case 5: + // for variable bitrate: QVBR we use bitrate + qp + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; + case 6: + // for variable bitrate: AVBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + break; + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_level >= 0) { + AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_sharpness >= 0) { + AV_DICT_SET_INT(opts, + "loop_filter_sharpness", + self->loop_filter_sharpness, + AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + case 2: + // AMD --> will allow any combination of parameters + // I am unable to confirm this platform because I don't have the HW + // Is only going to override bf to 0 (as highlited by the previous implementation) + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + AV_DICT_SET_INT(opts, "bf", 0, 0); + if (self->quality >= 0) { + AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_level >= 0) { + AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_sharpness >= 0) { + AV_DICT_SET_INT(opts, + "loop_filter_sharpness", + self->loop_filter_sharpness, + AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + } + // force keyframe every 3 sec. + AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); + return 0; } - static const codec_profile_class_t codec_profile_vaapi_vp8_class = { - { - .ic_super = (idclass_t *)&codec_profile_vaapi_class, - .ic_class = "codec_profile_vaapi_vp8", - .ic_caption = N_("vaapi_vp8"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "quality", // Don't change - .name = N_("Global Quality"), - .desc = N_("Set encode quality [-1=skip 0-127]."), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, quality), - .intextra = INTEXTRA_RANGE(-1, 127, 1), - .def.i = 40, - }, - { - .type = PT_INT, - .id = "loop_filter_level", // Don't change - .name = N_("Loop filter level"), - .desc = N_("Set Loop filter level (-1=skip from 0 to 63) [default 16]"), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, loop_filter_level), - .intextra = INTEXTRA_RANGE(-1, 63, 1), - .def.i = 16, - }, - { - .type = PT_INT, - .id = "loop_filter_sharpness", // Don't change - .name = N_("Loop filter sharpness"), - .desc = N_("Set Loop filter sharpness (-1=skip from 0 to 15) [default 4]"), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, loop_filter_sharpness), - .intextra = INTEXTRA_RANGE(-1, 15, 1), - .def.i = 4, - }, - {} - } - }, + {.ic_super = (idclass_t*)&codec_profile_vaapi_class, + .ic_class = "codec_profile_vaapi_vp8", + .ic_caption = N_("vaapi_vp8"), + .ic_properties = + (const property_t[]){{ + .type = PT_INT, + .id = "quality", // Don't change + .name = N_("Global Quality"), + .desc = N_("Set encode quality [-1=skip 0-127]."), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, quality), + .intextra = INTEXTRA_RANGE(-1, 127, 1), + .def.i = 40, + }, + { + .type = PT_INT, + .id = "loop_filter_level", // Don't change + .name = N_("Loop filter level"), + .desc = N_("Set Loop filter level (-1=skip from 0 to 63) [default 16]"), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, loop_filter_level), + .intextra = INTEXTRA_RANGE(-1, 63, 1), + .def.i = 16, + }, + { + .type = PT_INT, + .id = "loop_filter_sharpness", // Don't change + .name = N_("Loop filter sharpness"), + .desc = N_("Set Loop filter sharpness (-1=skip from 0 to 15) [default 4]"), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, loop_filter_sharpness), + .intextra = INTEXTRA_RANGE(-1, 15, 1), + .def.i = 4, + }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_vaapi_vp8_open, }; - TVHVideoCodec tvh_codec_vaapi_vp8 = { - .name = "vp8_vaapi", - .size = sizeof(tvh_codec_profile_vaapi_t), - .idclass = &codec_profile_vaapi_vp8_class, - .profiles = vaapi_vp8_profiles, - .profile_init = tvh_codec_profile_video_init, + .name = "vp8_vaapi", + .size = sizeof(tvh_codec_profile_vaapi_t), + .idclass = &codec_profile_vaapi_vp8_class, + .profiles = vaapi_vp8_profiles, + .profile_init = tvh_codec_profile_video_init, .profile_destroy = tvh_codec_profile_video_destroy, }; /* vp9_vaapi =============================================================== */ static const AVProfile vaapi_vp9_profiles[] = { - { FF_PROFILE_UNKNOWN }, + {FF_PROFILE_UNKNOWN}, }; -static int -tvh_codec_profile_vaapi_vp9_open(tvh_codec_profile_vaapi_t *self, - AVDictionary **opts) -{ - // to avoid issues we have this check: - if (self->buff_factor <= 0) { - self->buff_factor = 3; - } - int int_bitrate = (int)((double)(self->bit_rate) * 1024.0 * (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); - int int_buffer_size = (int)((double)(self->bit_rate) * 2048.0 * self->buff_factor * (1.0 + self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480)); - int int_max_bitrate = (int)((double)(self->max_bit_rate) * 1024.0 * (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); - tvhinfo(LS_VAAPI, "Bitrate = %d kbps; Buffer size = %d kbps; Max bitrate = %d kbps", int_bitrate / 1024, int_buffer_size / 1024, int_max_bitrate / 1024); - // https://wiki.libav.org/Hardware/vaapi - // to find available parameters use: - // ffmpeg -hide_banner -h encoder=vp9_vaapi - // vp9_vaapi AVOptions: - // -low_power E..V....... Use low-power encoding mode (only available on some platforms; may not support all encoding features) (default false) - // -idr_interval E..V....... Distance (in I-frames) between IDR frames (from 0 to INT_MAX) (default 0) - // -b_depth E..V....... Maximum B-frame reference depth (from 1 to INT_MAX) (default 1) - // -rc_mode E..V....... Set rate control mode (from 0 to 6) (default auto) - // auto 0 E..V....... Choose mode automatically based on other parameters - // CQP 1 E..V....... Constant-quality - // CBR 2 E..V....... Constant-bitrate - // VBR 3 E..V....... Variable-bitrate - // ICQ 4 E..V....... Intelligent constant-quality - // QVBR 5 E..V....... Quality-defined variable-bitrate - // AVBR 6 E..V....... Average variable-bitrate - // -loop_filter_level E..V....... Loop filter level (from 0 to 63) (default 16) - // -loop_filter_sharpness E..V....... Loop filter sharpness (from 0 to 15) (default 4) +static int tvh_codec_profile_vaapi_vp9_open(tvh_codec_profile_vaapi_t* self, AVDictionary** opts) { + // to avoid issues we have this check: + if (self->buff_factor <= 0) { + self->buff_factor = 3; + } + int int_bitrate = (int)((double)(self->bit_rate) * 1024.0 * + (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); + int int_buffer_size = (int)((double)(self->bit_rate) * 2048.0 * self->buff_factor * + (1.0 + self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480)); + int int_max_bitrate = (int)((double)(self->max_bit_rate) * 1024.0 * + (1.0 + (self->bit_rate_scale_factor * ((double)(self->size.den) - 480.0) / 480.0))); + tvhinfo(LS_VAAPI, + "Bitrate = %d kbps; Buffer size = %d kbps; Max bitrate = %d kbps", + int_bitrate / 1024, + int_buffer_size / 1024, + int_max_bitrate / 1024); + // https://wiki.libav.org/Hardware/vaapi + // to find available parameters use: + // ffmpeg -hide_banner -h encoder=vp9_vaapi + // vp9_vaapi AVOptions: + // -low_power E..V....... Use low-power encoding mode (only available on some + // platforms; may not support all encoding features) (default false) -idr_interval + // E..V....... Distance (in I-frames) between IDR frames (from 0 to INT_MAX) (default 0) -b_depth + // E..V....... Maximum B-frame reference depth (from 1 to INT_MAX) (default 1) + // -rc_mode E..V....... Set rate control mode (from 0 to 6) (default auto) + // auto 0 E..V....... Choose mode automatically based on other parameters + // CQP 1 E..V....... Constant-quality + // CBR 2 E..V....... Constant-bitrate + // VBR 3 E..V....... Variable-bitrate + // ICQ 4 E..V....... Intelligent constant-quality + // QVBR 5 E..V....... Quality-defined variable-bitrate + // AVBR 6 E..V....... Average variable-bitrate + // -loop_filter_level E..V....... Loop filter level (from 0 to 63) (default 16) + // -loop_filter_sharpness E..V....... Loop filter sharpness (from 0 to 15) (default + // 4) - if (self->rc_mode >= 0) { - AV_DICT_SET_INT(opts, "rc_mode", self->rc_mode, AV_DICT_DONT_OVERWRITE); - } - switch (self->platform) { + if (self->rc_mode >= 0) { + AV_DICT_SET_INT(opts, "rc_mode", self->rc_mode, AV_DICT_DONT_OVERWRITE); + } + switch (self->platform) { + case 0: + // Unconstrained --> will allow any combination of parameters (valid or invalid) + // this mode is usefull fur future platform and for debugging. + if ((self->low_power == 0) && (self->desired_b_depth)) { + AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + // max_b_frames + AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->super_frame) { + // according to example from https://trac.ffmpeg.org/wiki/Hardware/VAAPI + // -bsf:v vp9_raw_reorder,vp9_superframe + AV_DICT_SET(opts, "bsf", "vp9_raw_reorder,vp9_superframe", AV_DICT_DONT_OVERWRITE); + } + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + if (self->quality >= 0) { + AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_level >= 0) { + AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_sharpness >= 0) { + AV_DICT_SET_INT(opts, + "loop_filter_sharpness", + self->loop_filter_sharpness, + AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + case 1: + // Intel + if ((self->low_power == 0) && (self->desired_b_depth)) { + AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + // max_b_frames + AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->super_frame) { + // according to example from https://trac.ffmpeg.org/wiki/Hardware/VAAPI + // -bsf:v vp9_raw_reorder,vp9_superframe + AV_DICT_SET(opts, "bsf", "vp9_raw_reorder,vp9_superframe", AV_DICT_DONT_OVERWRITE); + } + if (self->quality >= 0) { + AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); + } + switch (self->rc_mode) { + case -1: + // same like 0 but is not sending 'rc_mode' case 0: - // Unconstrained --> will allow any combination of parameters (valid or invalid) - // this mode is usefull fur future platform and for debugging. - if ((self->low_power == 0) && (self->desired_b_depth)) { - AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - // max_b_frames - AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->super_frame) { - // according to example from https://trac.ffmpeg.org/wiki/Hardware/VAAPI - // -bsf:v vp9_raw_reorder,vp9_superframe - AV_DICT_SET(opts, "bsf", "vp9_raw_reorder,vp9_superframe", AV_DICT_DONT_OVERWRITE); - } - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - if (self->quality >= 0) { - AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_level >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_sharpness >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_sharpness", self->loop_filter_sharpness, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; + // for auto --> let the driver decide as requested by documentation + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; case 1: - // Intel - if ((self->low_power == 0) && (self->desired_b_depth)) { - AV_DICT_SET_INT(opts, "b_depth", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - // max_b_frames - AV_DICT_SET_INT(opts, "bf", self->desired_b_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->super_frame) { - // according to example from https://trac.ffmpeg.org/wiki/Hardware/VAAPI - // -bsf:v vp9_raw_reorder,vp9_superframe - AV_DICT_SET(opts, "bsf", "vp9_raw_reorder,vp9_superframe", AV_DICT_DONT_OVERWRITE); - } - if (self->quality >= 0) { - AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); - } - switch (self->rc_mode) { - case -1: - // same like 0 but is not sending 'rc_mode' - case 0: - // for auto --> let the driver decide as requested by documentation - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 1: - case 4: - // for constant quality: CQP we use qp - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 2: - // for constant bitrate: CBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - break; - case 3: - // for variable bitrate: VBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - break; - case 5: - // for variable bitrate: QVBR we use bitrate + qp - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - break; - case 6: - // for variable bitrate: AVBR we use bitrate - if (self->bit_rate && self->buff_factor) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - break; - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_level >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_sharpness >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_sharpness", self->loop_filter_sharpness, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; + case 4: + // for constant quality: CQP we use qp + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; case 2: - // AMD --> will allow any combination of parameters - // I am unable to confirm this platform because I don't have the HW - // Is only going to override bf to 0 (as highlited by the previous implementation) - if (self->bit_rate) { - AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); - AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); - } - if (self->max_bit_rate) { - AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); - } - if (self->qp) { - AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); - } - AV_DICT_SET_INT(opts, "bf", 0, 0); - if (self->quality >= 0) { - AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); - } - if (self->low_power) { - AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_level >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); - } - if (self->loop_filter_sharpness >= 0) { - AV_DICT_SET_INT(opts, "loop_filter_sharpness", self->loop_filter_sharpness, AV_DICT_DONT_OVERWRITE); - } - if (self->async_depth) { - AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); - } - if (self->qmin) { - AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); - } - if (self->qmax) { - AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); - } - break; - } - // force keyframe every 3 sec. - AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); - return 0; + // for constant bitrate: CBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + break; + case 3: + // for variable bitrate: VBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + break; + case 5: + // for variable bitrate: QVBR we use bitrate + qp + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + break; + case 6: + // for variable bitrate: AVBR we use bitrate + if (self->bit_rate && self->buff_factor) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + break; + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_level >= 0) { + AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_sharpness >= 0) { + AV_DICT_SET_INT(opts, + "loop_filter_sharpness", + self->loop_filter_sharpness, + AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + case 2: + // AMD --> will allow any combination of parameters + // I am unable to confirm this platform because I don't have the HW + // Is only going to override bf to 0 (as highlited by the previous implementation) + if (self->bit_rate) { + AV_DICT_SET_INT(opts, "b", int_bitrate, AV_DICT_DONT_OVERWRITE); + AV_DICT_SET_INT(opts, "bufsize", int_buffer_size, AV_DICT_DONT_OVERWRITE); + } + if (self->max_bit_rate) { + AV_DICT_SET_INT(opts, "maxrate", int_max_bitrate, AV_DICT_DONT_OVERWRITE); + } + if (self->qp) { + AV_DICT_SET_INT(opts, "qp", self->qp, AV_DICT_DONT_OVERWRITE); + } + AV_DICT_SET_INT(opts, "bf", 0, 0); + if (self->quality >= 0) { + AV_DICT_SET_INT(opts, "global_quality", self->quality, AV_DICT_DONT_OVERWRITE); + } + if (self->low_power) { + AV_DICT_SET_INT(opts, "low_power", self->low_power, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_level >= 0) { + AV_DICT_SET_INT(opts, "loop_filter_level", self->loop_filter_level, AV_DICT_DONT_OVERWRITE); + } + if (self->loop_filter_sharpness >= 0) { + AV_DICT_SET_INT(opts, + "loop_filter_sharpness", + self->loop_filter_sharpness, + AV_DICT_DONT_OVERWRITE); + } + if (self->async_depth) { + AV_DICT_SET_INT(opts, "async_depth", self->async_depth, AV_DICT_DONT_OVERWRITE); + } + if (self->qmin) { + AV_DICT_SET_INT(opts, "qmin", self->qmin, AV_DICT_DONT_OVERWRITE); + } + if (self->qmax) { + AV_DICT_SET_INT(opts, "qmax", self->qmax, AV_DICT_DONT_OVERWRITE); + } + break; + } + // force keyframe every 3 sec. + AV_DICT_SET(opts, "force_key_frames", "expr:gte(t,n_forced*3)", AV_DICT_DONT_OVERWRITE); + return 0; } - static const codec_profile_class_t codec_profile_vaapi_vp9_class = { - { - .ic_super = (idclass_t *)&codec_profile_vaapi_class, - .ic_class = "codec_profile_vaapi_vp9", - .ic_caption = N_("vaapi_vp9"), - .ic_properties = (const property_t[]){ - { - .type = PT_INT, - .id = "quality", // Don't change - .name = N_("Global Quality"), - .desc = N_("Set encode quality [-1=skip 0-255]."), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, quality), - .intextra = INTEXTRA_RANGE(-1, 255, 1), - .def.i = 40, - }, - { - .type = PT_INT, - .id = "loop_filter_level", // Don't change - .name = N_("Loop filter level"), - .desc = N_("Set Loop filter level (-1=skip from 0 to 63) [default 16]"), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, loop_filter_level), - .intextra = INTEXTRA_RANGE(-1, 63, 1), - .def.i = 16, - }, - { - .type = PT_INT, - .id = "loop_filter_sharpness", // Don't change - .name = N_("Loop filter sharpness"), - .desc = N_("Set Loop filter sharpness (-1=skip from 0 to 15) [default 4]"), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, loop_filter_sharpness), - .intextra = INTEXTRA_RANGE(-1, 15, 1), - .def.i = 4, - }, - { - .type = PT_BOOL, - .id = "super_frame", // Don't change - .name = N_("Super Frame"), - .desc = N_("Enable Super Frame for vp9 encoder.[default disabled]"), - .group = 5, - .opts = PO_EXPERT, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(tvh_codec_profile_vaapi_t, super_frame), - .def.i = 0, - }, - {} - } - }, + {.ic_super = (idclass_t*)&codec_profile_vaapi_class, + .ic_class = "codec_profile_vaapi_vp9", + .ic_caption = N_("vaapi_vp9"), + .ic_properties = + (const property_t[]){{ + .type = PT_INT, + .id = "quality", // Don't change + .name = N_("Global Quality"), + .desc = N_("Set encode quality [-1=skip 0-255]."), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, quality), + .intextra = INTEXTRA_RANGE(-1, 255, 1), + .def.i = 40, + }, + { + .type = PT_INT, + .id = "loop_filter_level", // Don't change + .name = N_("Loop filter level"), + .desc = N_("Set Loop filter level (-1=skip from 0 to 63) [default 16]"), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, loop_filter_level), + .intextra = INTEXTRA_RANGE(-1, 63, 1), + .def.i = 16, + }, + { + .type = PT_INT, + .id = "loop_filter_sharpness", // Don't change + .name = N_("Loop filter sharpness"), + .desc = N_("Set Loop filter sharpness (-1=skip from 0 to 15) [default 4]"), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, loop_filter_sharpness), + .intextra = INTEXTRA_RANGE(-1, 15, 1), + .def.i = 4, + }, + { + .type = PT_BOOL, + .id = "super_frame", // Don't change + .name = N_("Super Frame"), + .desc = N_("Enable Super Frame for vp9 encoder.[default disabled]"), + .group = 5, + .opts = PO_EXPERT, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(tvh_codec_profile_vaapi_t, super_frame), + .def.i = 0, + }, + {}}}, .open = (codec_profile_open_meth)tvh_codec_profile_vaapi_vp9_open, }; - TVHVideoCodec tvh_codec_vaapi_vp9 = { - .name = "vp9_vaapi", - .size = sizeof(tvh_codec_profile_vaapi_t), - .idclass = &codec_profile_vaapi_vp9_class, - .profiles = vaapi_vp9_profiles, - .profile_init = tvh_codec_profile_video_init, + .name = "vp9_vaapi", + .size = sizeof(tvh_codec_profile_vaapi_t), + .idclass = &codec_profile_vaapi_vp9_class, + .profiles = vaapi_vp9_profiles, + .profile_init = tvh_codec_profile_video_init, .profile_destroy = tvh_codec_profile_video_destroy, }; diff --git a/src/transcoding/codec/codecs/mp2.c b/src/transcoding/codec/codecs/mp2.c index e26ad3eb8..77f35ecb3 100644 --- a/src/transcoding/codec/codecs/mp2.c +++ b/src/transcoding/codec/codecs/mp2.c @@ -17,61 +17,48 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" - /* mp2 ====================================================================== */ -static int -tvh_codec_profile_mp2_open(TVHCodecProfile *self, AVDictionary **opts) -{ - AV_DICT_SET_TVH_REQUIRE_META(opts, 0); - // bit_rate - if (self->bit_rate) { - AV_DICT_SET_BIT_RATE(opts, self->bit_rate); - } - return 0; +static int tvh_codec_profile_mp2_open(TVHCodecProfile* self, AVDictionary** opts) { + AV_DICT_SET_TVH_REQUIRE_META(opts, 0); + // bit_rate + if (self->bit_rate) { + AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + } + return 0; } - -static htsmsg_t * -codec_profile_mp2_class_bit_rate_list(void *obj, const char *lang) -{ - // This is a place holder. - // The real list is set in src/webui/static/app/codec.js - return htsmsg_create_list(); +static htsmsg_t* codec_profile_mp2_class_bit_rate_list(void* obj, const char* lang) { + // This is a place holder. + // The real list is set in src/webui/static/app/codec.js + return htsmsg_create_list(); } - static const codec_profile_class_t codec_profile_mp2_class = { - { - .ic_super = (idclass_t *)&codec_profile_audio_class, + {.ic_super = (idclass_t*)&codec_profile_audio_class, .ic_class = "codec_profile_mp2", .ic_caption = N_("mp2"), - .ic_properties = (const property_t[]){ - { - .type = PT_DBL, - .id = "bit_rate", - .name = N_("Bitrate (kb/s)"), - .desc = N_("Constant bitrate (CBR) mode."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, bit_rate), - .list = codec_profile_mp2_class_bit_rate_list, - .def.d = 0, - }, - {} - } - }, + .ic_properties = (const property_t[]){{ + .type = PT_DBL, + .id = "bit_rate", + .name = N_("Bitrate (kb/s)"), + .desc = N_("Constant bitrate (CBR) mode."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, bit_rate), + .list = codec_profile_mp2_class_bit_rate_list, + .def.d = 0, + }, + {}}}, .open = tvh_codec_profile_mp2_open, }; - TVHAudioCodec tvh_codec_mp2 = { - .name = "mp2", - .size = sizeof(TVHAudioCodecProfile), - .idclass = &codec_profile_mp2_class, - .profile_init = tvh_codec_profile_audio_init, + .name = "mp2", + .size = sizeof(TVHAudioCodecProfile), + .idclass = &codec_profile_mp2_class, + .profile_init = tvh_codec_profile_audio_init, .profile_destroy = tvh_codec_profile_audio_destroy, }; diff --git a/src/transcoding/codec/codecs/mpeg2video.c b/src/transcoding/codec/codecs/mpeg2video.c index d50601f87..6aeba272e 100644 --- a/src/transcoding/codec/codecs/mpeg2video.c +++ b/src/transcoding/codec/codecs/mpeg2video.c @@ -17,42 +17,34 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" - /* mpeg2video =============================================================== */ -static int -tvh_codec_profile_mpeg2video_open(TVHCodecProfile *self, AVDictionary **opts) -{ - // bit_rate or global_quality - if (self->bit_rate) { - AV_DICT_SET_BIT_RATE(opts, self->bit_rate); - } - else { - AV_DICT_SET_GLOBAL_QUALITY(opts, self->qscale, 5); - } - return 0; +static int tvh_codec_profile_mpeg2video_open(TVHCodecProfile* self, AVDictionary** opts) { + // bit_rate or global_quality + if (self->bit_rate) { + AV_DICT_SET_BIT_RATE(opts, self->bit_rate); + } else { + AV_DICT_SET_GLOBAL_QUALITY(opts, self->qscale, 5); + } + return 0; } - static const codec_profile_class_t codec_profile_mpeg2video_class = { - { - .ic_super = (idclass_t *)&codec_profile_video_class, + {.ic_super = (idclass_t*)&codec_profile_video_class, .ic_class = "codec_profile_mpeg2video", .ic_caption = N_("mpeg2video"), - .ic_properties = (const property_t[]){ - { - .type = PT_DBL, - .id = "bit_rate", - .name = N_("Bitrate (kb/s) (0=auto)"), - .desc = N_("Constant bitrate (CBR) mode."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, bit_rate), - .def.d = 0, - }, + .ic_properties = (const property_t[]){{ + .type = PT_DBL, + .id = "bit_rate", + .name = N_("Bitrate (kb/s) (0=auto)"), + .desc = N_("Constant bitrate (CBR) mode."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, bit_rate), + .def.d = 0, + }, { .type = PT_DBL, .id = "qscale", @@ -64,17 +56,14 @@ static const codec_profile_class_t codec_profile_mpeg2video_class = { .intextra = INTEXTRA_RANGE(0, 31, 1), .def.d = 0, }, - {} - } - }, + {}}}, .open = tvh_codec_profile_mpeg2video_open, }; - TVHVideoCodec tvh_codec_mpeg2video = { - .name = "mpeg2video", - .size = sizeof(TVHVideoCodecProfile), - .idclass = &codec_profile_mpeg2video_class, - .profile_init = tvh_codec_profile_video_init, + .name = "mpeg2video", + .size = sizeof(TVHVideoCodecProfile), + .idclass = &codec_profile_mpeg2video_class, + .profile_init = tvh_codec_profile_video_init, .profile_destroy = tvh_codec_profile_video_destroy, }; diff --git a/src/transcoding/codec/codecs/vorbis.c b/src/transcoding/codec/codecs/vorbis.c index abd35d51e..6a0315b05 100644 --- a/src/transcoding/codec/codecs/vorbis.c +++ b/src/transcoding/codec/codecs/vorbis.c @@ -17,51 +17,37 @@ * along with this program. If not, see . */ - #include "transcoding/codec/internals.h" - /* vorbis =================================================================== */ -static int -tvh_codec_profile_vorbis_open(TVHCodecProfile *self, AVDictionary **opts) -{ - AV_DICT_SET_GLOBAL_QUALITY(opts, self->qscale, 5); - return 0; +static int tvh_codec_profile_vorbis_open(TVHCodecProfile* self, AVDictionary** opts) { + AV_DICT_SET_GLOBAL_QUALITY(opts, self->qscale, 5); + return 0; } - // see vorbis_encode_init() in ffmpeg-3.0.2/libavcodec/vorbisenc.c -static const uint64_t vorbis_channel_layouts[] = { - AV_CH_LAYOUT_STEREO, - 0 -}; - +static const uint64_t vorbis_channel_layouts[] = {AV_CH_LAYOUT_STEREO, 0}; static const codec_profile_class_t codec_profile_vorbis_class = { - { - .ic_super = (idclass_t *)&codec_profile_audio_class, + {.ic_super = (idclass_t*)&codec_profile_audio_class, .ic_class = "codec_profile_vorbis", .ic_caption = N_("vorbis"), - .ic_properties = (const property_t[]){ - { - .type = PT_DBL, - .id = "qscale", - .name = N_("Quality (0=auto)"), - .desc = N_("Variable bitrate (VBR) mode [0-10]."), - .group = 3, - .get_opts = codec_profile_class_get_opts, - .off = offsetof(TVHCodecProfile, qscale), - .intextra = INTEXTRA_RANGE(0, 10, 1), - .def.d = 0, - }, - {} - } - }, + .ic_properties = (const property_t[]){{ + .type = PT_DBL, + .id = "qscale", + .name = N_("Quality (0=auto)"), + .desc = N_("Variable bitrate (VBR) mode [0-10]."), + .group = 3, + .get_opts = codec_profile_class_get_opts, + .off = offsetof(TVHCodecProfile, qscale), + .intextra = INTEXTRA_RANGE(0, 10, 1), + .def.d = 0, + }, + {}}}, .open = tvh_codec_profile_vorbis_open, }; - TVHAudioCodec tvh_codec_vorbis = { .name = "vorbis", .size = sizeof(TVHAudioCodecProfile), diff --git a/src/transcoding/codec/internals.h b/src/transcoding/codec/internals.h index f7a7ac96c..70cb84324 100644 --- a/src/transcoding/codec/internals.h +++ b/src/transcoding/codec/internals.h @@ -17,23 +17,20 @@ * along with this program. If not, see . */ - #ifndef TVH_TRANSCODING_CODEC_INTERNALS_H__ #define TVH_TRANSCODING_CODEC_INTERNALS_H__ - #include "transcoding/codec.h" #include "transcoding/memutils.h" - #define AUTO_STR "auto" #define ADD_ENTRY(l, m, kt, k, vt, v) \ - do { \ - htsmsg_add_##kt((m), "key", (k)); \ - htsmsg_add_##vt((m), "val", (v)); \ - htsmsg_add_msg((l), NULL, (m)); \ - } while (0) + do { \ + htsmsg_add_##kt((m), "key", (k)); \ + htsmsg_add_##vt((m), "val", (v)); \ + htsmsg_add_msg((l), NULL, (m)); \ + } while (0) #define ADD_VAL(l, m, t, v) ADD_ENTRY(l, m, t, v, t, v) @@ -42,197 +39,157 @@ #define ADD_U32_VAL(l, m, v) ADD_VAL(l, m, u32, v) #define ADD_S64_VAL(l, m, v) ADD_VAL(l, m, s64, v) - #define _tvh_codec_get_opts(c, a, o, T) \ - ((c) ? tvh_codec_base_get_opts((c), (o), ((((T *)(c))->a) != NULL)) : (o)) + ((c) ? tvh_codec_base_get_opts((c), (o), ((((T*)(c))->a) != NULL)) : (o)) -#define tvh_codec_get_opts(c, a, o) \ - _tvh_codec_get_opts(c, a, o, TVHCodec) +#define tvh_codec_get_opts(c, a, o) _tvh_codec_get_opts(c, a, o, TVHCodec) -#define tvh_codec_video_get_opts(c, a, o) \ - _tvh_codec_get_opts(c, a, o, TVHVideoCodec) - -#define tvh_codec_audio_get_opts(c, a, o) \ - _tvh_codec_get_opts(c, a, o, TVHAudioCodec) +#define tvh_codec_video_get_opts(c, a, o) _tvh_codec_get_opts(c, a, o, TVHVideoCodec) +#define tvh_codec_audio_get_opts(c, a, o) _tvh_codec_get_opts(c, a, o, TVHAudioCodec) #define _tvh_codec_get_list(c, a, T, n) \ - (((c) && tvh_codec_is_enabled((c))) ? tvh_codec##n##get_list_##a(((T *)(c))) : NULL) - -#define tvh_codec_get_list(c, a) \ - _tvh_codec_get_list(c, a, TVHCodec, _) + (((c) && tvh_codec_is_enabled((c))) ? tvh_codec##n##get_list_##a(((T*)(c))) : NULL) -#define tvh_codec_video_get_list(c, a) \ - _tvh_codec_get_list(c, a, TVHVideoCodec, _video_) +#define tvh_codec_get_list(c, a) _tvh_codec_get_list(c, a, TVHCodec, _) -#define tvh_codec_audio_get_list(c, a) \ - _tvh_codec_get_list(c, a, TVHAudioCodec, _audio_) +#define tvh_codec_video_get_list(c, a) _tvh_codec_get_list(c, a, TVHVideoCodec, _video_) +#define tvh_codec_audio_get_list(c, a) _tvh_codec_get_list(c, a, TVHAudioCodec, _audio_) #define _tvh_codec_getattr(c, a, t, T) \ - (((c) && tvh_codec_is_enabled((c)) && tvh_codec_get_type((c)) == (t)) ? (((T *)(c))->a) : NULL) + (((c) && tvh_codec_is_enabled((c)) && tvh_codec_get_type((c)) == (t)) ? (((T*)(c))->a) : NULL) -#define tvh_codec_video_getattr(c, a) \ - _tvh_codec_getattr(c, a, AVMEDIA_TYPE_VIDEO, TVHVideoCodec) +#define tvh_codec_video_getattr(c, a) _tvh_codec_getattr(c, a, AVMEDIA_TYPE_VIDEO, TVHVideoCodec) -#define tvh_codec_audio_getattr(c, a) \ - _tvh_codec_getattr(c, a, AVMEDIA_TYPE_AUDIO, TVHAudioCodec) +#define tvh_codec_audio_getattr(c, a) _tvh_codec_getattr(c, a, AVMEDIA_TYPE_AUDIO, TVHAudioCodec) +#define AV_DICT_SET(d, k, v, f) \ + do { \ + if (av_dict_set((d), (k), (v), (f)) < 0) { \ + return -1; \ + } \ + } while (0) -#define AV_DICT_SET(d, k, v, f) \ - do { \ - if (av_dict_set((d), (k), (v), (f)) < 0) { \ - return -1; \ - } \ - } while (0) - -#define AV_DICT_SET_INT(d, k, v, f) \ - do { \ - if (av_dict_set_int((d), (k), (v), (f)) < 0) { \ - return -1; \ - } \ - } while (0) +#define AV_DICT_SET_INT(d, k, v, f) \ + do { \ + if (av_dict_set_int((d), (k), (v), (f)) < 0) { \ + return -1; \ + } \ + } while (0) #define AV_DICT_SET_TVH_REQUIRE_META(d, v) \ - AV_DICT_SET_INT((d), "tvh_require_meta", (v), AV_DICT_DONT_OVERWRITE) + AV_DICT_SET_INT((d), "tvh_require_meta", (v), AV_DICT_DONT_OVERWRITE) -#define AV_DICT_SET_FLAGS(d, v) \ - AV_DICT_SET((d), "flags", (v), AV_DICT_APPEND) +#define AV_DICT_SET_FLAGS(d, v) AV_DICT_SET((d), "flags", (v), AV_DICT_APPEND) -#define AV_DICT_SET_FLAGS_GLOBAL_HEADER(d) \ - AV_DICT_SET_FLAGS((d), "+global_header") +#define AV_DICT_SET_FLAGS_GLOBAL_HEADER(d) AV_DICT_SET_FLAGS((d), "+global_header") -#define AV_DICT_SET_BIT_RATE(d, v) \ - AV_DICT_SET_INT((d), "b", (v) * 1000, AV_DICT_DONT_OVERWRITE) +#define AV_DICT_SET_BIT_RATE(d, v) AV_DICT_SET_INT((d), "b", (v) * 1000, AV_DICT_DONT_OVERWRITE) #define AV_DICT_SET_GLOBAL_QUALITY(d, v, a) \ - do { \ - AV_DICT_SET_FLAGS((d), "+qscale"); \ - AV_DICT_SET_INT((d), "global_quality", ((v) ? (v) : (a)) * FF_QP2LAMBDA, \ - AV_DICT_DONT_OVERWRITE); \ - } while (0) + do { \ + AV_DICT_SET_FLAGS((d), "+qscale"); \ + AV_DICT_SET_INT((d), \ + "global_quality", \ + ((v) ? (v) : (a)) * FF_QP2LAMBDA, \ + AV_DICT_DONT_OVERWRITE); \ + } while (0) #define AV_DICT_SET_CRF(d, v, a) \ - AV_DICT_SET_INT((d), "crf", (v) ? (v) : (a), AV_DICT_DONT_OVERWRITE) + AV_DICT_SET_INT((d), "crf", (v) ? (v) : (a), AV_DICT_DONT_OVERWRITE) #define AV_DICT_SET_PIX_FMT(d, v, a) \ - AV_DICT_SET_INT((d), "pix_fmt", ((v) != AV_PIX_FMT_NONE) ? (v) : (a), \ - AV_DICT_DONT_OVERWRITE) - + AV_DICT_SET_INT((d), "pix_fmt", ((v) != AV_PIX_FMT_NONE) ? (v) : (a), AV_DICT_DONT_OVERWRITE) /* codec_profile_class ====================================================== */ -uint32_t -codec_profile_class_get_opts(void *obj, uint32_t opts); - -uint32_t -codec_profile_class_profile_get_opts(void *obj, uint32_t opts); +uint32_t codec_profile_class_get_opts(void* obj, uint32_t opts); +uint32_t codec_profile_class_profile_get_opts(void* obj, uint32_t opts); /* AVCodec ================================================================== */ -const char * -codec_get_title(const AVCodec *self); - +const char* codec_get_title(const AVCodec* self); /* TVHCodec ================================================================= */ -enum AVMediaType -tvh_codec_get_type(TVHCodec *self); +enum AVMediaType tvh_codec_get_type(TVHCodec* self); -const char * -tvh_codec_get_type_string(TVHCodec *self); +const char* tvh_codec_get_type_string(TVHCodec* self); -const AVCodec * -tvh_codec_get_codec(TVHCodec *self); +const AVCodec* tvh_codec_get_codec(TVHCodec* self); -int -tvh_codec_is_enabled(TVHCodec *self); +int tvh_codec_is_enabled(TVHCodec* self); -TVHCodec * -tvh_codec_find(const char *name); +TVHCodec* tvh_codec_find(const char* name); -void -tvh_codecs_register(void); - -void -tvh_codecs_forget(void); +void tvh_codecs_register(void); +void tvh_codecs_forget(void); /* codec_profile_class */ -uint32_t -tvh_codec_base_get_opts(TVHCodec *self, uint32_t opts, int visible); +uint32_t tvh_codec_base_get_opts(TVHCodec* self, uint32_t opts, int visible); -htsmsg_t * -tvh_codec_get_list_profiles(TVHCodec *self); +htsmsg_t* tvh_codec_get_list_profiles(TVHCodec* self); /* codec_profile_video_class */ typedef struct tvh_codec_video { - TVHCodec; - const enum AVPixelFormat *pix_fmts; + TVHCodec; + const enum AVPixelFormat* pix_fmts; } TVHVideoCodec; - /* codec_profile_audio_class */ typedef struct tvh_codec_audio { - TVHCodec; - const enum AVSampleFormat *sample_fmts; - const int *sample_rates; - const uint64_t *channel_layouts; + TVHCodec; + const enum AVSampleFormat* sample_fmts; + const int* sample_rates; + const uint64_t* channel_layouts; } TVHAudioCodec; - /* TVHCodecProfile ========================================================== */ -void -tvh_codec_profile_remove(TVHCodecProfile *self, int delete); - -TVHCodec * -tvh_codec_profile_get_codec(TVHCodecProfile *self); +void tvh_codec_profile_remove(TVHCodecProfile* self, int delete); -TVHCodecProfile * -tvh_codec_profile_find(const char *name); +TVHCodec* tvh_codec_profile_get_codec(TVHCodecProfile* self); -void -tvh_codec_profiles_load(void); +TVHCodecProfile* tvh_codec_profile_find(const char* name); -void -tvh_codec_profiles_remove(void); +void tvh_codec_profiles_load(void); +void tvh_codec_profiles_remove(void); /* video */ extern const codec_profile_class_t codec_profile_video_class; typedef struct tvh_codec_profile_video { - TVHCodecProfile; - int deinterlace; - int height; - int scaling_mode; // 0 --> up&down; 1 --> up; 2 --> down - int hwaccel; - int pix_fmt; - int crf; - AVRational size; + TVHCodecProfile; + int deinterlace; + int height; + int scaling_mode; // 0 --> up&down; 1 --> up; 2 --> down + int hwaccel; + int pix_fmt; + int crf; + AVRational size; } TVHVideoCodecProfile; - /* audio */ extern const codec_profile_class_t codec_profile_audio_class; typedef struct tvh_codec_profile_audio { - TVHCodecProfile; - int tracks; - char *language1; - char *language2; - char *language3; - int sample_fmt; - int sample_rate; - int64_t channel_layout; + TVHCodecProfile; + int tracks; + char* language1; + char* language2; + char* language3; + int sample_fmt; + int sample_rate; + int64_t channel_layout; } TVHAudioCodecProfile; - #endif // TVH_TRANSCODING_CODEC_INTERNALS_H__ diff --git a/src/transcoding/codec/module.c b/src/transcoding/codec/module.c index 8c78eda5f..d39e2c6f7 100644 --- a/src/transcoding/codec/module.c +++ b/src/transcoding/codec/module.c @@ -17,65 +17,54 @@ * along with this program. If not, see . */ - #include "internals.h" - /* module level ============================================================= */ -TVHCodecProfile * -codec_find_profile(const char *name) -{ - return name ? tvh_codec_profile_find(name) : NULL; +TVHCodecProfile* codec_find_profile(const char* name) { + return name ? tvh_codec_profile_find(name) : NULL; } +htsmsg_t* codec_get_profiles_list(enum AVMediaType media_type) { + htsmsg_t * list = NULL, *map = NULL; + TVHCodecProfile* profile = NULL; + TVHCodec* codec = NULL; -htsmsg_t * -codec_get_profiles_list(enum AVMediaType media_type) -{ - htsmsg_t *list = NULL, *map = NULL; - TVHCodecProfile *profile = NULL; - TVHCodec *codec = NULL; - - - if ((list = htsmsg_create_list())) { - LIST_FOREACH(profile, &tvh_codec_profiles, link) { - if ((codec = tvh_codec_profile_get_codec(profile)) && - tvh_codec_get_type(codec) == media_type) { - if (!(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - break; - } - ADD_ENTRY(list, map, - str, tvh_codec_profile_get_name(profile), - str, tvh_codec_profile_get_title(profile)); - } + if ((list = htsmsg_create_list())) { + LIST_FOREACH (profile, &tvh_codec_profiles, link) { + if ((codec = tvh_codec_profile_get_codec(profile)) && + tvh_codec_get_type(codec) == media_type) { + if (!(map = htsmsg_create_map())) { + htsmsg_destroy(list); + list = NULL; + break; } + ADD_ENTRY(list, + map, + str, + tvh_codec_profile_get_name(profile), + str, + tvh_codec_profile_get_title(profile)); + } } - return list; + } + return list; } - -void -codec_init(void) -{ - // codecs - tvh_codecs_register(); - // codec profiles - tvh_codec_profiles_load(); +void codec_init(void) { + // codecs + tvh_codecs_register(); + // codec profiles + tvh_codec_profiles_load(); } +void codec_done(void) { + tvh_mutex_lock(&global_lock); -void -codec_done(void) -{ - tvh_mutex_lock(&global_lock); - - // codec profiles - tvh_codec_profiles_remove(); - // codecs - tvh_codecs_forget(); + // codec profiles + tvh_codec_profiles_remove(); + // codecs + tvh_codecs_forget(); - tvh_mutex_unlock(&global_lock); + tvh_mutex_unlock(&global_lock); } diff --git a/src/transcoding/codec/profile.c b/src/transcoding/codec/profile.c index fd0514636..ce0a6194e 100644 --- a/src/transcoding/codec/profile.c +++ b/src/transcoding/codec/profile.c @@ -17,389 +17,312 @@ * along with this program. If not, see . */ - #include "internals.h" #include "settings.h" - struct TVHCodecProfiles tvh_codec_profiles; - /* TVHCodecProfile ========================================================== */ -static TVHCodecProfile * -tvh_codec_profile_alloc(TVHCodec *codec, htsmsg_t *conf) -{ - TVHCodecProfile *self = NULL; - - if ((self = calloc(1, codec->size))) { - self->codec = codec; - if (codec->profile_init) { - if (codec->profile_init(self, conf)) { - free(self); - return NULL; - } - } - } - return self; -} - +static TVHCodecProfile* tvh_codec_profile_alloc(TVHCodec* codec, htsmsg_t* conf) { + TVHCodecProfile* self = NULL; -static void -tvh_codec_profile_free(TVHCodecProfile *self) -{ - TVHCodec *codec; - - if (self) { - codec = self->codec; - if (codec && codec->profile_destroy) { - codec->profile_destroy(self); - } - free(self->name); - free(self->description); - free(self->codec_name); - free(self->device); + if ((self = calloc(1, codec->size))) { + self->codec = codec; + if (codec->profile_init) { + if (codec->profile_init(self, conf)) { free(self); + return NULL; + } } + } + return self; } +static void tvh_codec_profile_free(TVHCodecProfile* self) { + TVHCodec* codec; -static void -tvh_codec_profile_load(htsmsg_field_t *config) -{ - htsmsg_t *conf = NULL; - const char *name = NULL; - - if ((conf = htsmsg_field_get_map(config)) && - tvh_codec_profile_create(conf, htsmsg_field_name(config), 0)) { - tvherror(LS_CODEC, "unable to load codec profile: '%s'", - (name = htsmsg_get_str(conf, "name")) ? name : ""); + if (self) { + codec = self->codec; + if (codec && codec->profile_destroy) { + codec->profile_destroy(self); } + free(self->name); + free(self->description); + free(self->codec_name); + free(self->device); + free(self); + } } +static void tvh_codec_profile_load(htsmsg_field_t* config) { + htsmsg_t* conf = NULL; + const char* name = NULL; -static void -tvh_codec_profile_create2(htsmsg_field_t *config) -{ - htsmsg_t *conf = NULL; - const char *name = NULL; - - if ((conf = htsmsg_field_get_map(config)) != NULL) { - name = htsmsg_get_str(conf, "name"); - if (name == NULL) - return; - if (tvh_codec_profile_find(name)) - return; - if (tvh_codec_profile_create(conf, NULL, 1)) - tvherror(LS_CODEC, "unable to create codec profile from config tree: '%s'", - (name = htsmsg_get_str(conf, "name")) ? name : ""); - } + if ((conf = htsmsg_field_get_map(config)) && + tvh_codec_profile_create(conf, htsmsg_field_name(config), 0)) { + tvherror(LS_CODEC, + "unable to load codec profile: '%s'", + (name = htsmsg_get_str(conf, "name")) ? name : ""); + } } +static void tvh_codec_profile_create2(htsmsg_field_t* config) { + htsmsg_t* conf = NULL; + const char* name = NULL; + + if ((conf = htsmsg_field_get_map(config)) != NULL) { + name = htsmsg_get_str(conf, "name"); + if (name == NULL) + return; + if (tvh_codec_profile_find(name)) + return; + if (tvh_codec_profile_create(conf, NULL, 1)) + tvherror(LS_CODEC, + "unable to create codec profile from config tree: '%s'", + (name = htsmsg_get_str(conf, "name")) ? name : ""); + } +} -static int -tvh_codec_profile_setup(TVHCodecProfile *self, tvh_ssc_t *ssc) -{ - const idclass_t *idclass = (&self->idnode)->in_class; - const codec_profile_class_t *codec_profile_class = NULL; - int ret = 0; +static int tvh_codec_profile_setup(TVHCodecProfile* self, tvh_ssc_t* ssc) { + const idclass_t* idclass = (&self->idnode)->in_class; + const codec_profile_class_t* codec_profile_class = NULL; + int ret = 0; - while (idclass) { - codec_profile_class = (codec_profile_class_t *)idclass; - if (codec_profile_class->setup && - (ret = codec_profile_class->setup(self, ssc))) { - break; - } - idclass = idclass->ic_super; + while (idclass) { + codec_profile_class = (codec_profile_class_t*)idclass; + if (codec_profile_class->setup && (ret = codec_profile_class->setup(self, ssc))) { + break; } - return ret; + idclass = idclass->ic_super; + } + return ret; } - /* exposed */ -int -tvh_codec_profile_create(htsmsg_t *conf, const char *uuid, int save) -{ - const char *profile_name = NULL, *codec_name = NULL; - TVHCodec *codec = NULL; - TVHCodecProfile *profile = NULL; - - lock_assert(&global_lock); - - if ((!(profile_name = htsmsg_get_str(conf, "name")) || - profile_name[0] == '\0' || !strcmp(profile_name, "copy") || - strlen(profile_name) >= TVH_NAME_LEN) || - (!(codec_name = htsmsg_get_str(conf, "codec_name")) || - codec_name[0] == '\0')) { - tvherror(LS_CODEC, "missing/empty/wrong 'name' or 'codec_name'"); - return EINVAL; - } - if ((profile = tvh_codec_profile_find(profile_name))) { - tvherror(LS_CODEC, "codec profile '%s' already exists", profile_name); - return EEXIST; - } - if (!(codec = tvh_codec_find(codec_name))) { - tvherror(LS_CODEC, "codec '%s' not found", codec_name); - return ENOENT; - } - if (!(profile = tvh_codec_profile_alloc(codec, conf))) { - tvherror(LS_CODEC, "failed to allocate TVHCodecProfile"); - return ENOMEM; - } - if (idnode_insert(&profile->idnode, uuid, (idclass_t *)codec->idclass, 0)) { - tvh_codec_profile_free(profile); - tvherror(LS_CODEC, "failed to insert idnode"); - return EINVAL; - } - idnode_load(&profile->idnode, conf); - LIST_INSERT_HEAD(&tvh_codec_profiles, profile, link); - if (save) { - idnode_changed(&profile->idnode); - } - tvhinfo(LS_CODEC, "'%s' codec profile created", profile_name); - return 0; +int tvh_codec_profile_create(htsmsg_t* conf, const char* uuid, int save) { + const char * profile_name = NULL, *codec_name = NULL; + TVHCodec* codec = NULL; + TVHCodecProfile* profile = NULL; + + lock_assert(&global_lock); + + if ((!(profile_name = htsmsg_get_str(conf, "name")) || profile_name[0] == '\0' || + !strcmp(profile_name, "copy") || strlen(profile_name) >= TVH_NAME_LEN) || + (!(codec_name = htsmsg_get_str(conf, "codec_name")) || codec_name[0] == '\0')) { + tvherror(LS_CODEC, "missing/empty/wrong 'name' or 'codec_name'"); + return EINVAL; + } + if ((profile = tvh_codec_profile_find(profile_name))) { + tvherror(LS_CODEC, "codec profile '%s' already exists", profile_name); + return EEXIST; + } + if (!(codec = tvh_codec_find(codec_name))) { + tvherror(LS_CODEC, "codec '%s' not found", codec_name); + return ENOENT; + } + if (!(profile = tvh_codec_profile_alloc(codec, conf))) { + tvherror(LS_CODEC, "failed to allocate TVHCodecProfile"); + return ENOMEM; + } + if (idnode_insert(&profile->idnode, uuid, (idclass_t*)codec->idclass, 0)) { + tvh_codec_profile_free(profile); + tvherror(LS_CODEC, "failed to insert idnode"); + return EINVAL; + } + idnode_load(&profile->idnode, conf); + LIST_INSERT_HEAD(&tvh_codec_profiles, profile, link); + if (save) { + idnode_changed(&profile->idnode); + } + tvhinfo(LS_CODEC, "'%s' codec profile created", profile_name); + return 0; } +const char* tvh_codec_profile_get_status(TVHCodecProfile* self) { + TVHCodec* codec = tvh_codec_profile_get_codec(self); -const char * -tvh_codec_profile_get_status(TVHCodecProfile *self) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(self); - - if (codec && tvh_codec_is_enabled(codec)) { - return "codecEnabled"; - } - return "codecDisabled"; + if (codec && tvh_codec_is_enabled(codec)) { + return "codecEnabled"; + } + return "codecDisabled"; } - -const char * -tvh_codec_profile_get_name(TVHCodecProfile *self) -{ - return self->name; +const char* tvh_codec_profile_get_name(TVHCodecProfile* self) { + return self->name; } +const char* tvh_codec_profile_get_title(TVHCodecProfile* self) { + static __thread char profile_title[TVH_TITLE_LEN]; -const char * -tvh_codec_profile_get_title(TVHCodecProfile *self) -{ - static __thread char profile_title[TVH_TITLE_LEN]; - - memset(profile_title, 0, sizeof(profile_title)); - if (str_snprintf(profile_title, sizeof(profile_title), - (self->description && strcmp(self->description, "")) ? "%s (%s)" : "%s%s", - self->name, self->description ? self->description : "")) { - return NULL; - } - return profile_title; + memset(profile_title, 0, sizeof(profile_title)); + if (str_snprintf(profile_title, + sizeof(profile_title), + (self->description && strcmp(self->description, "")) ? "%s (%s)" : "%s%s", + self->name, + self->description ? self->description : "")) { + return NULL; + } + return profile_title; } - -const AVCodec * -tvh_codec_profile_get_avcodec(TVHCodecProfile *self) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(self); - return codec ? tvh_codec_get_codec(codec) : NULL; +const AVCodec* tvh_codec_profile_get_avcodec(TVHCodecProfile* self) { + TVHCodec* codec = tvh_codec_profile_get_codec(self); + return codec ? tvh_codec_get_codec(codec) : NULL; } - /* transcode api */ -int -tvh_codec_profile_is_copy(TVHCodecProfile *self, tvh_ssc_t *ssc) -{ - const idclass_t *idclass = NULL; - const codec_profile_class_t *codec_profile_class = NULL; - const AVCodec *avcodec = NULL; - tvh_sct_t out_type = SCT_UNKNOWN; +int tvh_codec_profile_is_copy(TVHCodecProfile* self, tvh_ssc_t* ssc) { + const idclass_t* idclass = NULL; + const codec_profile_class_t* codec_profile_class = NULL; + const AVCodec* avcodec = NULL; + tvh_sct_t out_type = SCT_UNKNOWN; - - if (tvh_codec_profile_setup(self, ssc)) { - return -1; - } - if (!(avcodec = tvh_codec_profile_get_avcodec(self))) { - tvherror(LS_CODEC, "profile '%s' is disabled", self->name); - return -1; - } - if ((out_type = codec_id2streaming_component_type(avcodec->id)) == SCT_UNKNOWN) { - tvherror(LS_CODEC, "unknown type for profile '%s'", self->name); - return -1; - } - if (out_type == ssc->es_type) { - idclass = (&self->idnode)->in_class; - while (idclass) { - codec_profile_class = (codec_profile_class_t *)idclass; - if (codec_profile_class->is_copy && - !codec_profile_class->is_copy(self, ssc)) { - return 0; - } - idclass = idclass->ic_super; - } - return 1; + if (tvh_codec_profile_setup(self, ssc)) { + return -1; + } + if (!(avcodec = tvh_codec_profile_get_avcodec(self))) { + tvherror(LS_CODEC, "profile '%s' is disabled", self->name); + return -1; + } + if ((out_type = codec_id2streaming_component_type(avcodec->id)) == SCT_UNKNOWN) { + tvherror(LS_CODEC, "unknown type for profile '%s'", self->name); + return -1; + } + if (out_type == ssc->es_type) { + idclass = (&self->idnode)->in_class; + while (idclass) { + codec_profile_class = (codec_profile_class_t*)idclass; + if (codec_profile_class->is_copy && !codec_profile_class->is_copy(self, ssc)) { + return 0; + } + idclass = idclass->ic_super; } - return 0; + return 1; + } + return 0; } +int tvh_codec_profile_open(TVHCodecProfile* self, AVDictionary** opts) { + const idclass_t* idclass = (&self->idnode)->in_class; + const codec_profile_class_t* codec_profile_class = NULL; + int ret = 0; -int -tvh_codec_profile_open(TVHCodecProfile *self, AVDictionary **opts) -{ - const idclass_t *idclass = (&self->idnode)->in_class; - const codec_profile_class_t *codec_profile_class = NULL; - int ret = 0; - - while (idclass) { - codec_profile_class = (codec_profile_class_t *)idclass; - if (codec_profile_class->open && - (ret = codec_profile_class->open(self, opts))) { - break; - } - idclass = idclass->ic_super; + while (idclass) { + codec_profile_class = (codec_profile_class_t*)idclass; + if (codec_profile_class->open && (ret = codec_profile_class->open(self, opts))) { + break; } - return ret; + idclass = idclass->ic_super; + } + return ret; } - /* video */ -int -tvh_codec_profile_video_init(TVHCodecProfile *_self, htsmsg_t *conf) -{ - TVHVideoCodecProfile *self = (TVHVideoCodecProfile *)_self; - self->pix_fmt = AV_PIX_FMT_NONE; - return 0; +int tvh_codec_profile_video_init(TVHCodecProfile* _self, htsmsg_t* conf) { + TVHVideoCodecProfile* self = (TVHVideoCodecProfile*)_self; + self->pix_fmt = AV_PIX_FMT_NONE; + return 0; } -void -tvh_codec_profile_video_destroy(TVHCodecProfile *_self) -{ -} +void tvh_codec_profile_video_destroy(TVHCodecProfile* _self) {} -int -tvh_codec_profile_video_get_hwaccel(TVHCodecProfile *self) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(self); - if (codec && tvh_codec_is_enabled(codec) && - tvh_codec_get_type(codec) == AVMEDIA_TYPE_VIDEO) { - return ((TVHVideoCodecProfile *)self)->hwaccel; - } - return -1; +int tvh_codec_profile_video_get_hwaccel(TVHCodecProfile* self) { + TVHCodec* codec = tvh_codec_profile_get_codec(self); + if (codec && tvh_codec_is_enabled(codec) && tvh_codec_get_type(codec) == AVMEDIA_TYPE_VIDEO) { + return ((TVHVideoCodecProfile*)self)->hwaccel; + } + return -1; } -const enum AVPixelFormat * -tvh_codec_profile_video_get_pix_fmts(TVHCodecProfile *self) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(self); - return tvh_codec_video_getattr(codec, pix_fmts); +const enum AVPixelFormat* tvh_codec_profile_video_get_pix_fmts(TVHCodecProfile* self) { + TVHCodec* codec = tvh_codec_profile_get_codec(self); + return tvh_codec_video_getattr(codec, pix_fmts); } - /* audio */ -int -tvh_codec_profile_audio_init(TVHCodecProfile *_self, htsmsg_t *conf) -{ - TVHAudioCodecProfile *self = (TVHAudioCodecProfile *)_self; - self->sample_fmt = AV_SAMPLE_FMT_NONE; - self->tracks = 1; - return 0; +int tvh_codec_profile_audio_init(TVHCodecProfile* _self, htsmsg_t* conf) { + TVHAudioCodecProfile* self = (TVHAudioCodecProfile*)_self; + self->sample_fmt = AV_SAMPLE_FMT_NONE; + self->tracks = 1; + return 0; } -void -tvh_codec_profile_audio_destroy(TVHCodecProfile *_self) -{ - TVHAudioCodecProfile *self = (TVHAudioCodecProfile *)_self; - free(self->language1); - free(self->language2); - free(self->language3); +void tvh_codec_profile_audio_destroy(TVHCodecProfile* _self) { + TVHAudioCodecProfile* self = (TVHAudioCodecProfile*)_self; + free(self->language1); + free(self->language2); + free(self->language3); } -const enum AVSampleFormat * -tvh_codec_profile_audio_get_sample_fmts(TVHCodecProfile *self) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(self); - return tvh_codec_audio_getattr(codec, sample_fmts); +const enum AVSampleFormat* tvh_codec_profile_audio_get_sample_fmts(TVHCodecProfile* self) { + TVHCodec* codec = tvh_codec_profile_get_codec(self); + return tvh_codec_audio_getattr(codec, sample_fmts); } -const int * -tvh_codec_profile_audio_get_sample_rates(TVHCodecProfile *self) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(self); - return tvh_codec_audio_getattr(codec, sample_rates); +const int* tvh_codec_profile_audio_get_sample_rates(TVHCodecProfile* self) { + TVHCodec* codec = tvh_codec_profile_get_codec(self); + return tvh_codec_audio_getattr(codec, sample_rates); } -const uint64_t * -tvh_codec_profile_audio_get_channel_layouts(TVHCodecProfile *self) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(self); - return tvh_codec_audio_getattr(codec, channel_layouts); +const uint64_t* tvh_codec_profile_audio_get_channel_layouts(TVHCodecProfile* self) { + TVHCodec* codec = tvh_codec_profile_get_codec(self); + return tvh_codec_audio_getattr(codec, channel_layouts); } - /* internal api */ -void -tvh_codec_profile_remove(TVHCodecProfile *self, int delete) -{ - char uuid[UUID_HEX_SIZE]; - - memset(uuid, 0, sizeof(uuid)); - idnode_save_check(&self->idnode, delete); - if (delete) { - hts_settings_remove("codec/%s", idnode_uuid_as_str(&self->idnode, uuid)); - } - LIST_REMOVE(self, link); - idnode_unlink(&self->idnode); - tvh_codec_profile_free(self); +void tvh_codec_profile_remove(TVHCodecProfile* self, int delete) { + char uuid[UUID_HEX_SIZE]; + + memset(uuid, 0, sizeof(uuid)); + idnode_save_check(&self->idnode, delete); + if (delete) { + hts_settings_remove("codec/%s", idnode_uuid_as_str(&self->idnode, uuid)); + } + LIST_REMOVE(self, link); + idnode_unlink(&self->idnode); + tvh_codec_profile_free(self); } - -TVHCodec * -tvh_codec_profile_get_codec(TVHCodecProfile *self) -{ - return self ? self->codec : NULL; +TVHCodec* tvh_codec_profile_get_codec(TVHCodecProfile* self) { + return self ? self->codec : NULL; } +TVHCodecProfile* tvh_codec_profile_find(const char* name) { + TVHCodecProfile* profile = NULL; -TVHCodecProfile * -tvh_codec_profile_find(const char *name) -{ - TVHCodecProfile *profile = NULL; - - LIST_FOREACH(profile, &tvh_codec_profiles, link) { - if (!strcmp(profile->name, name)) { - return profile; - } + LIST_FOREACH (profile, &tvh_codec_profiles, link) { + if (!strcmp(profile->name, name)) { + return profile; } - return NULL; + } + return NULL; } +void tvh_codec_profiles_load() { + htsmsg_t* settings = NULL; + htsmsg_field_t* config = NULL; -void -tvh_codec_profiles_load() -{ - htsmsg_t *settings = NULL; - htsmsg_field_t *config = NULL; - - LIST_INIT(&tvh_codec_profiles); - if ((settings = hts_settings_load("codec"))) { - HTSMSG_FOREACH(config, settings) { - tvh_codec_profile_load(config); - } - htsmsg_destroy(settings); + LIST_INIT(&tvh_codec_profiles); + if ((settings = hts_settings_load("codec"))) { + HTSMSG_FOREACH(config, settings) { + tvh_codec_profile_load(config); } - if ((settings = hts_settings_load("transcoder/codecs"))) { - HTSMSG_FOREACH(config, settings) { - tvh_codec_profile_create2(config); - } - htsmsg_destroy(settings); + htsmsg_destroy(settings); + } + if ((settings = hts_settings_load("transcoder/codecs"))) { + HTSMSG_FOREACH(config, settings) { + tvh_codec_profile_create2(config); } + htsmsg_destroy(settings); + } } - -void -tvh_codec_profiles_remove() -{ - tvhinfo(LS_CODEC, "removing codec profiles"); - while (!LIST_EMPTY(&tvh_codec_profiles)) { - tvh_codec_profile_remove(LIST_FIRST(&tvh_codec_profiles), 0); - } +void tvh_codec_profiles_remove() { + tvhinfo(LS_CODEC, "removing codec profiles"); + while (!LIST_EMPTY(&tvh_codec_profiles)) { + tvh_codec_profile_remove(LIST_FIRST(&tvh_codec_profiles), 0); + } } diff --git a/src/transcoding/codec/profile_audio_class.c b/src/transcoding/codec/profile_audio_class.c index dc3e22550..02cb73b12 100644 --- a/src/transcoding/codec/profile_audio_class.c +++ b/src/transcoding/codec/profile_audio_class.c @@ -17,318 +17,270 @@ * along with this program. If not, see . */ - #include "internals.h" #include "lang_codes.h" /* TVHCodec ================================================================= */ -static htsmsg_t * -tvh_codec_audio_get_list_sample_fmts(TVHAudioCodec *self) -{ - htsmsg_t *list = NULL, *map = NULL; - const enum AVSampleFormat *sample_fmts = self->sample_fmts; - enum AVSampleFormat f = AV_SAMPLE_FMT_NONE; - const char *f_str = NULL; - int i; - - if (sample_fmts && (list = htsmsg_create_list())) { - if (!(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - } - else { - ADD_ENTRY(list, map, s32, f, str, AUTO_STR); - for (i = 0; (f = sample_fmts[i]) != AV_SAMPLE_FMT_NONE; i++) { - if (!(f_str = av_get_sample_fmt_name(f)) || - !(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - break; - } - ADD_ENTRY(list, map, s32, f, str, f_str); - } +static htsmsg_t* tvh_codec_audio_get_list_sample_fmts(TVHAudioCodec* self) { + htsmsg_t * list = NULL, *map = NULL; + const enum AVSampleFormat* sample_fmts = self->sample_fmts; + enum AVSampleFormat f = AV_SAMPLE_FMT_NONE; + const char* f_str = NULL; + int i; + + if (sample_fmts && (list = htsmsg_create_list())) { + if (!(map = htsmsg_create_map())) { + htsmsg_destroy(list); + list = NULL; + } else { + ADD_ENTRY(list, map, s32, f, str, AUTO_STR); + for (i = 0; (f = sample_fmts[i]) != AV_SAMPLE_FMT_NONE; i++) { + if (!(f_str = av_get_sample_fmt_name(f)) || !(map = htsmsg_create_map())) { + htsmsg_destroy(list); + list = NULL; + break; } + ADD_ENTRY(list, map, s32, f, str, f_str); + } } - return list; + } + return list; } - -static htsmsg_t * -tvh_codec_audio_get_list_sample_rates(TVHAudioCodec *self) -{ - htsmsg_t *list = NULL, *map = NULL; - const int *sample_rates = self->sample_rates; - int r = 0, i; - - if (sample_rates && (list = htsmsg_create_list())) { +static htsmsg_t* tvh_codec_audio_get_list_sample_rates(TVHAudioCodec* self) { + htsmsg_t * list = NULL, *map = NULL; + const int* sample_rates = self->sample_rates; + int r = 0, i; + + if (sample_rates && (list = htsmsg_create_list())) { + if (!(map = htsmsg_create_map())) { + htsmsg_destroy(list); + list = NULL; + } else { + ADD_ENTRY(list, map, s32, r, str, AUTO_STR); + for (i = 0; (r = sample_rates[i]); i++) { if (!(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - } - else { - ADD_ENTRY(list, map, s32, r, str, AUTO_STR); - for (i = 0; (r = sample_rates[i]); i++) { - if (!(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - break; - } - ADD_S32_VAL(list, map, r); - } + htsmsg_destroy(list); + list = NULL; + break; } + ADD_S32_VAL(list, map, r); + } } - return list; + } + return list; } - -static htsmsg_t * -tvh_codec_audio_get_list_channel_layouts(TVHAudioCodec *self) -{ - htsmsg_t *list = NULL, *map = NULL; - const uint64_t *channel_layouts = self->channel_layouts; - uint64_t l = 0; - char l_buf[16]; - int i; - - if (channel_layouts && (list = htsmsg_create_list())) { - if (!(map = htsmsg_create_map())) { +static htsmsg_t* tvh_codec_audio_get_list_channel_layouts(TVHAudioCodec* self) { + htsmsg_t * list = NULL, *map = NULL; + const uint64_t* channel_layouts = self->channel_layouts; + uint64_t l = 0; + char l_buf[16]; + int i; + + if (channel_layouts && (list = htsmsg_create_list())) { + if (!(map = htsmsg_create_map())) { + htsmsg_destroy(list); + list = NULL; + } else { + ADD_ENTRY(list, map, s64, l, str, AUTO_STR); + for (i = 0; (l = channel_layouts[i]); i++) { + if (l < INT64_MAX) { + if (!(map = htsmsg_create_map())) { htsmsg_destroy(list); list = NULL; + break; + } + l_buf[0] = '\0'; + av_get_channel_layout_string(l_buf, sizeof(l_buf), 0, l); + ADD_ENTRY(list, map, s64, l, str, l_buf); } - else { - ADD_ENTRY(list, map, s64, l, str, AUTO_STR); - for (i = 0; (l = channel_layouts[i]); i++) { - if (l < INT64_MAX) { - if (!(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - break; - } - l_buf[0] = '\0'; - av_get_channel_layout_string(l_buf, sizeof(l_buf), 0, l); - ADD_ENTRY(list, map, s64, l, str, l_buf); - } - } - } + } } - return list; + } + return list; } - /* TVHCodecProfile ========================================================== */ -static int -tvh_codec_profile_audio_is_copy(TVHAudioCodecProfile *self, tvh_ssc_t *ssc) -{ - // TODO: fix me - // assuming default channel_layout (AV_CH_LAYOUT_STEREO) - // and sample_rate (48kHz) for input - int ssc_channels = ssc->es_channels ? ssc->es_channels : 2; - int ssc_sr = ssc->es_sri ? sri_to_rate(ssc->es_sri) : 48000; - if ((self->channel_layout && - ssc_channels != av_get_channel_layout_nb_channels(self->channel_layout)) || - (self->sample_rate && ssc_sr != self->sample_rate)) { - return 0; - } - return 1; -} - - -static int -tvh_codec_profile_audio_open(TVHAudioCodecProfile *self, AVDictionary **opts) -{ - if (self->sample_fmt != AV_SAMPLE_FMT_NONE) { - AV_DICT_SET_INT(opts, "sample_fmt", self->sample_fmt, - AV_DICT_DONT_OVERWRITE); - } - if (self->sample_rate) { - AV_DICT_SET_INT(opts, "sample_rate", self->sample_rate, - AV_DICT_DONT_OVERWRITE); - } - if (self->channel_layout) { - AV_DICT_SET_INT(opts, "channel_layout", self->channel_layout, - AV_DICT_DONT_OVERWRITE); - } +static int tvh_codec_profile_audio_is_copy(TVHAudioCodecProfile* self, tvh_ssc_t* ssc) { + // TODO: fix me + // assuming default channel_layout (AV_CH_LAYOUT_STEREO) + // and sample_rate (48kHz) for input + int ssc_channels = ssc->es_channels ? ssc->es_channels : 2; + int ssc_sr = ssc->es_sri ? sri_to_rate(ssc->es_sri) : 48000; + if ((self->channel_layout && + ssc_channels != av_get_channel_layout_nb_channels(self->channel_layout)) || + (self->sample_rate && ssc_sr != self->sample_rate)) { return 0; + } + return 1; } +static int tvh_codec_profile_audio_open(TVHAudioCodecProfile* self, AVDictionary** opts) { + if (self->sample_fmt != AV_SAMPLE_FMT_NONE) { + AV_DICT_SET_INT(opts, "sample_fmt", self->sample_fmt, AV_DICT_DONT_OVERWRITE); + } + if (self->sample_rate) { + AV_DICT_SET_INT(opts, "sample_rate", self->sample_rate, AV_DICT_DONT_OVERWRITE); + } + if (self->channel_layout) { + AV_DICT_SET_INT(opts, "channel_layout", self->channel_layout, AV_DICT_DONT_OVERWRITE); + } + return 0; +} /* codec_profile_audio_class ================================================ */ /* codec_profile_audio_class.language */ -static htsmsg_t * -codec_profile_audio_class_language_list(void *obj, const char *lang) -{ - htsmsg_t *list = htsmsg_create_list(); - lang_code_t *lc = (lang_code_t *)lang_codes; - char lc_buf[128]; - - while (lc->code2b) { - htsmsg_t *map = NULL; - if (!strcmp(lc->code2b, "und")) { - map = htsmsg_create_key_val("", tvh_gettext_lang(lang, N_("Use original"))); - } - else { - memset(lc_buf, 0, sizeof(lc_buf)); - if (!str_snprintf(lc_buf, sizeof(lc_buf), "%s (%s)", lc->desc, lc->code2b)) { - map = htsmsg_create_key_val(lc->code2b, lc_buf); - } - else { - htsmsg_destroy(list); - list = NULL; - break; - } - } - htsmsg_add_msg(list, NULL, map); - lc++; +static htsmsg_t* codec_profile_audio_class_language_list(void* obj, const char* lang) { + htsmsg_t* list = htsmsg_create_list(); + lang_code_t* lc = (lang_code_t*)lang_codes; + char lc_buf[128]; + + while (lc->code2b) { + htsmsg_t* map = NULL; + if (!strcmp(lc->code2b, "und")) { + map = htsmsg_create_key_val("", tvh_gettext_lang(lang, N_("Use original"))); + } else { + memset(lc_buf, 0, sizeof(lc_buf)); + if (!str_snprintf(lc_buf, sizeof(lc_buf), "%s (%s)", lc->desc, lc->code2b)) { + map = htsmsg_create_key_val(lc->code2b, lc_buf); + } else { + htsmsg_destroy(list); + list = NULL; + break; + } } - return list; + htsmsg_add_msg(list, NULL, map); + lc++; + } + return list; } - /* codec_profile_audio_class.sample_fmt */ -static uint32_t -codec_profile_audio_class_sample_fmt_get_opts(void *obj, uint32_t opts) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return tvh_codec_audio_get_opts(codec, sample_fmts, opts); +static uint32_t codec_profile_audio_class_sample_fmt_get_opts(void* obj, uint32_t opts) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return tvh_codec_audio_get_opts(codec, sample_fmts, opts); } - -static htsmsg_t * -codec_profile_audio_class_sample_fmt_list(void *obj, const char *lang) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return tvh_codec_audio_get_list(codec, sample_fmts); +static htsmsg_t* codec_profile_audio_class_sample_fmt_list(void* obj, const char* lang) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return tvh_codec_audio_get_list(codec, sample_fmts); } - /* codec_profile_audio_class.sample_rate */ -static uint32_t -codec_profile_audio_class_sample_rate_get_opts(void *obj, uint32_t opts) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return tvh_codec_audio_get_opts(codec, sample_rates, opts); +static uint32_t codec_profile_audio_class_sample_rate_get_opts(void* obj, uint32_t opts) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return tvh_codec_audio_get_opts(codec, sample_rates, opts); } - -static htsmsg_t * -codec_profile_audio_class_sample_rate_list(void *obj, const char *lang) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return tvh_codec_audio_get_list(codec, sample_rates); +static htsmsg_t* codec_profile_audio_class_sample_rate_list(void* obj, const char* lang) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return tvh_codec_audio_get_list(codec, sample_rates); } - /* codec_profile_audio_class.channel_layout */ -static uint32_t -codec_profile_audio_class_channel_layout_get_opts(void *obj, uint32_t opts) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return tvh_codec_audio_get_opts(codec, channel_layouts, opts); +static uint32_t codec_profile_audio_class_channel_layout_get_opts(void* obj, uint32_t opts) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return tvh_codec_audio_get_opts(codec, channel_layouts, opts); } - -static htsmsg_t * -codec_profile_audio_class_channel_layout_list(void *obj, const char *lang) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return tvh_codec_audio_get_list(codec, channel_layouts); +static htsmsg_t* codec_profile_audio_class_channel_layout_list(void* obj, const char* lang) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return tvh_codec_audio_get_list(codec, channel_layouts); } - /* codec_profile_audio_class */ const codec_profile_class_t codec_profile_audio_class = { - { - .ic_super = (idclass_t *)&codec_profile_class, - .ic_class = "codec_profile_audio", - .ic_caption = N_("audio"), - .ic_properties = (const property_t[]) { - { - .type = PT_INT, - .id = "tracks", - .name = N_("Limit audio tracks"), - .desc = N_("Use only defined number of audio tracks at maximum."), - .group = 2, - .off = offsetof(TVHAudioCodecProfile, tracks), - .def.i = 1, - }, - { - .type = PT_STR, - .id = "language1", - .name = N_("1. Language"), - .desc = N_("Preferred audio language."), - .group = 2, - .off = offsetof(TVHAudioCodecProfile, language1), - .list = codec_profile_audio_class_language_list, - .def.s = "", - }, - { - .type = PT_STR, - .id = "language2", - .name = N_("2. Language"), - .desc = N_("Preferred audio language."), - .group = 2, - .off = offsetof(TVHAudioCodecProfile, language2), - .list = codec_profile_audio_class_language_list, - .def.s = "", - }, - { - .type = PT_STR, - .id = "language3", - .name = N_("3. Language"), - .desc = N_("Preferred audio language."), - .group = 2, - .off = offsetof(TVHAudioCodecProfile, language3), - .list = codec_profile_audio_class_language_list, - .def.s = "", - }, - { - .type = PT_INT, - .id = "sample_fmt", - .name = N_("Sample format"), - .desc = N_("Audio sample format."), - .group = 4, - .opts = PO_ADVANCED | PO_PHIDDEN, - .get_opts = codec_profile_audio_class_sample_fmt_get_opts, - .off = offsetof(TVHAudioCodecProfile, sample_fmt), - .list = codec_profile_audio_class_sample_fmt_list, - .def.i = AV_SAMPLE_FMT_NONE, - }, - { - .type = PT_INT, - .id = "sample_rate", - .name = N_("Sample rate"), - .desc = N_("Samples per second."), - .group = 4, - .opts = PO_ADVANCED | PO_PHIDDEN, - .get_opts = codec_profile_audio_class_sample_rate_get_opts, - .off = offsetof(TVHAudioCodecProfile, sample_rate), - .list = codec_profile_audio_class_sample_rate_list, - .def.i = 0, - }, - { - .type = PT_S64, - .id = "channel_layout", - .name = N_("Channel layout"), - .desc = N_("Audio channel layout."), - .group = 4, - .opts = PO_ADVANCED | PO_PHIDDEN, - .get_opts = codec_profile_audio_class_channel_layout_get_opts, - .off = offsetof(TVHAudioCodecProfile, channel_layout), - .list = codec_profile_audio_class_channel_layout_list, - .def.s64 = 0, - }, - {} - } - }, + {.ic_super = (idclass_t*)&codec_profile_class, + .ic_class = "codec_profile_audio", + .ic_caption = N_("audio"), + .ic_properties = + (const property_t[]){ + { + .type = PT_INT, + .id = "tracks", + .name = N_("Limit audio tracks"), + .desc = N_("Use only defined number of audio tracks at maximum."), + .group = 2, + .off = offsetof(TVHAudioCodecProfile, tracks), + .def.i = 1, + }, + { + .type = PT_STR, + .id = "language1", + .name = N_("1. Language"), + .desc = N_("Preferred audio language."), + .group = 2, + .off = offsetof(TVHAudioCodecProfile, language1), + .list = codec_profile_audio_class_language_list, + .def.s = "", + }, + { + .type = PT_STR, + .id = "language2", + .name = N_("2. Language"), + .desc = N_("Preferred audio language."), + .group = 2, + .off = offsetof(TVHAudioCodecProfile, language2), + .list = codec_profile_audio_class_language_list, + .def.s = "", + }, + { + .type = PT_STR, + .id = "language3", + .name = N_("3. Language"), + .desc = N_("Preferred audio language."), + .group = 2, + .off = offsetof(TVHAudioCodecProfile, language3), + .list = codec_profile_audio_class_language_list, + .def.s = "", + }, + { + .type = PT_INT, + .id = "sample_fmt", + .name = N_("Sample format"), + .desc = N_("Audio sample format."), + .group = 4, + .opts = PO_ADVANCED | PO_PHIDDEN, + .get_opts = codec_profile_audio_class_sample_fmt_get_opts, + .off = offsetof(TVHAudioCodecProfile, sample_fmt), + .list = codec_profile_audio_class_sample_fmt_list, + .def.i = AV_SAMPLE_FMT_NONE, + }, + { + .type = PT_INT, + .id = "sample_rate", + .name = N_("Sample rate"), + .desc = N_("Samples per second."), + .group = 4, + .opts = PO_ADVANCED | PO_PHIDDEN, + .get_opts = codec_profile_audio_class_sample_rate_get_opts, + .off = offsetof(TVHAudioCodecProfile, sample_rate), + .list = codec_profile_audio_class_sample_rate_list, + .def.i = 0, + }, + { + .type = PT_S64, + .id = "channel_layout", + .name = N_("Channel layout"), + .desc = N_("Audio channel layout."), + .group = 4, + .opts = PO_ADVANCED | PO_PHIDDEN, + .get_opts = codec_profile_audio_class_channel_layout_get_opts, + .off = offsetof(TVHAudioCodecProfile, channel_layout), + .list = codec_profile_audio_class_channel_layout_list, + .def.s64 = 0, + }, + {}}}, .is_copy = (codec_profile_is_copy_meth)tvh_codec_profile_audio_is_copy, .open = (codec_profile_open_meth)tvh_codec_profile_audio_open, }; diff --git a/src/transcoding/codec/profile_class.c b/src/transcoding/codec/profile_class.c index fea65b174..cd8de444b 100644 --- a/src/transcoding/codec/profile_class.c +++ b/src/transcoding/codec/profile_class.c @@ -17,259 +17,216 @@ * along with this program. If not, see . */ - #include "internals.h" #include "access.h" - /* TVHCodec ================================================================= */ -uint32_t -tvh_codec_base_get_opts(TVHCodec *self, uint32_t opts, int visible) -{ - if (!tvh_codec_is_enabled(self)) { - opts |= PO_RDONLY; - } - else if (visible) { - opts &= ~(PO_PHIDDEN); - } - return opts; +uint32_t tvh_codec_base_get_opts(TVHCodec* self, uint32_t opts, int visible) { + if (!tvh_codec_is_enabled(self)) { + opts |= PO_RDONLY; + } else if (visible) { + opts &= ~(PO_PHIDDEN); + } + return opts; } - -htsmsg_t * -tvh_codec_get_list_profiles(TVHCodec *self) -{ - htsmsg_t *list = NULL, *map = NULL; - const AVProfile *profiles = self->profiles; - AVProfile *p = NULL; - - if (profiles && (list = htsmsg_create_list())) { +htsmsg_t* tvh_codec_get_list_profiles(TVHCodec* self) { + htsmsg_t * list = NULL, *map = NULL; + const AVProfile* profiles = self->profiles; + AVProfile* p = NULL; + + if (profiles && (list = htsmsg_create_list())) { + if (!(map = htsmsg_create_map())) { + htsmsg_destroy(list); + list = NULL; + } else { + ADD_ENTRY(list, map, s32, FF_PROFILE_UNKNOWN, str, AUTO_STR); + for (p = (AVProfile*)profiles; p->profile != FF_PROFILE_UNKNOWN; p++) { if (!(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - } - else { - ADD_ENTRY(list, map, s32, FF_PROFILE_UNKNOWN, str, AUTO_STR); - for (p = (AVProfile *)profiles; p->profile != FF_PROFILE_UNKNOWN; p++) { - if (!(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - break; - } - ADD_ENTRY(list, map, s32, p->profile, str, p->name); - } + htsmsg_destroy(list); + list = NULL; + break; } + ADD_ENTRY(list, map, s32, p->profile, str, p->name); + } } - return list; + } + return list; } - /* TVHCodecProfile ========================================================== */ -static int -tvh_codec_profile_base_is_copy(TVHCodecProfile *self, tvh_ssc_t *ssc) -{ - return (!(self->bit_rate || self->qscale)); +static int tvh_codec_profile_base_is_copy(TVHCodecProfile* self, tvh_ssc_t* ssc) { + return (!(self->bit_rate || self->qscale)); } - -static int -tvh_codec_profile_base_open(TVHCodecProfile *self, AVDictionary **opts) -{ - AV_DICT_SET_TVH_REQUIRE_META(opts, 1); - // profile - if (self->profile != FF_PROFILE_UNKNOWN) { - AV_DICT_SET_INT(opts, "profile", self->profile, 0); - } - return 0; +static int tvh_codec_profile_base_open(TVHCodecProfile* self, AVDictionary** opts) { + AV_DICT_SET_TVH_REQUIRE_META(opts, 1); + // profile + if (self->profile != FF_PROFILE_UNKNOWN) { + AV_DICT_SET_INT(opts, "profile", self->profile, 0); + } + return 0; } - /* codec_profile_class ====================================================== */ -static htsmsg_t * -codec_profile_class_save(idnode_t *idnode, char *filename, size_t fsize) -{ - htsmsg_t *map = htsmsg_create_map(); - char uuid[UUID_HEX_SIZE]; - idnode_save(idnode, map); - if (filename) - snprintf(filename, fsize, "codec/%s", idnode_uuid_as_str(idnode, uuid)); - return map; +static htsmsg_t* codec_profile_class_save(idnode_t* idnode, char* filename, size_t fsize) { + htsmsg_t* map = htsmsg_create_map(); + char uuid[UUID_HEX_SIZE]; + idnode_save(idnode, map); + if (filename) + snprintf(filename, fsize, "codec/%s", idnode_uuid_as_str(idnode, uuid)); + return map; } - -static void -codec_profile_class_delete(idnode_t *idnode) -{ - tvh_codec_profile_remove((TVHCodecProfile *)idnode, 1); +static void codec_profile_class_delete(idnode_t* idnode) { + tvh_codec_profile_remove((TVHCodecProfile*)idnode, 1); } - /* codec_profile_class.name */ -static int -codec_profile_class_name_set(void *obj, const void *val) -{ - TVHCodecProfile *self = (TVHCodecProfile *)obj, *other = NULL; - const char *name = (const char *)val; - - if (self) { - if (name && name[0] != '\0' && strcmp(name, "copy") && - strlen(name) < TVH_NAME_LEN && - strcmp(name, self->name ? self->name : "")) { - if ((other = tvh_codec_profile_find(name)) && other != self) { - tvherror(LS_CODEC, "profile '%s' already exists", name); - } - else { - free(self->name); - self->name = strdup(name); - return 1; - } - } +static int codec_profile_class_name_set(void* obj, const void* val) { + TVHCodecProfile *self = (TVHCodecProfile*)obj, *other = NULL; + const char* name = (const char*)val; + + if (self) { + if (name && name[0] != '\0' && strcmp(name, "copy") && strlen(name) < TVH_NAME_LEN && + strcmp(name, self->name ? self->name : "")) { + if ((other = tvh_codec_profile_find(name)) && other != self) { + tvherror(LS_CODEC, "profile '%s' already exists", name); + } else { + free(self->name); + self->name = strdup(name); + return 1; + } } - return 0; + } + return 0; } - /* codec_profile_class.name */ -static const void * -codec_profile_class_name_get(void *obj) -{ - static const char *type; +static const void* codec_profile_class_name_get(void* obj) { + static const char* type; - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - type = codec ? tvh_codec_get_title(codec) : ""; - return &type; + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + type = codec ? tvh_codec_get_title(codec) : ""; + return &type; } - /* codec_profile_class.type */ -static const void * -codec_profile_class_type_get(void *obj) -{ - static const char *type; +static const void* codec_profile_class_type_get(void* obj) { + static const char* type; - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - type = codec ? tvh_codec_get_type_string(codec) : ""; - return &type; + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + type = codec ? tvh_codec_get_type_string(codec) : ""; + return &type; } - /* codec_profile_class.enabled */ -static const void * -codec_profile_class_enabled_get(void *obj) -{ - static int enabled; +static const void* codec_profile_class_enabled_get(void* obj) { + static int enabled; - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - enabled = codec ? tvh_codec_is_enabled(codec) : 0; - return &enabled; + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + enabled = codec ? tvh_codec_is_enabled(codec) : 0; + return &enabled; } - /* codec_profile_class.profile */ -static htsmsg_t * -codec_profile_class_profile_list(void *obj, const char *lang) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return tvh_codec_get_list(codec, profiles); +static htsmsg_t* codec_profile_class_profile_list(void* obj, const char* lang) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return tvh_codec_get_list(codec, profiles); } - /* codec_profile_class */ CLASS_DOC(codec_profile) const codec_profile_class_t codec_profile_class = { - { - .ic_class = "codec_profile", - .ic_caption = N_("Stream - Codec Profiles"), - .ic_event = "codec_profile", - .ic_perm_def = ACCESS_ADMIN, + {.ic_class = "codec_profile", + .ic_caption = N_("Stream - Codec Profiles"), + .ic_event = "codec_profile", + .ic_perm_def = ACCESS_ADMIN, .ic_doc = tvh_doc_codec_profile_class, - .ic_save = codec_profile_class_save, - .ic_delete = codec_profile_class_delete, - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, + .ic_save = codec_profile_class_save, + .ic_delete = codec_profile_class_delete, + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + { + .name = N_("Profile Settings"), + .number = 2, }, - { - .name = N_("Profile Settings"), - .number = 2, + { + .name = N_("Codec Settings"), + .number = 3, }, - { - .name = N_("Codec Settings"), - .number = 3, + { + .name = N_("Advanced Settings"), + .number = 4, }, - { - .name = N_("Advanced Settings"), - .number = 4, + { + .name = N_("Expert Settings"), + .number = 5, }, + {}}, + .ic_properties = (const property_t[]){{ + .type = PT_STR, + .id = "name", + .name = N_("Name"), + .desc = N_("Name."), + .group = 1, + .off = offsetof(TVHCodecProfile, name), + .set = codec_profile_class_name_set, + }, { - .name = N_("Expert Settings"), - .number = 5, + .type = PT_STR, + .id = "description", + .name = N_("Description"), + .desc = N_("Profile description."), + .group = 1, + .off = offsetof(TVHCodecProfile, description), }, - {} - }, - .ic_properties = (const property_t[]) { { - .type = PT_STR, - .id = "name", - .name = N_("Name"), - .desc = N_("Name."), - .group = 1, - .off = offsetof(TVHCodecProfile, name), - .set = codec_profile_class_name_set, + .type = PT_STR, + .id = "codec_title", + .name = N_("Codec"), + .desc = N_("Codec title."), + .group = 1, + .opts = PO_RDONLY | PO_NOSAVE, + .get = codec_profile_class_name_get, }, { - .type = PT_STR, - .id = "description", - .name = N_("Description"), - .desc = N_("Profile description."), - .group = 1, - .off = offsetof(TVHCodecProfile, description), + .type = PT_STR, + .id = "codec_name", + .name = N_("Codec name"), + .desc = N_("Codec name."), + .group = 1, + .opts = PO_RDONLY, + .off = offsetof(TVHCodecProfile, codec_name), }, { - .type = PT_STR, - .id = "codec_title", - .name = N_("Codec"), - .desc = N_("Codec title."), - .group = 1, - .opts = PO_RDONLY | PO_NOSAVE, - .get = codec_profile_class_name_get, + .type = PT_STR, + .id = "type", + .name = N_("Type"), + .desc = N_("Codec type."), + .group = 1, + .opts = PO_RDONLY | PO_NOSAVE, + .get = codec_profile_class_type_get, }, { - .type = PT_STR, - .id = "codec_name", - .name = N_("Codec name"), - .desc = N_("Codec name."), - .group = 1, - .opts = PO_RDONLY, - .off = offsetof(TVHCodecProfile, codec_name), - }, - { - .type = PT_STR, - .id = "type", - .name = N_("Type"), - .desc = N_("Codec type."), - .group = 1, - .opts = PO_RDONLY | PO_NOSAVE, - .get = codec_profile_class_type_get, - }, - { - .type = PT_BOOL, - .id = "enabled", - .name = N_("Enabled"), - .desc = N_("Codec status."), - .group = 1, - .opts = PO_RDONLY | PO_NOSAVE, - .get = codec_profile_class_enabled_get, + .type = PT_BOOL, + .id = "enabled", + .name = N_("Enabled"), + .desc = N_("Codec status."), + .group = 1, + .opts = PO_RDONLY | PO_NOSAVE, + .get = codec_profile_class_enabled_get, }, { .type = PT_INT, @@ -283,27 +240,19 @@ const codec_profile_class_t codec_profile_class = { .list = codec_profile_class_profile_list, .def.i = FF_PROFILE_UNKNOWN, }, - {} - } - }, + {}}}, .is_copy = tvh_codec_profile_base_is_copy, .open = tvh_codec_profile_base_open, }; - /* exposed */ -uint32_t -codec_profile_class_get_opts(void *obj, uint32_t opts) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return codec ? tvh_codec_base_get_opts(codec, opts, 0) : opts; +uint32_t codec_profile_class_get_opts(void* obj, uint32_t opts) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return codec ? tvh_codec_base_get_opts(codec, opts, 0) : opts; } - -uint32_t -codec_profile_class_profile_get_opts(void *obj, uint32_t opts) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return tvh_codec_get_opts(codec, profiles, opts); +uint32_t codec_profile_class_profile_get_opts(void* obj, uint32_t opts) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return tvh_codec_get_opts(codec, profiles, opts); } diff --git a/src/transcoding/codec/profile_video_class.c b/src/transcoding/codec/profile_video_class.c index 35bd9353a..90cdf6f43 100644 --- a/src/transcoding/codec/profile_video_class.c +++ b/src/transcoding/codec/profile_video_class.c @@ -17,222 +17,195 @@ * along with this program. If not, see . */ - #include "internals.h" #include -static htsmsg_t * -scaling_mode_get_list( void *o, const char *lang ) -{ - static const struct strtab tab[] = { - { N_("Up & Down"), 0 }, - { N_("Up (only)"), 1 }, - { N_("Down (only)"), 2 }, - }; - return strtab2htsmsg(tab, 1, lang); +static htsmsg_t* scaling_mode_get_list(void* o, const char* lang) { + static const struct strtab tab[] = { + {N_("Up & Down"), 0}, + {N_("Up (only)"), 1}, + {N_("Down (only)"), 2}, + }; + return strtab2htsmsg(tab, 1, lang); } /* TVHCodec ================================================================= */ -static htsmsg_t * -tvh_codec_video_get_list_pix_fmts(TVHVideoCodec *self) -{ - htsmsg_t *list = NULL, *map = NULL; - const enum AVPixelFormat *pix_fmts = self->pix_fmts; - enum AVPixelFormat f = AV_PIX_FMT_NONE; - const char *f_str = NULL; - int i; - - if (pix_fmts && (list = htsmsg_create_list())) { - if (!(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - } - else { - ADD_ENTRY(list, map, s32, f, str, AUTO_STR); - for (i = 0; (f = pix_fmts[i]) != AV_PIX_FMT_NONE; i++) { - if (!(f_str = av_get_pix_fmt_name(f)) || - !(map = htsmsg_create_map())) { - htsmsg_destroy(list); - list = NULL; - break; - } - ADD_ENTRY(list, map, s32, f, str, f_str); - } +static htsmsg_t* tvh_codec_video_get_list_pix_fmts(TVHVideoCodec* self) { + htsmsg_t * list = NULL, *map = NULL; + const enum AVPixelFormat* pix_fmts = self->pix_fmts; + enum AVPixelFormat f = AV_PIX_FMT_NONE; + const char* f_str = NULL; + int i; + + if (pix_fmts && (list = htsmsg_create_list())) { + if (!(map = htsmsg_create_map())) { + htsmsg_destroy(list); + list = NULL; + } else { + ADD_ENTRY(list, map, s32, f, str, AUTO_STR); + for (i = 0; (f = pix_fmts[i]) != AV_PIX_FMT_NONE; i++) { + if (!(f_str = av_get_pix_fmt_name(f)) || !(map = htsmsg_create_map())) { + htsmsg_destroy(list); + list = NULL; + break; } + ADD_ENTRY(list, map, s32, f, str, f_str); + } } - return list; + } + return list; } - /* TVHCodecProfile ========================================================== */ -static int -tvh_codec_profile_video_setup(TVHVideoCodecProfile *self, tvh_ssc_t *ssc) -{ - self->size.den = ssc->es_height; - self->size.num = ssc->es_width; - switch (self->scaling_mode) { - case 0: - // scaling up and down - if (self->height) { - self->size.den = self->height; - self->size.den += self->size.den & 1; - self->size.num = (int)((double)self->size.den * ((double)ssc->es_width / (double)ssc->es_height)); - self->size.num += self->size.num & 1; - } - break; - case 1: - // scaling up (only) - if ((self->height > 0) && (self->size.den < self->height)) { - self->size.den = self->height; - self->size.den += self->size.den & 1; - self->size.num = (int)((double)self->size.den * ((double)ssc->es_width / (double)ssc->es_height)); - self->size.num += self->size.num & 1; - } - break; - case 2: - // scaling down (only) - if ((self->height > 0) && (self->size.den > self->height)) { - self->size.den = self->height; - self->size.den += self->size.den & 1; - self->size.num = (int)((double)self->size.den * ((double)ssc->es_width / (double)ssc->es_height)); - self->size.num += self->size.num & 1; - } - break; - } - return 0; +static int tvh_codec_profile_video_setup(TVHVideoCodecProfile* self, tvh_ssc_t* ssc) { + self->size.den = ssc->es_height; + self->size.num = ssc->es_width; + switch (self->scaling_mode) { + case 0: + // scaling up and down + if (self->height) { + self->size.den = self->height; + self->size.den += self->size.den & 1; + self->size.num = + (int)((double)self->size.den * ((double)ssc->es_width / (double)ssc->es_height)); + self->size.num += self->size.num & 1; + } + break; + case 1: + // scaling up (only) + if ((self->height > 0) && (self->size.den < self->height)) { + self->size.den = self->height; + self->size.den += self->size.den & 1; + self->size.num = + (int)((double)self->size.den * ((double)ssc->es_width / (double)ssc->es_height)); + self->size.num += self->size.num & 1; + } + break; + case 2: + // scaling down (only) + if ((self->height > 0) && (self->size.den > self->height)) { + self->size.den = self->height; + self->size.den += self->size.den & 1; + self->size.num = + (int)((double)self->size.den * ((double)ssc->es_width / (double)ssc->es_height)); + self->size.num += self->size.num & 1; + } + break; + } + return 0; } - -static int -tvh_codec_profile_video_is_copy(TVHVideoCodecProfile *self, tvh_ssc_t *ssc) -{ - return (!self->deinterlace && (self->size.den == ssc->es_height)); +static int tvh_codec_profile_video_is_copy(TVHVideoCodecProfile* self, tvh_ssc_t* ssc) { + return (!self->deinterlace && (self->size.den == ssc->es_height)); } - -static int -tvh_codec_profile_video_open(TVHVideoCodecProfile *self, AVDictionary **opts) -{ - AV_DICT_SET_INT(opts, "tvh_filter_deint", self->deinterlace, 0); - // video_size - AV_DICT_SET_INT(opts, "width", self->size.num, 0); - AV_DICT_SET_INT(opts, "height", self->size.den, 0); - // crf - if (self->crf) { - AV_DICT_SET_INT(opts, "crf", self->crf, AV_DICT_DONT_OVERWRITE); - } - // pix_fmt - AV_DICT_SET_PIX_FMT(opts, self->pix_fmt, AV_PIX_FMT_YUV420P); - // max_b_frames - AV_DICT_SET_INT(opts, "bf", 3, AV_DICT_DONT_OVERWRITE); - return 0; +static int tvh_codec_profile_video_open(TVHVideoCodecProfile* self, AVDictionary** opts) { + AV_DICT_SET_INT(opts, "tvh_filter_deint", self->deinterlace, 0); + // video_size + AV_DICT_SET_INT(opts, "width", self->size.num, 0); + AV_DICT_SET_INT(opts, "height", self->size.den, 0); + // crf + if (self->crf) { + AV_DICT_SET_INT(opts, "crf", self->crf, AV_DICT_DONT_OVERWRITE); + } + // pix_fmt + AV_DICT_SET_PIX_FMT(opts, self->pix_fmt, AV_PIX_FMT_YUV420P); + // max_b_frames + AV_DICT_SET_INT(opts, "bf", 3, AV_DICT_DONT_OVERWRITE); + return 0; } - /* codec_profile_video_class ================================================ */ /* codec_profile_video_class.deinterlace */ -static int -codec_profile_video_class_deinterlace_set(void *obj, const void *val) -{ - TVHVideoCodecProfile *self = (TVHVideoCodecProfile *)obj; - const AVCodec *avcodec = NULL; +static int codec_profile_video_class_deinterlace_set(void* obj, const void* val) { + TVHVideoCodecProfile* self = (TVHVideoCodecProfile*)obj; + const AVCodec* avcodec = NULL; - if (self && - (avcodec = tvh_codec_profile_get_avcodec((TVHCodecProfile *)self))) { - self->deinterlace = *(int *)val; - return 1; - } - return 0; + if (self && (avcodec = tvh_codec_profile_get_avcodec((TVHCodecProfile*)self))) { + self->deinterlace = *(int*)val; + return 1; + } + return 0; } - /* codec_profile_video_class.pix_fmt */ -static uint32_t -codec_profile_video_class_pix_fmt_get_opts(void *obj, uint32_t opts) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return tvh_codec_video_get_opts(codec, pix_fmts, opts); +static uint32_t codec_profile_video_class_pix_fmt_get_opts(void* obj, uint32_t opts) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return tvh_codec_video_get_opts(codec, pix_fmts, opts); } - -static htsmsg_t * -codec_profile_video_class_pix_fmt_list(void *obj, const char *lang) -{ - TVHCodec *codec = tvh_codec_profile_get_codec(obj); - return tvh_codec_video_get_list(codec, pix_fmts); +static htsmsg_t* codec_profile_video_class_pix_fmt_list(void* obj, const char* lang) { + TVHCodec* codec = tvh_codec_profile_get_codec(obj); + return tvh_codec_video_get_list(codec, pix_fmts); } - /* codec_profile_video_class */ const codec_profile_class_t codec_profile_video_class = { - { - .ic_super = (idclass_t *)&codec_profile_class, - .ic_class = "codec_profile_video", - .ic_caption = N_("video"), - .ic_properties = (const property_t[]) { - { - .type = PT_BOOL, - .id = "deinterlace", - .name = N_("Deinterlace"), - .desc = N_("Deinterlace."), - .group = 2, - .off = offsetof(TVHVideoCodecProfile, deinterlace), - .set = codec_profile_video_class_deinterlace_set, - .def.i = 1, - }, - { - .type = PT_INT, - .id = "height", - .name = N_("Height (pixels) (0=no scaling)"), - .desc = N_("Height of the output video stream. Horizontal resolution " - "is adjusted automatically to preserve aspect ratio. " - "When set to 0, the input resolution is used."), - .group = 2, - .off = offsetof(TVHVideoCodecProfile, height), - .def.i = 0, - }, - { - .type = PT_INT, - .id = "scaling_mode", - .name = N_("Scaling mode"), - .desc = N_("Allow control for scaling Up&Down, Up or Down"), - .group = 2, - .off = offsetof(TVHVideoCodecProfile, scaling_mode), - .list = scaling_mode_get_list, - .def.i = 0, - }, - { - .type = PT_BOOL, - .id = "hwaccel", - .name = N_("Hardware acceleration"), - .desc = N_("Use hardware acceleration for decoding if available."), - .group = 2, - .off = offsetof(TVHVideoCodecProfile, hwaccel), - .def.i = 0, - }, - { - .type = PT_INT, - .id = "pix_fmt", - .name = N_("Pixel format"), - .desc = N_("Video pixel format."), - .group = 4, - .opts = PO_ADVANCED | PO_PHIDDEN, - .get_opts = codec_profile_video_class_pix_fmt_get_opts, - .off = offsetof(TVHVideoCodecProfile, pix_fmt), - .list = codec_profile_video_class_pix_fmt_list, - .def.i = AV_PIX_FMT_NONE, - }, - {} - } - }, - .setup = (codec_profile_is_copy_meth)tvh_codec_profile_video_setup, - .is_copy = (codec_profile_is_copy_meth)tvh_codec_profile_video_is_copy, - .open = (codec_profile_open_meth)tvh_codec_profile_video_open, + {.ic_super = (idclass_t*)&codec_profile_class, + .ic_class = "codec_profile_video", + .ic_caption = N_("video"), + .ic_properties = + (const property_t[]){{ + .type = PT_BOOL, + .id = "deinterlace", + .name = N_("Deinterlace"), + .desc = N_("Deinterlace."), + .group = 2, + .off = offsetof(TVHVideoCodecProfile, deinterlace), + .set = codec_profile_video_class_deinterlace_set, + .def.i = 1, + }, + { + .type = PT_INT, + .id = "height", + .name = N_("Height (pixels) (0=no scaling)"), + .desc = N_("Height of the output video stream. Horizontal resolution " + "is adjusted automatically to preserve aspect ratio. " + "When set to 0, the input resolution is used."), + .group = 2, + .off = offsetof(TVHVideoCodecProfile, height), + .def.i = 0, + }, + { + .type = PT_INT, + .id = "scaling_mode", + .name = N_("Scaling mode"), + .desc = N_("Allow control for scaling Up&Down, Up or Down"), + .group = 2, + .off = offsetof(TVHVideoCodecProfile, scaling_mode), + .list = scaling_mode_get_list, + .def.i = 0, + }, + { + .type = PT_BOOL, + .id = "hwaccel", + .name = N_("Hardware acceleration"), + .desc = N_("Use hardware acceleration for decoding if available."), + .group = 2, + .off = offsetof(TVHVideoCodecProfile, hwaccel), + .def.i = 0, + }, + { + .type = PT_INT, + .id = "pix_fmt", + .name = N_("Pixel format"), + .desc = N_("Video pixel format."), + .group = 4, + .opts = PO_ADVANCED | PO_PHIDDEN, + .get_opts = codec_profile_video_class_pix_fmt_get_opts, + .off = offsetof(TVHVideoCodecProfile, pix_fmt), + .list = codec_profile_video_class_pix_fmt_list, + .def.i = AV_PIX_FMT_NONE, + }, + {}}}, + .setup = (codec_profile_is_copy_meth)tvh_codec_profile_video_setup, + .is_copy = (codec_profile_is_copy_meth)tvh_codec_profile_video_is_copy, + .open = (codec_profile_open_meth)tvh_codec_profile_video_open, }; diff --git a/src/transcoding/memutils.c b/src/transcoding/memutils.c index f34eaec90..19d9501f4 100644 --- a/src/transcoding/memutils.c +++ b/src/transcoding/memutils.c @@ -17,99 +17,84 @@ * along with this program. If not, see . */ - #include "memutils.h" #include #include +static char* str_add(const char* sep, const char* str) { + size_t sep_len = strlen(sep), str_len = strlen(str); + char* result = malloc(sep_len + str_len + 1); -static char * -str_add(const char *sep, const char *str) -{ - size_t sep_len = strlen(sep), str_len = strlen(str); - char *result = malloc(sep_len + str_len + 1); - - if (result) { - if (str_len > 0) { - strcpy(result, sep); - strcat(result, str); - } else { - result[0] = '\0'; - } + if (result) { + if (str_len > 0) { + strcpy(result, sep); + strcat(result, str); + } else { + result[0] = '\0'; } - return result; + } + return result; } +static char* str_vjoin(const char* separator, va_list ap) { + const char *sep = separator ? separator : "", *va_str = NULL; + char * str = NULL, *tmp_result = NULL, *result = NULL; + size_t str_len = 0, result_size = 1; -static char * -str_vjoin(const char *separator, va_list ap) -{ - const char *sep = separator ? separator : "", *va_str = NULL; - char *str = NULL, *tmp_result = NULL, *result = NULL; - size_t str_len = 0, result_size = 1; - - result = calloc(1, result_size); - if (result == NULL) - return NULL; - while ((va_str = va_arg(ap, const char *))) { - str_len = strlen(va_str); - if (str_len == 0) - continue; - str = str_add(result[0] ? sep : "", va_str); - if (str) { - str_len = strlen(str); - if (str_len) { - if ((tmp_result = realloc(result, result_size + str_len))) { - result = tmp_result; - strcpy(result + result_size - 1, str); - result_size += str_len; - } else { - str_clear(str); - goto reterr; - } - } - str_clear(str); + result = calloc(1, result_size); + if (result == NULL) + return NULL; + while ((va_str = va_arg(ap, const char*))) { + str_len = strlen(va_str); + if (str_len == 0) + continue; + str = str_add(result[0] ? sep : "", va_str); + if (str) { + str_len = strlen(str); + if (str_len) { + if ((tmp_result = realloc(result, result_size + str_len))) { + result = tmp_result; + strcpy(result + result_size - 1, str); + result_size += str_len; } else { - goto reterr; + str_clear(str); + goto reterr; } + } + str_clear(str); + } else { + goto reterr; } - return result; + } + return result; reterr: - free(result); - return NULL; + free(result); + return NULL; } - -char * -str_join(const char *separator, ...) -{ - va_list ap; - va_start(ap, separator); - char *result = str_vjoin(separator, ap); - va_end(ap); - return result; +char* str_join(const char* separator, ...) { + va_list ap; + va_start(ap, separator); + char* result = str_vjoin(separator, ap); + va_end(ap); + return result; } - -int -str_snprintf(char *str, size_t size, const char *format, ...) -{ - va_list ap; - va_start(ap, format); - int ret = vsnprintf(str, size, format, ap); - va_end(ap); - return (ret < 0 || ret >= size) ? -1 : 0; +int str_snprintf(char* str, size_t size, const char* format, ...) { + va_list ap; + va_start(ap, format); + int ret = vsnprintf(str, size, format, ap); + va_end(ap); + return (ret < 0 || ret >= size) ? -1 : 0; } /* _IMPORTANT!_: need to check for pb->pb_size and pb->pb_data _BEFORE_ calling pktbuf_copy_data */ -uint8_t * -pktbuf_copy_data(pktbuf_t *pb) -{ - uint8_t *data = av_malloc(pb->pb_size + AV_INPUT_BUFFER_PADDING_SIZE); - if (data) - memcpy(data, pb->pb_data, pb->pb_size); - return data; +uint8_t* pktbuf_copy_data(pktbuf_t* pb) { + uint8_t* data = av_malloc(pb->pb_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (data) + memcpy(data, pb->pb_data, pb->pb_size); + return data; } diff --git a/src/transcoding/memutils.h b/src/transcoding/memutils.h index 3ca2c9ebe..63aa242d5 100644 --- a/src/transcoding/memutils.h +++ b/src/transcoding/memutils.h @@ -17,50 +17,44 @@ * along with this program. If not, see . */ - #ifndef TVH_TRANSCODING_MEMUTILS_H__ #define TVH_TRANSCODING_MEMUTILS_H__ - #include "tvheadend.h" #include "streaming.h" - #define TVH_INPUT_BUFFER_MAX_SIZE (INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) -#define TVHPKT_CLEAR(ptr) \ - do { \ - th_pkt_t *_tmp = (ptr); \ - if (_tmp != NULL) { \ - (ptr) = NULL; \ - pkt_ref_dec(_tmp); \ - } \ - } while (0) +#define TVHPKT_CLEAR(ptr) \ + do { \ + th_pkt_t* _tmp = (ptr); \ + if (_tmp != NULL) { \ + (ptr) = NULL; \ + pkt_ref_dec(_tmp); \ + } \ + } while (0) #define TVHPKT_SET(ptr, pkt) \ - do { \ - pkt_ref_inc((pkt)); \ - TVHPKT_CLEAR((ptr)); \ - (ptr) = (pkt); \ - } while (0) + do { \ + pkt_ref_inc((pkt)); \ + TVHPKT_CLEAR((ptr)); \ + (ptr) = (pkt); \ + } while (0) -#define str_clear(str) \ - do { \ - if ((str) != NULL) { \ - free((str)); \ - (str) = NULL; \ - } \ - } while (0) +#define str_clear(str) \ + do { \ + if ((str) != NULL) { \ + free((str)); \ + (str) = NULL; \ + } \ + } while (0) -char * -str_join(const char *separator, ...); +char* str_join(const char* separator, ...); -int -str_snprintf(char *str, size_t size, const char *format, ...); +int str_snprintf(char* str, size_t size, const char* format, ...); /* _IMPORTANT!_: need to check for pb->pb_size and pb->pb_data _BEFORE_ calling pktbuf_copy_data */ -uint8_t * -pktbuf_copy_data(pktbuf_t *pb); +uint8_t* pktbuf_copy_data(pktbuf_t* pb); #endif // TVH_TRANSCODING_MEMUTILS_H__ diff --git a/src/transcoding/transcode.h b/src/transcoding/transcode.h index 4708919bc..5522f384d 100644 --- a/src/transcoding/transcode.h +++ b/src/transcoding/transcode.h @@ -17,33 +17,23 @@ * along with this program. If not, see . */ - #ifndef TVH_TRANSCODING_TRANSCODE_H__ #define TVH_TRANSCODING_TRANSCODE_H__ - #include "tvheadend.h" #include "streaming.h" - /* TVHTranscoder ============================================================ */ -streaming_target_t * -transcoder_create(streaming_target_t *output, - const char **profiles, - const char **src_codecs); - -void -transcoder_destroy(streaming_target_t *st); +streaming_target_t* +transcoder_create(streaming_target_t* output, const char** profiles, const char** src_codecs); +void transcoder_destroy(streaming_target_t* st); /* module level ============================================================= */ -void -transcode_init(void); - -void -transcode_done(void); +void transcode_init(void); +void transcode_done(void); #endif // TVH_TRANSCODING_TRANSCODE_H__ diff --git a/src/transcoding/transcode/audio.c b/src/transcoding/transcode/audio.c index 27bc32b33..c75921a80 100644 --- a/src/transcoding/transcode/audio.c +++ b/src/transcoding/transcode/audio.c @@ -17,256 +17,235 @@ * along with this program. If not, see . */ - #include "internals.h" - -static enum AVSampleFormat -_audio_context_sample_fmt(TVHContext *self, AVDictionary **opts) -{ - const enum AVSampleFormat *sample_fmts = - tvh_codec_profile_audio_get_sample_fmts(self->profile); - enum AVSampleFormat ifmt = self->iavctx->sample_fmt; - enum AVSampleFormat ofmt = AV_SAMPLE_FMT_NONE; - enum AVSampleFormat altfmt = AV_SAMPLE_FMT_NONE; - int i; - - if (!tvh_context_get_int_opt(opts, "sample_fmt", &ofmt) && - ofmt == AV_SAMPLE_FMT_NONE) { - if (sample_fmts) { - for (i = 0; (ofmt = sample_fmts[i]) != AV_SAMPLE_FMT_NONE; i++) { - if (ofmt == ifmt) { - break; - } - } - altfmt = (ofmt != AV_SAMPLE_FMT_NONE) ? ofmt : sample_fmts[0]; - } - else { - altfmt = ifmt; +static enum AVSampleFormat _audio_context_sample_fmt(TVHContext* self, AVDictionary** opts) { + const enum AVSampleFormat* sample_fmts = tvh_codec_profile_audio_get_sample_fmts(self->profile); + enum AVSampleFormat ifmt = self->iavctx->sample_fmt; + enum AVSampleFormat ofmt = AV_SAMPLE_FMT_NONE; + enum AVSampleFormat altfmt = AV_SAMPLE_FMT_NONE; + int i; + + if (!tvh_context_get_int_opt(opts, "sample_fmt", &ofmt) && ofmt == AV_SAMPLE_FMT_NONE) { + if (sample_fmts) { + for (i = 0; (ofmt = sample_fmts[i]) != AV_SAMPLE_FMT_NONE; i++) { + if (ofmt == ifmt) { + break; } + } + altfmt = (ofmt != AV_SAMPLE_FMT_NONE) ? ofmt : sample_fmts[0]; + } else { + altfmt = ifmt; } - if (tvhtrace_enabled()) - tvh_context_log(self, LOG_TRACE, "audio format selection: old %s, alt %s, in %s", - av_get_sample_fmt_name(ofmt), - av_get_sample_fmt_name(altfmt), - av_get_sample_fmt_name(ifmt)); - return ofmt == AV_SAMPLE_FMT_NONE ? altfmt : ofmt; + } + if (tvhtrace_enabled()) + tvh_context_log(self, + LOG_TRACE, + "audio format selection: old %s, alt %s, in %s", + av_get_sample_fmt_name(ofmt), + av_get_sample_fmt_name(altfmt), + av_get_sample_fmt_name(ifmt)); + return ofmt == AV_SAMPLE_FMT_NONE ? altfmt : ofmt; } - -static int -_audio_context_sample_rate(TVHContext *self, AVDictionary **opts) -{ - const int *sample_rates = - tvh_codec_profile_audio_get_sample_rates(self->profile); - int irate = self->iavctx->sample_rate, altrate = 0, orate = 0, i; - - if (!tvh_context_get_int_opt(opts, "sample_rate", &orate) && - !orate && sample_rates) { - for (i = 0; (orate = sample_rates[i]); i++) { - if (orate == irate) { - break; - } - if (orate < irate) { - altrate = orate; - } - } +static int _audio_context_sample_rate(TVHContext* self, AVDictionary** opts) { + const int* sample_rates = tvh_codec_profile_audio_get_sample_rates(self->profile); + int irate = self->iavctx->sample_rate, altrate = 0, orate = 0, i; + + if (!tvh_context_get_int_opt(opts, "sample_rate", &orate) && !orate && sample_rates) { + for (i = 0; (orate = sample_rates[i]); i++) { + if (orate == irate) { + break; + } + if (orate < irate) { + altrate = orate; + } } - if (tvhtrace_enabled()) - tvh_context_log(self, LOG_TRACE, "audio rate selection: old %i, alt %i, in %i", - orate, altrate, irate); - return orate ? orate : (altrate ? altrate : 48000); + } + if (tvhtrace_enabled()) + tvh_context_log(self, + LOG_TRACE, + "audio rate selection: old %i, alt %i, in %i", + orate, + altrate, + irate); + return orate ? orate : (altrate ? altrate : 48000); } - -static uint64_t -_audio_context_channel_layout(TVHContext *self, AVDictionary **opts) -{ - const uint64_t *channel_layouts = - tvh_codec_profile_audio_get_channel_layouts(self->profile); - uint64_t ilayout = self->iavctx->channel_layout; - uint64_t altlayout = 0, olayout = 0; - int tmp = 0, ichannels = 0, i; - char obuf[64], abuf[64], ibuf[64]; - - if (!tvh_context_get_int_opt(opts, "channel_layout", &tmp) && - !(olayout = tmp) && channel_layouts) { - ichannels = av_get_channel_layout_nb_channels(ilayout); - for (i = 0; (olayout = channel_layouts[i]); i++) { - if (olayout == ilayout) { - break; - } - if (av_get_channel_layout_nb_channels(olayout) <= ichannels) { - altlayout = olayout; - } - } - } - if (tvhtrace_enabled()) { - strcpy(obuf, "none"); - av_get_channel_layout_string(obuf, sizeof(obuf), 0, olayout); - strcpy(abuf, "none"); - av_get_channel_layout_string(abuf, sizeof(abuf), 0, altlayout); - strcpy(ibuf, "none"); - av_get_channel_layout_string(ibuf, sizeof(ibuf), 0, ilayout); - tvh_context_log(self, LOG_TRACE, "audio layout selection: old %s, alt %s, in %s", - obuf, abuf, ibuf); +static uint64_t _audio_context_channel_layout(TVHContext* self, AVDictionary** opts) { + const uint64_t* channel_layouts = tvh_codec_profile_audio_get_channel_layouts(self->profile); + uint64_t ilayout = self->iavctx->channel_layout; + uint64_t altlayout = 0, olayout = 0; + int tmp = 0, ichannels = 0, i; + char obuf[64], abuf[64], ibuf[64]; + + if (!tvh_context_get_int_opt(opts, "channel_layout", &tmp) && !(olayout = tmp) && + channel_layouts) { + ichannels = av_get_channel_layout_nb_channels(ilayout); + for (i = 0; (olayout = channel_layouts[i]); i++) { + if (olayout == ilayout) { + break; + } + if (av_get_channel_layout_nb_channels(olayout) <= ichannels) { + altlayout = olayout; + } } - return olayout ? olayout : (altlayout ? altlayout : AV_CH_LAYOUT_STEREO); + } + if (tvhtrace_enabled()) { + strcpy(obuf, "none"); + av_get_channel_layout_string(obuf, sizeof(obuf), 0, olayout); + strcpy(abuf, "none"); + av_get_channel_layout_string(abuf, sizeof(abuf), 0, altlayout); + strcpy(ibuf, "none"); + av_get_channel_layout_string(ibuf, sizeof(ibuf), 0, ilayout); + tvh_context_log(self, + LOG_TRACE, + "audio layout selection: old %s, alt %s, in %s", + obuf, + abuf, + ibuf); + } + return olayout ? olayout : (altlayout ? altlayout : AV_CH_LAYOUT_STEREO); } - -static int -tvh_audio_context_open_encoder(TVHContext *self, AVDictionary **opts) -{ - // XXX: is this a safe assumption? - if (!self->iavctx->time_base.den) { - self->iavctx->time_base = av_make_q(1, 90000); - } - // sample_fmt - self->oavctx->sample_fmt = _audio_context_sample_fmt(self, opts); - if (self->oavctx->sample_fmt == AV_SAMPLE_FMT_NONE) { - tvh_context_log(self, LOG_ERR, - "audio encoder has no suitable sample format"); - return -1; - } - // sample_rate - self->oavctx->sample_rate = _audio_context_sample_rate(self, opts); - if (!self->oavctx->sample_rate) { - tvh_context_log(self, LOG_ERR, - "audio encoder has no suitable sample rate"); - return -1; - } - self->oavctx->time_base = av_make_q(1, self->oavctx->sample_rate); - self->sri = rate_to_sri(self->oavctx->sample_rate); - // channel_layout - self->oavctx->channel_layout = _audio_context_channel_layout(self, opts); - if (!self->oavctx->channel_layout) { - tvh_context_log(self, LOG_ERR, - "audio encoder has no suitable channel layout"); - return -1; - } - self->oavctx->channels = - av_get_channel_layout_nb_channels(self->oavctx->channel_layout); - return 0; +static int tvh_audio_context_open_encoder(TVHContext* self, AVDictionary** opts) { + // XXX: is this a safe assumption? + if (!self->iavctx->time_base.den) { + self->iavctx->time_base = av_make_q(1, 90000); + } + // sample_fmt + self->oavctx->sample_fmt = _audio_context_sample_fmt(self, opts); + if (self->oavctx->sample_fmt == AV_SAMPLE_FMT_NONE) { + tvh_context_log(self, LOG_ERR, "audio encoder has no suitable sample format"); + return -1; + } + // sample_rate + self->oavctx->sample_rate = _audio_context_sample_rate(self, opts); + if (!self->oavctx->sample_rate) { + tvh_context_log(self, LOG_ERR, "audio encoder has no suitable sample rate"); + return -1; + } + self->oavctx->time_base = av_make_q(1, self->oavctx->sample_rate); + self->sri = rate_to_sri(self->oavctx->sample_rate); + // channel_layout + self->oavctx->channel_layout = _audio_context_channel_layout(self, opts); + if (!self->oavctx->channel_layout) { + tvh_context_log(self, LOG_ERR, "audio encoder has no suitable channel layout"); + return -1; + } + self->oavctx->channels = av_get_channel_layout_nb_channels(self->oavctx->channel_layout); + return 0; } - -static int -tvh_audio_context_open_filters(TVHContext *self, AVDictionary **opts) -{ - char source_args[128]; - char filters[16]; - char layout[32]; - int resample = (self->iavctx->sample_rate != self->oavctx->sample_rate); - - // source args - memset(source_args, 0, sizeof(source_args)); - av_get_channel_layout_string(layout, sizeof(layout), self->iavctx->channels, self->iavctx->channel_layout); - if (str_snprintf(source_args, sizeof(source_args), - "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%s", - self->iavctx->time_base.num, - self->iavctx->time_base.den, - self->iavctx->sample_rate, - av_get_sample_fmt_name(self->iavctx->sample_fmt), - layout)) { - return -1; - } - - // resample also if there should be a format conversion - if (self->iavctx->sample_fmt != self->oavctx->sample_fmt) - resample = 1; - - // context filters - memset(filters, 0, sizeof(filters)); - if (str_snprintf(filters, sizeof(filters), "%s", - (resample) ? "aresample" : "anull")) { - return -1; - } - - int ret = tvh_context_open_filters(self, - "abuffer", source_args, // source - filters, // filters - "abuffersink", // sink - "channel_layouts", &self->oavctx->channel_layout, // sink option: channel_layout - sizeof(self->oavctx->channel_layout), - "sample_fmts", &self->oavctx->sample_fmt, // sink option: sample_fmt - sizeof(self->oavctx->sample_fmt), - "sample_rates", &self->oavctx->sample_rate, // sink option: sample_rate - sizeof(self->oavctx->sample_rate), - NULL); // _IMPORTANT!_ - if (!ret) { - av_buffersink_set_frame_size(self->oavfltctx, self->oavctx->frame_size); - } - return ret; +static int tvh_audio_context_open_filters(TVHContext* self, AVDictionary** opts) { + char source_args[128]; + char filters[16]; + char layout[32]; + int resample = (self->iavctx->sample_rate != self->oavctx->sample_rate); + + // source args + memset(source_args, 0, sizeof(source_args)); + av_get_channel_layout_string(layout, + sizeof(layout), + self->iavctx->channels, + self->iavctx->channel_layout); + if (str_snprintf(source_args, + sizeof(source_args), + "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=%s", + self->iavctx->time_base.num, + self->iavctx->time_base.den, + self->iavctx->sample_rate, + av_get_sample_fmt_name(self->iavctx->sample_fmt), + layout)) { + return -1; + } + + // resample also if there should be a format conversion + if (self->iavctx->sample_fmt != self->oavctx->sample_fmt) + resample = 1; + + // context filters + memset(filters, 0, sizeof(filters)); + if (str_snprintf(filters, sizeof(filters), "%s", (resample) ? "aresample" : "anull")) { + return -1; + } + + int ret = tvh_context_open_filters(self, + "abuffer", + source_args, // source + filters, // filters + "abuffersink", // sink + "channel_layouts", + &self->oavctx->channel_layout, // sink option: channel_layout + sizeof(self->oavctx->channel_layout), + "sample_fmts", + &self->oavctx->sample_fmt, // sink option: sample_fmt + sizeof(self->oavctx->sample_fmt), + "sample_rates", + &self->oavctx->sample_rate, // sink option: sample_rate + sizeof(self->oavctx->sample_rate), + NULL); // _IMPORTANT!_ + if (!ret) { + av_buffersink_set_frame_size(self->oavfltctx, self->oavctx->frame_size); + } + return ret; } - -static int -tvh_audio_context_open(TVHContext *self, TVHOpenPhase phase, AVDictionary **opts) -{ - switch (phase) { - case OPEN_ENCODER: - return tvh_audio_context_open_encoder(self, opts); - case OPEN_ENCODER_POST: - self->delta = av_rescale_q_rnd(self->oavctx->frame_size, - self->oavctx->time_base, - self->iavctx->time_base, - AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); - return tvh_audio_context_open_filters(self, opts); - default: - break; - } - return 0; +static int tvh_audio_context_open(TVHContext* self, TVHOpenPhase phase, AVDictionary** opts) { + switch (phase) { + case OPEN_ENCODER: + return tvh_audio_context_open_encoder(self, opts); + case OPEN_ENCODER_POST: + self->delta = av_rescale_q_rnd(self->oavctx->frame_size, + self->oavctx->time_base, + self->iavctx->time_base, + AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX); + return tvh_audio_context_open_filters(self, opts); + default: + break; + } + return 0; } - -static int -tvh_audio_context_decode(TVHContext *self, AVPacket *avpkt) -{ - int64_t prev_pts = self->pts; - int64_t new_pts = avpkt->pts - self->duration; - - // rounding error? - if (new_pts - 10 <= prev_pts && new_pts + 10 >= prev_pts) { - prev_pts = new_pts; - } - - if (prev_pts != (self->pts = new_pts) && prev_pts > 12000) { - tvh_context_log(self, LOG_WARNING, "Detected framedrop in audio (%"PRId64" != %"PRId64")", prev_pts, new_pts); - } - self->duration += avpkt->duration; - return 0; +static int tvh_audio_context_decode(TVHContext* self, AVPacket* avpkt) { + int64_t prev_pts = self->pts; + int64_t new_pts = avpkt->pts - self->duration; + + // rounding error? + if (new_pts - 10 <= prev_pts && new_pts + 10 >= prev_pts) { + prev_pts = new_pts; + } + + if (prev_pts != (self->pts = new_pts) && prev_pts > 12000) { + tvh_context_log(self, + LOG_WARNING, + "Detected framedrop in audio (%" PRId64 " != %" PRId64 ")", + prev_pts, + new_pts); + } + self->duration += avpkt->duration; + return 0; } - -static int -tvh_audio_context_encode(TVHContext *self, AVFrame *avframe) -{ - avframe->nb_samples = self->oavctx->frame_size; - avframe->pts = self->pts; - self->pts += self->delta; - self->duration -= self->delta; - return 0; +static int tvh_audio_context_encode(TVHContext* self, AVFrame* avframe) { + avframe->nb_samples = self->oavctx->frame_size; + avframe->pts = self->pts; + self->pts += self->delta; + self->duration -= self->delta; + return 0; } - -static int -tvh_audio_context_ship(TVHContext *self, AVPacket *avpkt) -{ - return (avpkt->pts >= 0); +static int tvh_audio_context_ship(TVHContext* self, AVPacket* avpkt) { + return (avpkt->pts >= 0); } - -static int -tvh_audio_context_wrap(TVHContext *self, AVPacket *avpkt, th_pkt_t *pkt) -{ - pkt->pkt_duration = avpkt->duration; - pkt->a.pkt_channels = self->oavctx->channels; - pkt->a.pkt_sri = self->sri; - return 0; +static int tvh_audio_context_wrap(TVHContext* self, AVPacket* avpkt, th_pkt_t* pkt) { + pkt->pkt_duration = avpkt->duration; + pkt->a.pkt_channels = self->oavctx->channels; + pkt->a.pkt_sri = self->sri; + return 0; } - TVHContextType TVHAudioContext = { .media_type = AVMEDIA_TYPE_AUDIO, .open = tvh_audio_context_open, diff --git a/src/transcoding/transcode/context.c b/src/transcoding/transcode/context.c index d951a9246..03aaff319 100644 --- a/src/transcoding/transcode/context.c +++ b/src/transcoding/transcode/context.c @@ -17,734 +17,620 @@ * along with this program. If not, see . */ - #include "internals.h" #include - -#define TVH_BUFFERSRC_FLAGS AV_BUFFERSRC_FLAG_PUSH | AV_BUFFERSRC_FLAG_KEEP_REF +#define TVH_BUFFERSRC_FLAGS AV_BUFFERSRC_FLAG_PUSH | AV_BUFFERSRC_FLAG_KEEP_REF #define TVH_BUFFERSINK_FLAGS AV_BUFFERSINK_FLAG_NO_REQUEST - /* TVHContextType =========================================================== */ extern TVHContextType TVHVideoContext; extern TVHContextType TVHAudioContext; - SLIST_HEAD(TVHContextTypes, tvh_context_type); static struct TVHContextTypes tvh_context_types; - -static void -tvh_context_type_register(TVHContextType *self) -{ - if (self->media_type <= AVMEDIA_TYPE_UNKNOWN || - self->media_type >= AVMEDIA_TYPE_NB || - !self->ship) { - tvherror(LS_TRANSCODE, "incomplete/wrong definition for context type"); - return; - } - SLIST_INSERT_HEAD(&tvh_context_types, self, link); - tvhinfo(LS_TRANSCODE, "'%s' context type registered", - av_get_media_type_string(self->media_type)); +static void tvh_context_type_register(TVHContextType* self) { + if (self->media_type <= AVMEDIA_TYPE_UNKNOWN || self->media_type >= AVMEDIA_TYPE_NB || + !self->ship) { + tvherror(LS_TRANSCODE, "incomplete/wrong definition for context type"); + return; + } + SLIST_INSERT_HEAD(&tvh_context_types, self, link); + tvhinfo(LS_TRANSCODE, "'%s' context type registered", av_get_media_type_string(self->media_type)); } +static TVHContextType* tvh_context_type_find(enum AVMediaType media_type) { + TVHContextType* type = NULL; -static TVHContextType * -tvh_context_type_find(enum AVMediaType media_type) -{ - TVHContextType *type = NULL; - - SLIST_FOREACH(type, &tvh_context_types, link) { - if (type->media_type == media_type) { - return type; - } + SLIST_FOREACH (type, &tvh_context_types, link) { + if (type->media_type == media_type) { + return type; } - return NULL; + } + return NULL; } - -void -tvh_context_types_register() -{ - SLIST_INIT(&tvh_context_types); - tvh_context_type_register(&TVHVideoContext); - tvh_context_type_register(&TVHAudioContext); +void tvh_context_types_register() { + SLIST_INIT(&tvh_context_types); + tvh_context_type_register(&TVHVideoContext); + tvh_context_type_register(&TVHAudioContext); } - -void -tvh_context_types_forget() -{ - tvhinfo(LS_TRANSCODE, "forgetting context types"); - while (!SLIST_EMPTY(&tvh_context_types)) { - SLIST_REMOVE_HEAD(&tvh_context_types, link); - } +void tvh_context_types_forget() { + tvhinfo(LS_TRANSCODE, "forgetting context types"); + while (!SLIST_EMPTY(&tvh_context_types)) { + SLIST_REMOVE_HEAD(&tvh_context_types, link); + } } - /* TVHContext =============================================================== */ // wrappers -static void -_context_print_opts(TVHContext *self, AVDictionary *opts) -{ - char *buffer = NULL; +static void _context_print_opts(TVHContext* self, AVDictionary* opts) { + char* buffer = NULL; - if (opts) { - av_dict_get_string(opts, &buffer, '=', ','); - tvh_context_log(self, LOG_DEBUG, "opts: %s", buffer); - av_freep(&buffer); - } + if (opts) { + av_dict_get_string(opts, &buffer, '=', ','); + tvh_context_log(self, LOG_DEBUG, "opts: %s", buffer); + av_freep(&buffer); + } } +static int _context_filters_apply_sink_options(TVHContext* self, va_list ap) { + const char* opt_name = NULL; + const uint8_t* opt_val = NULL; + int opt_size = 0; + int ret = -1; -static int -_context_filters_apply_sink_options(TVHContext *self, va_list ap) -{ - const char *opt_name = NULL; - const uint8_t *opt_val = NULL; - int opt_size = 0; - int ret = -1; - - while ((opt_name = va_arg(ap, const char *))) { - opt_val = va_arg(ap, const uint8_t *); - opt_size = va_arg(ap, int); - if ((ret = av_opt_set_bin(self->oavfltctx, opt_name, opt_val, opt_size, - AV_OPT_SEARCH_CHILDREN))) { - tvh_context_log(self, LOG_ERR, "filters: failed to set option: '%s'", - opt_name); - break; - } + while ((opt_name = va_arg(ap, const char*))) { + opt_val = va_arg(ap, const uint8_t*); + opt_size = va_arg(ap, int); + if ((ret = av_opt_set_bin(self->oavfltctx, + opt_name, + opt_val, + opt_size, + AV_OPT_SEARCH_CHILDREN))) { + tvh_context_log(self, LOG_ERR, "filters: failed to set option: '%s'", opt_name); + break; } - return ret; + } + return ret; } - -static int -_context_open(TVHContext *self, TVHOpenPhase phase, AVDictionary **opts) -{ - return (self->type->open) ? self->type->open(self, phase, opts) : 0; +static int _context_open(TVHContext* self, TVHOpenPhase phase, AVDictionary** opts) { + return (self->type->open) ? self->type->open(self, phase, opts) : 0; } - -static int -_context_decode(TVHContext *self, AVPacket *avpkt) -{ - return (self->type->decode) ? self->type->decode(self, avpkt) : 0; +static int _context_decode(TVHContext* self, AVPacket* avpkt) { + return (self->type->decode) ? self->type->decode(self, avpkt) : 0; } +static int _context_encode(TVHContext* self, AVFrame* avframe) { + return (self->type->encode) ? self->type->encode(self, avframe) : 0; + /*int ret = -1; -static int -_context_encode(TVHContext *self, AVFrame *avframe) -{ - return (self->type->encode) ? self->type->encode(self, avframe) : 0; - /*int ret = -1; - - if (!(ret = (self->type->encode) ? self->type->encode(self, avframe) : 0) && - (self->helper && self->helper->encode)) { - ret = self->helper->encode(self, avframe); - } - return ret;*/ + if (!(ret = (self->type->encode) ? self->type->encode(self, avframe) : 0) && + (self->helper && self->helper->encode)) { + ret = self->helper->encode(self, avframe); + } + return ret;*/ } - -static int -_context_meta(TVHContext *self, AVPacket *avpkt, th_pkt_t *pkt) -{ - if ((avpkt->flags & AV_PKT_FLAG_KEY) == 0) - return 0; - if (self->require_meta) { - if (self->helper && self->helper->meta) { - self->require_meta = self->helper->meta(self, avpkt, pkt); - if (self->require_meta == 0) - self->require_meta = 1; - } - else if (self->oavctx->extradata_size) { - pkt->pkt_meta = pktbuf_alloc(self->oavctx->extradata, - self->oavctx->extradata_size); - self->require_meta = (pkt->pkt_meta) ? 1 : -1; - } +static int _context_meta(TVHContext* self, AVPacket* avpkt, th_pkt_t* pkt) { + if ((avpkt->flags & AV_PKT_FLAG_KEY) == 0) + return 0; + if (self->require_meta) { + if (self->helper && self->helper->meta) { + self->require_meta = self->helper->meta(self, avpkt, pkt); + if (self->require_meta == 0) + self->require_meta = 1; + } else if (self->oavctx->extradata_size) { + pkt->pkt_meta = pktbuf_alloc(self->oavctx->extradata, self->oavctx->extradata_size); + self->require_meta = (pkt->pkt_meta) ? 1 : -1; } - return (self->require_meta < 0) ? -1 : 0; + } + return (self->require_meta < 0) ? -1 : 0; } - -static int -_context_wrap(TVHContext *self, AVPacket *avpkt, th_pkt_t *pkt) -{ - return (self->type->wrap) ? self->type->wrap(self, avpkt, pkt) : 0; +static int _context_wrap(TVHContext* self, AVPacket* avpkt, th_pkt_t* pkt) { + return (self->type->wrap) ? self->type->wrap(self, avpkt, pkt) : 0; } - // creation -static AVCodecContext * -tvh_context_alloc_avctx(TVHContext *context, const AVCodec *avcodec) -{ - AVCodecContext *avctx = NULL; +static AVCodecContext* tvh_context_alloc_avctx(TVHContext* context, const AVCodec* avcodec) { + AVCodecContext* avctx = NULL; - if ((avctx = avcodec_alloc_context3(avcodec))) { - avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; - avctx->opaque = context; - } - return avctx; + if ((avctx = avcodec_alloc_context3(avcodec))) { + avctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; + avctx->opaque = context; + } + return avctx; } +static int tvh_context_setup(TVHContext* self, const AVCodec* iavcodec, const AVCodec* oavcodec) { + enum AVMediaType media_type = iavcodec->type; + const char* media_type_name = av_get_media_type_string(media_type); -static int -tvh_context_setup(TVHContext *self, const AVCodec *iavcodec, const AVCodec *oavcodec) -{ - enum AVMediaType media_type = iavcodec->type; - const char *media_type_name = av_get_media_type_string(media_type); - - if (!(self->type = tvh_context_type_find(media_type))) { - tvh_stream_log(self->stream, LOG_ERR, - "failed to find context type for '%s' media type", - media_type_name ? media_type_name : ""); - return -1; - } - if (!(self->iavctx = tvh_context_alloc_avctx(self, iavcodec)) || - !(self->oavctx = tvh_context_alloc_avctx(self, oavcodec)) || - !(self->iavframe = av_frame_alloc()) || - !(self->oavframe = av_frame_alloc())) { - tvh_stream_log(self->stream, LOG_ERR, - "failed to allocate AVCodecContext/AVFrame"); - return -1; - } - return 0; + if (!(self->type = tvh_context_type_find(media_type))) { + tvh_stream_log(self->stream, + LOG_ERR, + "failed to find context type for '%s' media type", + media_type_name ? media_type_name : ""); + return -1; + } + if (!(self->iavctx = tvh_context_alloc_avctx(self, iavcodec)) || + !(self->oavctx = tvh_context_alloc_avctx(self, oavcodec)) || + !(self->iavframe = av_frame_alloc()) || !(self->oavframe = av_frame_alloc())) { + tvh_stream_log(self->stream, LOG_ERR, "failed to allocate AVCodecContext/AVFrame"); + return -1; + } + return 0; } - // open -static int -tvh_context_open(TVHContext *self, TVHOpenPhase phase) -{ - AVCodecContext *avctx = NULL; - TVHContextHelper *helper = NULL; - AVDictionary *opts = NULL; - int ret = 0; - - switch (phase) { - case OPEN_DECODER: - avctx = self->iavctx; - helper = tvh_decoder_helper_find(avctx->codec); - break; - case OPEN_ENCODER: - avctx = self->oavctx; - helper = self->helper = tvh_encoder_helper_find(avctx->codec); - ret = tvh_codec_profile_open(self->profile, &opts); - break; - default: - tvh_context_log(self, LOG_ERR, "invalid open phase"); - ret = AVERROR(EINVAL); - break; - } - if (!ret) { - _context_print_opts(self, opts); - ret = tvh_context_get_int_opt(&opts, "tvh_require_meta", - &self->require_meta); - if (!ret && !(ret = _context_open(self, phase, &opts)) && // pre open - !(ret = (helper && helper->open) ? helper->open(self, &opts) : 0) && // pre open - !(ret = avcodec_open2(avctx, NULL, &opts))) { // open - ret = _context_open(self, phase + 1, &opts); // post open - } - _context_print_opts(self, opts); - } - if (opts) { - av_dict_free(&opts); - } - return ret; +static int tvh_context_open(TVHContext* self, TVHOpenPhase phase) { + AVCodecContext* avctx = NULL; + TVHContextHelper* helper = NULL; + AVDictionary* opts = NULL; + int ret = 0; + + switch (phase) { + case OPEN_DECODER: + avctx = self->iavctx; + helper = tvh_decoder_helper_find(avctx->codec); + break; + case OPEN_ENCODER: + avctx = self->oavctx; + helper = self->helper = tvh_encoder_helper_find(avctx->codec); + ret = tvh_codec_profile_open(self->profile, &opts); + break; + default: + tvh_context_log(self, LOG_ERR, "invalid open phase"); + ret = AVERROR(EINVAL); + break; + } + if (!ret) { + _context_print_opts(self, opts); + ret = tvh_context_get_int_opt(&opts, "tvh_require_meta", &self->require_meta); + if (!ret && !(ret = _context_open(self, phase, &opts)) && // pre open + !(ret = (helper && helper->open) ? helper->open(self, &opts) : 0) && // pre open + !(ret = avcodec_open2(avctx, NULL, &opts))) { // open + ret = _context_open(self, phase + 1, &opts); // post open + } + _context_print_opts(self, opts); + } + if (opts) { + av_dict_free(&opts); + } + return ret; } - // shipping -static th_pkt_t * -tvh_context_pack(TVHContext *self, AVPacket *avpkt) -{ - th_pkt_t *pkt = NULL; - - if (self->helper && self->helper->pack) { - pkt = self->helper->pack(self, avpkt); - } else { - pkt = pkt_alloc(self->stream->type, avpkt->data, avpkt->size, avpkt->pts, avpkt->dts, 0); - } - if (!pkt) { - tvh_context_log(self, LOG_ERR, "failed to create packet"); - } else { - // FIXME: ugly hack - if (pkt->pkt_pcr == 0) - pkt->pkt_pcr = pkt->pkt_dts; - if (_context_meta(self, avpkt, pkt) || _context_wrap(self, avpkt, pkt)) - TVHPKT_CLEAR(pkt); - } - return pkt; -} - - -static int -tvh_context_ship(TVHContext *self, AVPacket *avpkt) -{ - th_pkt_t *pkt = NULL; - int ret = -1; - - if (((ret = self->type->ship(self, avpkt)) > 0) && - (pkt = tvh_context_pack(self, avpkt))) { - ret = tvh_context_deliver(self, pkt); - } - if ((ret = (ret != 0) ? -1 : ret)) { - av_packet_unref(avpkt); - } - return ret; +static th_pkt_t* tvh_context_pack(TVHContext* self, AVPacket* avpkt) { + th_pkt_t* pkt = NULL; + + if (self->helper && self->helper->pack) { + pkt = self->helper->pack(self, avpkt); + } else { + pkt = pkt_alloc(self->stream->type, avpkt->data, avpkt->size, avpkt->pts, avpkt->dts, 0); + } + if (!pkt) { + tvh_context_log(self, LOG_ERR, "failed to create packet"); + } else { + // FIXME: ugly hack + if (pkt->pkt_pcr == 0) + pkt->pkt_pcr = pkt->pkt_dts; + if (_context_meta(self, avpkt, pkt) || _context_wrap(self, avpkt, pkt)) + TVHPKT_CLEAR(pkt); + } + return pkt; +} + +static int tvh_context_ship(TVHContext* self, AVPacket* avpkt) { + th_pkt_t* pkt = NULL; + int ret = -1; + + if (((ret = self->type->ship(self, avpkt)) > 0) && (pkt = tvh_context_pack(self, avpkt))) { + ret = tvh_context_deliver(self, pkt); + } + if ((ret = (ret != 0) ? -1 : ret)) { + av_packet_unref(avpkt); + } + return ret; } - // encoding -static int -tvh_context_receive_packet(TVHContext *self) -{ - AVPacket avpkt; - int ret = -1; +static int tvh_context_receive_packet(TVHContext* self) { + AVPacket avpkt; + int ret = -1; - av_init_packet(&avpkt); - while ((ret = avcodec_receive_packet(self->oavctx, &avpkt)) != AVERROR(EAGAIN)) { - if (ret || (ret = tvh_context_ship(self, &avpkt))) { - break; - } + av_init_packet(&avpkt); + while ((ret = avcodec_receive_packet(self->oavctx, &avpkt)) != AVERROR(EAGAIN)) { + if (ret || (ret = tvh_context_ship(self, &avpkt))) { + break; } - return (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) ? 0 : ret; + } + return (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) ? 0 : ret; } +static int tvh_context_encode_frame(TVHContext* self, AVFrame* avframe) { + int ret = -1; -static int -tvh_context_encode_frame(TVHContext *self, AVFrame *avframe) -{ - int ret = -1; - - if (!(ret = avframe ? _context_encode(self, avframe) : 0)) { - while ((ret = avcodec_send_frame(self->oavctx, avframe)) == AVERROR(EAGAIN)) { - if ((ret = tvh_context_receive_packet(self))) { - break; - } - } - } - if (!ret) { - ret = tvh_context_receive_packet(self); - } - if ((ret = (ret == AVERROR_EOF) ? 0 : ret)) { - av_frame_unref(avframe); + if (!(ret = avframe ? _context_encode(self, avframe) : 0)) { + while ((ret = avcodec_send_frame(self->oavctx, avframe)) == AVERROR(EAGAIN)) { + if ((ret = tvh_context_receive_packet(self))) { + break; + } } - return ret; + } + if (!ret) { + ret = tvh_context_receive_packet(self); + } + if ((ret = (ret == AVERROR_EOF) ? 0 : ret)) { + av_frame_unref(avframe); + } + return ret; } +static int tvh_context_pull_frame(TVHContext* self, AVFrame* avframe) { + int ret = -1; -static int -tvh_context_pull_frame(TVHContext *self, AVFrame *avframe) -{ - int ret = -1; - - av_frame_unref(avframe); - ret = av_buffersink_get_frame_flags(self->oavfltctx, avframe, TVH_BUFFERSINK_FLAGS); - return (ret > 0) ? 0 : ret; + av_frame_unref(avframe); + ret = av_buffersink_get_frame_flags(self->oavfltctx, avframe, TVH_BUFFERSINK_FLAGS); + return (ret > 0) ? 0 : ret; } +static int tvh_context_push_frame(TVHContext* self, AVFrame* avframe) { + int ret = -1; -static int -tvh_context_push_frame(TVHContext *self, AVFrame *avframe) -{ - int ret = -1; - - ret = av_buffersrc_add_frame_flags(self->iavfltctx, avframe, TVH_BUFFERSRC_FLAGS); - return (ret > 0) ? 0 : ret; + ret = av_buffersrc_add_frame_flags(self->iavfltctx, avframe, TVH_BUFFERSRC_FLAGS); + return (ret > 0) ? 0 : ret; } +static int tvh_context_encode(TVHContext* self, AVFrame* avframe) { + int ret = 0; -static int -tvh_context_encode(TVHContext *self, AVFrame *avframe) -{ - int ret = 0; - - if (!avcodec_is_open(self->oavctx)) { - ret = tvh_context_open(self, OPEN_ENCODER); + if (!avcodec_is_open(self->oavctx)) { + ret = tvh_context_open(self, OPEN_ENCODER); + } + if (!ret && !(ret = tvh_context_push_frame(self, avframe))) { + while ((ret = tvh_context_pull_frame(self, self->oavframe)) != AVERROR(EAGAIN)) { + if (ret || (ret = tvh_context_encode_frame(self, self->oavframe))) { + break; + } } - if (!ret && !(ret = tvh_context_push_frame(self, avframe))) { - while ((ret = tvh_context_pull_frame(self, self->oavframe)) != AVERROR(EAGAIN)) { - if (ret || (ret = tvh_context_encode_frame(self, self->oavframe))) { - break; - } - } - } - if ((ret = (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) ? 0 : ret)) { - av_frame_unref(avframe); - } - return ret; + } + if ((ret = (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) ? 0 : ret)) { + av_frame_unref(avframe); + } + return ret; } - // decoding -static int -tvh_context_receive_frame(TVHContext *self, AVFrame *avframe) -{ - int ret = -1; +static int tvh_context_receive_frame(TVHContext* self, AVFrame* avframe) { + int ret = -1; - while ((ret = avcodec_receive_frame(self->iavctx, avframe)) != AVERROR(EAGAIN)) { - if (ret || (ret = tvh_context_encode(self, avframe))) { - break; - } + while ((ret = avcodec_receive_frame(self->iavctx, avframe)) != AVERROR(EAGAIN)) { + if (ret || (ret = tvh_context_encode(self, avframe))) { + break; } - return (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) ? 0 : ret; + } + return (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) ? 0 : ret; } +static int tvh_context_decode_packet(TVHContext* self, const AVPacket* avpkt) { + int ret = -1; -static int -tvh_context_decode_packet(TVHContext *self, const AVPacket *avpkt) -{ - int ret = -1; - - while ((ret = avcodec_send_packet(self->iavctx, avpkt)) == AVERROR(EAGAIN)) { - if ((ret = tvh_context_receive_frame(self, self->iavframe))) { - break; - } + while ((ret = avcodec_send_packet(self->iavctx, avpkt)) == AVERROR(EAGAIN)) { + if ((ret = tvh_context_receive_frame(self, self->iavframe))) { + break; } - if (!ret) { - ret = tvh_context_receive_frame(self, self->iavframe); - } - return (ret == AVERROR_EOF) ? 0 : ret; + } + if (!ret) { + ret = tvh_context_receive_frame(self, self->iavframe); + } + return (ret == AVERROR_EOF) ? 0 : ret; } +static int tvh_context_decode(TVHContext* self, AVPacket* avpkt) { + int ret = 0; -static int -tvh_context_decode(TVHContext *self, AVPacket *avpkt) -{ - int ret = 0; - - if (!avcodec_is_open(self->iavctx)) { - ret = tvh_context_open(self, OPEN_DECODER); - } - if (!ret && !(ret = _context_decode(self, avpkt))) { - ret = tvh_context_decode_packet(self, avpkt); - } - return (ret == AVERROR(EAGAIN) || ret == AVERROR_INVALIDDATA) ? 0 : ret; + if (!avcodec_is_open(self->iavctx)) { + ret = tvh_context_open(self, OPEN_DECODER); + } + if (!ret && !(ret = _context_decode(self, avpkt))) { + ret = tvh_context_decode_packet(self, avpkt); + } + return (ret == AVERROR(EAGAIN) || ret == AVERROR_INVALIDDATA) ? 0 : ret; } - -static void -tvh_context_flush(TVHContext *self) -{ - tvh_context_decode_packet(self, NULL); - tvh_context_encode_frame(self, NULL); +static void tvh_context_flush(TVHContext* self) { + tvh_context_decode_packet(self, NULL); + tvh_context_encode_frame(self, NULL); } - /* exposed */ -int -tvh_context_get_int_opt(AVDictionary **opts, const char *key, int *value) -{ - AVDictionaryEntry *entry = NULL; - - if (*opts && - (entry = av_dict_get(*opts, key, NULL, AV_DICT_MATCH_CASE))) { - *value = atoi(entry->value); - return (av_dict_set(opts, key, NULL, 0) < 0) ? -1 : 0; - } - return 0; -} - - -int -tvh_context_get_str_opt(AVDictionary **opts, const char *key, char **value) -{ - AVDictionaryEntry *entry = NULL; - - if (*opts && - (entry = av_dict_get(*opts, key, NULL, AV_DICT_MATCH_CASE))) { - *value = strdup(entry->value); - return (av_dict_set(opts, key, NULL, 0) < 0) ? -1 : 0; - } - return 0; -} - - -void -tvh_context_close(TVHContext *self, int flush) -{ - if (flush) { - tvh_context_flush(self); - } - if (self->type->close) { - self->type->close(self); - } -} - - -int -tvh_context_open_filters(TVHContext *self, - const char *source_name, const char *source_args, - const char *filters, const char *sink_name, ...) -{ - static const AVClass logclass = { - .class_name = "TVHGraph", - .version = 1, - }; - struct { - const AVClass *class; - } logctx = { &logclass }; - const AVFilter *iavflt = NULL, *oavflt = NULL; - AVFilterInOut *iavfltio = NULL, *oavfltio = NULL; - AVBufferSrcParameters *par = NULL; - int i, ret = -1; - - tvh_context_log(self, LOG_DEBUG, "filters: source args: '%s'", source_args); - tvh_context_log(self, LOG_DEBUG, "filters: filters: '%s'", filters); - - if (!(self->avfltgraph = avfilter_graph_alloc()) || - !(iavfltio = avfilter_inout_alloc()) || - !(oavfltio = avfilter_inout_alloc()) || - !(par = av_buffersrc_parameters_alloc())) { - ret = AVERROR(ENOMEM); - goto finish; - } - - // source - if (!(iavflt = avfilter_get_by_name(source_name))) { - tvh_context_log(self, LOG_ERR, "filters: source filter'%s' not found", - source_name); - ret = AVERROR_FILTER_NOT_FOUND; - goto finish; - } - ret = avfilter_graph_create_filter(&self->iavfltctx, iavflt, "in", - source_args, NULL, self->avfltgraph); +int tvh_context_get_int_opt(AVDictionary** opts, const char* key, int* value) { + AVDictionaryEntry* entry = NULL; + + if (*opts && (entry = av_dict_get(*opts, key, NULL, AV_DICT_MATCH_CASE))) { + *value = atoi(entry->value); + return (av_dict_set(opts, key, NULL, 0) < 0) ? -1 : 0; + } + return 0; +} + +int tvh_context_get_str_opt(AVDictionary** opts, const char* key, char** value) { + AVDictionaryEntry* entry = NULL; + + if (*opts && (entry = av_dict_get(*opts, key, NULL, AV_DICT_MATCH_CASE))) { + *value = strdup(entry->value); + return (av_dict_set(opts, key, NULL, 0) < 0) ? -1 : 0; + } + return 0; +} + +void tvh_context_close(TVHContext* self, int flush) { + if (flush) { + tvh_context_flush(self); + } + if (self->type->close) { + self->type->close(self); + } +} + +int tvh_context_open_filters(TVHContext* self, + const char* source_name, + const char* source_args, + const char* filters, + const char* sink_name, + ...) { + static const AVClass logclass = { + .class_name = "TVHGraph", + .version = 1, + }; + struct { + const AVClass* class; + } logctx = {&logclass}; + const AVFilter * iavflt = NULL, *oavflt = NULL; + AVFilterInOut * iavfltio = NULL, *oavfltio = NULL; + AVBufferSrcParameters* par = NULL; + int i, ret = -1; + + tvh_context_log(self, LOG_DEBUG, "filters: source args: '%s'", source_args); + tvh_context_log(self, LOG_DEBUG, "filters: filters: '%s'", filters); + + if (!(self->avfltgraph = avfilter_graph_alloc()) || !(iavfltio = avfilter_inout_alloc()) || + !(oavfltio = avfilter_inout_alloc()) || !(par = av_buffersrc_parameters_alloc())) { + ret = AVERROR(ENOMEM); + goto finish; + } + + // source + if (!(iavflt = avfilter_get_by_name(source_name))) { + tvh_context_log(self, LOG_ERR, "filters: source filter'%s' not found", source_name); + ret = AVERROR_FILTER_NOT_FOUND; + goto finish; + } + ret = avfilter_graph_create_filter(&self->iavfltctx, + iavflt, + "in", + source_args, + NULL, + self->avfltgraph); + if (ret < 0) { + tvh_context_log(self, LOG_ERR, "filters: failed to create 'in' filter"); + goto finish; + } + + // additional buffersrc params + if (!strcmp("buffer", source_name) && self->iavctx->hw_frames_ctx) { // hmm... + memset(par, 0, sizeof(AVBufferSrcParameters)); + par->format = AV_PIX_FMT_NONE; + par->hw_frames_ctx = self->iavctx->hw_frames_ctx; + ret = av_buffersrc_parameters_set(self->iavfltctx, par); if (ret < 0) { - tvh_context_log(self, LOG_ERR, "filters: failed to create 'in' filter"); + tvh_context_log(self, LOG_ERR, "filters: failed to set additional parameters"); + goto finish; + } + } + + // sink + if (!(oavflt = avfilter_get_by_name(sink_name))) { + tvh_context_log(self, LOG_ERR, "filters: sink filter '%s' not found", sink_name); + ret = AVERROR_FILTER_NOT_FOUND; + goto finish; + } + ret = avfilter_graph_create_filter(&self->oavfltctx, oavflt, "out", NULL, NULL, self->avfltgraph); + if (ret < 0) { + tvh_context_log(self, LOG_ERR, "filters: failed to create 'out' filter"); + goto finish; + } + + // sink options + va_list ap; + va_start(ap, sink_name); + ret = _context_filters_apply_sink_options(self, ap); + va_end(ap); + if (ret) { + goto finish; + } + + // Endpoints for the filter graph. + iavfltio->name = av_strdup("out"); + iavfltio->filter_ctx = self->oavfltctx; + iavfltio->pad_idx = 0; + iavfltio->next = NULL; + + oavfltio->name = av_strdup("in"); + oavfltio->filter_ctx = self->iavfltctx; + oavfltio->pad_idx = 0; + oavfltio->next = NULL; + + if (!iavfltio->name || !oavfltio->name) { + ret = AVERROR(ENOMEM); + goto finish; + } + + // filters + ret = avfilter_graph_parse_ptr(self->avfltgraph, filters, &iavfltio, &oavfltio, NULL); + if (ret < 0) { + tvh_context_log(self, LOG_ERR, "filters: failed to add filters: '%s'", filters); + goto finish; + } + + // additional filtergraph params + if (!strcmp("buffer", source_name) && self->hw_device_octx) { + for (i = 0; i < self->avfltgraph->nb_filters; i++) { + if (!(self->avfltgraph->filters[i]->hw_device_ctx = av_buffer_ref(self->hw_device_octx))) { + ret = -1; goto finish; + } } + } - // additional buffersrc params - if (!strcmp("buffer", source_name) && self->iavctx->hw_frames_ctx) { // hmm... - memset(par, 0, sizeof(AVBufferSrcParameters)); - par->format = AV_PIX_FMT_NONE; - par->hw_frames_ctx = self->iavctx->hw_frames_ctx; - ret = av_buffersrc_parameters_set(self->iavfltctx, par); - if (ret < 0) { - tvh_context_log(self, LOG_ERR, - "filters: failed to set additional parameters"); - goto finish; - } - } + avfilter_graph_set_auto_convert(self->avfltgraph, AVFILTER_AUTO_CONVERT_ALL); - // sink - if (!(oavflt = avfilter_get_by_name(sink_name))) { - tvh_context_log(self, LOG_ERR, "filters: sink filter '%s' not found", - sink_name); - ret = AVERROR_FILTER_NOT_FOUND; - goto finish; - } - ret = avfilter_graph_create_filter(&self->oavfltctx, oavflt, "out", - NULL, NULL, self->avfltgraph); - if (ret < 0) { - tvh_context_log(self, LOG_ERR, "filters: failed to create 'out' filter"); - goto finish; - } - - // sink options - va_list ap; - va_start(ap, sink_name); - ret = _context_filters_apply_sink_options(self, ap); - va_end(ap); - if (ret) { - goto finish; - } - - // Endpoints for the filter graph. - iavfltio->name = av_strdup("out"); - iavfltio->filter_ctx = self->oavfltctx; - iavfltio->pad_idx = 0; - iavfltio->next = NULL; + if ((ret = avfilter_graph_config(self->avfltgraph, &logctx)) < 0) { + tvh_context_log(self, LOG_ERR, "filters: failed to config filter graph"); + } - oavfltio->name = av_strdup("in"); - oavfltio->filter_ctx = self->iavfltctx; - oavfltio->pad_idx = 0; - oavfltio->next = NULL; - - if (!iavfltio->name || !oavfltio->name) { - ret = AVERROR(ENOMEM); - goto finish; - } - - // filters - ret = avfilter_graph_parse_ptr(self->avfltgraph, filters, - &iavfltio, &oavfltio, NULL); - if (ret < 0) { - tvh_context_log(self, LOG_ERR, "filters: failed to add filters: '%s'", - filters); - goto finish; - } - - // additional filtergraph params - if (!strcmp("buffer", source_name) && self->hw_device_octx) { - for (i = 0; i < self->avfltgraph->nb_filters; i++) { - if (!(self->avfltgraph->filters[i]->hw_device_ctx = - av_buffer_ref(self->hw_device_octx))) { - ret = -1; - goto finish; - } - } - } - - avfilter_graph_set_auto_convert(self->avfltgraph, - AVFILTER_AUTO_CONVERT_ALL); - - if ((ret = avfilter_graph_config(self->avfltgraph, &logctx)) < 0) { - tvh_context_log(self, LOG_ERR, "filters: failed to config filter graph"); - } - - if (ret >= 0 && tvhtrace_enabled()) { - char *graph = avfilter_graph_dump(self->avfltgraph, NULL); - char *str, *token, *saveptr = NULL; - for (str = graph; ; str = NULL) { - token = strtok_r(str, "\n", &saveptr); - if (token == NULL) - break; - tvh_context_log(self, LOG_TRACE, "filters dump: %s", token); - } - av_freep(&graph); + if (ret >= 0 && tvhtrace_enabled()) { + char* graph = avfilter_graph_dump(self->avfltgraph, NULL); + char *str, *token, *saveptr = NULL; + for (str = graph;; str = NULL) { + token = strtok_r(str, "\n", &saveptr); + if (token == NULL) + break; + tvh_context_log(self, LOG_TRACE, "filters dump: %s", token); } + av_freep(&graph); + } finish: - if (par) { - av_freep(&par); - } - if (iavfltio) { - avfilter_inout_free(&iavfltio); - } - if (oavfltio) { - avfilter_inout_free(&oavfltio); - } - return (ret > 0) ? 0 : ret; -} - - -int -tvh_context_deliver(TVHContext *self, th_pkt_t *pkt) -{ - return tvh_stream_deliver(self->stream, pkt); -} - - -int -tvh_context_handle(TVHContext *self, th_pkt_t *pkt) -{ - int ret = 0; - uint8_t *data = NULL; - size_t size = 0; - AVPacket avpkt; - - if ((size = pktbuf_len(pkt->pkt_payload)) && pktbuf_ptr(pkt->pkt_payload)) { - if (size >= TVH_INPUT_BUFFER_MAX_SIZE) { - tvh_context_log(self, LOG_ERR, "packet payload too big"); - ret = AVERROR(EOVERFLOW); - } - else if (!(data = pktbuf_copy_data(pkt->pkt_payload))) { - tvh_context_log(self, LOG_ERR, "failed to copy packet payload"); - ret = AVERROR(ENOMEM); - } - else { - av_init_packet(&avpkt); - if ((ret = av_packet_from_data(&avpkt, data, size))) { // takes ownership of data - tvh_context_log(self, LOG_ERR, - "failed to allocate AVPacket buffer"); - av_freep(data); - } - else { - if (!self->input_gh && pkt->pkt_meta) { - pktbuf_ref_inc(pkt->pkt_meta); - self->input_gh = pkt->pkt_meta; - } - avpkt.pts = pkt->pkt_pts; - avpkt.dts = pkt->pkt_dts; - avpkt.duration = pkt->pkt_duration; - TVHPKT_SET(self->src_pkt, pkt); - ret = tvh_context_decode(self, &avpkt); - av_packet_unref(&avpkt); // will free data - } - } - } - return ret; -} - - -TVHContext * -tvh_context_create(TVHStream *stream, TVHCodecProfile *profile, - const AVCodec *iavcodec, const AVCodec *oavcodec, pktbuf_t *input_gh) -{ - TVHContext *self = NULL; - - if (!(self = calloc(1, sizeof(TVHContext)))) { - tvh_stream_log(stream, LOG_ERR, "failed to allocate context"); - return NULL; - } - self->stream = stream; - self->profile = profile; - if (tvh_context_setup(self, iavcodec, oavcodec)) { - tvh_context_destroy(self); - return NULL; - } - if (input_gh) { - pktbuf_ref_inc(input_gh); - self->input_gh = input_gh; - } - return self; -} - - -void -tvh_context_destroy(TVHContext *self) -{ - if (self) { - tvh_context_close(self, 0); - TVHPKT_CLEAR(self->src_pkt); - if (self->avfltgraph) { - avfilter_graph_free(&self->avfltgraph); // frees filter contexts - self->oavfltctx = NULL; - self->iavfltctx = NULL; - self->avfltgraph = NULL; - } - if (self->helper) { - self->helper = NULL; - } - if (self->input_gh) { - pktbuf_ref_dec(self->input_gh); - self->input_gh = NULL; - } - if (self->oavframe) { - av_frame_free(&self->oavframe); - self->oavframe = NULL; - } - if (self->iavframe) { - av_frame_free(&self->iavframe); - self->iavframe = NULL; - } - if (self->oavctx) { - avcodec_free_context(&self->oavctx); // frees extradata - self->oavctx = NULL; - } - if (self->iavctx) { - avcodec_free_context(&self->iavctx); - self->iavctx = NULL; + if (par) { + av_freep(&par); + } + if (iavfltio) { + avfilter_inout_free(&iavfltio); + } + if (oavfltio) { + avfilter_inout_free(&oavfltio); + } + return (ret > 0) ? 0 : ret; +} + +int tvh_context_deliver(TVHContext* self, th_pkt_t* pkt) { + return tvh_stream_deliver(self->stream, pkt); +} + +int tvh_context_handle(TVHContext* self, th_pkt_t* pkt) { + int ret = 0; + uint8_t* data = NULL; + size_t size = 0; + AVPacket avpkt; + + if ((size = pktbuf_len(pkt->pkt_payload)) && pktbuf_ptr(pkt->pkt_payload)) { + if (size >= TVH_INPUT_BUFFER_MAX_SIZE) { + tvh_context_log(self, LOG_ERR, "packet payload too big"); + ret = AVERROR(EOVERFLOW); + } else if (!(data = pktbuf_copy_data(pkt->pkt_payload))) { + tvh_context_log(self, LOG_ERR, "failed to copy packet payload"); + ret = AVERROR(ENOMEM); + } else { + av_init_packet(&avpkt); + if ((ret = av_packet_from_data(&avpkt, data, size))) { // takes ownership of data + tvh_context_log(self, LOG_ERR, "failed to allocate AVPacket buffer"); + av_freep(data); + } else { + if (!self->input_gh && pkt->pkt_meta) { + pktbuf_ref_inc(pkt->pkt_meta); + self->input_gh = pkt->pkt_meta; } - self->type = NULL; - self->profile = NULL; - self->stream = NULL; - free(self->hw_accel_device); - free(self); - self = NULL; - } + avpkt.pts = pkt->pkt_pts; + avpkt.dts = pkt->pkt_dts; + avpkt.duration = pkt->pkt_duration; + TVHPKT_SET(self->src_pkt, pkt); + ret = tvh_context_decode(self, &avpkt); + av_packet_unref(&avpkt); // will free data + } + } + } + return ret; +} + +TVHContext* tvh_context_create(TVHStream* stream, + TVHCodecProfile* profile, + const AVCodec* iavcodec, + const AVCodec* oavcodec, + pktbuf_t* input_gh) { + TVHContext* self = NULL; + + if (!(self = calloc(1, sizeof(TVHContext)))) { + tvh_stream_log(stream, LOG_ERR, "failed to allocate context"); + return NULL; + } + self->stream = stream; + self->profile = profile; + if (tvh_context_setup(self, iavcodec, oavcodec)) { + tvh_context_destroy(self); + return NULL; + } + if (input_gh) { + pktbuf_ref_inc(input_gh); + self->input_gh = input_gh; + } + return self; +} + +void tvh_context_destroy(TVHContext* self) { + if (self) { + tvh_context_close(self, 0); + TVHPKT_CLEAR(self->src_pkt); + if (self->avfltgraph) { + avfilter_graph_free(&self->avfltgraph); // frees filter contexts + self->oavfltctx = NULL; + self->iavfltctx = NULL; + self->avfltgraph = NULL; + } + if (self->helper) { + self->helper = NULL; + } + if (self->input_gh) { + pktbuf_ref_dec(self->input_gh); + self->input_gh = NULL; + } + if (self->oavframe) { + av_frame_free(&self->oavframe); + self->oavframe = NULL; + } + if (self->iavframe) { + av_frame_free(&self->iavframe); + self->iavframe = NULL; + } + if (self->oavctx) { + avcodec_free_context(&self->oavctx); // frees extradata + self->oavctx = NULL; + } + if (self->iavctx) { + avcodec_free_context(&self->iavctx); + self->iavctx = NULL; + } + self->type = NULL; + self->profile = NULL; + self->stream = NULL; + free(self->hw_accel_device); + free(self); + self = NULL; + } } diff --git a/src/transcoding/transcode/helpers.c b/src/transcoding/transcode/helpers.c index bd23c3e5e..0100669cd 100644 --- a/src/transcoding/transcode/helpers.c +++ b/src/transcoding/transcode/helpers.c @@ -17,7 +17,6 @@ * along with this program. If not, see . */ - #include "internals.h" #include "parsers/parsers.h" @@ -26,89 +25,76 @@ #include "parsers/parser_h264.h" #include "parsers/parser_hevc.h" - SLIST_HEAD(TVHContextHelpers, tvh_context_helper); static struct TVHContextHelpers tvh_decoder_helpers; static struct TVHContextHelpers tvh_encoder_helpers; - -#define tvh_context_helper_register(list, helper, kind) \ - do { \ - if ((helper)->type <= AVMEDIA_TYPE_UNKNOWN || \ - (helper)->type >= AVMEDIA_TYPE_NB) { \ - tvherror(LS_TRANSCODE, \ - "incomplete/wrong definition for " #helper " helper"); \ - return; \ - } \ - SLIST_INSERT_HEAD((list), (helper), link); \ - tvhinfo(LS_TRANSCODE, "'" #helper "' %s helper registered", (kind)); \ - } while (0) - -#define tvh_decoder_helper_register(helper) \ - do { \ - if (!(helper)->open) { \ - tvherror(LS_TRANSCODE, \ - "incomplete/wrong definition for " #helper " helper"); \ - return; \ - } \ - tvh_context_helper_register(&tvh_decoder_helpers, helper, "decoder"); \ - } while (0) - -#define tvh_encoder_helper_register(helper) \ - do { \ - if (!((helper)->open || (helper)->pack || (helper)->meta)) { \ - tvherror(LS_TRANSCODE, \ - "incomplete/wrong definition for " #helper " helper"); \ - return; \ - } \ - tvh_context_helper_register(&tvh_encoder_helpers, helper, "encoder"); \ - } while (0) - - -static TVHContextHelper * -tvh_context_helper_find(struct TVHContextHelpers *list, const AVCodec *codec) -{ - TVHContextHelper *helper = NULL; - - SLIST_FOREACH(helper, list, link) { - if (helper->type == codec->type && helper->id == codec->id) { - return helper; - } +#define tvh_context_helper_register(list, helper, kind) \ + do { \ + if ((helper)->type <= AVMEDIA_TYPE_UNKNOWN || (helper)->type >= AVMEDIA_TYPE_NB) { \ + tvherror(LS_TRANSCODE, "incomplete/wrong definition for " #helper " helper"); \ + return; \ + } \ + SLIST_INSERT_HEAD((list), (helper), link); \ + tvhinfo(LS_TRANSCODE, "'" #helper "' %s helper registered", (kind)); \ + } while (0) + +#define tvh_decoder_helper_register(helper) \ + do { \ + if (!(helper)->open) { \ + tvherror(LS_TRANSCODE, "incomplete/wrong definition for " #helper " helper"); \ + return; \ + } \ + tvh_context_helper_register(&tvh_decoder_helpers, helper, "decoder"); \ + } while (0) + +#define tvh_encoder_helper_register(helper) \ + do { \ + if (!((helper)->open || (helper)->pack || (helper)->meta)) { \ + tvherror(LS_TRANSCODE, "incomplete/wrong definition for " #helper " helper"); \ + return; \ + } \ + tvh_context_helper_register(&tvh_encoder_helpers, helper, "encoder"); \ + } while (0) + +static TVHContextHelper* tvh_context_helper_find(struct TVHContextHelpers* list, + const AVCodec* codec) { + TVHContextHelper* helper = NULL; + + SLIST_FOREACH (helper, list, link) { + if (helper->type == codec->type && helper->id == codec->id) { + return helper; } - return NULL; + } + return NULL; } - /* decoders ================================================================= */ /* shared by H264, AAC and VORBIS */ -static int -tvh_extradata_open(TVHContext *self, AVDictionary **opts) -{ - size_t extradata_size = 0; - - if (!(extradata_size = pktbuf_len(self->input_gh))) { - return AVERROR(EAGAIN); - } - if (extradata_size >= TVH_INPUT_BUFFER_MAX_SIZE) { - tvh_context_log(self, LOG_ERR, "extradata too big"); - return AVERROR(EOVERFLOW); - } - if (self->iavctx->extradata) { - tvh_context_log(self, LOG_ERR, "extradata already set!"); - return AVERROR(EALREADY); - } - if (!(self->iavctx->extradata = - av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE))) { - tvh_context_log(self, LOG_ERR, "failed to alloc extradata"); - return AVERROR(ENOMEM); - } - memcpy(self->iavctx->extradata, pktbuf_ptr(self->input_gh), extradata_size); - self->iavctx->extradata_size = extradata_size; - return 0; +static int tvh_extradata_open(TVHContext* self, AVDictionary** opts) { + size_t extradata_size = 0; + + if (!(extradata_size = pktbuf_len(self->input_gh))) { + return AVERROR(EAGAIN); + } + if (extradata_size >= TVH_INPUT_BUFFER_MAX_SIZE) { + tvh_context_log(self, LOG_ERR, "extradata too big"); + return AVERROR(EOVERFLOW); + } + if (self->iavctx->extradata) { + tvh_context_log(self, LOG_ERR, "extradata already set!"); + return AVERROR(EALREADY); + } + if (!(self->iavctx->extradata = av_mallocz(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE))) { + tvh_context_log(self, LOG_ERR, "failed to alloc extradata"); + return AVERROR(ENOMEM); + } + memcpy(self->iavctx->extradata, pktbuf_ptr(self->input_gh), extradata_size); + self->iavctx->extradata_size = extradata_size; + return 0; } - /* H264 */ static TVHContextHelper TVHH264Decoder = { .type = AVMEDIA_TYPE_VIDEO, @@ -123,7 +109,6 @@ static TVHContextHelper TVHTHEORADecoder = { .open = tvh_extradata_open, }; - /* AAC */ static TVHContextHelper TVHAACDecoder = { .type = AVMEDIA_TYPE_AUDIO, @@ -131,7 +116,6 @@ static TVHContextHelper TVHAACDecoder = { .open = tvh_extradata_open, }; - /* VORBIS */ static TVHContextHelper TVHVORBISDecoder = { .type = AVMEDIA_TYPE_AUDIO, @@ -139,7 +123,6 @@ static TVHContextHelper TVHVORBISDecoder = { .open = tvh_extradata_open, }; - /* OPUS */ static TVHContextHelper TVHOPUSDecoder = { .type = AVMEDIA_TYPE_AUDIO, @@ -147,131 +130,115 @@ static TVHContextHelper TVHOPUSDecoder = { .open = tvh_extradata_open, }; - -static void -tvh_decoder_helpers_register() -{ - SLIST_INIT(&tvh_decoder_helpers); - /* video */ - tvh_decoder_helper_register(&TVHH264Decoder); - tvh_decoder_helper_register(&TVHTHEORADecoder); - /* audio */ - tvh_decoder_helper_register(&TVHAACDecoder); - tvh_decoder_helper_register(&TVHVORBISDecoder); - tvh_decoder_helper_register(&TVHOPUSDecoder); +static void tvh_decoder_helpers_register() { + SLIST_INIT(&tvh_decoder_helpers); + /* video */ + tvh_decoder_helper_register(&TVHH264Decoder); + tvh_decoder_helper_register(&TVHTHEORADecoder); + /* audio */ + tvh_decoder_helper_register(&TVHAACDecoder); + tvh_decoder_helper_register(&TVHVORBISDecoder); + tvh_decoder_helper_register(&TVHOPUSDecoder); } - /* encoders ================================================================= */ /* MPEG2VIDEO */ -static int -tvh_mpeg2video_meta(TVHContext *self, AVPacket *avpkt, th_pkt_t *pkt) -{ - const uint8_t *data = avpkt->data; - size_t size = 12; // header size - - if ((avpkt->flags & AV_PKT_FLAG_KEY)) { - // sequence header - if (avpkt->size < size || RB32(data) != 0x000001b3) { // SEQ_START_CODE - tvh_context_log(self, LOG_ERR, - "MPEG2 header: missing sequence header"); - return -1; - } - // load intra quantiser matrix - if (data[size-1] & 0x02) { - if (avpkt->size < size + 64) { - tvh_context_log(self, LOG_ERR, - "MPEG2 header: missing load intra quantiser matrix"); - return -1; - } - size += 64; - } - // load non-intra quantiser matrix - if (data[size-1] & 0x01) { - if (avpkt->size < size + 64) { - tvh_context_log(self, LOG_ERR, - "MPEG2 header: missing load non-intra quantiser matrix"); - return -1; - } - size += 64; - } - // sequence extension - if (avpkt->size < size + 10 || RB32(data + size) != 0x000001b5) { // EXT_START_CODE - tvh_context_log(self, LOG_ERR, - "MPEG2 header: missing sequence extension"); - return -1; - } - size += 10; - // sequence display extension - if (RB32(data + size) == 0x000001b5) { // EXT_START_CODE - if (avpkt->size < size + 12) { - tvh_context_log(self, LOG_ERR, - "MPEG2 header: missing sequence display extension"); - return -1; - } - size += 12; - } - // group of pictures - if (avpkt->size < size + 8 || RB32(data + size) != 0x000001b8) { // GOP_START_CODE - tvh_context_log(self, LOG_ERR, - "MPEG2 header: missing group of pictures"); - return -1; - } - size += 8; - if (!(pkt->pkt_meta = pktbuf_alloc(data, size))) { - return -1; - } - return 0; +static int tvh_mpeg2video_meta(TVHContext* self, AVPacket* avpkt, th_pkt_t* pkt) { + const uint8_t* data = avpkt->data; + size_t size = 12; // header size + + if ((avpkt->flags & AV_PKT_FLAG_KEY)) { + // sequence header + if (avpkt->size < size || RB32(data) != 0x000001b3) { // SEQ_START_CODE + tvh_context_log(self, LOG_ERR, "MPEG2 header: missing sequence header"); + return -1; + } + // load intra quantiser matrix + if (data[size - 1] & 0x02) { + if (avpkt->size < size + 64) { + tvh_context_log(self, LOG_ERR, "MPEG2 header: missing load intra quantiser matrix"); + return -1; + } + size += 64; + } + // load non-intra quantiser matrix + if (data[size - 1] & 0x01) { + if (avpkt->size < size + 64) { + tvh_context_log(self, LOG_ERR, "MPEG2 header: missing load non-intra quantiser matrix"); + return -1; + } + size += 64; + } + // sequence extension + if (avpkt->size < size + 10 || RB32(data + size) != 0x000001b5) { // EXT_START_CODE + tvh_context_log(self, LOG_ERR, "MPEG2 header: missing sequence extension"); + return -1; + } + size += 10; + // sequence display extension + if (RB32(data + size) == 0x000001b5) { // EXT_START_CODE + if (avpkt->size < size + 12) { + tvh_context_log(self, LOG_ERR, "MPEG2 header: missing sequence display extension"); + return -1; + } + size += 12; } - return 1; + // group of pictures + if (avpkt->size < size + 8 || RB32(data + size) != 0x000001b8) { // GOP_START_CODE + tvh_context_log(self, LOG_ERR, "MPEG2 header: missing group of pictures"); + return -1; + } + size += 8; + if (!(pkt->pkt_meta = pktbuf_alloc(data, size))) { + return -1; + } + return 0; + } + return 1; } static TVHContextHelper TVHMPEG2VIDEOEncoder = { - .type = AVMEDIA_TYPE_VIDEO, - .id = AV_CODEC_ID_MPEG2VIDEO, - .meta = tvh_mpeg2video_meta, + .type = AVMEDIA_TYPE_VIDEO, + .id = AV_CODEC_ID_MPEG2VIDEO, + .meta = tvh_mpeg2video_meta, }; - /* H264 */ -static int -tvh_h264_meta(TVHContext *self, AVPacket *avpkt, th_pkt_t *pkt) -{ - if ((avpkt->flags & AV_PKT_FLAG_KEY) && (avpkt->size > 6) && - (RB32(avpkt->data) == 0x00000001 || RB24(avpkt->data) == 0x000001)) { - const uint8_t *p = avpkt->data; - const uint8_t *end = p + avpkt->size; - const uint8_t *nal_start, *nal_end; - int size = 0; - - nal_start = avc_find_startcode(p, end); - for (;;) { - while (nal_start < end && !*(nal_start++)); - if (nal_start == end) { - break; - } - nal_end = avc_find_startcode(nal_start, end); - int nal_len = nal_end - nal_start; - uint8_t nal_type = (nal_start[0] & 0x1f); - if ((nal_type == H264_NAL_SPS && - nal_len >= 4 && nal_len <= UINT16_MAX) || - (nal_type == H264_NAL_PPS && - nal_len <= UINT16_MAX)) { - size = nal_end - p; - nal_start = nal_end; - continue; - } - break; - } - if (size) { - if (!(pkt->pkt_meta = pktbuf_alloc(avpkt->data, size))) { - return -1; - } - return 0; - } +static int tvh_h264_meta(TVHContext* self, AVPacket* avpkt, th_pkt_t* pkt) { + if ((avpkt->flags & AV_PKT_FLAG_KEY) && (avpkt->size > 6) && + (RB32(avpkt->data) == 0x00000001 || RB24(avpkt->data) == 0x000001)) { + const uint8_t* p = avpkt->data; + const uint8_t* end = p + avpkt->size; + const uint8_t *nal_start, *nal_end; + int size = 0; + + nal_start = avc_find_startcode(p, end); + for (;;) { + while (nal_start < end && !*(nal_start++)) + ; + if (nal_start == end) { + break; + } + nal_end = avc_find_startcode(nal_start, end); + int nal_len = nal_end - nal_start; + uint8_t nal_type = (nal_start[0] & 0x1f); + if ((nal_type == H264_NAL_SPS && nal_len >= 4 && nal_len <= UINT16_MAX) || + (nal_type == H264_NAL_PPS && nal_len <= UINT16_MAX)) { + size = nal_end - p; + nal_start = nal_end; + continue; + } + break; } - return 1; + if (size) { + if (!(pkt->pkt_meta = pktbuf_alloc(avpkt->data, size))) { + return -1; + } + return 0; + } + } + return 1; } static TVHContextHelper TVHH264Encoder = { @@ -280,50 +247,47 @@ static TVHContextHelper TVHH264Encoder = { .meta = tvh_h264_meta, }; - /* HEVC */ -static int -tvh_hevc_meta(TVHContext *self, AVPacket *avpkt, th_pkt_t *pkt) -{ - - if ((avpkt->flags & AV_PKT_FLAG_KEY) && (avpkt->size >= 6) && - (*avpkt->data != 1) && - (RB24(avpkt->data) == 1 || RB32(avpkt->data) == 1)) { - const uint8_t *p = avpkt->data; - const uint8_t *end = p + avpkt->size; - const uint8_t *nal_start, *nal_end; - int size = 0; - - nal_start = avc_find_startcode(p, end); - for (;;) { - while (nal_start < end && !*(nal_start++)); - if (nal_start == end) { - break; - } - nal_end = avc_find_startcode(nal_start, end); - uint8_t nal_type = ((nal_start[0] >> 1) & 0x3f); - switch (nal_type) { - case HEVC_NAL_VPS: - case HEVC_NAL_SPS: - case HEVC_NAL_PPS: - case HEVC_NAL_SEI_PREFIX: - case HEVC_NAL_SEI_SUFFIX: - size = nal_end - p; - nal_start = nal_end; - continue; - default: - break; - } - break; - } - if (size) { - if (!(pkt->pkt_meta = pktbuf_alloc(avpkt->data, size))) { - return -1; - } - return 0; - } +static int tvh_hevc_meta(TVHContext* self, AVPacket* avpkt, th_pkt_t* pkt) { + + if ((avpkt->flags & AV_PKT_FLAG_KEY) && (avpkt->size >= 6) && (*avpkt->data != 1) && + (RB24(avpkt->data) == 1 || RB32(avpkt->data) == 1)) { + const uint8_t* p = avpkt->data; + const uint8_t* end = p + avpkt->size; + const uint8_t *nal_start, *nal_end; + int size = 0; + + nal_start = avc_find_startcode(p, end); + for (;;) { + while (nal_start < end && !*(nal_start++)) + ; + if (nal_start == end) { + break; + } + nal_end = avc_find_startcode(nal_start, end); + uint8_t nal_type = ((nal_start[0] >> 1) & 0x3f); + switch (nal_type) { + case HEVC_NAL_VPS: + case HEVC_NAL_SPS: + case HEVC_NAL_PPS: + case HEVC_NAL_SEI_PREFIX: + case HEVC_NAL_SEI_SUFFIX: + size = nal_end - p; + nal_start = nal_end; + continue; + default: + break; + } + break; + } + if (size) { + if (!(pkt->pkt_meta = pktbuf_alloc(avpkt->data, size))) { + return -1; + } + return 0; } - return 1; + } + return 1; } static TVHContextHelper TVHHEVCEncoder = { @@ -332,65 +296,59 @@ static TVHContextHelper TVHHEVCEncoder = { .meta = tvh_hevc_meta, }; - /* AAC */ -static void -tvh_aac_pack_adts_header(TVHContext *self, pktbuf_t *pb) -{ - // XXX: this really should happen in the muxer - int chan_conf = (self->oavctx->channels == 8) ? 7 : self->oavctx->channels; - bitstream_t bs; - - // https://wiki.multimedia.cx/index.php?title=ADTS - init_wbits(&bs, pktbuf_ptr(pb), 56); // 7 bytes - put_bits(&bs, 0xfff, 12); /* syncword */ - put_bits(&bs, 0, 1); /* version */ - put_bits(&bs, 0, 2); /* layer */ - put_bits(&bs, 1, 1); /* protection absent */ - put_bits(&bs, self->oavctx->profile, 2); /* profile (aot-1) */ - put_bits(&bs, self->sri, 4); /* sample rate index */ - put_bits(&bs, 0, 1); /* private bit */ - put_bits(&bs, chan_conf, 3); /* channel configuration */ - put_bits(&bs, 0, 1); /* originality */ - put_bits(&bs, 0, 1); /* home */ - put_bits(&bs, 0, 1); /* copyrighted id bit */ - put_bits(&bs, 0, 1); /* copyright id start */ - put_bits(&bs, pktbuf_len(pb), 13); /* frame length */ - put_bits(&bs, 0x7ff, 11); /* buffer fullness */ - put_bits(&bs, 0, 2); /* rdbs in frame (-1)*/ +static void tvh_aac_pack_adts_header(TVHContext* self, pktbuf_t* pb) { + // XXX: this really should happen in the muxer + int chan_conf = (self->oavctx->channels == 8) ? 7 : self->oavctx->channels; + bitstream_t bs; + + // https://wiki.multimedia.cx/index.php?title=ADTS + init_wbits(&bs, pktbuf_ptr(pb), 56); // 7 bytes + put_bits(&bs, 0xfff, 12); /* syncword */ + put_bits(&bs, 0, 1); /* version */ + put_bits(&bs, 0, 2); /* layer */ + put_bits(&bs, 1, 1); /* protection absent */ + put_bits(&bs, self->oavctx->profile, 2); /* profile (aot-1) */ + put_bits(&bs, self->sri, 4); /* sample rate index */ + put_bits(&bs, 0, 1); /* private bit */ + put_bits(&bs, chan_conf, 3); /* channel configuration */ + put_bits(&bs, 0, 1); /* originality */ + put_bits(&bs, 0, 1); /* home */ + put_bits(&bs, 0, 1); /* copyrighted id bit */ + put_bits(&bs, 0, 1); /* copyright id start */ + put_bits(&bs, pktbuf_len(pb), 13); /* frame length */ + put_bits(&bs, 0x7ff, 11); /* buffer fullness */ + put_bits(&bs, 0, 2); /* rdbs in frame (-1)*/ } -static th_pkt_t * -tvh_aac_pack(TVHContext *self, AVPacket *avpkt) -{ - static const size_t header_size = 7, max_size = ((1 << 14) - 1); - size_t pkt_size = 0; - th_pkt_t *pkt = NULL; - - // afaict: we write an adts header if there isn't one already, why would - // there be one in the first place?. - // originally there was a check for avpkt->size < 2, I don't get it. - // max aac frame size = 768 bytes per channel, max writable size 13 bits - if (avpkt->size > (768 * self->oavctx->channels)) { - tvh_context_log(self, LOG_WARNING, - "packet size (%d) > aac max frame size (%d for %d channels)", - avpkt->size, (768 * self->oavctx->channels), - self->oavctx->channels); - } - if ((pkt_size = avpkt->size + header_size) > max_size) { - tvh_context_log(self, LOG_ERR, "aac frame data too big"); +static th_pkt_t* tvh_aac_pack(TVHContext* self, AVPacket* avpkt) { + static const size_t header_size = 7, max_size = ((1 << 14) - 1); + size_t pkt_size = 0; + th_pkt_t* pkt = NULL; + + // afaict: we write an adts header if there isn't one already, why would + // there be one in the first place?. + // originally there was a check for avpkt->size < 2, I don't get it. + // max aac frame size = 768 bytes per channel, max writable size 13 bits + if (avpkt->size > (768 * self->oavctx->channels)) { + tvh_context_log(self, + LOG_WARNING, + "packet size (%d) > aac max frame size (%d for %d channels)", + avpkt->size, + (768 * self->oavctx->channels), + self->oavctx->channels); + } + if ((pkt_size = avpkt->size + header_size) > max_size) { + tvh_context_log(self, LOG_ERR, "aac frame data too big"); + } else if (avpkt->data[0] != 0xff || (avpkt->data[1] & 0xf0) != 0xf0) { + if ((pkt = pkt_alloc(self->stream->type, NULL, pkt_size, avpkt->pts, avpkt->dts, 0))) { + tvh_aac_pack_adts_header(self, pkt->pkt_payload); + memcpy(pktbuf_ptr(pkt->pkt_payload) + header_size, avpkt->data, avpkt->size); } - else if (avpkt->data[0] != 0xff || (avpkt->data[1] & 0xf0) != 0xf0) { - if ((pkt = pkt_alloc(self->stream->type, NULL, pkt_size, avpkt->pts, avpkt->dts, 0))) { - tvh_aac_pack_adts_header(self, pkt->pkt_payload); - memcpy(pktbuf_ptr(pkt->pkt_payload) + header_size, - avpkt->data, avpkt->size); - } - } - else { - pkt = pkt_alloc(self->stream->type, avpkt->data, avpkt->size, avpkt->pts, avpkt->dts, 0); - } - return pkt; + } else { + pkt = pkt_alloc(self->stream->type, avpkt->data, avpkt->size, avpkt->pts, avpkt->dts, 0); + } + return pkt; } static TVHContextHelper TVHAACEncoder = { @@ -399,52 +357,37 @@ static TVHContextHelper TVHAACEncoder = { .pack = tvh_aac_pack, }; - -static void -tvh_encoder_helpers_register() -{ - SLIST_INIT(&tvh_encoder_helpers); - /* video */ - tvh_encoder_helper_register(&TVHMPEG2VIDEOEncoder); - tvh_encoder_helper_register(&TVHH264Encoder); - tvh_encoder_helper_register(&TVHHEVCEncoder); - /* audio */ - tvh_encoder_helper_register(&TVHAACEncoder); +static void tvh_encoder_helpers_register() { + SLIST_INIT(&tvh_encoder_helpers); + /* video */ + tvh_encoder_helper_register(&TVHMPEG2VIDEOEncoder); + tvh_encoder_helper_register(&TVHH264Encoder); + tvh_encoder_helper_register(&TVHHEVCEncoder); + /* audio */ + tvh_encoder_helper_register(&TVHAACEncoder); } - /* public =================================================================== */ -TVHContextHelper * -tvh_decoder_helper_find(const AVCodec *codec) -{ - return tvh_context_helper_find(&tvh_decoder_helpers, codec); +TVHContextHelper* tvh_decoder_helper_find(const AVCodec* codec) { + return tvh_context_helper_find(&tvh_decoder_helpers, codec); } - -TVHContextHelper * -tvh_encoder_helper_find(const AVCodec *codec) -{ - return tvh_context_helper_find(&tvh_encoder_helpers, codec); +TVHContextHelper* tvh_encoder_helper_find(const AVCodec* codec) { + return tvh_context_helper_find(&tvh_encoder_helpers, codec); } - -void -tvh_context_helpers_register() -{ - tvh_decoder_helpers_register(); - tvh_encoder_helpers_register(); +void tvh_context_helpers_register() { + tvh_decoder_helpers_register(); + tvh_encoder_helpers_register(); } - -void -tvh_context_helpers_forget() -{ - tvhinfo(LS_TRANSCODE, "forgetting context helpers"); - while (!SLIST_EMPTY(&tvh_encoder_helpers)) { - SLIST_REMOVE_HEAD(&tvh_encoder_helpers, link); - } - while (!SLIST_EMPTY(&tvh_decoder_helpers)) { - SLIST_REMOVE_HEAD(&tvh_decoder_helpers, link); - } +void tvh_context_helpers_forget() { + tvhinfo(LS_TRANSCODE, "forgetting context helpers"); + while (!SLIST_EMPTY(&tvh_encoder_helpers)) { + SLIST_REMOVE_HEAD(&tvh_encoder_helpers, link); + } + while (!SLIST_EMPTY(&tvh_decoder_helpers)) { + SLIST_REMOVE_HEAD(&tvh_decoder_helpers, link); + } } diff --git a/src/transcoding/transcode/hwaccels/hwaccels.c b/src/transcoding/transcode/hwaccels/hwaccels.c index 892bbbc2f..acf24ffd3 100644 --- a/src/transcoding/transcode/hwaccels/hwaccels.c +++ b/src/transcoding/transcode/hwaccels/hwaccels.c @@ -26,235 +26,202 @@ #include - /* decoding ================================================================= */ #if LIBAVCODEC_VERSION_MAJOR < 58 /* lifted from libavcodec/utils.c */ -static AVHWAccel * -find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt) -{ - AVHWAccel *hwaccel = NULL; - while ((hwaccel = av_hwaccel_next(hwaccel))) { - if (hwaccel->id == codec_id && hwaccel->pix_fmt == pix_fmt) { - return hwaccel; - } +static AVHWAccel* find_hwaccel(enum AVCodecID codec_id, enum AVPixelFormat pix_fmt) { + AVHWAccel* hwaccel = NULL; + while ((hwaccel = av_hwaccel_next(hwaccel))) { + if (hwaccel->id == codec_id && hwaccel->pix_fmt == pix_fmt) { + return hwaccel; } - return NULL; + } + return NULL; } -static inline int check_pix_fmt(AVCodecContext *avctx, enum AVPixelFormat pix_fmt) -{ - return find_hwaccel(avctx->codec_id, pix_fmt) == NULL; +static inline int check_pix_fmt(AVCodecContext* avctx, enum AVPixelFormat pix_fmt) { + return find_hwaccel(avctx->codec_id, pix_fmt) == NULL; } #else -static const AVCodecHWConfig * -find_hwconfig(const AVCodec *codec, enum AVPixelFormat pix_fmt) -{ - const AVCodecHWConfig *hwcfg = NULL; - int i; - - for (i = 0;; i++) { - hwcfg = avcodec_get_hw_config(codec, i); - if (!hwcfg) - break; - if (hwcfg->pix_fmt == pix_fmt) - return hwcfg; - } - return NULL; +static const AVCodecHWConfig* find_hwconfig(const AVCodec* codec, enum AVPixelFormat pix_fmt) { + const AVCodecHWConfig* hwcfg = NULL; + int i; + + for (i = 0;; i++) { + hwcfg = avcodec_get_hw_config(codec, i); + if (!hwcfg) + break; + if (hwcfg->pix_fmt == pix_fmt) + return hwcfg; + } + return NULL; } -static inline int check_pix_fmt(AVCodecContext *avctx, enum AVPixelFormat pix_fmt) -{ - return find_hwconfig(avctx->codec, pix_fmt) == NULL; +static inline int check_pix_fmt(AVCodecContext* avctx, enum AVPixelFormat pix_fmt) { + return find_hwconfig(avctx->codec, pix_fmt) == NULL; } #endif -static int -hwaccels_decode_setup_context(AVCodecContext *avctx, - const enum AVPixelFormat pix_fmt) -{ - const AVPixFmtDescriptor *desc; +static int hwaccels_decode_setup_context(AVCodecContext* avctx, const enum AVPixelFormat pix_fmt) { + const AVPixFmtDescriptor* desc; - if (check_pix_fmt(avctx, pix_fmt)) { - desc = av_pix_fmt_desc_get(pix_fmt); - tvherror(LS_TRANSCODE, "no HWAccel for the pixel format '%s'", desc ? desc->name : ""); - return AVERROR(ENOENT); - } - switch (pix_fmt) { + if (check_pix_fmt(avctx, pix_fmt)) { + desc = av_pix_fmt_desc_get(pix_fmt); + tvherror(LS_TRANSCODE, "no HWAccel for the pixel format '%s'", desc ? desc->name : ""); + return AVERROR(ENOENT); + } + switch (pix_fmt) { #if ENABLE_VAAPI - case AV_PIX_FMT_VAAPI: - return vaapi_decode_setup_context(avctx); + case AV_PIX_FMT_VAAPI: + return vaapi_decode_setup_context(avctx); #endif - default: - break; - } - return -1; + default: + break; + } + return -1; } - -enum AVPixelFormat -hwaccels_decode_get_format(AVCodecContext *avctx, - const enum AVPixelFormat *pix_fmts) -{ - enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; - const AVPixFmtDescriptor *desc; - int i; - - for (i = 0; pix_fmts[i] != AV_PIX_FMT_NONE; i++) { - pix_fmt = pix_fmts[i]; - if ((desc = av_pix_fmt_desc_get(pix_fmt))) { - tvhtrace(LS_TRANSCODE, "hwaccels: [%s] trying pix_fmt: %s", avctx->codec->name, desc->name); - if ((desc->flags & AV_PIX_FMT_FLAG_HWACCEL) && - !hwaccels_decode_setup_context(avctx, pix_fmt)) { - break; - } - } +enum AVPixelFormat hwaccels_decode_get_format(AVCodecContext* avctx, + const enum AVPixelFormat* pix_fmts) { + enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; + const AVPixFmtDescriptor* desc; + int i; + + for (i = 0; pix_fmts[i] != AV_PIX_FMT_NONE; i++) { + pix_fmt = pix_fmts[i]; + if ((desc = av_pix_fmt_desc_get(pix_fmt))) { + tvhtrace(LS_TRANSCODE, "hwaccels: [%s] trying pix_fmt: %s", avctx->codec->name, desc->name); + if ((desc->flags & AV_PIX_FMT_FLAG_HWACCEL) && + !hwaccels_decode_setup_context(avctx, pix_fmt)) { + break; + } } - return pix_fmt; + } + return pix_fmt; } +void hwaccels_decode_close_context(AVCodecContext* avctx) { + TVHContext* ctx = avctx->opaque; -void -hwaccels_decode_close_context(AVCodecContext *avctx) -{ - TVHContext *ctx = avctx->opaque; - - if (ctx->hw_accel_ictx) { - switch (avctx->pix_fmt) { + if (ctx->hw_accel_ictx) { + switch (avctx->pix_fmt) { #if ENABLE_VAAPI - case AV_PIX_FMT_VAAPI: - vaapi_decode_close_context(avctx); - break; + case AV_PIX_FMT_VAAPI: + vaapi_decode_close_context(avctx); + break; #endif - default: - break; - } - ctx->hw_accel_ictx = NULL; + default: + break; } + ctx->hw_accel_ictx = NULL; + } } +int hwaccels_get_scale_filter(AVCodecContext* iavctx, + AVCodecContext* oavctx, + char* filter, + size_t filter_len) { + TVHContext* ctx = iavctx->opaque; -int -hwaccels_get_scale_filter(AVCodecContext *iavctx, AVCodecContext *oavctx, - char *filter, size_t filter_len) -{ - TVHContext *ctx = iavctx->opaque; - - if (ctx->hw_accel_ictx) { - switch (iavctx->pix_fmt) { + if (ctx->hw_accel_ictx) { + switch (iavctx->pix_fmt) { #if ENABLE_VAAPI - case AV_PIX_FMT_VAAPI: - return vaapi_get_scale_filter(iavctx, oavctx, filter, filter_len); + case AV_PIX_FMT_VAAPI: + return vaapi_get_scale_filter(iavctx, oavctx, filter, filter_len); #endif - default: - break; - } + default: + break; } - - return -1; -} + } + return -1; +} -int -hwaccels_get_deint_filter(AVCodecContext *avctx, char *filter, size_t filter_len) -{ - TVHContext *ctx = avctx->opaque; +int hwaccels_get_deint_filter(AVCodecContext* avctx, char* filter, size_t filter_len) { + TVHContext* ctx = avctx->opaque; - if (ctx->hw_accel_ictx) { - switch (avctx->pix_fmt) { + if (ctx->hw_accel_ictx) { + switch (avctx->pix_fmt) { #if ENABLE_VAAPI - case AV_PIX_FMT_VAAPI: - return vaapi_get_deint_filter(avctx, filter, filter_len); + case AV_PIX_FMT_VAAPI: + return vaapi_get_deint_filter(avctx, filter, filter_len); #endif - default: - break; - } + default: + break; } - - return -1; + } + + return -1; } -int -hwaccels_get_denoise_filter(AVCodecContext *avctx, int value, char *filter, size_t filter_len) -{ - TVHContext *ctx = avctx->opaque; +int hwaccels_get_denoise_filter(AVCodecContext* avctx, int value, char* filter, size_t filter_len) { + TVHContext* ctx = avctx->opaque; - if (ctx->hw_accel_ictx) { - switch (avctx->pix_fmt) { + if (ctx->hw_accel_ictx) { + switch (avctx->pix_fmt) { #if ENABLE_VAAPI - case AV_PIX_FMT_VAAPI: - return vaapi_get_denoise_filter(avctx, value, filter, filter_len); + case AV_PIX_FMT_VAAPI: + return vaapi_get_denoise_filter(avctx, value, filter, filter_len); #endif - default: - break; - } + default: + break; } - - return -1; + } + + return -1; } -int -hwaccels_get_sharpness_filter(AVCodecContext *avctx, int value, char *filter, size_t filter_len) -{ - TVHContext *ctx = avctx->opaque; +int hwaccels_get_sharpness_filter(AVCodecContext* avctx, + int value, + char* filter, + size_t filter_len) { + TVHContext* ctx = avctx->opaque; - if (ctx->hw_accel_ictx) { - switch (avctx->pix_fmt) { + if (ctx->hw_accel_ictx) { + switch (avctx->pix_fmt) { #if ENABLE_VAAPI - case AV_PIX_FMT_VAAPI: - return vaapi_get_sharpness_filter(avctx, value, filter, filter_len); + case AV_PIX_FMT_VAAPI: + return vaapi_get_sharpness_filter(avctx, value, filter, filter_len); #endif - default: - break; - } + default: + break; } - - return -1; + } + + return -1; } /* encoding ================================================================= */ -int -hwaccels_encode_setup_context(AVCodecContext *avctx, int low_power) -{ - switch (avctx->pix_fmt) { +int hwaccels_encode_setup_context(AVCodecContext* avctx, int low_power) { + switch (avctx->pix_fmt) { #if ENABLE_VAAPI - case AV_PIX_FMT_VAAPI: - return vaapi_encode_setup_context(avctx, low_power); + case AV_PIX_FMT_VAAPI: + return vaapi_encode_setup_context(avctx, low_power); #endif - default: - break; - } - return 0; + default: + break; + } + return 0; } - -void -hwaccels_encode_close_context(AVCodecContext *avctx) -{ - switch (avctx->pix_fmt) { +void hwaccels_encode_close_context(AVCodecContext* avctx) { + switch (avctx->pix_fmt) { #if ENABLE_VAAPI - case AV_PIX_FMT_VAAPI: - vaapi_encode_close_context(avctx); - break; + case AV_PIX_FMT_VAAPI: + vaapi_encode_close_context(avctx); + break; #endif - default: - break; - } + default: + break; + } } - /* module =================================================================== */ -void -hwaccels_init(void) -{ -} - +void hwaccels_init(void) {} -void -hwaccels_done(void) -{ +void hwaccels_done(void) { #if ENABLE_VAAPI - vaapi_done(); + vaapi_done(); #endif } diff --git a/src/transcoding/transcode/hwaccels/hwaccels.h b/src/transcoding/transcode/hwaccels/hwaccels.h index ca129ef88..275f18f01 100644 --- a/src/transcoding/transcode/hwaccels/hwaccels.h +++ b/src/transcoding/transcode/hwaccels/hwaccels.h @@ -17,55 +17,44 @@ * along with this program. If not, see . */ - #ifndef TVH_TRANSCODING_TRANSCODE_HWACCELS_H__ #define TVH_TRANSCODING_TRANSCODE_HWACCELS_H__ - #include "tvheadend.h" #include - /* decoding ================================================================= */ -enum AVPixelFormat -hwaccels_decode_get_format(AVCodecContext *avctx, - const enum AVPixelFormat *pix_fmts); +enum AVPixelFormat hwaccels_decode_get_format(AVCodecContext* avctx, + const enum AVPixelFormat* pix_fmts); -void -hwaccels_decode_close_context(AVCodecContext *avctx); +void hwaccels_decode_close_context(AVCodecContext* avctx); -int -hwaccels_get_scale_filter(AVCodecContext *iavctx, AVCodecContext *oavctx, - char *filter, size_t filter_len); +int hwaccels_get_scale_filter(AVCodecContext* iavctx, + AVCodecContext* oavctx, + char* filter, + size_t filter_len); -int -hwaccels_get_deint_filter(AVCodecContext *avctx, char *filter, size_t filter_len); +int hwaccels_get_deint_filter(AVCodecContext* avctx, char* filter, size_t filter_len); -int -hwaccels_get_denoise_filter(AVCodecContext *avctx, int value, char *filter, size_t filter_len); - -int -hwaccels_get_sharpness_filter(AVCodecContext *avctx, int value, char *filter, size_t filter_len); +int hwaccels_get_denoise_filter(AVCodecContext* avctx, int value, char* filter, size_t filter_len); +int hwaccels_get_sharpness_filter(AVCodecContext* avctx, + int value, + char* filter, + size_t filter_len); /* encoding ================================================================= */ -int -hwaccels_encode_setup_context(AVCodecContext *avctx, int low_power); - -void -hwaccels_encode_close_context(AVCodecContext *avctx); +int hwaccels_encode_setup_context(AVCodecContext* avctx, int low_power); +void hwaccels_encode_close_context(AVCodecContext* avctx); /* module =================================================================== */ -void -hwaccels_init(void); - -void -hwaccels_done(void); +void hwaccels_init(void); +void hwaccels_done(void); #endif // TVH_TRANSCODING_TRANSCODE_HWACCELS_H__ diff --git a/src/transcoding/transcode/hwaccels/vaapi.c b/src/transcoding/transcode/hwaccels/vaapi.c index f3971f3cd..910eea1ed 100644 --- a/src/transcoding/transcode/hwaccels/vaapi.c +++ b/src/transcoding/transcode/hwaccels/vaapi.c @@ -17,7 +17,6 @@ * along with this program. If not, see . */ - #include "../internals.h" #include "vaapi.h" @@ -27,664 +26,604 @@ #include - typedef struct tvh_vaapi_device { - char *hw_device_name; - AVBufferRef *hw_device_ref; - LIST_ENTRY(tvh_vaapi_device) link; + char* hw_device_name; + AVBufferRef* hw_device_ref; + LIST_ENTRY(tvh_vaapi_device) link; } TVHVADevice; - typedef struct tvh_vaapi_context_t { - void *display; - uint32_t config_id; - uint32_t context_id; - const char *logpref; - VAEntrypoint entrypoint; - enum AVPixelFormat io_format; - enum AVPixelFormat sw_format; - int width; - int height; - AVBufferRef *hw_device_ref; - AVBufferRef *hw_frames_ref; + void* display; + uint32_t config_id; + uint32_t context_id; + const char* logpref; + VAEntrypoint entrypoint; + enum AVPixelFormat io_format; + enum AVPixelFormat sw_format; + int width; + int height; + AVBufferRef* hw_device_ref; + AVBufferRef* hw_frames_ref; } TVHVAContext; - static LIST_HEAD(, tvh_vaapi_device) tvhva_devices; - -static AVBufferRef * -tvhva_init(const char *device) -{ - TVHVADevice *vad; - - if (tvh_str_default(device, NULL) == NULL) - device = "/dev/dri/renderD128"; - LIST_FOREACH(vad, &tvhva_devices, link) { - if (strcmp(vad->hw_device_name, device) == 0) - break; - } - if (vad == NULL) { - vad = calloc(1, sizeof(*vad)); - vad->hw_device_name = strdup(device); - LIST_INSERT_HEAD(&tvhva_devices, vad, link); - } - if (vad->hw_device_ref) - return vad->hw_device_ref; - tvhtrace(LS_VAAPI, "trying device: %s", device); - if (av_hwdevice_ctx_create(&vad->hw_device_ref, AV_HWDEVICE_TYPE_VAAPI, - device, NULL, 0)) { - tvherror(LS_VAAPI, - "failed to create a context for device: %s", device); - return NULL; - } - tvhtrace(LS_VAAPI, "successful context creation for device: %s", device); +static AVBufferRef* tvhva_init(const char* device) { + TVHVADevice* vad; + + if (tvh_str_default(device, NULL) == NULL) + device = "/dev/dri/renderD128"; + LIST_FOREACH (vad, &tvhva_devices, link) { + if (strcmp(vad->hw_device_name, device) == 0) + break; + } + if (vad == NULL) { + vad = calloc(1, sizeof(*vad)); + vad->hw_device_name = strdup(device); + LIST_INSERT_HEAD(&tvhva_devices, vad, link); + } + if (vad->hw_device_ref) return vad->hw_device_ref; + tvhtrace(LS_VAAPI, "trying device: %s", device); + if (av_hwdevice_ctx_create(&vad->hw_device_ref, AV_HWDEVICE_TYPE_VAAPI, device, NULL, 0)) { + tvherror(LS_VAAPI, "failed to create a context for device: %s", device); + return NULL; + } + tvhtrace(LS_VAAPI, "successful context creation for device: %s", device); + return vad->hw_device_ref; } +static void tvhva_done() { + TVHVADevice* vad; -static void -tvhva_done() -{ - TVHVADevice *vad; - - while ((vad = LIST_FIRST(&tvhva_devices)) != NULL) { - LIST_REMOVE(vad, link); - av_buffer_unref(&vad->hw_device_ref); - free(vad->hw_device_name); - free(vad); - } + while ((vad = LIST_FIRST(&tvhva_devices)) != NULL) { + LIST_REMOVE(vad, link); + av_buffer_unref(&vad->hw_device_ref); + free(vad->hw_device_name); + free(vad); + } } - /* TVHVAContext ============================================================= */ -static void -tvhva_context_destroy(TVHVAContext *self) -{ - if (self) { - if (self->context_id != VA_INVALID_ID) { - vaDestroyContext(self->display, self->context_id); - self->context_id = VA_INVALID_ID; - } - if (self->config_id != VA_INVALID_ID) { - vaDestroyConfig(self->display, self->config_id); - self->config_id = VA_INVALID_ID; - } - self->display = NULL; - if (self->hw_frames_ref) { - av_buffer_unref(&self->hw_frames_ref); - self->hw_frames_ref = NULL; - } - if (self->hw_device_ref) { - av_buffer_unref(&self->hw_device_ref); - self->hw_device_ref = NULL; - } - free(self); - self = NULL; +static void tvhva_context_destroy(TVHVAContext* self) { + if (self) { + if (self->context_id != VA_INVALID_ID) { + vaDestroyContext(self->display, self->context_id); + self->context_id = VA_INVALID_ID; } -} - - -static VADisplay * -tvhva_context_display(TVHVAContext *self, AVCodecContext *avctx) -{ - TVHContext *ctx = avctx->opaque; - AVHWDeviceContext *hw_device_ctx = NULL; - - if (!ctx->hw_device_ref && - !(ctx->hw_device_ref = tvhva_init(ctx->hw_accel_device))) { - return NULL; + if (self->config_id != VA_INVALID_ID) { + vaDestroyConfig(self->display, self->config_id); + self->config_id = VA_INVALID_ID; } - if (!(self->hw_device_ref = av_buffer_ref(ctx->hw_device_ref))) { - return NULL; + self->display = NULL; + if (self->hw_frames_ref) { + av_buffer_unref(&self->hw_frames_ref); + self->hw_frames_ref = NULL; + } + if (self->hw_device_ref) { + av_buffer_unref(&self->hw_device_ref); + self->hw_device_ref = NULL; } - hw_device_ctx = (AVHWDeviceContext*)self->hw_device_ref->data; - return ((AVVAAPIDeviceContext *)hw_device_ctx->hwctx)->display; + free(self); + self = NULL; + } } +static VADisplay* tvhva_context_display(TVHVAContext* self, AVCodecContext* avctx) { + TVHContext* ctx = avctx->opaque; + AVHWDeviceContext* hw_device_ctx = NULL; + + if (!ctx->hw_device_ref && !(ctx->hw_device_ref = tvhva_init(ctx->hw_accel_device))) { + return NULL; + } + if (!(self->hw_device_ref = av_buffer_ref(ctx->hw_device_ref))) { + return NULL; + } + hw_device_ctx = (AVHWDeviceContext*)self->hw_device_ref->data; + return ((AVVAAPIDeviceContext*)hw_device_ctx->hwctx)->display; +} -static VAProfile -tvhva_context_profile(TVHVAContext *self, AVCodecContext *avctx) -{ - VAStatus va_res = VA_STATUS_ERROR_UNKNOWN; - VAProfile profile = VAProfileNone, check = VAProfileNone, *profiles = NULL; - int i, j, profiles_max, profiles_len; - - switch (avctx->codec->id) { - case AV_CODEC_ID_MPEG2VIDEO: - switch (avctx->profile) { - case FF_PROFILE_UNKNOWN: - case FF_PROFILE_MPEG2_MAIN: - check = VAProfileMPEG2Main; - break; - case FF_PROFILE_MPEG2_SIMPLE: - check = VAProfileMPEG2Simple; - break; - default: - break; - } - break; - case AV_CODEC_ID_H264: - switch (avctx->profile) { - case FF_PROFILE_UNKNOWN: - case FF_PROFILE_H264_HIGH: - check = VAProfileH264High; - break; - case FF_PROFILE_H264_CONSTRAINED_BASELINE: - check = VAProfileH264ConstrainedBaseline; - break; - case FF_PROFILE_H264_MAIN: - check = VAProfileH264Main; - break; - default: - break; - } - break; - case AV_CODEC_ID_HEVC: - switch (avctx->profile) { - case FF_PROFILE_UNKNOWN: - case FF_PROFILE_HEVC_MAIN: - check = VAProfileHEVCMain; - break; - case FF_PROFILE_HEVC_MAIN_10: - case FF_PROFILE_HEVC_REXT: - check = VAProfileHEVCMain10; - break; - default: - break; - } - break; - case AV_CODEC_ID_VP8: - switch (avctx->profile) { - case FF_PROFILE_UNKNOWN: - check = VAProfileVP8Version0_3; - break; - default: - break; - } - break; - case AV_CODEC_ID_VP9: - switch (avctx->profile) { - case FF_PROFILE_UNKNOWN: - case FF_PROFILE_VP9_0: - check = VAProfileVP9Profile0; - break; - case FF_PROFILE_VP9_1: - check = VAProfileVP9Profile1; - break; - case FF_PROFILE_VP9_2: - check = VAProfileVP9Profile2; - break; - case FF_PROFILE_VP9_3: - check = VAProfileVP9Profile3; - break; - default: - break; - } - break; +static VAProfile tvhva_context_profile(TVHVAContext* self, AVCodecContext* avctx) { + VAStatus va_res = VA_STATUS_ERROR_UNKNOWN; + VAProfile profile = VAProfileNone, check = VAProfileNone, *profiles = NULL; + int i, j, profiles_max, profiles_len; + + switch (avctx->codec->id) { + case AV_CODEC_ID_MPEG2VIDEO: + switch (avctx->profile) { + case FF_PROFILE_UNKNOWN: + case FF_PROFILE_MPEG2_MAIN: + check = VAProfileMPEG2Main; + break; + case FF_PROFILE_MPEG2_SIMPLE: + check = VAProfileMPEG2Simple; + break; default: - break; - } - - if (check != VAProfileNone && - (profiles_max = vaMaxNumProfiles(self->display)) > 0 && - (profiles = calloc(profiles_max, sizeof(VAProfile)))) { - for (j = 0; j < profiles_max; j++) { - profiles[j] = VAProfileNone; - } - if (profiles_max == 0) { - tvherror(LS_VAAPI, "%s: vaMaxNumProfiles() returned %d; vaapi doesn't have any profiles available, run: $ vainfo", self->logpref, profiles_max); - } - va_res = vaQueryConfigProfiles(self->display, - profiles, &profiles_len); - if (va_res == VA_STATUS_SUCCESS) { - for (i = 0; i < profiles_len; i++) { - if (profiles[i] == check) { - profile = check; - break; - } - } - } - else { - tvherror(LS_VAAPI, "%s: va_res != VA_STATUS_SUCCESS; Failed to query profiles: %d (%s), run: $ vainfo", self->logpref, va_res, vaErrorStr(va_res)); + break; + } + break; + case AV_CODEC_ID_H264: + switch (avctx->profile) { + case FF_PROFILE_UNKNOWN: + case FF_PROFILE_H264_HIGH: + check = VAProfileH264High; + break; + case FF_PROFILE_H264_CONSTRAINED_BASELINE: + check = VAProfileH264ConstrainedBaseline; + break; + case FF_PROFILE_H264_MAIN: + check = VAProfileH264Main; + break; + default: + break; + } + break; + case AV_CODEC_ID_HEVC: + switch (avctx->profile) { + case FF_PROFILE_UNKNOWN: + case FF_PROFILE_HEVC_MAIN: + check = VAProfileHEVCMain; + break; + case FF_PROFILE_HEVC_MAIN_10: + case FF_PROFILE_HEVC_REXT: + check = VAProfileHEVCMain10; + break; + default: + break; + } + break; + case AV_CODEC_ID_VP8: + switch (avctx->profile) { + case FF_PROFILE_UNKNOWN: + check = VAProfileVP8Version0_3; + break; + default: + break; + } + break; + case AV_CODEC_ID_VP9: + switch (avctx->profile) { + case FF_PROFILE_UNKNOWN: + case FF_PROFILE_VP9_0: + check = VAProfileVP9Profile0; + break; + case FF_PROFILE_VP9_1: + check = VAProfileVP9Profile1; + break; + case FF_PROFILE_VP9_2: + check = VAProfileVP9Profile2; + break; + case FF_PROFILE_VP9_3: + check = VAProfileVP9Profile3; + break; + default: + break; + } + break; + default: + break; + } + + if (check != VAProfileNone && (profiles_max = vaMaxNumProfiles(self->display)) > 0 && + (profiles = calloc(profiles_max, sizeof(VAProfile)))) { + for (j = 0; j < profiles_max; j++) { + profiles[j] = VAProfileNone; + } + if (profiles_max == 0) { + tvherror(LS_VAAPI, + "%s: vaMaxNumProfiles() returned %d; vaapi doesn't have any profiles available, run: $ " + "vainfo", + self->logpref, + profiles_max); + } + va_res = vaQueryConfigProfiles(self->display, profiles, &profiles_len); + if (va_res == VA_STATUS_SUCCESS) { + for (i = 0; i < profiles_len; i++) { + if (profiles[i] == check) { + profile = check; + break; } - free(profiles); - } - - return profile; + } + } else { + tvherror(LS_VAAPI, + "%s: va_res != VA_STATUS_SUCCESS; Failed to query profiles: %d (%s), run: $ vainfo", + self->logpref, + va_res, + vaErrorStr(va_res)); + } + free(profiles); + } + + return profile; } - -static int -tvhva_context_check_profile(TVHVAContext *self, VAProfile profile) -{ - VAStatus va_res = VA_STATUS_ERROR_UNKNOWN; - VAEntrypoint *entrypoints = NULL; - int res = -1, i, entrypoints_max, entrypoints_len; - - entrypoints_max = vaMaxNumEntrypoints(self->display); - - if (entrypoints_max > 0) { - entrypoints = calloc(entrypoints_max, sizeof(VAEntrypoint)); +static int tvhva_context_check_profile(TVHVAContext* self, VAProfile profile) { + VAStatus va_res = VA_STATUS_ERROR_UNKNOWN; + VAEntrypoint* entrypoints = NULL; + int res = -1, i, entrypoints_max, entrypoints_len; + + entrypoints_max = vaMaxNumEntrypoints(self->display); + + if (entrypoints_max > 0) { + entrypoints = calloc(entrypoints_max, sizeof(VAEntrypoint)); + va_res = vaQueryConfigEntrypoints(self->display, profile, entrypoints, &entrypoints_len); + if (va_res == VA_STATUS_SUCCESS) { + for (i = 0; i < entrypoints_len; i++) { + if (entrypoints[i] == self->entrypoint) { + res = 0; + break; + } + } + } else { + tvherror(LS_VAAPI, + "%s: va_res != VA_STATUS_SUCCESS; Failed to query entrypoints: %d (%s), run: $ vainfo", + self->logpref, + va_res, + vaErrorStr(va_res)); + } + if (res != 0) { + // before giving up we swap VAEntrypointEncSliceLP with VAEntrypointEncSlice or viceversa + if (self->entrypoint == VAEntrypointEncSlice) { + // we try VAEntrypointEncSliceLP + self->entrypoint = VAEntrypointEncSliceLP; va_res = vaQueryConfigEntrypoints(self->display, profile, entrypoints, &entrypoints_len); if (va_res == VA_STATUS_SUCCESS) { - for (i = 0; i < entrypoints_len; i++) { - if (entrypoints[i] == self->entrypoint) { - res = 0; - break; - } + for (i = 0; i < entrypoints_len; i++) { + if (entrypoints[i] == self->entrypoint) { + res = 0; + break; } + } } - else { - tvherror(LS_VAAPI, "%s: va_res != VA_STATUS_SUCCESS; Failed to query entrypoints: %d (%s), run: $ vainfo", self->logpref, va_res, vaErrorStr(va_res)); - } - if (res != 0) { - // before giving up we swap VAEntrypointEncSliceLP with VAEntrypointEncSlice or viceversa - if (self->entrypoint == VAEntrypointEncSlice) { - // we try VAEntrypointEncSliceLP - self->entrypoint = VAEntrypointEncSliceLP; - va_res = vaQueryConfigEntrypoints(self->display, profile, entrypoints, &entrypoints_len); - if (va_res == VA_STATUS_SUCCESS) { - for (i = 0; i < entrypoints_len; i++) { - if (entrypoints[i] == self->entrypoint) { - res = 0; - break; - } - } - } - } - else { - // we try VAEntrypointEncSlice - self->entrypoint = VAEntrypointEncSlice; - va_res = vaQueryConfigEntrypoints(self->display, profile, entrypoints, &entrypoints_len); - if (va_res == VA_STATUS_SUCCESS) { - for (i = 0; i < entrypoints_len; i++) { - if (entrypoints[i] == self->entrypoint) { - res = 0; - break; - } - } - } + } else { + // we try VAEntrypointEncSlice + self->entrypoint = VAEntrypointEncSlice; + va_res = vaQueryConfigEntrypoints(self->display, profile, entrypoints, &entrypoints_len); + if (va_res == VA_STATUS_SUCCESS) { + for (i = 0; i < entrypoints_len; i++) { + if (entrypoints[i] == self->entrypoint) { + res = 0; + break; } + } } - free(entrypoints); - } - else { - tvherror(LS_VAAPI, "%s: vaMaxNumEntrypoints() returned %d; vaapi doesn't have any entrypoints available, run: $ vainfo", self->logpref, entrypoints_max); - } - return res; + } + } + free(entrypoints); + } else { + tvherror(LS_VAAPI, + "%s: vaMaxNumEntrypoints() returned %d; vaapi doesn't have any entrypoints available, run: " + "$ vainfo", + self->logpref, + entrypoints_max); + } + return res; } - -static unsigned int -tvhva_get_format(enum AVPixelFormat pix_fmt) -{ - switch (pix_fmt) { - //case AV_PIX_FMT_YUV420P: // the cake is a lie - case AV_PIX_FMT_NV12: - return VA_RT_FORMAT_YUV420; - case AV_PIX_FMT_YUV422P: - case AV_PIX_FMT_UYVY422: - case AV_PIX_FMT_YUYV422: - return VA_RT_FORMAT_YUV422; - case AV_PIX_FMT_GRAY8: - return VA_RT_FORMAT_YUV400; - default: - return 0; - } +static unsigned int tvhva_get_format(enum AVPixelFormat pix_fmt) { + switch (pix_fmt) { + // case AV_PIX_FMT_YUV420P: // the cake is a lie + case AV_PIX_FMT_NV12: + return VA_RT_FORMAT_YUV420; + case AV_PIX_FMT_YUV422P: + case AV_PIX_FMT_UYVY422: + case AV_PIX_FMT_YUYV422: + return VA_RT_FORMAT_YUV422; + case AV_PIX_FMT_GRAY8: + return VA_RT_FORMAT_YUV400; + default: + return 0; + } } - -static int -tvhva_context_config(TVHVAContext *self, VAProfile profile, unsigned int format) -{ - VAStatus va_res = VA_STATUS_ERROR_UNKNOWN; - VAConfigAttrib attrib = { VAConfigAttribRTFormat, VA_ATTRIB_NOT_SUPPORTED }; - - // vaCreateConfig - va_res = vaGetConfigAttributes(self->display, profile, self->entrypoint, - &attrib, 1); - if (va_res != VA_STATUS_SUCCESS) { - tvherror(LS_VAAPI, "%s: vaGetConfigAttributes: %s", - self->logpref, vaErrorStr(va_res)); - return -1; - } - if (attrib.value == VA_ATTRIB_NOT_SUPPORTED || !(attrib.value & format)) { - tvherror(LS_VAAPI, "%s: unsupported VA_RT_FORMAT", self->logpref); - return -1; - } - attrib.value = format; - va_res = vaCreateConfig(self->display, profile, self->entrypoint, - &attrib, 1, &self->config_id); - if (va_res != VA_STATUS_SUCCESS) { - tvherror(LS_VAAPI, "%s: vaCreateConfig: %s", - self->logpref, vaErrorStr(va_res)); - return -1; - } - return 0; +static int tvhva_context_config(TVHVAContext* self, VAProfile profile, unsigned int format) { + VAStatus va_res = VA_STATUS_ERROR_UNKNOWN; + VAConfigAttrib attrib = {VAConfigAttribRTFormat, VA_ATTRIB_NOT_SUPPORTED}; + + // vaCreateConfig + va_res = vaGetConfigAttributes(self->display, profile, self->entrypoint, &attrib, 1); + if (va_res != VA_STATUS_SUCCESS) { + tvherror(LS_VAAPI, "%s: vaGetConfigAttributes: %s", self->logpref, vaErrorStr(va_res)); + return -1; + } + if (attrib.value == VA_ATTRIB_NOT_SUPPORTED || !(attrib.value & format)) { + tvherror(LS_VAAPI, "%s: unsupported VA_RT_FORMAT", self->logpref); + return -1; + } + attrib.value = format; + va_res = vaCreateConfig(self->display, profile, self->entrypoint, &attrib, 1, &self->config_id); + if (va_res != VA_STATUS_SUCCESS) { + tvherror(LS_VAAPI, "%s: vaCreateConfig: %s", self->logpref, vaErrorStr(va_res)); + return -1; + } + return 0; } - -static int -tvhva_context_check_constraints(TVHVAContext *self) -{ - AVVAAPIHWConfig *va_config = NULL; - AVHWFramesConstraints *hw_constraints = NULL; - enum AVPixelFormat sw_format = AV_PIX_FMT_NONE; - const AVPixFmtDescriptor *sw_desc = NULL, *io_desc = NULL; - int i, ret = 0; - - if (!(va_config = av_hwdevice_hwconfig_alloc(self->hw_device_ref))) { - tvherror(LS_VAAPI, "%s: failed to allocate hwconfig", self->logpref); - return AVERROR(ENOMEM); - } - va_config->config_id = self->config_id; - - hw_constraints = - av_hwdevice_get_hwframe_constraints(self->hw_device_ref, va_config); - if (!hw_constraints) { - tvherror(LS_VAAPI, "%s: failed to get constraints", self->logpref); - av_freep(&va_config); - return -1; - } - - if (self->io_format != AV_PIX_FMT_NONE) { - for (i = 0; hw_constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) { - sw_format = hw_constraints->valid_sw_formats[i]; - if (sw_format == self->io_format) { - self->sw_format = sw_format; - break; - } - } - if (self->sw_format == AV_PIX_FMT_NONE && - (io_desc = av_pix_fmt_desc_get(self->io_format))) { - for (i = 0; hw_constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) { - sw_format = hw_constraints->valid_sw_formats[i]; - if ((sw_desc = av_pix_fmt_desc_get(sw_format)) && - sw_desc->nb_components == io_desc->nb_components && - sw_desc->log2_chroma_w == io_desc->log2_chroma_w && - sw_desc->log2_chroma_h == io_desc->log2_chroma_h) { - self->sw_format = sw_format; - break; - } - } +static int tvhva_context_check_constraints(TVHVAContext* self) { + AVVAAPIHWConfig* va_config = NULL; + AVHWFramesConstraints* hw_constraints = NULL; + enum AVPixelFormat sw_format = AV_PIX_FMT_NONE; + const AVPixFmtDescriptor *sw_desc = NULL, *io_desc = NULL; + int i, ret = 0; + + if (!(va_config = av_hwdevice_hwconfig_alloc(self->hw_device_ref))) { + tvherror(LS_VAAPI, "%s: failed to allocate hwconfig", self->logpref); + return AVERROR(ENOMEM); + } + va_config->config_id = self->config_id; + + hw_constraints = av_hwdevice_get_hwframe_constraints(self->hw_device_ref, va_config); + if (!hw_constraints) { + tvherror(LS_VAAPI, "%s: failed to get constraints", self->logpref); + av_freep(&va_config); + return -1; + } + + if (self->io_format != AV_PIX_FMT_NONE) { + for (i = 0; hw_constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) { + sw_format = hw_constraints->valid_sw_formats[i]; + if (sw_format == self->io_format) { + self->sw_format = sw_format; + break; + } + } + if (self->sw_format == AV_PIX_FMT_NONE && (io_desc = av_pix_fmt_desc_get(self->io_format))) { + for (i = 0; hw_constraints->valid_sw_formats[i] != AV_PIX_FMT_NONE; i++) { + sw_format = hw_constraints->valid_sw_formats[i]; + if ((sw_desc = av_pix_fmt_desc_get(sw_format)) && + sw_desc->nb_components == io_desc->nb_components && + sw_desc->log2_chroma_w == io_desc->log2_chroma_w && + sw_desc->log2_chroma_h == io_desc->log2_chroma_h) { + self->sw_format = sw_format; + break; } - } - if (self->sw_format == AV_PIX_FMT_NONE) { - tvherror(LS_VAAPI, "%s: VAAPI hardware does not support pixel format: %s", - self->logpref, av_get_pix_fmt_name(self->io_format)); - ret = AVERROR(EINVAL); - goto end; - } - - // Ensure the picture size is supported by the hardware. - if (self->width < hw_constraints->min_width || - self->height < hw_constraints->min_height || - self->width > hw_constraints->max_width || - self->height > hw_constraints->max_height) { - tvherror(LS_VAAPI, "%s: VAAPI hardware does not support image " - "size %dx%d (constraints: width %d-%d height %d-%d).", - self->logpref, self->width, self->height, - hw_constraints->min_width, hw_constraints->max_width, - hw_constraints->min_height, hw_constraints->max_height); - ret = AVERROR(EINVAL); - } + } + } + } + if (self->sw_format == AV_PIX_FMT_NONE) { + tvherror(LS_VAAPI, + "%s: VAAPI hardware does not support pixel format: %s", + self->logpref, + av_get_pix_fmt_name(self->io_format)); + ret = AVERROR(EINVAL); + goto end; + } + + // Ensure the picture size is supported by the hardware. + if (self->width < hw_constraints->min_width || self->height < hw_constraints->min_height || + self->width > hw_constraints->max_width || self->height > hw_constraints->max_height) { + tvherror(LS_VAAPI, + "%s: VAAPI hardware does not support image " + "size %dx%d (constraints: width %d-%d height %d-%d).", + self->logpref, + self->width, + self->height, + hw_constraints->min_width, + hw_constraints->max_width, + hw_constraints->min_height, + hw_constraints->max_height); + ret = AVERROR(EINVAL); + } end: - av_hwframe_constraints_free(&hw_constraints); - av_freep(&va_config); - return ret; + av_hwframe_constraints_free(&hw_constraints); + av_freep(&va_config); + return ret; } - -static int -tvhva_context_setup(TVHVAContext *self, AVCodecContext *avctx) -{ - VAProfile profile = VAProfileNone; - unsigned int format = 0; - VAStatus va_res = VA_STATUS_ERROR_UNKNOWN; - AVHWFramesContext *hw_frames_ctx = NULL; - AVVAAPIFramesContext *va_frames = NULL; - - if (!(self->display = tvhva_context_display(self, avctx))) { - return -1; - } - - libav_vaapi_init_context(self->display); - // - profile = tvhva_context_profile(self, avctx); - - if (profile == VAProfileNone) { - tvherror(LS_VAAPI, "%s: tvhva_context_profile() returned VAProfileNone for %s", - self->logpref, - avctx->codec->name); - return -1; - } - - if (tvhva_context_check_profile(self, profile)) { - tvherror(LS_VAAPI, "%s: tvhva_context_check_profile() check failed for codec: %s --> codec not available", - self->logpref, - avctx->codec->name); - return -1; - } - if (!(format = tvhva_get_format(self->io_format))) { - tvherror(LS_VAAPI, "%s: unsupported pixel format: %s", - self->logpref, - av_get_pix_fmt_name(self->io_format)); - return -1; - } - - if (tvhva_context_config(self, profile, format) || - tvhva_context_check_constraints(self)) { - return -1; - } - - if (!(self->hw_frames_ref = av_hwframe_ctx_alloc(self->hw_device_ref))) { - tvherror(LS_VAAPI, "%s: failed to create VAAPI frame context.", - self->logpref); - return AVERROR(ENOMEM); - } - hw_frames_ctx = (AVHWFramesContext*)self->hw_frames_ref->data; - hw_frames_ctx->format = AV_PIX_FMT_VAAPI; - hw_frames_ctx->sw_format = self->sw_format; - hw_frames_ctx->width = self->width; - hw_frames_ctx->height = self->height; - hw_frames_ctx->initial_pool_size = 32; - - if (av_hwframe_ctx_init(self->hw_frames_ref) < 0) { - tvherror(LS_VAAPI, "%s: failed to initialise VAAPI frame context", - self->logpref); - return -1; - } - - // vaCreateContext - if (self->entrypoint == VAEntrypointVLD) { // decode only - va_frames = hw_frames_ctx->hwctx; - va_res = vaCreateContext(self->display, self->config_id, - self->width, self->height, - VA_PROGRESSIVE, - va_frames->surface_ids, va_frames->nb_surfaces, - &self->context_id); - if (va_res != VA_STATUS_SUCCESS) { - tvherror(LS_VAAPI, "%s: vaCreateContext: %s", - self->logpref, vaErrorStr(va_res)); - return -1; - } +static int tvhva_context_setup(TVHVAContext* self, AVCodecContext* avctx) { + VAProfile profile = VAProfileNone; + unsigned int format = 0; + VAStatus va_res = VA_STATUS_ERROR_UNKNOWN; + AVHWFramesContext* hw_frames_ctx = NULL; + AVVAAPIFramesContext* va_frames = NULL; + + if (!(self->display = tvhva_context_display(self, avctx))) { + return -1; + } + + libav_vaapi_init_context(self->display); + // + profile = tvhva_context_profile(self, avctx); + + if (profile == VAProfileNone) { + tvherror(LS_VAAPI, + "%s: tvhva_context_profile() returned VAProfileNone for %s", + self->logpref, + avctx->codec->name); + return -1; + } + + if (tvhva_context_check_profile(self, profile)) { + tvherror(LS_VAAPI, + "%s: tvhva_context_check_profile() check failed for codec: %s --> codec not available", + self->logpref, + avctx->codec->name); + return -1; + } + if (!(format = tvhva_get_format(self->io_format))) { + tvherror(LS_VAAPI, + "%s: unsupported pixel format: %s", + self->logpref, + av_get_pix_fmt_name(self->io_format)); + return -1; + } + + if (tvhva_context_config(self, profile, format) || tvhva_context_check_constraints(self)) { + return -1; + } + + if (!(self->hw_frames_ref = av_hwframe_ctx_alloc(self->hw_device_ref))) { + tvherror(LS_VAAPI, "%s: failed to create VAAPI frame context.", self->logpref); + return AVERROR(ENOMEM); + } + hw_frames_ctx = (AVHWFramesContext*)self->hw_frames_ref->data; + hw_frames_ctx->format = AV_PIX_FMT_VAAPI; + hw_frames_ctx->sw_format = self->sw_format; + hw_frames_ctx->width = self->width; + hw_frames_ctx->height = self->height; + hw_frames_ctx->initial_pool_size = 32; + + if (av_hwframe_ctx_init(self->hw_frames_ref) < 0) { + tvherror(LS_VAAPI, "%s: failed to initialise VAAPI frame context", self->logpref); + return -1; + } + + // vaCreateContext + if (self->entrypoint == VAEntrypointVLD) { // decode only + va_frames = hw_frames_ctx->hwctx; + va_res = vaCreateContext(self->display, + self->config_id, + self->width, + self->height, + VA_PROGRESSIVE, + va_frames->surface_ids, + va_frames->nb_surfaces, + &self->context_id); + if (va_res != VA_STATUS_SUCCESS) { + tvherror(LS_VAAPI, "%s: vaCreateContext: %s", self->logpref, vaErrorStr(va_res)); + return -1; } + } - if (!(avctx->hw_frames_ctx = av_buffer_ref(self->hw_frames_ref))) { - return AVERROR(ENOMEM); - } + if (!(avctx->hw_frames_ctx = av_buffer_ref(self->hw_frames_ref))) { + return AVERROR(ENOMEM); + } - avctx->sw_pix_fmt = self->sw_format; - avctx->thread_count = 1; + avctx->sw_pix_fmt = self->sw_format; + avctx->thread_count = 1; - return 0; + return 0; } - -static TVHVAContext * -tvhva_context_create(const char *logpref, - AVCodecContext *avctx, VAEntrypoint entrypoint) -{ - TVHVAContext *self = NULL; - enum AVPixelFormat pix_fmt; - - if (!(self = calloc(1, sizeof(TVHVAContext)))) { - tvherror(LS_VAAPI, "%s: failed to allocate vaapi context", logpref); - return NULL; - } - self->logpref = logpref; - self->display = NULL; - self->config_id = VA_INVALID_ID; - self->context_id = VA_INVALID_ID; - self->entrypoint = entrypoint; - pix_fmt = self->entrypoint == VAEntrypointVLD ? - avctx->sw_pix_fmt : avctx->pix_fmt; - if (pix_fmt == AV_PIX_FMT_YUV420P || - pix_fmt == AV_PIX_FMT_VAAPI) { - self->io_format = AV_PIX_FMT_NV12; - } - else { - self->io_format = pix_fmt; - } - if (self->io_format == AV_PIX_FMT_NONE) { - tvherror(LS_VAAPI, "%s: failed to get pix_fmt for vaapi context " - "(sw_pix_fmt: %s, pix_fmt: %s)", - logpref, - av_get_pix_fmt_name(avctx->sw_pix_fmt), - av_get_pix_fmt_name(avctx->pix_fmt)); - free(self); - return NULL; - } - self->sw_format = AV_PIX_FMT_NONE; - self->width = avctx->coded_width; - self->height = avctx->coded_height; - self->hw_device_ref = NULL; - self->hw_frames_ref = NULL; - if (tvhva_context_setup(self, avctx)) { - tvhva_context_destroy(self); - return NULL; - } - return self; +static TVHVAContext* +tvhva_context_create(const char* logpref, AVCodecContext* avctx, VAEntrypoint entrypoint) { + TVHVAContext* self = NULL; + enum AVPixelFormat pix_fmt; + + if (!(self = calloc(1, sizeof(TVHVAContext)))) { + tvherror(LS_VAAPI, "%s: failed to allocate vaapi context", logpref); + return NULL; + } + self->logpref = logpref; + self->display = NULL; + self->config_id = VA_INVALID_ID; + self->context_id = VA_INVALID_ID; + self->entrypoint = entrypoint; + pix_fmt = self->entrypoint == VAEntrypointVLD ? avctx->sw_pix_fmt : avctx->pix_fmt; + if (pix_fmt == AV_PIX_FMT_YUV420P || pix_fmt == AV_PIX_FMT_VAAPI) { + self->io_format = AV_PIX_FMT_NV12; + } else { + self->io_format = pix_fmt; + } + if (self->io_format == AV_PIX_FMT_NONE) { + tvherror(LS_VAAPI, + "%s: failed to get pix_fmt for vaapi context " + "(sw_pix_fmt: %s, pix_fmt: %s)", + logpref, + av_get_pix_fmt_name(avctx->sw_pix_fmt), + av_get_pix_fmt_name(avctx->pix_fmt)); + free(self); + return NULL; + } + self->sw_format = AV_PIX_FMT_NONE; + self->width = avctx->coded_width; + self->height = avctx->coded_height; + self->hw_device_ref = NULL; + self->hw_frames_ref = NULL; + if (tvhva_context_setup(self, avctx)) { + tvhva_context_destroy(self); + return NULL; + } + return self; } - /* decoding ================================================================= */ -static int -vaapi_get_buffer2(AVCodecContext *avctx, AVFrame *avframe, int flags) -{ - if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { - return avcodec_default_get_buffer2(avctx, avframe, flags); - } - return av_hwframe_get_buffer(avctx->hw_frames_ctx, avframe, 0); +static int vaapi_get_buffer2(AVCodecContext* avctx, AVFrame* avframe, int flags) { + if (!(avctx->codec->capabilities & AV_CODEC_CAP_DR1)) { + return avcodec_default_get_buffer2(avctx, avframe, flags); + } + return av_hwframe_get_buffer(avctx->hw_frames_ctx, avframe, 0); } +int vaapi_decode_setup_context(AVCodecContext* avctx) { + TVHContext* ctx = avctx->opaque; -int -vaapi_decode_setup_context(AVCodecContext *avctx) -{ - TVHContext *ctx = avctx->opaque; + if (!(ctx->hw_accel_ictx = tvhva_context_create("decode", avctx, VAEntrypointVLD))) { + return -1; + } - if (!(ctx->hw_accel_ictx = - tvhva_context_create("decode", avctx, VAEntrypointVLD))) { - return -1; - } - - avctx->get_buffer2 = vaapi_get_buffer2; + avctx->get_buffer2 = vaapi_get_buffer2; #if LIBAVCODEC_VERSION_MAJOR < 60 - avctx->thread_safe_callbacks = 0; + avctx->thread_safe_callbacks = 0; #endif - return 0; + return 0; } +void vaapi_decode_close_context(AVCodecContext* avctx) { + TVHContext* ctx = avctx->opaque; -void -vaapi_decode_close_context(AVCodecContext *avctx) -{ - TVHContext *ctx = avctx->opaque; - - tvhva_context_destroy(ctx->hw_accel_ictx); + tvhva_context_destroy(ctx->hw_accel_ictx); } - -int -vaapi_get_scale_filter(AVCodecContext *iavctx, AVCodecContext *oavctx, - char *filter, size_t filter_len) -{ - snprintf(filter, filter_len, "scale_vaapi=w=%d:h=%d", oavctx->width, oavctx->height); - return 0; +int vaapi_get_scale_filter(AVCodecContext* iavctx, + AVCodecContext* oavctx, + char* filter, + size_t filter_len) { + snprintf(filter, filter_len, "scale_vaapi=w=%d:h=%d", oavctx->width, oavctx->height); + return 0; } - -int -vaapi_get_deint_filter(AVCodecContext *avctx, char *filter, size_t filter_len) -{ - snprintf(filter, filter_len, "deinterlace_vaapi"); - return 0; +int vaapi_get_deint_filter(AVCodecContext* avctx, char* filter, size_t filter_len) { + snprintf(filter, filter_len, "deinterlace_vaapi"); + return 0; } - -int -vaapi_get_denoise_filter(AVCodecContext *avctx, int value, char *filter, size_t filter_len) -{ - snprintf(filter, filter_len, "denoise_vaapi=%d", value); - return 0; +int vaapi_get_denoise_filter(AVCodecContext* avctx, int value, char* filter, size_t filter_len) { + snprintf(filter, filter_len, "denoise_vaapi=%d", value); + return 0; } - -int -vaapi_get_sharpness_filter(AVCodecContext *avctx, int value, char *filter, size_t filter_len) -{ - snprintf(filter, filter_len, "sharpness_vaapi=%d", value); - return 0; +int vaapi_get_sharpness_filter(AVCodecContext* avctx, int value, char* filter, size_t filter_len) { + snprintf(filter, filter_len, "sharpness_vaapi=%d", value); + return 0; } /* encoding ================================================================= */ -int -vaapi_encode_setup_context(AVCodecContext *avctx, int low_power) -{ - TVHContext *ctx = avctx->opaque; - TVHVAContext *hwaccel_context = NULL; - VAEntrypoint entrypoint; - - if (low_power) { - entrypoint = VAEntrypointEncSliceLP; - } - else { - entrypoint = VAEntrypointEncSlice; - } - - if (!(hwaccel_context = - tvhva_context_create("encode", avctx, entrypoint))) { - return -1; - } - if (!(ctx->hw_device_octx = av_buffer_ref(hwaccel_context->hw_device_ref))) { - tvhva_context_destroy(hwaccel_context); - return AVERROR(ENOMEM); - } +int vaapi_encode_setup_context(AVCodecContext* avctx, int low_power) { + TVHContext* ctx = avctx->opaque; + TVHVAContext* hwaccel_context = NULL; + VAEntrypoint entrypoint; + + if (low_power) { + entrypoint = VAEntrypointEncSliceLP; + } else { + entrypoint = VAEntrypointEncSlice; + } + + if (!(hwaccel_context = tvhva_context_create("encode", avctx, entrypoint))) { + return -1; + } + if (!(ctx->hw_device_octx = av_buffer_ref(hwaccel_context->hw_device_ref))) { tvhva_context_destroy(hwaccel_context); - return 0; + return AVERROR(ENOMEM); + } + tvhva_context_destroy(hwaccel_context); + return 0; } - -void -vaapi_encode_close_context(AVCodecContext *avctx) -{ - TVHContext *ctx = avctx->opaque; - av_buffer_unref(&ctx->hw_device_octx); - ctx->hw_device_octx = NULL; +void vaapi_encode_close_context(AVCodecContext* avctx) { + TVHContext* ctx = avctx->opaque; + av_buffer_unref(&ctx->hw_device_octx); + ctx->hw_device_octx = NULL; } - /* module =================================================================== */ -void -vaapi_done() -{ - tvhva_done(); +void vaapi_done() { + tvhva_done(); } diff --git a/src/transcoding/transcode/hwaccels/vaapi.h b/src/transcoding/transcode/hwaccels/vaapi.h index 72a2c4bab..abddb9e5a 100644 --- a/src/transcoding/transcode/hwaccels/vaapi.h +++ b/src/transcoding/transcode/hwaccels/vaapi.h @@ -17,50 +17,38 @@ * along with this program. If not, see . */ - #ifndef TVH_TRANSCODING_TRANSCODE_HWACCELS_VAAPI_H__ #define TVH_TRANSCODING_TRANSCODE_HWACCELS_VAAPI_H__ - #include "tvheadend.h" #include - /* decoding ================================================================= */ -int -vaapi_decode_setup_context(AVCodecContext *avctx); +int vaapi_decode_setup_context(AVCodecContext* avctx); -void -vaapi_decode_close_context(AVCodecContext *avctx); +void vaapi_decode_close_context(AVCodecContext* avctx); -int -vaapi_get_scale_filter(AVCodecContext *iavctx, AVCodecContext *oavctx, char *filter, size_t filter_len); +int vaapi_get_scale_filter(AVCodecContext* iavctx, + AVCodecContext* oavctx, + char* filter, + size_t filter_len); -int -vaapi_get_deint_filter(AVCodecContext *avctx, char *filter, size_t filter_len); +int vaapi_get_deint_filter(AVCodecContext* avctx, char* filter, size_t filter_len); -int -vaapi_get_denoise_filter(AVCodecContext *avctx, int value, char *filter, size_t filter_len); - -int -vaapi_get_sharpness_filter(AVCodecContext *avctx, int value, char *filter, size_t filter_len); +int vaapi_get_denoise_filter(AVCodecContext* avctx, int value, char* filter, size_t filter_len); +int vaapi_get_sharpness_filter(AVCodecContext* avctx, int value, char* filter, size_t filter_len); /* encoding ================================================================= */ -int -vaapi_encode_setup_context(AVCodecContext *avctx, int low_power); - -void -vaapi_encode_close_context(AVCodecContext *avctx); +int vaapi_encode_setup_context(AVCodecContext* avctx, int low_power); +void vaapi_encode_close_context(AVCodecContext* avctx); /* module =================================================================== */ -void -vaapi_done(void); - +void vaapi_done(void); #endif // TVH_TRANSCODING_TRANSCODE_HWACCELS_VAAPI_H__ diff --git a/src/transcoding/transcode/internals.h b/src/transcoding/transcode/internals.h index e0776cec4..92a92f63b 100644 --- a/src/transcoding/transcode/internals.h +++ b/src/transcoding/transcode/internals.h @@ -17,11 +17,9 @@ * along with this program. If not, see . */ - #ifndef TVH_TRANSCODING_TRANSCODE_INTERNALS_H__ #define TVH_TRANSCODING_TRANSCODE_INTERNALS_H__ - #include "log.h" #include "transcoding/codec.h" @@ -33,196 +31,167 @@ #include #include - #define tvh_st_t streaming_target_t #define tvh_ss_t streaming_start_t #define tvh_sm_t streaming_message_t +extern TVHCodecProfile* tvh_codec_profile_copy; -extern TVHCodecProfile *tvh_codec_profile_copy; - - -typedef struct tvh_transcoder TVHTranscoder; -typedef struct tvh_stream TVHStream; -typedef struct tvh_context_type TVHContextType; -typedef struct tvh_context TVHContext; +typedef struct tvh_transcoder TVHTranscoder; +typedef struct tvh_stream TVHStream; +typedef struct tvh_context_type TVHContextType; +typedef struct tvh_context TVHContext; typedef struct tvh_context_helper TVHContextHelper; // post phase _MUST_ be == phase + 1 -typedef enum { - OPEN_DECODER, - OPEN_DECODER_POST, - OPEN_ENCODER, - OPEN_ENCODER_POST -} TVHOpenPhase; - +typedef enum { OPEN_DECODER, OPEN_DECODER_POST, OPEN_ENCODER, OPEN_ENCODER_POST } TVHOpenPhase; /* TVHTranscoder ============================================================ */ SLIST_HEAD(TVHStreams, tvh_stream); struct tvh_transcoder { - tvh_st_t input; - struct TVHStreams streams; - uint32_t id; - tvh_st_t *output; - TVHCodecProfile *profiles[AVMEDIA_TYPE_NB]; - char *src_codecs[AVMEDIA_TYPE_NB]; + tvh_st_t input; + struct TVHStreams streams; + uint32_t id; + tvh_st_t* output; + TVHCodecProfile* profiles[AVMEDIA_TYPE_NB]; + char* src_codecs[AVMEDIA_TYPE_NB]; }; -int -tvh_transcoder_deliver(TVHTranscoder *self, th_pkt_t *pkt); +int tvh_transcoder_deliver(TVHTranscoder* self, th_pkt_t* pkt); -TVHTranscoder * -tvh_transcoder_create(tvh_st_t *output, - const char **profiles, - const char **src_codecs); - -void -tvh_transcoder_destroy(TVHTranscoder *self); +TVHTranscoder* +tvh_transcoder_create(tvh_st_t* output, const char** profiles, const char** src_codecs); +void tvh_transcoder_destroy(TVHTranscoder* self); /* TVHStream ================================================================ */ struct tvh_stream { - TVHTranscoder *transcoder; - int id; - int index; - tvh_sct_t type; - TVHContext *context; - int is_copy; - SLIST_ENTRY(tvh_stream) link; + TVHTranscoder* transcoder; + int id; + int index; + tvh_sct_t type; + TVHContext* context; + int is_copy; + SLIST_ENTRY(tvh_stream) link; }; -void -tvh_stream_stop(TVHStream *self, int flush); - -int -tvh_stream_handle(TVHStream *self, th_pkt_t *pkt); +void tvh_stream_stop(TVHStream* self, int flush); -int -tvh_stream_deliver(TVHStream *self, th_pkt_t *pkt); +int tvh_stream_handle(TVHStream* self, th_pkt_t* pkt); -TVHStream * -tvh_stream_create(TVHTranscoder *transcoder, TVHCodecProfile *profile, - tvh_ssc_t *ssc, const char *src_codecs); +int tvh_stream_deliver(TVHStream* self, th_pkt_t* pkt); -void -tvh_stream_destroy(TVHStream *self); +TVHStream* tvh_stream_create(TVHTranscoder* transcoder, + TVHCodecProfile* profile, + tvh_ssc_t* ssc, + const char* src_codecs); +void tvh_stream_destroy(TVHStream* self); /* TVHContextType =========================================================== */ -typedef int (*tvh_context_open_meth)(TVHContext *, TVHOpenPhase, AVDictionary **); -typedef int (*tvh_context_decode_meth)(TVHContext *, AVPacket *); -typedef int (*tvh_context_encode_meth)(TVHContext *, AVFrame *); -typedef int (*tvh_context_ship_meth)(TVHContext *, AVPacket *); -typedef int (*tvh_context_wrap_meth)(TVHContext *, AVPacket *, th_pkt_t *); -typedef void (*tvh_context_close_meth)(TVHContext *); +typedef int (*tvh_context_open_meth)(TVHContext*, TVHOpenPhase, AVDictionary**); +typedef int (*tvh_context_decode_meth)(TVHContext*, AVPacket*); +typedef int (*tvh_context_encode_meth)(TVHContext*, AVFrame*); +typedef int (*tvh_context_ship_meth)(TVHContext*, AVPacket*); +typedef int (*tvh_context_wrap_meth)(TVHContext*, AVPacket*, th_pkt_t*); +typedef void (*tvh_context_close_meth)(TVHContext*); struct tvh_context_type { - enum AVMediaType media_type; - tvh_context_open_meth open; - tvh_context_decode_meth decode; - tvh_context_encode_meth encode; - tvh_context_ship_meth ship; - tvh_context_wrap_meth wrap; - tvh_context_close_meth close; - SLIST_ENTRY(tvh_context_type) link; + enum AVMediaType media_type; + tvh_context_open_meth open; + tvh_context_decode_meth decode; + tvh_context_encode_meth encode; + tvh_context_ship_meth ship; + tvh_context_wrap_meth wrap; + tvh_context_close_meth close; + SLIST_ENTRY(tvh_context_type) link; }; -void -tvh_context_types_register(void); - -void -tvh_context_types_forget(void); +void tvh_context_types_register(void); +void tvh_context_types_forget(void); /* TVHContext =============================================================== */ struct tvh_context { - TVHStream *stream; - TVHCodecProfile *profile; - TVHContextType *type; - AVCodecContext *iavctx; - AVCodecContext *oavctx; - AVFrame *iavframe; - AVFrame *oavframe; - pktbuf_t *input_gh; - TVHContextHelper *helper; // encoder helper - AVFilterGraph *avfltgraph; - AVFilterContext *iavfltctx; - AVFilterContext *oavfltctx; - th_pkt_t *src_pkt; - int require_meta; - int64_t pts; - // only for audio - int64_t duration; - int64_t delta; - uint8_t sri; - // hardware acceleration - char *hw_accel_device; - AVBufferRef *hw_device_ref; - void *hw_accel_ictx; - AVBufferRef *hw_device_octx; + TVHStream* stream; + TVHCodecProfile* profile; + TVHContextType* type; + AVCodecContext* iavctx; + AVCodecContext* oavctx; + AVFrame* iavframe; + AVFrame* oavframe; + pktbuf_t* input_gh; + TVHContextHelper* helper; // encoder helper + AVFilterGraph* avfltgraph; + AVFilterContext* iavfltctx; + AVFilterContext* oavfltctx; + th_pkt_t* src_pkt; + int require_meta; + int64_t pts; + // only for audio + int64_t duration; + int64_t delta; + uint8_t sri; + // hardware acceleration + char* hw_accel_device; + AVBufferRef* hw_device_ref; + void* hw_accel_ictx; + AVBufferRef* hw_device_octx; }; -int -tvh_context_get_int_opt(AVDictionary **opts, const char *key, int *value); +int tvh_context_get_int_opt(AVDictionary** opts, const char* key, int* value); -int -tvh_context_get_str_opt(AVDictionary **opts, const char *key, char **value); +int tvh_context_get_str_opt(AVDictionary** opts, const char* key, char** value); -void -tvh_context_close(TVHContext *self, int flush); +void tvh_context_close(TVHContext* self, int flush); /* __VA_ARGS__ = NULL terminated list of sink options sink option = (const char *name, const uint8_t *value, int size) */ -int -tvh_context_open_filters(TVHContext *self, - const char *source_name, const char *source_args, - const char *filters, const char *sink_name, ...); +int tvh_context_open_filters(TVHContext* self, + const char* source_name, + const char* source_args, + const char* filters, + const char* sink_name, + ...); -int -tvh_context_handle(TVHContext *self, th_pkt_t *pkt); +int tvh_context_handle(TVHContext* self, th_pkt_t* pkt); -int -tvh_context_deliver(TVHContext *self, th_pkt_t *pkt); +int tvh_context_deliver(TVHContext* self, th_pkt_t* pkt); -TVHContext * -tvh_context_create(TVHStream *stream, TVHCodecProfile *profile, - const AVCodec *iavcodec, const AVCodec *oavcodec, pktbuf_t *input_gh); - -void -tvh_context_destroy(TVHContext *self); +TVHContext* tvh_context_create(TVHStream* stream, + TVHCodecProfile* profile, + const AVCodec* iavcodec, + const AVCodec* oavcodec, + pktbuf_t* input_gh); +void tvh_context_destroy(TVHContext* self); /* TVHContextHelper ========================================================= */ -typedef int (*tvh_context_helper_open_meth)(TVHContext *, AVDictionary **); -typedef th_pkt_t *(*tvh_context_helper_pack_meth)(TVHContext *, AVPacket *); -typedef int (*tvh_context_helper_meta_meth)(TVHContext *, AVPacket *, th_pkt_t *); +typedef int (*tvh_context_helper_open_meth)(TVHContext*, AVDictionary**); +typedef th_pkt_t* (*tvh_context_helper_pack_meth)(TVHContext*, AVPacket*); +typedef int (*tvh_context_helper_meta_meth)(TVHContext*, AVPacket*, th_pkt_t*); struct tvh_context_helper { - enum AVMediaType type; - enum AVCodecID id; - tvh_context_helper_open_meth open; - tvh_context_helper_pack_meth pack; - tvh_context_helper_meta_meth meta; - SLIST_ENTRY(tvh_context_helper) link; + enum AVMediaType type; + enum AVCodecID id; + tvh_context_helper_open_meth open; + tvh_context_helper_pack_meth pack; + tvh_context_helper_meta_meth meta; + SLIST_ENTRY(tvh_context_helper) link; }; -TVHContextHelper * -tvh_decoder_helper_find(const AVCodec *avcodec); - -TVHContextHelper * -tvh_encoder_helper_find(const AVCodec *avcodec); +TVHContextHelper* tvh_decoder_helper_find(const AVCodec* avcodec); -void -tvh_context_helpers_register(void); +TVHContextHelper* tvh_encoder_helper_find(const AVCodec* avcodec); -void -tvh_context_helpers_forget(void); +void tvh_context_helpers_register(void); +void tvh_context_helpers_forget(void); #endif // TVH_TRANSCODING_TRANSCODE_INTERNALS_H__ diff --git a/src/transcoding/transcode/log.h b/src/transcoding/transcode/log.h index db471674c..f835cb59a 100644 --- a/src/transcoding/transcode/log.h +++ b/src/transcoding/transcode/log.h @@ -17,51 +17,42 @@ * along with this program. If not, see . */ - #ifndef TVH_TRANSCODING_TRANSCODE_LOG_H__ #define TVH_TRANSCODING_TRANSCODE_LOG_H__ - -#define tvh_transcoder_log(self, level, fmt, ...) \ - do { \ - tvhlog((level), LS_TRANSCODE, "%04X: " fmt, \ - (((self)->id) & 0xffff), \ - ##__VA_ARGS__); \ - } while (0) +#define tvh_transcoder_log(self, level, fmt, ...) \ + do { \ + tvhlog((level), LS_TRANSCODE, "%04X: " fmt, (((self)->id) & 0xffff), ##__VA_ARGS__); \ + } while (0) #define _stream_log(level, fmt, transcoder, id, type, ...) \ - do { \ - tvh_transcoder_log((transcoder), (level), "%02d:%s: " fmt, \ - (id), \ - streaming_component_type2txt((type)), \ - ##__VA_ARGS__); \ - } while (0) - -#define tvh_ssc_log(ssc, level, fmt, transcoder, ...) \ - do { \ - _stream_log((level), fmt, \ - (transcoder), \ - (ssc)->es_index, \ - (ssc)->es_type, \ - ##__VA_ARGS__); \ - } while (0) - -#define tvh_stream_log(self, level, fmt, ...) \ - do { \ - _stream_log((level), fmt, \ - (self)->transcoder, \ - (self)->id, \ - (self)->type, \ - ##__VA_ARGS__); \ - } while (0) - -#define tvh_context_log(self, level, fmt, ...) \ - do { \ - tvh_stream_log((self)->stream, (level), "[%s => %s]: " fmt, \ - ((self)->iavctx && (self)->iavctx->codec) ? (self)->iavctx->codec->name : "", \ - ((self)->oavctx && (self)->oavctx->codec) ? (self)->oavctx->codec->name : "", \ - ##__VA_ARGS__); \ - } while (0) - + do { \ + tvh_transcoder_log((transcoder), \ + (level), \ + "%02d:%s: " fmt, \ + (id), \ + streaming_component_type2txt((type)), \ + ##__VA_ARGS__); \ + } while (0) + +#define tvh_ssc_log(ssc, level, fmt, transcoder, ...) \ + do { \ + _stream_log((level), fmt, (transcoder), (ssc)->es_index, (ssc)->es_type, ##__VA_ARGS__); \ + } while (0) + +#define tvh_stream_log(self, level, fmt, ...) \ + do { \ + _stream_log((level), fmt, (self)->transcoder, (self)->id, (self)->type, ##__VA_ARGS__); \ + } while (0) + +#define tvh_context_log(self, level, fmt, ...) \ + do { \ + tvh_stream_log((self)->stream, \ + (level), \ + "[%s => %s]: " fmt, \ + ((self)->iavctx && (self)->iavctx->codec) ? (self)->iavctx->codec->name : "", \ + ((self)->oavctx && (self)->oavctx->codec) ? (self)->oavctx->codec->name : "", \ + ##__VA_ARGS__); \ + } while (0) #endif // TVH_TRANSCODING_TRANSCODE_LOG_H__ diff --git a/src/transcoding/transcode/module.c b/src/transcoding/transcode/module.c index c41d2f9ae..51c005d5f 100644 --- a/src/transcoding/transcode/module.c +++ b/src/transcoding/transcode/module.c @@ -17,7 +17,6 @@ * along with this program. If not, see . */ - #include "transcoding/transcode.h" #include "internals.h" @@ -25,43 +24,31 @@ #include "hwaccels/hwaccels.h" #endif - /* TVHTranscoder ============================================================ */ -streaming_target_t * -transcoder_create(streaming_target_t *output, - const char **profiles, - const char **src_profiles) -{ - return (streaming_target_t *)tvh_transcoder_create(output, profiles, src_profiles); +streaming_target_t* +transcoder_create(streaming_target_t* output, const char** profiles, const char** src_profiles) { + return (streaming_target_t*)tvh_transcoder_create(output, profiles, src_profiles); } - -void -transcoder_destroy(streaming_target_t *st) -{ - tvh_transcoder_destroy((TVHTranscoder *)st); +void transcoder_destroy(streaming_target_t* st) { + tvh_transcoder_destroy((TVHTranscoder*)st); } - /* module level ============================================================= */ -void -transcode_init() -{ - tvh_context_types_register(); - tvh_context_helpers_register(); +void transcode_init() { + tvh_context_types_register(); + tvh_context_helpers_register(); #if ENABLE_HWACCELS - hwaccels_init(); + hwaccels_init(); #endif } -void -transcode_done() -{ +void transcode_done() { #if ENABLE_HWACCELS - hwaccels_done(); + hwaccels_done(); #endif - tvh_context_helpers_forget(); - tvh_context_types_forget(); + tvh_context_helpers_forget(); + tvh_context_types_forget(); } diff --git a/src/transcoding/transcode/stream.c b/src/transcoding/transcode/stream.c index b3117e3bc..57e43301a 100644 --- a/src/transcoding/transcode/stream.c +++ b/src/transcoding/transcode/stream.c @@ -17,177 +17,159 @@ * along with this program. If not, see . */ - #include "internals.h" #include "../codec/internals.h" - /* TVHStream ================================================================ */ -static int -tvh_stream_is_copy(TVHCodecProfile *profile, tvh_ssc_t *ssc, - const char *src_codecs) -{ - const char *txtname; - htsmsg_t *list; - int r; - - /* if the source codec is in the list, do the stream copy only */ - if (src_codecs && *src_codecs != '\0' && *src_codecs != '-') { - list = htsmsg_csv_2_list(src_codecs, ','); - if (list) { - txtname = streaming_component_type2txt(ssc->es_type); - r = htsmsg_is_string_in_list(list, txtname); - htsmsg_destroy(list); - if (r) - goto cont; - } - return 1; - } +static int tvh_stream_is_copy(TVHCodecProfile* profile, tvh_ssc_t* ssc, const char* src_codecs) { + const char* txtname; + htsmsg_t* list; + int r; + + /* if the source codec is in the list, do the stream copy only */ + if (src_codecs && *src_codecs != '\0' && *src_codecs != '-') { + list = htsmsg_csv_2_list(src_codecs, ','); + if (list) { + txtname = streaming_component_type2txt(ssc->es_type); + r = htsmsg_is_string_in_list(list, txtname); + htsmsg_destroy(list); + if (r) + goto cont; + } + return 1; + } cont: - if (profile == tvh_codec_profile_copy) { - return 1; - } - return tvh_codec_profile_is_copy(profile, ssc); + if (profile == tvh_codec_profile_copy) { + return 1; + } + return tvh_codec_profile_is_copy(profile, ssc); } - -static int -tvh_stream_setup(TVHStream *self, TVHCodecProfile *profile, tvh_ssc_t *ssc) -{ - enum AVCodecID icodec_id = streaming_component_type2codec_id(ssc->es_type); - const AVCodec *icodec = NULL, *ocodec = NULL; - - if (icodec_id == AV_CODEC_ID_NONE) { - tvh_stream_log(self, LOG_ERR, "unknown decoder id for '%s'", - streaming_component_type2txt(ssc->es_type)); - return -1; - } +static int tvh_stream_setup(TVHStream* self, TVHCodecProfile* profile, tvh_ssc_t* ssc) { + enum AVCodecID icodec_id = streaming_component_type2codec_id(ssc->es_type); + const AVCodec *icodec = NULL, *ocodec = NULL; + + if (icodec_id == AV_CODEC_ID_NONE) { + tvh_stream_log(self, + LOG_ERR, + "unknown decoder id for '%s'", + streaming_component_type2txt(ssc->es_type)); + return -1; + } #if ENABLE_MMAL - if (idnode_is_instance(&profile->idnode, - (idclass_t *)&codec_profile_video_class)) { - if (tvh_codec_profile_video_get_hwaccel(profile) > 0) { - if (icodec_id == AV_CODEC_ID_H264) { - icodec = avcodec_find_decoder_by_name("h264_mmal"); - } else if (icodec_id == AV_CODEC_ID_MPEG2VIDEO) { - icodec = avcodec_find_decoder_by_name("mpeg2_mmal"); - } + if (idnode_is_instance(&profile->idnode, (idclass_t*)&codec_profile_video_class)) { + if (tvh_codec_profile_video_get_hwaccel(profile) > 0) { + if (icodec_id == AV_CODEC_ID_H264) { + icodec = avcodec_find_decoder_by_name("h264_mmal"); + } else if (icodec_id == AV_CODEC_ID_MPEG2VIDEO) { + icodec = avcodec_find_decoder_by_name("mpeg2_mmal"); } } + } #endif #if ENABLE_NVENC - if (idnode_is_instance(&profile->idnode, - (idclass_t *)&codec_profile_video_class)) { - if (tvh_codec_profile_video_get_hwaccel(profile) > 0) { - if (icodec_id == AV_CODEC_ID_H264) { - icodec = avcodec_find_decoder_by_name("h264_cuvid"); - } else if (icodec_id == AV_CODEC_ID_HEVC) { - icodec = avcodec_find_decoder_by_name("hevc_cuvid"); - } + if (idnode_is_instance(&profile->idnode, (idclass_t*)&codec_profile_video_class)) { + if (tvh_codec_profile_video_get_hwaccel(profile) > 0) { + if (icodec_id == AV_CODEC_ID_H264) { + icodec = avcodec_find_decoder_by_name("h264_cuvid"); + } else if (icodec_id == AV_CODEC_ID_HEVC) { + icodec = avcodec_find_decoder_by_name("hevc_cuvid"); } } + } #endif - if (!icodec && !(icodec = avcodec_find_decoder(icodec_id))) { - tvh_stream_log(self, LOG_ERR, "failed to find decoder for '%s'", - streaming_component_type2txt(ssc->es_type)); - return -1; - } - if (!(ocodec = tvh_codec_profile_get_avcodec(profile))) { - tvh_stream_log(self, LOG_ERR, "profile '%s' is disabled", - tvh_codec_profile_get_name(profile)); - return -1; - } - if (icodec->type == AVMEDIA_TYPE_UNKNOWN || - icodec->type != ocodec->type) { // is this even possible? - tvh_stream_log(self, LOG_ERR, "unknown or mismatch media type"); - return -1; - } - - if (!(self->context = tvh_context_create(self, profile, - icodec, ocodec, ssc->ssc_gh))) { - return -1; - } - self->type = ssc->es_type = codec_id2streaming_component_type(ocodec->id); - if (ssc->es_type == SCT_UNKNOWN) { - tvh_stream_log(self, LOG_ERR, "unable to translate AV type %s [%d] to SCT!", ocodec->name, ocodec->id); - } - ssc->ssc_gh = NULL; - return 0; + if (!icodec && !(icodec = avcodec_find_decoder(icodec_id))) { + tvh_stream_log(self, + LOG_ERR, + "failed to find decoder for '%s'", + streaming_component_type2txt(ssc->es_type)); + return -1; + } + if (!(ocodec = tvh_codec_profile_get_avcodec(profile))) { + tvh_stream_log(self, LOG_ERR, "profile '%s' is disabled", tvh_codec_profile_get_name(profile)); + return -1; + } + if (icodec->type == AVMEDIA_TYPE_UNKNOWN || + icodec->type != ocodec->type) { // is this even possible? + tvh_stream_log(self, LOG_ERR, "unknown or mismatch media type"); + return -1; + } + + if (!(self->context = tvh_context_create(self, profile, icodec, ocodec, ssc->ssc_gh))) { + return -1; + } + self->type = ssc->es_type = codec_id2streaming_component_type(ocodec->id); + if (ssc->es_type == SCT_UNKNOWN) { + tvh_stream_log(self, + LOG_ERR, + "unable to translate AV type %s [%d] to SCT!", + ocodec->name, + ocodec->id); + } + ssc->ssc_gh = NULL; + return 0; } - /* exposed */ -void -tvh_stream_stop(TVHStream *self, int flush) -{ - if (self->index >= 0) { - if (self->context) { - tvh_context_close(self->context, flush); - } - self->index = -1; +void tvh_stream_stop(TVHStream* self, int flush) { + if (self->index >= 0) { + if (self->context) { + tvh_context_close(self->context, flush); } + self->index = -1; + } } - -int -tvh_stream_handle(TVHStream *self, th_pkt_t *pkt) -{ - if (pkt->pkt_payload && self->context) { - return (tvh_context_handle(self->context, pkt) < 0) ? -1 : 0; - } - pkt_ref_inc(pkt); - return tvh_transcoder_deliver(self->transcoder, pkt); +int tvh_stream_handle(TVHStream* self, th_pkt_t* pkt) { + if (pkt->pkt_payload && self->context) { + return (tvh_context_handle(self->context, pkt) < 0) ? -1 : 0; + } + pkt_ref_inc(pkt); + return tvh_transcoder_deliver(self->transcoder, pkt); } - -int -tvh_stream_deliver(TVHStream *self, th_pkt_t *pkt) -{ - pkt->pkt_componentindex = self->index; - return tvh_transcoder_deliver(self->transcoder, pkt); +int tvh_stream_deliver(TVHStream* self, th_pkt_t* pkt) { + pkt->pkt_componentindex = self->index; + return tvh_transcoder_deliver(self->transcoder, pkt); } - -TVHStream * -tvh_stream_create(TVHTranscoder *transcoder, TVHCodecProfile *profile, - tvh_ssc_t *ssc, const char *src_codecs) -{ - TVHStream *self = NULL; - int is_copy = -1; - - if (!(self = calloc(1, sizeof(TVHStream)))) { - tvh_ssc_log(ssc, LOG_ERR, "failed to allocate stream", transcoder); - return NULL; - } - self->transcoder = transcoder; - self->id = self->index = ssc->es_index; - self->type = ssc->es_type; - if ((is_copy = tvh_stream_is_copy(profile, ssc, src_codecs)) > 0) { - self->is_copy = 1; - if (ssc->ssc_gh) { - pktbuf_ref_inc(ssc->ssc_gh); - } - } - else if (is_copy < 0 || tvh_stream_setup(self, profile, ssc)) { - tvh_stream_destroy(self); - return NULL; - } - return self; +TVHStream* tvh_stream_create(TVHTranscoder* transcoder, + TVHCodecProfile* profile, + tvh_ssc_t* ssc, + const char* src_codecs) { + TVHStream* self = NULL; + int is_copy = -1; + + if (!(self = calloc(1, sizeof(TVHStream)))) { + tvh_ssc_log(ssc, LOG_ERR, "failed to allocate stream", transcoder); + return NULL; + } + self->transcoder = transcoder; + self->id = self->index = ssc->es_index; + self->type = ssc->es_type; + if ((is_copy = tvh_stream_is_copy(profile, ssc, src_codecs)) > 0) { + self->is_copy = 1; + if (ssc->ssc_gh) { + pktbuf_ref_inc(ssc->ssc_gh); + } + } else if (is_copy < 0 || tvh_stream_setup(self, profile, ssc)) { + tvh_stream_destroy(self); + return NULL; + } + return self; } - -void -tvh_stream_destroy(TVHStream *self) -{ - if (self) { - tvh_stream_stop(self, 0); - if (self->context) { - tvh_context_destroy(self->context); - self->context = NULL; - } - self->transcoder = NULL; - free(self); - self = NULL; - } +void tvh_stream_destroy(TVHStream* self) { + if (self) { + tvh_stream_stop(self, 0); + if (self->context) { + tvh_context_destroy(self->context); + self->context = NULL; + } + self->transcoder = NULL; + free(self); + self = NULL; + } } diff --git a/src/transcoding/transcode/transcoder.c b/src/transcoding/transcode/transcoder.c index 902f444aa..5bffbdf83 100644 --- a/src/transcoding/transcode/transcoder.c +++ b/src/transcoding/transcode/transcoder.c @@ -17,379 +17,334 @@ * along with this program. If not, see . */ - #include "internals.h" #include "../codec/internals.h" #include "service.h" - -static TVHCodecProfile _codec_profile_copy = { .name = (char *)"copy" }; -TVHCodecProfile *tvh_codec_profile_copy = &_codec_profile_copy; - +static TVHCodecProfile _codec_profile_copy = {.name = (char*)"copy"}; +TVHCodecProfile* tvh_codec_profile_copy = &_codec_profile_copy; /* utils ==================================================================== */ -static enum AVMediaType -ssc_get_media_type(tvh_ssc_t *ssc) -{ - if (ssc->ssc_disabled) { - return AVMEDIA_TYPE_UNKNOWN; - } - if (SCT_ISVIDEO(ssc->es_type)) { - return AVMEDIA_TYPE_VIDEO; - } - if (SCT_ISAUDIO(ssc->es_type)) { - return AVMEDIA_TYPE_AUDIO; - } - if (SCT_ISSUBTITLE(ssc->es_type)) { - return AVMEDIA_TYPE_SUBTITLE; - } +static enum AVMediaType ssc_get_media_type(tvh_ssc_t* ssc) { + if (ssc->ssc_disabled) { return AVMEDIA_TYPE_UNKNOWN; + } + if (SCT_ISVIDEO(ssc->es_type)) { + return AVMEDIA_TYPE_VIDEO; + } + if (SCT_ISAUDIO(ssc->es_type)) { + return AVMEDIA_TYPE_AUDIO; + } + if (SCT_ISSUBTITLE(ssc->es_type)) { + return AVMEDIA_TYPE_SUBTITLE; + } + return AVMEDIA_TYPE_UNKNOWN; } - -static TVHCodecProfile * -_find_profile(const char *name) -{ - if (!strcmp(name, "copy")) { - return tvh_codec_profile_copy; - } - return codec_find_profile(name); +static TVHCodecProfile* _find_profile(const char* name) { + if (!strcmp(name, "copy")) { + return tvh_codec_profile_copy; + } + return codec_find_profile(name); } -static TVHAudioCodecProfile * -_audio_profile(TVHCodecProfile *profile) -{ - if (profile && - idnode_is_instance(&profile->idnode, - (idclass_t *)&codec_profile_audio_class)) { - return (TVHAudioCodecProfile *)profile; - } - return NULL; +static TVHAudioCodecProfile* _audio_profile(TVHCodecProfile* profile) { + if (profile && idnode_is_instance(&profile->idnode, (idclass_t*)&codec_profile_audio_class)) { + return (TVHAudioCodecProfile*)profile; + } + return NULL; } - -static int -lang_match(const char *lang, tvh_ssc_t *ssc, int *index, int value) -{ - if (*index >= 0) - return 0; - if (lang && strcmp(lang, ssc->es_lang) == 0) { - *index = value; - return 1; - } +static int lang_match(const char* lang, tvh_ssc_t* ssc, int* index, int value) { + if (*index >= 0) return 0; + if (lang && strcmp(lang, ssc->es_lang) == 0) { + *index = value; + return 1; + } + return 0; } - /* TVHTranscoder ============================================================ */ -static void -tvh_transcoder_handle(TVHTranscoder *self, th_pkt_t *pkt) -{ - TVHStream *stream = NULL; +static void tvh_transcoder_handle(TVHTranscoder* self, th_pkt_t* pkt) { + TVHStream* stream = NULL; - SLIST_FOREACH(stream, &self->streams, link) { - if (pkt->pkt_componentindex == stream->index) { - if (tvh_stream_handle(stream, pkt)) { - tvh_stream_stop(stream, 0); - } - break; - } + SLIST_FOREACH (stream, &self->streams, link) { + if (pkt->pkt_componentindex == stream->index) { + if (tvh_stream_handle(stream, pkt)) { + tvh_stream_stop(stream, 0); + } + break; } + } } - -static tvh_ss_t * -tvh_transcoder_start(TVHTranscoder *self, tvh_ss_t *ss_src) -{ - tvh_ss_t *ss; - tvh_ssc_t *ssc_src, *ssc; - const char *codecs; - TVHCodecProfile *profile; - TVHAudioCodecProfile *aprofile; - TVHStream *stream = NULL; - int indexes[ss_src->ss_num_components]; - int i, j, k, count; - int video_index = -1; - int audio_index = -1; - int audio_pindex[3] = { -1, -1, -1 }; - int subtitle_index = -1; - enum AVMediaType media_type; - - aprofile = _audio_profile(self->profiles[AVMEDIA_TYPE_AUDIO]); - - for (i = 0; i < ss_src->ss_num_components; i++) { - if ((ssc = &ss_src->ss_components[i]) == NULL) - continue; - media_type = ssc_get_media_type(ssc); - if (media_type == AVMEDIA_TYPE_UNKNOWN) - continue; - switch (media_type) { - case AVMEDIA_TYPE_VIDEO: - if (video_index < 0) - video_index = i; - break; - case AVMEDIA_TYPE_AUDIO: - if (aprofile) { - if (lang_match(aprofile->language1, ssc, &audio_pindex[0], i) == 0 && - lang_match(aprofile->language2, ssc, &audio_pindex[1], i) == 0) - lang_match(aprofile->language3, ssc, &audio_pindex[2], i); - } - break; - case AVMEDIA_TYPE_SUBTITLE: - if (subtitle_index < 0) - subtitle_index = i; - break; - default: - break; +static tvh_ss_t* tvh_transcoder_start(TVHTranscoder* self, tvh_ss_t* ss_src) { + tvh_ss_t* ss; + tvh_ssc_t * ssc_src, *ssc; + const char* codecs; + TVHCodecProfile* profile; + TVHAudioCodecProfile* aprofile; + TVHStream* stream = NULL; + int indexes[ss_src->ss_num_components]; + int i, j, k, count; + int video_index = -1; + int audio_index = -1; + int audio_pindex[3] = {-1, -1, -1}; + int subtitle_index = -1; + enum AVMediaType media_type; + + aprofile = _audio_profile(self->profiles[AVMEDIA_TYPE_AUDIO]); + + for (i = 0; i < ss_src->ss_num_components; i++) { + if ((ssc = &ss_src->ss_components[i]) == NULL) + continue; + media_type = ssc_get_media_type(ssc); + if (media_type == AVMEDIA_TYPE_UNKNOWN) + continue; + switch (media_type) { + case AVMEDIA_TYPE_VIDEO: + if (video_index < 0) + video_index = i; + break; + case AVMEDIA_TYPE_AUDIO: + if (aprofile) { + if (lang_match(aprofile->language1, ssc, &audio_pindex[0], i) == 0 && + lang_match(aprofile->language2, ssc, &audio_pindex[1], i) == 0) + lang_match(aprofile->language3, ssc, &audio_pindex[2], i); } + break; + case AVMEDIA_TYPE_SUBTITLE: + if (subtitle_index < 0) + subtitle_index = i; + break; + default: + break; } + } - /* select the preferred audio stream */ - for (i = 0; i < ARRAY_SIZE(audio_pindex); i++) { - if (audio_pindex[i] >= 0) { - audio_index = audio_pindex[i]; - break; - } + /* select the preferred audio stream */ + for (i = 0; i < ARRAY_SIZE(audio_pindex); i++) { + if (audio_pindex[i] >= 0) { + audio_index = audio_pindex[i]; + break; } - - count = 0; - if (video_index >= 0) { - indexes[count++] = video_index; + } + + count = 0; + if (video_index >= 0) { + indexes[count++] = video_index; + } + if (audio_index >= 0) { + for (i = j = 0; i < ARRAY_SIZE(audio_pindex); i++) { + if (audio_pindex[i] >= 0) { + indexes[count++] = audio_pindex[i]; + if ((ssc = &ss_src->ss_components[audio_pindex[i]]) == NULL) + continue; + media_type = ssc_get_media_type(ssc); + if (media_type != AVMEDIA_TYPE_AUDIO) + continue; + j++; + if (aprofile && j >= aprofile->tracks) + break; + } } - if (audio_index >= 0) { - for (i = j = 0; i < ARRAY_SIZE(audio_pindex); i++) { - if (audio_pindex[i] >= 0) { - indexes[count++] = audio_pindex[i]; - if ((ssc = &ss_src->ss_components[audio_pindex[i]]) == NULL) - continue; - media_type = ssc_get_media_type(ssc); - if (media_type != AVMEDIA_TYPE_AUDIO) - continue; - j++; - if (aprofile && j >= aprofile->tracks) - break; - } - } - } else { - /* nothing is preferred, use all audio tracks */ - for (i = j = 0; i < ss_src->ss_num_components; i++) { - if ((ssc = &ss_src->ss_components[i]) == NULL) - continue; - media_type = ssc_get_media_type(ssc); - if (media_type != AVMEDIA_TYPE_AUDIO) - continue; - indexes[count++] = i; - j++; - if (aprofile && j >= aprofile->tracks) - break; - } + } else { + /* nothing is preferred, use all audio tracks */ + for (i = j = 0; i < ss_src->ss_num_components; i++) { + if ((ssc = &ss_src->ss_components[i]) == NULL) + continue; + media_type = ssc_get_media_type(ssc); + if (media_type != AVMEDIA_TYPE_AUDIO) + continue; + indexes[count++] = i; + j++; + if (aprofile && j >= aprofile->tracks) + break; } - if (subtitle_index >= 0) { - indexes[count++] = subtitle_index; + } + if (subtitle_index >= 0) { + indexes[count++] = subtitle_index; + } + + ss = calloc(1, (sizeof(tvh_ss_t) + (sizeof(tvh_ssc_t) * count))); + if (ss) { + ss->ss_refcount = 1; + ss->ss_pcr_pid = ss_src->ss_pcr_pid; + ss->ss_pmt_pid = ss_src->ss_pmt_pid; + service_source_info_copy(&ss->ss_si, &ss_src->ss_si); + for (j = k = 0; j < count; j++) { + i = indexes[j]; + ssc_src = &ss_src->ss_components[i]; + ssc = &ss->ss_components[k]; + assert(ssc); + media_type = ssc_get_media_type(ssc_src); + assert(media_type != AVMEDIA_TYPE_UNKNOWN); + profile = self->profiles[media_type]; + codecs = self->src_codecs[media_type]; + if (profile == NULL) { + indexes[j] = -1; + continue; + } + *ssc = *ssc_src; + if ((stream = tvh_stream_create(self, profile, ssc, codecs))) { + if (stream->is_copy) + tvh_ssc_log(ssc_src, LOG_INFO, "==> Copy", self); + else + tvh_ssc_log(ssc_src, + LOG_INFO, + "==> Using profile %s", + self, + tvh_codec_profile_get_name(profile)); + SLIST_INSERT_HEAD(&self->streams, stream, link); + k++; + } else { + indexes[j] = -1; + continue; + } } - - ss = calloc(1, (sizeof(tvh_ss_t) + (sizeof(tvh_ssc_t) * count))); - if (ss) { - ss->ss_refcount = 1; - ss->ss_pcr_pid = ss_src->ss_pcr_pid; - ss->ss_pmt_pid = ss_src->ss_pmt_pid; - service_source_info_copy(&ss->ss_si, &ss_src->ss_si); - for (j = k = 0; j < count; j++) { - i = indexes[j]; - ssc_src = &ss_src->ss_components[i]; - ssc = &ss->ss_components[k]; - assert(ssc); - media_type = ssc_get_media_type(ssc_src); - assert(media_type != AVMEDIA_TYPE_UNKNOWN); - profile = self->profiles[media_type]; - codecs = self->src_codecs[media_type]; - if (profile == NULL) { - indexes[j] = -1; - continue; - } - *ssc = *ssc_src; - if ((stream = tvh_stream_create(self, profile, ssc, codecs))) { - if (stream->is_copy) - tvh_ssc_log(ssc_src, LOG_INFO, "==> Copy", self); - else - tvh_ssc_log(ssc_src, LOG_INFO, "==> Using profile %s", self, - tvh_codec_profile_get_name(profile)); - SLIST_INSERT_HEAD(&self->streams, stream, link); - k++; - } else { - indexes[j] = -1; - continue; - } - } - ss->ss_num_components = k; - for (i = 0; i < ss_src->ss_num_components; i++) { - for (j = 0; j < count; j++) { - if (i == indexes[j]) - break; - } - if (j < count) - continue; - ssc_src = &ss_src->ss_components[i]; - switch (ssc_src->es_type) { - case SCT_CA: - case SCT_HBBTV: - case SCT_TELETEXT: - break; - default: - tvh_ssc_log(ssc_src, LOG_INFO, "==> Filtered out", self); - break; - } - } + ss->ss_num_components = k; + for (i = 0; i < ss_src->ss_num_components; i++) { + for (j = 0; j < count; j++) { + if (i == indexes[j]) + break; + } + if (j < count) + continue; + ssc_src = &ss_src->ss_components[i]; + switch (ssc_src->es_type) { + case SCT_CA: + case SCT_HBBTV: + case SCT_TELETEXT: + break; + default: + tvh_ssc_log(ssc_src, LOG_INFO, "==> Filtered out", self); + break; + } } - return ss; + } + return ss; } +static void tvh_transcoder_stop(TVHTranscoder* self, int flush) { + TVHStream* stream = NULL; -static void -tvh_transcoder_stop(TVHTranscoder *self, int flush) -{ - TVHStream *stream = NULL; - - SLIST_FOREACH(stream, &self->streams, link) { - tvh_stream_stop(stream, flush); - } + SLIST_FOREACH (stream, &self->streams, link) { + tvh_stream_stop(stream, flush); + } } - -static void -tvh_transcoder_stream(void *opaque, tvh_sm_t *msg) -{ - TVHTranscoder *self = opaque; - tvh_ss_t *ss = NULL; - - switch (msg->sm_type) { - case SMT_PACKET: - if(msg->sm_data) { - tvh_transcoder_handle(self, msg->sm_data); - TVHPKT_CLEAR(msg->sm_data); - } - streaming_msg_free(msg); - break; - case SMT_START: - if (msg->sm_data) { - ss = tvh_transcoder_start(self, msg->sm_data); - streaming_start_unref(msg->sm_data); - msg->sm_data = ss; - } - streaming_target_deliver2(self->output, msg); - break; - case SMT_STOP: - tvh_transcoder_stop(self, 1); - /* !!! FALLTHROUGH !!! */ - default: - streaming_target_deliver2(self->output, msg); - break; - } +static void tvh_transcoder_stream(void* opaque, tvh_sm_t* msg) { + TVHTranscoder* self = opaque; + tvh_ss_t* ss = NULL; + + switch (msg->sm_type) { + case SMT_PACKET: + if (msg->sm_data) { + tvh_transcoder_handle(self, msg->sm_data); + TVHPKT_CLEAR(msg->sm_data); + } + streaming_msg_free(msg); + break; + case SMT_START: + if (msg->sm_data) { + ss = tvh_transcoder_start(self, msg->sm_data); + streaming_start_unref(msg->sm_data); + msg->sm_data = ss; + } + streaming_target_deliver2(self->output, msg); + break; + case SMT_STOP: + tvh_transcoder_stop(self, 1); + /* !!! FALLTHROUGH !!! */ + default: + streaming_target_deliver2(self->output, msg); + break; + } } - static int -tvh_transcoder_setup(TVHTranscoder *self, - const char **profiles, - const char **src_codecs) -{ - const char *profile = NULL; - int i; - - for (i = 0; i < AVMEDIA_TYPE_NB; i++) { - if ((profile = profiles[i]) && strlen(profile)) { - if (!(self->profiles[i] = _find_profile(profile))) { - tvh_transcoder_log(self, LOG_ERR, - "failed to find codec profile: '%s'", profile); - return -1; - } - if (src_codecs[i]) - self->src_codecs[i] = strdup(src_codecs[i]); - } +tvh_transcoder_setup(TVHTranscoder* self, const char** profiles, const char** src_codecs) { + const char* profile = NULL; + int i; + + for (i = 0; i < AVMEDIA_TYPE_NB; i++) { + if ((profile = profiles[i]) && strlen(profile)) { + if (!(self->profiles[i] = _find_profile(profile))) { + tvh_transcoder_log(self, LOG_ERR, "failed to find codec profile: '%s'", profile); + return -1; + } + if (src_codecs[i]) + self->src_codecs[i] = strdup(src_codecs[i]); } - return 0; + } + return 0; } - -static htsmsg_t * -tvh_transcoder_info(void *opaque, htsmsg_t *list) -{ - TVHTranscoder *self = opaque; - streaming_target_t *st = self->output; +static htsmsg_t* tvh_transcoder_info(void* opaque, htsmsg_t* list) { + TVHTranscoder* self = opaque; + streaming_target_t* st = self->output; htsmsg_add_str(list, NULL, "transcoder input"); return st->st_ops.st_info(st->st_opaque, list); } - /* exposed */ -int -tvh_transcoder_deliver(TVHTranscoder *self, th_pkt_t *pkt) -{ - tvh_sm_t *msg = NULL; +int tvh_transcoder_deliver(TVHTranscoder* self, th_pkt_t* pkt) { + tvh_sm_t* msg = NULL; - if (!(msg = streaming_msg_create_pkt(pkt))) { // takes ownership of pkt - tvh_transcoder_log(self, LOG_ERR, "failed to create message"); - return -1; - } - pkt_ref_dec(pkt); - streaming_target_deliver2(self->output, msg); - return 0; + if (!(msg = streaming_msg_create_pkt(pkt))) { // takes ownership of pkt + tvh_transcoder_log(self, LOG_ERR, "failed to create message"); + return -1; + } + pkt_ref_dec(pkt); + streaming_target_deliver2(self->output, msg); + return 0; } +static streaming_ops_t tvh_transcoder_ops = {.st_cb = tvh_transcoder_stream, + .st_info = tvh_transcoder_info}; -static streaming_ops_t tvh_transcoder_ops = { - .st_cb = tvh_transcoder_stream, - .st_info = tvh_transcoder_info -}; +TVHTranscoder* +tvh_transcoder_create(tvh_st_t* output, const char** profiles, const char** src_codecs) { + static uint32_t id = 0; + TVHTranscoder* self = NULL; - -TVHTranscoder * -tvh_transcoder_create(tvh_st_t *output, - const char **profiles, - const char **src_codecs) -{ - static uint32_t id = 0; - TVHTranscoder *self = NULL; - - if (!(self = calloc(1, sizeof(TVHTranscoder)))) { - tvherror(LS_TRANSCODE, "failed to allocate transcoder"); - return NULL; - } - SLIST_INIT(&self->streams); + if (!(self = calloc(1, sizeof(TVHTranscoder)))) { + tvherror(LS_TRANSCODE, "failed to allocate transcoder"); + return NULL; + } + SLIST_INIT(&self->streams); + self->id = ++id; + if (!self->id) { self->id = ++id; - if (!self->id) { - self->id = ++id; - } - self->output = output; - if (tvh_transcoder_setup(self, profiles, src_codecs)) { - tvh_transcoder_destroy(self); - return NULL; - } - streaming_target_init(&self->input, &tvh_transcoder_ops, self, 0); - return self; + } + self->output = output; + if (tvh_transcoder_setup(self, profiles, src_codecs)) { + tvh_transcoder_destroy(self); + return NULL; + } + streaming_target_init(&self->input, &tvh_transcoder_ops, self, 0); + return self; } - -void -tvh_transcoder_destroy(TVHTranscoder *self) -{ - TVHStream *stream = NULL; - int i; - - if (self) { - tvh_transcoder_stop(self, 0); - self->output = NULL; - while (!SLIST_EMPTY(&self->streams)) { - stream = SLIST_FIRST(&self->streams); - SLIST_REMOVE_HEAD(&self->streams, link); - tvh_stream_destroy(stream); - } - for (i = 0; i < AVMEDIA_TYPE_NB; i++) - free(self->src_codecs[i]); - free(self); - self = NULL; +void tvh_transcoder_destroy(TVHTranscoder* self) { + TVHStream* stream = NULL; + int i; + + if (self) { + tvh_transcoder_stop(self, 0); + self->output = NULL; + while (!SLIST_EMPTY(&self->streams)) { + stream = SLIST_FIRST(&self->streams); + SLIST_REMOVE_HEAD(&self->streams, link); + tvh_stream_destroy(stream); } + for (i = 0; i < AVMEDIA_TYPE_NB; i++) + free(self->src_codecs[i]); + free(self); + self = NULL; + } } diff --git a/src/transcoding/transcode/video.c b/src/transcoding/transcode/video.c index 029157c10..0ae6986db 100644 --- a/src/transcoding/transcode/video.c +++ b/src/transcoding/transcode/video.c @@ -23,377 +23,357 @@ #include "hwaccels/hwaccels.h" #endif +static int _video_filters_hw_pix_fmt(enum AVPixelFormat pix_fmt) { + const AVPixFmtDescriptor* desc; -static int -_video_filters_hw_pix_fmt(enum AVPixelFormat pix_fmt) -{ - const AVPixFmtDescriptor *desc; - - if ((desc = av_pix_fmt_desc_get(pix_fmt)) && - (desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { - return 1; - } - return 0; + if ((desc = av_pix_fmt_desc_get(pix_fmt)) && (desc->flags & AV_PIX_FMT_FLAG_HWACCEL)) { + return 1; + } + return 0; } - -static int -_video_filters_get_filters(TVHContext *self, AVDictionary **opts, char **filters) -{ - char download[48]; - char deint[8]; - char hw_deint[64]; - char scale[24]; - char hw_scale[64]; - char upload[48]; - char hw_denoise[64]; - char hw_sharpness[64]; - int ihw = _video_filters_hw_pix_fmt(self->iavctx->pix_fmt); - int ohw = _video_filters_hw_pix_fmt(self->oavctx->pix_fmt); - int filter_scale = (self->iavctx->height != self->oavctx->height); - int filter_deint = 0, filter_download = 0, filter_upload = 0; +static int _video_filters_get_filters(TVHContext* self, AVDictionary** opts, char** filters) { + char download[48]; + char deint[8]; + char hw_deint[64]; + char scale[24]; + char hw_scale[64]; + char upload[48]; + char hw_denoise[64]; + char hw_sharpness[64]; + int ihw = _video_filters_hw_pix_fmt(self->iavctx->pix_fmt); + int ohw = _video_filters_hw_pix_fmt(self->oavctx->pix_fmt); + int filter_scale = (self->iavctx->height != self->oavctx->height); + int filter_deint = 0, filter_download = 0, filter_upload = 0; #if ENABLE_HWACCELS - int filter_denoise = 0; - int filter_sharpness = 0; + int filter_denoise = 0; + int filter_sharpness = 0; #endif - if (tvh_context_get_int_opt(opts, "tvh_filter_deint", &filter_deint)) { - return -1; - } + if (tvh_context_get_int_opt(opts, "tvh_filter_deint", &filter_deint)) { + return -1; + } #if ENABLE_VAAPI - filter_denoise = self->profile->filter_hw_denoise; - filter_sharpness = self->profile->filter_hw_sharpness; + filter_denoise = self->profile->filter_hw_denoise; + filter_sharpness = self->profile->filter_hw_sharpness; #endif - // in --> out | download | upload - // -------------|-------------|------------ - // hw --> hw | 0 | 0 - // sw --> hw | 0 | 1 - // hw --> sw | 1 | 0 - // sw --> sw | 0 | 0 - filter_download = (ihw && (!ohw)) ? 1 : 0; - filter_upload = ((!ihw) && ohw) ? 1 : 0; - - memset(deint, 0, sizeof(deint)); - memset(hw_deint, 0, sizeof(hw_deint)); + // in --> out | download | upload + // -------------|-------------|------------ + // hw --> hw | 0 | 0 + // sw --> hw | 0 | 1 + // hw --> sw | 1 | 0 + // sw --> sw | 0 | 0 + filter_download = (ihw && (!ohw)) ? 1 : 0; + filter_upload = ((!ihw) && ohw) ? 1 : 0; + + memset(deint, 0, sizeof(deint)); + memset(hw_deint, 0, sizeof(hw_deint)); #if ENABLE_HWACCELS - if (filter_deint) { - // when hwaccel is enabled we have two options: - if (ihw) { - // hw deint - hwaccels_get_deint_filter(self->iavctx, hw_deint, sizeof(hw_deint)); - } - else { - // sw deint - if (str_snprintf(deint, sizeof(deint), "yadif")) { - return -1; - } - } + if (filter_deint) { + // when hwaccel is enabled we have two options: + if (ihw) { + // hw deint + hwaccels_get_deint_filter(self->iavctx, hw_deint, sizeof(hw_deint)); + } else { + // sw deint + if (str_snprintf(deint, sizeof(deint), "yadif")) { + return -1; + } } + } #else - if (filter_deint) { - if (str_snprintf(deint, sizeof(deint), "yadif")) { - return -1; - } + if (filter_deint) { + if (str_snprintf(deint, sizeof(deint), "yadif")) { + return -1; } + } #endif - memset(scale, 0, sizeof(scale)); - memset(hw_scale, 0, sizeof(hw_scale)); + memset(scale, 0, sizeof(scale)); + memset(hw_scale, 0, sizeof(hw_scale)); #if ENABLE_HWACCELS - if (filter_scale) { - // when hwaccel is enabled we have two options: - if (ihw) { - // hw scale - hwaccels_get_scale_filter(self->iavctx, self->oavctx, hw_scale, sizeof(hw_scale)); - } - else { - // sw scale - if (str_snprintf(scale, sizeof(scale), "scale=w=-2:h=%d", - self->oavctx->height)) { - return -1; - } - } + if (filter_scale) { + // when hwaccel is enabled we have two options: + if (ihw) { + // hw scale + hwaccels_get_scale_filter(self->iavctx, self->oavctx, hw_scale, sizeof(hw_scale)); + } else { + // sw scale + if (str_snprintf(scale, sizeof(scale), "scale=w=-2:h=%d", self->oavctx->height)) { + return -1; + } } + } #else - if (filter_scale) { - if (str_snprintf(scale, sizeof(scale), "scale=w=-2:h=%d", - self->oavctx->height)) { - return -1; - } + if (filter_scale) { + if (str_snprintf(scale, sizeof(scale), "scale=w=-2:h=%d", self->oavctx->height)) { + return -1; } + } #endif - memset(hw_denoise, 0, sizeof(hw_denoise)); + memset(hw_denoise, 0, sizeof(hw_denoise)); #if ENABLE_HWACCELS - if (filter_denoise) { - // used only when hwaccel is enabled - if (ihw) { - // hw scale - hwaccels_get_denoise_filter(self->iavctx, filter_denoise, hw_denoise, sizeof(hw_denoise)); - } + if (filter_denoise) { + // used only when hwaccel is enabled + if (ihw) { + // hw scale + hwaccels_get_denoise_filter(self->iavctx, filter_denoise, hw_denoise, sizeof(hw_denoise)); } + } #endif - memset(hw_sharpness, 0, sizeof(hw_sharpness)); + memset(hw_sharpness, 0, sizeof(hw_sharpness)); #if ENABLE_HWACCELS - if (filter_sharpness) { - // used only when hwaccel is enabled - if (ihw) { - // hw scale - hwaccels_get_sharpness_filter(self->iavctx, filter_sharpness, hw_sharpness, sizeof(hw_sharpness)); - } + if (filter_sharpness) { + // used only when hwaccel is enabled + if (ihw) { + // hw scale + hwaccels_get_sharpness_filter(self->iavctx, + filter_sharpness, + hw_sharpness, + sizeof(hw_sharpness)); } + } #endif #if ENABLE_HWACCELS - // no filter required. + // no filter required. #else - if (deint[0] == '\0' && scale[0] == '\0') { - filter_download = filter_upload = 0; - } + if (deint[0] == '\0' && scale[0] == '\0') { + filter_download = filter_upload = 0; + } #endif - memset(download, 0, sizeof(download)); - if (filter_download && - str_snprintf(download, sizeof(download), "hwdownload,format=pix_fmts=%s", - av_get_pix_fmt_name(self->iavctx->sw_pix_fmt))) { - return -1; - } - - memset(upload, 0, sizeof(upload)); - if (filter_upload && - str_snprintf(upload, sizeof(upload), "format=pix_fmts=%s|%s,hwupload", - av_get_pix_fmt_name(self->oavctx->sw_pix_fmt), - av_get_pix_fmt_name(self->oavctx->pix_fmt))) { - return -1; - } - - if (!(*filters = str_join(",", hw_deint, hw_scale, hw_denoise, hw_sharpness, download, deint, scale, upload, NULL))) { - return -1; - } + memset(download, 0, sizeof(download)); + if (filter_download && + str_snprintf(download, + sizeof(download), + "hwdownload,format=pix_fmts=%s", + av_get_pix_fmt_name(self->iavctx->sw_pix_fmt))) { + return -1; + } + + memset(upload, 0, sizeof(upload)); + if (filter_upload && + str_snprintf(upload, + sizeof(upload), + "format=pix_fmts=%s|%s,hwupload", + av_get_pix_fmt_name(self->oavctx->sw_pix_fmt), + av_get_pix_fmt_name(self->oavctx->pix_fmt))) { + return -1; + } + + if (!(*filters = str_join(",", + hw_deint, + hw_scale, + hw_denoise, + hw_sharpness, + download, + deint, + scale, + upload, + NULL))) { + return -1; + } - return 0; + return 0; } - -static int -tvh_video_context_open_decoder(TVHContext *self, AVDictionary **opts) -{ +static int tvh_video_context_open_decoder(TVHContext* self, AVDictionary** opts) { #if ENABLE_HWACCELS - int hwaccel = -1; - if ((hwaccel = tvh_codec_profile_video_get_hwaccel(self->profile)) < 0) { - return -1; - } - if (hwaccel) { - self->iavctx->get_format = hwaccels_decode_get_format; - } - mystrset(&self->hw_accel_device, self->profile->device); + int hwaccel = -1; + if ((hwaccel = tvh_codec_profile_video_get_hwaccel(self->profile)) < 0) { + return -1; + } + if (hwaccel) { + self->iavctx->get_format = hwaccels_decode_get_format; + } + mystrset(&self->hw_accel_device, self->profile->device); #endif - self->iavctx->time_base = av_make_q(1, 90000); // MPEG-TS uses a fixed timebase of 90kHz - return 0; + self->iavctx->time_base = av_make_q(1, 90000); // MPEG-TS uses a fixed timebase of 90kHz + return 0; } - -static int -tvh_video_context_notify_gh(TVHContext *self) -{ - /* notify global headers that we're live */ - /* the video packets might be delayed */ - th_pkt_t *pkt = NULL; - - pkt = pkt_alloc(self->stream->type, NULL, 0, - self->src_pkt->pkt_pts, - self->src_pkt->pkt_dts, - self->src_pkt->pkt_pcr); - if (pkt) { - return tvh_context_deliver(self, pkt); - } - return -1; +static int tvh_video_context_notify_gh(TVHContext* self) { + /* notify global headers that we're live */ + /* the video packets might be delayed */ + th_pkt_t* pkt = NULL; + + pkt = pkt_alloc(self->stream->type, + NULL, + 0, + self->src_pkt->pkt_pts, + self->src_pkt->pkt_dts, + self->src_pkt->pkt_pcr); + if (pkt) { + return tvh_context_deliver(self, pkt); + } + return -1; } +static int tvh_video_context_open_encoder(TVHContext* self, AVDictionary** opts) { + AVRational ticks_per_frame; -static int -tvh_video_context_open_encoder(TVHContext *self, AVDictionary **opts) -{ - AVRational ticks_per_frame; - - if (tvh_context_get_int_opt(opts, "pix_fmt", &self->oavctx->pix_fmt) || - tvh_context_get_int_opt(opts, "width", &self->oavctx->width) || - tvh_context_get_int_opt(opts, "height", &self->oavctx->height)) { - return -1; - } + if (tvh_context_get_int_opt(opts, "pix_fmt", &self->oavctx->pix_fmt) || + tvh_context_get_int_opt(opts, "width", &self->oavctx->width) || + tvh_context_get_int_opt(opts, "height", &self->oavctx->height)) { + return -1; + } #if ENABLE_HWACCELS - self->oavctx->coded_width = self->oavctx->width; - self->oavctx->coded_height = self->oavctx->height; - if (hwaccels_encode_setup_context(self->oavctx, self->profile->low_power)) { - return -1; - } + self->oavctx->coded_width = self->oavctx->width; + self->oavctx->coded_height = self->oavctx->height; + if (hwaccels_encode_setup_context(self->oavctx, self->profile->low_power)) { + return -1; + } #endif - // XXX: is this a safe assumption? - if (!self->iavctx->framerate.num) { - self->iavctx->framerate = av_make_q(30, 1); - } - self->oavctx->framerate = self->iavctx->framerate; - self->oavctx->ticks_per_frame = (90000 * self->iavctx->framerate.den) / self->iavctx->framerate.num; // We assume 90kHz as timebase which is mandatory for MPEG-TS - ticks_per_frame = av_make_q(self->oavctx->ticks_per_frame, 1); - self->oavctx->time_base = av_inv_q(av_mul_q( - self->oavctx->framerate, ticks_per_frame)); - self->oavctx->gop_size = ceil(av_q2d(av_inv_q(av_mul_q( - self->oavctx->time_base, ticks_per_frame)))); - self->oavctx->gop_size *= 3; - - self->oavctx->sample_aspect_ratio = self->iavctx->sample_aspect_ratio; - return 0; + // XXX: is this a safe assumption? + if (!self->iavctx->framerate.num) { + self->iavctx->framerate = av_make_q(30, 1); + } + self->oavctx->framerate = self->iavctx->framerate; + self->oavctx->ticks_per_frame = (90000 * self->iavctx->framerate.den) / + self->iavctx->framerate.num; // We assume 90kHz as timebase which is mandatory for MPEG-TS + ticks_per_frame = av_make_q(self->oavctx->ticks_per_frame, 1); + self->oavctx->time_base = av_inv_q(av_mul_q(self->oavctx->framerate, ticks_per_frame)); + self->oavctx->gop_size = + ceil(av_q2d(av_inv_q(av_mul_q(self->oavctx->time_base, ticks_per_frame)))); + self->oavctx->gop_size *= 3; + + self->oavctx->sample_aspect_ratio = self->iavctx->sample_aspect_ratio; + return 0; } +static int tvh_video_context_open_filters(TVHContext* self, AVDictionary** opts) { + char source_args[128]; + char* filters = NULL; + + // source args + memset(source_args, 0, sizeof(source_args)); + if (str_snprintf(source_args, + sizeof(source_args), + "video_size=%dx%d:pix_fmt=%s:time_base=%d/%d:pixel_aspect=%d/%d", + self->iavctx->width, + self->iavctx->height, + av_get_pix_fmt_name(self->iavctx->pix_fmt), + self->iavctx->time_base.num, + self->iavctx->time_base.den, + self->iavctx->sample_aspect_ratio.num, + self->iavctx->sample_aspect_ratio.den)) { + return -1; + } -static int -tvh_video_context_open_filters(TVHContext *self, AVDictionary **opts) -{ - char source_args[128]; - char *filters = NULL; - - // source args - memset(source_args, 0, sizeof(source_args)); - if (str_snprintf(source_args, sizeof(source_args), - "video_size=%dx%d:pix_fmt=%s:time_base=%d/%d:pixel_aspect=%d/%d", - self->iavctx->width, - self->iavctx->height, - av_get_pix_fmt_name(self->iavctx->pix_fmt), - self->iavctx->time_base.num, - self->iavctx->time_base.den, - self->iavctx->sample_aspect_ratio.num, - self->iavctx->sample_aspect_ratio.den)) { - return -1; - } - - // filters - if (_video_filters_get_filters(self, opts, &filters)) { - return -1; - } - - int ret = tvh_context_open_filters(self, - "buffer", source_args, // source - strlen(filters) ? filters : "null", // filters - "buffersink", // sink - "pix_fmts", &self->oavctx->pix_fmt, // sink option: pix_fmt - sizeof(self->oavctx->pix_fmt), - NULL); // _IMPORTANT!_ - str_clear(filters); - return ret; + // filters + if (_video_filters_get_filters(self, opts, &filters)) { + return -1; + } + + int ret = tvh_context_open_filters(self, + "buffer", + source_args, // source + strlen(filters) ? filters : "null", // filters + "buffersink", // sink + "pix_fmts", + &self->oavctx->pix_fmt, // sink option: pix_fmt + sizeof(self->oavctx->pix_fmt), + NULL); // _IMPORTANT!_ + str_clear(filters); + return ret; } - -static int -tvh_video_context_open(TVHContext *self, TVHOpenPhase phase, AVDictionary **opts) -{ - switch (phase) { - case OPEN_DECODER: - return tvh_video_context_open_decoder(self, opts); - case OPEN_DECODER_POST: - return tvh_video_context_notify_gh(self); - case OPEN_ENCODER: - return tvh_video_context_open_encoder(self, opts); - case OPEN_ENCODER_POST: - return tvh_video_context_open_filters(self, opts); - default: - break; - } - return 0; +static int tvh_video_context_open(TVHContext* self, TVHOpenPhase phase, AVDictionary** opts) { + switch (phase) { + case OPEN_DECODER: + return tvh_video_context_open_decoder(self, opts); + case OPEN_DECODER_POST: + return tvh_video_context_notify_gh(self); + case OPEN_ENCODER: + return tvh_video_context_open_encoder(self, opts); + case OPEN_ENCODER_POST: + return tvh_video_context_open_filters(self, opts); + default: + break; + } + return 0; } - -static int -tvh_video_context_encode(TVHContext *self, AVFrame *avframe) -{ - avframe->pts = avframe->best_effort_timestamp; - if (avframe->pts <= self->pts) { - tvh_context_log(self, LOG_WARNING, - "Invalid pts (%"PRId64") <= last (%"PRId64"), dropping frame", - avframe->pts, self->pts); - return AVERROR(EAGAIN); - } - self->pts = avframe->pts; - if (avframe->interlaced_frame) { - self->oavctx->field_order = - avframe->top_field_first ? AV_FIELD_TB : AV_FIELD_BT; - } - else { - self->oavctx->field_order = AV_FIELD_PROGRESSIVE; - } - return 0; +static int tvh_video_context_encode(TVHContext* self, AVFrame* avframe) { + avframe->pts = avframe->best_effort_timestamp; + if (avframe->pts <= self->pts) { + tvh_context_log(self, + LOG_WARNING, + "Invalid pts (%" PRId64 ") <= last (%" PRId64 "), dropping frame", + avframe->pts, + self->pts); + return AVERROR(EAGAIN); + } + self->pts = avframe->pts; + if (avframe->interlaced_frame) { + self->oavctx->field_order = avframe->top_field_first ? AV_FIELD_TB : AV_FIELD_BT; + } else { + self->oavctx->field_order = AV_FIELD_PROGRESSIVE; + } + return 0; } - -static int -tvh_video_context_ship(TVHContext *self, AVPacket *avpkt) -{ - if (avpkt->size < 0 || avpkt->pts < avpkt->dts) { - tvh_context_log(self, LOG_ERR, "encode failed"); - return -1; - } - return avpkt->size; +static int tvh_video_context_ship(TVHContext* self, AVPacket* avpkt) { + if (avpkt->size < 0 || avpkt->pts < avpkt->dts) { + tvh_context_log(self, LOG_ERR, "encode failed"); + return -1; + } + return avpkt->size; } - -static int -tvh_video_context_wrap(TVHContext *self, AVPacket *avpkt, th_pkt_t *pkt) -{ - enum AVPictureType pict_type = self->oavframe->pict_type; - - if (pict_type == AV_PICTURE_TYPE_NONE && avpkt->flags & AV_PKT_FLAG_KEY) { - pict_type = AV_PICTURE_TYPE_I; +static int tvh_video_context_wrap(TVHContext* self, AVPacket* avpkt, th_pkt_t* pkt) { + enum AVPictureType pict_type = self->oavframe->pict_type; + + if (pict_type == AV_PICTURE_TYPE_NONE && avpkt->flags & AV_PKT_FLAG_KEY) { + pict_type = AV_PICTURE_TYPE_I; + } + if (pict_type == AV_PICTURE_TYPE_NONE) { + // some codecs do not set pict_type but set key_frame, in this case, + // we assume that when key_frame == 1 the frame is an I-frame + // (all the others are assumed to be P-frames) + if (self->oavframe->key_frame) { + pict_type = AV_PICTURE_TYPE_I; + } else { + pict_type = AV_PICTURE_TYPE_P; } - if (pict_type == AV_PICTURE_TYPE_NONE) { - // some codecs do not set pict_type but set key_frame, in this case, - // we assume that when key_frame == 1 the frame is an I-frame - // (all the others are assumed to be P-frames) - if (self->oavframe->key_frame) { - pict_type = AV_PICTURE_TYPE_I; - } - else { - pict_type = AV_PICTURE_TYPE_P; - } - } - - switch (pict_type) { - case AV_PICTURE_TYPE_I: - pkt->v.pkt_frametype = PKT_I_FRAME; - break; - case AV_PICTURE_TYPE_P: - pkt->v.pkt_frametype = PKT_P_FRAME; - break; - case AV_PICTURE_TYPE_B: - pkt->v.pkt_frametype = PKT_B_FRAME; - break; - case AV_PICTURE_TYPE_NONE: - break; - default: - tvh_context_log(self, LOG_WARNING, "unknown picture type: %d", - pict_type); - break; - } - pkt->pkt_duration = avpkt->duration; - pkt->pkt_commercial = self->src_pkt->pkt_commercial; - pkt->v.pkt_field = (self->oavctx->field_order > AV_FIELD_PROGRESSIVE); - pkt->v.pkt_aspect_num = self->src_pkt->v.pkt_aspect_num; - pkt->v.pkt_aspect_den = self->src_pkt->v.pkt_aspect_den; - return 0; + } + + switch (pict_type) { + case AV_PICTURE_TYPE_I: + pkt->v.pkt_frametype = PKT_I_FRAME; + break; + case AV_PICTURE_TYPE_P: + pkt->v.pkt_frametype = PKT_P_FRAME; + break; + case AV_PICTURE_TYPE_B: + pkt->v.pkt_frametype = PKT_B_FRAME; + break; + case AV_PICTURE_TYPE_NONE: + break; + default: + tvh_context_log(self, LOG_WARNING, "unknown picture type: %d", pict_type); + break; + } + pkt->pkt_duration = avpkt->duration; + pkt->pkt_commercial = self->src_pkt->pkt_commercial; + pkt->v.pkt_field = (self->oavctx->field_order > AV_FIELD_PROGRESSIVE); + pkt->v.pkt_aspect_num = self->src_pkt->v.pkt_aspect_num; + pkt->v.pkt_aspect_den = self->src_pkt->v.pkt_aspect_den; + return 0; } - -static void -tvh_video_context_close(TVHContext *self) -{ +static void tvh_video_context_close(TVHContext* self) { #if ENABLE_HWACCELS - hwaccels_encode_close_context(self->oavctx); - hwaccels_decode_close_context(self->iavctx); + hwaccels_encode_close_context(self->oavctx); + hwaccels_decode_close_context(self->iavctx); #endif } - TVHContextType TVHVideoContext = { .media_type = AVMEDIA_TYPE_VIDEO, .open = tvh_video_context_open, diff --git a/src/trap.c b/src/trap.c index 952f55318..760f3496a 100644 --- a/src/trap.c +++ b/src/trap.c @@ -59,12 +59,10 @@ static char libs[1024]; static char self[PATH_MAX]; #ifdef PLATFORM_FREEBSD -extern char **environ; +extern char** environ; #endif -static void -sappend(char *buf, size_t l, const char *fmt, ...) -{ +static void sappend(char* buf, size_t l, const char* fmt, ...) { va_list ap; va_start(ap, fmt); @@ -72,21 +70,17 @@ sappend(char *buf, size_t l, const char *fmt, ...) va_end(ap); } - - /** * */ #ifndef ENABLE_LIBUNWIND #if ENABLE_EXECINFO -static int -addr2lineresolve(const char *binary, intptr_t addr, char *buf0, size_t buflen) -{ - char *buf = buf0; - int fd[2], r, f; - const char *argv[5]; - pid_t p; - char addrstr[30], *cp; +static int addr2lineresolve(const char* binary, intptr_t addr, char* buf0, size_t buflen) { + char* buf = buf0; + int fd[2], r, f; + const char* argv[5]; + pid_t p; + char addrstr[30], *cp; argv[0] = "addr2line"; argv[1] = "-e"; @@ -94,43 +88,43 @@ addr2lineresolve(const char *binary, intptr_t addr, char *buf0, size_t buflen) argv[3] = addrstr; argv[4] = NULL; - snprintf(addrstr, sizeof(addrstr), "%p", (void *)(addr-1)); + snprintf(addrstr, sizeof(addrstr), "%p", (void*)(addr - 1)); - if(pipe(fd) == -1) + if (pipe(fd) == -1) return -1; - if((p = fork()) == -1) + if ((p = fork()) == -1) return -1; - if(p == 0) { + if (p == 0) { close(0); close(2); close(fd[0]); dup2(fd[1], 1); close(fd[1]); - if((f = open("/dev/null", O_RDWR)) == -1) + if ((f = open("/dev/null", O_RDWR)) == -1) exit(1); dup2(f, 0); dup2(f, 2); close(f); - execve("/usr/bin/addr2line", (char *const *) argv, environ); + execve("/usr/bin/addr2line", (char* const*)argv, environ); exit(2); } close(fd[1]); *buf = 0; - while(buflen > 1) { + while (buflen > 1) { r = read(fd[0], buf, buflen); - if(r < 1) + if (r < 1) break; buf += r; buflen -= r; *buf = 0; - cp = strchr(buf0, '\n'); - if(cp != NULL) { + cp = strchr(buf0, '\n'); + if (cp != NULL) { *cp = 0; break; } @@ -142,14 +136,12 @@ addr2lineresolve(const char *binary, intptr_t addr, char *buf0, size_t buflen) #endif #if ENABLE_LIBUNWIND -static void -traphandler_libunwind() -{ +static void traphandler_libunwind() { tvhlog_spawn(LOG_ALERT, LS_CRASH, "STACKTRACE"); - unw_cursor_t cursor; + unw_cursor_t cursor; unw_context_t uc; - unw_word_t ip, sp; - char buf[128]; + unw_word_t ip, sp; + char buf[128]; unw_getcontext(&uc); unw_init_local(&cursor, &uc); @@ -157,55 +149,65 @@ traphandler_libunwind() unw_get_reg(&cursor, UNW_REG_IP, &ip); unw_get_reg(&cursor, UNW_REG_SP, &sp); unw_word_t offp = 0; - const int pn = unw_get_proc_name(&cursor, buf, sizeof buf, &offp); - if (pn) *buf=0; - tvhlog_spawn (LOG_ALERT, LS_CRASH, "%s+%lx (ip=%lx sp=%lx)", buf, (long)offp, (long)ip, (long)sp); + const int pn = unw_get_proc_name(&cursor, buf, sizeof buf, &offp); + if (pn) + *buf = 0; + tvhlog_spawn(LOG_ALERT, + LS_CRASH, + "%s+%lx (ip=%lx sp=%lx)", + buf, + (long)offp, + (long)ip, + (long)sp); } } #endif -static void -traphandler(int sig, siginfo_t *si, void *UC) -{ +static void traphandler(int sig, siginfo_t* si, void* UC) { #ifdef NGREG - ucontext_t *uc = UC; + ucontext_t* uc = UC; #endif #if ENABLE_EXECINFO - char buf[200]; - static void *frames[MAXFRAMES]; - int nframes = backtrace(frames, MAXFRAMES); - Dl_info dli; + char buf[200]; + static void* frames[MAXFRAMES]; + int nframes = backtrace(frames, MAXFRAMES); + Dl_info dli; #endif #if defined(NGREG) || ENABLE_EXECINFO int i; #endif - const char *reason = NULL; + const char* reason = NULL; tvhlog_spawn(LOG_ALERT, LS_CRASH, "Signal: %d in %s ", sig, line1); - switch(sig) { - case SIGSEGV: - switch(si->si_code) { - case SEGV_MAPERR: reason = "Address not mapped"; break; - case SEGV_ACCERR: reason = "Access error"; break; - } - break; + switch (sig) { + case SIGSEGV: + switch (si->si_code) { + case SEGV_MAPERR: + reason = "Address not mapped"; + break; + case SEGV_ACCERR: + reason = "Access error"; + break; + } + break; - case SIGFPE: - switch(si->si_code) { - case FPE_INTDIV: reason = "Integer division by zero"; break; - } - break; + case SIGFPE: + switch (si->si_code) { + case FPE_INTDIV: + reason = "Integer division by zero"; + break; + } + break; } - tvhlog_spawn(LOG_ALERT, LS_CRASH, "Fault address %p (%s)", - si->si_addr, reason ?: "N/A"); + tvhlog_spawn(LOG_ALERT, LS_CRASH, "Fault address %p (%s)", si->si_addr, reason ?: "N/A"); tvhlog_spawn(LOG_ALERT, LS_CRASH, "Loaded libraries: %s ", libs); #ifdef NGREG snprintf(tmpbuf, sizeof(tmpbuf), "Register dump [%d]: ", (int)NGREG); - for(i = 0; i < NGREG; i++) { + for (i = 0; i < NGREG; i++) { sappend(tmpbuf, sizeof(tmpbuf), "%016" PRIx64, uc->uc_mcontext.gregs[i]); } #endif @@ -225,114 +227,110 @@ traphandler(int sig, siginfo_t *si, void *UC) #if ENABLE_EXECINFO tvhlog_spawn(LOG_ALERT, LS_CRASH, "STACKTRACE"); - for(i = 0; i < nframes; i++) { + for (i = 0; i < nframes; i++) { - if(dladdr(frames[i], &dli)) { + if (dladdr(frames[i], &dli)) { - if(dli.dli_sname != NULL && dli.dli_saddr != NULL) { - tvhlog_spawn(LOG_ALERT, LS_CRASH, "%s+0x%tx (%s)", - dli.dli_sname, - frames[i] - dli.dli_saddr, - dli.dli_fname); + if (dli.dli_sname != NULL && dli.dli_saddr != NULL) { + tvhlog_spawn(LOG_ALERT, + LS_CRASH, + "%s+0x%tx (%s)", + dli.dli_sname, + frames[i] - dli.dli_saddr, + dli.dli_fname); continue; } - if(self[0] && !addr2lineresolve(self, frames[i] - dli.dli_fbase, buf, sizeof(buf))) { + if (self[0] && !addr2lineresolve(self, frames[i] - dli.dli_fbase, buf, sizeof(buf))) { tvhlog_spawn(LOG_ALERT, LS_CRASH, "%s %p %p", buf, frames[i], dli.dli_fbase); continue; } - if(dli.dli_fname != NULL && dli.dli_fbase != NULL) { - tvhlog_spawn(LOG_ALERT, LS_CRASH, "%s %p %p", - dli.dli_fname, frames[i], dli.dli_fbase); + if (dli.dli_fname != NULL && dli.dli_fbase != NULL) { + tvhlog_spawn(LOG_ALERT, LS_CRASH, "%s %p %p", dli.dli_fname, frames[i], dli.dli_fbase); continue; } - tvhlog_spawn(LOG_ALERT, LS_CRASH, "%p %p", frames[i], dli.dli_fbase); } } #endif } - - -static int -callback(struct dl_phdr_info *info, size_t size, void *data) -{ - if(info->dlpi_name[0]) +static int callback(struct dl_phdr_info* info, size_t size, void* data) { + if (info->dlpi_name[0]) sappend(libs, sizeof(libs), "%s ", info->dlpi_name); return 0; } - -void -trap_init(const char *ver) -{ - int r; - uint8_t digest[20]; +void trap_init(const char* ver) { + int r; + uint8_t digest[20]; struct sigaction sa, old; - char path[256]; + char path[256]; SHA_CTX binsum; - int fd; + int fd; r = readlink("/proc/self/exe", self, sizeof(self) - 1); - if(r == -1) + if (r == -1) self[0] = 0; else self[r] = 0; - memset(digest, 0, sizeof(digest)); - if((fd = open("/proc/self/exe", O_RDONLY)) != -1) { + memset(digest, 0, sizeof(digest)); + if ((fd = open("/proc/self/exe", O_RDONLY)) != -1) { struct stat st; - if(!fstat(fd, &st)) { - char *m = malloc(st.st_size); - if(m != NULL) { - if(read(fd, m, st.st_size) == st.st_size) { - SHA1_Init(&binsum); - SHA1_Update(&binsum, (void *)m, st.st_size); - SHA1_Final(digest, &binsum); - } - free(m); + if (!fstat(fd, &st)) { + char* m = malloc(st.st_size); + if (m != NULL) { + if (read(fd, m, st.st_size) == st.st_size) { + SHA1_Init(&binsum); + SHA1_Update(&binsum, (void*)m, st.st_size); + SHA1_Final(digest, &binsum); + } + free(m); } } close(fd); } - - snprintf(line1, sizeof(line1), - "PRG: %s (%s) " - "[%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" - "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x] " - "CWD: %s ", ver, tvheadend_version, - digest[0], - digest[1], - digest[2], - digest[3], - digest[4], - digest[5], - digest[6], - digest[7], - digest[8], - digest[9], - digest[10], - digest[11], - digest[12], - digest[13], - digest[14], - digest[15], - digest[16], - digest[17], - digest[18], - digest[19], - getcwd(path, sizeof(path))); + + snprintf(line1, + sizeof(line1), + "PRG: %s (%s) " + "[%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" + "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x] " + "CWD: %s ", + ver, + tvheadend_version, + digest[0], + digest[1], + digest[2], + digest[3], + digest[4], + digest[5], + digest[6], + digest[7], + digest[8], + digest[9], + digest[10], + digest[11], + digest[12], + digest[13], + digest[14], + digest[15], + digest[16], + digest[17], + digest[18], + digest[19], + getcwd(path, sizeof(path))); memcpy(tvh_binshasum, digest, 20); dl_iterate_phdr(callback, NULL); - + #if ENABLE_EXECINFO - void *frames[MAXFRAMES]; + void* frames[MAXFRAMES]; /* warmup backtrace allocators */ backtrace(frames, MAXFRAMES); #endif @@ -348,12 +346,12 @@ trap_init(const char *ver) sigaddset(&m, SIGFPE); sa.sa_sigaction = traphandler; - sa.sa_flags = SA_SIGINFO | SA_RESETHAND; + sa.sa_flags = SA_SIGINFO | SA_RESETHAND; sigaction(SIGSEGV, &sa, &old); - sigaction(SIGBUS, &sa, &old); - sigaction(SIGILL, &sa, &old); + sigaction(SIGBUS, &sa, &old); + sigaction(SIGILL, &sa, &old); sigaction(SIGABRT, &sa, &old); - sigaction(SIGFPE, &sa, &old); + sigaction(SIGFPE, &sa, &old); sigprocmask(SIG_UNBLOCK, &m, NULL); } @@ -363,9 +361,7 @@ trap_init(const char *ver) #include #include -void -trap_init(const char *ver) -{ +void trap_init(const char* ver) { sigset_t m; sigemptyset(&m); @@ -380,9 +376,5 @@ trap_init(const char *ver) #else -void -trap_init(const char *ver) -{ - -} +void trap_init(const char* ver) {} #endif diff --git a/src/trap.h b/src/trap.h index bc40a2844..660a46fc9 100644 --- a/src/trap.h +++ b/src/trap.h @@ -19,7 +19,6 @@ #ifndef TRAP_H__ #define TRAP_H__ -void trap_init(const char *swname); +void trap_init(const char* swname); #endif /* TRAP_H__ */ - diff --git a/src/tvh_locale.c b/src/tvh_locale.c index 7d1420e99..41ec68653 100644 --- a/src/tvh_locale.c +++ b/src/tvh_locale.c @@ -23,13 +23,13 @@ #include "redblack.h" struct tvh_locale { - const char *lang; - const char **strings; + const char* lang; + const char** strings; }; #include "tvh_locale_inc.c" -#define ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) tvh_mutex_t tvh_gettext_mutex = TVH_THREAD_MUTEX_INITIALIZER; @@ -39,39 +39,37 @@ tvh_mutex_t tvh_gettext_mutex = TVH_THREAD_MUTEX_INITIALIZER; struct msg { RB_ENTRY(msg) link; - const char *src; - const char *dst; + const char* src; + const char* dst; }; struct lng { RB_ENTRY(lng) link; - const char *tvh_lang; - const char *locale_lang; - int msgs_initialized; + const char* tvh_lang; + const char* locale_lang; + int msgs_initialized; RB_HEAD(, msg) msgs; }; static RB_HEAD(, lng) lngs; -static struct lng *lng_default = NULL; -static struct lng *lng_last = NULL; +static struct lng* lng_default = NULL; +static struct lng* lng_last = NULL; /* * Message RB tree */ -static inline int msg_cmp(const struct msg *a, const struct msg *b) -{ +static inline int msg_cmp(const struct msg* a, const struct msg* b) { return strcmp(a->src, b->src); } -static void msg_add_strings(struct lng *lng, const char **strings) -{ - struct msg *m; - const char **p; +static void msg_add_strings(struct lng* lng, const char** strings) { + struct msg* m; + const char** p; for (p = strings; *p; p += 2) { - m = calloc(1, sizeof(*m)); + m = calloc(1, sizeof(*m)); m->src = p[0]; m->dst = p[1]; if (RB_INSERT_SORTED(&lng->msgs, m, link, msg_cmp)) @@ -79,12 +77,11 @@ static void msg_add_strings(struct lng *lng, const char **strings) } } -static inline const char *msg_find(struct lng *lng, const char *msg) -{ +static inline const char* msg_find(struct lng* lng, const char* msg) { struct msg *m, ms; ms.src = msg; - m = RB_FIND(&lng->msgs, &ms, link, msg_cmp); + m = RB_FIND(&lng->msgs, &ms, link, msg_cmp); if (m) return m->dst; return msg; @@ -94,25 +91,22 @@ static inline const char *msg_find(struct lng *lng, const char *msg) * Language RB tree */ -static inline int lng_cmp(const struct lng *a, const struct lng *b) -{ +static inline int lng_cmp(const struct lng* a, const struct lng* b) { return strcmp(a->tvh_lang, b->tvh_lang); } -static struct lng *lng_add(const char *tvh_lang, const char *locale_lang) -{ - struct lng *l = calloc(1, sizeof(*l)); - l->tvh_lang = tvh_lang; +static struct lng* lng_add(const char* tvh_lang, const char* locale_lang) { + struct lng* l = calloc(1, sizeof(*l)); + l->tvh_lang = tvh_lang; l->locale_lang = locale_lang; if (RB_INSERT_SORTED(&lngs, l, link, lng_cmp)) abort(); return l; } -static void lng_init(struct lng *l) -{ - struct tvh_locale *tl; - int i; +static void lng_init(struct lng* l) { + struct tvh_locale* tl; + int i; l->msgs_initialized = 1; for (i = 0, tl = tvh_locales; i < ARRAY_SIZE(tvh_locales); i++, tl++) @@ -122,18 +116,17 @@ static void lng_init(struct lng *l) } } -static struct lng *lng_get(const char *tvh_lang) -{ +static struct lng* lng_get(const char* tvh_lang) { struct lng *l, ls; - char *s; + char* s; if (tvh_lang != NULL && tvh_lang[0] != '\0') { - s = alloca(strlen(tvh_lang) + 1); + s = alloca(strlen(tvh_lang) + 1); ls.tvh_lang = s; - for ( ; *tvh_lang && *tvh_lang != ','; s++, tvh_lang++) + for (; *tvh_lang && *tvh_lang != ','; s++, tvh_lang++) *s = *tvh_lang; *s = '\0'; - l = RB_FIND(&lngs, &ls, link, lng_cmp); + l = RB_FIND(&lngs, &ls, link, lng_cmp); if (l) { if (!l->msgs_initialized) lng_init(l); @@ -143,12 +136,11 @@ static struct lng *lng_get(const char *tvh_lang) return lng_get("eng"); } -static struct lng *lng_get_locale(char *locale_lang) -{ - struct lng *l; +static struct lng* lng_get_locale(char* locale_lang) { + struct lng* l; if (locale_lang != NULL && locale_lang[0] != '\0') { - RB_FOREACH(l, &lngs, link) + RB_FOREACH (l, &lngs, link) if (!strcmp(l->locale_lang, locale_lang)) { if (!l->msgs_initialized) lng_init(l); @@ -161,14 +153,13 @@ static struct lng *lng_get_locale(char *locale_lang) /* * */ -int tvh_gettext_langcode_valid(const char *code) -{ +int tvh_gettext_langcode_valid(const char* code) { struct lng ls; - int ret; + int ret; tvh_mutex_lock(&tvh_gettext_mutex); ls.tvh_lang = code; - ret = RB_FIND(&lngs, &ls, link, lng_cmp) != NULL; + ret = RB_FIND(&lngs, &ls, link, lng_cmp) != NULL; tvh_mutex_unlock(&tvh_gettext_mutex); return ret; } @@ -177,16 +168,14 @@ int tvh_gettext_langcode_valid(const char *code) * */ -const char *tvh_gettext_get_lang(const char *lang) -{ - struct lng *l = lng_get(lang); +const char* tvh_gettext_get_lang(const char* lang) { + struct lng* l = lng_get(lang); return l->locale_lang; } -static void tvh_gettext_default_init(void) -{ +static void tvh_gettext_default_init(void) { static char dflt[16]; - char *p; + char* p; p = getenv("LC_ALL"); if (p == NULL) @@ -194,17 +183,21 @@ static void tvh_gettext_default_init(void) if (p == NULL) p = getenv("LANGUAGE"); if (p == NULL) - p = (char *)"en_US"; + p = (char*)"en_US"; strlcpy(dflt, p, sizeof(dflt)); - for (p = dflt; *p && *p != '.'; p++); - if (*p == '.') *p = '\0'; + for (p = dflt; *p && *p != '.'; p++) + ; + if (*p == '.') + *p = '\0'; if ((lng_default = lng_get_locale(dflt)) != NULL) return; - for (p = dflt; *p && *p != '_'; p++); - if (*p == '_') *p = '\0'; + for (p = dflt; *p && *p != '_'; p++) + ; + if (*p == '_') + *p = '\0'; if ((lng_default = lng_get_locale(dflt)) != NULL) return; @@ -214,8 +207,7 @@ static void tvh_gettext_default_init(void) return; } -const char *tvh_gettext_lang(const char *lang, const char *s) -{ +const char* tvh_gettext_lang(const char* lang, const char* s) { tvh_mutex_lock(&tvh_gettext_mutex); if (lang == NULL) { s = msg_find(lng_default, s); @@ -237,59 +229,93 @@ const char *tvh_gettext_lang(const char *lang, const char *s) * */ -void tvh_gettext_init(void) -{ - static const char *tbl[] = { - "ach", "ach", - "ady", "ady", - "ara", "ar", - "bul", "bg", - "cze", "cs", - "dan", "da", - "ger", "de", - "eng", "en_US", - "eng_GB", "en_GB", - "eng_US", "en_US", - "spa", "es", - "est", "et", - "per", "fa", - "fin", "fi", - "fre", "fr", - "heb", "he", - "hrv", "hr", - "hun", "hu", - "ita", "it", - "kor", "ko", - "lav", "lv", - "lit", "lt", - "dut", "nl", - "nor", "no", - "pol", "pl", - "por", "pt", - "rum", "ro", - "rus", "ru", - "slv", "sl", - "slo", "sk", - "srp", "sr", - "alb", "sq", - "swe", "sv", - "tur", "tr", - "ukr", "uk", - "chi", "zh", - "chi_CN", "zh-Hans", - NULL, NULL - }; - const char **p; +void tvh_gettext_init(void) { + static const char* tbl[] = {"ach", + "ach", + "ady", + "ady", + "ara", + "ar", + "bul", + "bg", + "cze", + "cs", + "dan", + "da", + "ger", + "de", + "eng", + "en_US", + "eng_GB", + "en_GB", + "eng_US", + "en_US", + "spa", + "es", + "est", + "et", + "per", + "fa", + "fin", + "fi", + "fre", + "fr", + "heb", + "he", + "hrv", + "hr", + "hun", + "hu", + "ita", + "it", + "kor", + "ko", + "lav", + "lv", + "lit", + "lt", + "dut", + "nl", + "nor", + "no", + "pol", + "pl", + "por", + "pt", + "rum", + "ro", + "rus", + "ru", + "slv", + "sl", + "slo", + "sk", + "srp", + "sr", + "alb", + "sq", + "swe", + "sv", + "tur", + "tr", + "ukr", + "uk", + "chi", + "zh", + "chi_CN", + "zh-Hans", + NULL, + NULL}; + const char** p; for (p = tbl; *p; p += 2) lng_add(p[0], p[1]); tvh_gettext_default_init(); lng_last = lng_default; } -void tvh_gettext_done(void) -{ - struct lng *l; - struct msg *m; +void tvh_gettext_done(void) { + struct lng* l; + struct msg* m; while ((l = RB_FIRST(&lngs)) != NULL) { while ((m = RB_FIRST(&l->msgs)) != NULL) { diff --git a/src/tvh_locale.h b/src/tvh_locale.h index 05564a400..40e5195b2 100644 --- a/src/tvh_locale.h +++ b/src/tvh_locale.h @@ -20,15 +20,16 @@ #include -const char *tvh_gettext_get_lang(const char *lang); -const char *tvh_gettext_lang(const char *lang, const char *s); -static inline const char *tvh_gettext(const char *s) - { return tvh_gettext_lang(NULL, s); } +const char* tvh_gettext_get_lang(const char* lang); +const char* tvh_gettext_lang(const char* lang, const char* s); +static inline const char* tvh_gettext(const char* s) { + return tvh_gettext_lang(NULL, s); +} -#define _(s) tvh_gettext(s) +#define _(s) tvh_gettext(s) #define N_(s) (s) -int tvh_gettext_langcode_valid(const char *code); +int tvh_gettext_langcode_valid(const char* code); void tvh_gettext_init(void); void tvh_gettext_done(void); diff --git a/src/tvh_string.h b/src/tvh_string.h index 707a01007..372a952e9 100644 --- a/src/tvh_string.h +++ b/src/tvh_string.h @@ -24,63 +24,65 @@ #include "build.h" -static inline int strempty(const char *c) - { return c == NULL || *c == '\0'; } +static inline int strempty(const char* c) { + return c == NULL || *c == '\0'; +} -char *hts_strndup(const char *str, size_t len); +char* hts_strndup(const char* str, size_t len); -char *htsstr_unescape(char *str); +char* htsstr_unescape(char* str); -char *htsstr_unescape_to(const char *src, char *dst, size_t dstlen); +char* htsstr_unescape_to(const char* src, char* dst, size_t dstlen); -const char *htsstr_escape_find(const char *src, size_t upto_index); +const char* htsstr_escape_find(const char* src, size_t upto_index); -char **htsstr_argsplit(const char *str); +char** htsstr_argsplit(const char* str); -void htsstr_argsplit_free(char **argv); +void htsstr_argsplit_free(char** argv); typedef struct { - const char *id; - const char *(*getval)(const char *id, const char *fmt, const void *aux, char *tmp, size_t tmplen); + const char* id; + const char* (*getval)(const char* id, const char* fmt, const void* aux, char* tmp, size_t tmplen); } htsstr_substitute_t; -const char * -htsstr_substitute_find(const char *src, int first); +const char* htsstr_substitute_find(const char* src, int first); -char * -htsstr_substitute(const char *src, char *dst, size_t dstlen, - int first, htsstr_substitute_t *sub, const void *aux, - char *tmp, size_t tmplen); +char* htsstr_substitute(const char* src, + char* dst, + size_t dstlen, + int first, + htsstr_substitute_t* sub, + const void* aux, + char* tmp, + size_t tmplen); -static inline size_t tvh_strlen(const char *s) -{ +static inline size_t tvh_strlen(const char* s) { return (s) ? strlen(s) : 0; } -static inline const char *tvh_str_default(const char *s, const char *dflt) -{ +static inline const char* tvh_str_default(const char* s, const char* dflt) { return s && s[0] ? s : dflt; } -void tvh_str_set(char **strp, const char *src); -int tvh_str_update(char **strp, const char *src); +void tvh_str_set(char** strp, const char* src); +int tvh_str_update(char** strp, const char* src); -#define tvh_strdupa(n) \ - ({ int tvh_l = strlen(n); \ - char *tvh_b = alloca(tvh_l + 1); \ - memcpy(tvh_b, n, tvh_l + 1); }) +#define tvh_strdupa(n) \ + ({ \ + int tvh_l = strlen(n); \ + char* tvh_b = alloca(tvh_l + 1); \ + memcpy(tvh_b, n, tvh_l + 1); \ + }) -static inline const char *tvh_strbegins(const char *s1, const char *s2) -{ - while(*s2) - if(*s1++ != *s2++) +static inline const char* tvh_strbegins(const char* s1, const char* s2) { + while (*s2) + if (*s1++ != *s2++) return NULL; return s1; } #ifndef ENABLE_STRLCPY -static inline size_t strlcpy(char *dst, const char *src, size_t size) -{ +static inline size_t strlcpy(char* dst, const char* src, size_t size) { size_t ret = strlen(src); if (size) { size_t len = ret >= size ? size - 1 : ret; @@ -92,11 +94,10 @@ static inline size_t strlcpy(char *dst, const char *src, size_t size) #endif #ifndef ENABLE_STRLCAT -static inline size_t strlcat(char *dst, const char *src, size_t count) -{ +static inline size_t strlcat(char* dst, const char* src, size_t count) { size_t dlen = strlen(dst); - size_t len = strlen(src); - size_t res = dlen + len; + size_t len = strlen(src); + size_t res = dlen + len; dst += dlen; count -= dlen; @@ -108,27 +109,27 @@ static inline size_t strlcat(char *dst, const char *src, size_t count) } #endif -#define tvh_strlcatf(buf, size, ptr, fmt...) \ - do { int __r = snprintf((buf) + ptr, (size) - ptr, fmt); \ - ptr = __r >= (size) - ptr ? (size) - 1 : ptr + __r; } while (0) +#define tvh_strlcatf(buf, size, ptr, fmt...) \ + do { \ + int __r = snprintf((buf) + ptr, (size) - ptr, fmt); \ + ptr = __r >= (size) - ptr ? (size) - 1 : ptr + __r; \ + } while (0) -static inline void mystrset(char **p, const char *s) -{ +static inline void mystrset(char** p, const char* s) { free(*p); *p = s ? strdup(s) : NULL; } -static inline unsigned int tvh_strhash(const char *s, unsigned int mod) -{ +static inline unsigned int tvh_strhash(const char* s, unsigned int mod) { unsigned int v = 5381; - while(*s) + while (*s) v += (v << 5) + v + *s++; return v % mod; } -int put_utf8(char *out, int c); +int put_utf8(char* out, int c); -char *utf8_lowercase_inplace(char *s); -char *utf8_validate_inplace(char *s); +char* utf8_lowercase_inplace(char* s); +char* utf8_validate_inplace(char* s); #endif /* TVHEADEND_STRING_H */ diff --git a/src/tvh_thread.c b/src/tvh_thread.c index 6a019d7a0..a6d53dc16 100644 --- a/src/tvh_thread.c +++ b/src/tvh_thread.c @@ -22,36 +22,32 @@ #endif #if ENABLE_TRACE -int tvh_thread_debug; -static int tvhwatch_done; -static pthread_t thrwatch_tid; +int tvh_thread_debug; +static int tvhwatch_done; +static pthread_t thrwatch_tid; static pthread_mutex_t thrwatch_mutex = PTHREAD_MUTEX_INITIALIZER; static TAILQ_HEAD(, tvh_mutex) thrwatch_mutexes = TAILQ_HEAD_INITIALIZER(thrwatch_mutexes); static int64_t tvh_thread_crash_time; #endif #if ENABLE_TRACE -static void tvh_thread_mutex_failed(tvh_mutex_t *mutex, const char *reason, const char *filename, int lineno); +static void +tvh_thread_mutex_failed(tvh_mutex_t* mutex, const char* reason, const char* filename, int lineno); #endif /* * thread routines */ -static void doquit(int sig) -{ -} +static void doquit(int sig) {} -struct -thread_state { - void *(*run)(void*); - void *arg; - char name[17]; +struct thread_state { + void* (*run)(void*); + void* arg; + char name[17]; }; -static inline int -thread_get_tid(void) -{ +static inline int thread_get_tid(void) { #ifdef SYS_gettid return syscall(SYS_gettid); #elif ENABLE_ANDROID @@ -61,11 +57,9 @@ thread_get_tid(void) #endif } -static void * -thread_wrapper(void *p) -{ - struct thread_state *ts = p; - sigset_t set; +static void* thread_wrapper(void* p) { + struct thread_state* ts = p; + sigset_t set; #if defined(PLATFORM_LINUX) /* Set name */ @@ -86,48 +80,49 @@ thread_wrapper(void *p) tvh_signal(SIGQUIT, doquit); /* Run */ - tvhtrace(LS_THREAD, "created thread %ld [%s / %p(%p)]", - (long)pthread_self(), ts->name, ts->run, ts->arg); - void *r = ts->run(ts->arg); + tvhtrace(LS_THREAD, + "created thread %ld [%s / %p(%p)]", + (long)pthread_self(), + ts->name, + ts->run, + ts->arg); + void* r = ts->run(ts->arg); free(ts); return r; } -int -tvh_thread_create - (pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine) (void *), void *arg, const char *name) -{ - int r; - struct thread_state *ts = calloc(1, sizeof(struct thread_state)); - pthread_attr_t _attr; +int tvh_thread_create(pthread_t* thread, + const pthread_attr_t* attr, + void* (*start_routine)(void*), + void* arg, + const char* name) { + int r; + struct thread_state* ts = calloc(1, sizeof(struct thread_state)); + pthread_attr_t _attr; if (attr == NULL) { pthread_attr_init(&_attr); - pthread_attr_setstacksize(&_attr, 2*1024*1024); + pthread_attr_setstacksize(&_attr, 2 * 1024 * 1024); attr = &_attr; } strlcpy(ts->name, "tvh:", 5); - strlcpy(ts->name+4, name, sizeof(ts->name)-4); - ts->run = start_routine; - ts->arg = arg; - r = pthread_create(thread, attr, thread_wrapper, ts); + strlcpy(ts->name + 4, name, sizeof(ts->name) - 4); + ts->run = start_routine; + ts->arg = arg; + r = pthread_create(thread, attr, thread_wrapper, ts); return r; } -int tvh_thread_kill(pthread_t thread, int sig) -{ +int tvh_thread_kill(pthread_t thread, int sig) { return pthread_kill(thread, sig); } /* linux style: -19 .. 20 */ -int -tvh_thread_renice(int value) -{ +int tvh_thread_renice(int value) { int ret = 0; #if defined(SYS_gettid) || ENABLE_ANDROID pid_t tid = thread_get_tid(); - ret = setpriority(PRIO_PROCESS, tid, value); + ret = setpriority(PRIO_PROCESS, tid, value); #elif defined(PLATFORM_DARWIN) /* Currently not possible */ #elif defined(PLATFORM_FREEBSD) @@ -139,22 +134,16 @@ tvh_thread_renice(int value) } #if ENABLE_TRACE -static void tvh_mutex_check_magic(tvh_mutex_t *mutex, const char *filename, int lineno) -{ - if (mutex && - mutex->magic1 == TVH_THREAD_MUTEX_MAGIC1 && - mutex->magic2 == TVH_THREAD_MUTEX_MAGIC2) +static void tvh_mutex_check_magic(tvh_mutex_t* mutex, const char* filename, int lineno) { + if (mutex && mutex->magic1 == TVH_THREAD_MUTEX_MAGIC1 && mutex->magic2 == TVH_THREAD_MUTEX_MAGIC2) return; tvh_thread_mutex_failed(mutex, "magic", filename, lineno); } #else -static inline void tvh_mutex_check_magic(tvh_mutex_t *mutex, const char *filename, int lineno) -{ -} +static inline void tvh_mutex_check_magic(tvh_mutex_t* mutex, const char* filename, int lineno) {} #endif -int tvh_mutex_init(tvh_mutex_t *mutex, const pthread_mutexattr_t *attr) -{ +int tvh_mutex_init(tvh_mutex_t* mutex, const pthread_mutexattr_t* attr) { memset(mutex, 0, sizeof(*mutex)); #if ENABLE_TRACE mutex->magic1 = TVH_THREAD_MUTEX_MAGIC1; @@ -163,20 +152,18 @@ int tvh_mutex_init(tvh_mutex_t *mutex, const pthread_mutexattr_t *attr) return pthread_mutex_init(&mutex->mutex, attr); } -int tvh_mutex_destroy(tvh_mutex_t *mutex) -{ +int tvh_mutex_destroy(tvh_mutex_t* mutex) { tvh_mutex_check_magic(mutex, NULL, 0); return pthread_mutex_destroy(&mutex->mutex); } #if ENABLE_TRACE -static void tvh_mutex_add_to_list(tvh_mutex_t *mutex, const char *filename, int lineno) -{ +static void tvh_mutex_add_to_list(tvh_mutex_t* mutex, const char* filename, int lineno) { pthread_mutex_lock(&thrwatch_mutex); if (filename != NULL) { - mutex->tid = thread_get_tid(); + mutex->tid = thread_get_tid(); mutex->filename = filename; - mutex->lineno = lineno; + mutex->lineno = lineno; } mutex->tstamp = getfastmonoclock(); TAILQ_SAFE_REMOVE(&thrwatch_mutexes, mutex, link); @@ -186,22 +173,23 @@ static void tvh_mutex_add_to_list(tvh_mutex_t *mutex, const char *filename, int #endif #if ENABLE_TRACE -static void tvh_mutex_check_interval(tvh_mutex_t *mutex) -{ +static void tvh_mutex_check_interval(tvh_mutex_t* mutex) { if (tvh_thread_debug > 10000) { - int64_t ms = ((int64_t)tvh_thread_debug - 10000) * 1000; + int64_t ms = ((int64_t)tvh_thread_debug - 10000) * 1000; int64_t diff = getfastmonoclock() - mutex->tstamp; if (diff > ms) - tvhdbg(LS_THREAD, "mutex %p at %s:%d took %lldms", - mutex, mutex->filename, mutex->lineno, - diff / (MONOCLOCK_RESOLUTION / 1000)); + tvhdbg(LS_THREAD, + "mutex %p at %s:%d took %lldms", + mutex, + mutex->filename, + mutex->lineno, + diff / (MONOCLOCK_RESOLUTION / 1000)); } } #endif #if ENABLE_TRACE -static void tvh_mutex_remove_from_list(tvh_mutex_t *mutex, const char **filename, int *lineno) -{ +static void tvh_mutex_remove_from_list(tvh_mutex_t* mutex, const char** filename, int* lineno) { pthread_mutex_lock(&thrwatch_mutex); if (filename) *filename = mutex->filename; @@ -210,22 +198,21 @@ static void tvh_mutex_remove_from_list(tvh_mutex_t *mutex, const char **filename TAILQ_SAFE_REMOVE(&thrwatch_mutexes, mutex, link); tvh_mutex_check_interval(mutex); mutex->filename = NULL; - mutex->lineno = 0; + mutex->lineno = 0; pthread_mutex_unlock(&thrwatch_mutex); } #endif #if ENABLE_TRACE -static tvh_mutex_waiter_t * -tvh_mutex_add_to_waiters(tvh_mutex_t *mutex, const char *filename, int lineno) -{ - tvh_mutex_waiter_t *w = malloc(sizeof(*w)); +static tvh_mutex_waiter_t* +tvh_mutex_add_to_waiters(tvh_mutex_t* mutex, const char* filename, int lineno) { + tvh_mutex_waiter_t* w = malloc(sizeof(*w)); pthread_mutex_lock(&thrwatch_mutex); if (filename != NULL) { - w->tid = thread_get_tid(); + w->tid = thread_get_tid(); w->filename = filename; - w->lineno = lineno; + w->lineno = lineno; } w->tstamp = getfastmonoclock(); LIST_INSERT_HEAD(&mutex->waiters, w, link); @@ -235,9 +222,7 @@ tvh_mutex_add_to_waiters(tvh_mutex_t *mutex, const char *filename, int lineno) #endif #if ENABLE_TRACE -static void -tvh_mutex_remove_from_waiters(tvh_mutex_waiter_t *w) -{ +static void tvh_mutex_remove_from_waiters(tvh_mutex_waiter_t* w) { pthread_mutex_lock(&thrwatch_mutex); LIST_REMOVE(w, link); free(w); @@ -246,11 +231,10 @@ tvh_mutex_remove_from_waiters(tvh_mutex_waiter_t *w) #endif #if ENABLE_TRACE -int tvh__mutex_lock(tvh_mutex_t *mutex, const char *filename, int lineno) -{ - tvh_mutex_waiter_t *w; +int tvh__mutex_lock(tvh_mutex_t* mutex, const char* filename, int lineno) { + tvh_mutex_waiter_t* w; tvh_mutex_check_magic(mutex, filename, lineno); - w = tvh_mutex_add_to_waiters(mutex, filename, lineno); + w = tvh_mutex_add_to_waiters(mutex, filename, lineno); int r = pthread_mutex_lock(&mutex->mutex); tvh_mutex_remove_from_waiters(w); if (r == 0) @@ -260,8 +244,7 @@ int tvh__mutex_lock(tvh_mutex_t *mutex, const char *filename, int lineno) #endif #if ENABLE_TRACE -int tvh__mutex_trylock(tvh_mutex_t *mutex, const char *filename, int lineno) -{ +int tvh__mutex_trylock(tvh_mutex_t* mutex, const char* filename, int lineno) { tvh_mutex_check_magic(mutex, filename, lineno); int r = pthread_mutex_trylock(&mutex->mutex); if (r == 0) @@ -271,8 +254,7 @@ int tvh__mutex_trylock(tvh_mutex_t *mutex, const char *filename, int lineno) #endif #if ENABLE_TRACE -int tvh__mutex_unlock(tvh_mutex_t *mutex) -{ +int tvh__mutex_unlock(tvh_mutex_t* mutex) { tvh_mutex_check_magic(mutex, NULL, 0); int r = pthread_mutex_unlock(&mutex->mutex); if (r == 0) @@ -281,15 +263,12 @@ int tvh__mutex_unlock(tvh_mutex_t *mutex) } #endif -int -tvh_mutex_timedlock - ( tvh_mutex_t *mutex, int64_t usec ) -{ +int tvh_mutex_timedlock(tvh_mutex_t* mutex, int64_t usec) { int64_t finish = getfastmonoclock() + usec; - int retcode; + int retcode; tvh_mutex_check_magic(mutex, NULL, 0); - while ((retcode = pthread_mutex_trylock (&mutex->mutex)) == EBUSY) { + while ((retcode = pthread_mutex_trylock(&mutex->mutex)) == EBUSY) { if (getfastmonoclock() >= finish) return ETIMEDOUT; @@ -303,10 +282,7 @@ tvh_mutex_timedlock * thread condition variables - monotonic clocks */ -int -tvh_cond_init - ( tvh_cond_t *cond, int monotonic ) -{ +int tvh_cond_init(tvh_cond_t* cond, int monotonic) { int r; pthread_condattr_t attr; @@ -330,32 +306,23 @@ tvh_cond_init return pthread_cond_init(&cond->cond, &attr); } -int -tvh_cond_destroy - ( tvh_cond_t *cond ) -{ +int tvh_cond_destroy(tvh_cond_t* cond) { return pthread_cond_destroy(&cond->cond); } -int -tvh_cond_signal - ( tvh_cond_t *cond, int broadcast ) -{ +int tvh_cond_signal(tvh_cond_t* cond, int broadcast) { if (broadcast) return pthread_cond_broadcast(&cond->cond); else return pthread_cond_signal(&cond->cond); } -int -tvh_cond_wait - ( tvh_cond_t *cond, tvh_mutex_t *mutex) -{ +int tvh_cond_wait(tvh_cond_t* cond, tvh_mutex_t* mutex) { int r; - + #if ENABLE_TRACE - const char *filename = NULL; - int lineno = -1; + const char* filename = NULL; + int lineno = -1; tvh_mutex_check_magic(mutex, NULL, 0); if (tvh_thread_debug > 0) tvh_mutex_remove_from_list(mutex, &filename, &lineno); @@ -368,40 +335,35 @@ tvh_cond_wait return r; } -int -tvh_cond_timedwait - ( tvh_cond_t *cond, tvh_mutex_t *mutex, int64_t monoclock ) -{ +int tvh_cond_timedwait(tvh_cond_t* cond, tvh_mutex_t* mutex, int64_t monoclock) { int r; #if ENABLE_TRACE - const char *filename = NULL; - int lineno = -1; + const char* filename = NULL; + int lineno = -1; tvh_mutex_check_magic(mutex, NULL, 0); if (tvh_thread_debug > 0) tvh_mutex_remove_from_list(mutex, &filename, &lineno); #endif - + #if defined(PLATFORM_DARWIN) /* Use a relative timedwait implementation */ - int64_t now = getmonoclock(); - int64_t relative = monoclock - now; + int64_t now = getmonoclock(); + int64_t relative = monoclock - now; struct timespec ts; if (relative < 0) return 0; ts.tv_sec = relative / MONOCLOCK_RESOLUTION; - ts.tv_nsec = (relative % MONOCLOCK_RESOLUTION) * - (1000000000ULL/MONOCLOCK_RESOLUTION); + ts.tv_nsec = (relative % MONOCLOCK_RESOLUTION) * (1000000000ULL / MONOCLOCK_RESOLUTION); r = pthread_cond_timedwait_relative_np(&cond->cond, &mutex->mutex, &ts); #else struct timespec ts; - ts.tv_sec = monoclock / MONOCLOCK_RESOLUTION; - ts.tv_nsec = (monoclock % MONOCLOCK_RESOLUTION) * - (1000000000ULL/MONOCLOCK_RESOLUTION); - r = pthread_cond_timedwait(&cond->cond, &mutex->mutex, &ts); + ts.tv_sec = monoclock / MONOCLOCK_RESOLUTION; + ts.tv_nsec = (monoclock % MONOCLOCK_RESOLUTION) * (1000000000ULL / MONOCLOCK_RESOLUTION); + r = pthread_cond_timedwait(&cond->cond, &mutex->mutex, &ts); #endif #if ENABLE_TRACE @@ -411,13 +373,12 @@ tvh_cond_timedwait return r; } -int tvh_cond_timedwait_ts(tvh_cond_t *cond, tvh_mutex_t *mutex, struct timespec *ts) -{ +int tvh_cond_timedwait_ts(tvh_cond_t* cond, tvh_mutex_t* mutex, struct timespec* ts) { int r; - + #if ENABLE_TRACE - const char *filename = NULL; - int lineno = -1; + const char* filename = NULL; + int lineno = -1; tvh_mutex_check_magic(mutex, NULL, 0); if (tvh_thread_debug > 0) tvh_mutex_remove_from_list(mutex, &filename, &lineno); @@ -430,30 +391,28 @@ int tvh_cond_timedwait_ts(tvh_cond_t *cond, tvh_mutex_t *mutex, struct timespec return r; } -int tvh_signal(int signal, void (*handler) (int)) -{ +int tvh_signal(int signal, void (*handler)(int)) { struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = handler; return sigaction(signal, &action, NULL); } -void -tvh_mutex_not_held(const char *file, int line) -{ +void tvh_mutex_not_held(const char* file, int line) { tvherror(LS_THREAD, "Mutex not held at %s:%d", file, line); fprintf(stderr, "Mutex not held at %s:%d\n", file, line); abort(); } #if ENABLE_TRACE -static void tvh_thread_deadlock_write(htsbuf_queue_t *q) -{ - size_t l; - char *s, *s2, *saveptr; +static void tvh_thread_deadlock_write(htsbuf_queue_t* q) { + size_t l; + char * s, *s2, *saveptr; const int fd_stderr = fileno(stderr); - int fd = hts_settings_open_file(HTS_SETTINGS_OPEN_WRITE | HTS_SETTINGS_OPEN_DIRECT, "mutex-deadlock.txt"); - if (fd < 0) fd = fd_stderr; + int fd = hts_settings_open_file(HTS_SETTINGS_OPEN_WRITE | HTS_SETTINGS_OPEN_DIRECT, + "mutex-deadlock.txt"); + if (fd < 0) + fd = fd_stderr; s = htsbuf_to_string(q); l = s ? strlen(s) : 0; @@ -464,38 +423,58 @@ static void tvh_thread_deadlock_write(htsbuf_queue_t *q) } saveptr = NULL; - for (; ; s = NULL) { + for (;; s = NULL) { s2 = strtok_r(s, "\n", &saveptr); if (s2 == NULL) break; tvhdbg(LS_THREAD, "%s", s2); } - if (fd != fd_stderr) close(fd); + if (fd != fd_stderr) + close(fd); free(s); } #endif #if ENABLE_TRACE static void -tvh_thread_mutex_failed - (tvh_mutex_t *mutex, const char *reason, const char *filename, int lineno) -{ - htsbuf_queue_t q; - tvh_mutex_t *m; - tvh_mutex_waiter_t *w; +tvh_thread_mutex_failed(tvh_mutex_t* mutex, const char* reason, const char* filename, int lineno) { + htsbuf_queue_t q; + tvh_mutex_t* m; + tvh_mutex_waiter_t* w; htsbuf_queue_init(&q, 0); htsbuf_qprintf(&q, "REASON: %s (%s:%d)\n", reason, filename, lineno); if (mutex) { - htsbuf_qprintf(&q, "mutex %p locked in: %s:%i (thread %ld)\n", mutex, mutex->filename, mutex->lineno, mutex->tid); - LIST_FOREACH(w, &mutex->waiters, link) - htsbuf_qprintf(&q, "mutex %p waiting in: %s:%i (thread %ld)\n", mutex, w->filename, w->lineno, w->tid); + htsbuf_qprintf(&q, + "mutex %p locked in: %s:%i (thread %ld)\n", + mutex, + mutex->filename, + mutex->lineno, + mutex->tid); + LIST_FOREACH (w, &mutex->waiters, link) + htsbuf_qprintf(&q, + "mutex %p waiting in: %s:%i (thread %ld)\n", + mutex, + w->filename, + w->lineno, + w->tid); } - TAILQ_FOREACH(m, &thrwatch_mutexes, link) { - if (m == mutex) continue; - htsbuf_qprintf(&q, "mutex %p other in: %s:%i (thread %ld)\n", m, m->filename, m->lineno, m->tid); - LIST_FOREACH(w, &m->waiters, link) - htsbuf_qprintf(&q, "mutex %p waiting in: %s:%i (thread %ld)\n", m, w->filename, w->lineno, w->tid); + TAILQ_FOREACH (m, &thrwatch_mutexes, link) { + if (m == mutex) + continue; + htsbuf_qprintf(&q, + "mutex %p other in: %s:%i (thread %ld)\n", + m, + m->filename, + m->lineno, + m->tid); + LIST_FOREACH (w, &m->waiters, link) + htsbuf_qprintf(&q, + "mutex %p waiting in: %s:%i (thread %ld)\n", + m, + w->filename, + w->lineno, + w->tid); } tvh_thread_deadlock_write(&q); tvh_safe_usleep(2000000); @@ -504,18 +483,17 @@ tvh_thread_mutex_failed #endif #if ENABLE_TRACE -static void *tvh_thread_watch_thread(void *aux) -{ - int64_t now, limit; +static void* tvh_thread_watch_thread(void* aux) { + int64_t now, limit; tvh_mutex_t *mutex, dmutex; - const char *s; + const char* s; - s = getenv("TVHEADEND_THREAD_WATCH_LIMIT"); + s = getenv("TVHEADEND_THREAD_WATCH_LIMIT"); limit = s ? atol(s) : 15; limit = MINMAX(limit, 5, 120); while (!atomic_get(&tvhwatch_done)) { pthread_mutex_lock(&thrwatch_mutex); - now = getfastmonoclock(); + now = getfastmonoclock(); mutex = TAILQ_LAST(&thrwatch_mutexes, tvh_mutex_queue); if (mutex && mutex->tstamp + sec2mono(limit) < now) { pthread_mutex_unlock(&thrwatch_mutex); @@ -533,10 +511,9 @@ static void *tvh_thread_watch_thread(void *aux) } #endif -void tvh_thread_init(int debug_level) -{ +void tvh_thread_init(int debug_level) { #if ENABLE_TRACE - tvh_thread_debug = debug_level; + tvh_thread_debug = debug_level; tvh_thread_crash_time = getfastmonoclock() + sec2mono(15); if (debug_level > 0) { atomic_set(&tvhwatch_done, 0); @@ -545,8 +522,7 @@ void tvh_thread_init(int debug_level) #endif } -void tvh_thread_done(void) -{ +void tvh_thread_done(void) { #if ENABLE_TRACE if (tvh_thread_debug > 0) { atomic_set(&tvhwatch_done, 1); diff --git a/src/tvh_thread.h b/src/tvh_thread.h index 3305ba299..73ca4b061 100644 --- a/src/tvh_thread.h +++ b/src/tvh_thread.h @@ -37,21 +37,21 @@ TAILQ_HEAD(tvh_mutex_queue, tvh_mutex); #if ENABLE_TRACE typedef struct tvh_mutex_waiter { LIST_ENTRY(tvh_mutex_waiter) link; - long tid; - const char *filename; - int lineno; - int64_t tstamp; + long tid; + const char* filename; + int lineno; + int64_t tstamp; } tvh_mutex_waiter_t; #endif typedef struct tvh_mutex { pthread_mutex_t mutex; #if ENABLE_TRACE - uint32_t magic1; - long tid; - const char *filename; - int lineno; - int64_t tstamp; + uint32_t magic1; + long tid; + const char* filename; + int lineno; + int64_t tstamp; LIST_HEAD(, tvh_mutex_waiter) waiters; TAILQ_ENTRY(tvh_mutex) link; uint32_t magic2; @@ -62,15 +62,13 @@ typedef struct tvh_mutex { * */ -void tvh_mutex_not_held(const char *file, int line); +void tvh_mutex_not_held(const char* file, int line); -static inline void -lock_assert0(tvh_mutex_t *l, const char *file, int line) -{ +static inline void lock_assert0(tvh_mutex_t* l, const char* file, int line) { #if 0 && ENABLE_LOCKOWNER assert(l->mutex.__data.__owner == syscall(SYS_gettid)); #else - if(pthread_mutex_trylock(&l->mutex) == EBUSY) + if (pthread_mutex_trylock(&l->mutex) == EBUSY) return; tvh_mutex_not_held(file, line); #endif @@ -79,15 +77,14 @@ lock_assert0(tvh_mutex_t *l, const char *file, int line) #define lock_assert(l) lock_assert0(l, __FILE__, __LINE__) #if ENABLE_TRACE -#define TVH_THREAD_MUTEX_INITIALIZER { \ - .magic1 = TVH_THREAD_MUTEX_MAGIC1, \ - .magic2 = TVH_THREAD_MUTEX_MAGIC2, \ - .mutex = PTHREAD_MUTEX_INITIALIZER, \ -} +#define TVH_THREAD_MUTEX_INITIALIZER \ + { \ + .magic1 = TVH_THREAD_MUTEX_MAGIC1, .magic2 = TVH_THREAD_MUTEX_MAGIC2, \ + .mutex = PTHREAD_MUTEX_INITIALIZER, \ + } #else -#define TVH_THREAD_MUTEX_INITIALIZER { \ - .mutex = PTHREAD_MUTEX_INITIALIZER, \ -} +#define TVH_THREAD_MUTEX_INITIALIZER \ + { .mutex = PTHREAD_MUTEX_INITIALIZER, } #endif /* @@ -101,62 +98,57 @@ extern int tvh_thread_debug; void tvh_thread_init(int debug_level); void tvh_thread_done(void); -int tvh_thread_create - (pthread_t *thread, const pthread_attr_t *attr, - void *(*start_routine) (void *), void *arg, - const char *name); +int tvh_thread_create(pthread_t* thread, + const pthread_attr_t* attr, + void* (*start_routine)(void*), + void* arg, + const char* name); int tvh_thread_kill(pthread_t thread, int sig); int tvh_thread_renice(int value); -int tvh_mutex_init(tvh_mutex_t *mutex, const pthread_mutexattr_t *attr); -int tvh_mutex_destroy(tvh_mutex_t *mutex); +int tvh_mutex_init(tvh_mutex_t* mutex, const pthread_mutexattr_t* attr); +int tvh_mutex_destroy(tvh_mutex_t* mutex); #if ENABLE_TRACE -int tvh__mutex_lock(tvh_mutex_t *mutex, const char *filename, int lineno); -#define tvh_mutex_lock(_mutex) \ - ({ \ - tvh_thread_debug == 0 ? \ - pthread_mutex_lock(&(_mutex)->mutex) : \ - tvh__mutex_lock((_mutex), __FILE__, __LINE__); \ - }) -int tvh__mutex_trylock(tvh_mutex_t *mutex, const char *filename, int lineno); -#define tvh_mutex_trylock(_mutex) \ - ({ \ - tvh_thread_debug == 0 ? \ - pthread_mutex_trylock(&(_mutex)->mutex) : \ - tvh__mutex_trylock((_mutex), __FILE__, __LINE__); \ - }) -int tvh__mutex_unlock(tvh_mutex_t *mutex); -static inline int tvh_mutex_unlock(tvh_mutex_t *mutex) -{ +int tvh__mutex_lock(tvh_mutex_t* mutex, const char* filename, int lineno); +#define tvh_mutex_lock(_mutex) \ + ({ \ + tvh_thread_debug == 0 ? pthread_mutex_lock(&(_mutex)->mutex) \ + : tvh__mutex_lock((_mutex), __FILE__, __LINE__); \ + }) +int tvh__mutex_trylock(tvh_mutex_t* mutex, const char* filename, int lineno); +#define tvh_mutex_trylock(_mutex) \ + ({ \ + tvh_thread_debug == 0 ? pthread_mutex_trylock(&(_mutex)->mutex) \ + : tvh__mutex_trylock((_mutex), __FILE__, __LINE__); \ + }) +int tvh__mutex_unlock(tvh_mutex_t* mutex); +static inline int tvh_mutex_unlock(tvh_mutex_t* mutex) { if (tvh_thread_debug == 0) return pthread_mutex_unlock(&mutex->mutex); return tvh__mutex_unlock(mutex); } #else -static inline int tvh_mutex_lock(tvh_mutex_t *mutex) -{ +static inline int tvh_mutex_lock(tvh_mutex_t* mutex) { return pthread_mutex_lock(&mutex->mutex); } -static inline int tvh_mutex_trylock(tvh_mutex_t *mutex) -{ +static inline int tvh_mutex_trylock(tvh_mutex_t* mutex) { return pthread_mutex_trylock(&mutex->mutex); } -static inline int tvh_mutex_unlock(tvh_mutex_t *mutex) -{ +static inline int tvh_mutex_unlock(tvh_mutex_t* mutex) { return pthread_mutex_unlock(&mutex->mutex); } #endif -int tvh_mutex_timedlock(tvh_mutex_t *mutex, int64_t usec); +int tvh_mutex_timedlock(tvh_mutex_t* mutex, int64_t usec); -int tvh_cond_init(tvh_cond_t *cond, int monotonic); -int tvh_cond_destroy(tvh_cond_t *cond); -int tvh_cond_signal(tvh_cond_t *cond, int broadcast); -int tvh_cond_wait(tvh_cond_t *cond, tvh_mutex_t *mutex); -int tvh_cond_timedwait(tvh_cond_t *cond, tvh_mutex_t *mutex, int64_t clock); -int tvh_cond_timedwait_ts(tvh_cond_t *cond, tvh_mutex_t *mutex, struct timespec *ts); +int tvh_cond_init(tvh_cond_t* cond, int monotonic); +int tvh_cond_destroy(tvh_cond_t* cond); +int tvh_cond_signal(tvh_cond_t* cond, int broadcast); +int tvh_cond_wait(tvh_cond_t* cond, tvh_mutex_t* mutex); +int tvh_cond_timedwait(tvh_cond_t* cond, tvh_mutex_t* mutex, int64_t clock); +int tvh_cond_timedwait_ts(tvh_cond_t* cond, tvh_mutex_t* mutex, struct timespec* ts); -int tvh_signal(int signal, void (*handler) (int)); +int tvh_signal(int signal, void (*handler)(int)); #ifndef TVH_THREAD_C #define pthread_cond __do_not_use_pthread_cond diff --git a/src/tvheadend.h b/src/tvheadend.h index 23f58cbd9..998b1b42e 100644 --- a/src/tvheadend.h +++ b/src/tvheadend.h @@ -49,28 +49,26 @@ #include "compat.h" typedef struct { - const char *name; - const uint32_t *enabled; + const char* name; + const uint32_t* enabled; } tvh_caps_t; extern int tvheadend_running; -extern const char *tvheadend_version; -extern const char *tvheadend_cwd; -extern const char *tvheadend_webroot; +extern const char* tvheadend_version; +extern const char* tvheadend_cwd; +extern const char* tvheadend_webroot; extern const tvh_caps_t tvheadend_capabilities[]; -static inline int tvheadend_is_running(void) -{ +static inline int tvheadend_is_running(void) { return atomic_get(&tvheadend_running); } -htsmsg_t *tvheadend_capabilities_list(int check); +htsmsg_t* tvheadend_capabilities_list(int check); -typedef struct str_list -{ - int max; - int num; - char **str; +typedef struct str_list { + int max; + int num; + char** str; } str_list_t; #define PTS_UNSET INT64_C(0x8000000000000000) @@ -108,8 +106,8 @@ extern int tvheadend_htsp_port; /* * */ -#define PICON_STANDARD 0 -#define PICON_ISVCTYPE 1 +#define PICON_STANDARD 0 +#define PICON_ISVCTYPE 1 /* * timer support functions @@ -117,7 +115,7 @@ extern int tvheadend_htsp_port; #if ENABLE_GTIMER_CHECK #define GTIMER_TRACEID_ const char *id, -#define GTIMER_FCN(n) check_##n +#define GTIMER_FCN(n) check_##n #else #define GTIMER_TRACEID_ #define GTIMER_FCN(n) n @@ -127,7 +125,7 @@ extern int tvheadend_htsp_port; * global timer - monotonic */ -typedef void (mti_callback_t)(void *opaque); +typedef void(mti_callback_t)(void* opaque); #define MTIMER_MAGIC1 0x0d62a9de @@ -136,27 +134,29 @@ typedef struct mtimer { #if ENABLE_TRACE uint32_t mti_magic1; #endif - mti_callback_t *mti_callback; - void *mti_opaque; - int64_t mti_expire; + mti_callback_t* mti_callback; + void* mti_opaque; + int64_t mti_expire; #if ENABLE_GTIMER_CHECK - const char *mti_id; + const char* mti_id; #endif } mtimer_t; -void GTIMER_FCN(mtimer_arm_rel) - (GTIMER_TRACEID_ mtimer_t *mti, mti_callback_t *callback, void *opaque, int64_t delta); -void GTIMER_FCN(mtimer_arm_abs) - (GTIMER_TRACEID_ mtimer_t *mti, mti_callback_t *callback, void *opaque, int64_t when); +void GTIMER_FCN(mtimer_arm_rel)(GTIMER_TRACEID_ mtimer_t* mti, + mti_callback_t* callback, + void* opaque, + int64_t delta); +void GTIMER_FCN(mtimer_arm_abs)(GTIMER_TRACEID_ mtimer_t* mti, + mti_callback_t* callback, + void* opaque, + int64_t when); #if ENABLE_GTIMER_CHECK #define mtimer_arm_rel(a, b, c, d) GTIMER_FCN(mtimer_arm_rel)(SRCLINEID(), a, b, c, d) #define mtimer_arm_abs(a, b, c, d) GTIMER_FCN(mtimer_arm_abs)(SRCLINEID(), a, b, c, d) #endif -void mtimer_disarm(mtimer_t *mti); - - +void mtimer_disarm(mtimer_t* mti); /* * global timer (based on the current system time - time()) @@ -164,197 +164,223 @@ void mtimer_disarm(mtimer_t *mti); #define GTIMER_MAGIC1 0x8a6f238f -typedef void (gti_callback_t)(void *opaque); +typedef void(gti_callback_t)(void* opaque); typedef struct gtimer { LIST_ENTRY(gtimer) gti_link; #if ENABLE_TRACE uint32_t gti_magic1; #endif - gti_callback_t *gti_callback; - void *gti_opaque; - time_t gti_expire; + gti_callback_t* gti_callback; + void* gti_opaque; + time_t gti_expire; #if ENABLE_GTIMER_CHECK - const char *gti_id; + const char* gti_id; #endif } gtimer_t; -void GTIMER_FCN(gtimer_arm_rel) - (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t delta); -void GTIMER_FCN(gtimer_arm_absn) - (GTIMER_TRACEID_ gtimer_t *gti, gti_callback_t *callback, void *opaque, time_t when); +void GTIMER_FCN(gtimer_arm_rel)(GTIMER_TRACEID_ gtimer_t* gti, + gti_callback_t* callback, + void* opaque, + time_t delta); +void GTIMER_FCN(gtimer_arm_absn)(GTIMER_TRACEID_ gtimer_t* gti, + gti_callback_t* callback, + void* opaque, + time_t when); #if ENABLE_GTIMER_CHECK -#define gtimer_arm_rel(a, b, c, d) GTIMER_FCN(gtimer_arm_rel)(SRCLINEID(), a, b, c, d) +#define gtimer_arm_rel(a, b, c, d) GTIMER_FCN(gtimer_arm_rel)(SRCLINEID(), a, b, c, d) #define gtimer_arm_absn(a, b, c, d) GTIMER_FCN(gtimer_arm_absn)(SRCLINEID(), a, b, c, d) #endif -void gtimer_disarm(gtimer_t *gti); - +void gtimer_disarm(gtimer_t* gti); /* * tasklet */ -typedef void (tsk_callback_t)(void *opaque, int disarmed); +typedef void(tsk_callback_t)(void* opaque, int disarmed); typedef struct tasklet { TAILQ_ENTRY(tasklet) tsk_link; - tsk_callback_t *tsk_callback; - void *tsk_opaque; - void (*tsk_free)(void *); + tsk_callback_t* tsk_callback; + void* tsk_opaque; + void (*tsk_free)(void*); } tasklet_t; -tasklet_t *tasklet_arm_alloc(tsk_callback_t *callback, void *opaque); -void tasklet_arm(tasklet_t *tsk, tsk_callback_t *callback, void *opaque); -void tasklet_disarm(tasklet_t *gti); +tasklet_t* tasklet_arm_alloc(tsk_callback_t* callback, void* opaque); +void tasklet_arm(tasklet_t* tsk, tsk_callback_t* callback, void* opaque); +void tasklet_disarm(tasklet_t* gti); /** * */ -#define TVH_KILL_KILL 0 -#define TVH_KILL_TERM 1 -#define TVH_KILL_INT 2 -#define TVH_KILL_HUP 3 -#define TVH_KILL_USR1 4 -#define TVH_KILL_USR2 5 +#define TVH_KILL_KILL 0 +#define TVH_KILL_TERM 1 +#define TVH_KILL_INT 2 +#define TVH_KILL_HUP 3 +#define TVH_KILL_USR1 4 +#define TVH_KILL_USR2 5 int tvh_kill_to_sig(int tvh_kill); -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) -#define MINMAX(a,mi,ma) MAX(mi, MIN(ma, a)) -#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define MINMAX(a, mi, ma) MAX(mi, MIN(ma, a)) +#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0])) int sri_to_rate(int sri); int rate_to_sri(int rate); -typedef struct th_pipe -{ +typedef struct th_pipe { int rd; int wr; } th_pipe_t; void doexit(int x); -int tvh_open(const char *pathname, int flags, mode_t mode); +int tvh_open(const char* pathname, int flags, mode_t mode); int tvh_socket(int domain, int type, int protocol); -int tvh_pipe(int flags, th_pipe_t *pipe); +int tvh_pipe(int flags, th_pipe_t* pipe); -void tvh_pipe_close(th_pipe_t *pipe); +void tvh_pipe_close(th_pipe_t* pipe); -int tvh_write(int fd, const void *buf, size_t len); +int tvh_write(int fd, const void* buf, size_t len); -int tvh_write_in_chunks(int fd, const void *buf, size_t len, size_t chunkSize); +int tvh_write_in_chunks(int fd, const void* buf, size_t len, size_t chunkSize); -int tvh_nonblock_write(int fd, const void *buf, size_t len); +int tvh_nonblock_write(int fd, const void* buf, size_t len); -FILE *tvh_fopen(const char *filename, const char *mode); +FILE* tvh_fopen(const char* filename, const char* mode); -void hexdump(const char *pfx, const uint8_t *data, int len); +void hexdump(const char* pfx, const uint8_t* data, int len); -uint32_t tvh_crc32(const uint8_t *data, size_t datalen, uint32_t crc); +uint32_t tvh_crc32(const uint8_t* data, size_t datalen, uint32_t crc); -int base64_decode(uint8_t *out, const char *in, int out_size); +int base64_decode(uint8_t* out, const char* in, int out_size); -char *base64_encode(char *out, int out_size, const uint8_t *in, int in_size); +char* base64_encode(char* out, int out_size, const uint8_t* in, int in_size); /* Calculate the output size needed to base64-encode x bytes. */ -#define BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1) +#define BASE64_SIZE(x) (((x) + 2) / 3 * 4 + 1) -static inline int64_t ts_rescale(int64_t ts, int tb) -{ +static inline int64_t ts_rescale(int64_t ts, int tb) { // return (ts * tb + (tb / 2)) / 90000LL; - return (ts * tb ) / 90000LL; + return (ts * tb) / 90000LL; } -static inline int64_t ts_rescale_inv(int64_t ts, int tb) -{ +static inline int64_t ts_rescale_inv(int64_t ts, int tb) { return (ts * 90000LL) / tb; } -char *md5sum ( const char *str, int lowercase ); -char *sha256sum ( const char *str, int lowercase ); -char *sha512sum256 ( const char *str, int lowercase ); -char *sha256sum_base64 ( const char *str ); +char* md5sum(const char* str, int lowercase); +char* sha256sum(const char* str, int lowercase); +char* sha512sum256(const char* str, int lowercase); +char* sha256sum_base64(const char* str); -int makedirs ( int subsys, const char *path, int mode, int mstrict, gid_t gid, uid_t uid ); +int makedirs(int subsys, const char* path, int mode, int mstrict, gid_t gid, uid_t uid); -int rmtree ( const char *path ); +int rmtree(const char* path); -char *regexp_escape ( const char *str ); +char* regexp_escape(const char* str); #if ENABLE_ZLIB -uint8_t *tvh_gzip_inflate ( const uint8_t *data, size_t size, size_t orig ); -uint8_t *tvh_gzip_deflate ( const uint8_t *data, size_t orig, size_t *size ); -int tvh_gzip_deflate_fd ( int fd, const uint8_t *data, size_t orig, size_t *size, int speed ); -int tvh_gzip_deflate_fd_header ( int fd, const uint8_t *data, size_t orig, size_t *size, int speed , const char *signature); +uint8_t* tvh_gzip_inflate(const uint8_t* data, size_t size, size_t orig); +uint8_t* tvh_gzip_deflate(const uint8_t* data, size_t orig, size_t* size); +int tvh_gzip_deflate_fd(int fd, const uint8_t* data, size_t orig, size_t* size, int speed); +int tvh_gzip_deflate_fd_header(int fd, + const uint8_t* data, + size_t orig, + size_t* size, + int speed, + const char* signature); #endif /* URL decoding */ -char to_hex(char code); -char *url_encode(const char *str); -void http_deescape(char *str); - -int mpegts_word_count(const uint8_t *tsb, int len, uint32_t mask); +char to_hex(char code); +char* url_encode(const char* str); +void http_deescape(char* str); -int deferred_unlink(const char *filename, const char *rootdir); -void dvr_cutpoint_delete_files (const char *s); +int mpegts_word_count(const uint8_t* tsb, int len, uint32_t mask); -void sha1_calc(uint8_t *dst, const uint8_t *d1, size_t d1_len, const uint8_t *d2, size_t d2_len); +int deferred_unlink(const char* filename, const char* rootdir); +void dvr_cutpoint_delete_files(const char* s); -uint32_t gcdU32(uint32_t a, uint32_t b); -static inline int32_t deltaI32(int32_t a, int32_t b) { return (a > b) ? (a - b) : (b - a); } -static inline uint32_t deltaU32(uint32_t a, uint32_t b) { return (a > b) ? (a - b) : (b - a); } +void sha1_calc(uint8_t* dst, const uint8_t* d1, size_t d1_len, const uint8_t* d2, size_t d2_len); -#define SKEL_DECLARE(name, type) type *name; -#define SKEL_ALLOC(name) do { if (!name) name = calloc(1, sizeof(*name)); } while (0) -#define SKEL_USED(name) do { name = NULL; } while (0) -#define SKEL_FREE(name) do { free(name); name = NULL; } while (0) - -htsmsg_t *network_interfaces_enum(void *obj, const char *lang); +uint32_t gcdU32(uint32_t a, uint32_t b); +static inline int32_t deltaI32(int32_t a, int32_t b) { + return (a > b) ? (a - b) : (b - a); +} +static inline uint32_t deltaU32(uint32_t a, uint32_t b) { + return (a > b) ? (a - b) : (b - a); +} -const char *gmtime2local(time_t gmt, char *buf, size_t buflen); +#define SKEL_DECLARE(name, type) type* name; +#define SKEL_ALLOC(name) \ + do { \ + if (!name) \ + name = calloc(1, sizeof(*name)); \ + } while (0) +#define SKEL_USED(name) \ + do { \ + name = NULL; \ + } while (0) +#define SKEL_FREE(name) \ + do { \ + free(name); \ + name = NULL; \ + } while (0) + +htsmsg_t* network_interfaces_enum(void* obj, const char* lang); + +const char* gmtime2local(time_t gmt, char* buf, size_t buflen); /* glibc wrapper */ -#if ! ENABLE_QSORT_R -void -qsort_r(void *base, size_t nmemb, size_t size, - int (*cmp)(const void *, const void *, void *), void *aux); +#if !ENABLE_QSORT_R +void qsort_r(void* base, + size_t nmemb, + size_t size, + int (*cmp)(const void*, const void*, void*), + void* aux); #endif /* ENABLE_QSORT_R */ -void tvh_qsort_r(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *, void *), void *arg); +void tvh_qsort_r(void* base, + size_t nmemb, + size_t size, + int (*compar)(const void*, const void*, void*), + void* arg); /* printing */ #ifndef __WORDSIZE -# if ULONG_MAX == 0xffffffffffffffff -# define __WORDSIZE 64 -# elif ULONG_MAX == 0xffffffff -# define __WORDSIZE 32 -# endif /* ULONG_MAX */ +#if ULONG_MAX == 0xffffffffffffffff +#define __WORDSIZE 64 +#elif ULONG_MAX == 0xffffffff +#define __WORDSIZE 32 +#endif /* ULONG_MAX */ #endif /* __WORDSIZE */ #if CONFIG_TIME_LLD == 1 -# define PRItime_t "lld" +#define PRItime_t "lld" #elif CONFIG_TIME_LD == 1 -# define PRItime_t "ld" +#define PRItime_t "ld" #else -# error "CONFIG_TIME not properly defined" +#error "CONFIG_TIME not properly defined" #endif /* transcoding */ -#define TVH_NAME_LEN 32 +#define TVH_NAME_LEN 32 #define TVH_TITLE_LEN 256 /* sanitizer helpers */ #if ENABLE_CCLANG_THREADSAN -void *blacklisted_memcpy(void *dest, const void *src, size_t n); -int blacklisted_close(int fildes); +void* blacklisted_memcpy(void* dest, const void* src, size_t n); +int blacklisted_close(int fildes); #else #define blacklisted_memcpy memcpy -#define blacklisted_close close +#define blacklisted_close close #endif #endif /* TVHEADEND_H */ diff --git a/src/tvhlog.c b/src/tvhlog.c index cf526f5c2..a4a3b26e0 100644 --- a/src/tvhlog.c +++ b/src/tvhlog.c @@ -36,185 +36,180 @@ #include "tcp.h" #include "webui/webui.h" -int tvhlog_run; -int tvhlog_level; -int tvhlog_options; -char *tvhlog_path; -//TVHLOG_BITARRAY is defined in bitops.h -bitops_ulong_t tvhlog_debug[TVHLOG_BITARRAY]; -bitops_ulong_t tvhlog_trace[TVHLOG_BITARRAY]; -pthread_t tvhlog_tid; -tvh_mutex_t tvhlog_mutex; -tvh_cond_t tvhlog_cond; -TAILQ_HEAD(,tvhlog_msg) tvhlog_queue; -int tvhlog_queue_size; -int tvhlog_queue_full; +int tvhlog_run; +int tvhlog_level; +int tvhlog_options; +char* tvhlog_path; +// TVHLOG_BITARRAY is defined in bitops.h +bitops_ulong_t tvhlog_debug[TVHLOG_BITARRAY]; +bitops_ulong_t tvhlog_trace[TVHLOG_BITARRAY]; +pthread_t tvhlog_tid; +tvh_mutex_t tvhlog_mutex; +tvh_cond_t tvhlog_cond; +TAILQ_HEAD(, tvhlog_msg) tvhlog_queue; +int tvhlog_queue_size; +int tvhlog_queue_full; #if ENABLE_TRACE -int tvhlog_rtfd = STDOUT_FILENO; -struct sockaddr_storage tvhlog_rtss; +int tvhlog_rtfd = STDOUT_FILENO; +struct sockaddr_storage tvhlog_rtss; #endif #define TVHLOG_QUEUE_MAXSIZE 10000 -#define TVHLOG_THREAD 1 - -typedef struct tvhlog_msg -{ - TAILQ_ENTRY(tvhlog_msg) link; - char *msg; - int severity; - int notify; - struct timeval time; +#define TVHLOG_THREAD 1 + +typedef struct tvhlog_msg { + TAILQ_ENTRY(tvhlog_msg) link; + char* msg; + int severity; + int notify; + struct timeval time; } tvhlog_msg_t; -static const char *logtxtmeta[9][2] = { - {"EMERGENCY", "\033[31m"}, - {"ALERT", "\033[31m"}, - {"CRITICAL", "\033[31m"}, - {"ERROR", "\033[31m"}, - {"WARNING", "\033[33m"}, - {"NOTICE", "\033[36m"}, - {"INFO", "\033[32m"}, - {"DEBUG", "\033[32m"}, - {"TRACE", "\033[32m"}, +static const char* logtxtmeta[9][2] = { + {"EMERGENCY", "\033[31m"}, + {"ALERT", "\033[31m"}, + {"CRITICAL", "\033[31m"}, + {"ERROR", "\033[31m"}, + {"WARNING", "\033[33m"}, + {"NOTICE", "\033[36m"}, + {"INFO", "\033[32m"}, + {"DEBUG", "\033[32m"}, + {"TRACE", "\033[32m"}, }; tvhlog_subsys_t tvhlog_subsystems[] = { - [LS_NONE] = { "", N_("None") }, - [LS_START] = { "START", N_("START") }, - [LS_STOP] = { "STOP", N_("STOP") }, - [LS_CRASH] = { "CRASH", N_("CRASH") }, - [LS_CPU] = { "CPU", N_("CPU") }, - [LS_MAIN] = { "main", N_("Main") }, - [LS_TPROF] = { "tprof", N_("Time profiling") }, - [LS_QPROF] = { "qprof", N_("Queue profiling") }, - [LS_THREAD] = { "thread", N_("Thread") }, - [LS_TVHPOLL] = { "tvhpoll", N_("Poll multiplexer") }, - [LS_TIME] = { "time", N_("Time") }, - [LS_SPAWN] = { "spawn", N_("Spawn") }, - [LS_FSMONITOR] = { "fsmonitor", N_("Filesystem monitor") }, - [LS_LOCK] = { "lock", N_("Locking") }, - [LS_UUID] = { "uuid", N_("UUID") }, - [LS_IDNODE] = { "idnode", N_("Node subsystem") }, - [LS_URL] = { "url", N_("URL") }, - [LS_TCP] = { "tcp", N_("TCP Protocol") }, - [LS_RTSP] = { "rtsp", N_("RTSP Protocol") }, - [LS_UPNP] = { "upnp", N_("UPnP Protocol") }, - [LS_SETTINGS] = { "settings", N_("Settings") }, - [LS_CONFIG] = { "config", N_("Configuration") }, - [LS_ACCESS] = { "access", N_("Access (ACL)") }, - [LS_CRON] = { "cron", N_("Cron") }, - [LS_DBUS] = { "dbus", N_("DBUS") }, - [LS_AVAHI] = { "avahi", N_("Avahi") }, - [LS_BONJOUR] = { "bonjour", N_("Bonjour") }, - [LS_API] = { "api", N_("API") }, - [LS_HTTP] = { "http", N_("HTTP Server") }, - [LS_HTTPC] = { "httpc", N_("HTTP Client") }, - [LS_HTSP] = { "htsp", N_("HTSP Server") }, - [LS_HTSP_SUB] = { "htsp-sub", N_("HTSP Subscription") }, - [LS_HTSP_REQ] = { "htsp-req", N_("HTSP Request") }, - [LS_HTSP_ANS] = { "htsp-ans", N_("HTSP Answer") }, - [LS_IMAGECACHE] = { "imagecache", N_("Image Cache") }, - [LS_TBL] = { "tbl", N_("DVB SI Tables") }, - [LS_TBL_BASE] = { "tbl-base", N_("Base DVB SI Tables (PAT,CAT,PMT,SDT etc.)") }, - [LS_TBL_CSA] = { "tbl-csa", N_("DVB CSA (descrambling) Tables") }, - [LS_TBL_EIT] = { "tbl-eit", N_("DVB EPG Tables") }, - [LS_TBL_TIME] = { "tbl-time", N_("DVB Time Tables") }, - [LS_TBL_ATSC] = { "tbl-atsc", N_("ATSC SI Tables") }, - [LS_TBL_PASS] = { "tbl-pass", N_("Passthrough Muxer SI Tables") }, - [LS_TBL_SATIP] = { "tbl-satip", N_("SAT>IP Server SI Tables") }, - [LS_FASTSCAN] = { "fastscan", N_("Fastscan DVB") }, - [LS_PCR] = { "pcr", N_("PCR Clocks") }, - [LS_PARSER] = { "parser", N_("MPEG-TS Parser") }, - [LS_TS] = { "TS", N_("Transport Stream") }, - [LS_GLOBALHEADERS] = { "globalheaders", N_("Global Headers") }, - [LS_TSFIX] = { "tsfix", N_("Time Stamp Fix") }, - [LS_HEVC] = { "hevc", N_("HEVC - H.265") }, - [LS_MUXER] = { "muxer", N_("Muxer") }, - [LS_PASS] = { "pass", N_("Pass-thru muxer") }, - [LS_AUDIOES] = { "audioes", N_("Audioes muxer") }, - [LS_MKV] = { "mkv", N_("Matroska muxer") }, - [LS_SERVICE] = { "service", N_("Service") }, - [LS_CHANNEL] = { "channel", N_("Channel") }, - [LS_SUBSCRIPTION] = { "subscription", N_("Subscription") }, - [LS_SERVICE_MAPPER]= { "service-mapper",N_("Service Mapper") }, - [LS_BOUQUET] = { "bouquet", N_("Bouquet") }, - [LS_ESFILTER] = { "esfilter", N_("Elementary Stream Filter") }, - [LS_PROFILE] = { "profile", N_("Streaming Profile") }, - [LS_DESCRAMBLER] = { "descrambler", N_("Descrambler") }, - [LS_DESCRAMBLER_EMM]={ "descrambler-emm",N_("Descrambler EMM") }, - [LS_CACLIENT] = { "caclient", N_("CA (descrambling) Client") }, - [LS_CSA] = { "csa", N_("CSA (descrambling)") }, - [LS_CAPMT] = { "capmt", N_("CAPMT CA Client") }, - [LS_CWC] = { "cwc", N_("CWC CA Client") }, - [LS_CCCAM] = { "cccam", N_("CWC CCCam Client") }, - [LS_DVBCAM] = { "dvbcam", N_("DVB CAM Client") }, - [LS_DVR] = { "dvr", N_("Digital Video Recorder") }, - [LS_DVR_INOTIFY] = { "dvr-inotify", N_("DVR Inotify") }, - [LS_EPG] = { "epg", N_("Electronic Program Guide") }, - [LS_EPGDB] = { "epgdb", N_("EPG Database") }, - [LS_EPGGRAB] = { "epggrab", N_("EPG Grabber") }, - [LS_CHARSET] = { "charset", N_("Charset") }, - [LS_DVB] = { "dvb", N_("DVB") }, - [LS_MPEGTS] = { "mpegts", N_("MPEG-TS") }, - [LS_MUXSCHED] = { "muxsched", N_("Mux Scheduler") }, - [LS_LIBAV] = { "libav", N_("libav / ffmpeg") }, - [LS_TRANSCODE] = { "transcode", N_("Transcode") }, - [LS_IPTV] = { "iptv", N_("IPTV") }, - [LS_IPTV_PCR] = { "iptv-pcr", N_("IPTV PCR") }, - [LS_IPTV_SUB] = { "iptv-sub", N_("IPTV Subcription") }, - [LS_LINUXDVB] = { "linuxdvb", N_("LinuxDVB Input") }, - [LS_DISEQC] = { "diseqc", N_("DiseqC") }, - [LS_EN50221] = { "en50221", N_("CI Module") }, - [LS_EN50494] = { "en50494", N_("Unicable (EN50494)") }, - [LS_SATIP] = { "satip", N_("SAT>IP Client") }, - [LS_SATIPS] = { "satips", N_("SAT>IP Server") }, - [LS_TVHDHOMERUN] = { "tvhdhomerun", N_("TVHDHomeRun Client") }, - [LS_PSIP] = { "psip", N_("ATSC PSIP EPG") }, - [LS_OPENTV] = { "opentv", N_("OpenTV EPG") }, - [LS_PYEPG] = { "pyepg", N_("PyEPG Import") }, - [LS_XMLTV] = { "xmltv", N_("XMLTV EPG Import") }, - [LS_WEBUI] = { "webui", N_("Web User Interface") }, - [LS_TIMESHIFT] = { "timeshift", N_("Timeshift") }, - [LS_SCANFILE] = { "scanfile", N_("Scanfile") }, - [LS_TSFILE] = { "tsfile", N_("MPEG-TS File") }, - [LS_TSDEBUG] = { "tsdebug", N_("MPEG-TS Input Debug") }, - [LS_CODEC] = { "codec", N_("Codec") }, - [LS_VAAPI] = { "vaapi", N_("VA-API") }, + [LS_NONE] = {"", N_("None")}, + [LS_START] = {"START", N_("START")}, + [LS_STOP] = {"STOP", N_("STOP")}, + [LS_CRASH] = {"CRASH", N_("CRASH")}, + [LS_CPU] = {"CPU", N_("CPU")}, + [LS_MAIN] = {"main", N_("Main")}, + [LS_TPROF] = {"tprof", N_("Time profiling")}, + [LS_QPROF] = {"qprof", N_("Queue profiling")}, + [LS_THREAD] = {"thread", N_("Thread")}, + [LS_TVHPOLL] = {"tvhpoll", N_("Poll multiplexer")}, + [LS_TIME] = {"time", N_("Time")}, + [LS_SPAWN] = {"spawn", N_("Spawn")}, + [LS_FSMONITOR] = {"fsmonitor", N_("Filesystem monitor")}, + [LS_LOCK] = {"lock", N_("Locking")}, + [LS_UUID] = {"uuid", N_("UUID")}, + [LS_IDNODE] = {"idnode", N_("Node subsystem")}, + [LS_URL] = {"url", N_("URL")}, + [LS_TCP] = {"tcp", N_("TCP Protocol")}, + [LS_RTSP] = {"rtsp", N_("RTSP Protocol")}, + [LS_UPNP] = {"upnp", N_("UPnP Protocol")}, + [LS_SETTINGS] = {"settings", N_("Settings")}, + [LS_CONFIG] = {"config", N_("Configuration")}, + [LS_ACCESS] = {"access", N_("Access (ACL)")}, + [LS_CRON] = {"cron", N_("Cron")}, + [LS_DBUS] = {"dbus", N_("DBUS")}, + [LS_AVAHI] = {"avahi", N_("Avahi")}, + [LS_BONJOUR] = {"bonjour", N_("Bonjour")}, + [LS_API] = {"api", N_("API")}, + [LS_HTTP] = {"http", N_("HTTP Server")}, + [LS_HTTPC] = {"httpc", N_("HTTP Client")}, + [LS_HTSP] = {"htsp", N_("HTSP Server")}, + [LS_HTSP_SUB] = {"htsp-sub", N_("HTSP Subscription")}, + [LS_HTSP_REQ] = {"htsp-req", N_("HTSP Request")}, + [LS_HTSP_ANS] = {"htsp-ans", N_("HTSP Answer")}, + [LS_IMAGECACHE] = {"imagecache", N_("Image Cache")}, + [LS_TBL] = {"tbl", N_("DVB SI Tables")}, + [LS_TBL_BASE] = {"tbl-base", N_("Base DVB SI Tables (PAT,CAT,PMT,SDT etc.)")}, + [LS_TBL_CSA] = {"tbl-csa", N_("DVB CSA (descrambling) Tables")}, + [LS_TBL_EIT] = {"tbl-eit", N_("DVB EPG Tables")}, + [LS_TBL_TIME] = {"tbl-time", N_("DVB Time Tables")}, + [LS_TBL_ATSC] = {"tbl-atsc", N_("ATSC SI Tables")}, + [LS_TBL_PASS] = {"tbl-pass", N_("Passthrough Muxer SI Tables")}, + [LS_TBL_SATIP] = {"tbl-satip", N_("SAT>IP Server SI Tables")}, + [LS_FASTSCAN] = {"fastscan", N_("Fastscan DVB")}, + [LS_PCR] = {"pcr", N_("PCR Clocks")}, + [LS_PARSER] = {"parser", N_("MPEG-TS Parser")}, + [LS_TS] = {"TS", N_("Transport Stream")}, + [LS_GLOBALHEADERS] = {"globalheaders", N_("Global Headers")}, + [LS_TSFIX] = {"tsfix", N_("Time Stamp Fix")}, + [LS_HEVC] = {"hevc", N_("HEVC - H.265")}, + [LS_MUXER] = {"muxer", N_("Muxer")}, + [LS_PASS] = {"pass", N_("Pass-thru muxer")}, + [LS_AUDIOES] = {"audioes", N_("Audioes muxer")}, + [LS_MKV] = {"mkv", N_("Matroska muxer")}, + [LS_SERVICE] = {"service", N_("Service")}, + [LS_CHANNEL] = {"channel", N_("Channel")}, + [LS_SUBSCRIPTION] = {"subscription", N_("Subscription")}, + [LS_SERVICE_MAPPER] = {"service-mapper", N_("Service Mapper")}, + [LS_BOUQUET] = {"bouquet", N_("Bouquet")}, + [LS_ESFILTER] = {"esfilter", N_("Elementary Stream Filter")}, + [LS_PROFILE] = {"profile", N_("Streaming Profile")}, + [LS_DESCRAMBLER] = {"descrambler", N_("Descrambler")}, + [LS_DESCRAMBLER_EMM] = {"descrambler-emm", N_("Descrambler EMM")}, + [LS_CACLIENT] = {"caclient", N_("CA (descrambling) Client")}, + [LS_CSA] = {"csa", N_("CSA (descrambling)")}, + [LS_CAPMT] = {"capmt", N_("CAPMT CA Client")}, + [LS_CWC] = {"cwc", N_("CWC CA Client")}, + [LS_CCCAM] = {"cccam", N_("CWC CCCam Client")}, + [LS_DVBCAM] = {"dvbcam", N_("DVB CAM Client")}, + [LS_DVR] = {"dvr", N_("Digital Video Recorder")}, + [LS_DVR_INOTIFY] = {"dvr-inotify", N_("DVR Inotify")}, + [LS_EPG] = {"epg", N_("Electronic Program Guide")}, + [LS_EPGDB] = {"epgdb", N_("EPG Database")}, + [LS_EPGGRAB] = {"epggrab", N_("EPG Grabber")}, + [LS_CHARSET] = {"charset", N_("Charset")}, + [LS_DVB] = {"dvb", N_("DVB")}, + [LS_MPEGTS] = {"mpegts", N_("MPEG-TS")}, + [LS_MUXSCHED] = {"muxsched", N_("Mux Scheduler")}, + [LS_LIBAV] = {"libav", N_("libav / ffmpeg")}, + [LS_TRANSCODE] = {"transcode", N_("Transcode")}, + [LS_IPTV] = {"iptv", N_("IPTV")}, + [LS_IPTV_PCR] = {"iptv-pcr", N_("IPTV PCR")}, + [LS_IPTV_SUB] = {"iptv-sub", N_("IPTV Subcription")}, + [LS_LINUXDVB] = {"linuxdvb", N_("LinuxDVB Input")}, + [LS_DISEQC] = {"diseqc", N_("DiseqC")}, + [LS_EN50221] = {"en50221", N_("CI Module")}, + [LS_EN50494] = {"en50494", N_("Unicable (EN50494)")}, + [LS_SATIP] = {"satip", N_("SAT>IP Client")}, + [LS_SATIPS] = {"satips", N_("SAT>IP Server")}, + [LS_TVHDHOMERUN] = {"tvhdhomerun", N_("TVHDHomeRun Client")}, + [LS_PSIP] = {"psip", N_("ATSC PSIP EPG")}, + [LS_OPENTV] = {"opentv", N_("OpenTV EPG")}, + [LS_PYEPG] = {"pyepg", N_("PyEPG Import")}, + [LS_XMLTV] = {"xmltv", N_("XMLTV EPG Import")}, + [LS_WEBUI] = {"webui", N_("Web User Interface")}, + [LS_TIMESHIFT] = {"timeshift", N_("Timeshift")}, + [LS_SCANFILE] = {"scanfile", N_("Scanfile")}, + [LS_TSFILE] = {"tsfile", N_("MPEG-TS File")}, + [LS_TSDEBUG] = {"tsdebug", N_("MPEG-TS Input Debug")}, + [LS_CODEC] = {"codec", N_("Codec")}, + [LS_VAAPI] = {"vaapi", N_("VA-API")}, #if ENABLE_DDCI - [LS_DDCI] = { "ddci", N_("DD-CI") }, + [LS_DDCI] = {"ddci", N_("DD-CI")}, #endif - [LS_UDP] = { "udp", N_("UDP Streamer") }, - [LS_RATINGLABELS] = { "ratinglabels", N_("Rating Labels") }, + [LS_UDP] = {"udp", N_("UDP Streamer")}, + [LS_RATINGLABELS] = {"ratinglabels", N_("Rating Labels")}, }; -static void -tvhlog_get_subsys ( bitops_ulong_t *ss, char *subsys, size_t len ) -{ - size_t c = 0; +static void tvhlog_get_subsys(bitops_ulong_t* ss, char* subsys, size_t len) { + size_t c = 0; uint_fast32_t first = 1, i; - *subsys = '\0'; + *subsys = '\0'; for (i = 0; i < LS_LAST; i++) - if (!test_bit(i, ss)) break; + if (!test_bit(i, ss)) + break; if (i >= LS_LAST) { tvh_strlcatf(subsys, len, c, "all"); return; } for (i = 0; i < LS_LAST; i++) { - if (!test_bit(i, ss)) continue; - tvh_strlcatf(subsys, len, c, "%s%s", - first ? "" : ",", - tvhlog_subsystems[i].name); + if (!test_bit(i, ss)) + continue; + tvh_strlcatf(subsys, len, c, "%s%s", first ? "" : ",", tvhlog_subsystems[i].name); first = 0; } } /* Set subsys */ -static void -tvhlog_set_subsys ( bitops_ulong_t *c, const char *subsys ) -{ +static void tvhlog_set_subsys(bitops_ulong_t* c, const char* subsys) { uint_fast32_t a, i; - char *s, *t, *r = NULL; + char * s, *t, *r = NULL; memset(c, 0, TVHLOG_BITARRAY * sizeof(bitops_ulong_t)); @@ -223,7 +218,7 @@ tvhlog_set_subsys ( bitops_ulong_t *c, const char *subsys ) s = strdup(subsys); t = strtok_r(s, ",", &r); - while ( t ) { + while (t) { subsys = NULL; a = 1; while (*t && (*t == '+' || *t == '-' || *t <= ' ')) { @@ -231,55 +226,48 @@ tvhlog_set_subsys ( bitops_ulong_t *c, const char *subsys ) a = *t == '+'; t++; } - if (!*t) goto next; + if (!*t) + goto next; if (!strcmp(t, "all")) { memset(c, a ? 0xff : 0, TVHLOG_BITARRAY * sizeof(bitops_ulong_t)); } else { for (i = 0; i < LS_LAST; i++) if (!strcmp(tvhlog_subsystems[i].name, t)) { - if (a) set_bit(i, c); else clear_bit(i, c); + if (a) + set_bit(i, c); + else + clear_bit(i, c); break; } if (i >= LS_LAST) tvherror(LS_CONFIG, "unknown subsystem '%s'", t); } -next: + next: t = strtok_r(NULL, ",", &r); } free(s); } -void -tvhlog_set_debug ( const char *subsys ) -{ +void tvhlog_set_debug(const char* subsys) { tvhlog_set_subsys(tvhlog_debug, subsys); } -void -tvhlog_set_trace ( const char *subsys ) -{ +void tvhlog_set_trace(const char* subsys) { tvhlog_set_subsys(tvhlog_trace, subsys); } -void -tvhlog_get_debug ( char *subsys, size_t len ) -{ +void tvhlog_get_debug(char* subsys, size_t len) { tvhlog_get_subsys(tvhlog_debug, subsys, len); } -void -tvhlog_get_trace ( char *subsys, size_t len ) -{ +void tvhlog_get_trace(char* subsys, size_t len) { tvhlog_get_subsys(tvhlog_trace, subsys, len); } -static void -tvhlog_process - ( tvhlog_msg_t *msg, int options, FILE **fp, const char *path ) -{ - int s; - size_t l; - char buf[2048], t[128]; +static void tvhlog_process(tvhlog_msg_t* msg, int options, FILE** fp, const char* path) { + int s; + size_t l; + char buf[2048], t[128]; struct tm tm; /* Syslog */ @@ -292,7 +280,7 @@ tvhlog_process /* Get time */ localtime_r(&msg->time.tv_sec, &tm); - l = strftime(t, sizeof(t), "%F %T", &tm);// %d %H:%M:%S", &tm); + l = strftime(t, sizeof(t), "%F %T", &tm); // %d %H:%M:%S", &tm); if (options & TVHLOG_OPT_MILLIS) { int ms = msg->time.tv_usec / 1000; tvh_strlcatf(t, sizeof(t), l, ".%03d", ms); @@ -307,9 +295,9 @@ tvhlog_process /* Console */ if (options & TVHLOG_OPT_STDERR) { if (options & TVHLOG_OPT_DBG_STDERR || msg->severity < LOG_DEBUG) { - const char *ltxt = logtxtmeta[msg->severity][0]; - const char *sgr = logtxtmeta[msg->severity][1]; - const char *sgroff; + const char* ltxt = logtxtmeta[msg->severity][0]; + const char* sgr = logtxtmeta[msg->severity][1]; + const char* sgroff; if (options & TVHLOG_OPT_DECORATE) sgroff = "\033[0m"; @@ -324,7 +312,7 @@ tvhlog_process /* File */ if (*fp || path) { if (options & TVHLOG_OPT_DBG_FILE || msg->severity < LOG_DEBUG) { - const char *ltxt = logtxtmeta[msg->severity][0]; + const char* ltxt = logtxtmeta[msg->severity][0]; if (!*fp) *fp = tvh_fopen(path, "a"); if (*fp) @@ -337,13 +325,11 @@ tvhlog_process } /* Log */ -static void * -tvhlog_thread ( void *p ) -{ - int options; - char *path = NULL, buf[512]; - FILE *fp = NULL; - tvhlog_msg_t *msg; +static void* tvhlog_thread(void* p) { + int options; + char * path = NULL, buf[512]; + FILE* fp = NULL; + tvhlog_msg_t* msg; tvh_mutex_lock(&tvhlog_mutex); while (tvhlog_run) { @@ -372,7 +358,7 @@ tvhlog_thread ( void *p ) path = NULL; } } - options = tvhlog_options; + options = tvhlog_options; tvh_mutex_unlock(&tvhlog_mutex); tvhlog_process(msg, options, &fp, path); tvh_mutex_lock(&tvhlog_mutex); @@ -383,12 +369,10 @@ tvhlog_thread ( void *p ) return NULL; } -void tvhlogv ( const char *file, int line, int severity, - int subsys, const char *fmt, va_list *args ) -{ - int ok, options, notify; +void tvhlogv(const char* file, int line, int severity, int subsys, const char* fmt, va_list* args) { + int ok, options, notify; size_t l; - char buf[1024]; + char buf[1024]; notify = (severity & LOG_TVH_NOTIFY) ? 1 : 0; severity &= ~LOG_TVH_NOTIFY; @@ -419,14 +403,14 @@ void tvhlogv ( const char *file, int line, int severity, /* FULL */ if (tvhlog_queue_size == TVHLOG_QUEUE_MAXSIZE) { tvhlog_queue_full = 1; - fmt = "log buffer full"; - args = NULL; - severity = LOG_ERR; + fmt = "log buffer full"; + args = NULL; + severity = LOG_ERR; } /* Basic message */ options = tvhlog_options; - l = 0; + l = 0; if (options & TVHLOG_OPT_THREAD) { tvh_strlcatf(buf, sizeof(buf), l, "tid %ld: ", (long)pthread_self()); } @@ -439,7 +423,7 @@ void tvhlogv ( const char *file, int line, int severity, snprintf(buf + l, sizeof(buf) - l, "%s", fmt); /* Store */ - tvhlog_msg_t *msg = calloc(1, sizeof(tvhlog_msg_t)); + tvhlog_msg_t* msg = calloc(1, sizeof(tvhlog_msg_t)); gettimeofday(&msg->time, NULL); msg->msg = strdup(buf); msg->severity = severity; @@ -451,22 +435,20 @@ void tvhlogv ( const char *file, int line, int severity, tvh_cond_signal(&tvhlog_cond, 0); } else { #endif - FILE *fp = NULL; + FILE* fp = NULL; tvhlog_process(msg, tvhlog_options, &fp, tvhlog_path); - if (fp) fclose(fp); + if (fp) + fclose(fp); #if TVHLOG_THREAD } #endif tvh_mutex_unlock(&tvhlog_mutex); } - /* * Map args */ -void _tvhlog ( const char *file, int line, int severity, - int subsys, const char *fmt, ... ) -{ +void _tvhlog(const char* file, int line, int severity, int subsys, const char* fmt, ...) { va_list args; va_start(args, fmt); tvhlogv(file, line, severity, subsys, fmt, &args); @@ -477,11 +459,13 @@ void _tvhlog ( const char *file, int line, int severity, * Log a hexdump */ #define HEXDUMP_WIDTH 16 -void -_tvhlog_hexdump(const char *file, int line, int severity, - int subsys, const uint8_t *data, ssize_t len ) -{ - int i, c; +void _tvhlog_hexdump(const char* file, + int line, + int severity, + int subsys, + const uint8_t* data, + ssize_t len) { + int i, c; char str[1024]; /* Assume that severify was validated before call */ @@ -507,7 +491,7 @@ _tvhlog_hexdump(const char *file, int line, int severity, } str[c] = '\0'; tvhlogv(file, line, severity, subsys, str, NULL); - len -= HEXDUMP_WIDTH; + len -= HEXDUMP_WIDTH; data += HEXDUMP_WIDTH; } } @@ -515,14 +499,12 @@ _tvhlog_hexdump(const char *file, int line, int severity, /* * */ -void -tvhlog_backtrace_printf(const char *fmt, ...) -{ +void tvhlog_backtrace_printf(const char* fmt, ...) { #if ENABLE_EXECINFO - static void *frames[5]; - int nframes = backtrace(frames, 5), i; - char **strings = backtrace_symbols(frames, nframes); - va_list args; + static void* frames[5]; + int nframes = backtrace(frames, 5), i; + char** strings = backtrace_symbols(frames, nframes); + va_list args; va_start(args, fmt); vprintf(fmt, args); @@ -537,17 +519,17 @@ tvhlog_backtrace_printf(const char *fmt, ...) * */ #if ENABLE_TRACE -static void tvhdbgv(int subsys, const char *fmt, va_list *args) -{ - char buf[2048]; +static void tvhdbgv(int subsys, const char* fmt, va_list* args) { + char buf[2048]; size_t l = 0; - if (tvhlog_rtfd < 0) return; + if (tvhlog_rtfd < 0) + return; tvh_strlcatf(buf, sizeof(buf), l, "%s: ", tvhlog_subsystems[subsys].name); l += vsnprintf(buf + l, sizeof(buf) - l, fmt, *args); if (l + 1 < sizeof(buf)) buf[l++] = '\n'; - sendto(tvhlog_rtfd, buf, l, 0, (struct sockaddr *)&tvhlog_rtss, sizeof(struct sockaddr_in)); + sendto(tvhlog_rtfd, buf, l, 0, (struct sockaddr*)&tvhlog_rtss, sizeof(struct sockaddr_in)); } #endif @@ -555,8 +537,7 @@ static void tvhdbgv(int subsys, const char *fmt, va_list *args) * */ #if ENABLE_TRACE -void tvhdbg(int subsys, const char *fmt, ...) -{ +void tvhdbg(int subsys, const char* fmt, ...) { va_list args; va_start(args, fmt); tvhdbgv(subsys, fmt, &args); @@ -567,23 +548,21 @@ void tvhdbg(int subsys, const char *fmt, ...) /* * Initialise */ -void -tvhlog_init ( int level, int options, const char *path ) -{ +void tvhlog_init(int level, int options, const char* path) { atomic_set(&tvhlog_level, level); tvhlog_options = options; tvhlog_path = path ? strdup(path) : NULL; memset(tvhlog_trace, 0, sizeof(tvhlog_trace)); memset(tvhlog_debug, 0, sizeof(tvhlog_debug)); - tvhlog_run = 1; + tvhlog_run = 1; openlog("tvheadend", LOG_PID, LOG_DAEMON); tvh_mutex_init(&tvhlog_mutex, NULL); tvh_cond_init(&tvhlog_cond, 1); TAILQ_INIT(&tvhlog_queue); #if ENABLE_TRACE { - const char *rtport0 = getenv("TVHEADEND_RTLOG_UDP_PORT"); - int rtport = rtport0 ? atoi(rtport0) : 0; + const char* rtport0 = getenv("TVHEADEND_RTLOG_UDP_PORT"); + int rtport = rtport0 ? atoi(rtport0) : 0; if (rtport > 0) { tvhlog_rtfd = tvh_socket(AF_INET, SOCK_DGRAM, 0); tcp_get_ip_from_str("127.0.0.1", &tvhlog_rtss); @@ -593,18 +572,14 @@ tvhlog_init ( int level, int options, const char *path ) #endif } -void -tvhlog_start ( void ) -{ +void tvhlog_start(void) { idclass_register(&tvhlog_conf_class); tvh_thread_create(&tvhlog_tid, NULL, tvhlog_thread, NULL, "log"); } -void -tvhlog_end ( void ) -{ - FILE *fp = NULL; - tvhlog_msg_t *msg; +void tvhlog_end(void) { + FILE* fp = NULL; + tvhlog_msg_t* msg; tvh_mutex_lock(&tvhlog_mutex); tvhlog_run = 0; tvh_cond_signal(&tvhlog_cond, 0); @@ -633,16 +608,12 @@ tvhlog_end ( void ) * Configuration */ -static const void * -tvhlog_class_path_get ( void *o ) -{ +static const void* tvhlog_class_path_get(void* o) { return &tvhlog_path; } -static int -tvhlog_class_path_set ( void *o, const void *v ) -{ - const char *s = v; +static int tvhlog_class_path_set(void* o, const void* v) { + const char* s = v; if (strcmp(s ?: "", tvhlog_path ?: "")) { tvh_mutex_lock(&tvhlog_mutex); free(tvhlog_path); @@ -657,49 +628,37 @@ tvhlog_class_path_set ( void *o, const void *v ) return 0; } -static const void * -tvhlog_class_debugsubs_get ( void *o ) -{ - static char *p = prop_sbuf; +static const void* tvhlog_class_debugsubs_get(void* o) { + static char* p = prop_sbuf; tvhlog_get_debug(prop_sbuf, PROP_SBUF_LEN); return &p; } -static int -tvhlog_class_debugsubs_set ( void *o, const void *v ) -{ - tvhlog_set_debug((const char *)v); +static int tvhlog_class_debugsubs_set(void* o, const void* v) { + tvhlog_set_debug((const char*)v); return 1; } -static const void * -tvhlog_class_tracesubs_get ( void *o ) -{ - static char *p = prop_sbuf; +static const void* tvhlog_class_tracesubs_get(void* o) { + static char* p = prop_sbuf; tvhlog_get_trace(prop_sbuf, PROP_SBUF_LEN); return &p; } -static int -tvhlog_class_tracesubs_set ( void *o, const void *v ) -{ - tvhlog_set_trace((const char *)v); +static int tvhlog_class_tracesubs_set(void* o, const void* v) { + tvhlog_set_trace((const char*)v); return 1; } -static const void * -tvhlog_class_enable_syslog_get ( void *o ) -{ +static const void* tvhlog_class_enable_syslog_get(void* o) { static int si; si = (tvhlog_options & TVHLOG_OPT_SYSLOG) ? 1 : 0; return &si; } -static int -tvhlog_class_enable_syslog_set ( void *o, const void *v ) -{ +static int tvhlog_class_enable_syslog_set(void* o, const void* v) { tvh_mutex_lock(&tvhlog_mutex); - if (*(int *)v) + if (*(int*)v) tvhlog_options |= TVHLOG_OPT_SYSLOG; else tvhlog_options &= ~TVHLOG_OPT_SYSLOG; @@ -707,19 +666,15 @@ tvhlog_class_enable_syslog_set ( void *o, const void *v ) return 1; } -static const void * -tvhlog_class_debug_syslog_get ( void *o ) -{ +static const void* tvhlog_class_debug_syslog_get(void* o) { static int si; si = (tvhlog_options & TVHLOG_OPT_DBG_SYSLOG) ? 1 : 0; return &si; } -static int -tvhlog_class_debug_syslog_set ( void *o, const void *v ) -{ +static int tvhlog_class_debug_syslog_set(void* o, const void* v) { tvh_mutex_lock(&tvhlog_mutex); - if (*(int *)v) + if (*(int*)v) tvhlog_options |= TVHLOG_OPT_DBG_SYSLOG; else tvhlog_options &= ~TVHLOG_OPT_DBG_SYSLOG; @@ -727,34 +682,26 @@ tvhlog_class_debug_syslog_set ( void *o, const void *v ) return 1; } -static const void * -tvhlog_class_trace_get ( void *o ) -{ +static const void* tvhlog_class_trace_get(void* o) { static int si; si = atomic_get(&tvhlog_level) >= LOG_TRACE; return &si; } -static int -tvhlog_class_trace_set ( void *o, const void *v ) -{ - atomic_set(&tvhlog_level, *(int *)v ? LOG_TRACE : LOG_DEBUG); +static int tvhlog_class_trace_set(void* o, const void* v) { + atomic_set(&tvhlog_level, *(int*)v ? LOG_TRACE : LOG_DEBUG); return 1; } -static const void * -tvhlog_class_libav_get ( void *o ) -{ +static const void* tvhlog_class_libav_get(void* o) { static int si; si = (tvhlog_options & TVHLOG_OPT_LIBAV) ? 1 : 0; return &si; } -static int -tvhlog_class_libav_set ( void *o, const void *v ) -{ +static int tvhlog_class_libav_set(void* o, const void* v) { tvh_mutex_lock(&tvhlog_mutex); - if (*(int *)v) + if (*(int*)v) tvhlog_options |= TVHLOG_OPT_LIBAV; else tvhlog_options &= ~TVHLOG_OPT_LIBAV; @@ -763,111 +710,104 @@ tvhlog_class_libav_set ( void *o, const void *v ) return 1; } -idnode_t tvhlog_conf = { - .in_class = &tvhlog_conf_class -}; +idnode_t tvhlog_conf = {.in_class = &tvhlog_conf_class}; CLASS_DOC(debugging) -const idclass_t tvhlog_conf_class = { - .ic_snode = &tvhlog_conf, - .ic_class = "tvhlog_conf", - .ic_caption = N_("Debugging"), - .ic_doc = tvh_doc_debugging_class, - .ic_event = "tvhlog_conf", - .ic_perm_def = ACCESS_ADMIN, - .ic_groups = (const property_group_t[]) { - { - .name = N_("General Settings"), - .number = 1, - }, - { - .name = N_("Subsystem Output Settings"), - .number = 2, - }, - { - .name = N_("Miscellaneous Settings"), - .number = 3, - }, - {} - }, - .ic_properties = (const property_t[]){ - { - .type = PT_STR, - .id = "path", - .name = N_("Filename (including path)"), - .desc = N_("Enter the filename (including path) where " - "Tvheadend should write the log."), - .get = tvhlog_class_path_get, - .set = tvhlog_class_path_set, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "enable_syslog", - .name = N_("Enable syslog"), - .desc = N_("Enable/disable logging to syslog."), - .get = tvhlog_class_enable_syslog_get, - .set = tvhlog_class_enable_syslog_set, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "syslog", - .name = N_("Debug to syslog"), - .desc = N_("Enable/disable debugging output to syslog."), - .get = tvhlog_class_debug_syslog_get, - .set = tvhlog_class_debug_syslog_set, - .group = 1, - }, - { - .type = PT_BOOL, - .id = "trace", - .name = N_("Debug trace (low-level)"), - .desc = N_("Enable/disable inclusion of low-level debug traces."), - .get = tvhlog_class_trace_get, - .set = tvhlog_class_trace_set, +const idclass_t tvhlog_conf_class = {.ic_snode = &tvhlog_conf, + .ic_class = "tvhlog_conf", + .ic_caption = N_("Debugging"), + .ic_doc = tvh_doc_debugging_class, + .ic_event = "tvhlog_conf", + .ic_perm_def = ACCESS_ADMIN, + .ic_groups = (const property_group_t[]){{ + .name = N_("General Settings"), + .number = 1, + }, + { + .name = N_("Subsystem Output Settings"), + .number = 2, + }, + { + .name = N_("Miscellaneous Settings"), + .number = 3, + }, + {}}, + .ic_properties = + (const property_t[]){{ + .type = PT_STR, + .id = "path", + .name = N_("Filename (including path)"), + .desc = N_("Enter the filename (including path) where " + "Tvheadend should write the log."), + .get = tvhlog_class_path_get, + .set = tvhlog_class_path_set, + .group = 1, + }, + { + .type = PT_BOOL, + .id = "enable_syslog", + .name = N_("Enable syslog"), + .desc = N_("Enable/disable logging to syslog."), + .get = tvhlog_class_enable_syslog_get, + .set = tvhlog_class_enable_syslog_set, + .group = 1, + }, + { + .type = PT_BOOL, + .id = "syslog", + .name = N_("Debug to syslog"), + .desc = N_("Enable/disable debugging output to syslog."), + .get = tvhlog_class_debug_syslog_get, + .set = tvhlog_class_debug_syslog_set, + .group = 1, + }, + { + .type = PT_BOOL, + .id = "trace", + .name = N_("Debug trace (low-level)"), + .desc = N_("Enable/disable inclusion of low-level debug traces."), + .get = tvhlog_class_trace_get, + .set = tvhlog_class_trace_set, #if !ENABLE_TRACE - .opts = PO_RDONLY | PO_HIDDEN, + .opts = PO_RDONLY | PO_HIDDEN, #endif - .group = 1, - }, - { - .type = PT_STR, - .id = "debugsubs", - .name = N_("Debug subsystems"), - .desc = N_("Enter comma-separated list of subsystems you want " - "debugging output for (e.g. " - "linuxdvb,subscription,mpegts)."), - .get = tvhlog_class_debugsubs_get, - .set = tvhlog_class_debugsubs_set, - .opts = PO_MULTILINE, - .group = 2, - }, - { - .type = PT_STR, - .id = "tracesubs", - .name = N_("Trace subsystems"), - .desc = N_("Enter comma-separated list of subsystems you want " - "to get traces for (e.g linuxdvb,subscription,mpegts)."), - .get = tvhlog_class_tracesubs_get, - .set = tvhlog_class_tracesubs_set, + .group = 1, + }, + { + .type = PT_STR, + .id = "debugsubs", + .name = N_("Debug subsystems"), + .desc = N_("Enter comma-separated list of subsystems you want " + "debugging output for (e.g. " + "linuxdvb,subscription,mpegts)."), + .get = tvhlog_class_debugsubs_get, + .set = tvhlog_class_debugsubs_set, + .opts = PO_MULTILINE, + .group = 2, + }, + { + .type = PT_STR, + .id = "tracesubs", + .name = N_("Trace subsystems"), + .desc = N_("Enter comma-separated list of subsystems you want " + "to get traces for (e.g linuxdvb,subscription,mpegts)."), + .get = tvhlog_class_tracesubs_get, + .set = tvhlog_class_tracesubs_set, #if !ENABLE_TRACE - .opts = PO_RDONLY | PO_HIDDEN | PO_MULTILINE, + .opts = PO_RDONLY | PO_HIDDEN | PO_MULTILINE, #else - .opts = PO_MULTILINE, + .opts = PO_MULTILINE, #endif - .group = 2, - }, - { - .type = PT_BOOL, - .id = "libav", - .name = N_("Debug libav log"), - .desc = N_("Enable/disable libav log output."), - .get = tvhlog_class_libav_get, - .set = tvhlog_class_libav_set, - .group = 3, - }, - {} - } -}; + .group = 2, + }, + { + .type = PT_BOOL, + .id = "libav", + .name = N_("Debug libav log"), + .desc = N_("Enable/disable libav log output."), + .get = tvhlog_class_libav_get, + .set = tvhlog_class_libav_set, + .group = 3, + }, + {}}}; diff --git a/src/tvhlog.h b/src/tvhlog.h index c69cd8fc9..af7604638 100644 --- a/src/tvhlog.h +++ b/src/tvhlog.h @@ -34,60 +34,68 @@ typedef struct { int64_t last; - size_t count; + size_t count; } tvhlog_limit_t; typedef struct { - const char *name; - const char *desc; + const char* name; + const char* desc; } tvhlog_subsys_t; /* Config */ -extern int tvhlog_level; -extern char *tvhlog_path; -extern int tvhlog_options; -extern tvh_mutex_t tvhlog_mutex; -extern tvhlog_subsys_t tvhlog_subsystems[]; +extern int tvhlog_level; +extern char* tvhlog_path; +extern int tvhlog_options; +extern tvh_mutex_t tvhlog_mutex; +extern tvhlog_subsys_t tvhlog_subsystems[]; /* Initialise */ -void tvhlog_init ( int level, int options, const char *path ); -void tvhlog_start ( void ); -void tvhlog_end ( void ); -void tvhlog_set_debug ( const char *subsys ); -void tvhlog_get_debug ( char *subsys, size_t len ); -void tvhlog_set_trace ( const char *subsys ); -void tvhlog_get_trace ( char *subsys, size_t len ); -void tvhlogv ( const char *file, int line, int severity, - int subsys, const char *fmt, va_list *args ); -void _tvhlog ( const char *file, int line, int severity, - int subsys, const char *fmt, ... ) - __attribute__((format(printf,5,6))); -void _tvhlog_hexdump ( const char *file, int line, int severity, - int subsys, const uint8_t *data, ssize_t len ); -static inline void tvhlog_limit_reset ( tvhlog_limit_t *limit ) - { limit->last = 0; limit->count = 0; } -static inline int tvhlog_limit ( tvhlog_limit_t *limit, uint32_t delay ) - { int64_t t = mclk(); limit->count++; - if (limit->last + sec2mono(delay) < t) { limit->last = t; return 1; } - return 0; } - +void tvhlog_init(int level, int options, const char* path); +void tvhlog_start(void); +void tvhlog_end(void); +void tvhlog_set_debug(const char* subsys); +void tvhlog_get_debug(char* subsys, size_t len); +void tvhlog_set_trace(const char* subsys); +void tvhlog_get_trace(char* subsys, size_t len); +void tvhlogv(const char* file, int line, int severity, int subsys, const char* fmt, va_list* args); +void _tvhlog(const char* file, int line, int severity, int subsys, const char* fmt, ...) + __attribute__((format(printf, 5, 6))); +void _tvhlog_hexdump(const char* file, + int line, + int severity, + int subsys, + const uint8_t* data, + ssize_t len); +static inline void tvhlog_limit_reset(tvhlog_limit_t* limit) { + limit->last = 0; + limit->count = 0; +} +static inline int tvhlog_limit(tvhlog_limit_t* limit, uint32_t delay) { + int64_t t = mclk(); + limit->count++; + if (limit->last + sec2mono(delay) < t) { + limit->last = t; + return 1; + } + return 0; +} /* Options */ -#define TVHLOG_OPT_DBG_SYSLOG 0x0001 -#define TVHLOG_OPT_DBG_STDERR 0x0002 -#define TVHLOG_OPT_DBG_FILE 0x0004 -#define TVHLOG_OPT_SYSLOG 0x0010 -#define TVHLOG_OPT_STDERR 0x0020 -#define TVHLOG_OPT_MILLIS 0x0100 -#define TVHLOG_OPT_DECORATE 0x0200 -#define TVHLOG_OPT_FILELINE 0x0400 -#define TVHLOG_OPT_THREAD 0x0800 -#define TVHLOG_OPT_LIBAV 0x1000 -#define TVHLOG_OPT_ALL 0xFFFF +#define TVHLOG_OPT_DBG_SYSLOG 0x0001 +#define TVHLOG_OPT_DBG_STDERR 0x0002 +#define TVHLOG_OPT_DBG_FILE 0x0004 +#define TVHLOG_OPT_SYSLOG 0x0010 +#define TVHLOG_OPT_STDERR 0x0020 +#define TVHLOG_OPT_MILLIS 0x0100 +#define TVHLOG_OPT_DECORATE 0x0200 +#define TVHLOG_OPT_FILELINE 0x0400 +#define TVHLOG_OPT_THREAD 0x0800 +#define TVHLOG_OPT_LIBAV 0x1000 +#define TVHLOG_OPT_ALL 0xFFFF /* Levels */ #ifndef LOG_TRACE -#define LOG_TRACE (LOG_DEBUG+1) +#define LOG_TRACE (LOG_DEBUG + 1) #endif #define LOG_TVH_NOTIFY 0x40000000 @@ -200,57 +208,67 @@ enum { #endif LS_UDP, LS_RATINGLABELS, - LS_LAST /* keep this last */ + LS_LAST /* keep this last */ }; /* Macros */ -#define tvhlog(severity, subsys, fmt, ...)\ +#define tvhlog(severity, subsys, fmt, ...) \ _tvhlog(__FILE__, __LINE__, severity | LOG_TVH_NOTIFY, subsys, fmt, ##__VA_ARGS__) -#define tvhlog_spawn(severity, subsys, fmt, ...)\ +#define tvhlog_spawn(severity, subsys, fmt, ...) \ _tvhlog(__FILE__, __LINE__, severity, subsys, fmt, ##__VA_ARGS__) #if ENABLE_TRACE #define tvhtrace_enabled() (LOG_TRACE <= atomic_get(&tvhlog_level)) -#define tvhtrace(subsys, fmt, ...) \ - do { \ - if (tvhtrace_enabled()) \ +#define tvhtrace(subsys, fmt, ...) \ + do { \ + if (tvhtrace_enabled()) \ _tvhlog(__FILE__, __LINE__, LOG_TRACE, subsys, fmt, ##__VA_ARGS__); \ } while (0) -#define tvhlog_hexdump(subsys, data, len) \ - do { \ - if (tvhtrace_enabled()) \ +#define tvhlog_hexdump(subsys, data, len) \ + do { \ + if (tvhtrace_enabled()) \ _tvhlog_hexdump(__FILE__, __LINE__, LOG_TRACE, subsys, (uint8_t*)data, len); \ } while (0) #else -static inline void tvhtrace_no_warnings(const char *fmt, ...) { (void)fmt; } +static inline void tvhtrace_no_warnings(const char* fmt, ...) { + (void)fmt; +} #define tvhtrace_enabled() 0 -#define tvhtrace(subsys, fmt, ...) do { tvhtrace_no_warnings(NULL, subsys, fmt, ##__VA_ARGS__); } while (0) -#define tvhlog_hexdump(subsys, data, len) do { tvhtrace_no_warnings(NULL, subsys, data, len); } while (0) +#define tvhtrace(subsys, fmt, ...) \ + do { \ + tvhtrace_no_warnings(NULL, subsys, fmt, ##__VA_ARGS__); \ + } while (0) +#define tvhlog_hexdump(subsys, data, len) \ + do { \ + tvhtrace_no_warnings(NULL, subsys, data, len); \ + } while (0) #endif -#define tvhftrace(subsys, fcn, ...) do { \ - tvhtrace(subsys, "%s() enter", #fcn); \ - fcn(__VA_ARGS__); \ - tvhtrace(subsys, "%s() leave", #fcn); \ -} while (0) +#define tvhftrace(subsys, fcn, ...) \ + do { \ + tvhtrace(subsys, "%s() enter", #fcn); \ + fcn(__VA_ARGS__); \ + tvhtrace(subsys, "%s() leave", #fcn); \ + } while (0) -#define tvhdebug(...) tvhlog(LOG_DEBUG, ##__VA_ARGS__) -#define tvhinfo(...) tvhlog(LOG_INFO, ##__VA_ARGS__) +#define tvhdebug(...) tvhlog(LOG_DEBUG, ##__VA_ARGS__) +#define tvhinfo(...) tvhlog(LOG_INFO, ##__VA_ARGS__) #define tvhwarn(...) tvhlog(LOG_WARNING, ##__VA_ARGS__) -#define tvhnotice(...) tvhlog(LOG_NOTICE, ##__VA_ARGS__) -#define tvherror(...) tvhlog(LOG_ERR, ##__VA_ARGS__) -#define tvhalert(...) tvhlog(LOG_ALERT, ##__VA_ARGS__) -#define tvhabort(...) do { \ - tvhlog(LOG_ALERT, ##__VA_ARGS__); \ - tvh_safe_usleep(2000000); \ - abort(); \ -} while (0) +#define tvhnotice(...) tvhlog(LOG_NOTICE, ##__VA_ARGS__) +#define tvherror(...) tvhlog(LOG_ERR, ##__VA_ARGS__) +#define tvhalert(...) tvhlog(LOG_ALERT, ##__VA_ARGS__) +#define tvhabort(...) \ + do { \ + tvhlog(LOG_ALERT, ##__VA_ARGS__); \ + tvh_safe_usleep(2000000); \ + abort(); \ + } while (0) -void tvhlog_backtrace_printf(const char *fmt, ...); +void tvhlog_backtrace_printf(const char* fmt, ...); #if ENABLE_TRACE -void tvhdbg(int subsys, const char *fmt, ...); +void tvhdbg(int subsys, const char* fmt, ...); #else -static inline void tvhdbg(int subsys, const char *fmt, ...) {}; +static inline void tvhdbg(int subsys, const char* fmt, ...) {}; #endif #endif /* __TVH_LOGGING_H__ */ diff --git a/src/tvhpoll.c b/src/tvhpoll.c index 71db7036f..f602d0582 100644 --- a/src/tvhpoll.c +++ b/src/tvhpoll.c @@ -39,60 +39,51 @@ #define EV_SIZE sizeof(struct kevent) #endif -struct tvhpoll -{ +struct tvhpoll { tvh_mutex_t lock; #if ENABLE_TRACE int trace_subsys; int trace_type; #endif - uint8_t *events; + uint8_t* events; uint32_t events_off; uint32_t nevents; #if ENABLE_EPOLL - int fd; - struct epoll_event *ev; - uint32_t nev; + int fd; + struct epoll_event* ev; + uint32_t nev; #elif ENABLE_KQUEUE - int fd; - struct kevent *ev; - uint32_t nev; + int fd; + struct kevent* ev; + uint32_t nev; #else #endif }; -static void -tvhpoll_alloc_events ( tvhpoll_t *tp, int fd ) -{ - tp->events = calloc(1, tp->nevents = 8); +static void tvhpoll_alloc_events(tvhpoll_t* tp, int fd) { + tp->events = calloc(1, tp->nevents = 8); tp->events_off = fd; } -static void -tvhpoll_realloc_events1 ( tvhpoll_t *tp, int fd ) -{ +static void tvhpoll_realloc_events1(tvhpoll_t* tp, int fd) { uint32_t diff = tp->events_off - fd; - uint8_t *evs = malloc(tp->nevents + diff); + uint8_t* evs = malloc(tp->nevents + diff); memset(evs, 0, diff); memcpy(evs + diff, tp->events, tp->nevents); free(tp->events); - tp->events = evs; + tp->events = evs; tp->events_off = fd; tp->nevents += diff; } -static void -tvhpoll_realloc_events2 ( tvhpoll_t *tp, int fd ) -{ +static void tvhpoll_realloc_events2(tvhpoll_t* tp, int fd) { uint32_t size = (fd - tp->events_off) + 4; - tp->events = realloc(tp->events, size); + tp->events = realloc(tp->events, size); memset(tp->events + tp->nevents, 0, size - tp->nevents); tp->nevents = size; } -static inline void -tvhpoll_set_events ( tvhpoll_t *tp, int fd, uint32_t events ) -{ +static inline void tvhpoll_set_events(tvhpoll_t* tp, int fd, uint32_t events) { if (tp->nevents == 0) { tvhpoll_alloc_events(tp, fd); } else if (fd < tp->events_off) { @@ -104,9 +95,7 @@ tvhpoll_set_events ( tvhpoll_t *tp, int fd, uint32_t events ) tp->events[fd - tp->events_off] = events; } -static inline uint32_t -tvhpoll_get_events( tvhpoll_t *tp, int fd ) -{ +static inline uint32_t tvhpoll_get_events(tvhpoll_t* tp, int fd) { const uint32_t off = tp->events_off; if (fd < off) return 0; @@ -116,9 +105,7 @@ tvhpoll_get_events( tvhpoll_t *tp, int fd ) return tp->events[fd]; } -static void -tvhpoll_alloc ( tvhpoll_t *tp, uint32_t n ) -{ +static void tvhpoll_alloc(tvhpoll_t* tp, uint32_t n) { #if ENABLE_EPOLL || ENABLE_KQUEUE if (n > tp->nev) { tp->ev = realloc(tp->ev, n * EV_SIZE); @@ -128,9 +115,7 @@ tvhpoll_alloc ( tvhpoll_t *tp, uint32_t n ) #endif } -tvhpoll_t * -tvhpoll_create ( size_t n ) -{ +tvhpoll_t* tvhpoll_create(size_t n) { int fd; #if ENABLE_EPOLL if ((fd = epoll_create1(EPOLL_CLOEXEC)) < 0) { @@ -145,15 +130,14 @@ tvhpoll_create ( size_t n ) #else fd = -1; #endif - tvhpoll_t *tp = calloc(1, sizeof(tvhpoll_t)); + tvhpoll_t* tp = calloc(1, sizeof(tvhpoll_t)); tvh_mutex_init(&tp->lock, NULL); tp->fd = fd; tvhpoll_alloc(tp, n); return tp; } -void tvhpoll_destroy ( tvhpoll_t *tp ) -{ +void tvhpoll_destroy(tvhpoll_t* tp) { if (tp == NULL) return; #if ENABLE_EPOLL || ENABLE_KQUEUE @@ -165,37 +149,44 @@ void tvhpoll_destroy ( tvhpoll_t *tp ) free(tp); } -void tvhpoll_set_trace ( tvhpoll_t *tp, int subsys, int type ) -{ +void tvhpoll_set_trace(tvhpoll_t* tp, int subsys, int type) { #if ENABLE_TRACE assert(type == 0 || type == 1); tp->trace_subsys = subsys; - tp->trace_type = type; + tp->trace_type = type; #endif } -static int tvhpoll_add0 - ( tvhpoll_t *tp, tvhpoll_event_t *evs, size_t num ) -{ +static int tvhpoll_add0(tvhpoll_t* tp, tvhpoll_event_t* evs, size_t num) { #if ENABLE_EPOLL int i; for (i = 0; i < num; i++) { - struct epoll_event ev = { 0 }; - const int fd = evs[i].fd; - const uint32_t events = evs[i].events; - const uint32_t oevents = tvhpoll_get_events(tp, fd); - if (oevents == events) continue; + struct epoll_event ev = {0}; + const int fd = evs[i].fd; + const uint32_t events = evs[i].events; + const uint32_t oevents = tvhpoll_get_events(tp, fd); + if (oevents == events) + continue; ev.data.ptr = evs[i].ptr; - if (events & TVHPOLL_IN) ev.events |= EPOLLIN; - if (events & TVHPOLL_OUT) ev.events |= EPOLLOUT; - if (events & TVHPOLL_PRI) ev.events |= EPOLLPRI; - if (events & TVHPOLL_ERR) ev.events |= EPOLLERR; - if (events & TVHPOLL_HUP) ev.events |= EPOLLHUP; + if (events & TVHPOLL_IN) + ev.events |= EPOLLIN; + if (events & TVHPOLL_OUT) + ev.events |= EPOLLOUT; + if (events & TVHPOLL_PRI) + ev.events |= EPOLLPRI; + if (events & TVHPOLL_ERR) + ev.events |= EPOLLERR; + if (events & TVHPOLL_HUP) + ev.events |= EPOLLHUP; if (oevents) { #if ENABLE_TRACE if (tp->trace_type == 1) - tvhtrace(tp->trace_subsys, "epoll mod: fd=%d events=%x oevents=%x ptr=%p", - fd, events, oevents, evs[i].ptr); + tvhtrace(tp->trace_subsys, + "epoll mod: fd=%d events=%x oevents=%x ptr=%p", + fd, + events, + oevents, + evs[i].ptr); #endif if (epoll_ctl(tp->fd, EPOLL_CTL_MOD, fd, &ev)) { tvherror(LS_TVHPOLL, "epoll mod failed [%s]", strerror(errno)); @@ -204,8 +195,7 @@ static int tvhpoll_add0 } else { #if ENABLE_TRACE if (tp->trace_type == 1) - tvhtrace(tp->trace_subsys, "epoll add: fd=%d events=%x ptr=%p", - fd, events, evs[i].ptr); + tvhtrace(tp->trace_subsys, "epoll add: fd=%d events=%x ptr=%p", fd, events, evs[i].ptr); #endif if (epoll_ctl(tp->fd, EPOLL_CTL_ADD, fd, &ev)) { tvherror(LS_TVHPOLL, "epoll add failed [%s]", strerror(errno)); @@ -216,14 +206,15 @@ static int tvhpoll_add0 } return i >= num ? 0 : -1; #elif ENABLE_KQUEUE - int i, j; - struct kevent *ev = alloca(EV_SIZE * num * 2); + int i, j; + struct kevent* ev = alloca(EV_SIZE * num * 2); for (i = j = 0; i < num; i++) { - const int fd = evs[i].fd; - void *ptr = evs[i].ptr; - const uint32_t events = evs[i].events; + const int fd = evs[i].fd; + void* ptr = evs[i].ptr; + const uint32_t events = evs[i].events; const uint32_t oevents = tvhpoll_get_events(tp, fd); - if (events == oevents) continue; + if (events == oevents) + continue; tvhpoll_set_events(tp, fd, events); /* Unlike poll, the kevent is not a bitmask (on FreeBSD, * EVILT_READ=-1, EVFILT_WRITE=-2). That means if you OR them @@ -231,17 +222,17 @@ static int tvhpoll_add0 * register them separately here. */ if (events & TVHPOLL_OUT) { - EV_SET(ev+j, fd, EVFILT_WRITE, EV_ADD, 0, 0, ptr); + EV_SET(ev + j, fd, EVFILT_WRITE, EV_ADD, 0, 0, ptr); j++; } else if (oevents & TVHPOLL_OUT) { - EV_SET(ev+j, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); + EV_SET(ev + j, fd, EVFILT_WRITE, EV_DELETE, 0, 0, NULL); j++; } if (events & TVHPOLL_IN) { - EV_SET(ev+j, fd, EVFILT_READ, EV_ADD, 0, 0, ptr); + EV_SET(ev + j, fd, EVFILT_READ, EV_ADD, 0, 0, ptr); j++; } else if (oevents & TVHPOLL_IN) { - EV_SET(ev+j, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); + EV_SET(ev + j, fd, EVFILT_READ, EV_DELETE, 0, 0, NULL); j++; } } @@ -251,9 +242,7 @@ static int tvhpoll_add0 #endif } -int tvhpoll_add - ( tvhpoll_t *tp, tvhpoll_event_t *evs, size_t num ) -{ +int tvhpoll_add(tvhpoll_t* tp, tvhpoll_event_t* evs, size_t num) { int r; tvh_mutex_lock(&tp->lock); @@ -262,19 +251,15 @@ int tvhpoll_add return r; } -int tvhpoll_add1 - ( tvhpoll_t *tp, int fd, uint32_t events, void *ptr ) -{ - tvhpoll_event_t ev = { 0 }; - ev.fd = fd; - ev.events = events; - ev.ptr = ptr; +int tvhpoll_add1(tvhpoll_t* tp, int fd, uint32_t events, void* ptr) { + tvhpoll_event_t ev = {0}; + ev.fd = fd; + ev.events = events; + ev.ptr = ptr; return tvhpoll_add(tp, &ev, 1); } -static int tvhpoll_rem0 - ( tvhpoll_t *tp, tvhpoll_event_t *evs, size_t num ) -{ +static int tvhpoll_rem0(tvhpoll_t* tp, tvhpoll_event_t* evs, size_t num) { int r = -1; #if ENABLE_EPOLL int i; @@ -283,8 +268,7 @@ static int tvhpoll_rem0 if (tvhpoll_get_events(tp, fd)) { #if ENABLE_TRACE if (tp->trace_type == 1) - tvhtrace(tp->trace_subsys, "epoll rem: fd=%d events=%x", - fd, tvhpoll_get_events(tp, fd)); + tvhtrace(tp->trace_subsys, "epoll rem: fd=%d events=%x", fd, tvhpoll_get_events(tp, fd)); #endif if (epoll_ctl(tp->fd, EPOLL_CTL_DEL, fd, NULL)) { tvherror(LS_TVHPOLL, "epoll del failed [%s]", strerror(errno)); @@ -296,12 +280,12 @@ static int tvhpoll_rem0 if (i >= num) r = 0; #elif ENABLE_KQUEUE - int i, j; - struct kevent *ev = alloca(EV_SIZE * num); + int i, j; + struct kevent* ev = alloca(EV_SIZE * num); for (i = j = 0; i < num; i++) { const int fd = evs[i].fd; if (tvhpoll_get_events(tp, fd)) { - EV_SET(ev+j, fd, 0, EV_DELETE, 0, 0, NULL); + EV_SET(ev + j, fd, 0, EV_DELETE, 0, 0, NULL); j++; } } @@ -315,9 +299,7 @@ static int tvhpoll_rem0 return r; } -int tvhpoll_rem - ( tvhpoll_t *tp, tvhpoll_event_t *evs, size_t num ) -{ +int tvhpoll_rem(tvhpoll_t* tp, tvhpoll_event_t* evs, size_t num) { int r; tvh_mutex_lock(&tp->lock); @@ -326,19 +308,15 @@ int tvhpoll_rem return r; } -int tvhpoll_rem1 - ( tvhpoll_t *tp, int fd ) -{ - tvhpoll_event_t ev = { 0 }; - ev.fd = fd; +int tvhpoll_rem1(tvhpoll_t* tp, int fd) { + tvhpoll_event_t ev = {0}; + ev.fd = fd; return tvhpoll_rem(tp, &ev, 1); } -int tvhpoll_set - ( tvhpoll_t *tp, tvhpoll_event_t *evs, size_t num ) -{ +int tvhpoll_set(tvhpoll_t* tp, tvhpoll_event_t* evs, size_t num) { tvhpoll_event_t *lev, *ev; - int i, j, k, r; + int i, j, k, r; tvh_mutex_lock(&tp->lock); lev = alloca(tp->nevents * sizeof(*lev)); for (i = k = 0; i < tp->nevents; i++) @@ -349,9 +327,9 @@ int tvhpoll_set if (j >= num) { ev = lev + k; k++; - ev->fd = i + tp->events_off; + ev->fd = i + tp->events_off; ev->events = tp->events[i]; - ev->ptr = 0; + ev->ptr = 0; } } r = tvhpoll_rem0(tp, lev, k); @@ -361,9 +339,7 @@ int tvhpoll_set return r; } -int tvhpoll_wait - ( tvhpoll_t *tp, tvhpoll_event_t *evs, size_t num, int ms ) -{ +int tvhpoll_wait(tvhpoll_t* tp, tvhpoll_event_t* evs, size_t num, int ms) { int nfds = 0, i; tvhpoll_alloc(tp, num); #if ENABLE_EPOLL @@ -371,14 +347,19 @@ int tvhpoll_wait for (i = 0; i < nfds; i++) { uint32_t events1 = tp->ev[i].events; uint32_t events2 = 0; - if (events1 & EPOLLIN) events2 |= TVHPOLL_IN; - if (events1 & EPOLLOUT) events2 |= TVHPOLL_OUT; - if (events1 & EPOLLERR) events2 |= TVHPOLL_ERR; - if (events1 & EPOLLPRI) events2 |= TVHPOLL_PRI; - if (events1 & EPOLLHUP) events2 |= TVHPOLL_HUP; + if (events1 & EPOLLIN) + events2 |= TVHPOLL_IN; + if (events1 & EPOLLOUT) + events2 |= TVHPOLL_OUT; + if (events1 & EPOLLERR) + events2 |= TVHPOLL_ERR; + if (events1 & EPOLLPRI) + events2 |= TVHPOLL_PRI; + if (events1 & EPOLLHUP) + events2 |= TVHPOLL_HUP; evs[i].events = events2; - evs[i].fd = -1; - evs[i].ptr = tp->ev[i].data.ptr; + evs[i].fd = -1; + evs[i].ptr = tp->ev[i].data.ptr; #if ENABLE_TRACE if (tp->trace_type == 1) tvhtrace(tp->trace_subsys, "epoll wait: events=%x ptr=%p", events2, tp->ev[i].data.ptr); @@ -389,17 +370,22 @@ int tvhpoll_wait if (ms > 0) { tm.tv_sec = ms / 1000; tm.tv_nsec = (ms % 1000) * 1000000LL; - to = &tm; + to = &tm; } nfds = kevent(tp->fd, NULL, 0, tp->ev, num, to); for (i = 0; i < nfds; i++) { uint32_t events2 = 0; - if (tp->ev[i].filter == EVFILT_WRITE) events2 |= TVHPOLL_OUT; - if (tp->ev[i].filter == EVFILT_READ) events2 |= TVHPOLL_IN; - if (tp->ev[i].flags & EV_ERROR) events2 |= TVHPOLL_ERR; - if (tp->ev[i].flags & EV_EOF) events2 |= TVHPOLL_HUP; + if (tp->ev[i].filter == EVFILT_WRITE) + events2 |= TVHPOLL_OUT; + if (tp->ev[i].filter == EVFILT_READ) + events2 |= TVHPOLL_IN; + if (tp->ev[i].flags & EV_ERROR) + events2 |= TVHPOLL_ERR; + if (tp->ev[i].flags & EV_EOF) + events2 |= TVHPOLL_HUP; evs[i].events = events2; - evs[i].fd = -1; /* tp->ev[i].ident */; + evs[i].fd = -1; /* tp->ev[i].ident */ + ; evs[i].ptr = tp->ev[i].udata; } #else diff --git a/src/tvhpoll.h b/src/tvhpoll.h index a76970b90..52c802842 100644 --- a/src/tvhpoll.h +++ b/src/tvhpoll.h @@ -25,11 +25,10 @@ #include typedef struct tvhpoll tvhpoll_t; -typedef struct tvhpoll_event -{ - int fd; // input - uint32_t events; - void *ptr; +typedef struct tvhpoll_event { + int fd; // input + uint32_t events; + void* ptr; } tvhpoll_event_t; #define TVHPOLL_IN 0x01 @@ -38,27 +37,29 @@ typedef struct tvhpoll_event #define TVHPOLL_ERR 0x08 #define TVHPOLL_HUP 0x10 -static inline -tvhpoll_event_t *tvhpoll_event - (tvhpoll_event_t *ev, int fd, uint32_t events, void *ptr) -{ - ev->fd = fd; ev->events = events; ev->ptr = ptr; return ev; +static inline tvhpoll_event_t* +tvhpoll_event(tvhpoll_event_t* ev, int fd, uint32_t events, void* ptr) { + ev->fd = fd; + ev->events = events; + ev->ptr = ptr; + return ev; } -static inline -tvhpoll_event_t *tvhpoll_event1(tvhpoll_event_t *ev, int fd) -{ - ev->fd = fd; ev->events = 0; ev->ptr = NULL; return ev; +static inline tvhpoll_event_t* tvhpoll_event1(tvhpoll_event_t* ev, int fd) { + ev->fd = fd; + ev->events = 0; + ev->ptr = NULL; + return ev; } -tvhpoll_t *tvhpoll_create(size_t num); -void tvhpoll_destroy(tvhpoll_t *tp); -void tvhpoll_set_trace(tvhpoll_t *tp, int subsys, int trace); -int tvhpoll_set(tvhpoll_t *tp, tvhpoll_event_t *evs, size_t num); -int tvhpoll_add(tvhpoll_t *tp, tvhpoll_event_t *evs, size_t num); -int tvhpoll_add1(tvhpoll_t *tp, int fd, uint32_t events, void *ptr); -int tvhpoll_rem(tvhpoll_t *tp, tvhpoll_event_t *evs, size_t num); -int tvhpoll_rem1(tvhpoll_t *tp, int fd); -int tvhpoll_wait(tvhpoll_t *tp, tvhpoll_event_t *evs, size_t num, int ms); +tvhpoll_t* tvhpoll_create(size_t num); +void tvhpoll_destroy(tvhpoll_t* tp); +void tvhpoll_set_trace(tvhpoll_t* tp, int subsys, int trace); +int tvhpoll_set(tvhpoll_t* tp, tvhpoll_event_t* evs, size_t num); +int tvhpoll_add(tvhpoll_t* tp, tvhpoll_event_t* evs, size_t num); +int tvhpoll_add1(tvhpoll_t* tp, int fd, uint32_t events, void* ptr); +int tvhpoll_rem(tvhpoll_t* tp, tvhpoll_event_t* evs, size_t num); +int tvhpoll_rem1(tvhpoll_t* tp, int fd); +int tvhpoll_wait(tvhpoll_t* tp, tvhpoll_event_t* evs, size_t num, int ms); #endif /* __TVHPOLL_H__ */ diff --git a/src/tvhregex.h b/src/tvhregex.h index b7b8ec1d3..1e50ab4dc 100644 --- a/src/tvhregex.h +++ b/src/tvhregex.h @@ -21,58 +21,58 @@ #if ENABLE_PCRE -# include -# ifndef PCRE_STUDY_JIT_COMPILE -# define PCRE_STUDY_JIT_COMPILE 0 -# endif +#include +#ifndef PCRE_STUDY_JIT_COMPILE +#define PCRE_STUDY_JIT_COMPILE 0 +#endif -#define TVHREGEX_TYPE "pcre1" +#define TVHREGEX_TYPE "pcre1" #elif ENABLE_PCRE2 -# define PCRE2_CODE_UNIT_WIDTH 8 -# include +#define PCRE2_CODE_UNIT_WIDTH 8 +#include -#define TVHREGEX_TYPE "pcre2" +#define TVHREGEX_TYPE "pcre2" #endif -# include +#include -#define TVHREGEX_MAX_MATCHES 10 +#define TVHREGEX_MAX_MATCHES 10 /* Compile flags */ -#define TVHREGEX_POSIX 1 /* Use POSIX regex engine */ -#define TVHREGEX_CASELESS 2 /* Use case-insensitive matching */ +#define TVHREGEX_POSIX 1 /* Use POSIX regex engine */ +#define TVHREGEX_CASELESS 2 /* Use case-insensitive matching */ typedef struct { #if ENABLE_PCRE - pcre *re_code; - pcre_extra *re_extra; - int re_match[TVHREGEX_MAX_MATCHES * 3]; - const char *re_text; - int re_matches; + pcre* re_code; + pcre_extra* re_extra; + int re_match[TVHREGEX_MAX_MATCHES * 3]; + const char* re_text; + int re_matches; #if PCRE_STUDY_JIT_COMPILE - pcre_jit_stack *re_jit_stack; + pcre_jit_stack* re_jit_stack; #endif #elif ENABLE_PCRE2 - pcre2_code *re_code; - pcre2_match_data *re_match; - pcre2_match_context *re_mcontext; - pcre2_jit_stack *re_jit_stack; + pcre2_code* re_code; + pcre2_match_data* re_match; + pcre2_match_context* re_mcontext; + pcre2_jit_stack* re_jit_stack; #endif - regex_t re_posix_code; - regmatch_t re_posix_match[TVHREGEX_MAX_MATCHES]; - const char *re_posix_text; + regex_t re_posix_code; + regmatch_t re_posix_match[TVHREGEX_MAX_MATCHES]; + const char* re_posix_text; #if ENABLE_PCRE || ENABLE_PCRE2 int is_posix; #endif } tvh_regex_t; -void regex_free(tvh_regex_t *regex); -int regex_compile(tvh_regex_t *regex, const char *re_str, int flags, int subsys); -int regex_match(tvh_regex_t *regex, const char *str); -int regex_match_substring(tvh_regex_t *regex, unsigned number, char *buf, size_t size_buf); -int regex_match_substring_length(tvh_regex_t *regex, unsigned number); +void regex_free(tvh_regex_t* regex); +int regex_compile(tvh_regex_t* regex, const char* re_str, int flags, int subsys); +int regex_match(tvh_regex_t* regex, const char* str); +int regex_match_substring(tvh_regex_t* regex, unsigned number, char* buf, size_t size_buf); +int regex_match_substring_length(tvh_regex_t* regex, unsigned number); #endif /* __TVHREGEX_H__ */ diff --git a/src/tvhtime.c b/src/tvhtime.c index 82c910da0..84ea924f8 100644 --- a/src/tvhtime.c +++ b/src/tvhtime.c @@ -18,20 +18,19 @@ /* * NTP processing */ -#define NTPD_BASE 0x4e545030 /* "NTP0" */ -#define NTPD_UNIT 2 +#define NTPD_BASE 0x4e545030 /* "NTP0" */ +#define NTPD_UNIT 2 #if !ENABLE_ANDROID -typedef struct -{ - int mode; /* 0 - if valid set - * use values, - * clear valid - * 1 - if valid set - * if count before and after read of values is equal, - * use values - * clear valid - */ +typedef struct { + int mode; /* 0 - if valid set + * use values, + * clear valid + * 1 - if valid set + * if count before and after read of values is equal, + * use values + * clear valid + */ int count; time_t clockTimeStampSec; int clockTimeStampUSec; @@ -44,11 +43,9 @@ typedef struct int pad[10]; } ntp_shm_t; -static ntp_shm_t * -ntp_shm_init ( void ) -{ - int shmid, unit, mode; - static ntp_shm_t *shmptr = NULL; +static ntp_shm_t* ntp_shm_init(void) { + int shmid, unit, mode; + static ntp_shm_t* shmptr = NULL; if (shmptr != NULL) return shmptr; @@ -76,21 +73,24 @@ ntp_shm_init ( void ) /* * Update time */ -void -tvhtime_update ( time_t utc, const char *srcname ) -{ +void tvhtime_update(time_t utc, const char* srcname) { #if !ENABLE_ANDROID - struct tm tm; + struct tm tm; struct timeval tv; - ntp_shm_t *ntp_shm; - int64_t t1, t2, diff; + ntp_shm_t* ntp_shm; + int64_t t1, t2, diff; localtime_r(&utc, &tm); - tvhtrace(LS_TIME, "%s - current time is %04d/%02d/%02d %02d:%02d:%02d", - srcname, - tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec); + tvhtrace(LS_TIME, + "%s - current time is %04d/%02d/%02d %02d:%02d:%02d", + srcname, + tm.tm_year + 1900, + tm.tm_mon + 1, + tm.tm_mday, + tm.tm_hour, + tm.tm_min, + tm.tm_sec); gettimeofday(&tv, NULL); @@ -110,7 +110,7 @@ tvhtime_update ( time_t utc, const char *srcname ) tvhnotice(LS_TIME, "%s - stime(2) not implemented", srcname); #endif } else { - tvhwarn(LS_TIME, "%s - time not updated (diff %"PRId64")", srcname, diff); + tvhwarn(LS_TIME, "%s - time not updated (diff %" PRId64 ")", srcname, diff); } } @@ -119,7 +119,7 @@ tvhtime_update ( time_t utc, const char *srcname ) if (!(ntp_shm = ntp_shm_init())) return; - tvhtrace(LS_TIME, "ntp delta = %"PRId64" us\n", t2 - t1); + tvhtrace(LS_TIME, "ntp delta = %" PRId64 " us\n", t2 - t1); ntp_shm->valid = 0; ntp_shm->count++; ntp_shm->clockTimeStampSec = utc; @@ -133,8 +133,7 @@ tvhtime_update ( time_t utc, const char *srcname ) } /* Initialise */ -void tvhtime_init ( void ) -{ +void tvhtime_init(void) { if (config.tvhtime_tolerance == 0) config.tvhtime_tolerance = 5000; } diff --git a/src/tvhtime.h b/src/tvhtime.h index 4bff0dd14..98d2ab0d4 100644 --- a/src/tvhtime.h +++ b/src/tvhtime.h @@ -22,7 +22,7 @@ #include "idnode.h" -void tvhtime_init ( void ); -void tvhtime_update ( time_t utc, const char *srcname ); +void tvhtime_init(void); +void tvhtime_update(time_t utc, const char* srcname); #endif /* __TVH_TIME_H__ */ diff --git a/src/tvhvfs.c b/src/tvhvfs.c index 0be2592a3..be5f58097 100644 --- a/src/tvhvfs.c +++ b/src/tvhvfs.c @@ -22,10 +22,9 @@ #endif #include -int tvh_vfs_fsid_build(const char *path, struct statvfs *vfs, tvh_fsid_t *dst) -{ +int tvh_vfs_fsid_build(const char* path, struct statvfs* vfs, tvh_fsid_t* dst) { struct statvfs _vfs; - struct stat st; + struct stat st; if (vfs == NULL) vfs = &_vfs; @@ -33,7 +32,7 @@ int tvh_vfs_fsid_build(const char *path, struct statvfs *vfs, tvh_fsid_t *dst) if (statvfs(path, vfs) == -1) return -1; - dst->fsid = tvh_fsid(vfs->f_fsid); + dst->fsid = tvh_fsid(vfs->f_fsid); dst->id[0] = '\0'; if (dst->fsid == 0) { if (stat(path, &st) == -1) diff --git a/src/tvhvfs.h b/src/tvhvfs.h index 5a33672f6..695f4882a 100644 --- a/src/tvhvfs.h +++ b/src/tvhvfs.h @@ -21,8 +21,8 @@ #if ENABLE_ANDROID #include -#define statvfs statfs -#define fstatvfs fstatfs +#define statvfs statfs +#define fstatvfs fstatfs #define tvh_fsid(x) (((uint64_t)x.__val[0] << 32) | (x.__val[1])) #else #include @@ -33,13 +33,12 @@ struct statvfs; typedef struct { uint64_t fsid; - char id[64]; + char id[64]; } tvh_fsid_t; -int tvh_vfs_fsid_build(const char *path, struct statvfs *vfs, tvh_fsid_t *dst); +int tvh_vfs_fsid_build(const char* path, struct statvfs* vfs, tvh_fsid_t* dst); -static inline int tvh_vfs_fsid_match(tvh_fsid_t *a, tvh_fsid_t *b) -{ +static inline int tvh_vfs_fsid_match(tvh_fsid_t* a, tvh_fsid_t* b) { if (a->fsid != 0 && b->fsid != 0) return a->fsid == b->fsid; if (a->fsid == 0 && b->fsid == 0) diff --git a/src/udp.c b/src/udp.c index b0c3c1e5c..dfc587781 100644 --- a/src/udp.c +++ b/src/udp.c @@ -32,35 +32,36 @@ #include #include #ifndef IPV6_ADD_MEMBERSHIP -#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP -#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP +#define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP +#define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP #endif extern int tcp_preferred_address_family; -static int -udp_resolve( udp_connection_t *uc, - struct sockaddr_storage *ss, - const char *host, - int port, int *multicast, - int receiver ) -{ +static int udp_resolve(udp_connection_t* uc, + struct sockaddr_storage* ss, + const char* host, + int port, + int* multicast, + int receiver) { struct addrinfo hints, *res, *ressave, *use = NULL; - char port_buf[6]; - int x; + char port_buf[6]; + int x; snprintf(port_buf, 6, "%d", port); memset(&hints, 0, sizeof(struct addrinfo)); - hints.ai_flags = (receiver ? AI_PASSIVE : 0) | AI_NUMERICSERV; - hints.ai_family = AF_UNSPEC; + hints.ai_flags = (receiver ? AI_PASSIVE : 0) | AI_NUMERICSERV; + hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_DGRAM; - + x = getaddrinfo(host, port_buf, &hints, &res); if (x < 0) { - tvhlog(LOG_ERR, uc->subsystem, "getaddrinfo: %s: %s", - host != NULL ? host : "*", - x == EAI_SYSTEM ? strerror(errno) : gai_strerror(x)); + tvhlog(LOG_ERR, + uc->subsystem, + "getaddrinfo: %s: %s", + host != NULL ? host : "*", + x == EAI_SYSTEM ? strerror(errno) : gai_strerror(x)); return -1; } @@ -75,16 +76,17 @@ udp_resolve( udp_connection_t *uc, res = res->ai_next; } if (use->ai_family == AF_INET6) { - ss->ss_family = AF_INET6; - IP_AS_V6(ss, port) = htons(port); - memcpy(&IP_AS_V6(ss, addr), &((struct sockaddr_in6 *)use->ai_addr)->sin6_addr, - sizeof(struct in6_addr)); - *multicast = !!IN6_IS_ADDR_MULTICAST(&IP_AS_V6(ss, addr)); + ss->ss_family = AF_INET6; + IP_AS_V6(ss, port) = htons(port); + memcpy(&IP_AS_V6(ss, addr), + &((struct sockaddr_in6*)use->ai_addr)->sin6_addr, + sizeof(struct in6_addr)); + *multicast = !!IN6_IS_ADDR_MULTICAST(&IP_AS_V6(ss, addr)); } else if (use->ai_family == AF_INET) { - ss->ss_family = AF_INET; - IP_AS_V4(ss, port) = htons(port); - IP_AS_V4(ss, addr) = ((struct sockaddr_in *)use->ai_addr)->sin_addr; - *multicast = !!IN_MULTICAST(ntohl(IP_AS_V4(ss, addr.s_addr))); + ss->ss_family = AF_INET; + IP_AS_V4(ss, port) = htons(port); + IP_AS_V4(ss, addr) = ((struct sockaddr_in*)use->ai_addr)->sin_addr; + *multicast = !!IN_MULTICAST(ntohl(IP_AS_V4(ss, addr.s_addr))); } freeaddrinfo(ressave); if (ss->ss_family != AF_INET && ss->ss_family != AF_INET6) { @@ -94,9 +96,7 @@ udp_resolve( udp_connection_t *uc, return 0; } -static inline int -udp_ifindex_required( udp_connection_t *uc ) -{ +static inline int udp_ifindex_required(udp_connection_t* uc) { if (!uc->multicast) return 0; #if defined(PLATFORM_DARWIN) @@ -106,9 +106,7 @@ udp_ifindex_required( udp_connection_t *uc ) return 1; } -static int -udp_get_ifindex( const char *ifname ) -{ +static int udp_get_ifindex(const char* ifname) { unsigned int r; if (tvh_str_default(ifname, NULL) == NULL) @@ -120,56 +118,54 @@ udp_get_ifindex( const char *ifname ) return r; } -static int -udp_get_ifaddr( int fd, const char *ifname, struct in_addr *addr ) -{ +static int udp_get_ifaddr(int fd, const char* ifname, struct in_addr* addr) { struct ifreq ifreq; if (tvh_str_default(ifname, NULL) == NULL) return -1; - + memset(&ifreq, 0, sizeof(ifreq)); strlcpy(ifreq.ifr_name, ifname, IFNAMSIZ); - + if (ioctl(fd, SIOCGIFADDR, &ifreq) < 0) return -1; - memcpy(addr, &((struct sockaddr_in *) &ifreq.ifr_addr)->sin_addr, - sizeof(struct in_addr)); + memcpy(addr, &((struct sockaddr_in*)&ifreq.ifr_addr)->sin_addr, sizeof(struct in_addr)); return 0; } -static int -udp_get_solip( void ) -{ +static int udp_get_solip(void) { #ifdef SOL_IP return SOL_IP; #else - struct protoent *pent; + struct protoent* pent; pent = getprotobyname("ip"); return (pent != NULL) ? pent->p_proto : 0; #endif } -udp_connection_t * -udp_bind ( int subsystem, const char *name, - const char *bindaddr, int port, const char *multicast_src, - const char *ifname, int rxsize, int txsize ) -{ - int fd, ifindex, reuse = 1; - udp_connection_t *uc; - char buf[256]; - socklen_t addrlen; - - uc = calloc(1, sizeof(udp_connection_t)); - uc->fd = -1; - uc->host = bindaddr ? strdup(bindaddr) : NULL; - uc->port = port; - uc->ifname = ifname ? strdup(ifname) : NULL; - uc->subsystem = subsystem; - uc->name = name ? strdup(name) : NULL; - uc->rxsize = rxsize; - uc->txsize = txsize; +udp_connection_t* udp_bind(int subsystem, + const char* name, + const char* bindaddr, + int port, + const char* multicast_src, + const char* ifname, + int rxsize, + int txsize) { + int fd, ifindex, reuse = 1; + udp_connection_t* uc; + char buf[256]; + socklen_t addrlen; + + uc = calloc(1, sizeof(udp_connection_t)); + uc->fd = -1; + uc->host = bindaddr ? strdup(bindaddr) : NULL; + uc->port = port; + uc->ifname = ifname ? strdup(ifname) : NULL; + uc->subsystem = subsystem; + uc->name = name ? strdup(name) : NULL; + uc->rxsize = rxsize; + uc->txsize = txsize; if (udp_resolve(uc, &uc->ip, uc->host, port, &uc->multicast, 1)) { udp_close(uc); @@ -178,8 +174,7 @@ udp_bind ( int subsystem, const char *name, /* Open socket */ if ((fd = tvh_socket(uc->ip.ss_family, SOCK_DGRAM, 0)) == -1) { - tvherror(subsystem, "%s - failed to create socket [%s]", - name, strerror(errno)); + tvherror(subsystem, "%s - failed to create socket [%s]", name, strerror(errno)); udp_close(uc); return UDP_FATAL_ERROR; } @@ -188,8 +183,7 @@ udp_bind ( int subsystem, const char *name, /* Mark reuse address */ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) { - tvherror(subsystem, "%s - failed to reuse address for socket [%s]", - name, strerror(errno)); + tvherror(subsystem, "%s - failed to reuse address for socket [%s]", name, strerror(errno)); udp_close(uc); return UDP_FATAL_ERROR; } @@ -197,8 +191,7 @@ udp_bind ( int subsystem, const char *name, /* Bind to interface */ ifindex = udp_ifindex_required(uc) ? udp_get_ifindex(ifname) : 0; if (ifindex < 0) { - tvherror(subsystem, "%s - could not find interface %s", - name, ifname); + tvherror(subsystem, "%s - could not find interface %s", name, ifname); goto error; } @@ -206,13 +199,17 @@ udp_bind ( int subsystem, const char *name, if (uc->ip.ss_family == AF_INET) { /* Bind useful for receiver subsystem (not for udp streamer) */ if (subsystem != LS_UDP) { - if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in))) { - inet_ntop(AF_INET, &IP_AS_V4(&uc->ip, addr), buf, sizeof(buf)); - tvherror(subsystem, "%s - cannot bind %s:%hu [e=%s]", - name, buf, ntohs(IP_AS_V4(&uc->ip, port)), strerror(errno)); - goto error; + if (bind(fd, (struct sockaddr*)&uc->ip, sizeof(struct sockaddr_in))) { + inet_ntop(AF_INET, &IP_AS_V4(&uc->ip, addr), buf, sizeof(buf)); + tvherror(subsystem, + "%s - cannot bind %s:%hu [e=%s]", + name, + buf, + ntohs(IP_AS_V4(&uc->ip, port)), + strerror(errno)); + goto error; + } } - } if (uc->multicast) { /* Join multicast group */ @@ -226,63 +223,75 @@ udp_bind ( int subsystem, const char *name, /* Note, ip_mreq_source does not support the ifindex parameter, so we have to resolve to the ip of the interface on all platforms. */ if (udp_get_ifaddr(fd, ifname, &ms.imr_interface) == -1) { - tvherror(subsystem, "%s - cannot find ip address for interface %s [e=%s]", - name, ifname, strerror(errno)); + tvherror(subsystem, + "%s - cannot find ip address for interface %s [e=%s]", + name, + ifname, + strerror(errno)); goto error; } if (inet_pton(AF_INET, multicast_src, &ms.imr_sourceaddr) < 1) { - tvherror(subsystem, "%s - invalid ipv4 address '%s' specified as multicast source [e=%s]", - name, multicast_src, strerror(errno)); + tvherror(subsystem, + "%s - invalid ipv4 address '%s' specified as multicast source [e=%s]", + name, + multicast_src, + strerror(errno)); goto error; } - if (setsockopt(fd, udp_get_solip(), IP_ADD_SOURCE_MEMBERSHIP, - &ms, sizeof(ms)) < 0) { - tvherror(subsystem, "%s - setsockopt IP_ADD_SOURCE_MEMBERSHIP failed [e=%s]", - name, strerror(errno)); + if (setsockopt(fd, udp_get_solip(), IP_ADD_SOURCE_MEMBERSHIP, &ms, sizeof(ms)) < 0) { + tvherror(subsystem, + "%s - setsockopt IP_ADD_SOURCE_MEMBERSHIP failed [e=%s]", + name, + strerror(errno)); goto error; } - } - else { + } else { /* Standard multicast join (non-SSM) */ #if defined(PLATFORM_DARWIN) - struct ip_mreq m; + struct ip_mreq m; #else - struct ip_mreqn m; + struct ip_mreqn m; #endif - memset(&m, 0, sizeof(m)); + memset(&m, 0, sizeof(m)); - m.imr_multiaddr = IP_AS_V4(&uc->ip, addr); + m.imr_multiaddr = IP_AS_V4(&uc->ip, addr); #if !defined(PLATFORM_DARWIN) m.imr_address.s_addr = 0; m.imr_ifindex = ifindex; #else if (udp_get_ifaddr(fd, ifname, &m.imr_interface) == -1) { - tvherror(subsystem, "%s - cannot find ip address for interface %s [e=%s]", - name, ifname, strerror(errno)); + tvherror(subsystem, + "%s - cannot find ip address for interface %s [e=%s]", + name, + ifname, + strerror(errno)); goto error; } #endif if (setsockopt(fd, udp_get_solip(), IP_ADD_MEMBERSHIP, &m, sizeof(m))) { inet_ntop(AF_INET, &m.imr_multiaddr, buf, sizeof(buf)); - tvhwarn(subsystem, "%s - cannot join %s [%s]", - name, buf, strerror(errno)); + tvhwarn(subsystem, "%s - cannot join %s [%s]", name, buf, strerror(errno)); } } - } + } - /* Bind to IPv6 group */ + /* Bind to IPv6 group */ } else { struct ipv6_mreq m; - memset(&m, 0, sizeof(m)); + memset(&m, 0, sizeof(m)); /* Bind */ - if (bind(fd, (struct sockaddr *)&uc->ip, sizeof(struct sockaddr_in6))) { + if (bind(fd, (struct sockaddr*)&uc->ip, sizeof(struct sockaddr_in6))) { inet_ntop(AF_INET6, &IP_AS_V6(&uc->ip, addr), buf, sizeof(buf)); - tvherror(subsystem, "%s - cannot bind %s:%hu [e=%s]", - name, buf, ntohs(IP_AS_V6(&uc->ip, port)), strerror(errno)); + tvherror(subsystem, + "%s - cannot bind %s:%hu [e=%s]", + name, + buf, + ntohs(IP_AS_V6(&uc->ip, port)), + strerror(errno)); goto error; } @@ -293,8 +302,7 @@ udp_bind ( int subsystem, const char *name, #ifdef SOL_IPV6 if (setsockopt(fd, SOL_IPV6, IPV6_ADD_MEMBERSHIP, &m, sizeof(m))) { inet_ntop(AF_INET, &m.ipv6mr_multiaddr, buf, sizeof(buf)); - tvhwarn(subsystem, "%s - cannot join %s [%s]", - name, buf, strerror(errno)); + tvhwarn(subsystem, "%s - cannot join %s [%s]", name, buf, strerror(errno)); } #else tvherror(subsystem, "IPv6 multicast not supported"); @@ -304,23 +312,18 @@ udp_bind ( int subsystem, const char *name, } addrlen = sizeof(uc->ip); - if (getsockname(fd, (struct sockaddr *)&uc->ip, &addrlen)) { - tvherror(subsystem, "%s - cannot obtain socket name [%s]", - name, strerror(errno)); + if (getsockname(fd, (struct sockaddr*)&uc->ip, &addrlen)) { + tvherror(subsystem, "%s - cannot obtain socket name [%s]", name, strerror(errno)); goto error; } - + /* Increase/Decrease RX buffer size */ - if (rxsize > 0 && - setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rxsize, sizeof(rxsize)) == -1) - tvhwarn(subsystem, "%s - cannot change UDP rx buffer size [%s]", - name, strerror(errno)); + if (rxsize > 0 && setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &rxsize, sizeof(rxsize)) == -1) + tvhwarn(subsystem, "%s - cannot change UDP rx buffer size [%s]", name, strerror(errno)); /* Increase/Decrease TX buffer size */ - if (txsize > 0 && - setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &txsize, sizeof(txsize)) == -1) - tvhwarn(subsystem, "%s - cannot change UDP tx buffer size [%s]", - name, strerror(errno)); + if (txsize > 0 && setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &txsize, sizeof(txsize)) == -1) + tvhwarn(subsystem, "%s - cannot change UDP tx buffer size [%s]", name, strerror(errno)); return uc; @@ -329,16 +332,21 @@ error: return NULL; } -int -udp_bind_double ( udp_connection_t **_u1, udp_connection_t **_u2, - int subsystem, const char *name1, - const char *name2, const char *host, int port, - const char *ifname, int rxsize1, int rxsize2, - int txsize1, int txsize2 ) -{ +int udp_bind_double(udp_connection_t** _u1, + udp_connection_t** _u2, + int subsystem, + const char* name1, + const char* name2, + const char* host, + int port, + const char* ifname, + int rxsize1, + int rxsize2, + int txsize1, + int txsize2) { udp_connection_t *u1 = NULL, *u2 = NULL; - udp_connection_t *ucs[10]; - int tst = 40, pos = 0, i, port2; + udp_connection_t* ucs[10]; + int tst = 40, pos = 0, i, port2; memset(&ucs, 0, sizeof(ucs)); while (1) { @@ -372,24 +380,20 @@ fail: return -1; } -udp_connection_t * -udp_sendinit ( int subsystem, const char *name, - const char *ifname, int txsize ) -{ - int fd, ifindex; - udp_connection_t *uc; +udp_connection_t* udp_sendinit(int subsystem, const char* name, const char* ifname, int txsize) { + int fd, ifindex; + udp_connection_t* uc; - uc = calloc(1, sizeof(udp_connection_t)); - uc->fd = -1; - uc->ifname = ifname ? strdup(ifname) : NULL; - uc->subsystem = subsystem; - uc->name = name ? strdup(name) : NULL; - uc->txsize = txsize; + uc = calloc(1, sizeof(udp_connection_t)); + uc->fd = -1; + uc->ifname = ifname ? strdup(ifname) : NULL; + uc->subsystem = subsystem; + uc->name = name ? strdup(name) : NULL; + uc->txsize = txsize; /* Open socket */ if ((fd = tvh_socket(uc->ip.ss_family, SOCK_DGRAM, 0)) == -1) { - tvherror(subsystem, "%s - failed to create socket [%s]", - name, strerror(errno)); + tvherror(subsystem, "%s - failed to create socket [%s]", name, strerror(errno)); udp_close(uc); return UDP_FATAL_ERROR; } @@ -399,8 +403,7 @@ udp_sendinit ( int subsystem, const char *name, /* Bind to interface */ ifindex = udp_ifindex_required(uc) ? udp_get_ifindex(ifname) : 0; if (ifindex < 0) { - tvherror(subsystem, "%s - could not find interface %s", - name, ifname); + tvherror(subsystem, "%s - could not find interface %s", name, ifname); goto error; } @@ -413,22 +416,31 @@ udp_sendinit ( int subsystem, const char *name, #else struct in_addr m; if (udp_get_ifaddr(fd, ifname, &m) == -1) { - tvherror(subsystem, "%s - cannot find ip address for interface %s [e=%s]", - name, ifname, strerror(errno)); + tvherror(subsystem, + "%s - cannot find ip address for interface %s [e=%s]", + name, + ifname, + strerror(errno)); goto error; } #endif if (setsockopt(fd, udp_get_solip(), IP_MULTICAST_IF, &m, sizeof(m))) - tvhwarn(subsystem, "%s - cannot set source interface %s [%s]", - name, ifname, strerror(errno)); + tvhwarn(subsystem, + "%s - cannot set source interface %s [%s]", + name, + ifname, + strerror(errno)); } else { struct ipv6_mreq m; - memset(&m, 0, sizeof(m)); + memset(&m, 0, sizeof(m)); m.ipv6mr_interface = ifindex; #ifdef SOL_IPV6 if (setsockopt(fd, SOL_IPV6, IPV6_MULTICAST_IF, &m, sizeof(m))) { - tvhwarn(subsystem, "%s - cannot set source interface %s [%s]", - name, ifname, strerror(errno)); + tvhwarn(subsystem, + "%s - cannot set source interface %s [%s]", + name, + ifname, + strerror(errno)); } #else tvherror(subsystem, "IPv6 multicast not supported"); @@ -439,8 +451,7 @@ udp_sendinit ( int subsystem, const char *name, /* Increase TX buffer size */ if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &txsize, sizeof(txsize)) == -1) - tvhwarn(subsystem, "%s - cannot increase UDP tx buffer size [%s]", - name, strerror(errno)); + tvhwarn(subsystem, "%s - cannot increase UDP tx buffer size [%s]", name, strerror(errno)); return uc; @@ -449,36 +460,35 @@ error: return NULL; } -int -udp_connect( udp_connection_t *uc, const char *name, - const char *host, int port ) -{ +int udp_connect(udp_connection_t* uc, const char* name, const char* host, int port) { char buf[50]; - int r; + int r; if (uc == NULL || uc == UDP_FATAL_ERROR) return -1; - uc->peer_host = host ? strdup(host) : NULL; - uc->peer_port = port; + uc->peer_host = host ? strdup(host) : NULL; + uc->peer_port = port; uc->peer_multicast = 0; if (udp_resolve(uc, &uc->peer, host, port, &uc->peer_multicast, 1)) return -1; - if (connect(uc->fd, (struct sockaddr *)&uc->peer, sizeof(struct sockaddr_in))) { + if (connect(uc->fd, (struct sockaddr*)&uc->peer, sizeof(struct sockaddr_in))) { inet_ntop(uc->peer.ss_family, IP_IN_ADDR(uc->peer), buf, sizeof(buf)); - tvherror(uc->subsystem, "%s - cannot bind %s:%hu [e=%s]", - name, buf, ntohs(IP_PORT(uc->peer)), strerror(errno)); + tvherror(uc->subsystem, + "%s - cannot bind %s:%hu [e=%s]", + name, + buf, + ntohs(IP_PORT(uc->peer)), + strerror(errno)); r = -errno; return r; } return 0; } -void -udp_close( udp_connection_t *uc ) -{ +void udp_close(udp_connection_t* uc) { if (uc == NULL || uc == UDP_FATAL_ERROR) return; if (uc->fd >= 0) @@ -490,18 +500,18 @@ udp_close( udp_connection_t *uc ) free(uc); } -int -udp_write( udp_connection_t *uc, const void *buf, size_t len, - struct sockaddr_storage *storage ) -{ +int udp_write(udp_connection_t* uc, const void* buf, size_t len, struct sockaddr_storage* storage) { int r; if (storage == NULL) storage = &uc->ip; while (len) { - r = sendto(uc->fd, buf, len, 0, (struct sockaddr*)storage, - storage->ss_family == AF_INET6 ? - sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); + r = sendto(uc->fd, + buf, + len, + 0, + (struct sockaddr*)storage, + storage->ss_family == AF_INET6 ? sizeof(struct sockaddr_in6) : sizeof(struct sockaddr_in)); if (r < 0) { if (ERRNO_AGAIN(errno)) { tvh_safe_usleep(100); @@ -515,13 +525,10 @@ udp_write( udp_connection_t *uc, const void *buf, size_t len, return len; } -int -udp_write_queue( udp_connection_t *uc, htsbuf_queue_t *q, - struct sockaddr_storage *storage ) -{ - htsbuf_data_t *hd; - int l, r = 0; - void *p; +int udp_write_queue(udp_connection_t* uc, htsbuf_queue_t* q, struct sockaddr_storage* storage) { + htsbuf_data_t* hd; + int l, r = 0; + void* p; while ((hd = TAILQ_FIRST(&q->hq_q)) != NULL) { if (!r) { @@ -539,7 +546,7 @@ udp_write_queue( udp_connection_t *uc, htsbuf_queue_t *q, * UDP multi packet receive support */ -#if !defined (CONFIG_RECVMMSG) && defined(__linux__) +#if !defined(CONFIG_RECVMMSG) && defined(__linux__) /* define the syscall - works only for linux */ #include #ifdef __NR_recvmmsg @@ -549,12 +556,17 @@ struct mmsghdr { unsigned int msg_len; }; -int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, - unsigned int flags, struct timespec *timeout); - -int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, - unsigned int flags, struct timespec *timeout) -{ +int recvmmsg(int sockfd, + struct mmsghdr* msgvec, + unsigned int vlen, + unsigned int flags, + struct timespec* timeout); + +int recvmmsg(int sockfd, + struct mmsghdr* msgvec, + unsigned int vlen, + unsigned int flags, + struct timespec* timeout) { return syscall(__NR_recvmmsg, sockfd, msgvec, vlen, flags, timeout); } @@ -573,10 +585,8 @@ struct mmsghdr { #endif static inline int -recvmmsg_i(int sockfd, struct mmsghdr *msgvec, - unsigned int vlen, unsigned int flags) -{ - ssize_t r; +recvmmsg_i(int sockfd, struct mmsghdr* msgvec, unsigned int vlen, unsigned int flags) { + ssize_t r; unsigned int i; for (i = 0; i < vlen; i++) { @@ -591,21 +601,23 @@ recvmmsg_i(int sockfd, struct mmsghdr *msgvec, #ifndef CONFIG_RECVMMSG -int recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, - unsigned int flags, struct timespec *timeout); - -int -recvmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, - unsigned int flags, struct timespec *timeout) -{ +int recvmmsg(int sockfd, + struct mmsghdr* msgvec, + unsigned int vlen, + unsigned int flags, + struct timespec* timeout); + +int recvmmsg(int sockfd, + struct mmsghdr* msgvec, + unsigned int vlen, + unsigned int flags, + struct timespec* timeout) { return recvmmsg_i(sockfd, msgvec, vlen, flags); } #endif -void -udp_multirecv_init( udp_multirecv_t *um, int packets, int psize ) -{ +void udp_multirecv_init(udp_multirecv_t* um, int packets, int psize) { int i; assert(um); @@ -614,35 +626,34 @@ udp_multirecv_init( udp_multirecv_t *um, int packets, int psize ) um->um_data = malloc(packets * psize); um->um_iovec = malloc(packets * sizeof(struct iovec)); um->um_riovec = malloc(packets * sizeof(struct iovec)); - um->um_msg = calloc(packets, sizeof(struct mmsghdr)); + um->um_msg = calloc(packets, sizeof(struct mmsghdr)); for (i = 0; i < packets; i++) { - ((struct mmsghdr *)um->um_msg)[i].msg_hdr.msg_iov = &um->um_iovec[i]; - ((struct mmsghdr *)um->um_msg)[i].msg_hdr.msg_iovlen = 1; - um->um_iovec[i].iov_base = /* follow thru */ - um->um_riovec[i].iov_base = um->um_data + i * psize; - um->um_iovec[i].iov_len = psize; + ((struct mmsghdr*)um->um_msg)[i].msg_hdr.msg_iov = &um->um_iovec[i]; + ((struct mmsghdr*)um->um_msg)[i].msg_hdr.msg_iovlen = 1; + um->um_iovec[i].iov_base = /* follow thru */ + um->um_riovec[i].iov_base = um->um_data + i * psize; + um->um_iovec[i].iov_len = psize; } } -void -udp_multirecv_free( udp_multirecv_t *um ) -{ +void udp_multirecv_free(udp_multirecv_t* um) { if (um == NULL) return; - free(um->um_msg); um->um_msg = NULL; - free(um->um_riovec); um->um_riovec = NULL; - free(um->um_iovec); um->um_iovec = NULL; - free(um->um_data); um->um_data = NULL; + free(um->um_msg); + um->um_msg = NULL; + free(um->um_riovec); + um->um_riovec = NULL; + free(um->um_iovec); + um->um_iovec = NULL; + free(um->um_data); + um->um_data = NULL; um->um_psize = 0; um->um_packets = 0; } -int -udp_multirecv_read( udp_multirecv_t *um, int fd, int packets, - struct iovec **iovec ) -{ +int udp_multirecv_read(udp_multirecv_t* um, int fd, int packets, struct iovec** iovec) { static char use_emul = 0; - int n, i; + int n, i; if (um == NULL || iovec == NULL) { errno = EINVAL; return -1; @@ -650,18 +661,18 @@ udp_multirecv_read( udp_multirecv_t *um, int fd, int packets, if (packets > um->um_packets) packets = um->um_packets; if (!use_emul) { - n = recvmmsg(fd, (struct mmsghdr *)um->um_msg, packets, MSG_DONTWAIT, NULL); + n = recvmmsg(fd, (struct mmsghdr*)um->um_msg, packets, MSG_DONTWAIT, NULL); } else { - n = -1; + n = -1; errno = ENOSYS; } if (n < 0 && errno == ENOSYS) { use_emul = 1; - n = recvmmsg_i(fd, (struct mmsghdr *)um->um_msg, packets, MSG_DONTWAIT); + n = recvmmsg_i(fd, (struct mmsghdr*)um->um_msg, packets, MSG_DONTWAIT); } if (n > 0) { for (i = 0; i < n; i++) - um->um_riovec[i].iov_len = ((struct mmsghdr *)um->um_msg)[i].msg_len; + um->um_riovec[i].iov_len = ((struct mmsghdr*)um->um_msg)[i].msg_len; *iovec = um->um_riovec; } return n; @@ -671,17 +682,14 @@ udp_multirecv_read( udp_multirecv_t *um, int fd, int packets, * UDP multi packet send support */ -#if !defined (CONFIG_SENDMMSG) && defined(__linux__) +#if !defined(CONFIG_SENDMMSG) && defined(__linux__) /* define the syscall - works only for linux */ #include #ifdef __NR_sendmmsg -int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, - unsigned int flags); +int sendmmsg(int sockfd, struct mmsghdr* msgvec, unsigned int vlen, unsigned int flags); -int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, - unsigned int flags) -{ +int sendmmsg(int sockfd, struct mmsghdr* msgvec, unsigned int vlen, unsigned int flags) { return syscall(__NR_sendmmsg, sockfd, msgvec, vlen, flags); } @@ -691,10 +699,8 @@ int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, #endif static inline int -sendmmsg_i(int sockfd, struct mmsghdr *msgvec, - unsigned int vlen, unsigned int flags) -{ - ssize_t r; +sendmmsg_i(int sockfd, struct mmsghdr* msgvec, unsigned int vlen, unsigned int flags) { + ssize_t r; unsigned int i; for (i = 0; i < vlen; i++) { @@ -709,22 +715,15 @@ sendmmsg_i(int sockfd, struct mmsghdr *msgvec, #ifndef CONFIG_SENDMMSG -int sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, - unsigned int flags); +int sendmmsg(int sockfd, struct mmsghdr* msgvec, unsigned int vlen, unsigned int flags); -int -sendmmsg(int sockfd, struct mmsghdr *msgvec, unsigned int vlen, - unsigned int flags) -{ +int sendmmsg(int sockfd, struct mmsghdr* msgvec, unsigned int vlen, unsigned int flags) { return recvmmsg_i(sockfd, msgvec, vlen, flags); } #endif -void -udp_multisend_init( udp_multisend_t *um, int packets, int psize, - struct iovec **iovec ) -{ +void udp_multisend_init(udp_multisend_t* um, int packets, int psize, struct iovec** iovec) { int i; assert(um); @@ -732,41 +731,38 @@ udp_multisend_init( udp_multisend_t *um, int packets, int psize, um->um_packets = packets; um->um_data = malloc(packets * psize); um->um_iovec = malloc(packets * sizeof(struct iovec)); - um->um_msg = calloc(packets, sizeof(struct mmsghdr)); + um->um_msg = calloc(packets, sizeof(struct mmsghdr)); for (i = 0; i < packets; i++) { - ((struct mmsghdr *)um->um_msg)[i].msg_hdr.msg_iov = &um->um_iovec[i]; - ((struct mmsghdr *)um->um_msg)[i].msg_hdr.msg_iovlen = 1; - um->um_iovec[i].iov_base = um->um_data + i * psize; - um->um_iovec[i].iov_len = 0; + ((struct mmsghdr*)um->um_msg)[i].msg_hdr.msg_iov = &um->um_iovec[i]; + ((struct mmsghdr*)um->um_msg)[i].msg_hdr.msg_iovlen = 1; + um->um_iovec[i].iov_base = um->um_data + i * psize; + um->um_iovec[i].iov_len = 0; } *iovec = um->um_iovec; } -void -udp_multisend_free( udp_multisend_t *um ) -{ +void udp_multisend_free(udp_multisend_t* um) { if (um == NULL) return; - free(um->um_msg); um->um_msg = NULL; - free(um->um_iovec); um->um_iovec = NULL; - free(um->um_data); um->um_data = NULL; + free(um->um_msg); + um->um_msg = NULL; + free(um->um_iovec); + um->um_iovec = NULL; + free(um->um_data); + um->um_data = NULL; um->um_psize = 0; um->um_packets = 0; } -void -udp_multisend_clean( udp_multisend_t *um ) -{ +void udp_multisend_clean(udp_multisend_t* um) { int i; for (i = 0; i < um->um_packets; i++) um->um_iovec[i].iov_len = 0; } -int -udp_multisend_send( udp_multisend_t *um, int fd, int packets ) -{ +int udp_multisend_send(udp_multisend_t* um, int fd, int packets) { static char use_emul = 0; - int n, i; + int n, i; if (um == NULL) { errno = EINVAL; return -1; @@ -774,20 +770,20 @@ udp_multisend_send( udp_multisend_t *um, int fd, int packets ) if (packets > um->um_packets) packets = um->um_packets; for (i = 0; i < packets; i++) - ((struct mmsghdr *)um->um_msg)[i].msg_len = um->um_iovec[i].iov_len; + ((struct mmsghdr*)um->um_msg)[i].msg_len = um->um_iovec[i].iov_len; if (!use_emul) { - n = sendmmsg(fd, (struct mmsghdr *)um->um_msg, packets, MSG_DONTWAIT); + n = sendmmsg(fd, (struct mmsghdr*)um->um_msg, packets, MSG_DONTWAIT); } else { - n = -1; + n = -1; errno = ENOSYS; } if (n < 0 && errno == ENOSYS) { use_emul = 1; - n = sendmmsg_i(fd, (struct mmsghdr *)um->um_msg, packets, MSG_DONTWAIT); + n = sendmmsg_i(fd, (struct mmsghdr*)um->um_msg, packets, MSG_DONTWAIT); } if (n > 0) { for (i = 0; i < n; i++) - um->um_iovec[i].iov_len = ((struct mmsghdr *)um->um_msg)[i].msg_len; + um->um_iovec[i].iov_len = ((struct mmsghdr*)um->um_msg)[i].msg_len; } return n; } diff --git a/src/udp.h b/src/udp.h index 55b6dfad3..2ea516626 100644 --- a/src/udp.h +++ b/src/udp.h @@ -23,83 +23,75 @@ #include #include "tcp.h" -#define UDP_FATAL_ERROR ((void *)-1) +#define UDP_FATAL_ERROR ((void*)-1) typedef struct udp_connection { - char *host; - int port; - int multicast; - char *ifname; + char* host; + int port; + int multicast; + char* ifname; struct sockaddr_storage ip; - char *peer_host; - int peer_port; - int peer_multicast; + char* peer_host; + int peer_port; + int peer_multicast; struct sockaddr_storage peer; - int fd; - int subsystem; - char *name; - int rxsize; - int txsize; + int fd; + int subsystem; + char* name; + int rxsize; + int txsize; } udp_connection_t; -udp_connection_t * -udp_bind ( int subsystem, const char *name, - const char *bindaddr, int port, const char *multicast_src, - const char *ifname, int rxsize, int txsize ); -int -udp_bind_double ( udp_connection_t **_u1, udp_connection_t **_u2, - int subsystem, const char *name1, - const char *name2, const char *host, int port, - const char *ifname, int rxsize1, int rxsize2, - int txsize1, int txsize2 ); -udp_connection_t * -udp_sendinit ( int subsystem, const char *name, - const char *ifname, int txsize ); -int -udp_connect ( udp_connection_t *uc, const char *name, - const char *host, int port ); -void -udp_close ( udp_connection_t *uc ); -int -udp_write( udp_connection_t *uc, const void *buf, size_t len, - struct sockaddr_storage *storage ); -int -udp_write_queue( udp_connection_t *uc, htsbuf_queue_t *q, - struct sockaddr_storage *storage ); +udp_connection_t* udp_bind(int subsystem, + const char* name, + const char* bindaddr, + int port, + const char* multicast_src, + const char* ifname, + int rxsize, + int txsize); +int udp_bind_double(udp_connection_t** _u1, + udp_connection_t** _u2, + int subsystem, + const char* name1, + const char* name2, + const char* host, + int port, + const char* ifname, + int rxsize1, + int rxsize2, + int txsize1, + int txsize2); +udp_connection_t* udp_sendinit(int subsystem, const char* name, const char* ifname, int txsize); +int udp_connect(udp_connection_t* uc, const char* name, const char* host, int port); +void udp_close(udp_connection_t* uc); +int udp_write(udp_connection_t* uc, const void* buf, size_t len, struct sockaddr_storage* storage); +int udp_write_queue(udp_connection_t* uc, htsbuf_queue_t* q, struct sockaddr_storage* storage); typedef struct udp_multirecv { int um_psize; int um_packets; - uint8_t *um_data; - struct iovec *um_iovec; - struct iovec *um_riovec; - struct mmsghdr *um_msg; + uint8_t* um_data; + struct iovec* um_iovec; + struct iovec* um_riovec; + struct mmsghdr* um_msg; } udp_multirecv_t; -void -udp_multirecv_init( udp_multirecv_t *um, int packets, int psize ); -void -udp_multirecv_free( udp_multirecv_t *um ); -int -udp_multirecv_read( udp_multirecv_t *um, int fd, int packets, - struct iovec **iovec ); +void udp_multirecv_init(udp_multirecv_t* um, int packets, int psize); +void udp_multirecv_free(udp_multirecv_t* um); +int udp_multirecv_read(udp_multirecv_t* um, int fd, int packets, struct iovec** iovec); typedef struct udp_multisend { int um_psize; int um_packets; - uint8_t *um_data; - struct iovec *um_iovec; - struct mmsghdr *um_msg; + uint8_t* um_data; + struct iovec* um_iovec; + struct mmsghdr* um_msg; } udp_multisend_t; -void -udp_multisend_init( udp_multisend_t *um, int packets, int psize, - struct iovec **iovec ); -void -udp_multisend_clean( udp_multisend_t *um ); -void -udp_multisend_free( udp_multisend_t *um ); -int -udp_multisend_send( udp_multisend_t *um, int fd, int packets ); +void udp_multisend_init(udp_multisend_t* um, int packets, int psize, struct iovec** iovec); +void udp_multisend_clean(udp_multisend_t* um); +void udp_multisend_free(udp_multisend_t* um); +int udp_multisend_send(udp_multisend_t* um, int fd, int packets); #endif /* UDP_H_ */ diff --git a/src/udp_stream.c b/src/udp_stream.c index 48842a992..8e2d4ffed 100644 --- a/src/udp_stream.c +++ b/src/udp_stream.c @@ -22,27 +22,25 @@ #include "config.h" #include "udp_stream.h" -static tvh_mutex_t udp_streams_mutex = TVH_THREAD_MUTEX_INITIALIZER; +static tvh_mutex_t udp_streams_mutex = TVH_THREAD_MUTEX_INITIALIZER; static struct udp_stream_list udp_streams; -udp_stream_t * -create_udp_stream ( udp_connection_t *uc, const char *hint ) -{ - udp_stream_t *ustream; - char port_buf[6]; - size_t unlen; +udp_stream_t* create_udp_stream(udp_connection_t* uc, const char* hint) { + udp_stream_t* ustream; + char port_buf[6]; + size_t unlen; - ustream = calloc(1,sizeof(udp_stream_t)); + ustream = calloc(1, sizeof(udp_stream_t)); if (!ustream) { return NULL; } - ustream->us_uc = uc; + ustream->us_uc = uc; ustream->us_hint = strdup(hint); - snprintf(port_buf, 6, "%d", uc->port); - unlen = strlen(uc->host) + strlen(port_buf) + 8; + snprintf(port_buf, 6, "%d", uc->port); + unlen = strlen(uc->host) + strlen(port_buf) + 8; ustream->us_udp_url = malloc(unlen); - snprintf(ustream->us_udp_url, unlen, "udp://%s:%s", uc->host, port_buf); + snprintf(ustream->us_udp_url, unlen, "udp://%s:%s", uc->host, port_buf); tvh_mutex_lock(&udp_streams_mutex); LIST_INSERT_HEAD(&udp_streams, ustream, us_link); @@ -50,29 +48,25 @@ create_udp_stream ( udp_connection_t *uc, const char *hint ) return ustream; } -void -delete_udp_stream (udp_stream_t * ustream) -{ +void delete_udp_stream(udp_stream_t* ustream) { tvh_mutex_lock(&udp_streams_mutex); LIST_REMOVE(ustream, us_link); tvh_mutex_unlock(&udp_streams_mutex); free(ustream->us_hint); free(ustream->us_udp_url); - free(ustream); + free(ustream); } -udp_stream_t * -find_udp_stream_by_hint ( const char *hint ) -{ - udp_stream_t *us; - int found = 0; +udp_stream_t* find_udp_stream_by_hint(const char* hint) { + udp_stream_t* us; + int found = 0; tvh_mutex_lock(&udp_streams_mutex); - LIST_FOREACH(us, &udp_streams, us_link) - if(strcmp(us->us_hint, hint) == 0) { - found = 1; - break; - } + LIST_FOREACH (us, &udp_streams, us_link) + if (strcmp(us->us_hint, hint) == 0) { + found = 1; + break; + } tvh_mutex_unlock(&udp_streams_mutex); if (found) { @@ -82,18 +76,16 @@ find_udp_stream_by_hint ( const char *hint ) } } -udp_stream_t * -find_udp_stream_by_url ( const char *url ) -{ - udp_stream_t *us; - int found = 0; +udp_stream_t* find_udp_stream_by_url(const char* url) { + udp_stream_t* us; + int found = 0; tvh_mutex_lock(&udp_streams_mutex); - LIST_FOREACH(us, &udp_streams, us_link) - if(strcmp(us->us_udp_url, url) == 0) { - found = 1; - break; - } + LIST_FOREACH (us, &udp_streams, us_link) + if (strcmp(us->us_udp_url, url) == 0) { + found = 1; + break; + } tvh_mutex_unlock(&udp_streams_mutex); if (found) { @@ -103,34 +95,32 @@ find_udp_stream_by_url ( const char *url ) } } -static void * -udp_stream_thread ( void *aux ) -{ - udp_stream_t *us = (udp_stream_t *)aux; - profile_chain_t *prch = &(us->us_prch); - streaming_message_t *sm; - int run = 1, started = 0; - streaming_queue_t *sq = &prch->prch_sq; - muxer_t *mux = prch->prch_muxer; - int ptimeout, grace = 20, r; - streaming_start_t *ss_copy; - int64_t lastpkt, mono; - int fd = us->us_uc->fd; - - if(muxer_open_stream(mux, fd)) +static void* udp_stream_thread(void* aux) { + udp_stream_t* us = (udp_stream_t*)aux; + profile_chain_t* prch = &(us->us_prch); + streaming_message_t* sm; + int run = 1, started = 0; + streaming_queue_t* sq = &prch->prch_sq; + muxer_t* mux = prch->prch_muxer; + int ptimeout, grace = 20, r; + streaming_start_t* ss_copy; + int64_t lastpkt, mono; + int fd = us->us_uc->fd; + + if (muxer_open_stream(mux, fd)) run = 0; - mux->m_config.m_output_chunk = us->us_uc->txsize; - + mux->m_config.m_output_chunk = us->us_uc->txsize; + if (config.dscp >= 0) socket_set_dscp(fd, config.dscp, NULL, 0); - lastpkt = mclk(); + lastpkt = mclk(); ptimeout = prch->prch_pro ? prch->prch_pro->pro_timeout : 5; - while(atomic_get(&us->us_running) && run && tvheadend_is_running()) { + while (atomic_get(&us->us_running) && run && tvheadend_is_running()) { tvh_mutex_lock(&sq->sq_mutex); sm = TAILQ_FIRST(&sq->sq_queue); - if(sm == NULL) { + if (sm == NULL) { mono = mclk() + sec2mono(1); do { r = tvh_cond_timedwait(&sq->sq_cond, &sq->sq_mutex, mono); @@ -145,92 +135,92 @@ udp_stream_thread ( void *aux ) streaming_queue_remove(sq, sm); tvh_mutex_unlock(&sq->sq_mutex); - switch(sm->sm_type) { - case SMT_MPEGTS: - case SMT_PACKET: - if(started) { - pktbuf_t *pb; - int len; - if (sm->sm_type == SMT_PACKET) - pb = ((th_pkt_t*)sm->sm_data)->pkt_payload; - else - pb = sm->sm_data; - subscription_add_bytes_out(us->us_subscript, len = pktbuf_len(pb)); - if (len > 0) - lastpkt = mclk(); - muxer_write_pkt(mux, sm->sm_type, sm->sm_data); - sm->sm_data = NULL; - } - break; + switch (sm->sm_type) { + case SMT_MPEGTS: + case SMT_PACKET: + if (started) { + pktbuf_t* pb; + int len; + if (sm->sm_type == SMT_PACKET) + pb = ((th_pkt_t*)sm->sm_data)->pkt_payload; + else + pb = sm->sm_data; + subscription_add_bytes_out(us->us_subscript, len = pktbuf_len(pb)); + if (len > 0) + lastpkt = mclk(); + muxer_write_pkt(mux, sm->sm_type, sm->sm_data); + sm->sm_data = NULL; + } + break; - case SMT_GRACE: - grace = sm->sm_code < 5 ? 5 : grace; - break; + case SMT_GRACE: + grace = sm->sm_code < 5 ? 5 : grace; + break; - case SMT_START: - grace = 10; - if(!started) { - tvhdebug(LS_UDP, "Start streaming %s", us->us_udp_url); - ss_copy = streaming_start_copy((streaming_start_t *)sm->sm_data); - if(muxer_init(mux, ss_copy, us->us_content_name) < 0) + case SMT_START: + grace = 10; + if (!started) { + tvhdebug(LS_UDP, "Start streaming %s", us->us_udp_url); + ss_copy = streaming_start_copy((streaming_start_t*)sm->sm_data); + if (muxer_init(mux, ss_copy, us->us_content_name) < 0) + run = 0; + streaming_start_unref(ss_copy); + + started = 1; + } else if (muxer_reconfigure(mux, sm->sm_data) < 0) { + tvhwarn(LS_UDP, "Unable to reconfigure stream %s", us->us_udp_url); + } + break; + + case SMT_STOP: + if ((mux->m_caps & MC_CAP_ANOTHER_SERVICE) != 0) /* give a chance to use another svc */ + break; + if (sm->sm_code != SM_CODE_SOURCE_RECONFIGURED) { + tvhwarn(LS_UDP, "Stop streaming %s, %s", us->us_udp_url, streaming_code2txt(sm->sm_code)); run = 0; - streaming_start_unref(ss_copy); + } + break; - started = 1; - } else if(muxer_reconfigure(mux, sm->sm_data) < 0) { - tvhwarn(LS_UDP, "Unable to reconfigure stream %s", us->us_udp_url); - } - break; + case SMT_SERVICE_STATUS: + case SMT_SIGNAL_STATUS: + case SMT_DESCRAMBLE_INFO: + if ((!started && mclk() - lastpkt > sec2mono(grace)) || + (started && ptimeout > 0 && mclk() - lastpkt > sec2mono(ptimeout))) { + tvhwarn(LS_UDP, "Stop streaming %s, timeout waiting for packets", us->us_udp_url); + run = 0; + } + break; - case SMT_STOP: - if((mux->m_caps & MC_CAP_ANOTHER_SERVICE) != 0) /* give a chance to use another svc */ + case SMT_NOSTART_WARN: + case SMT_SKIP: + case SMT_SPEED: + case SMT_TIMESHIFT_STATUS: break; - if(sm->sm_code != SM_CODE_SOURCE_RECONFIGURED) { - tvhwarn(LS_UDP, "Stop streaming %s, %s", us->us_udp_url, - streaming_code2txt(sm->sm_code)); - run = 0; - } - break; - case SMT_SERVICE_STATUS: - case SMT_SIGNAL_STATUS: - case SMT_DESCRAMBLE_INFO: - if((!started && mclk() - lastpkt > sec2mono(grace)) || - (started && ptimeout > 0 && mclk() - lastpkt > sec2mono(ptimeout))) { - tvhwarn(LS_UDP, "Stop streaming %s, timeout waiting for packets", us->us_udp_url); + case SMT_NOSTART: + tvhwarn(LS_UDP, + "Couldn't start streaming %s, %s", + us->us_udp_url, + streaming_code2txt(sm->sm_code)); run = 0; - } - break; - - case SMT_NOSTART_WARN: - case SMT_SKIP: - case SMT_SPEED: - case SMT_TIMESHIFT_STATUS: - break; - - case SMT_NOSTART: - tvhwarn(LS_UDP, "Couldn't start streaming %s, %s", - us->us_udp_url, streaming_code2txt(sm->sm_code)); - run = 0; - break; + break; - case SMT_EXIT: - tvhwarn(LS_UDP, "Stop streaming %s, %s", us->us_udp_url, - streaming_code2txt(sm->sm_code)); - run = 0; - break; + case SMT_EXIT: + tvhwarn(LS_UDP, "Stop streaming %s, %s", us->us_udp_url, streaming_code2txt(sm->sm_code)); + run = 0; + break; } streaming_msg_free(sm); - if(mux->m_errors) { + if (mux->m_errors) { if (!mux->m_eos) - tvhwarn(LS_UDP, "Stop streaming %s, muxer reported errors", us->us_udp_url); + tvhwarn(LS_UDP, "Stop streaming %s, muxer reported errors", us->us_udp_url); run = 0; } } - if(started) + if (started) muxer_close(mux); atomic_set(&us->us_running, 0); tvh_mutex_lock(us->us_global_lock); @@ -239,26 +229,22 @@ udp_stream_thread ( void *aux ) tvh_mutex_unlock(us->us_global_lock); udp_close(us->us_uc); free(us->us_content_name); - delete_udp_stream(us); - return NULL; + delete_udp_stream(us); + return NULL; } -int -udp_stream_run (udp_stream_t *us) -{ +int udp_stream_run(udp_stream_t* us) { if (atomic_get(&us->us_running)) { - tvhwarn(LS_UDP, "UDP stream %s is already running", us->us_udp_url); + tvhwarn(LS_UDP, "UDP stream %s is already running", us->us_udp_url); return -1; } atomic_set(&us->us_running, 1); - return tvh_thread_create(&us->us_tid, NULL, udp_stream_thread, (void *)us, us->us_udp_url); + return tvh_thread_create(&us->us_tid, NULL, udp_stream_thread, (void*)us, us->us_udp_url); } -int -udp_stream_shutdown (udp_stream_t *us) -{ +int udp_stream_shutdown(udp_stream_t* us) { if (!atomic_get(&us->us_running)) { - tvhwarn(LS_UDP, "UDP stream %s is not currently running", us->us_udp_url); + tvhwarn(LS_UDP, "UDP stream %s is not currently running", us->us_udp_url); return -1; } atomic_set(&us->us_running, 0); diff --git a/src/udp_stream.h b/src/udp_stream.h index 64bbea0e2..6b466b316 100644 --- a/src/udp_stream.h +++ b/src/udp_stream.h @@ -25,35 +25,29 @@ typedef struct udp_stream { LIST_ENTRY(udp_stream) us_link; - char *us_hint; - char *us_udp_url; - udp_connection_t *us_uc; - profile_chain_t us_prch; - th_subscription_t *us_subscript; - char *us_content_name; - pthread_t us_tid; - int us_running; - tvh_mutex_t* us_global_lock; + char* us_hint; + char* us_udp_url; + udp_connection_t* us_uc; + profile_chain_t us_prch; + th_subscription_t* us_subscript; + char* us_content_name; + pthread_t us_tid; + int us_running; + tvh_mutex_t* us_global_lock; } udp_stream_t; LIST_HEAD(udp_stream_list, udp_stream); -udp_stream_t * -create_udp_stream ( udp_connection_t *uc, const char *hint ); +udp_stream_t* create_udp_stream(udp_connection_t* uc, const char* hint); -void -delete_udp_stream (udp_stream_t * ustream); +void delete_udp_stream(udp_stream_t* ustream); -udp_stream_t * -find_udp_stream_by_hint ( const char *hint ); +udp_stream_t* find_udp_stream_by_hint(const char* hint); -udp_stream_t * -find_udp_stream_by_url ( const char *url ); +udp_stream_t* find_udp_stream_by_url(const char* url); -int -udp_stream_run (udp_stream_t *us); +int udp_stream_run(udp_stream_t* us); -int -udp_stream_shutdown (udp_stream_t *us); +int udp_stream_shutdown(udp_stream_t* us); #endif /* UDP_STREAM_H_ */ diff --git a/src/upnp.c b/src/upnp.c index f6a3c649f..2579dad78 100644 --- a/src/upnp.c +++ b/src/upnp.c @@ -39,30 +39,28 @@ TAILQ_HEAD(upnp_active_services, upnp_service); typedef struct upnp_data { TAILQ_ENTRY(upnp_data) data_link; struct sockaddr_storage storage; - htsbuf_queue_t queue; - int delay_ms; - int from_multicast; + htsbuf_queue_t queue; + int delay_ms; + int from_multicast; } upnp_data_t; TAILQ_HEAD(upnp_data_queue_write, upnp_data); -static struct upnp_active_services upnp_services; +static struct upnp_active_services upnp_services; static struct upnp_data_queue_write upnp_data_write; -static struct sockaddr_storage upnp_ipv4_multicast; +static struct sockaddr_storage upnp_ipv4_multicast; /* * */ -upnp_service_t *upnp_service_create0( upnp_service_t *us ) -{ +upnp_service_t* upnp_service_create0(upnp_service_t* us) { tvh_mutex_lock(&upnp_lock); TAILQ_INSERT_TAIL(&upnp_services, us, us_link); tvh_mutex_unlock(&upnp_lock); return us; } -void upnp_service_destroy( upnp_service_t *us ) -{ +void upnp_service_destroy(upnp_service_t* us) { tvh_mutex_lock(&upnp_lock); TAILQ_REMOVE(&upnp_services, us, us_link); us->us_destroy(us); @@ -73,11 +71,11 @@ void upnp_service_destroy( upnp_service_t *us ) /* * */ -void -upnp_send( htsbuf_queue_t *q, struct sockaddr_storage *storage, - int delay_ms, int from_multicast ) -{ - upnp_data_t *data; +void upnp_send(htsbuf_queue_t* q, + struct sockaddr_storage* storage, + int delay_ms, + int from_multicast) { + upnp_data_t* data; if (!atomic_get(&upnp_running)) return; @@ -88,7 +86,7 @@ upnp_send( htsbuf_queue_t *q, struct sockaddr_storage *storage, data->storage = upnp_ipv4_multicast; else data->storage = *storage; - data->delay_ms = delay_ms; + data->delay_ms = delay_ms; data->from_multicast = from_multicast; tvh_mutex_lock(&upnp_lock); TAILQ_INSERT_TAIL(&upnp_data_write, data, data_link); @@ -98,9 +96,7 @@ upnp_send( htsbuf_queue_t *q, struct sockaddr_storage *storage, /* * */ -static void -upnp_dump_data( upnp_data_t *data ) -{ +static void upnp_dump_data(upnp_data_t* data) { #if 0 char tbuf[256]; inet_ntop(data->storage.ss_family, IP_IN_ADDR(data->storage), tbuf, sizeof(tbuf)); @@ -112,34 +108,36 @@ upnp_dump_data( upnp_data_t *data ) /* * Discovery thread */ -static void * -upnp_thread( void *aux ) -{ - char *bindaddr = aux; - tvhpoll_t *poll = tvhpoll_create(2); - tvhpoll_event_t ev[2]; - upnp_data_t *data; - udp_connection_t *multicast = NULL, *unicast = NULL; - udp_connection_t *conn; - unsigned char buf[16384]; - upnp_service_t *us; +static void* upnp_thread(void* aux) { + char* bindaddr = aux; + tvhpoll_t* poll = tvhpoll_create(2); + tvhpoll_event_t ev[2]; + upnp_data_t* data; + udp_connection_t * multicast = NULL, *unicast = NULL; + udp_connection_t* conn; + unsigned char buf[16384]; + upnp_service_t* us; struct sockaddr_storage ip; - socklen_t iplen; - size_t size; - int r, delay_ms; - - multicast = udp_bind(LS_UPNP, "upnp_thread_multicast", - "239.255.255.250", 1900, NULL, - NULL, 32*1024, 32*1024); + socklen_t iplen; + size_t size; + int r, delay_ms; + + multicast = udp_bind(LS_UPNP, + "upnp_thread_multicast", + "239.255.255.250", + 1900, + NULL, + NULL, + 32 * 1024, + 32 * 1024); if (multicast == NULL || multicast == UDP_FATAL_ERROR) goto error; - unicast = udp_bind(LS_UPNP, "upnp_thread_unicast", bindaddr, 0, NULL, - NULL, 32*1024, 32*1024); + unicast = udp_bind(LS_UPNP, "upnp_thread_unicast", bindaddr, 0, NULL, NULL, 32 * 1024, 32 * 1024); if (unicast == NULL || unicast == UDP_FATAL_ERROR) goto error; - tvhpoll_event(ev+0, multicast->fd, TVHPOLL_IN, multicast); - tvhpoll_event(ev+1, unicast->fd, TVHPOLL_IN, unicast); + tvhpoll_event(ev + 0, multicast->fd, TVHPOLL_IN, multicast); + tvhpoll_event(ev + 1, unicast->fd, TVHPOLL_IN, unicast); tvhpoll_add(poll, ev, 2); delay_ms = 0; @@ -151,20 +149,22 @@ upnp_thread( void *aux ) while (r-- > 0) { if ((ev[r].events & TVHPOLL_IN) != 0) { - conn = ev[r].ptr; + conn = ev[r].ptr; iplen = sizeof(ip); - size = recvfrom(conn->fd, buf, sizeof(buf), 0, - (struct sockaddr *)&ip, &iplen); + size = recvfrom(conn->fd, buf, sizeof(buf), 0, (struct sockaddr*)&ip, &iplen); if (size > 0 && tvhtrace_enabled()) { char tbuf[256]; inet_ntop(ip.ss_family, IP_IN_ADDR(ip), tbuf, sizeof(tbuf)); - tvhtrace(LS_UPNP, "%s - received data from %s:%hu [size=%zi]", - conn == multicast ? "multicast" : "unicast", - tbuf, (unsigned short) ntohs(IP_PORT(ip)), size); + tvhtrace(LS_UPNP, + "%s - received data from %s:%hu [size=%zi]", + conn == multicast ? "multicast" : "unicast", + tbuf, + (unsigned short)ntohs(IP_PORT(ip)), + size); tvhlog_hexdump(LS_UPNP, buf, size); } /* TODO: a filter */ - TAILQ_FOREACH(us, &upnp_services, us_link) + TAILQ_FOREACH (us, &upnp_services, us_link) us->us_received(buf, size, conn, &ip); } } @@ -173,7 +173,7 @@ upnp_thread( void *aux ) tvh_mutex_lock(&upnp_lock); data = TAILQ_FIRST(&upnp_data_write); if (data) { - delay_ms = data->delay_ms; + delay_ms = data->delay_ms; data->delay_ms = 0; if (!delay_ms) { TAILQ_REMOVE(&upnp_data_write, data, data_link); @@ -185,8 +185,7 @@ upnp_thread( void *aux ) if (data == NULL) break; upnp_dump_data(data); - udp_write_queue(data->from_multicast ? multicast : unicast, - &data->queue, &data->storage); + udp_write_queue(data->from_multicast ? multicast : unicast, &data->queue, &data->storage); htsbuf_queue_flush(&data->queue); free(data); delay_ms = 0; @@ -220,13 +219,11 @@ error: /* * Fire up UPnP server */ -void -upnp_server_init(const char *bindaddr) -{ +void upnp_server_init(const char* bindaddr) { int r; memset(&upnp_ipv4_multicast, 0, sizeof(upnp_ipv4_multicast)); - upnp_ipv4_multicast.ss_family = AF_INET; + upnp_ipv4_multicast.ss_family = AF_INET; IP_AS_V4(&upnp_ipv4_multicast, port) = htons(1900); r = inet_pton(AF_INET, "239.255.255.250", &IP_AS_V4(&upnp_ipv4_multicast, addr)); assert(r); @@ -235,14 +232,12 @@ upnp_server_init(const char *bindaddr) TAILQ_INIT(&upnp_data_write); TAILQ_INIT(&upnp_services); atomic_set(&upnp_running, 1); - tvh_thread_create(&upnp_tid, NULL, upnp_thread, (char *)bindaddr, "upnp"); + tvh_thread_create(&upnp_tid, NULL, upnp_thread, (char*)bindaddr, "upnp"); } -void -upnp_server_done(void) -{ - upnp_data_t *data; - upnp_service_t *us; +void upnp_server_done(void) { + upnp_data_t* data; + upnp_service_t* us; atomic_set(&upnp_running, 0); tvh_thread_kill(upnp_tid, SIGTERM); diff --git a/src/upnp.h b/src/upnp.h index c2f6726cd..d31d2227e 100644 --- a/src/upnp.h +++ b/src/upnp.h @@ -28,21 +28,23 @@ typedef struct upnp_service upnp_service_t; struct upnp_service { TAILQ_ENTRY(upnp_service) us_link; - void (*us_received)(uint8_t *data, size_t len, - udp_connection_t *conn, - struct sockaddr_storage *storage); - void (*us_destroy)(upnp_service_t *us); + void (*us_received)(uint8_t* data, + size_t len, + udp_connection_t* conn, + struct sockaddr_storage* storage); + void (*us_destroy)(upnp_service_t* us); }; -upnp_service_t *upnp_service_create0(upnp_service_t *us); -#define upnp_service_create(us) \ - upnp_service_create0(calloc(1, sizeof(struct us))) -void upnp_service_destroy(upnp_service_t *service); +upnp_service_t* upnp_service_create0(upnp_service_t* us); +#define upnp_service_create(us) upnp_service_create0(calloc(1, sizeof(struct us))) +void upnp_service_destroy(upnp_service_t* service); -void upnp_send(htsbuf_queue_t *q, struct sockaddr_storage *storage, - int delay_ms, int from_multicast); +void upnp_send(htsbuf_queue_t* q, + struct sockaddr_storage* storage, + int delay_ms, + int from_multicast); -void upnp_server_init(const char *bindaddr); +void upnp_server_init(const char* bindaddr); void upnp_server_done(void); #endif /* UPNP_H_ */ diff --git a/src/url.c b/src/url.c index 77a1eaaf8..eb77e9f11 100644 --- a/src/url.c +++ b/src/url.c @@ -25,10 +25,7 @@ #include #include - -void -urlreset ( url_t *url ) -{ +void urlreset(url_t* url) { free(url->scheme); free(url->user); free(url->pass); @@ -40,9 +37,7 @@ urlreset ( url_t *url ) memset(url, 0, sizeof(*url)); } -void -urlcopy ( url_t *dst, const url_t *src ) -{ +void urlcopy(url_t* dst, const url_t* src) { dst->scheme = src->scheme ? strdup(src->scheme) : NULL; dst->user = src->user ? strdup(src->user) : NULL; dst->pass = src->pass ? strdup(src->pass) : NULL; @@ -54,21 +49,16 @@ urlcopy ( url_t *dst, const url_t *src ) dst->raw = src->raw ? strdup(src->raw) : NULL; } -int -urlrecompose( url_t *url ) -{ - size_t len; - char *raw, port[16]; +int urlrecompose(url_t* url) { + size_t len; + char * raw, port[16]; const int user = url->user && url->user[0]; const int pass = url->pass && url->pass[0]; - len = (url->scheme ? strlen(url->scheme) : 0) + 4 + - (user ? strlen(url->user) + 1 : 0) + - (pass ? strlen(url->pass) + 1 : 0) + - (url->host ? strlen(url->host) : 0) + - (url->port > 0 ? 6 : 0) + - (url->path ? strlen(url->path) : 0) + - (url->query ? strlen(url->query) + 1 : 0); + len = (url->scheme ? strlen(url->scheme) : 0) + 4 + (user ? strlen(url->user) + 1 : 0) + + (pass ? strlen(url->pass) + 1 : 0) + (url->host ? strlen(url->host) : 0) + + (url->port > 0 ? 6 : 0) + (url->path ? strlen(url->path) : 0) + + (url->query ? strlen(url->query) + 1 : 0); raw = malloc(len); if (raw == NULL) return -ENOMEM; @@ -76,16 +66,20 @@ urlrecompose( url_t *url ) snprintf(port, sizeof(port), ":%d", url->port); else port[0] = '\0'; - snprintf(raw, len, "%s%s%s%s%s%s%s%s%s%s%s", - url->scheme ?: "", url->scheme ? "://" : "", - user ? url->user : "", - (user && pass) ? ":" : "", - (user && pass) ? url->pass : "", - user ? "@" : "", - url->host ?: "", port, - url->path ?: "", - (url->query && url->query[0]) ? "?" : "", - url->query ?: ""); + snprintf(raw, + len, + "%s%s%s%s%s%s%s%s%s%s%s", + url->scheme ?: "", + url->scheme ? "://" : "", + user ? url->user : "", + (user && pass) ? ":" : "", + (user && pass) ? url->pass : "", + user ? "@" : "", + url->host ?: "", + port, + url->path ?: "", + (url->query && url->query[0]) ? "?" : "", + url->query ?: ""); free(url->raw); url->raw = raw; return 0; @@ -95,13 +89,11 @@ urlrecompose( url_t *url ) #if ENABLE_URIPARSER #include -int -urlparse ( const char *str, url_t *url ) -{ - UriParserStateA state; - UriPathSegmentA *path; - UriUriA uri; - char *s, buf[256]; +int urlparse(const char* str, url_t* url) { + UriParserStateA state; + UriPathSegmentA* path; + UriUriA uri; + char * s, buf[256]; if (str == NULL || url == NULL) return -1; @@ -114,31 +106,35 @@ urlparse ( const char *str, url_t *url ) uriFreeUriMembersA(&uri); return -1; } - + /* Store raw */ url->raw = strdup(str); /* Copy */ -#define uri_copy(y, x)\ - if (x.first) {\ - size_t len = x.afterLast - x.first;\ - y = strndup(x.first, len);\ +#define uri_copy(y, x) \ + if (x.first) { \ + size_t len = x.afterLast - x.first; \ + y = strndup(x.first, len); \ } -#define uri_copy_static(y, s, x)\ - if (x.first) {\ - size_t len = x.afterLast - x.first;\ - if (len > sizeof(y) - 1) \ - { y[0] = '\0'; s = strndup(x.first, len); } else \ - { s = NULL; strlcpy(y, x.first, len + 1); }\ - } else {\ - s = NULL;\ - y[0] = '\0';\ +#define uri_copy_static(y, s, x) \ + if (x.first) { \ + size_t len = x.afterLast - x.first; \ + if (len > sizeof(y) - 1) { \ + y[0] = '\0'; \ + s = strndup(x.first, len); \ + } else { \ + s = NULL; \ + strlcpy(y, x.first, len + 1); \ + } \ + } else { \ + s = NULL; \ + y[0] = '\0'; \ } uri_copy(url->scheme, uri.scheme); - uri_copy(url->host, uri.hostText); - uri_copy(url->user, uri.userInfo); - uri_copy(url->query, uri.query); - uri_copy(url->frag, uri.fragment); + uri_copy(url->host, uri.hostText); + uri_copy(url->user, uri.userInfo); + uri_copy(url->query, uri.query); + uri_copy(url->frag, uri.fragment); uri_copy_static(buf, s, uri.portText); if (s) { url->port = atoi(s); @@ -147,7 +143,7 @@ urlparse ( const char *str, url_t *url ) url->port = atoi(buf); else url->port = 0; - path = uri.pathHead; + path = uri.pathHead; while (path) { uri_copy_static(buf, s, path->text); if (url->path) @@ -166,7 +162,7 @@ urlparse ( const char *str, url_t *url ) s = strstr(url->user, ":"); if (s) { url->pass = strdup(s + 1); - *s = 0; + *s = 0; } } @@ -175,10 +171,7 @@ urlparse ( const char *str, url_t *url ) return 0; } -void -urlparse_done( void ) -{ -} +void urlparse_done(void) {} /* Fallback to limited support */ #else /* ENABLE_URIPARSER */ @@ -188,15 +181,14 @@ urlparse_done( void ) #define UC "[a-z0-9_\\.!£$%^&-]" #define PC UC #define HC "[a-z0-9_\\.-]" -#define URL_RE "^([A-Za-z]+)://(("UC"+)(:("PC"+))?@|@)?("HC"+)(:([0-9]+))?(/[^\\?]*)?(.([^#]*))?(#(.*))?" +#define URL_RE \ + "^([A-Za-z]+)://((" UC "+)(:(" PC "+))?@|@)?(" HC "+)(:([0-9]+))?(/[^\\?]*)?(.([^#]*))?(#(.*))?" -static regex_t *urlparse_exp = NULL; +static regex_t* urlparse_exp = NULL; -int -urlparse ( const char *str, url_t *url ) -{ +int urlparse(const char* str, url_t* url) { regmatch_t m[16]; - char buf[16]; + char buf[16]; if (str == NULL || url == NULL) return -1; @@ -215,38 +207,36 @@ urlparse ( const char *str, url_t *url ) /* Execute */ if (regexec(urlparse_exp, str, ARRAY_SIZE(m), m, 0)) return -1; - - /* Extract data */ -#define copy(x, i)\ - {\ - x = strndup(str+m[i].rm_so, m[i].rm_eo - m[i].rm_so);\ - }(void)0 -#define copy_static(x, i)\ - {\ - int len = m[i].rm_eo - m[i].rm_so;\ - if (len >= sizeof(x) - 1)\ - len = sizeof(x) - 1;\ - memcpy(x, str+m[i].rm_so, len);\ - x[len] = 0;\ - }(void)0 + + /* Extract data */ +#define copy(x, i) \ + { x = strndup(str + m[i].rm_so, m[i].rm_eo - m[i].rm_so); } \ + (void)0 +#define copy_static(x, i) \ + { \ + int len = m[i].rm_eo - m[i].rm_so; \ + if (len >= sizeof(x) - 1) \ + len = sizeof(x) - 1; \ + memcpy(x, str + m[i].rm_so, len); \ + x[len] = 0; \ + } \ + (void)0 copy(url->scheme, 1); - copy(url->user, 3); - copy(url->pass, 5); - copy(url->host, 6); - copy(url->path, 9); - copy_static(buf, 8); + copy(url->user, 3); + copy(url->pass, 5); + copy(url->host, 6); + copy(url->path, 9); + copy_static(buf, 8); url->port = atoi(buf); copy(url->query, 11); - copy(url->frag, 13); + copy(url->frag, 13); url->raw = strdup(str); return 0; } -void -urlparse_done( void ) -{ +void urlparse_done(void) { if (urlparse_exp) { regfree(urlparse_exp); free(urlparse_exp); diff --git a/src/url.h b/src/url.h index f4859c1a9..d75aa332e 100644 --- a/src/url.h +++ b/src/url.h @@ -24,24 +24,25 @@ #include /* URL structure */ -typedef struct url -{ - char *scheme; - char *user; - char *pass; - char *host; - int port; - char *path; - char *query; - char *frag; - char *raw; +typedef struct url { + char* scheme; + char* user; + char* pass; + char* host; + int port; + char* path; + char* query; + char* frag; + char* raw; } url_t; -static inline void urlinit ( url_t *url ) { memset(url, 0, sizeof(*url)); } -void urlreset ( url_t *url ); -int urlparse ( const char *str, url_t *url ); -void urlparse_done ( void ); -void urlcopy ( url_t *dst, const url_t *src ); -int urlrecompose ( url_t *url ); +static inline void urlinit(url_t* url) { + memset(url, 0, sizeof(*url)); +} +void urlreset(url_t* url); +int urlparse(const char* str, url_t* url); +void urlparse_done(void); +void urlcopy(url_t* dst, const url_t* src); +int urlrecompose(url_t* url); #endif diff --git a/src/utils.c b/src/utils.c index bc6401d22..1fb7c4244 100644 --- a/src/utils.c +++ b/src/utils.c @@ -38,115 +38,327 @@ #include "sbuf.h" /** - * CRC32 + * CRC32 */ -static uint32_t crc_tab[256] = { - 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, - 0x1a864db2, 0x1e475005, 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, - 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, 0x4c11db70, 0x48d0c6c7, - 0x4593e01e, 0x4152fda9, 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, - 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, 0x791d4014, 0x7ddc5da3, - 0x709f7b7a, 0x745e66cd, 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, - 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, 0xbe2b5b58, 0xbaea46ef, - 0xb7a96036, 0xb3687d81, 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, - 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, 0xc7361b4c, 0xc3f706fb, - 0xceb42022, 0xca753d95, 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, - 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, 0x34867077, 0x30476dc0, - 0x3d044b19, 0x39c556ae, 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, - 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, 0x018aeb13, 0x054bf6a4, - 0x0808d07d, 0x0cc9cdca, 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, - 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, 0x5e9f46bf, 0x5a5e5b08, - 0x571d7dd1, 0x53dc6066, 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, - 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, 0xbfa1b04b, 0xbb60adfc, - 0xb6238b25, 0xb2e29692, 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, - 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, 0xe0b41de7, 0xe4750050, - 0xe9362689, 0xedf73b3e, 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, - 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, 0xd5b88683, 0xd1799b34, - 0xdc3abded, 0xd8fba05a, 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, - 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, 0x4f040d56, 0x4bc510e1, - 0x46863638, 0x42472b8f, 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, - 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, 0x36194d42, 0x32d850f5, - 0x3f9b762c, 0x3b5a6b9b, 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, - 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, 0xf12f560e, 0xf5ee4bb9, - 0xf8ad6d60, 0xfc6c70d7, 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, - 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, 0xc423cd6a, 0xc0e2d0dd, - 0xcda1f604, 0xc960ebb3, 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, - 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, 0x9b3660c6, 0x9ff77d71, - 0x92b45ba8, 0x9675461f, 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, - 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, 0x4e8ee645, 0x4a4ffbf2, - 0x470cdd2b, 0x43cdc09c, 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, - 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, 0x119b4be9, 0x155a565e, - 0x18197087, 0x1cd86d30, 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, - 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, 0x2497d08d, 0x2056cd3a, - 0x2d15ebe3, 0x29d4f654, 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, - 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, 0xe3a1cbc1, 0xe760d676, - 0xea23f0af, 0xeee2ed18, 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, - 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, 0x9abc8bd5, 0x9e7d9662, - 0x933eb0bb, 0x97ffad0c, 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, - 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 -}; - -uint32_t -tvh_crc32(const uint8_t *data, size_t datalen, uint32_t crc) -{ - while(datalen--) +static uint32_t crc_tab[256] = {0x00000000, + 0x04c11db7, + 0x09823b6e, + 0x0d4326d9, + 0x130476dc, + 0x17c56b6b, + 0x1a864db2, + 0x1e475005, + 0x2608edb8, + 0x22c9f00f, + 0x2f8ad6d6, + 0x2b4bcb61, + 0x350c9b64, + 0x31cd86d3, + 0x3c8ea00a, + 0x384fbdbd, + 0x4c11db70, + 0x48d0c6c7, + 0x4593e01e, + 0x4152fda9, + 0x5f15adac, + 0x5bd4b01b, + 0x569796c2, + 0x52568b75, + 0x6a1936c8, + 0x6ed82b7f, + 0x639b0da6, + 0x675a1011, + 0x791d4014, + 0x7ddc5da3, + 0x709f7b7a, + 0x745e66cd, + 0x9823b6e0, + 0x9ce2ab57, + 0x91a18d8e, + 0x95609039, + 0x8b27c03c, + 0x8fe6dd8b, + 0x82a5fb52, + 0x8664e6e5, + 0xbe2b5b58, + 0xbaea46ef, + 0xb7a96036, + 0xb3687d81, + 0xad2f2d84, + 0xa9ee3033, + 0xa4ad16ea, + 0xa06c0b5d, + 0xd4326d90, + 0xd0f37027, + 0xddb056fe, + 0xd9714b49, + 0xc7361b4c, + 0xc3f706fb, + 0xceb42022, + 0xca753d95, + 0xf23a8028, + 0xf6fb9d9f, + 0xfbb8bb46, + 0xff79a6f1, + 0xe13ef6f4, + 0xe5ffeb43, + 0xe8bccd9a, + 0xec7dd02d, + 0x34867077, + 0x30476dc0, + 0x3d044b19, + 0x39c556ae, + 0x278206ab, + 0x23431b1c, + 0x2e003dc5, + 0x2ac12072, + 0x128e9dcf, + 0x164f8078, + 0x1b0ca6a1, + 0x1fcdbb16, + 0x018aeb13, + 0x054bf6a4, + 0x0808d07d, + 0x0cc9cdca, + 0x7897ab07, + 0x7c56b6b0, + 0x71159069, + 0x75d48dde, + 0x6b93dddb, + 0x6f52c06c, + 0x6211e6b5, + 0x66d0fb02, + 0x5e9f46bf, + 0x5a5e5b08, + 0x571d7dd1, + 0x53dc6066, + 0x4d9b3063, + 0x495a2dd4, + 0x44190b0d, + 0x40d816ba, + 0xaca5c697, + 0xa864db20, + 0xa527fdf9, + 0xa1e6e04e, + 0xbfa1b04b, + 0xbb60adfc, + 0xb6238b25, + 0xb2e29692, + 0x8aad2b2f, + 0x8e6c3698, + 0x832f1041, + 0x87ee0df6, + 0x99a95df3, + 0x9d684044, + 0x902b669d, + 0x94ea7b2a, + 0xe0b41de7, + 0xe4750050, + 0xe9362689, + 0xedf73b3e, + 0xf3b06b3b, + 0xf771768c, + 0xfa325055, + 0xfef34de2, + 0xc6bcf05f, + 0xc27dede8, + 0xcf3ecb31, + 0xcbffd686, + 0xd5b88683, + 0xd1799b34, + 0xdc3abded, + 0xd8fba05a, + 0x690ce0ee, + 0x6dcdfd59, + 0x608edb80, + 0x644fc637, + 0x7a089632, + 0x7ec98b85, + 0x738aad5c, + 0x774bb0eb, + 0x4f040d56, + 0x4bc510e1, + 0x46863638, + 0x42472b8f, + 0x5c007b8a, + 0x58c1663d, + 0x558240e4, + 0x51435d53, + 0x251d3b9e, + 0x21dc2629, + 0x2c9f00f0, + 0x285e1d47, + 0x36194d42, + 0x32d850f5, + 0x3f9b762c, + 0x3b5a6b9b, + 0x0315d626, + 0x07d4cb91, + 0x0a97ed48, + 0x0e56f0ff, + 0x1011a0fa, + 0x14d0bd4d, + 0x19939b94, + 0x1d528623, + 0xf12f560e, + 0xf5ee4bb9, + 0xf8ad6d60, + 0xfc6c70d7, + 0xe22b20d2, + 0xe6ea3d65, + 0xeba91bbc, + 0xef68060b, + 0xd727bbb6, + 0xd3e6a601, + 0xdea580d8, + 0xda649d6f, + 0xc423cd6a, + 0xc0e2d0dd, + 0xcda1f604, + 0xc960ebb3, + 0xbd3e8d7e, + 0xb9ff90c9, + 0xb4bcb610, + 0xb07daba7, + 0xae3afba2, + 0xaafbe615, + 0xa7b8c0cc, + 0xa379dd7b, + 0x9b3660c6, + 0x9ff77d71, + 0x92b45ba8, + 0x9675461f, + 0x8832161a, + 0x8cf30bad, + 0x81b02d74, + 0x857130c3, + 0x5d8a9099, + 0x594b8d2e, + 0x5408abf7, + 0x50c9b640, + 0x4e8ee645, + 0x4a4ffbf2, + 0x470cdd2b, + 0x43cdc09c, + 0x7b827d21, + 0x7f436096, + 0x7200464f, + 0x76c15bf8, + 0x68860bfd, + 0x6c47164a, + 0x61043093, + 0x65c52d24, + 0x119b4be9, + 0x155a565e, + 0x18197087, + 0x1cd86d30, + 0x029f3d35, + 0x065e2082, + 0x0b1d065b, + 0x0fdc1bec, + 0x3793a651, + 0x3352bbe6, + 0x3e119d3f, + 0x3ad08088, + 0x2497d08d, + 0x2056cd3a, + 0x2d15ebe3, + 0x29d4f654, + 0xc5a92679, + 0xc1683bce, + 0xcc2b1d17, + 0xc8ea00a0, + 0xd6ad50a5, + 0xd26c4d12, + 0xdf2f6bcb, + 0xdbee767c, + 0xe3a1cbc1, + 0xe760d676, + 0xea23f0af, + 0xeee2ed18, + 0xf0a5bd1d, + 0xf464a0aa, + 0xf9278673, + 0xfde69bc4, + 0x89b8fd09, + 0x8d79e0be, + 0x803ac667, + 0x84fbdbd0, + 0x9abc8bd5, + 0x9e7d9662, + 0x933eb0bb, + 0x97ffad0c, + 0xafb010b1, + 0xab710d06, + 0xa6322bdf, + 0xa2f33668, + 0xbcb4666d, + 0xb8757bda, + 0xb5365d03, + 0xb1f740b4}; + +uint32_t tvh_crc32(const uint8_t* data, size_t datalen, uint32_t crc) { + while (datalen--) crc = (crc << 8) ^ crc_tab[((crc >> 24) ^ *data++) & 0xff]; return crc; } - /** * */ -static const int sample_rates[16] = { - 96000, 88200, 64000, 48000, - 44100, 32000, 24000, 22050, - 16000, 12000, 11025, 8000, - 7350, 0, 0, 0 -}; +static const int sample_rates[16] = {96000, + 88200, + 64000, + 48000, + 44100, + 32000, + 24000, + 22050, + 16000, + 12000, + 11025, + 8000, + 7350, + 0, + 0, + 0}; /** * */ -int -sri_to_rate(int sri) -{ +int sri_to_rate(int sri) { return sample_rates[sri & 0xf]; } - /** * */ -int -rate_to_sri(int rate) -{ +int rate_to_sri(int rate) { int i; - for(i = 0; i < 16; i++) - if(sample_rates[i] == rate) + for (i = 0; i < 16; i++) + if (sample_rates[i] == rate) return i; return -1; } - /** * */ #define HEXDUMP_WIDTH 16 -void -hexdump(const char *pfx, const uint8_t *data, int len) -{ - int i, j=0, l; - char str[HEXDUMP_WIDTH+1]; - l = ((len+(HEXDUMP_WIDTH-1))/HEXDUMP_WIDTH)*HEXDUMP_WIDTH; +void hexdump(const char* pfx, const uint8_t* data, int len) { + int i, j = 0, l; + char str[HEXDUMP_WIDTH + 1]; + l = ((len + (HEXDUMP_WIDTH - 1)) / HEXDUMP_WIDTH) * HEXDUMP_WIDTH; str[0] = 0; for (i = 0; i < l; i++) { - if (!j) printf("%s: ", pfx); + if (!j) + printf("%s: ", pfx); if (i < len) { printf("%02X ", data[i]); str[j] = data[i]; - if (str[j] < ' ' || str[j] > '~') str[j] = '.'; + if (str[j] < ' ' || str[j] > '~') + str[j] = '.'; } else { printf(" "); str[j] = ' '; @@ -156,7 +368,7 @@ hexdump(const char *pfx, const uint8_t *data, int len) str[j] = 0; printf("%s\n", str); str[0] = 0; - j = 0; + j = 0; } } } @@ -167,28 +379,92 @@ hexdump(const char *pfx, const uint8_t *data, int len) * @author Ryan Martell (with lots of Michael) */ - /* ---------------- private code */ -static const uint8_t map2[] = -{ - 0x3e, 0xff, 0xff, 0xff, 0x3f, 0x34, 0x35, 0x36, - 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, - 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, - 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, - 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, - 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1a, 0x1b, - 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, - 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, - 0x2c, 0x2d, 0x2e, 0x2f, 0x30, 0x31, 0x32, 0x33 -}; - -int -base64_decode(uint8_t *out, const char *in, int out_size) -{ - int i, v; +static const uint8_t map2[] = {0x3e, + 0xff, + 0xff, + 0xff, + 0x3f, + 0x34, + 0x35, + 0x36, + 0x37, + 0x38, + 0x39, + 0x3a, + 0x3b, + 0x3c, + 0x3d, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x00, + 0x01, + 0x02, + 0x03, + 0x04, + 0x05, + 0x06, + 0x07, + 0x08, + 0x09, + 0x0a, + 0x0b, + 0x0c, + 0x0d, + 0x0e, + 0x0f, + 0x10, + 0x11, + 0x12, + 0x13, + 0x14, + 0x15, + 0x16, + 0x17, + 0x18, + 0x19, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0xff, + 0x1a, + 0x1b, + 0x1c, + 0x1d, + 0x1e, + 0x1f, + 0x20, + 0x21, + 0x22, + 0x23, + 0x24, + 0x25, + 0x26, + 0x27, + 0x28, + 0x29, + 0x2a, + 0x2b, + 0x2c, + 0x2d, + 0x2e, + 0x2f, + 0x30, + 0x31, + 0x32, + 0x33}; + +int base64_decode(uint8_t* out, const char* in, int out_size) { + int i, v; unsigned int index; - uint8_t *dst = out; + uint8_t* dst = out; v = 0; for (i = 0; *in && *in != '='; i++, in++) { @@ -211,18 +487,15 @@ base64_decode(uint8_t *out, const char *in, int out_size) * Simplified by Michael. * Fixed edge cases and made it work from data (vs. strings) by Ryan. */ -char *base64_encode(char *out, int out_size, const uint8_t *in, int in_size) -{ - static const char b64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - char *dst; - unsigned i_bits = 0; - int i_shift = 0; - int bytes_remaining = in_size; - - if (in_size >= UINT_MAX / 4 || - out_size < BASE64_SIZE(in_size)) - return NULL; +char* base64_encode(char* out, int out_size, const uint8_t* in, int in_size) { + static const char b64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + char* dst; + unsigned i_bits = 0; + int i_shift = 0; + int bytes_remaining = in_size; + + if (in_size >= UINT_MAX / 4 || out_size < BASE64_SIZE(in_size)) + return NULL; dst = out; while (bytes_remaining) { i_bits = (i_bits << 8) + *in++; @@ -243,44 +516,42 @@ char *base64_encode(char *out, int out_size, const uint8_t *in, int in_size) /** * */ -int -put_utf8(char *out, int c) -{ - if(c == 0xfffe || c == 0xffff || (c >= 0xD800 && c < 0xE000)) +int put_utf8(char* out, int c) { + if (c == 0xfffe || c == 0xffff || (c >= 0xD800 && c < 0xE000)) return 0; - + if (c < 0x80) { *out = c; return 1; } - if(c < 0x800) { - *out++ = 0xc0 | (0x1f & (c >> 6)); - *out = 0x80 | (0x3f & c); + if (c < 0x800) { + *out++ = 0xc0 | (0x1f & (c >> 6)); + *out = 0x80 | (0x3f & c); return 2; } - if(c < 0x10000) { + if (c < 0x10000) { *out++ = 0xe0 | (0x0f & (c >> 12)); *out++ = 0x80 | (0x3f & (c >> 6)); - *out = 0x80 | (0x3f & c); + *out = 0x80 | (0x3f & c); return 3; } - if(c < 0x200000) { + if (c < 0x200000) { *out++ = 0xf0 | (0x07 & (c >> 18)); *out++ = 0x80 | (0x3f & (c >> 12)); *out++ = 0x80 | (0x3f & (c >> 6)); - *out = 0x80 | (0x3f & c); + *out = 0x80 | (0x3f & c); return 4; } - - if(c < 0x4000000) { + + if (c < 0x4000000) { *out++ = 0xf8 | (0x03 & (c >> 24)); *out++ = 0x80 | (0x3f & (c >> 18)); *out++ = 0x80 | (0x3f & (c >> 12)); - *out++ = 0x80 | (0x3f & (c >> 6)); - *out++ = 0x80 | (0x3f & c); + *out++ = 0x80 | (0x3f & (c >> 6)); + *out++ = 0x80 | (0x3f & c); return 5; } @@ -288,17 +559,16 @@ put_utf8(char *out, int c) *out++ = 0x80 | (0x3f & (c >> 24)); *out++ = 0x80 | (0x3f & (c >> 18)); *out++ = 0x80 | (0x3f & (c >> 12)); - *out++ = 0x80 | (0x3f & (c >> 6)); - *out++ = 0x80 | (0x3f & c); + *out++ = 0x80 | (0x3f & (c >> 6)); + *out++ = 0x80 | (0x3f & c); return 6; } -char *utf8_lowercase_inplace(char *s) -{ - char *r = s; +char* utf8_lowercase_inplace(char* s) { + char* r = s; uint8_t c; - for ( ; *s; s++) { + for (; *s; s++) { /* FIXME: this is really wrong version of lowercase for utf-8 */ /* but it's a deep issue with the different locale handling */ c = (uint8_t)*s; @@ -308,26 +578,33 @@ char *utf8_lowercase_inplace(char *s) continue; } else if ((c & 0xf0) == 0xe0) { s++; - if (*s) s++; + if (*s) + s++; } else if ((c & 0xf8) == 0xf0) { s++; - if (*s) s++; - if (*s) s++; + if (*s) + s++; + if (*s) + s++; } } if (c >= 'A' && c <= 'Z') - *(char *)s = c - 'A' + 'a'; + *(char*)s = c - 'A' + 'a'; } return r; } -static int utf8_len(char first) -{ - if ((first & 0xe0) == 0xc0) return 2; - if ((first & 0xf0) == 0xe0) return 3; - if ((first & 0xf8) == 0xf0) return 4; - if ((first & 0xfc) == 0xf8) return 5; - if ((first & 0xfe) == 0xfc) return 6; +static int utf8_len(char first) { + if ((first & 0xe0) == 0xc0) + return 2; + if ((first & 0xf0) == 0xe0) + return 3; + if ((first & 0xf8) == 0xf0) + return 4; + if ((first & 0xfc) == 0xf8) + return 5; + if ((first & 0xfe) == 0xfc) + return 6; assert(0); return 1; } @@ -335,20 +612,22 @@ static int utf8_len(char first) /* * Remove the partial utf8 character at the end of the string */ -char *utf8_validate_inplace(char *s) -{ - if (s == NULL) return NULL; +char* utf8_validate_inplace(char* s) { + if (s == NULL) + return NULL; size_t i, l = strlen(s); - if (l < 1) return s; + if (l < 1) + return s; for (i = l; i > 0; i--) { - char c = s[i-1]; + char c = s[i - 1]; if ((c & 0x80) == 0) { - if (l != i) s[i] = '\0'; + if (l != i) + s[i] = '\0'; break; } if ((c & 0xc0) == 0xc0) { if (1 + l - i != utf8_len(c)) - s[i-1] = '\0'; + s[i - 1] = '\0'; break; } } @@ -359,22 +638,16 @@ char *utf8_validate_inplace(char *s) * */ -static void -sbuf_alloc_fail(size_t len) -{ +static void sbuf_alloc_fail(size_t len) { fprintf(stderr, "Unable to allocate %zd bytes\n", len); abort(); } -void -sbuf_init(sbuf_t *sb) -{ +void sbuf_init(sbuf_t* sb) { memset(sb, 0, sizeof(sbuf_t)); } -void -sbuf_init_fixed(sbuf_t *sb, int len) -{ +void sbuf_init_fixed(sbuf_t* sb, int len) { memset(sb, 0, sizeof(sbuf_t)); sb->sb_data = malloc(len); if (sb->sb_data == NULL) @@ -382,20 +655,16 @@ sbuf_init_fixed(sbuf_t *sb, int len) sb->sb_size = len; } -void -sbuf_free(sbuf_t *sb) -{ +void sbuf_free(sbuf_t* sb) { free(sb->sb_data); sb->sb_size = sb->sb_ptr = sb->sb_err = 0; - sb->sb_data = NULL; + sb->sb_data = NULL; } -void -sbuf_reset(sbuf_t *sb, int max_len) -{ +void sbuf_reset(sbuf_t* sb, int max_len) { sb->sb_ptr = sb->sb_err = 0; if (sb->sb_size > max_len) { - void *n = realloc(sb->sb_data, max_len); + void* n = realloc(sb->sb_data, max_len); if (n) { sb->sb_data = n; sb->sb_size = max_len; @@ -403,17 +672,13 @@ sbuf_reset(sbuf_t *sb, int max_len) } } -void -sbuf_reset_and_alloc(sbuf_t *sb, int len) -{ +void sbuf_reset_and_alloc(sbuf_t* sb, int len) { sbuf_realloc(sb, len); sb->sb_ptr = sb->sb_err = 0; } -void -sbuf_alloc_(sbuf_t *sb, int len) -{ - if(sb->sb_data == NULL) { +void sbuf_alloc_(sbuf_t* sb, int len) { + if (sb->sb_data == NULL) { sb->sb_size = len * 4 > 4000 ? len * 4 : 4000; sb->sb_data = malloc(sb->sb_size); return; @@ -422,16 +687,14 @@ sbuf_alloc_(sbuf_t *sb, int len) sb->sb_data = realloc(sb->sb_data, sb->sb_size); } - if(sb->sb_data == NULL) + if (sb->sb_data == NULL) sbuf_alloc_fail(sb->sb_size); } -void -sbuf_realloc(sbuf_t *sb, int len) -{ +void sbuf_realloc(sbuf_t* sb, int len) { if (sb->sb_data) { if (len != sb->sb_size) { - void *n = realloc(sb->sb_data, len); + void* n = realloc(sb->sb_data, len); if (n) { sb->sb_data = n; sb->sb_size = len; @@ -445,29 +708,23 @@ sbuf_realloc(sbuf_t *sb, int len) sbuf_alloc_fail(len); } -void -sbuf_replace(sbuf_t *sb, sbuf_t *src) -{ +void sbuf_replace(sbuf_t* sb, sbuf_t* src) { sbuf_free(sb); *sb = *src; sbuf_init(src); } -void -sbuf_append(sbuf_t *sb, const void *data, int len) -{ +void sbuf_append(sbuf_t* sb, const void* data, int len) { sbuf_alloc(sb, len); memcpy(sb->sb_data + sb->sb_ptr, data, len); sb->sb_ptr += len; } -void -sbuf_append_from_sbuf(sbuf_t *sb, sbuf_t *src) -{ +void sbuf_append_from_sbuf(sbuf_t* sb, sbuf_t* src) { if (sb->sb_ptr == 0) { sbuf_free(sb); sb->sb_data = src->sb_data; - sb->sb_ptr = src->sb_ptr; + sb->sb_ptr = src->sb_ptr; sb->sb_size = src->sb_size; sbuf_steal_data(src); } else { @@ -476,83 +733,63 @@ sbuf_append_from_sbuf(sbuf_t *sb, sbuf_t *src) } } -void -sbuf_put_be32(sbuf_t *sb, uint32_t u32) -{ +void sbuf_put_be32(sbuf_t* sb, uint32_t u32) { u32 = htonl(u32); sbuf_append(sb, &u32, 4); } -void -sbuf_put_be16(sbuf_t *sb, uint16_t u16) -{ +void sbuf_put_be16(sbuf_t* sb, uint16_t u16) { u16 = htons(u16); sbuf_append(sb, &u16, 2); } -void -sbuf_put_byte(sbuf_t *sb, uint8_t u8) -{ +void sbuf_put_byte(sbuf_t* sb, uint8_t u8) { sbuf_append(sb, &u8, 1); } -uint16_t sbuf_peek_u16(sbuf_t *sb, int off) -{ - uint8_t *p = sb->sb_data + off; +uint16_t sbuf_peek_u16(sbuf_t* sb, int off) { + uint8_t* p = sb->sb_data + off; if (ENDIAN_SWAP_COND(sb->sb_bswap)) return p[0] | (((uint16_t)p[1]) << 8); else return (((uint16_t)p[0]) << 8) | p[1]; } -uint16_t sbuf_peek_u16le(sbuf_t *sb, int off) -{ - uint8_t *p = sb->sb_data + off; +uint16_t sbuf_peek_u16le(sbuf_t* sb, int off) { + uint8_t* p = sb->sb_data + off; return p[0] | (((uint16_t)p[1]) << 8); } -uint16_t sbuf_peek_u16be(sbuf_t *sb, int off) -{ - uint8_t *p = sb->sb_data + off; +uint16_t sbuf_peek_u16be(sbuf_t* sb, int off) { + uint8_t* p = sb->sb_data + off; return (((uint16_t)p[0]) << 8) | p[1]; } -uint32_t sbuf_peek_u32(sbuf_t *sb, int off) -{ - uint8_t *p = sb->sb_data + off; +uint32_t sbuf_peek_u32(sbuf_t* sb, int off) { + uint8_t* p = sb->sb_data + off; if (ENDIAN_SWAP_COND(sb->sb_bswap)) - return p[0] | (((uint32_t)p[1]) << 8) | - (((uint32_t)p[2]) << 16) | (((uint32_t)p[3]) << 24); + return p[0] | (((uint32_t)p[1]) << 8) | (((uint32_t)p[2]) << 16) | (((uint32_t)p[3]) << 24); else - return (((uint16_t)p[0]) << 24) | (((uint16_t)p[1]) << 16) | - (((uint16_t)p[2]) << 8) | p[3]; + return (((uint16_t)p[0]) << 24) | (((uint16_t)p[1]) << 16) | (((uint16_t)p[2]) << 8) | p[3]; } -uint32_t sbuf_peek_u32le(sbuf_t *sb, int off) -{ - uint8_t *p = sb->sb_data + off; - return p[0] | (((uint32_t)p[1]) << 8) | - (((uint32_t)p[2]) << 16) | (((uint32_t)p[3]) << 24); +uint32_t sbuf_peek_u32le(sbuf_t* sb, int off) { + uint8_t* p = sb->sb_data + off; + return p[0] | (((uint32_t)p[1]) << 8) | (((uint32_t)p[2]) << 16) | (((uint32_t)p[3]) << 24); } -uint32_t sbuf_peek_u32be(sbuf_t *sb, int off) -{ - uint8_t *p = sb->sb_data + off; - return (((uint16_t)p[0]) << 24) | (((uint16_t)p[1]) << 16) | - (((uint16_t)p[2]) << 8) | p[3]; +uint32_t sbuf_peek_u32be(sbuf_t* sb, int off) { + uint8_t* p = sb->sb_data + off; + return (((uint16_t)p[0]) << 24) | (((uint16_t)p[1]) << 16) | (((uint16_t)p[2]) << 8) | p[3]; } -void -sbuf_cut(sbuf_t *sb, int off) -{ +void sbuf_cut(sbuf_t* sb, int off) { assert(off <= sb->sb_ptr); sb->sb_ptr = sb->sb_ptr - off; memmove(sb->sb_data, sb->sb_data + off, sb->sb_ptr); } -ssize_t -sbuf_read(sbuf_t *sb, int fd) -{ +ssize_t sbuf_read(sbuf_t* sb, int fd) { ssize_t n = read(fd, sb->sb_data + sb->sb_ptr, sb->sb_size - sb->sb_ptr); if (n > 0) sb->sb_ptr += n; @@ -563,10 +800,8 @@ sbuf_read(sbuf_t *sb, int fd) * */ -static uint8_t * -openssl_hash ( uint8_t *hash, const uint8_t *msg, size_t msglen, const EVP_MD *md ) -{ - EVP_MD_CTX *mdctx; +static uint8_t* openssl_hash(uint8_t* hash, const uint8_t* msg, size_t msglen, const EVP_MD* md) { + EVP_MD_CTX* mdctx; if ((mdctx = EVP_MD_CTX_create()) == NULL) return NULL; @@ -583,39 +818,32 @@ __error: return NULL; } -static char * -openssl_hash_hexstr ( const char *str, int lowercase, const EVP_MD *md, int len ) -{ - int i; - uint8_t hash[len]; - char *ret = malloc((len * 2) + 1); - const char *fmt = lowercase ? "%02x" : "%02X"; - if (ret == NULL) return NULL; - if (openssl_hash(hash, (const uint8_t *)str, strlen(str), md) == NULL) { +static char* openssl_hash_hexstr(const char* str, int lowercase, const EVP_MD* md, int len) { + int i; + uint8_t hash[len]; + char* ret = malloc((len * 2) + 1); + const char* fmt = lowercase ? "%02x" : "%02X"; + if (ret == NULL) + return NULL; + if (openssl_hash(hash, (const uint8_t*)str, strlen(str), md) == NULL) { free(ret); return NULL; } for (i = 0; i < len; i++) - sprintf(ret + i*2, fmt, hash[i]); - ret[len*2] = '\0'; + sprintf(ret + i * 2, fmt, hash[i]); + ret[len * 2] = '\0'; return ret; } -char * -md5sum ( const char *str, int lowercase ) -{ +char* md5sum(const char* str, int lowercase) { return openssl_hash_hexstr(str, lowercase, EVP_md5(), 16); } -char * -sha256sum ( const char *str, int lowercase ) -{ +char* sha256sum(const char* str, int lowercase) { return openssl_hash_hexstr(str, lowercase, EVP_sha256(), 32); } -char * -sha512sum256 ( const char *str, int lowercase ) -{ +char* sha512sum256(const char* str, int lowercase) { #if OPENSSL_VERSION_NUMBER >= 0x1010101fL && !defined(LIBRESSL_VERSION_NUMBER) return openssl_hash_hexstr(str, lowercase, EVP_sha512_256(), 32); #else @@ -623,37 +851,34 @@ sha512sum256 ( const char *str, int lowercase ) #endif } -char * -sha256sum_base64 ( const char *str ) -{ +char* sha256sum_base64(const char* str) { uint8_t hash[32]; - char *out = malloc(64); - if (out == NULL) return NULL; - if (openssl_hash(hash, (const uint8_t *)str, strlen(str), EVP_sha256()) == NULL) { + char* out = malloc(64); + if (out == NULL) + return NULL; + if (openssl_hash(hash, (const uint8_t*)str, strlen(str), EVP_sha256()) == NULL) { free(out); return NULL; } return base64_encode(out, 64, hash, 32); } -#define FILE_MODE_BITS(x) (x&(S_IRWXU|S_IRWXG|S_IRWXO)) +#define FILE_MODE_BITS(x) (x & (S_IRWXU | S_IRWXG | S_IRWXO)) -int -makedirs ( int subsys, const char *inpath, int mode, - int mstrict, gid_t gid, uid_t uid ) -{ - int err, ok; - size_t x; +int makedirs(int subsys, const char* inpath, int mode, int mstrict, gid_t gid, uid_t uid) { + int err, ok; + size_t x; struct stat st; - char *path; + char* path; - if (!inpath || !*inpath) return -1; + if (!inpath || !*inpath) + return -1; - x = 1; - ok = 1; + x = 1; + ok = 1; path = alloca(strlen(inpath) + 1); strcpy(path, inpath); - while(ok) { + while (ok) { ok = path[x]; if (path[x] == '/' || !path[x]) { path[x] = 0; @@ -661,26 +886,32 @@ makedirs ( int subsys, const char *inpath, int mode, err = mkdir(path, mode); if (!err && gid != -1 && uid != -1) err = chown(path, uid, gid); - if (!err && !stat(path, &st) && - FILE_MODE_BITS(mode) != FILE_MODE_BITS(st.st_mode)) { + if (!err && !stat(path, &st) && FILE_MODE_BITS(mode) != FILE_MODE_BITS(st.st_mode)) { err = chmod(path, mode); /* override umode */ if (!mstrict) { err = 0; - tvhwarn(subsys, "Unable to change directory permissions " - "to \"%o\" for \"%s\" (keeping \"%o\")", - mode, path, FILE_MODE_BITS(st.st_mode)); + tvhwarn(subsys, + "Unable to change directory permissions " + "to \"%o\" for \"%s\" (keeping \"%o\")", + mode, + path, + FILE_MODE_BITS(st.st_mode)); mode = FILE_MODE_BITS(st.st_mode); } } - tvhtrace(subsys, "Creating directory \"%s\" with octal permissions " - "\"%o\" gid %d uid %d", path, mode, gid, uid); + tvhtrace(subsys, + "Creating directory \"%s\" with octal permissions " + "\"%o\" gid %d uid %d", + path, + mode, + gid, + uid); } else { err = S_ISDIR(st.st_mode) ? 0 : 1; errno = ENOTDIR; } if (err) { - tvhalert(subsys, "Unable to create dir \"%s\": %s", - path, strerror(errno)); + tvhalert(subsys, "Unable to create dir \"%s\": %s", path, strerror(errno)); return -1; } path[x] = '/'; @@ -690,29 +921,30 @@ makedirs ( int subsys, const char *inpath, int mode, return 0; } -int -rmtree ( const char *path ) -{ - int err = 0; +int rmtree(const char* path) { + int err = 0; struct dirent de, *der; - struct stat st; - char buf[PATH_MAX]; - DIR *dir = opendir(path); - if (!dir) return -1; + struct stat st; + char buf[PATH_MAX]; + DIR* dir = opendir(path); + if (!dir) + return -1; while (!readdir_r(dir, &de, &der) && der) { if (!strcmp("..", de.d_name) || !strcmp(".", de.d_name)) continue; if (snprintf(buf, sizeof(buf), "%s/%s", path, de.d_name) >= sizeof(buf)) { - err = -ENAMETOOLONG; - break; + err = -ENAMETOOLONG; + break; } err = stat(buf, &st); - if (err) break; + if (err) + break; if (S_ISDIR(st.st_mode)) err = rmtree(buf); else err = unlink(buf); - if (err) break; + if (err) + break; } closedir(dir); if (!err) @@ -720,11 +952,9 @@ rmtree ( const char *path ) return err; } -char * -regexp_escape(const char* str) -{ - const char *a; - char *tmp, *b; +char* regexp_escape(const char* str) { + const char* a; + char * tmp, *b; if (!str) return NULL; a = str; @@ -764,15 +994,14 @@ char to_hex(char code) { /* Returns a url-encoded version of str IMPORTANT: be sure to free() the returned string after use http://www.geekhideout.com/urlcode.shtml */ -char *url_encode(const char *str) -{ +char* url_encode(const char* str) { char *buf = malloc(strlen(str) * 3 + 1), *pbuf = buf; while (*str) { if (isalnum(*str) || *str == '-' || *str == '_' || *str == '.' || *str == '~') *pbuf++ = *str; /*else if (*str == ' ') - *pbuf++ = '+';*/ - else + *pbuf++ = '+';*/ + else *pbuf++ = '%', *pbuf++ = to_hex(*str >> 4), *pbuf++ = to_hex(*str & 15); str++; } @@ -783,45 +1012,43 @@ char *url_encode(const char *str) /** * De-escape HTTP URL */ -void -http_deescape(char *s) -{ +void http_deescape(char* s) { char v, *d = s; - while(*s) { - if(*s == '+') { + while (*s) { + if (*s == '+') { *d++ = ' '; s++; - } else if(*s == '%') { + } else if (*s == '%') { s++; - switch(*s) { - case '0' ... '9': - v = (*s - '0') << 4; - break; - case 'a' ... 'f': - v = (*s - 'a' + 10) << 4; - break; - case 'A' ... 'F': - v = (*s - 'A' + 10) << 4; - break; - default: - *d = 0; - return; + switch (*s) { + case '0' ... '9': + v = (*s - '0') << 4; + break; + case 'a' ... 'f': + v = (*s - 'a' + 10) << 4; + break; + case 'A' ... 'F': + v = (*s - 'A' + 10) << 4; + break; + default: + *d = 0; + return; } s++; - switch(*s) { - case '0' ... '9': - v |= (*s - '0'); - break; - case 'a' ... 'f': - v |= (*s - 'a' + 10); - break; - case 'A' ... 'F': - v |= (*s - 'A' + 10); - break; - default: - *d = 0; - return; + switch (*s) { + case '0' ... '9': + v |= (*s - '0'); + break; + case 'a' ... 'f': + v |= (*s - 'a' + 10); + break; + case 'A' ... 'F': + v |= (*s - 'A' + 10); + break; + default: + *d = 0; + return; } s++; @@ -837,35 +1064,31 @@ http_deescape(char *s) * */ -static inline uint32_t mpegts_word32( const uint8_t *tsb ) -{ - //assert(((intptr_t)tsb & 3) == 0); - return *(uint32_t *)tsb; +static inline uint32_t mpegts_word32(const uint8_t* tsb) { + // assert(((intptr_t)tsb & 3) == 0); + return *(uint32_t*)tsb; } -int -mpegts_word_count ( const uint8_t *tsb, int len, uint32_t mask ) -{ +int mpegts_word_count(const uint8_t* tsb, int len, uint32_t mask) { uint32_t val; - int r = 0; + int r = 0; #if BYTE_ORDER == LITTLE_ENDIAN mask = bswap_32(mask); #endif - val = mpegts_word32(tsb) & mask; + val = mpegts_word32(tsb) & mask; while (len >= 188) { - if (len >= 4*188 && - (mpegts_word32(tsb+0*188) & mask) == val && - (mpegts_word32(tsb+1*188) & mask) == val && - (mpegts_word32(tsb+2*188) & mask) == val && - (mpegts_word32(tsb+3*188) & mask) == val) { - r += 4*188; - len -= 4*188; - tsb += 4*188; + if (len >= 4 * 188 && (mpegts_word32(tsb + 0 * 188) & mask) == val && + (mpegts_word32(tsb + 1 * 188) & mask) == val && + (mpegts_word32(tsb + 2 * 188) & mask) == val && + (mpegts_word32(tsb + 3 * 188) & mask) == val) { + r += 4 * 188; + len -= 4 * 188; + tsb += 4 * 188; } else if ((mpegts_word32(tsb) & mask) == val) { - r += 188; + r += 188; len -= 188; tsb += 188; } else { @@ -876,40 +1099,36 @@ mpegts_word_count ( const uint8_t *tsb, int len, uint32_t mask ) return r; } -static void -deferred_unlink_cb(void *s, int dearmed) -{ - if (unlink((const char *)s)) - tvherror(LS_MAIN, "unable to remove file '%s'", (const char *)s); +static void deferred_unlink_cb(void* s, int dearmed) { + if (unlink((const char*)s)) + tvherror(LS_MAIN, "unable to remove file '%s'", (const char*)s); free(s); } typedef struct { - char *filename; - char *rootdir; + char* filename; + char* rootdir; } deferred_unlink_t; -static void -deferred_unlink_dir_cb(void *s, int dearmed) -{ - deferred_unlink_t *du = s; - char *p; - int l; +static void deferred_unlink_dir_cb(void* s, int dearmed) { + deferred_unlink_t* du = s; + char* p; + int l; - if (unlink((const char *)du->filename)) - tvherror(LS_MAIN, "unable to remove file '%s'", (const char *)du->filename); + if (unlink((const char*)du->filename)) + tvherror(LS_MAIN, "unable to remove file '%s'", (const char*)du->filename); /* Remove all directories up to rootdir */ l = strlen(du->filename) - 1; p = du->filename; - for(; l >= 0; l--) { - if(p[l] == '/') { + for (; l >= 0; l--) { + if (p[l] == '/') { p[l] = 0; - if(strncmp(p, du->rootdir, l) == 0) + if (strncmp(p, du->rootdir, l) == 0) break; - if(rmdir(p) == -1) + if (rmdir(p) == -1) break; } } @@ -919,14 +1138,12 @@ deferred_unlink_dir_cb(void *s, int dearmed) free(du); } -int -deferred_unlink(const char *filename, const char *rootdir) -{ - deferred_unlink_t *du; - char *s, *p; - size_t l; - int r; - long max; +int deferred_unlink(const char* filename, const char* rootdir) { + deferred_unlink_t* du; + char * s, *p; + size_t l; + int r; + long max; l = strlen(filename); s = malloc(l + 9 + 1); @@ -950,29 +1167,24 @@ deferred_unlink(const char *filename, const char *rootdir) free(s); return r; } - if (rootdir == NULL){ - dvr_cutpoint_delete_files (filename); + if (rootdir == NULL) { + dvr_cutpoint_delete_files(filename); tasklet_arm_alloc(deferred_unlink_cb, s); - } - else { + } else { du = calloc(1, sizeof(*du)); if (du == NULL) { free(s); return -ENOMEM; } du->filename = s; - du->rootdir = strdup(rootdir); - dvr_cutpoint_delete_files (filename); + du->rootdir = strdup(rootdir); + dvr_cutpoint_delete_files(filename); tasklet_arm_alloc(deferred_unlink_dir_cb, du); } return 0; } -void -sha1_calc(uint8_t *dst, - const uint8_t *d1, size_t d1_len, - const uint8_t *d2, size_t d2_len) -{ +void sha1_calc(uint8_t* dst, const uint8_t* d1, size_t d1_len, const uint8_t* d2, size_t d2_len) { SHA_CTX shactx; SHA1_Init(&shactx); @@ -983,18 +1195,16 @@ sha1_calc(uint8_t *dst, SHA1_Final(dst, &shactx); } -uint32_t -gcdU32(uint32_t a, uint32_t b) -{ +uint32_t gcdU32(uint32_t a, uint32_t b) { uint32_t r; if (a < b) { - while((r = b % a) != 0) { + while ((r = b % a) != 0) { b = a; a = r; } return a; } else { - while((r = a % b) != 0) { + while ((r = a % b) != 0) { a = b; b = r; } @@ -1002,14 +1212,13 @@ gcdU32(uint32_t a, uint32_t b) } } -htsmsg_t *network_interfaces_enum(void *obj, const char *lang) -{ +htsmsg_t* network_interfaces_enum(void* obj, const char* lang) { #if ENABLE_IFNAMES - htsmsg_t *list = htsmsg_create_list(); - struct if_nameindex *ifnames = if_nameindex(); + htsmsg_t* list = htsmsg_create_list(); + struct if_nameindex* ifnames = if_nameindex(); if (ifnames) { - struct if_nameindex *ifname; + struct if_nameindex* ifname; for (ifname = ifnames; ifname->if_name; ifname++) htsmsg_add_msg(list, NULL, htsmsg_create_key_val(ifname->if_name, ifname->if_name)); if_freenameindex(ifnames); @@ -1021,24 +1230,25 @@ htsmsg_t *network_interfaces_enum(void *obj, const char *lang) #endif } -const char * -gmtime2local(time_t gmt, char *buf, size_t buflen) -{ +const char* gmtime2local(time_t gmt, char* buf, size_t buflen) { struct tm tm; localtime_r(&gmt, &tm); strftime(buf, buflen, "%F;%T(%z)", &tm); return buf; } -int -tvh_kill_to_sig(int tvh_kill) -{ +int tvh_kill_to_sig(int tvh_kill) { switch (tvh_kill) { - case TVH_KILL_TERM: return SIGTERM; - case TVH_KILL_INT: return SIGINT; - case TVH_KILL_HUP: return SIGHUP; - case TVH_KILL_USR1: return SIGUSR1; - case TVH_KILL_USR2: return SIGUSR2; + case TVH_KILL_TERM: + return SIGTERM; + case TVH_KILL_INT: + return SIGINT; + case TVH_KILL_HUP: + return SIGHUP; + case TVH_KILL_USR1: + return SIGUSR1; + case TVH_KILL_USR2: + return SIGUSR2; } return SIGKILL; } diff --git a/src/uuid.c b/src/uuid.c index acbdfd4dd..019ef94d2 100644 --- a/src/uuid.c +++ b/src/uuid.c @@ -27,7 +27,7 @@ #define RANDOM_PATH "/dev/urandom" -uint8_t ___uuid_empty[UUID_BIN_SIZE] = { 0 }; +uint8_t ___uuid_empty[UUID_BIN_SIZE] = {0}; static int fd = -1; @@ -38,33 +38,31 @@ static int fd = -1; /** * */ -static inline int -hexnibble(char c) -{ - switch(c) { - case '0' ... '9': return c - '0'; - case 'a' ... 'f': return c - 'a' + 10; - case 'A' ... 'F': return c - 'A' + 10; - default: - return -1; +static inline int hexnibble(char c) { + switch (c) { + case '0' ... '9': + return c - '0'; + case 'a' ... 'f': + return c - 'a' + 10; + case 'A' ... 'F': + return c - 'A' + 10; + default: + return -1; } } - /** * */ -int -hex2bin(uint8_t *buf, size_t buflen, const char *str) -{ +int hex2bin(uint8_t* buf, size_t buflen, const char* str) { int hi, lo; - while(*str) { - if(buflen == 0) + while (*str) { + if (buflen == 0) return -1; - if((hi = hexnibble(*str++)) == -1) + if ((hi = hexnibble(*str++)) == -1) return -1; - if((lo = hexnibble(*str++)) == -1) + if ((lo = hexnibble(*str++)) == -1) return -1; *buf++ = hi << 4 | lo; @@ -76,12 +74,10 @@ hex2bin(uint8_t *buf, size_t buflen, const char *str) /** * */ -char * -bin2hex(char *dst, size_t dstlen, const uint8_t *src, size_t srclen) -{ +char* bin2hex(char* dst, size_t dstlen, const uint8_t* src, size_t srclen) { static const char table[] = "0123456789abcdef"; - char *ret = dst; - while(dstlen > 2 && srclen > 0) { + char* ret = dst; + while (dstlen > 2 && srclen > 0) { *dst++ = table[*src >> 4]; *dst++ = table[*src & 0xf]; src++; @@ -96,9 +92,7 @@ bin2hex(char *dst, size_t dstlen, const uint8_t *src, size_t srclen) * UUID Handling * *************************************************************************/ -void -uuid_init ( void ) -{ +void uuid_init(void) { fd = tvh_open(RANDOM_PATH, O_RDONLY, 0); if (fd == -1) { tvherror(LS_UUID, "failed to open %s", RANDOM_PATH); @@ -106,9 +100,7 @@ uuid_init ( void ) } } -void -uuid_random ( uint8_t *buf, size_t bufsize ) -{ +void uuid_random(uint8_t* buf, size_t bufsize) { if (read(fd, buf, bufsize) != bufsize) { tvherror(LS_UUID, "random failed: %s", strerror(errno)); exit(1); @@ -116,9 +108,7 @@ uuid_random ( uint8_t *buf, size_t bufsize ) } /* Initialise binary */ -int -uuid_set ( tvh_uuid_t *u, const char *str ) -{ +int uuid_set(tvh_uuid_t* u, const char* str) { if (str) { if (strlen(str) != UUID_HEX_SIZE - 1) { memset(u, 0, sizeof(*u)); @@ -138,17 +128,13 @@ uuid_set ( tvh_uuid_t *u, const char *str ) } /* Initialise hex string */ -char * -uuid_get_hex ( const tvh_uuid_t *u, char *dst ) -{ +char* uuid_get_hex(const tvh_uuid_t* u, char* dst) { assert(dst); return bin2hex(dst, UUID_HEX_SIZE, u->bin, sizeof(u->bin)); } /* Validate the hexadecimal representation of uuid */ -int -uuid_hexvalid ( const char *uuid ) -{ +int uuid_hexvalid(const char* uuid) { int i; if (uuid == NULL) return 0; @@ -159,35 +145,29 @@ uuid_hexvalid ( const char *uuid ) } /* Init uuid set */ -void -uuid_set_init( tvh_uuid_set_t *us, uint32_t alloc_chunk ) -{ +void uuid_set_init(tvh_uuid_set_t* us, uint32_t alloc_chunk) { memset(us, 0, sizeof(*us)); us->us_alloc_chunk = alloc_chunk ?: 10; } /* Copy uuid set */ -tvh_uuid_set_t * -uuid_set_copy( tvh_uuid_set_t *dst, const tvh_uuid_set_t *src ) -{ +tvh_uuid_set_t* uuid_set_copy(tvh_uuid_set_t* dst, const tvh_uuid_set_t* src) { size_t size; memset(dst, 0, sizeof(*dst)); dst->us_alloc_chunk = src->us_alloc_chunk; - size = sizeof(tvh_uuid_t) * src->us_size; - dst->us_array = malloc(size); + size = sizeof(tvh_uuid_t) * src->us_size; + dst->us_array = malloc(size); if (dst->us_array == NULL) return NULL; memcpy(dst->us_array, src->us_array, size); - dst->us_size = src->us_size; + dst->us_size = src->us_size; dst->us_count = src->us_count; return dst; } /* Add an uuid to set */ -tvh_uuid_t * -uuid_set_add ( tvh_uuid_set_t *us, const tvh_uuid_t *u ) -{ - tvh_uuid_t *nu; +tvh_uuid_t* uuid_set_add(tvh_uuid_set_t* us, const tvh_uuid_t* u) { + tvh_uuid_t* nu; if (us->us_count >= us->us_size) { nu = realloc(us->us_array, sizeof(*u) * (us->us_size + us->us_alloc_chunk)); @@ -196,26 +176,22 @@ uuid_set_add ( tvh_uuid_set_t *us, const tvh_uuid_t *u ) us->us_array = nu; us->us_size += us->us_alloc_chunk; } - nu = &us->us_array[us->us_count++]; + nu = &us->us_array[us->us_count++]; *nu = *u; return nu; } /* Free uuid set */ -void -uuid_set_free ( tvh_uuid_set_t *us ) -{ +void uuid_set_free(tvh_uuid_set_t* us) { if (us) { free(us->us_array); - us->us_size = 0; + us->us_size = 0; us->us_count = 0; } } /* Destroy uuid set */ -void -uuid_set_destroy ( tvh_uuid_set_t *us ) -{ +void uuid_set_destroy(tvh_uuid_set_t* us) { if (us) { uuid_set_free(us); free(us); diff --git a/src/uuid.h b/src/uuid.h index ebadbb20c..fa651bcf2 100644 --- a/src/uuid.h +++ b/src/uuid.h @@ -23,8 +23,8 @@ #include #include -#define UUID_BIN_SIZE (16) -#define UUID_HEX_SIZE (33) // inc NUL +#define UUID_BIN_SIZE (16) +#define UUID_HEX_SIZE (33) // inc NUL extern uint8_t ___uuid_empty[UUID_BIN_SIZE]; @@ -35,100 +35,97 @@ typedef struct uuid { /* Structure for the uuid set */ typedef struct uuid_set { - tvh_uuid_t *us_array; - uint32_t us_count; - uint32_t us_size; - uint32_t us_alloc_chunk; + tvh_uuid_t* us_array; + uint32_t us_count; + uint32_t us_size; + uint32_t us_alloc_chunk; } tvh_uuid_set_t; /* Initialise subsystem */ -void uuid_init ( void ); +void uuid_init(void); /* Random bytes */ -void uuid_random ( uint8_t *buf, size_t bufsize ); +void uuid_random(uint8_t* buf, size_t bufsize); /* Set uuid */ -int uuid_set ( tvh_uuid_t *u, const char *str ); +int uuid_set(tvh_uuid_t* u, const char* str); /* Get hexa uuid, str must have length at least UUID_HEX_SIZE */ -char *uuid_get_hex ( const tvh_uuid_t *u, char *dst ); +char* uuid_get_hex(const tvh_uuid_t* u, char* dst); /** * Copy */ -static inline void uuid_duplicate ( tvh_uuid_t *dst, const tvh_uuid_t *src ) -{ +static inline void uuid_duplicate(tvh_uuid_t* dst, const tvh_uuid_t* src) { *dst = *src; } /** * Compare */ -static inline int uuid_cmp ( const tvh_uuid_t *a, const tvh_uuid_t *b ) -{ +static inline int uuid_cmp(const tvh_uuid_t* a, const tvh_uuid_t* b) { return memcmp(a->bin, b->bin, UUID_BIN_SIZE); } /** * Empty */ -static inline int uuid_empty ( const tvh_uuid_t *a ) -{ +static inline int uuid_empty(const tvh_uuid_t* a) { return memcmp(a->bin, ___uuid_empty, UUID_BIN_SIZE) == 0; } /** * Validate the hexadecimal representation of uuid */ -int uuid_hexvalid ( const char *uuid ); +int uuid_hexvalid(const char* uuid); /** * */ -void uuid_set_init( tvh_uuid_set_t *us, uint32_t alloc_chunk ); +void uuid_set_init(tvh_uuid_set_t* us, uint32_t alloc_chunk); /** * */ -tvh_uuid_set_t *uuid_set_copy( tvh_uuid_set_t *dst, const tvh_uuid_set_t *src ); +tvh_uuid_set_t* uuid_set_copy(tvh_uuid_set_t* dst, const tvh_uuid_set_t* src); /** * */ -tvh_uuid_t *uuid_set_add( tvh_uuid_set_t *us, const tvh_uuid_t *u ); +tvh_uuid_t* uuid_set_add(tvh_uuid_set_t* us, const tvh_uuid_t* u); /** * */ -void uuid_set_free( tvh_uuid_set_t *us ); +void uuid_set_free(tvh_uuid_set_t* us); /** * */ -void uuid_set_destroy( tvh_uuid_set_t *us ); +void uuid_set_destroy(tvh_uuid_set_t* us); /** * */ -static inline int uuid_set_empty( tvh_uuid_set_t *us ) - { return us->us_count == 0; } +static inline int uuid_set_empty(tvh_uuid_set_t* us) { + return us->us_count == 0; +} /** * */ #define UUID_SET_FOREACH(u, us, u32) \ - if ((us)->us_count > 0) \ - for ((u32) = 0, (u) = (us)->us_array; \ - (u32) < (us)->us_count; (u32)++, (u)++) + if ((us)->us_count > 0) \ + for ((u32) = 0, (u) = (us)->us_array; (u32) < (us)->us_count; (u32)++, (u)++) /** * Hex string to binary */ -int hex2bin ( uint8_t *buf, size_t buflen, const char *hex ); +int hex2bin(uint8_t* buf, size_t buflen, const char* hex); /** * Binary to hex string */ -char *bin2hex ( char *dst, size_t dstlen, const uint8_t *src, size_t srclen ); +char* bin2hex(char* dst, size_t dstlen, const uint8_t* src, size_t srclen); #endif /* __TVH_UUID_H__ */ diff --git a/src/watchdog.c b/src/watchdog.c index 9fcb4d857..e954b2d4b 100644 --- a/src/watchdog.c +++ b/src/watchdog.c @@ -21,17 +21,16 @@ #include -static pthread_t watchdog_tid; +static pthread_t watchdog_tid; static tvh_mutex_t watchdog_exiting_mutex; -static tvh_cond_t watchdog_exiting_cond; -static int watchdog_exiting; /* 1 if exit has been requested */ -static int watchdog_enabled; /* 1 if watchdog was enabled for the systemd unit */ -static uint64_t watchdog_interval_usec; /* value from .service divided by 2 */ +static tvh_cond_t watchdog_exiting_cond; +static int watchdog_exiting; /* 1 if exit has been requested */ +static int watchdog_enabled; /* 1 if watchdog was enabled for the systemd unit */ +static uint64_t watchdog_interval_usec; /* value from .service divided by 2 */ -static void* watchdog_thread(void* aux) -{ +static void* watchdog_thread(void* aux) { int exiting = 0; - (void) aux; /* ignore */ + (void)aux; /* ignore */ sd_notify(0, "READY=1"); tvh_mutex_lock(&watchdog_exiting_mutex); while (!exiting) { @@ -40,7 +39,9 @@ static void* watchdog_thread(void* aux) * Just keep ticking regardless the return value; its intention is * to pace the loop down, and let us exit fast when the time comes */ - tvh_cond_timedwait(&watchdog_exiting_cond, &watchdog_exiting_mutex, mclk() + watchdog_interval_usec); + tvh_cond_timedwait(&watchdog_exiting_cond, + &watchdog_exiting_mutex, + mclk() + watchdog_interval_usec); if (!watchdog_exiting) { tvh_mutex_lock(&global_lock); tvh_mutex_unlock(&global_lock); @@ -54,8 +55,7 @@ static void* watchdog_thread(void* aux) return NULL; } -void watchdog_init(void) -{ +void watchdog_init(void) { /* * I doubt MONOCLOCK_RESOLUTION is going to change, but if it does, * let's break this @@ -66,7 +66,7 @@ void watchdog_init(void) watchdog_enabled = sd_watchdog_enabled(0, &watchdog_interval_usec) > 0; if (watchdog_enabled) { - /* suggested by sd_watchdog_enabled documentation: */ + /* suggested by sd_watchdog_enabled documentation: */ watchdog_interval_usec /= 2; watchdog_exiting = 0; @@ -77,8 +77,7 @@ void watchdog_init(void) } } -void watchdog_done(void) -{ +void watchdog_done(void) { if (watchdog_enabled) { tvh_mutex_lock(&watchdog_exiting_mutex); watchdog_exiting = 1; diff --git a/src/watchdog.h b/src/watchdog.h index 68af82831..ead42e0c1 100644 --- a/src/watchdog.h +++ b/src/watchdog.h @@ -28,10 +28,9 @@ void watchdog_done(void); #else /* #if ENABLE_LIBSYSTEMD_DAEMON */ -static inline void watchdog_init(void) { } -static inline void watchdog_done(void) { } +static inline void watchdog_init(void) {} +static inline void watchdog_done(void) {} #endif /* #if else ENABLE_LIBSYSTEMD_DAEMON */ - #endif /* WATCHDOG_H_ */ diff --git a/src/webui/comet.c b/src/webui/comet.c index b4c9c8fe5..15a710606 100644 --- a/src/webui/comet.c +++ b/src/webui/comet.c @@ -32,54 +32,49 @@ #include "memoryinfo.h" static tvh_mutex_t comet_mutex = TVH_THREAD_MUTEX_INITIALIZER; -static tvh_cond_t comet_cond; -static int comet_waiting; +static tvh_cond_t comet_cond; +static int comet_waiting; #define MAILBOX_UNUSED_TIMEOUT 20 #define MAILBOX_EMPTY_REPLY_TIMEOUT 10 -//#define mbdebug(fmt...) printf(fmt); +// #define mbdebug(fmt...) printf(fmt); #define mbdebug(fmt...) - static LIST_HEAD(, comet_mailbox) mailboxes; int mailbox_tally; int comet_running; static memoryinfo_t comet_memoryinfo = { - .my_name = "Comet", + .my_name = "Comet", }; typedef struct comet_mailbox { - char *cmb_boxid; /* SHA-1 hash */ - char *cmb_lang; /* UI language */ - int cmb_refcount; - int cmb_restricted; /* !admin */ - htsmsg_t *cmb_messages; /* A vector */ - int64_t cmb_last_used; + char* cmb_boxid; /* SHA-1 hash */ + char* cmb_lang; /* UI language */ + int cmb_refcount; + int cmb_restricted; /* !admin */ + htsmsg_t* cmb_messages; /* A vector */ + int64_t cmb_last_used; LIST_ENTRY(comet_mailbox) cmb_link; int cmb_debug; } comet_mailbox_t; - /** * */ -static void -cmb_destroy(comet_mailbox_t *cmb) -{ +static void cmb_destroy(comet_mailbox_t* cmb) { mbdebug("mailbox[%s]: destroyed\n", cmb->cmb_boxid); - if(cmb->cmb_messages != NULL) + if (cmb->cmb_messages != NULL) htsmsg_destroy(cmb->cmb_messages); LIST_REMOVE(cmb, cmb_link); memoryinfo_free(&comet_memoryinfo, - sizeof(*cmb) + - (strlen(cmb->cmb_boxid) + 1) + - (cmb->cmb_lang ? strlen(cmb->cmb_lang) + 1 : 0)); + sizeof(*cmb) + (strlen(cmb->cmb_boxid) + 1) + + (cmb->cmb_lang ? strlen(cmb->cmb_lang) + 1 : 0)); free(cmb->cmb_lang); free(cmb->cmb_boxid); @@ -89,18 +84,15 @@ cmb_destroy(comet_mailbox_t *cmb) /** * */ -void -comet_flush(void) -{ +void comet_flush(void) { comet_mailbox_t *cmb, *next; tvh_mutex_lock(&comet_mutex); - for(cmb = LIST_FIRST(&mailboxes); cmb != NULL; cmb = next) { + for (cmb = LIST_FIRST(&mailboxes); cmb != NULL; cmb = next) { next = LIST_NEXT(cmb, cmb_link); - if(cmb->cmb_refcount == 1 && - cmb->cmb_last_used && cmb->cmb_last_used + sec2mono(60) < mclk()) + if (cmb->cmb_refcount == 1 && cmb->cmb_last_used && cmb->cmb_last_used + sec2mono(60) < mclk()) cmb_destroy(cmb); } tvh_mutex_unlock(&comet_mutex); @@ -109,58 +101,53 @@ comet_flush(void) /** * */ -static comet_mailbox_t * -comet_mailbox_create(const char *lang) -{ - comet_mailbox_t *cmb = calloc(1, sizeof(comet_mailbox_t)); +static comet_mailbox_t* comet_mailbox_create(const char* lang) { + comet_mailbox_t* cmb = calloc(1, sizeof(comet_mailbox_t)); struct timeval tv; - uint8_t sum[20]; - char id[20 * 2 + 1]; - int i; - SHA_CTX sha1; + uint8_t sum[20]; + char id[20 * 2 + 1]; + int i; + SHA_CTX sha1; gettimeofday(&tv, NULL); SHA1_Init(&sha1); - SHA1_Update(&sha1, (void *)&tv, sizeof(tv)); - SHA1_Update(&sha1, (void *)&mailbox_tally, sizeof(uint32_t)); + SHA1_Update(&sha1, (void*)&tv, sizeof(tv)); + SHA1_Update(&sha1, (void*)&mailbox_tally, sizeof(uint32_t)); SHA1_Final(sum, &sha1); - for(i = 0; i < sizeof(sum); i++) { + for (i = 0; i < sizeof(sum); i++) { id[i * 2 + 0] = "0123456789abcdef"[sum[i] >> 4]; id[i * 2 + 1] = "0123456789abcdef"[sum[i] & 15]; } id[40] = 0; - cmb->cmb_boxid = strdup(id); - cmb->cmb_lang = lang ? strdup(lang) : NULL; - cmb->cmb_refcount = 1; + cmb->cmb_boxid = strdup(id); + cmb->cmb_lang = lang ? strdup(lang) : NULL; + cmb->cmb_refcount = 1; cmb->cmb_last_used = mclk(); mailbox_tally++; LIST_INSERT_HEAD(&mailboxes, cmb, cmb_link); - memoryinfo_alloc(&comet_memoryinfo, sizeof(*cmb) + - (strlen(id) + 1) + - (lang ? strlen(lang) + 1 : 0)); + memoryinfo_alloc(&comet_memoryinfo, + sizeof(*cmb) + (strlen(id) + 1) + (lang ? strlen(lang) + 1 : 0)); return cmb; } /** * */ -static void -comet_access_update(http_connection_t *hc, comet_mailbox_t *cmb) -{ +static void comet_access_update(http_connection_t* hc, comet_mailbox_t* cmb) { extern int access_noacl; - htsmsg_t *m = htsmsg_create_map(); - const char *username = ""; - int64_t bfree, bused, btotal; - int dvr = !http_access_verify(hc, ACCESS_RECORDER); - int admin = !http_access_verify(hc, ACCESS_ADMIN); - const char *s; + htsmsg_t* m = htsmsg_create_map(); + const char* username = ""; + int64_t bfree, bused, btotal; + int dvr = !http_access_verify(hc, ACCESS_RECORDER); + int admin = !http_access_verify(hc, ACCESS_ADMIN); + const char* s; htsmsg_add_str(m, "notificationClass", "accessUpdate"); @@ -168,10 +155,18 @@ comet_access_update(http_connection_t *hc, comet_mailbox_t *cmb) username = hc->hc_access->aa_username ?: ""; switch (hc->hc_access->aa_uilevel) { - case UILEVEL_BASIC: s = "basic"; break; - case UILEVEL_ADVANCED: s = "advanced"; break; - case UILEVEL_EXPERT: s = "expert"; break; - default: s = NULL; break; + case UILEVEL_BASIC: + s = "basic"; + break; + case UILEVEL_ADVANCED: + s = "advanced"; + break; + case UILEVEL_EXPERT: + s = "expert"; + break; + default: + s = NULL; + break; } if (s) { htsmsg_add_str(m, "uilevel", s); @@ -189,10 +184,10 @@ comet_access_update(http_connection_t *hc, comet_mailbox_t *cmb) htsmsg_add_str(m, "username", username); if (hc->hc_peer_ipstr) htsmsg_add_str(m, "address", hc->hc_peer_ipstr); - htsmsg_add_u32(m, "dvr", dvr); - htsmsg_add_u32(m, "admin", admin); + htsmsg_add_u32(m, "dvr", dvr); + htsmsg_add_u32(m, "admin", admin); - htsmsg_add_s64(m, "time", time(NULL)); + htsmsg_add_s64(m, "time", time(NULL)); if (config.cookie_expires) htsmsg_add_u32(m, "cookie_expires", config.cookie_expires); @@ -212,7 +207,7 @@ comet_access_update(http_connection_t *hc, comet_mailbox_t *cmb) if (admin && config.wizard) htsmsg_add_str(m, "wizard", config.wizard); - if(cmb->cmb_messages == NULL) + if (cmb->cmb_messages == NULL) cmb->cmb_messages = htsmsg_create_list(); htsmsg_add_msg(cmb->cmb_messages, NULL, m); } @@ -220,29 +215,27 @@ comet_access_update(http_connection_t *hc, comet_mailbox_t *cmb) /** * */ -static void -comet_serverIpPort(http_connection_t *hc, comet_mailbox_t *cmb) -{ - char buf[50]; +static void comet_serverIpPort(http_connection_t* hc, comet_mailbox_t* cmb) { + char buf[50]; uint32_t port; tcp_get_str_from_ip(hc->hc_self, buf, 50); - if(hc->hc_self->ss_family == AF_INET) + if (hc->hc_self->ss_family == AF_INET) port = ((struct sockaddr_in*)hc->hc_self)->sin_port; - else if(hc->hc_self->ss_family == AF_INET6) + else if (hc->hc_self->ss_family == AF_INET6) port = ((struct sockaddr_in6*)hc->hc_self)->sin6_port; else port = 0; - htsmsg_t *m = htsmsg_create_map(); + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "notificationClass", "setServerIpPort"); htsmsg_add_str(m, "ip", buf); htsmsg_add_u32(m, "port", ntohs(port)); - if(cmb->cmb_messages == NULL) + if (cmb->cmb_messages == NULL) cmb->cmb_messages = htsmsg_create_list(); htsmsg_add_msg(cmb->cmb_messages, NULL, m); } @@ -250,10 +243,8 @@ comet_serverIpPort(http_connection_t *hc, comet_mailbox_t *cmb) /** * */ -static htsmsg_t * -comet_message(comet_mailbox_t *cmb, int include_boxid, int ignore_null) -{ - htsmsg_t *m; +static htsmsg_t* comet_message(comet_mailbox_t* cmb, int include_boxid, int ignore_null) { + htsmsg_t* m; if (ignore_null && cmb->cmb_messages == NULL) return NULL; @@ -261,7 +252,7 @@ comet_message(comet_mailbox_t *cmb, int include_boxid, int ignore_null) if (include_boxid) htsmsg_add_str(m, "boxid", cmb->cmb_boxid); htsmsg_add_msg(m, "messages", cmb->cmb_messages ?: htsmsg_create_list()); - cmb->cmb_messages = NULL; + cmb->cmb_messages = NULL; cmb->cmb_last_used = mclk(); return m; } @@ -269,22 +260,21 @@ comet_message(comet_mailbox_t *cmb, int include_boxid, int ignore_null) /** * */ -static comet_mailbox_t * -comet_find_mailbox(http_connection_t *hc, const char *cometid, const char *lang, int create) -{ - comet_mailbox_t *cmb = NULL; +static comet_mailbox_t* +comet_find_mailbox(http_connection_t* hc, const char* cometid, const char* lang, int create) { + comet_mailbox_t* cmb = NULL; if (!atomic_get(&comet_running)) return NULL; if (cometid != NULL) - LIST_FOREACH(cmb, &mailboxes, cmb_link) - if(!strcmp(cmb->cmb_boxid, cometid)) - break; + LIST_FOREACH (cmb, &mailboxes, cmb_link) + if (!strcmp(cmb->cmb_boxid, cometid)) + break; if (!create) return cmb; - + if (cmb == NULL) { cmb = comet_mailbox_create(lang); comet_access_update(hc, cmb); @@ -295,7 +285,9 @@ comet_find_mailbox(http_connection_t *hc, const char *cometid, const char *lang, if (!cmb->cmb_restricted) { cmb->cmb_restricted = 1; tvh_mutex_unlock(&comet_mutex); - comet_mailbox_add_logmsg(tvh_gettext_lang(lang, N_("Restricted log mode (no administrator)")), 0, 0); + comet_mailbox_add_logmsg(tvh_gettext_lang(lang, N_("Restricted log mode (no administrator)")), + 0, + 0); tvh_mutex_lock(&comet_mutex); } } @@ -306,18 +298,16 @@ comet_find_mailbox(http_connection_t *hc, const char *cometid, const char *lang, /** * Poll callback */ -static int -comet_mailbox_poll(http_connection_t *hc, const char *remain, void *opaque) -{ - comet_mailbox_t *cmb = NULL; - const char *cometid = http_arg_get(&hc->hc_req_args, "boxid"); - const char *immediate = http_arg_get(&hc->hc_req_args, "immediate"); - const char *lang = hc->hc_access->aa_lang_ui; - int im = immediate ? atoi(immediate) : 0, e; - int64_t mono; - htsmsg_t *m; - - if(!im) +static int comet_mailbox_poll(http_connection_t* hc, const char* remain, void* opaque) { + comet_mailbox_t* cmb = NULL; + const char* cometid = http_arg_get(&hc->hc_req_args, "boxid"); + const char* immediate = http_arg_get(&hc->hc_req_args, "immediate"); + const char* lang = hc->hc_access->aa_lang_ui; + int im = immediate ? atoi(immediate) : 0, e; + int64_t mono; + htsmsg_t* m; + + if (!im) tvh_safe_usleep(100000); /* Always sleep 0.1 sec to avoid comet storms */ tvh_mutex_lock(&comet_mutex); @@ -327,7 +317,7 @@ comet_mailbox_poll(http_connection_t *hc, const char *remain, void *opaque) return HTTP_STATUS_BAD_REQUEST; } - if(!im && cmb->cmb_messages == NULL) { + if (!im && cmb->cmb_messages == NULL) { mono = mclk() + sec2mono(10); atomic_add(&comet_waiting, 1); do { @@ -354,15 +344,13 @@ comet_mailbox_poll(http_connection_t *hc, const char *remain, void *opaque) /** * Poll callback */ -static int -comet_mailbox_dbg(http_connection_t *hc, const char *remain, void *opaque) -{ - comet_mailbox_t *cmb = NULL; - const char *cometid = http_arg_get(&hc->hc_req_args, "boxid"); - const char *lang = hc->hc_access->aa_lang_ui; - const char *s; - - if(cometid == NULL) +static int comet_mailbox_dbg(http_connection_t* hc, const char* remain, void* opaque) { + comet_mailbox_t* cmb = NULL; + const char* cometid = http_arg_get(&hc->hc_req_args, "boxid"); + const char* lang = hc->hc_access->aa_lang_ui; + const char* s; + + if (cometid == NULL) return HTTP_STATUS_BAD_REQUEST; tvh_mutex_lock(&comet_mutex); @@ -371,18 +359,18 @@ comet_mailbox_dbg(http_connection_t *hc, const char *remain, void *opaque) char buf[64]; cmb->cmb_debug = !cmb->cmb_debug; - if(cmb->cmb_messages == NULL) + if (cmb->cmb_messages == NULL) cmb->cmb_messages = htsmsg_create_list(); - if(cmb->cmb_restricted || http_access_verify(hc, ACCESS_ADMIN)) + if (cmb->cmb_restricted || http_access_verify(hc, ACCESS_ADMIN)) s = N_("Only admin can watch the realtime log."); - else if(cmb->cmb_debug) + else if (cmb->cmb_debug) s = N_("Loglevel debug: enabled"); else s = N_("Loglevel debug: disabled"); snprintf(buf, sizeof(buf), "%s", tvh_gettext_lang(lang, s)); - htsmsg_t *m = htsmsg_create_map(); + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "notificationClass", "logmessage"); htsmsg_add_str(m, "logtxt", buf); htsmsg_add_msg(cmb->cmb_messages, NULL, m); @@ -399,15 +387,14 @@ comet_mailbox_dbg(http_connection_t *hc, const char *remain, void *opaque) * */ static void -comet_mailbox_ws_msg(http_connection_t *hc, comet_mailbox_t *cmb, int first, htsmsg_t *msg) -{ - htsmsg_t *m = NULL; +comet_mailbox_ws_msg(http_connection_t* hc, comet_mailbox_t* cmb, int first, htsmsg_t* msg) { + htsmsg_t* m = NULL; tvh_mutex_lock(&comet_mutex); if (!atomic_get(&comet_running)) { tvh_mutex_unlock(&comet_mutex); return; } - m = comet_message(cmb, first, 1); + m = comet_message(cmb, first, 1); cmb->cmb_last_used = 0; tvh_mutex_unlock(&comet_mutex); if (m) { @@ -419,14 +406,12 @@ comet_mailbox_ws_msg(http_connection_t *hc, comet_mailbox_t *cmb, int first, hts /** * Websocket handler */ -static int -comet_mailbox_ws(http_connection_t *hc, const char *remain, void *opaque) -{ - int res, first = 1; - htsmsg_t *msg; - const char *cometid = http_arg_get(&hc->hc_req_args, "boxid"); - const char *lang = hc->hc_access->aa_lang_ui; - comet_mailbox_t *cmb; +static int comet_mailbox_ws(http_connection_t* hc, const char* remain, void* opaque) { + int res, first = 1; + htsmsg_t* msg; + const char* cometid = http_arg_get(&hc->hc_req_args, "boxid"); + const char* lang = hc->hc_access->aa_lang_ui; + comet_mailbox_t* cmb; res = http_send_header_websocket(hc, "tvheadend-comet"); @@ -466,10 +451,8 @@ comet_mailbox_ws(http_connection_t *hc, const char *remain, void *opaque) /** * */ -void -comet_init(void) -{ - http_path_t *hp; +void comet_init(void) { + http_path_t* hp; memoryinfo_register(&comet_memoryinfo); tvh_mutex_lock(&comet_mutex); @@ -477,16 +460,14 @@ comet_init(void) atomic_set(&comet_running, 1); atomic_set(&comet_waiting, 0); tvh_mutex_unlock(&comet_mutex); - hp = http_path_add("/comet/ws", NULL, comet_mailbox_ws, ACCESS_WEB_INTERFACE); + hp = http_path_add("/comet/ws", NULL, comet_mailbox_ws, ACCESS_WEB_INTERFACE); hp->hp_flags = HTTP_PATH_WEBSOCKET; - http_path_add("/comet/poll", NULL, comet_mailbox_poll, ACCESS_WEB_INTERFACE); - http_path_add("/comet/debug", NULL, comet_mailbox_dbg, ACCESS_WEB_INTERFACE); + http_path_add("/comet/poll", NULL, comet_mailbox_poll, ACCESS_WEB_INTERFACE); + http_path_add("/comet/debug", NULL, comet_mailbox_dbg, ACCESS_WEB_INTERFACE); } -void -comet_done(void) -{ - comet_mailbox_t *cmb; +void comet_done(void) { + comet_mailbox_t* cmb; tvh_mutex_lock(&comet_mutex); atomic_set(&comet_running, 0); @@ -509,9 +490,7 @@ comet_done(void) /** * */ -static void -comet_mailbox_rewrite_str(htsmsg_t *m, const char *key, const char *lang) -{ +static void comet_mailbox_rewrite_str(htsmsg_t* m, const char* key, const char* lang) { const char *s = htsmsg_get_str(m, key), *p; if (s) { p = tvh_gettext_lang(lang, s); @@ -520,12 +499,10 @@ comet_mailbox_rewrite_str(htsmsg_t *m, const char *key, const char *lang) } } -static void -comet_mailbox_rewrite_title(htsmsg_t *m, const char *lang) -{ - idnode_t *in; - const char *s = htsmsg_get_str(m, "uuid"); - char buf[384]; +static void comet_mailbox_rewrite_title(htsmsg_t* m, const char* lang) { + idnode_t* in; + const char* s = htsmsg_get_str(m, "uuid"); + char buf[384]; if (s) { idnode_lock(); in = idnode_find(s, NULL, NULL); @@ -535,27 +512,23 @@ comet_mailbox_rewrite_title(htsmsg_t *m, const char *lang) } } -static void -comet_mailbox_rewrite_msg(int rewrite, htsmsg_t *m, const char *lang) -{ +static void comet_mailbox_rewrite_msg(int rewrite, htsmsg_t* m, const char* lang) { switch (rewrite) { - case NOTIFY_REWRITE_TITLE: - comet_mailbox_rewrite_title(m, lang); - break; - case NOTIFY_REWRITE_SUBSCRIPTIONS: - comet_mailbox_rewrite_str(m, "state", lang); - break; + case NOTIFY_REWRITE_TITLE: + comet_mailbox_rewrite_title(m, lang); + break; + case NOTIFY_REWRITE_SUBSCRIPTIONS: + comet_mailbox_rewrite_str(m, "state", lang); + break; } } /** * */ -void -comet_mailbox_add_message(htsmsg_t *m, int isdebug, int isrestricted, int rewrite) -{ - comet_mailbox_t *cmb; - htsmsg_t *e; +void comet_mailbox_add_message(htsmsg_t* m, int isdebug, int isrestricted, int rewrite) { + comet_mailbox_t* cmb; + htsmsg_t* e; if (!atomic_get(&comet_running)) return; @@ -563,15 +536,15 @@ comet_mailbox_add_message(htsmsg_t *m, int isdebug, int isrestricted, int rewrit tvh_mutex_lock(&comet_mutex); if (atomic_get(&comet_running)) { - LIST_FOREACH(cmb, &mailboxes, cmb_link) { + LIST_FOREACH (cmb, &mailboxes, cmb_link) { - if(isrestricted && cmb->cmb_restricted) + if (isrestricted && cmb->cmb_restricted) continue; - if(isdebug && !cmb->cmb_debug) + if (isdebug && !cmb->cmb_debug) continue; - - if(cmb->cmb_messages == NULL) + + if (cmb->cmb_messages == NULL) cmb->cmb_messages = htsmsg_create_list(); e = htsmsg_copy(m); if (cmb->cmb_lang && rewrite) @@ -587,10 +560,8 @@ comet_mailbox_add_message(htsmsg_t *m, int isdebug, int isrestricted, int rewrit /** * */ -void -comet_mailbox_add_logmsg(const char *txt, int isdebug, int rewrite) -{ - htsmsg_t *m = htsmsg_create_map(); +void comet_mailbox_add_logmsg(const char* txt, int isdebug, int rewrite) { + htsmsg_t* m = htsmsg_create_map(); htsmsg_add_str(m, "notificationClass", "logmessage"); htsmsg_add_str(m, "logtxt", txt); comet_mailbox_add_message(m, isdebug, 1, 0); diff --git a/src/webui/doc_md.c b/src/webui/doc_md.c index e4f776cfe..42d8b5609 100644 --- a/src/webui/doc_md.c +++ b/src/webui/doc_md.c @@ -22,32 +22,26 @@ #include "http.h" #include "docs.h" -static int md_doc(htsbuf_queue_t *hq, const char **doc, const char *lang, int nl); -static int md_class(htsbuf_queue_t *hq, const char *clazz, const char *lang, - int hdr, int docs, int props); +static int md_doc(htsbuf_queue_t* hq, const char** doc, const char* lang, int nl); +static int +md_class(htsbuf_queue_t* hq, const char* clazz, const char* lang, int hdr, int docs, int props); /* */ -static int -md_nl(htsbuf_queue_t *hq, int nl) -{ +static int md_nl(htsbuf_queue_t* hq, int nl) { if (nl) htsbuf_append(hq, "\n", 1); return 1; } /* */ -static void -md_header(htsbuf_queue_t *hq, const char *prefix, const char *s) -{ +static void md_header(htsbuf_queue_t* hq, const char* prefix, const char* s) { htsbuf_append_str(hq, prefix); htsbuf_append_str(hq, s); htsbuf_append(hq, "\n", 1); } /* */ -static void -md_style(htsbuf_queue_t *hq, const char *style, const char *s) -{ +static void md_style(htsbuf_queue_t* hq, const char* style, const char* s) { size_t l = strlen(style); htsbuf_append(hq, style, l); htsbuf_append_str(hq, s); @@ -55,11 +49,9 @@ md_style(htsbuf_queue_t *hq, const char *style, const char *s) } /* */ -static void -md_text(htsbuf_queue_t *hq, const char *first, const char *next, const char *text) -{ +static void md_text(htsbuf_queue_t* hq, const char* first, const char* next, const char* text) { char *s, *t, *p; - int col, nl; + int col, nl; t = s = p = tvh_strdupa(text); col = nl = 0; @@ -79,7 +71,7 @@ md_text(htsbuf_queue_t *hq, const char *first, const char *next, const char *tex t = s = p; } else if (*s <= ' ') { *s = ' '; - p = ++s; + p = ++s; } else { s++; } @@ -95,31 +87,32 @@ md_text(htsbuf_queue_t *hq, const char *first, const char *next, const char *tex } /* */ -static int -md_props(htsbuf_queue_t *hq, htsmsg_t *m, const char *lang, int nl) -{ - htsmsg_t *l, *n, *e, *x; +static int md_props(htsbuf_queue_t* hq, htsmsg_t* m, const char* lang, int nl) { + htsmsg_t * l, *n, *e, *x; htsmsg_field_t *f, *f2; - const char *s; - int first = 1, b; + const char* s; + int first = 1, b; l = htsmsg_get_list(m, "props"); if (l == NULL) return nl; HTSMSG_FOREACH(f, l) { n = htsmsg_field_get_map(f); - if (!n) continue; - if (!htsmsg_get_bool(n, "noui", &b) && b) continue; + if (!n) + continue; + if (!htsmsg_get_bool(n, "noui", &b) && b) + continue; s = htsmsg_get_str(n, "caption"); - if (!s) continue; + if (!s) + continue; if (first) { nl = md_nl(hq, nl); htsbuf_append_str(hq, "### "); htsbuf_append_str(hq, tvh_gettext_lang(lang, N_("Items"))); md_nl(hq, 1); md_nl(hq, 1); - //htsbuf_append_str(hq, tvh_gettext_lang(lang, N_("The items have the following functions:"))); - //md_nl(hq, 1); + // htsbuf_append_str(hq, tvh_gettext_lang(lang, N_("The items have the following + // functions:"))); md_nl(hq, 1); first = 0; } nl = md_nl(hq, nl); @@ -164,29 +157,27 @@ md_props(htsbuf_queue_t *hq, htsmsg_t *m, const char *lang, int nl) } /* */ -static void -md_render(htsbuf_queue_t *hq, const char *doc, const char *lang) -{ - const struct tvh_doc_page *page; +static void md_render(htsbuf_queue_t* hq, const char* doc, const char* lang) { + const struct tvh_doc_page* page; if (doc[0] == '\xff') { switch (doc[1]) { - case 1: - htsbuf_append_str(hq, tvh_gettext_lang(lang, doc + 2)); - break; - case 2: - md_class(hq, doc + 2, lang, 0, 1, 0); - break; - case 3: - md_class(hq, doc + 2, lang, 0, 0, 1); - break; - case 4: - for (page = tvh_doc_markdown_pages; page->name; page++) - if (!strcmp(page->name, doc + 2)) { - if (page->strings) - md_doc(hq, page->strings, lang, 0); - break; - } - break; + case 1: + htsbuf_append_str(hq, tvh_gettext_lang(lang, doc + 2)); + break; + case 2: + md_class(hq, doc + 2, lang, 0, 1, 0); + break; + case 3: + md_class(hq, doc + 2, lang, 0, 0, 1); + break; + case 4: + for (page = tvh_doc_markdown_pages; page->name; page++) + if (!strcmp(page->name, doc + 2)) { + if (page->strings) + md_doc(hq, page->strings, lang, 0); + break; + } + break; } } else { htsbuf_append_str(hq, doc); @@ -194,9 +185,7 @@ md_render(htsbuf_queue_t *hq, const char *doc, const char *lang) } /* */ -static int -md_doc(htsbuf_queue_t *hq, const char **doc, const char *lang, int nl) -{ +static int md_doc(htsbuf_queue_t* hq, const char** doc, const char* lang, int nl) { if (doc == NULL) return nl; for (; *doc; doc++) { @@ -208,13 +197,11 @@ md_doc(htsbuf_queue_t *hq, const char **doc, const char *lang, int nl) /* */ static int -md_class(htsbuf_queue_t *hq, const char *clazz, const char *lang, - int hdr, int docs, int props) -{ - const idclass_t *ic; - htsmsg_t *m; - const char *s, **doc; - int nl = 0; +md_class(htsbuf_queue_t* hq, const char* clazz, const char* lang, int hdr, int docs, int props) { + const idclass_t* ic; + htsmsg_t* m; + const char * s, **doc; + int nl = 0; tvh_mutex_lock(&global_lock); ic = idclass_find(clazz); @@ -223,7 +210,7 @@ md_class(htsbuf_queue_t *hq, const char *clazz, const char *lang, return HTTP_STATUS_NOT_FOUND; } doc = idclass_get_doc(ic); - m = idclass_serializedoc(ic, lang); + m = idclass_serializedoc(ic, lang); tvh_mutex_unlock(&global_lock); if (hdr) { s = htsmsg_get_str(m, "caption"); @@ -243,12 +230,10 @@ md_class(htsbuf_queue_t *hq, const char *clazz, const char *lang, /** * List of all classes with documentation */ -static int -http_markdown_classes(http_connection_t *hc) -{ +static int http_markdown_classes(http_connection_t* hc) { idclass_t const **all, **all2; - const idclass_t *ic; - htsbuf_queue_t *hq = &hc->hc_reply; + const idclass_t* ic; + htsbuf_queue_t* hq = &hc->hc_reply; tvh_mutex_lock(&global_lock); all = idclass_find_all(); @@ -272,11 +257,9 @@ http_markdown_classes(http_connection_t *hc) /** * */ -static int -http_markdown_class(http_connection_t *hc, const char *clazz) -{ - const char *lang = hc->hc_access->aa_lang_ui; - htsbuf_queue_t *hq = &hc->hc_reply; +static int http_markdown_class(http_connection_t* hc, const char* clazz) { + const char* lang = hc->hc_access->aa_lang_ui; + htsbuf_queue_t* hq = &hc->hc_reply; return md_class(hq, clazz, lang, 1, 1, 1); } @@ -284,12 +267,10 @@ http_markdown_class(http_connection_t *hc, const char *clazz) /** * */ -static int -http_markdown_page(http_connection_t *hc, const struct tvh_doc_page *page) -{ - const char **doc = page->strings; - const char *lang = hc->hc_access->aa_lang_ui; - htsbuf_queue_t *hq = &hc->hc_reply; +static int http_markdown_page(http_connection_t* hc, const struct tvh_doc_page* page) { + const char** doc = page->strings; + const char* lang = hc->hc_access->aa_lang_ui; + htsbuf_queue_t* hq = &hc->hc_reply; if (doc == NULL) return HTTP_STATUS_NOT_FOUND; @@ -300,14 +281,12 @@ http_markdown_page(http_connection_t *hc, const struct tvh_doc_page *page) /** * Handle requests for markdown export. */ -int -page_markdown(http_connection_t *hc, const char *remain, void *opaque) -{ - const struct tvh_doc_page *page; - char *components[2]; - int nc, r; +int page_markdown(http_connection_t* hc, const char* remain, void* opaque) { + const struct tvh_doc_page* page; + char* components[2]; + int nc, r; - nc = http_tokenize((char *)remain, components, 2, '/'); + nc = http_tokenize((char*)remain, components, 2, '/'); if (!nc) return HTTP_STATUS_BAD_REQUEST; diff --git a/src/webui/extjs.c b/src/webui/extjs.c index 73b338a21..c6813131b 100644 --- a/src/webui/extjs.c +++ b/src/webui/extjs.c @@ -29,9 +29,7 @@ /** * */ -static void -extjs_load(htsbuf_queue_t *hq, const char *script, ...) -{ +static void extjs_load(htsbuf_queue_t* hq, const char* script, ...) { va_list ap; htsbuf_append_str(hq, "